Salome HOME
Implementation of planar symmetry + aggregation methods for MEDFileData+MEDFileUMesh
authorAnthony Geay <anthony.geay@edf.fr>
Tue, 27 Sep 2016 13:34:09 +0000 (15:34 +0200)
committerAnthony Geay <anthony.geay@edf.fr>
Tue, 4 Oct 2016 11:36:24 +0000 (13:36 +0200)
23 files changed:
src/INTERP_KERNEL/InterpolationUtils.hxx
src/MEDCoupling/MEDCouplingCurveLinearMesh.cxx
src/MEDCoupling/MEDCouplingMemArray.cxx
src/MEDCoupling/MEDCouplingMemArray.hxx
src/MEDCoupling/MEDCouplingPointSet.cxx
src/MEDCoupling/MEDCouplingPointSet.hxx
src/MEDCoupling/MEDCouplingUMesh.cxx
src/MEDCoupling/MEDCouplingUMesh.hxx
src/MEDCoupling/Test/MEDCouplingBasicsTest1.cxx
src/MEDCoupling_Swig/MEDCouplingBasicsTest5.py
src/MEDCoupling_Swig/MEDCouplingCommon.i
src/MEDCoupling_Swig/MEDCouplingMemArray.i
src/MEDLoader/MEDFileData.cxx
src/MEDLoader/MEDFileData.hxx
src/MEDLoader/MEDFileField.cxx
src/MEDLoader/MEDFileField.hxx
src/MEDLoader/MEDFileField.txx [new file with mode: 0644]
src/MEDLoader/MEDFileMesh.cxx
src/MEDLoader/MEDFileMesh.hxx
src/MEDLoader/MEDLoaderTraits.hxx [new file with mode: 0644]
src/MEDLoader/Swig/MEDLoaderCommon.i
src/MEDLoader/Swig/MEDLoaderTest3.py
src/MEDLoader/Swig/MEDLoaderTypemaps.i

index f8209fd68605d548844bc7647c75866592a6d716..2c3cb65012b4e369cda1f5604cbd592889997524 100644 (file)
@@ -946,6 +946,24 @@ namespace INTERP_KERNEL
       }              
   }
 
+  /*!
+   * Find a vector orthogonal to the input vector
+   */
+  inline void orthogonalVect3(const double inpVect[3], double outVect[3])
+  {
+    std::vector<bool> sw(3,false);
+    double inpVect2[3];
+    std::transform(inpVect,inpVect+3,inpVect2,std::ptr_fun<double,double>(fabs));
+    std::size_t posMin(std::distance(inpVect2,std::min_element(inpVect2,inpVect2+3)));
+    sw[posMin]=true;
+    std::size_t posMax(std::distance(inpVect2,std::max_element(inpVect2,inpVect2+3)));
+    if(posMax==posMin)
+      { posMax=(posMin+1)%3; }
+    sw[posMax]=true;
+    std::size_t posMid(std::distance(sw.begin(),std::find(sw.begin(),sw.end(),false)));
+    outVect[posMin]=0.; outVect[posMid]=1.; outVect[posMax]=-inpVect[posMid]/inpVect[posMax];
+  }
+  
   /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _*/
   /* Computes the dot product of a and b */
   /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _*/
index d5621e9030133d4c37419bc4ccca7bf544aa4357..d16420e8b82d1b8182fd2e93c7a20adf891de342 100644 (file)
@@ -637,9 +637,9 @@ void MEDCouplingCurveLinearMesh::rotate(const double *center, const double *vect
   int nbNodes=_coords->getNumberOfTuples();
   double *coords=_coords->getPointer();
   if(spaceDim==3)
-    MEDCouplingPointSet::Rotate3DAlg(center,vector,angle,nbNodes,coords);
+    DataArrayDouble::Rotate3DAlg(center,vector,angle,nbNodes,coords,coords);
   else if(spaceDim==2)
-    MEDCouplingPointSet::Rotate2DAlg(center,angle,nbNodes,coords);
+    DataArrayDouble::Rotate2DAlg(center,angle,nbNodes,coords,coords);
   else
     throw INTERP_KERNEL::Exception("MEDCouplingCurveLinearMesh::rotate : invalid space dim for rotation must be 2 or 3");
   _coords->declareAsNew();
index 35853e0a220980bb1f4e3a40c7b729716a5f5e1a..194cdccf4dc382df760b3f55f1ce0ce6e3c0fabb 100644 (file)
@@ -19,7 +19,6 @@
 // Author : Anthony Geay (CEA/DEN)
 
 #include "MEDCouplingMemArray.txx"
-#include "MCAuto.hxx"
 
 #include "BBTree.txx"
 #include "GenMathFormulae.hxx"
@@ -3217,6 +3216,21 @@ void DataArrayDouble::applyFuncFast64(const std::string& func)
   declareAsNew();
 }
 
+/*!
+ * \return a new object that is the result of the symmetry along 3D plane defined by its normal vector \a normalVector and a point \a point.
+ */
+MCAuto<DataArrayDouble> DataArrayDouble::symmetry3DPlane(const double point[3], const double normalVector[3]) const
+{
+  checkAllocated();
+  if(getNumberOfComponents()!=3)
+    throw INTERP_KERNEL::Exception("DataArrayDouble::symmetry3DPlane : this is excepted to have 3 components !");
+  int nbTuples(getNumberOfTuples());
+  MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
+  ret->alloc(nbTuples,3);
+  Symmetry3DPlane(point,normalVector,nbTuples,begin(),ret->getPointer());
+  return ret;
+}
+
 DataArrayDoubleIterator *DataArrayDouble::iterator()
 {
   return new DataArrayDoubleIterator(this);
@@ -4356,6 +4370,112 @@ void DataArrayDouble::finishUnserialization(const std::vector<int>& tinyInfoI, c
     }
 }
 
+/*!
+ * Low static method that operates 3D rotation of 'nbNodes' 3D nodes whose coordinates are arranged in \a coordsIn
+ * around an axe ( \a center, \a vect) and with angle \a angle.
+ */
+void DataArrayDouble::Rotate3DAlg(const double *center, const double *vect, double angle, int nbNodes, const double *coordsIn, double *coordsOut)
+{
+  if(!center || !vect)
+    throw INTERP_KERNEL::Exception("DataArrayDouble::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("DataArrayDouble::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(coordsIn+i*3,coordsIn+(i+1)*3,center,tmp,std::minus<double>());
+      coordsOut[i*3]=matrix[0]*tmp[0]+matrix[1]*tmp[1]+matrix[2]*tmp[2]+center[0];
+      coordsOut[i*3+1]=matrix[3]*tmp[0]+matrix[4]*tmp[1]+matrix[5]*tmp[2]+center[1];
+      coordsOut[i*3+2]=matrix[6]*tmp[0]+matrix[7]*tmp[1]+matrix[8]*tmp[2]+center[2];
+    }
+}
+
+void DataArrayDouble::Symmetry3DPlane(const double point[3], const double normalVector[3], int nbNodes, const double *coordsIn, double *coordsOut)
+{
+  double matrix[9],matrix2[9],matrix3[9];
+  double vect[3],crossVect[3];
+  INTERP_KERNEL::orthogonalVect3(normalVector,vect);
+  crossVect[0]=normalVector[1]*vect[2]-normalVector[2]*vect[1];
+  crossVect[1]=normalVector[2]*vect[0]-normalVector[0]*vect[2];
+  crossVect[2]=normalVector[0]*vect[1]-normalVector[1]*vect[0];
+  double nv(INTERP_KERNEL::norm<3>(vect)),ni(INTERP_KERNEL::norm<3>(normalVector)),nc(INTERP_KERNEL::norm<3>(crossVect));
+  matrix[0]=vect[0]/nv; matrix[1]=crossVect[0]/nc; matrix[2]=-normalVector[0]/ni;
+  matrix[3]=vect[1]/nv; matrix[4]=crossVect[1]/nc; matrix[5]=-normalVector[1]/ni;
+  matrix[6]=vect[2]/nv; matrix[7]=crossVect[2]/nc; matrix[8]=-normalVector[2]/ni;
+  matrix2[0]=vect[0]/nv; matrix2[1]=vect[1]/nv; matrix2[2]=vect[2]/nv;
+  matrix2[3]=crossVect[0]/nc; matrix2[4]=crossVect[1]/nc; matrix2[5]=crossVect[2]/nc;
+  matrix2[6]=normalVector[0]/ni; matrix2[7]=normalVector[1]/ni; matrix2[8]=normalVector[2]/ni;
+  for(int i=0;i<3;i++)
+    for(int j=0;j<3;j++)
+      {
+        double val(0.);
+        for(int k=0;k<3;k++)
+          val+=matrix[3*i+k]*matrix2[3*k+j];
+        matrix3[3*i+j]=val;
+      }
+  //rotation matrix computed.
+  double tmp[3];
+  for(int i=0; i<nbNodes; i++)
+    {
+      std::transform(coordsIn+i*3,coordsIn+(i+1)*3,point,tmp,std::minus<double>());
+      coordsOut[i*3]=matrix3[0]*tmp[0]+matrix3[1]*tmp[1]+matrix3[2]*tmp[2]+point[0];
+      coordsOut[i*3+1]=matrix3[3]*tmp[0]+matrix3[4]*tmp[1]+matrix3[5]*tmp[2]+point[1];
+      coordsOut[i*3+2]=matrix3[6]*tmp[0]+matrix3[7]*tmp[1]+matrix3[8]*tmp[2]+point[2];
+    }
+}
+
+void DataArrayDouble::GiveBaseForPlane(const double normalVector[3], double baseOfPlane[9])
+{
+  double vect[3],crossVect[3];
+  INTERP_KERNEL::orthogonalVect3(normalVector,vect);
+  crossVect[0]=normalVector[1]*vect[2]-normalVector[2]*vect[1];
+  crossVect[1]=normalVector[2]*vect[0]-normalVector[0]*vect[2];
+  crossVect[2]=normalVector[0]*vect[1]-normalVector[1]*vect[0];
+  double nv(INTERP_KERNEL::norm<3>(vect)),ni(INTERP_KERNEL::norm<3>(normalVector)),nc(INTERP_KERNEL::norm<3>(crossVect));
+  baseOfPlane[0]=vect[0]/nv; baseOfPlane[1]=vect[1]/nv; baseOfPlane[2]=vect[2]/nv;
+  baseOfPlane[3]=crossVect[0]/nc; baseOfPlane[4]=crossVect[1]/nc; baseOfPlane[5]=crossVect[2]/nc;
+  baseOfPlane[6]=normalVector[0]/ni; baseOfPlane[7]=normalVector[1]/ni; baseOfPlane[8]=normalVector[2]/ni;
+}
+
+/*!
+ * Low static method that operates 3D rotation of \a nbNodes 3D nodes whose coordinates are arranged in \a coords
+ * around the center point \a center and with angle \a angle.
+ */
+void DataArrayDouble::Rotate2DAlg(const double *center, double angle, int nbNodes, const double *coordsIn, double *coordsOut)
+{
+  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(coordsIn+i*2,coordsIn+(i+1)*2,center,tmp,std::minus<double>());
+      coordsOut[i*2]=matrix[0]*tmp[0]+matrix[1]*tmp[1]+center[0];
+      coordsOut[i*2+1]=matrix[2]*tmp[0]+matrix[3]*tmp[1]+center[1];
+    }
+}
+
 DataArrayDoubleIterator::DataArrayDoubleIterator(DataArrayDouble *da):_da(da),_tuple_id(0),_nb_comp(0),_nb_tuple(0)
 {
   if(_da)
index 77f89b9c7c4fceb42001192c74e79ad5d25c1265..991673bf98053076db96c1c61eaffb4a25b794ea 100644 (file)
@@ -22,6 +22,7 @@
 #define __MEDCOUPLING_MEDCOUPLINGMEMARRAY_HXX__
 
 #include "MEDCoupling.hxx"
+#include "MCAuto.hxx"
 #include "MEDCouplingTimeLabel.hxx"
 #include "MEDCouplingRefCountObject.hxx"
 #include "InterpKernelException.hxx"
@@ -385,6 +386,7 @@ namespace MEDCoupling
     MEDCOUPLING_EXPORT DataArrayDouble *applyFuncNamedCompo(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 MCAuto<DataArrayDouble> symmetry3DPlane(const double point[3], const double normalVector[3]) const;
     MEDCOUPLING_EXPORT DataArrayInt *findIdsInRange(double vmin, double vmax) const;
     MEDCOUPLING_EXPORT DataArrayInt *findIdsNotInRange(double vmin, double vmax) const;
     MEDCOUPLING_EXPORT static DataArrayDouble *Aggregate(const DataArrayDouble *a1, const DataArrayDouble *a2);
@@ -409,6 +411,10 @@ namespace MEDCoupling
     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;
+    MEDCOUPLING_EXPORT static void Rotate2DAlg(const double *center, double angle, int nbNodes, const double *coordsIn, double *coordsOut);
+    MEDCOUPLING_EXPORT static void Rotate3DAlg(const double *center, const double *vect, double angle, int nbNodes, const double *coordsIn, double *coordsOut);
+    MEDCOUPLING_EXPORT static void Symmetry3DPlane(const double point[3], const double normalVector[3], int nbNodes, const double *coordsIn, double *coordsOut);
+    MEDCOUPLING_EXPORT static void GiveBaseForPlane(const double normalVector[3], double baseOfPlane[9]);
   public:
     MEDCOUPLING_EXPORT void getTinySerializationIntInformation(std::vector<int>& tinyInfo) const;
     MEDCOUPLING_EXPORT void getTinySerializationStrInformation(std::vector<std::string>& tinyInfo) const;
index 299d219481e97af379eea9f6944a292d3b5bf5a2..b3761c2d962244540756a0432409bd2ad112a8cc 100644 (file)
@@ -994,8 +994,8 @@ bool MEDCouplingPointSet::intersectsBoundingBox(const double* bb1, const double*
  */
 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;
+  double* bbtemp(new double[2*dim]);
+  double deltamax(0.0);
 
   for (int i=0; i< dim; i++)
     {
@@ -1011,7 +1011,7 @@ bool MEDCouplingPointSet::intersectsBoundingBox(const INTERP_KERNEL::DirectedBou
       bbtemp[i*2+1]=bb2[i*2+1]+deltamax*eps;
     }
   
-  bool intersects = !bb1.isDisjointWith( bbtemp );
+  bool intersects(!bb1.isDisjointWith(bbtemp));
   delete [] bbtemp;
   return intersects;
 }
@@ -1021,49 +1021,9 @@ bool MEDCouplingPointSet::intersectsBoundingBox(const INTERP_KERNEL::DirectedBou
  */
 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];
-    }
+  double *coords(_coords->getPointer());
+  int nbNodes(getNumberOfNodes());
+  DataArrayDouble::Rotate3DAlg(center,vect,angle,nbNodes,coords,coords);
 }
 
 /*!
@@ -1157,7 +1117,7 @@ MEDCouplingMesh *MEDCouplingPointSet::buildPartRange(int beginCellIds, int endCe
  */
 MEDCouplingMesh *MEDCouplingPointSet::buildPartRangeAndReduceNodes(int beginCellIds, int endCellIds, int stepCellIds, int& beginOut, int& endOut, int& stepOut, DataArrayInt*& arr) const
 {
-  MCAuto<MEDCouplingPointSet> ret=buildPartOfMySelfSlice(beginCellIds,endCellIds,stepCellIds,true);
+  MCAuto<MEDCouplingPointSet> ret(buildPartOfMySelfSlice(beginCellIds,endCellIds,stepCellIds,true));
   arr=ret->zipCoordsTraducer();
   return ret.retn();
 }
@@ -1167,28 +1127,9 @@ MEDCouplingMesh *MEDCouplingPointSet::buildPartRangeAndReduceNodes(int beginCell
  */
 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];
-    }
+  double *coords(_coords->getPointer());
+  int nbNodes(getNumberOfNodes());
+  DataArrayDouble::Rotate2DAlg(center,angle,nbNodes,coords,coords);
 }
 
 /// @cond INTERNAL
@@ -1212,8 +1153,8 @@ public:
  */
 void MEDCouplingPointSet::project2DCellOnXY(const int *startConn, const int *endConn, std::vector<double>& res) const
 {
-  const double *coords=_coords->getConstPointer();
-  int spaceDim=getSpaceDimension();
+  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)
@@ -1239,7 +1180,7 @@ void MEDCouplingPointSet::project2DCellOnXY(const int *startConn, const int *end
  */
 bool MEDCouplingPointSet::isButterfly2DCell(const std::vector<double>& res, bool isQuad, double eps)
 {
-  std::size_t nbOfNodes=res.size()/2;
+  std::size_t nbOfNodes(res.size()/2);
   std::vector<INTERP_KERNEL::Node *> nodes(nbOfNodes);
   for(std::size_t i=0;i<nbOfNodes;i++)
     {
@@ -1253,7 +1194,7 @@ bool MEDCouplingPointSet::isButterfly2DCell(const std::vector<double>& res, bool
     pol=INTERP_KERNEL::QuadraticPolygon::BuildArcCirclePolygon(nodes);
   else
     pol=INTERP_KERNEL::QuadraticPolygon::BuildLinearPolygon(nodes);
-  bool ret=pol->isButterflyAbs();
+  bool ret(pol->isButterflyAbs());
   delete pol;
   return ret;
 }
@@ -1269,7 +1210,7 @@ bool MEDCouplingPointSet::areCellsFrom2MeshEqual(const MEDCouplingPointSet *othe
   std::vector<int> c1,c2;
   getNodeIdsOfCell(cellId,c1);
   other->getNodeIdsOfCell(cellId,c2);
-  std::size_t sz=c1.size();
+  std::size_t sz(c1.size());
   if(sz!=c2.size())
     return false;
   for(std::size_t i=0;i<sz;i++)
index b88121b6b27ae41bfdbac2b9ef401281b2ffddcd..cf821d257e8d68133b9b56237738163f9858103f 100644 (file)
@@ -103,8 +103,6 @@ namespace MEDCoupling
     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;
index ea521f6758cb6ba0d47302d56be915f72c93b0cd..a3bbcc180bd98caaf790dde91ad234f84ef6cd2a 100644 (file)
@@ -4009,7 +4009,7 @@ DataArrayInt *MEDCouplingUMesh::getCellIdsCrossingPlane(const double *origin, co
       MCAuto<DataArrayDouble> coo=_coords->deepCopy();
       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());
+        DataArrayDouble::Rotate3DAlg(origin,vec2,angle,coo->getNumberOfTuples(),coo->getPointer(),coo->getPointer());
       MCAuto<MEDCouplingUMesh> mw=clone(false);//false -> shallow copy
       mw->setCoords(coo);
       mw->getBoundingBox(bbox);
@@ -7963,7 +7963,7 @@ MEDCouplingUMesh *MEDCouplingUMesh::MergeUMeshes(const MEDCouplingUMesh *mesh1,
  *  \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)
+MEDCouplingUMesh *MEDCouplingUMesh::MergeUMeshes(const std::vector<const MEDCouplingUMesh *>& a)
 {
   std::size_t sz=a.size();
   if(sz==0)
@@ -7996,7 +7996,7 @@ MEDCouplingUMesh *MEDCouplingUMesh::MergeUMeshes(std::vector<const MEDCouplingUM
 
 /// @cond INTERNAL
 
-MEDCouplingUMesh *MEDCouplingUMesh::MergeUMeshesLL(std::vector<const MEDCouplingUMesh *>& a)
+MEDCouplingUMesh *MEDCouplingUMesh::MergeUMeshesLL(const std::vector<const MEDCouplingUMesh *>& a)
 {
   if(a.empty())
     throw INTERP_KERNEL::Exception("MEDCouplingUMesh::MergeUMeshes : input array must be NON EMPTY !");
index 68093553c692c5c99f0ff89dd03e9e57765f1b2d..9a8fc33c22fdb5adeb6e5e75e08013b87261899d 100644 (file)
@@ -232,7 +232,7 @@ namespace MEDCoupling
     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 *MergeUMeshes(const 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);
@@ -311,7 +311,7 @@ namespace MEDCoupling
     void getCellsContainingPointsAlg(const double *coords, const double *pos, int nbOfPoints,
                                      double eps, MCAuto<DataArrayInt>& elts, MCAuto<DataArrayInt>& eltsIndex) const;
 /// @cond INTERNAL
-    static MEDCouplingUMesh *MergeUMeshesLL(std::vector<const MEDCouplingUMesh *>& a);
+    static MEDCouplingUMesh *MergeUMeshesLL(const 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;
index 1373d886e40a6969369ddb95af07af22c88ceafe..0348dafb87b261a272e9eb459ffdb95d8ca443ea 100644 (file)
@@ -2175,7 +2175,7 @@ void MEDCouplingBasicsTest1::testGetCellsContainingPoint()
   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);
+  DataArrayDouble::Rotate2DAlg(center,0.78539816339744830962,6,pos,pos);
   targetMesh->rotate(center,0,0.78539816339744830962);
   targetMesh->getCellsContainingPoints(pos,6,1e-12,t1,t2);
   CPPUNIT_ASSERT_EQUAL(6,(int)t1->getNbOfElems());
index ad084d3d0ad0eeb951c041934abe4b2442cb0146..57951ce92795358d72314d96d471a1ad275519d9 100644 (file)
@@ -4375,6 +4375,41 @@ class MEDCouplingBasicsTest5(unittest.TestCase):
             self.assertEqual(f1.isEqual(f4,1e-12,0.),expected)
             pass
         pass
+
+    def testDADSymmetry1(self):
+        arr=DataArrayDouble([2,3,4],1,3)
+        res=arr.symmetry3DPlane([0.,0.,0.],[0.,0.,2.])
+        self.assertTrue(res.isEqual(DataArrayDouble([2,3,-4],1,3),1e-14))
+        #
+        res=arr.symmetry3DPlane([-1000,100,-1],[0.,0.,2.])
+        self.assertTrue(res.isEqual(DataArrayDouble([2,3,-6],1,3),1e-14))
+        #
+        res=arr.symmetry3DPlane([0,0,0],[1.,0.,0.])
+        self.assertTrue(res.isEqual(DataArrayDouble([-2,3,4],1,3),1e-14))
+        #
+        res=arr.symmetry3DPlane([0,0,0],[0.,1.,0.])
+        self.assertTrue(res.isEqual(DataArrayDouble([2,-3,4],1,3),1e-14))
+        #
+        res=arr.symmetry3DPlane([0,0,0],[-1.,1.,0.])
+        self.assertTrue(res.isEqual(DataArrayDouble([3,2,4],1,3),1e-14))
+        #
+        plane=[5.,4.,-7.]
+        a=DataArrayDouble(DataArrayDouble.GiveBaseForPlane(plane))
+        self.assertAlmostEqual(DataArrayDouble.Dot(a[0],a[1]).magnitude()[0],0.,13)
+        self.assertAlmostEqual(DataArrayDouble.Dot(a[0],a[2]).magnitude()[0],0.,13)
+        self.assertAlmostEqual(DataArrayDouble.Dot(a[1],a[2]).magnitude()[0],0.,13)
+        coo=DataArrayDouble.Aggregate([10*a[0]+10*a[1],-10*a[0]+10*a[1],-10*a[0]-10*a[1],10*a[0]-10*a[1]])
+        m=MEDCouplingUMesh("",2) ; m.setCoords(coo) ; m.allocateCells()
+        m.insertNextCell(NORM_QUAD4,[0,1,2,3])
+        d,_=m.distanceToPoint(arr)
+        res=arr.symmetry3DPlane([0.,0.,0.],plane) #
+        d2,_=m.distanceToPoint(res)
+        self.assertAlmostEqual(abs(d-d2),0.,12)
+        self.assertAlmostEqual(DataArrayDouble.Dot(res-arr,a[0])[0],0.,12)
+        self.assertAlmostEqual(DataArrayDouble.Dot(res-arr,a[1])[0],0.,12)
+        self.assertAlmostEqual((res-arr).magnitude()[0]-2*d,0.,12)
+        self.assertTrue(res.isEqual(DataArrayDouble([2.666666666666667,3.5333333333333333,3.0666666666666666],1,3),1e-12))
+        pass
     
     pass
 
index eebe898c7050640c70313fc87a69301cbdae0d01..cb145e880d6fdc019e7d87fd9b8827d4d811cc52 100644 (file)
@@ -1621,7 +1621,7 @@ namespace MEDCoupling
              int sz;
              INTERP_KERNEL::AutoCPtr<double> c=convertPyToNewDblArr2(center,&sz);
              INTERP_KERNEL::AutoCPtr<double> coo=convertPyToNewDblArr2(coords,&sz);
-             MEDCoupling::MEDCouplingPointSet::Rotate2DAlg(c,angle,nbNodes,coo);
+             MEDCoupling::DataArrayDouble::Rotate2DAlg(c,angle,nbNodes,coo,coo);
              for(int i=0;i<sz;i++)
                PyList_SetItem(coords,i,PyFloat_FromDouble(coo[i]));
            }
@@ -1637,7 +1637,7 @@ namespace MEDCoupling
                                                             "Rotate2DAlg",2,true,nbNodes);
              if(sw!=2 && sw!=3)
                throw INTERP_KERNEL::Exception("Invalid call to MEDCouplingPointSet::Rotate2DAlg : try another overload method !");
-             MEDCoupling::MEDCouplingPointSet::Rotate2DAlg(c,angle,nbNodes,const_cast<double *>(coo));
+             MEDCoupling::DataArrayDouble::Rotate2DAlg(c,angle,nbNodes,coo,const_cast<double *>(coo));
            }
            
            static void Rotate3DAlg(PyObject *center, PyObject *vect, double angle, int nbNodes, PyObject *coords) throw(INTERP_KERNEL::Exception)
@@ -1646,7 +1646,7 @@ namespace MEDCoupling
              INTERP_KERNEL::AutoCPtr<double> c=convertPyToNewDblArr2(center,&sz);
              INTERP_KERNEL::AutoCPtr<double> coo=convertPyToNewDblArr2(coords,&sz);
              INTERP_KERNEL::AutoCPtr<double> v=convertPyToNewDblArr2(vect,&sz2);
-             MEDCoupling::MEDCouplingPointSet::Rotate3DAlg(c,v,angle,nbNodes,coo);
+             MEDCoupling::DataArrayDouble::Rotate3DAlg(c,v,angle,nbNodes,coo,coo);
              for(int i=0;i<sz;i++)
                PyList_SetItem(coords,i,PyFloat_FromDouble(coo[i]));
            }
@@ -1663,7 +1663,7 @@ namespace MEDCoupling
              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);
-             MEDCoupling::MEDCouplingPointSet::Rotate3DAlg(c,v,angle,nbNodes,const_cast<double *>(coo));
+             MEDCoupling::DataArrayDouble::Rotate3DAlg(c,v,angle,nbNodes,coo,const_cast<double *>(coo));
            }
          }
     };
index 28e239007466b86b415fe73c5d1e6dbd67c45a50..bb63fbb5bd9b634490efd6ea00236f435db4a907 100644 (file)
 %newobject MEDCoupling::DataArrayDouble::Multiply;
 %newobject MEDCoupling::DataArrayDouble::Divide;
 %newobject MEDCoupling::DataArrayDouble::Pow;
+%newobject MEDCoupling::DataArrayDouble::symmetry3DPlane;
 %newobject MEDCoupling::DataArrayDouble::subArray;
 %newobject MEDCoupling::DataArrayDouble::changeNbOfComponents;
 %newobject MEDCoupling::DataArrayDouble::accumulatePerChunck;
@@ -870,6 +871,34 @@ namespace MEDCoupling
         return convertDblArrToPyListOfTuple(vals,nbOfComp,nbOfTuples);
       }
 
+      DataArrayDouble *symmetry3DPlane(PyObject *point, PyObject *normalVector) throw(INTERP_KERNEL::Exception)
+      {
+        const char msg[]="Python wrap of DataArrayDouble::symmetry3DPlane : ";
+        double val,val2;
+        DataArrayDouble *a,*a2;
+        DataArrayDoubleTuple *aa,*aa2;
+        std::vector<double> bb,bb2;
+        int sw;
+        const double *centerPtr(convertObjToPossibleCpp5_Safe(point,sw,val,a,aa,bb,msg,1,3,true));
+        const double *vectorPtr(convertObjToPossibleCpp5_Safe(normalVector,sw,val2,a2,aa2,bb2,msg,1,3,true));
+        MCAuto<DataArrayDouble> ret(self->symmetry3DPlane(centerPtr,vectorPtr));
+        return ret.retn();
+      }
+
+      static PyObject *GiveBaseForPlane(PyObject *normalVector) throw(INTERP_KERNEL::Exception)
+      {
+        const char msg[]="Python wrap of DataArrayDouble::GiveBaseForPlane : ";
+        double val,val2;
+        DataArrayDouble *a,*a2;
+        DataArrayDoubleTuple *aa,*aa2;
+        std::vector<double> bb,bb2;
+        int sw;
+        const double *vectorPtr(convertObjToPossibleCpp5_Safe(normalVector,sw,val,a,aa,bb,msg,1,3,true));
+        double res[9];
+        DataArrayDouble::GiveBaseForPlane(vectorPtr,res);
+        return convertDblArrToPyListOfTuple(res,3,3);
+      }
+      
       DataArrayDouble *renumber(PyObject *li) throw(INTERP_KERNEL::Exception)
       {
         void *da=0;
index 96e77a72cd4b1b49f3b4a8383cdd0d7b34719c88..72606a8d8f445149e8937c28d7c5ed06c2094eb2 100644 (file)
@@ -219,6 +219,74 @@ bool MEDFileData::unPolyzeMeshes()
   return !meshesImpacted.empty();
 }
 
+/*!
+ * Precondition : all instances in \a mfds should have a single mesh with fields on it. If there is an instance with not exactly one mesh an exception will be thrown.
+ * You can invoke MEDFileFields::partOfThisLyingOnSpecifiedMeshName method to make it work.
+ */
+MCAuto<MEDFileData> MEDFileData::Aggregate(const std::vector<const MEDFileData *>& mfds)
+{
+  if(mfds.empty())
+    throw INTERP_KERNEL::Exception("MEDFileData::Aggregate : empty vector !");
+  std::size_t sz(mfds.size()),i(0);
+  MCAuto<MEDFileData> ret(MEDFileData::New());
+  std::vector<const MEDFileUMesh *> ms(sz);
+  std::vector< std::vector< std::pair<int,int> > > dts(sz);
+  for(std::vector<const MEDFileData *>::const_iterator it=mfds.begin();it!=mfds.end();it++,i++)
+    {
+      const MEDFileData *elt(*it);
+      if(!elt)
+        throw INTERP_KERNEL::Exception("MEDFileData::Aggregate : presence of NULL pointer !");
+      const MEDFileMeshes *meshes(elt->getMeshes());
+      if(!meshes)
+        throw INTERP_KERNEL::Exception("MEDFileData::Aggregate : presence of an instance with no meshes attached on it !");
+      if(meshes->getNumberOfMeshes()!=1)
+        throw INTERP_KERNEL::Exception("MEDFileData::Aggregate : all instances in input vector must lie on exactly one mesh ! To have it you can invoke partOfThisLyingOnSpecifiedMeshName method.");
+      const MEDFileMesh *mesh(meshes->getMeshAtPos(0));
+      if(!mesh)
+        throw INTERP_KERNEL::Exception("MEDFileData::Aggregate : presence of null mesh in a MEDFileData instance among input vector !");
+      const MEDFileUMesh *umesh(dynamic_cast<const MEDFileUMesh *>(mesh));
+      if(!umesh)
+        throw INTERP_KERNEL::Exception("MEDFileData::Aggregate : works only for unstructured meshes !");
+      ms[i]=umesh;
+      dts[i]=umesh->getAllDistributionOfTypes();
+    }
+  MCAuto<MEDFileUMesh> agg_m(MEDFileUMesh::Aggregate(ms));
+  MCAuto<MEDFileMeshes> mss(MEDFileMeshes::New()); mss->pushMesh(agg_m);
+  ret->setMeshes(mss);
+  // fields
+  std::vector<std::string> fieldNames(mfds[0]->getFields()->getFieldsNames());
+  std::set<std::string> fieldNamess(fieldNames.begin(),fieldNames.end());
+  if(fieldNames.size()!=fieldNamess.size())
+    throw INTERP_KERNEL::Exception("MEDFileData::Aggregate : field names must be different each other !");
+  std::vector< std::vector<const MEDFileAnyTypeFieldMultiTS *> > vectOfFields(fieldNames.size());
+  std::vector< std::vector< MCAuto< MEDFileAnyTypeFieldMultiTS > > > vectOfFields2(fieldNames.size());
+  MCAuto<MEDFileFields> fss(MEDFileFields::New());
+  for(std::vector<const MEDFileData *>::const_iterator it=mfds.begin();it!=mfds.end();it++)
+    {
+      std::vector<std::string> fieldNames0((*it)->getFields()->getFieldsNames());
+      std::set<std::string> fieldNamess0(fieldNames0.begin(),fieldNames0.end());
+      if(fieldNamess!=fieldNamess0)
+        throw INTERP_KERNEL::Exception("MEDFileData::Aggregate : field names must be the same for all input instances !");
+      i=0;
+      for(std::vector<std::string>::const_iterator it1=fieldNames.begin();it1!=fieldNames.end();it1++,i++)
+        {
+          MCAuto<MEDFileAnyTypeFieldMultiTS> fmts((*it)->getFields()->getFieldWithName(*it1));
+          if(fmts.isNull())
+            throw INTERP_KERNEL::Exception("MEDFileData::Aggregate : internal error 1 !");
+          vectOfFields2[i].push_back(fmts); vectOfFields[i].push_back(fmts);
+        }
+    }
+  i=0;
+  for(std::vector<std::string>::const_iterator it1=fieldNames.begin();it1!=fieldNames.end();it1++,i++)
+    {
+      MCAuto<MEDFileAnyTypeFieldMultiTS> fmts(MEDFileAnyTypeFieldMultiTS::Aggregate(vectOfFields[i],dts));
+      fmts->setMeshName(agg_m->getName());
+      fss->pushField(fmts);
+    }
+  ret->setFields(fss);
+  return ret;
+}
+
 MEDFileData::MEDFileData()
 {
 }
index d09cfd33ea2e9775765d79d99f6283e395bd8061..bdb21eb97e200bb2b165300e9f1ab0e6ccb5ccc7 100644 (file)
@@ -53,6 +53,7 @@ namespace MEDCoupling
     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 static MCAuto<MEDFileData> Aggregate(const std::vector<const MEDFileData *>& mfds);
     //
     MEDLOADER_EXPORT void write(const std::string& fileName, int mode) const;
   private:
index 612cb82d95fda34b0e60b17b44edc26a49c5f8ab..81292d8407d4c095864b36fce1ae078fe2f79a50 100644 (file)
 //
 // Author : Anthony Geay (CEA/DEN)
 
-#include "MEDFileField.hxx"
+#include "MEDFileField.txx"
 #include "MEDFileMesh.hxx"
 #include "MEDLoaderBase.hxx"
+#include "MEDLoaderTraits.hxx"
 #include "MEDFileUtilities.hxx"
 #include "MEDFileSafeCaller.txx"
 #include "MEDFileFieldOverView.hxx"
@@ -42,6 +43,9 @@ extern med_geometry_type typmai3[34];
 
 using namespace MEDCoupling;
 
+template class MEDFileField1TSTemplateWithoutSDA<int>;
+template class MEDFileField1TSTemplateWithoutSDA<double>;
+
 const char MEDFileField1TSWithoutSDA::TYPE_STR[]="FLOAT64";
 const char MEDFileIntField1TSWithoutSDA::TYPE_STR[]="INT32";
 
@@ -1579,10 +1583,6 @@ bool MEDFileFieldPerMeshPerType::keepOnlyGaussDiscretization(std::size_t idOfDis
   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);
@@ -2341,6 +2341,90 @@ const MEDFileFieldPerMeshPerTypePerDisc *MEDFileFieldPerMesh::getLeafGivenTypeAn
   throw INTERP_KERNEL::Exception(oss.str());
 }
 
+/*!
+ * \param [in,out] start - Integer that gives the current position in the final aggregated array
+ * \param [in] pms - list of elements to aggregate. integer gives the mesh id 
+ * \param [in] dts - (Distribution of types) = level 1 : meshes to aggregate. Level 2 : all geo type. Level 3 pair specifying geo type and number of elem in geotype.
+ * \param [out] extractInfo - Gives information about the where the data comes from. It is a vector of triplet. First element in the triplet the mesh pos. The 2nd one the start pos. The 3rd the end pos.
+ */
+MCAuto<MEDFileFieldPerMeshPerTypePerDisc> MEDFileFieldPerMeshPerTypePerDisc::Aggregate(int &start, const std::vector< std::pair<int,const MEDFileFieldPerMeshPerTypePerDisc *> >& pms, const std::vector< std::vector< std::pair<int,int> > >& dts, TypeOfField tof, MEDFileFieldPerMeshPerType *father, std::vector<std::pair< int, std::pair<int,int> > >& extractInfo)
+{
+  MCAuto<MEDFileFieldPerMeshPerTypePerDisc> ret(new MEDFileFieldPerMeshPerTypePerDisc(father,tof));
+  if(pms.empty())
+    throw INTERP_KERNEL::Exception("MEDFileFieldPerMeshPerTypePerDisc::Aggregate : empty input vector !");
+  for(std::vector<std::pair<int,const MEDFileFieldPerMeshPerTypePerDisc *> >::const_iterator it=pms.begin();it!=pms.end();it++)
+    {
+      if(!(*it).second)
+        throw INTERP_KERNEL::Exception("MEDFileFieldPerMeshPerTypePerDisc::Aggregate : presence of null pointer !");
+      if(!(*it).second->getProfile().empty())
+        throw INTERP_KERNEL::Exception("MEDFileFieldPerMeshPerTypePerDisc::Aggregate : not implemented yet for profiles !");
+      if(!(*it).second->getLocalization().empty())
+        throw INTERP_KERNEL::Exception("MEDFileFieldPerMeshPerTypePerDisc::Aggregate : not implemented yet for gauss pts !");
+    }
+  INTERP_KERNEL::NormalizedCellType gt(pms[0].second->getGeoType());
+  std::size_t i(0);
+  std::vector< std::pair<int,int> > filteredDTS;
+  for(std::vector< std::vector< std::pair<int,int> > >::const_iterator it=dts.begin();it!=dts.end();it++,i++)
+    for(std::vector< std::pair<int,int> >::const_iterator it2=(*it).begin();it2!=(*it).end();it2++)
+      if((*it2).first==gt)
+        filteredDTS.push_back(std::pair<int,int>(i,(*it2).second));
+  if(pms.size()!=filteredDTS.size())
+    throw INTERP_KERNEL::Exception("MEDFileFieldPerMeshPerTypePerDisc::Aggregate : not implemented yet for generated profiles !");
+  std::vector<std::pair<int,const MEDFileFieldPerMeshPerTypePerDisc *> >::const_iterator it1(pms.begin());
+  std::vector< std::pair<int,int> >::const_iterator it2(filteredDTS.begin());
+  int zeStart(start),nval(0);
+  for(;it1!=pms.end();it1++,it2++)
+    {
+      if((*it1).first!=(*it2).first)
+        throw INTERP_KERNEL::Exception("MEDFileFieldPerMeshPerTypePerDisc::Aggregate : not implemented yet for generated profiles 2 !");
+      int s1((*it1).second->getStart()),e1((*it1).second->getEnd());
+      extractInfo.push_back(std::pair<int, std::pair<int,int> >((*it1).first,std::pair<int,int>(s1,e1)));
+      start+=e1-s1;
+      nval+=((*it1).second)->getNumberOfVals();
+    }
+  ret->_start=zeStart; ret->_end=start; ret->_nval=nval;
+  return ret;
+}
+
+MCAuto<MEDFileFieldPerMeshPerType> MEDFileFieldPerMeshPerType::Aggregate(int &start, const std::vector<std::pair<int,const MEDFileFieldPerMeshPerType *> >& pms, const std::vector< std::vector< std::pair<int,int> > >& dts, INTERP_KERNEL::NormalizedCellType gt, MEDFileFieldPerMesh *father, std::vector<std::pair< int, std::pair<int,int> > >& extractInfo)
+{
+  MCAuto<MEDFileFieldPerMeshPerType> ret(new MEDFileFieldPerMeshPerType(father,gt));
+  std::map<TypeOfField, std::vector< std::pair<int,const MEDFileFieldPerMeshPerTypePerDisc * > > > m;
+  for(std::vector<std::pair<int,const MEDFileFieldPerMeshPerType *> >::const_iterator it=pms.begin();it!=pms.end();it++)
+    {
+      for(std::vector< MCAuto<MEDFileFieldPerMeshPerTypePerDisc> >::const_iterator it2=(*it).second->_field_pm_pt_pd.begin();it2!=(*it).second->_field_pm_pt_pd.end();it2++)
+        m[(*it2)->getType()].push_back(std::pair<int,const MEDFileFieldPerMeshPerTypePerDisc * >((*it).first,*it2));
+    }
+  for(std::map<TypeOfField, std::vector< std::pair<int,const MEDFileFieldPerMeshPerTypePerDisc * > > >::const_iterator it=m.begin();it!=m.end();it++)
+    {
+      MCAuto<MEDFileFieldPerMeshPerTypePerDisc> agg(MEDFileFieldPerMeshPerTypePerDisc::Aggregate(start,(*it).second,dts,(*it).first,ret,extractInfo));
+      ret->_field_pm_pt_pd.push_back(agg);
+    }
+  return ret;
+}
+
+MCAuto<MEDFileFieldPerMesh> MEDFileFieldPerMesh::Aggregate(int &start, const std::vector<const MEDFileFieldPerMesh *>& pms, const std::vector< std::vector< std::pair<int,int> > >& dts, MEDFileAnyTypeField1TSWithoutSDA *father, std::vector<std::pair< int, std::pair<int,int> > >& extractInfo)
+{
+  MCAuto<MEDFileFieldPerMesh> ret(new MEDFileFieldPerMesh(father,pms[0]->getMeshName(),pms[0]->getMeshIteration(),pms[0]->getMeshOrder()));
+  std::map<INTERP_KERNEL::NormalizedCellType, std::vector< std::pair<int,const MEDFileFieldPerMeshPerType *> > > m;
+  std::size_t i(0);
+  for(std::vector<const MEDFileFieldPerMesh *>::const_iterator it=pms.begin();it!=pms.end();it++,i++)
+    {
+      const std::vector< MCAuto< MEDFileFieldPerMeshPerType > >& v((*it)->_field_pm_pt);
+      for(std::vector< MCAuto< MEDFileFieldPerMeshPerType > >::const_iterator it2=v.begin();it2!=v.end();it2++)
+        {
+          INTERP_KERNEL::NormalizedCellType gt((*it2)->getGeoType());
+          m[gt].push_back(std::pair<int,const MEDFileFieldPerMeshPerType *>(i,*it2));
+        }
+    }
+  for(std::map<INTERP_KERNEL::NormalizedCellType, std::vector< std::pair<int,const MEDFileFieldPerMeshPerType *> > >::const_iterator it=m.begin();it!=m.end();it++)
+    {
+      MCAuto<MEDFileFieldPerMeshPerType> agg(MEDFileFieldPerMeshPerType::Aggregate(start,(*it).second,dts,(*it).first,ret,extractInfo));
+      ret->_field_pm_pt.push_back(agg);
+    }
+  return ret;
+}
+
 int MEDFileFieldPerMesh::addNewEntryIfNecessary(INTERP_KERNEL::NormalizedCellType type)
 {
   int i=0;
@@ -5114,22 +5198,6 @@ std::vector< std::vector<DataArrayDouble *> > MEDFileField1TSWithoutSDA::getFiel
   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;
@@ -5149,18 +5217,6 @@ MEDFileIntField1TSWithoutSDA *MEDFileField1TSWithoutSDA::convertToInt() const
   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
@@ -5184,7 +5240,7 @@ DataArrayDouble *MEDFileField1TSWithoutSDA::getUndergroundDataArrayDoubleExt(std
   if(_field_per_mesh[0]==0)
     throw INTERP_KERNEL::Exception("MEDFileField1TSWithoutSDA::getUndergroundDataArrayExt : no field specified !");
   _field_per_mesh[0]->getUndergroundDataArrayExt(entries);
-  return getUndergroundDataArrayDouble();
+  return getUndergroundDataArrayTemplate();
 }
 
 /*!
@@ -5208,13 +5264,13 @@ DataArray *MEDFileField1TSWithoutSDA::getUndergroundDataArrayExt(std::vector< st
   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)
+MEDFileField1TSWithoutSDA::MEDFileField1TSWithoutSDA(const std::string& fieldName, int csit, int iteration, int order, const std::vector<std::string>& infos):MEDFileField1TSTemplateWithoutSDA<double>(fieldName,csit,iteration,order)
 {
-  DataArrayDouble *arr(getOrCreateAndGetArrayDouble());
+  DataArrayDouble *arr(getOrCreateAndGetArrayTemplate());
   arr->setInfoAndChangeNbOfCompo(infos);
 }
 
-MEDFileField1TSWithoutSDA::MEDFileField1TSWithoutSDA():MEDFileAnyTypeField1TSWithoutSDA()
+MEDFileField1TSWithoutSDA::MEDFileField1TSWithoutSDA():MEDFileField1TSTemplateWithoutSDA<double>()
 {
 }
 
@@ -5233,57 +5289,6 @@ MEDFileAnyTypeField1TSWithoutSDA *MEDFileField1TSWithoutSDA::deepCopy() const
   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)
@@ -5291,14 +5296,14 @@ MEDFileIntField1TSWithoutSDA *MEDFileIntField1TSWithoutSDA::New(const std::strin
   return new MEDFileIntField1TSWithoutSDA(fieldName,csit,iteration,order,infos);
 }
 
-MEDFileIntField1TSWithoutSDA::MEDFileIntField1TSWithoutSDA():MEDFileAnyTypeField1TSWithoutSDA()
+MEDFileIntField1TSWithoutSDA::MEDFileIntField1TSWithoutSDA():MEDFileField1TSTemplateWithoutSDA<int>()
 {
 }
 
 MEDFileIntField1TSWithoutSDA::MEDFileIntField1TSWithoutSDA(const std::string& fieldName, int csit, int iteration, int order,
-                                                           const std::vector<std::string>& infos):MEDFileAnyTypeField1TSWithoutSDA(fieldName,csit,iteration,order)
+                                                           const std::vector<std::string>& infos):MEDFileField1TSTemplateWithoutSDA<int>(fieldName,csit,iteration,order)
 {
-  DataArrayInt *arr(getOrCreateAndGetArrayInt());
+  DataArrayInt *arr(getOrCreateAndGetArrayTemplate());
   arr->setInfoAndChangeNbOfCompo(infos);
 }
 
@@ -5321,34 +5326,6 @@ MEDFileField1TSWithoutSDA *MEDFileIntField1TSWithoutSDA::convertToDouble() const
   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
@@ -5393,7 +5370,7 @@ DataArrayInt *MEDFileIntField1TSWithoutSDA::getUndergroundDataArrayIntExt(std::v
   if(_field_per_mesh[0]==0)
     throw INTERP_KERNEL::Exception("MEDFileField1TSWithoutSDA::getUndergroundDataArrayExt : no field specified !");
   _field_per_mesh[0]->getUndergroundDataArrayExt(entries);
-  return getUndergroundDataArrayInt();
+  return getUndergroundDataArrayTemplate();
 }
 
 MEDFileAnyTypeField1TSWithoutSDA *MEDFileIntField1TSWithoutSDA::shallowCpy() const
@@ -5411,57 +5388,6 @@ MEDFileAnyTypeField1TSWithoutSDA *MEDFileIntField1TSWithoutSDA::deepCopy() const
   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()
 {
 }
@@ -6328,7 +6254,7 @@ MEDFileField1TS *MEDFileField1TS::New(const std::string& fileName, const std::st
  */
 MEDFileField1TS *MEDFileField1TS::New(const MEDFileField1TSWithoutSDA& other, bool shallowCopyOfContent)
 {
-  MCAuto<MEDFileField1TS> ret=new MEDFileField1TS(other,shallowCopyOfContent);
+  MCAuto<MEDFileField1TS> ret(new MEDFileField1TS(other,shallowCopyOfContent));
   ret->contentNotNull();
   return ret.retn();
 }
@@ -6340,7 +6266,7 @@ MEDFileField1TS *MEDFileField1TS::New(const MEDFileField1TSWithoutSDA& other, bo
  */
 MEDFileField1TS *MEDFileField1TS::New()
 {
-  MCAuto<MEDFileField1TS> ret=new MEDFileField1TS;
+  MCAuto<MEDFileField1TS> ret(new MEDFileField1TS);
   ret->contentNotNull();
   return ret.retn();
 }
@@ -6761,7 +6687,7 @@ MEDFileAnyTypeField1TS *MEDFileField1TS::shallowCpy() const
 
 DataArrayDouble *MEDFileField1TS::getUndergroundDataArray() const
 {
-  return contentNotNull()->getUndergroundDataArrayDouble();
+  return contentNotNull()->getUndergroundDataArrayTemplate();
 }
 
 DataArrayDouble *MEDFileField1TS::getUndergroundDataArrayExt(std::vector< std::pair<std::pair<INTERP_KERNEL::NormalizedCellType,int>,std::pair<int,int> > >& entries) const
@@ -7168,7 +7094,7 @@ MEDFileIntField1TSWithoutSDA *MEDFileIntField1TS::contentNotNull()
 
 DataArrayInt *MEDFileIntField1TS::getUndergroundDataArray() const
 {
-  return contentNotNull()->getUndergroundDataArrayInt();
+  return contentNotNull()->getUndergroundDataArrayTemplate();
 }
 
 //= MEDFileAnyTypeFieldMultiTSWithoutSDA
@@ -7489,6 +7415,8 @@ void MEDFileAnyTypeFieldMultiTSWithoutSDA::pushBackTimeStep(MCAuto<MEDFileAnyTyp
       setInfo(tse2->getInfo());
     }
   checkThatComponentsMatch(tse2->getInfo());
+  if(getDtUnit().empty() && !tse->getDtUnit().empty())
+    setDtUnit(tse->getDtUnit());
   _time_steps.push_back(tse);
 }
 
@@ -7540,6 +7468,7 @@ void MEDFileAnyTypeFieldMultiTSWithoutSDA::loadStructureOrStructureAndBigArraysR
         _time_steps[i]->loadStructureAndBigArraysRecursively(fid,*this,ms,entities);
       else
         _time_steps[i]->loadOnlyStructureOfDataRecursively(fid,*this,ms,entities);
+      synchronizeNameScope();
     }
 }
 
@@ -9094,6 +9023,97 @@ MEDFileAnyTypeFieldMultiTS *MEDFileAnyTypeFieldMultiTS::extractPart(const std::m
   return fmtsOut.retn();
 }
 
+template<class T>
+MCAuto<MEDFileAnyTypeField1TS> AggregateHelperF1TS(const std::vector< typename MLFieldTraits<T>::F1TSType const *>& f1tss, const std::vector< std::vector< std::pair<int,int> > >& dts)
+{
+  MCAuto< typename MLFieldTraits<T>::F1TSType > ret(MLFieldTraits<T>::F1TSType::New());
+  if(f1tss.empty())
+    throw INTERP_KERNEL::Exception("AggregateHelperF1TS : empty vector !");
+  std::size_t sz(f1tss.size()),i(0);
+  std::vector< typename MLFieldTraits<T>::F1TSWSDAType const *> f1tsw(sz);
+  for(typename std::vector< typename MLFieldTraits<T>::F1TSType const *>::const_iterator it=f1tss.begin();it!=f1tss.end();it++,i++)
+    {
+      typename MLFieldTraits<T>::F1TSType const *elt(*it);
+      if(!elt)
+        throw INTERP_KERNEL::Exception("AggregateHelperF1TS : presence of a null pointer !");
+      f1tsw[i]=dynamic_cast<typename MLFieldTraits<T>::F1TSWSDAType const *>(elt->contentNotNullBase());
+    }
+  typename MLFieldTraits<T>::F1TSWSDAType *retc(dynamic_cast<typename MLFieldTraits<T>::F1TSWSDAType *>(ret->contentNotNullBase()));
+  if(!retc)
+    throw INTERP_KERNEL::Exception("AggregateHelperF1TS : internal error 1 !");
+  retc->aggregate(f1tsw,dts);
+  ret->setDtUnit(f1tss[0]->getDtUnit());
+  return DynamicCast<typename MLFieldTraits<T>::F1TSType , MEDFileAnyTypeField1TS>(ret);
+}
+
+template<class T>
+MCAuto< MEDFileAnyTypeFieldMultiTS > AggregateHelperFMTS(const std::vector< typename MLFieldTraits<T>::FMTSType const *>& fmtss, const std::vector< std::vector< std::pair<int,int> > >& dts)
+{
+  MCAuto< typename MLFieldTraits<T>::FMTSType > ret(MLFieldTraits<T>::FMTSType::New());
+  if(fmtss.empty())
+    throw INTERP_KERNEL::Exception("AggregateHelperFMTS : empty vector !");
+  std::size_t sz(fmtss.size());
+  for(typename std::vector< typename MLFieldTraits<T>::FMTSType const *>::const_iterator it=fmtss.begin();it!=fmtss.end();it++)
+    {
+      typename MLFieldTraits<T>::FMTSType const *elt(*it);
+      if(!elt)
+        throw INTERP_KERNEL::Exception("AggregateHelperFMTS : presence of null pointer !");
+    }
+  int nbTS(fmtss[0]->getNumberOfTS());
+  for(typename std::vector< typename MLFieldTraits<T>::FMTSType const *>::const_iterator it=fmtss.begin();it!=fmtss.end();it++)
+    if((*it)->getNumberOfTS()!=nbTS)
+      throw INTERP_KERNEL::Exception("AggregateHelperFMTS : all fields must have the same number of TS !");
+  for(int iterTS=0;iterTS<nbTS;iterTS++)
+    {
+      std::size_t i(0);
+      std::vector< typename MLFieldTraits<T>::F1TSType const *> f1tss(sz);
+      std::vector< MCAuto<typename MLFieldTraits<T>::F1TSType> > f1tss2(sz);
+      for(typename std::vector< typename MLFieldTraits<T>::FMTSType const *>::const_iterator it=fmtss.begin();it!=fmtss.end();it++,i++)
+        { f1tss2[i]=(*it)->getTimeStepAtPos(iterTS); f1tss[i]=f1tss2[i]; }
+      MCAuto<MEDFileAnyTypeField1TS> f1ts(AggregateHelperF1TS<T>(f1tss,dts));
+      ret->pushBackTimeStep(f1ts);
+      ret->setDtUnit(f1ts->getDtUnit());
+    }
+  return DynamicCast<typename MLFieldTraits<T>::FMTSType , MEDFileAnyTypeFieldMultiTS>(ret);
+}
+
+/*!
+ * \a dts and \a ftmss are expected to have same size.
+ */
+MCAuto<MEDFileAnyTypeFieldMultiTS> MEDFileAnyTypeFieldMultiTS::Aggregate(const std::vector<const MEDFileAnyTypeFieldMultiTS *>& fmtss, const std::vector< std::vector< std::pair<int,int> > >& dts)
+{
+  if(fmtss.empty())
+    throw INTERP_KERNEL::Exception("MEDFileAnyTypeFieldMultiTS::Aggregate : input vector is empty !");
+  std::size_t sz(fmtss.size());
+  std::vector<const MEDFileFieldMultiTS *> fmtss1;
+  std::vector<const MEDFileIntFieldMultiTS *> fmtss2;
+  for(std::vector<const MEDFileAnyTypeFieldMultiTS *>::const_iterator it=fmtss.begin();it!=fmtss.end();it++)
+    {
+      if(!(*it))
+        throw INTERP_KERNEL::Exception("MEDFileAnyTypeFieldMultiTS::Aggregate : presence of null instance in input vector !");
+      const MEDFileFieldMultiTS *elt1(dynamic_cast<const MEDFileFieldMultiTS *>(*it));
+      if(elt1)
+        {
+          fmtss1.push_back(elt1);
+          continue;
+        }
+      const MEDFileIntFieldMultiTS *elt2(dynamic_cast<const MEDFileIntFieldMultiTS *>(*it));
+      if(elt2)
+        {
+          fmtss2.push_back(elt2);
+          continue;
+        }
+      throw INTERP_KERNEL::Exception("MEDFileAnyTypeFieldMultiTS::Aggregate : not recognized type !");
+    }
+  if(fmtss1.size()!=sz && fmtss2.size()!=sz)
+    throw INTERP_KERNEL::Exception("MEDFileAnyTypeFieldMultiTS::Aggregate : type of data is not homogeneous !");
+  if(fmtss1.size()==sz)
+    return AggregateHelperFMTS<double>(fmtss1,dts);
+  if(fmtss2.size()!=sz)
+    return AggregateHelperFMTS<int>(fmtss2,dts);
+  throw INTERP_KERNEL::Exception("MEDFileAnyTypeFieldMultiTS::Aggregate : not implemented yet !");
+}
+
 MEDFileAnyTypeFieldMultiTSIterator *MEDFileAnyTypeFieldMultiTS::iterator()
 {
   return new MEDFileAnyTypeFieldMultiTSIterator(this);
@@ -9899,7 +9919,7 @@ DataArrayInt *MEDFileIntFieldMultiTS::getFieldWithProfile(TypeOfField type, int
  *          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
+MEDFileIntField1TS *MEDFileIntFieldMultiTS::getTimeStepAtPos(int pos) const
 {
   const MEDFileAnyTypeField1TSWithoutSDA *item=contentNotNullBase()->getTimeStepAtPos2(pos);
   if(!item)
index a748d0b09acadc86bac281b2896111bcc8379306..d26ae7a69424035616bea54a74201012c650e66f 100644 (file)
@@ -27,6 +27,8 @@
 #include "MEDFileUtilities.hxx"
 
 #include "MCAuto.hxx"
+#include "MEDLoaderTraits.hxx"
+#include "MEDCouplingTraits.hxx"
 #include "MEDCouplingRefCountObject.hxx"
 #include "MEDCouplingFieldInt.hxx"
 #include "MEDCouplingMemArray.hxx"
@@ -127,6 +129,7 @@ namespace MEDCoupling
     int getNumberOfTuples() const;
     int getStart() const { return _start; }
     int getEnd() const { return _end; }
+    int getNumberOfVals() const { return _nval; }
     DataArray *getOrCreateAndGetArray();
     const DataArray *getOrCreateAndGetArray() const;
     const std::vector<std::string>& getInfo() const;
@@ -152,6 +155,8 @@ namespace MEDCoupling
     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 &notInExisting);
+    static MCAuto<MEDFileFieldPerMeshPerTypePerDisc> Aggregate(int &start, const std::vector<std::pair<int,const MEDFileFieldPerMeshPerTypePerDisc *> >& pms, const std::vector< std::vector< std::pair<int,int> > >& dts, TypeOfField tof, MEDFileFieldPerMeshPerType *father, std::vector<std::pair< int, std::pair<int,int> > >& extractInfo);
+    MEDFileFieldPerMeshPerTypePerDisc(MEDFileFieldPerMeshPerType *fath, TypeOfField type):_type(type),_father(fath),_start(-1),_end(-1),_nval(-1),_loc_id(-5),_profile_it(-1) { }
   private:
     MEDFileFieldPerMeshPerTypePerDisc(MEDFileFieldPerMeshPerType *fath, TypeOfField type, int profileIt, const PartDefinition *pd);
     MEDFileFieldPerMeshPerTypePerDisc(MEDFileFieldPerMeshPerType *fath, TypeOfField type, int profileIt, const std::string& dummy);
@@ -216,19 +221,21 @@ namespace MEDCoupling
     void changeLocsRefsNamesGen(const std::vector< std::pair<std::vector<std::string>, std::string > >& mapOfModif);
     MEDFileFieldPerMeshPerTypePerDisc *getLeafGivenLocId(int locId);
     const MEDFileFieldPerMeshPerTypePerDisc *getLeafGivenLocId(int locId) const;
+    int getNumberOfLoc() const { return _field_pm_pt_pd.size(); }
     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< MCAuto< 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);
+    static MCAuto<MEDFileFieldPerMeshPerType> Aggregate(int &start, const std::vector< std::pair<int,const MEDFileFieldPerMeshPerType *> >& pms, const std::vector< std::vector< std::pair<int,int> > >& dts, INTERP_KERNEL::NormalizedCellType gt, MEDFileFieldPerMesh *father, std::vector<std::pair< int, std::pair<int,int> > >& extractInfo);
+    MEDFileFieldPerMeshPerType(MEDFileFieldPerMesh *father, INTERP_KERNEL::NormalizedCellType gt):_father(father),_geo_type(gt) { }
   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< MCAuto<MEDFileFieldPerMeshPerTypePerDisc> > _field_pm_pt_pd;
@@ -284,6 +291,7 @@ namespace MEDCoupling
     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;
+    static MCAuto<MEDFileFieldPerMesh> Aggregate(int &start, const std::vector<const MEDFileFieldPerMesh *>& pms, const std::vector< std::vector< std::pair<int,int> > >& dts, MEDFileAnyTypeField1TSWithoutSDA *father, std::vector<std::pair< int, std::pair<int,int> > >& extractInfo);
   private:
     int addNewEntryIfNecessary(INTERP_KERNEL::NormalizedCellType type);
     MEDCouplingFieldDouble *finishField(TypeOfField type, const MEDFileFieldGlobsReal *glob,
@@ -303,6 +311,7 @@ namespace MEDCoupling
     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);
+    MEDFileFieldPerMesh(MEDFileAnyTypeField1TSWithoutSDA *fath, const std::string& meshName, int meshIt, int meshOrd):_father(fath),_mesh_name(meshName),_mesh_iteration(meshIt),_mesh_order(meshOrd) { }
   private:
     std::string _mesh_name;
     int _mesh_iteration;
@@ -562,16 +571,34 @@ namespace MEDCoupling
 
   class MEDFileIntField1TSWithoutSDA;
 
+  template<class T>
+  class MEDFileField1TSTemplateWithoutSDA : public MEDFileAnyTypeField1TSWithoutSDA
+  {
+  protected:
+    MEDFileField1TSTemplateWithoutSDA(const std::string& fieldName, int csit, int iteration, int order):MEDFileAnyTypeField1TSWithoutSDA(fieldName,csit,iteration,order) { }
+    MEDFileField1TSTemplateWithoutSDA():MEDFileAnyTypeField1TSWithoutSDA() { }
+  public:
+    MEDLOADER_EXPORT void setArray(DataArray *arr);
+    MEDLOADER_EXPORT DataArray *createNewEmptyDataArrayInstance() const;
+    MEDLOADER_EXPORT typename Traits<T>::ArrayType *getOrCreateAndGetArrayTemplate();
+    MEDLOADER_EXPORT typename Traits<T>::ArrayType const *getOrCreateAndGetArrayTemplate() const;
+    MEDLOADER_EXPORT typename Traits<T>::ArrayType *getUndergroundDataArrayTemplate() const;
+    MEDLOADER_EXPORT DataArray *getOrCreateAndGetArray();
+    MEDLOADER_EXPORT const DataArray *getOrCreateAndGetArray() const;
+    MEDLOADER_EXPORT DataArray *getUndergroundDataArray() const;
+    MEDLOADER_EXPORT void aggregate(const typename std::vector< typename MLFieldTraits<T>::F1TSWSDAType const * >& f1tss, const std::vector< std::vector< std::pair<int,int> > >& dts);
+  protected:
+    MCAuto< typename Traits<T>::ArrayType > _arr;
+  };
+
   /*!
    * SDA is for Shared Data Arrays such as profiles.
    */
-  class MEDFileField1TSWithoutSDA : public MEDFileAnyTypeField1TSWithoutSDA
+  class MEDFileField1TSWithoutSDA : public MEDFileField1TSTemplateWithoutSDA<double>
   {
   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);
@@ -582,15 +609,7 @@ namespace MEDCoupling
     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 *deepCopy() 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:
-    MCAuto< DataArrayDouble > _arr;
   public:
     static const char TYPE_STR[];
   };
@@ -598,7 +617,7 @@ namespace MEDCoupling
   /*!
    * SDA is for Shared Data Arrays such as profiles.
    */
-  class MEDFileIntField1TSWithoutSDA : public MEDFileAnyTypeField1TSWithoutSDA
+  class MEDFileIntField1TSWithoutSDA : public MEDFileField1TSTemplateWithoutSDA<int>
   {
   public:
     MEDLOADER_EXPORT MEDFileIntField1TSWithoutSDA();
@@ -606,21 +625,11 @@ namespace MEDCoupling
     MEDLOADER_EXPORT MEDFileAnyTypeField1TSWithoutSDA *deepCopy() 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:
-    MCAuto< DataArrayInt > _arr;
   public:
     MEDLOADER_EXPORT static const char TYPE_STR[];
   };
@@ -1000,6 +1009,7 @@ namespace MEDCoupling
   public:
     MEDLOADER_EXPORT virtual MEDFileAnyTypeFieldMultiTS *buildNewEmpty() const = 0;
     MEDLOADER_EXPORT MEDFileAnyTypeFieldMultiTS *extractPart(const std::map<int, MCAuto<DataArrayInt> >& extractDef, MEDFileMesh *mm) const;
+    MEDLOADER_EXPORT static MCAuto<MEDFileAnyTypeFieldMultiTS> Aggregate(const std::vector<const MEDFileAnyTypeFieldMultiTS *>& fmtss, const std::vector< std::vector< std::pair<int,int> > >& dts);
   public:
     MEDLOADER_EXPORT std::vector<std::string> getPflsReallyUsed() const;
     MEDLOADER_EXPORT std::vector<std::string> getLocsReallyUsed() const;
@@ -1076,7 +1086,7 @@ namespace MEDCoupling
     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 MEDFileIntField1TS *getTimeStepAtPos(int pos) const;
     MEDLOADER_EXPORT MEDFileFieldMultiTS *convertToDouble(bool isDeepCpyGlobs=true) const;
     //
     MEDLOADER_EXPORT MEDCouplingFieldInt *field(int iteration, int order, const MEDFileMesh *mesh) const;
diff --git a/src/MEDLoader/MEDFileField.txx b/src/MEDLoader/MEDFileField.txx
new file mode 100644 (file)
index 0000000..ae2b3a9
--- /dev/null
@@ -0,0 +1,172 @@
+// Copyright (C) 2007-2016  CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 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 __MEDFILEFIELD_TXX__
+#define __MEDFILEFIELD_TXX__
+
+#include "MEDFileField.hxx"
+#include "MEDCouplingTraits.hxx"
+
+namespace MEDCoupling
+{
+  template<class T>
+  void MEDFileField1TSTemplateWithoutSDA<T>::setArray(DataArray *arr)
+  {
+    if(!arr)
+      {
+        _nb_of_tuples_to_be_allocated=-1;
+        _arr=0;
+        return ;
+      }
+    typename Traits<T>::ArrayType *arrC=dynamic_cast<typename Traits<T>::ArrayType *>(arr);
+    if(!arrC)
+      throw INTERP_KERNEL::Exception("MEDFileField1TSTemplateWithoutSDA::setArray : the input not null array is not of type DataArrayDouble !");
+    else
+      _nb_of_tuples_to_be_allocated=-3;
+    arrC->incrRef();
+    _arr=arrC;
+  }
+  
+  /*!
+   * Returns a pointer to the underground DataArrayTemplate<T>  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 DataArrayTemplate<T> * - the pointer to the field values array.
+   */
+  template<class T>
+  DataArray *MEDFileField1TSTemplateWithoutSDA<T>::getOrCreateAndGetArray()
+  {
+    return getOrCreateAndGetArrayTemplate();
+  }
+  
+  template<class T>
+  const DataArray *MEDFileField1TSTemplateWithoutSDA<T>::getOrCreateAndGetArray() const
+  {
+    return getOrCreateAndGetArrayTemplate();
+  }
+  
+  template<class T>
+  DataArray *MEDFileField1TSTemplateWithoutSDA<T>::createNewEmptyDataArrayInstance() const
+  {
+    return Traits<T>::ArrayType::New();
+  }
+  
+  template<class T>
+  typename Traits<T>::ArrayType const *MEDFileField1TSTemplateWithoutSDA<T>::getOrCreateAndGetArrayTemplate() const
+  {
+    typename Traits<T>::ArrayType const *ret(_arr);
+    if(ret)
+      return ret;
+    (const_cast< MEDFileField1TSTemplateWithoutSDA<T> *>(this))->_arr=Traits<T>::ArrayType::New();
+    return _arr;
+  }
+  
+  template<class T>
+  typename Traits<T>::ArrayType *MEDFileField1TSTemplateWithoutSDA<T>::getOrCreateAndGetArrayTemplate()
+  {
+    typename Traits<T>::ArrayType *ret(_arr);
+    if(ret)
+      return ret;
+    _arr=Traits<T>::ArrayType::New();
+    return _arr;
+  }
+
+  /*!
+   * Returns a pointer to the underground DataArrayTemplate<T> 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 DataArrayTemplate<T> * - the pointer to the field values array.
+   */
+  template<class T>
+  typename Traits<T>::ArrayType *MEDFileField1TSTemplateWithoutSDA<T>::getUndergroundDataArrayTemplate() const
+  {
+    typename Traits<T>::ArrayType const *ret(_arr);
+    if(ret)
+      return const_cast<typename Traits<T>::ArrayType *>(ret);
+    else
+      return 0;
+  }
+  
+  /*!
+   * 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.
+   */
+  template<class T>
+  DataArray *MEDFileField1TSTemplateWithoutSDA<T>::getUndergroundDataArray() const
+  {
+    return getUndergroundDataArrayTemplate();
+  }
+  
+  template<class T>
+  void MEDFileField1TSTemplateWithoutSDA<T>::aggregate(const std::vector<typename MLFieldTraits<T>::F1TSWSDAType const *>& f1tss, const std::vector< std::vector< std::pair<int,int> > >& dts)
+  {
+    if(f1tss.empty())
+      throw INTERP_KERNEL::Exception("MEDFileField1TSTemplateWithoutSDA::aggregate : empty vector !");
+    std::size_t sz(f1tss.size()),ii(0);
+    std::vector<const MEDFileFieldPerMesh *> pms;
+    std::vector<const DataArray *> das(sz);
+    for(typename std::vector<typename MLFieldTraits<T>::F1TSWSDAType const *>::const_iterator it=f1tss.begin();it!=f1tss.end();it++,ii++)
+      {
+        if(!*it)
+          throw INTERP_KERNEL::Exception("MEDFileField1TSTemplateWithoutSDA::aggregate : presence of null pointer in input vector !");
+        if((*it)->_field_per_mesh.empty())
+          throw INTERP_KERNEL::Exception("MEDFileField1TSTemplateWithoutSDA::aggregate : no info !");
+        const typename Traits<T>::ArrayType *arr((*it)->getUndergroundDataArrayTemplate());
+        if(!arr)
+          throw INTERP_KERNEL::Exception("MEDFileField1TSTemplateWithoutSDA::aggregate : presence of null array !");
+        das[ii]=arr;
+        pms.push_back((*it)->_field_per_mesh[0]);
+      }
+    typename MLFieldTraits<T>::F1TSWSDAType const *refPt(f1tss[0]);
+    setName(refPt->getName());
+    
+    const DataArray *arr(refPt->getUndergroundDataArray());
+    int nbCompo(arr->getNumberOfComponents());
+    for(typename std::vector<typename MLFieldTraits<T>::F1TSWSDAType const *>::const_iterator it=f1tss.begin();it!=f1tss.end();it++)
+      {
+        const typename Traits<T>::ArrayType *myArr((*it)->getUndergroundDataArrayTemplate());
+        if(myArr->getNumberOfComponents()!=nbCompo)
+          throw INTERP_KERNEL::Exception("MEDFileField1TSTemplateWithoutSDA::aggregate : arrays must have same number of components !");
+      }
+    std::vector<std::pair< int, std::pair<int,int> > > extractInfo;
+    int start(0);
+    MCAuto<MEDFileFieldPerMesh> fpm(MEDFileFieldPerMesh::Aggregate(start,pms,dts,this,extractInfo));
+    _field_per_mesh.push_back(fpm);
+    int iteration,order;
+    double tv(f1tss[0]->getTime(iteration,order));
+    _iteration=iteration; _order=order; _dt=tv;
+    _arr=Traits<T>::ArrayType::New();
+    _arr->alloc(start,nbCompo); _arr->copyStringInfoFrom(*arr);
+    start=0;
+    for(std::vector<std::pair< int, std::pair<int,int> > >::const_iterator it=extractInfo.begin();it!=extractInfo.end();it++)
+      {
+        const DataArray *zeArr(das[(*it).first]);
+        _arr->setContigPartOfSelectedValuesSlice(start,zeArr,(*it).second.first,(*it).second.second,1);
+        start+=(*it).second.second-(*it).second.first;
+      }
+  }
+}
+
+#endif
index d187a455e0e1e851d19a5a9a542a37b1fd76b94b..0332e42d6eb037c6a2a3751c8685a9f0289612a8 100644 (file)
@@ -2090,6 +2090,9 @@ std::vector<INTERP_KERNEL::NormalizedCellType> MEDFileMesh::getAllGeoTypes() con
   return ret;
 }
 
+/*!
+ * \sa getAllDistributionOfTypes
+ */
 std::vector<int> MEDFileMesh::getDistributionOfTypes(int meshDimRelToMax) const
 {
   MCAuto<MEDCouplingMesh> mLev(getMeshAtLevel(meshDimRelToMax));
@@ -2335,7 +2338,7 @@ std::vector<const BigMemoryObject *> MEDFileUMesh::getDirectChildrenWithNull() c
   return ret;
 }
 
-MEDFileMesh *MEDFileUMesh::shallowCpy() const
+MEDFileUMesh *MEDFileUMesh::shallowCpy() const
 {
   MCAuto<MEDFileUMesh> ret(new MEDFileUMesh(*this));
   return ret.retn();
@@ -2346,7 +2349,7 @@ MEDFileMesh *MEDFileUMesh::createNewEmpty() const
   return new MEDFileUMesh;
 }
 
-MEDFileMesh *MEDFileUMesh::deepCopy() const
+MEDFileUMesh *MEDFileUMesh::deepCopy() const
 {
   MCAuto<MEDFileUMesh> ret(new MEDFileUMesh(*this));
   ret->deepCpyEquivalences(*this);
@@ -3588,6 +3591,30 @@ MEDCoupling1GTUMesh *MEDFileUMesh::getDirectUndergroundSingleGeoTypeMesh(INTERP_
   return sp->getDirectUndergroundSingleGeoTypeMesh(gt);
 }
 
+/*!
+ * This method returns for each geo types in \a this number of cells with this geo type.
+ * This method returns info as a vector of pair. The first element of pair is geo type and the second the number of cells associated.
+ * This method also returns the number of nodes of \a this (key associated is NORM_ERROR)
+ *
+ * \sa getDistributionOfTypes
+ */
+std::vector< std::pair<int,int> > MEDFileUMesh::getAllDistributionOfTypes() const
+{
+  std::vector< std::pair<int,int> > ret;
+  std::vector<int> nel(getNonEmptyLevels());
+  for(std::vector<int>::reverse_iterator it=nel.rbegin();it!=nel.rend();it++)
+    {
+      std::vector<INTERP_KERNEL::NormalizedCellType> gt(getGeoTypesAtLevel(*it));
+      for(std::vector<INTERP_KERNEL::NormalizedCellType>::const_iterator it1=gt.begin();it1!=gt.end();it1++)
+        {
+          int nbCells(getNumberOfCellsWithType(*it1));
+          ret.push_back(std::pair<int,int>(*it1,nbCells));
+        }
+    }
+  ret.push_back(std::pair<int,int>(INTERP_KERNEL::NORM_ERROR,getNumberOfNodes()));
+  return ret;
+}
+
 /*!
  * 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.
@@ -3703,12 +3730,42 @@ void MEDFileUMesh::setCoords(DataArrayDouble *coords)
   if(coords==(DataArrayDouble *)_coords)
     return ;
   coords->checkAllocated();
-  int nbOfTuples=coords->getNumberOfTuples();
+  int nbOfTuples(coords->getNumberOfTuples());
   _coords=coords;
   coords->incrRef();
   _fam_coords=DataArrayInt::New();
   _fam_coords->alloc(nbOfTuples,1);
   _fam_coords->fillWithZero();
+  _num_coords=0; _rev_num_coords=0; _name_coords=0;
+  for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
+    if((MEDFileUMeshSplitL1 *)(*it))
+      (*it)->setCoords(coords);
+}
+
+/*!
+ * Change coords without changing anything concerning families and numbering on nodes.
+ */
+void MEDFileUMesh::setCoordsForced(DataArrayDouble *coords)
+{
+  if(!coords)
+    throw INTERP_KERNEL::Exception("MEDFileUMesh::setCoordsForced : null pointer in input !");
+  if(coords==(DataArrayDouble *)_coords)
+    return ;
+  coords->checkAllocated();
+  int nbOfTuples(coords->getNumberOfTuples());
+  if(_coords.isNull())
+    {
+      _coords=coords;
+      coords->incrRef();
+    }
+  else
+    {
+      int oldNbTuples(_coords->getNumberOfTuples());
+      if(oldNbTuples!=nbOfTuples)
+        throw INTERP_KERNEL::Exception("MEDFileUMesh::setCoordsForced : number of tuples is not the same -> invoke setCoords instead !");
+      _coords=coords;
+      coords->incrRef();
+    }
   for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
     if((MEDFileUMeshSplitL1 *)(*it))
       (*it)->setCoords(coords);
@@ -4453,6 +4510,120 @@ MEDFileUMesh *MEDFileUMesh::quadraticToLinear(double eps) const
   return ret.retn();
 }
 
+/*!
+ * Computes the symmetry of \a this.
+ * \return a new object.
+ */
+MCAuto<MEDFileUMesh> MEDFileUMesh::symmetry3DPlane(const double point[3], const double normalVector[3]) const
+{
+  MCAuto<MEDFileUMesh> ret(deepCopy());
+  DataArrayDouble *myCoo(getCoords());
+  if(myCoo)
+    {
+      MCAuto<DataArrayDouble> newCoo(myCoo->symmetry3DPlane(point,normalVector));
+      ret->setCoordsForced(newCoo);
+    }
+  return ret;
+}
+
+MCAuto<MEDFileUMesh> MEDFileUMesh::Aggregate(const std::vector<const MEDFileUMesh *>& meshes)
+{
+  if(meshes.empty())
+    throw INTERP_KERNEL::Exception("MEDFileUMesh::Aggregate : empty input vector !");
+  std::size_t sz(meshes.size()),i(0);
+  std::vector<const DataArrayDouble *> coos(sz);
+  std::vector<const DataArrayInt *> fam_coos(sz),num_coos(sz);
+  for(std::vector<const MEDFileUMesh *>::const_iterator it=meshes.begin();it!=meshes.end();it++,i++)
+    {
+      if(!(*it))
+        throw INTERP_KERNEL::Exception("MEDFileUMesh::Aggregate : presence of NULL pointer in input vector !");
+      coos[i]=(*it)->getCoords();
+      fam_coos[i]=(*it)->getFamilyFieldAtLevel(1);
+      num_coos[i]=(*it)->getNumberFieldAtLevel(1);
+    }
+  const MEDFileUMesh *ref(meshes[0]);
+  int spaceDim(ref->getSpaceDimension()),meshDim(ref->getMeshDimension());
+  std::vector<int> levs(ref->getNonEmptyLevels());
+  std::map<int, std::vector<const DataArrayInt *> > m_fam,m_renum;
+  std::map<int, std::vector< MCAuto< MEDCouplingUMesh > > > m_mesh2;
+  std::map<int, std::vector<const MEDCouplingUMesh *> > m_mesh;
+  std::map<std::string,int> map1;
+  std::map<std::string, std::vector<std::string> > map2;
+  for(std::vector<const MEDFileUMesh *>::const_iterator it=meshes.begin();it!=meshes.end();it++,i++)
+    {
+      if((*it)->getSpaceDimension()!=spaceDim)
+        throw INTERP_KERNEL::Exception("MEDFileUMesh::Aggregate : space dimension must be homogeneous !");
+      if((*it)->getMeshDimension()!=meshDim)
+        throw INTERP_KERNEL::Exception("MEDFileUMesh::Aggregate : mesh dimension must be homogeneous !");
+      if((*it)->getNonEmptyLevels()!=levs)
+        throw INTERP_KERNEL::Exception("MEDFileUMesh::Aggregate : levels must be the same for elements in input vector !");
+      for(std::vector<int>::const_iterator it2=levs.begin();it2!=levs.end();it2++)
+        {
+          MCAuto<MEDCouplingUMesh> locMesh((*it)->getMeshAtLevel(*it2));
+          m_mesh[*it2].push_back(locMesh); m_mesh2[*it2].push_back(locMesh);
+          m_fam[*it2].push_back((*it)->getFamilyFieldAtLevel(*it2));
+          m_renum[*it2].push_back((*it)->getNumberFieldAtLevel(*it2));
+        }
+      const std::map<std::string,int>& locMap1((*it)->getFamilyInfo());
+      for(std::map<std::string,int>::const_iterator it3=locMap1.begin();it3!=locMap1.end();it3++)
+        map1[(*it3).first]=(*it3).second;
+      const std::map<std::string, std::vector<std::string> >& locMap2((*it)->getGroupInfo());
+      for(std::map<std::string, std::vector<std::string> >::const_iterator it4=locMap2.begin();it4!=locMap2.end();it4++)
+        map2[(*it4).first]=(*it4).second;
+    }
+  // Easy part : nodes
+  MCAuto<MEDFileUMesh> ret(MEDFileUMesh::New());
+  MCAuto<DataArrayDouble> coo(DataArrayDouble::Aggregate(coos));
+  ret->setCoords(coo);
+  if(std::find(fam_coos.begin(),fam_coos.end(),(const DataArrayInt *)0)==fam_coos.end())
+    {
+      MCAuto<DataArrayInt> fam_coo(DataArrayInt::Aggregate(fam_coos));
+      ret->setFamilyFieldArr(1,fam_coo);
+    }
+  if(std::find(num_coos.begin(),num_coos.end(),(const DataArrayInt *)0)==num_coos.end())
+    {
+      MCAuto<DataArrayInt> num_coo(DataArrayInt::Aggregate(num_coos));
+      ret->setRenumFieldArr(1,num_coo);
+    }
+  // cells
+  for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
+    {
+      std::map<int, std::vector<const MEDCouplingUMesh *> >::const_iterator it2(m_mesh.find(*it));
+      if(it2==m_mesh.end())
+        throw INTERP_KERNEL::Exception("MEDFileUMesh::Aggregate : internal error 1 !");
+      MCAuto<MEDCouplingUMesh> mesh(MEDCouplingUMesh::MergeUMeshes((*it2).second));
+      mesh->setCoords(coo); mesh->setName(ref->getName());
+      MCAuto<DataArrayInt> renum(mesh->sortCellsInMEDFileFrmt());
+      ret->setMeshAtLevel(*it,mesh);
+      std::map<int, std::vector<const DataArrayInt *> >::const_iterator it3(m_fam.find(*it)),it4(m_renum.find(*it));
+      if(it3!=m_fam.end())
+        {
+          const std::vector<const DataArrayInt *>& fams((*it3).second);
+          if(std::find(fams.begin(),fams.end(),(const DataArrayInt *)0)==fams.end())
+            {
+              MCAuto<DataArrayInt> famm(DataArrayInt::Aggregate(fams));
+              famm->renumberInPlace(renum->begin());
+              ret->setFamilyFieldArr(*it,famm);
+            }
+        }
+      if(it4!=m_renum.end())
+        {
+          const std::vector<const DataArrayInt *>& renums((*it4).second);
+          if(std::find(renums.begin(),renums.end(),(const DataArrayInt *)0)==renums.end())
+            {
+              MCAuto<DataArrayInt> renumm(DataArrayInt::Aggregate(renums));
+              renumm->renumberInPlace(renum->begin());
+              ret->setRenumFieldArr(*it,renumm);
+            }
+        }
+    }
+  //
+  ret->setFamilyInfo(map1);
+  ret->setGroupInfo(map2);
+  ret->setName(ref->getName());
+  return ret;
+}
+
 void MEDFileUMesh::serialize(std::vector<double>& tinyDouble, std::vector<int>& tinyInt, std::vector<std::string>& tinyStr, std::vector< MCAuto<DataArrayInt> >& bigArraysI, MCAuto<DataArrayDouble>& bigArrayD)
 {
   clearNonDiscrAttributes();
@@ -6305,7 +6476,7 @@ std::string MEDFileCMesh::advancedRepr() const
   return simpleRepr();
 }
 
-MEDFileMesh *MEDFileCMesh::shallowCpy() const
+MEDFileCMesh *MEDFileCMesh::shallowCpy() const
 {
   MCAuto<MEDFileCMesh> ret(new MEDFileCMesh(*this));
   return ret.retn();
@@ -6316,7 +6487,7 @@ MEDFileMesh *MEDFileCMesh::createNewEmpty() const
   return new MEDFileCMesh;
 }
 
-MEDFileMesh *MEDFileCMesh::deepCopy() const
+MEDFileCMesh *MEDFileCMesh::deepCopy() const
 {
   MCAuto<MEDFileCMesh> ret(new MEDFileCMesh(*this));
   ret->deepCpyEquivalences(*this);
@@ -6547,7 +6718,7 @@ std::vector<const BigMemoryObject *> MEDFileCurveLinearMesh::getDirectChildrenWi
   return ret;
 }
 
-MEDFileMesh *MEDFileCurveLinearMesh::shallowCpy() const
+MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::shallowCpy() const
 {
   MCAuto<MEDFileCurveLinearMesh> ret(new MEDFileCurveLinearMesh(*this));
   return ret.retn();
@@ -6558,7 +6729,7 @@ MEDFileMesh *MEDFileCurveLinearMesh::createNewEmpty() const
   return new MEDFileCurveLinearMesh;
 }
 
-MEDFileMesh *MEDFileCurveLinearMesh::deepCopy() const
+MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::deepCopy() const
 {
   MCAuto<MEDFileCurveLinearMesh> ret(new MEDFileCurveLinearMesh(*this));
   ret->deepCpyEquivalences(*this);
index 9f0231313ad906583b759bdf525a90b537b5f9e8..1e0f48bb2cb855431ca99f80bc00a7b91dba18ef 100644 (file)
@@ -252,8 +252,8 @@ namespace MEDCoupling
     MEDLOADER_EXPORT std::size_t getHeapMemorySizeWithoutChildren() const;
     MEDLOADER_EXPORT std::vector<const BigMemoryObject *> getDirectChildrenWithNull() const;
     MEDLOADER_EXPORT MEDFileMesh *createNewEmpty() const;
-    MEDLOADER_EXPORT MEDFileMesh *deepCopy() const;
-    MEDLOADER_EXPORT MEDFileMesh *shallowCpy() const;
+    MEDLOADER_EXPORT MEDFileUMesh *deepCopy() const;
+    MEDLOADER_EXPORT MEDFileUMesh *shallowCpy() const;
     MEDLOADER_EXPORT bool isEqual(const MEDFileMesh *other, double eps, std::string& what) const;
     MEDLOADER_EXPORT void checkConsistency() const;
     MEDLOADER_EXPORT void checkSMESHConsistency() const;
@@ -299,6 +299,7 @@ namespace MEDCoupling
     MEDLOADER_EXPORT DataArrayInt *getFamiliesArr(int meshDimRelToMaxExt, const std::vector<std::string>& fams, bool renum=false) const;
     MEDLOADER_EXPORT MEDCouplingUMesh *getMeshAtLevel(int meshDimRelToMax, bool renum=false) const;
     MEDLOADER_EXPORT std::vector<int> getDistributionOfTypes(int meshDimRelToMax) const;
+    MEDLOADER_EXPORT std::vector< std::pair<int,int> > getAllDistributionOfTypes() 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;
@@ -312,6 +313,7 @@ namespace MEDCoupling
     //
     MEDLOADER_EXPORT void setFamilyNameAttachedOnId(int id, const std::string& newFamName);
     MEDLOADER_EXPORT void setCoords(DataArrayDouble *coords);
+    MEDLOADER_EXPORT void setCoordsForced(DataArrayDouble *coords);
     MEDLOADER_EXPORT void eraseGroupsAtLevel(int meshDimRelToMaxExt);
     MEDLOADER_EXPORT void setFamilyFieldArr(int meshDimRelToMaxExt, DataArrayInt *famArr);
     MEDLOADER_EXPORT void setRenumFieldArr(int meshDimRelToMaxExt, DataArrayInt *renumArr);
@@ -334,6 +336,8 @@ namespace MEDCoupling
     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;
+    MEDLOADER_EXPORT MCAuto<MEDFileUMesh> symmetry3DPlane(const double point[3], const double normalVector[3]) const;
+    MEDLOADER_EXPORT static MCAuto<MEDFileUMesh> Aggregate(const std::vector<const MEDFileUMesh *>& meshes);
     // serialization
     MEDLOADER_EXPORT void serialize(std::vector<double>& tinyDouble, std::vector<int>& tinyInt, std::vector<std::string>& tinyStr,
                                     std::vector< MCAuto<DataArrayInt> >& bigArraysI, MCAuto<DataArrayDouble>& bigArrayD);
@@ -447,8 +451,8 @@ namespace MEDCoupling
     MEDLOADER_EXPORT std::size_t getHeapMemorySizeWithoutChildren() const;
     MEDLOADER_EXPORT std::vector<const BigMemoryObject *> getDirectChildrenWithNull() const;
     MEDLOADER_EXPORT MEDFileMesh *createNewEmpty() const;
-    MEDLOADER_EXPORT MEDFileMesh *deepCopy() const;
-    MEDLOADER_EXPORT MEDFileMesh *shallowCpy() const;
+    MEDLOADER_EXPORT MEDFileCMesh *deepCopy() const;
+    MEDLOADER_EXPORT MEDFileCMesh *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;
@@ -480,8 +484,8 @@ namespace MEDCoupling
     MEDLOADER_EXPORT std::size_t getHeapMemorySizeWithoutChildren() const;
     MEDLOADER_EXPORT std::vector<const BigMemoryObject *> getDirectChildrenWithNull() const;
     MEDLOADER_EXPORT MEDFileMesh *createNewEmpty() const;
-    MEDLOADER_EXPORT MEDFileMesh *deepCopy() const;
-    MEDLOADER_EXPORT MEDFileMesh *shallowCpy() const;
+    MEDLOADER_EXPORT MEDFileCurveLinearMesh *deepCopy() const;
+    MEDLOADER_EXPORT MEDFileCurveLinearMesh *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;
diff --git a/src/MEDLoader/MEDLoaderTraits.hxx b/src/MEDLoader/MEDLoaderTraits.hxx
new file mode 100644 (file)
index 0000000..25cdfb3
--- /dev/null
@@ -0,0 +1,58 @@
+// Copyright (C) 2016  CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 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 __MEDLOADERTRAITS_HXX__
+#define __MEDLOADERTRAITS_HXX__
+
+#include "MEDLoaderDefines.hxx"
+
+namespace MEDCoupling
+{
+  template<class T>
+  struct MEDLOADER_EXPORT MLFieldTraits
+  {
+    typedef T EltType;
+  };
+
+  class MEDFileFieldMultiTS;
+  class MEDFileField1TS;
+  class MEDFileIntFieldMultiTS;
+  class MEDFileIntField1TS;
+  class MEDFileField1TSWithoutSDA;
+  class MEDFileIntField1TSWithoutSDA;
+  
+  template<>
+  struct MEDLOADER_EXPORT MLFieldTraits<double>
+  {
+    typedef MEDFileFieldMultiTS FMTSType;
+    typedef MEDFileField1TS F1TSType;
+    typedef MEDFileField1TSWithoutSDA F1TSWSDAType;
+  };
+  
+  template<>
+  struct MEDLOADER_EXPORT MLFieldTraits<int>
+  {
+    typedef MEDFileIntFieldMultiTS FMTSType;
+    typedef MEDFileIntField1TS F1TSType;
+    typedef MEDFileIntField1TSWithoutSDA F1TSWSDAType;
+  };
+}
+
+#endif
index 818147457532b8f2e4a48e6d2a3596a7f9e34677..3a348ebde8ff090e0178ae1fa9b630b90dbbe5c3 100644 (file)
@@ -125,6 +125,8 @@ using namespace MEDCoupling;
 %newobject MEDCoupling::MEDFileUMesh::buildExtrudedMesh;
 %newobject MEDCoupling::MEDFileUMesh::linearToQuadratic;
 %newobject MEDCoupling::MEDFileUMesh::quadraticToLinear;
+%newobject MEDCoupling::MEDFileUMesh::symmetry3DPlane;
+%newobject MEDCoupling::MEDFileUMesh::Aggregate;
 %newobject MEDCoupling::MEDFileCMesh::New;
 %newobject MEDCoupling::MEDFileCurveLinearMesh::New;
 %newobject MEDCoupling::MEDFileMeshMultiTS::New;
@@ -205,6 +207,7 @@ using namespace MEDCoupling;
 %newobject MEDCoupling::MEDFileData::getMeshes;
 %newobject MEDCoupling::MEDFileData::getFields;
 %newobject MEDCoupling::MEDFileData::getParams;
+%newobject MEDCoupling::MEDFileData::Aggregate;
 
 %newobject MEDCoupling::MEDFileParameterDouble1TS::New;
 %newobject MEDCoupling::MEDFileParameterDouble1TS::deepCopy;
@@ -1241,6 +1244,7 @@ namespace MEDCoupling
     //
     void setFamilyNameAttachedOnId(int id, const std::string& newFamName) throw(INTERP_KERNEL::Exception);
     void setCoords(DataArrayDouble *coords) throw(INTERP_KERNEL::Exception);
+    void setCoordsForced(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);
@@ -1394,6 +1398,34 @@ namespace MEDCoupling
            self->removeMeshAtLevel(meshDimRelToMax);
          }
 
+         MEDFileUMesh *symmetry3DPlane(PyObject *point, PyObject *normalVector) const throw(INTERP_KERNEL::Exception)
+         {
+           const char msg[]="Python wrap of MEDFileUMesh::symmetry3DPlane : ";
+           double val,val2;
+           DataArrayDouble *a,*a2;
+           DataArrayDoubleTuple *aa,*aa2;
+           std::vector<double> bb,bb2;
+           int sw;
+           const double *centerPtr(convertObjToPossibleCpp5_Safe(point,sw,val,a,aa,bb,msg,1,3,true));
+           const double *vectorPtr(convertObjToPossibleCpp5_Safe(normalVector,sw,val2,a2,aa2,bb2,msg,1,3,true));
+           MCAuto<MEDFileUMesh> ret(self->symmetry3DPlane(centerPtr,vectorPtr));
+           return ret.retn();
+         }
+
+         static MEDFileUMesh *Aggregate(PyObject *meshes) throw(INTERP_KERNEL::Exception)
+         {
+           std::vector<const MEDFileUMesh *> meshesCpp;
+           convertFromPyObjVectorOfObj<const MEDCoupling::MEDFileUMesh *>(meshes,SWIGTYPE_p_MEDCoupling__MEDFileUMesh,"MEDFileUMesh",meshesCpp);
+           MCAuto<MEDFileUMesh> ret(MEDFileUMesh::Aggregate(meshesCpp));
+           return ret.retn();
+         }
+
+         PyObject *getAllDistributionOfTypes() const throw(INTERP_KERNEL::Exception)
+         {
+           std::vector< std::pair<int,int> > ret(self->getAllDistributionOfTypes());
+           return convertVecPairIntToPy(ret);
+         }
+         
          DataArrayInt *deduceNodeSubPartFromCellSubPart(PyObject *extractDef) const throw(INTERP_KERNEL::Exception)
          {
            std::map<int, MCAuto<DataArrayInt> > extractDefCpp;
@@ -2304,17 +2336,8 @@ namespace MEDCoupling
       
       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;
+        std::vector< std::pair<int,int> > res(self->getIterations());
+        return convertVecPairIntToPy(res);
       }
       
       PyObject *getTimeSteps() const throw(INTERP_KERNEL::Exception)
@@ -3460,6 +3483,14 @@ namespace MEDCoupling
            std::vector< std::pair<std::string,std::string> > modifTab=convertVecPairStStFromPy(li);
            return self->changeMeshNames(modifTab);
          }
+
+         static MEDFileData *Aggregate(PyObject *mfds) throw(INTERP_KERNEL::Exception)
+         {
+           std::vector<const MEDFileData *> mfdsCpp;
+           convertFromPyObjVectorOfObj<const MEDCoupling::MEDFileData *>(mfds,SWIGTYPE_p_MEDCoupling__MEDFileData,"MEDFileData",mfdsCpp);
+           MCAuto<MEDFileData> ret(MEDFileData::Aggregate(mfdsCpp));
+           return ret.retn();
+         }
        }
   };
 
index 9ec3797c1ae5ac888ea0425cb84469e208441d9b..7dc76b2a200a004a2f033fefa259f4e8bd629533 100644 (file)
@@ -5527,6 +5527,222 @@ class MEDLoaderTest3(unittest.TestCase):
             self.assertEqual(fPart.getTime(),list(tt))
             pass
         pass
+
+    def test42(self):
+        """ Testing of MEDFileData::Aggregate and MEDFileUMesh::Aggregate and MEDFileUMesh::getAllDistributionOfType """
+        fname1="Pyfile106_1.med"
+        fname2="Pyfile106_2.med"
+        fname3="Pyfile106_3.med"
+        meshName="mesh"
+        mm1=MEDFileUMesh()
+        da1=DataArrayDouble([1,2,10,3,4,11,5,6,12,7,8,13],4,3) ; da1.setInfoOnComponents(["aa [m]","bbb [kg]","cccc [MW]"])
+        mm1.setCoords(da1)
+        mm1_0=MEDCouplingUMesh(meshName,3) ; mm1_0.allocateCells()
+        mm1_0.setCoords(da1)
+        mm1_0.insertNextCell(NORM_TETRA4,[0,1,2,3])
+        mm1_0.insertNextCell(NORM_TETRA4,[4,5,6,7])
+        mm1_0.insertNextCell(NORM_PENTA6,[8,9,10,11,12,13])
+        mm1_0.insertNextCell(NORM_PENTA6,[14,15,16,17,18,19])
+        mm1_0.insertNextCell(NORM_PENTA6,[20,21,22,23,24,25])
+        mm1[0]=mm1_0
+        mm1.setFamilyFieldArr(0,DataArrayInt([1,2,3,4,5]))
+        mm1.setRenumFieldArr(0,DataArrayInt([11,12,13,14,15]))
+        #
+        mm1_1=MEDCouplingUMesh(meshName,2) ; mm1_1.allocateCells()
+        mm1_1.setCoords(da1)
+        mm1_1.insertNextCell(NORM_TRI3,[0,1,2])
+        mm1_1.insertNextCell(NORM_TRI3,[3,4,5])
+        mm1_1.insertNextCell(NORM_QUAD4,[6,7,8,9])
+        mm1_1.insertNextCell(NORM_QUAD4,[10,11,12,13])
+        mm1_1.insertNextCell(NORM_QUAD4,[14,15,16,17])
+        mm1_1.insertNextCell(NORM_QUAD4,[18,19,20,21])
+        mm1[-1]=mm1_1
+        mm1.setFamilyFieldArr(-1,DataArrayInt([6,7,8,9,10,11]))
+        mm1.setRenumFieldArr(-1,DataArrayInt([16,17,18,19,20,21]))
+        for i in range(1,10):
+            mm1.setFamilyId("F%d"%i,i)
+        mm1.setFamilyId("FAMILLE_ZERO",0)
+        mm1.setFamilyId("H1",100)
+        mm1.setFamiliesOnGroup("myGRP",["F2","F6"])
+        mm1.setFamiliesOnGroup("myGRP1",["F2","F6"])
+        mm1.setFamilyFieldArr(1,DataArrayInt([12,13,14,15]))
+        mm1.setRenumFieldArr(1,DataArrayInt([22,23,24,25]))
+        ##############
+        mm2=MEDFileUMesh()
+        da1=DataArrayDouble([9,10,30,11,12,31,13,14,32,15,16,33,17,18,34],5,3) ; da1.setInfoOnComponents(["aa [m]","bbb [kg]","cccc [MW]"])
+        mm2.setCoords(da1)
+        mm2_0=MEDCouplingUMesh(meshName,3) ; mm2_0.allocateCells()
+        mm2_0.setCoords(da1)
+        mm2_0.insertNextCell(NORM_TETRA4,[100,101,102,103])
+        mm2_0.insertNextCell(NORM_TETRA4,[104,105,106,107])
+        mm2_0.insertNextCell(NORM_TETRA4,[108,109,110,111])
+        mm2_0.insertNextCell(NORM_PENTA6,[112,113,114,115,116,117])
+        mm2[0]=mm2_0
+        mm2.setFamilyFieldArr(0,DataArrayInt([40,41,42,43]))
+        mm2.setRenumFieldArr(0,DataArrayInt([50,51,52,53]))
+        #
+        mm2_1=MEDCouplingUMesh(meshName,2) ; mm2_1.allocateCells()
+        mm2_1.setCoords(da1)
+        mm2_1.insertNextCell(NORM_TRI3,[100,101,102])
+        mm2_1.insertNextCell(NORM_TRI3,[103,104,105])
+        mm2_1.insertNextCell(NORM_TRI3,[106,107,108])
+        mm2_1.insertNextCell(NORM_QUAD4,[109,110,111,112])
+        mm2_1.insertNextCell(NORM_QUAD4,[113,114,115,116])
+        mm2_1.insertNextCell(NORM_QUAD4,[117,118,119,120])
+        mm2_1.insertNextCell(NORM_QUAD4,[121,122,123,124])
+        mm2_1.insertNextCell(NORM_QUAD4,[125,126,127,128])
+        mm2[-1]=mm2_1
+        mm2.setFamilyFieldArr(-1,DataArrayInt([200,201,202,203,204,205,206,207]))
+        mm2.setRenumFieldArr(-1,DataArrayInt([300,301,302,303,304,305,306,307]))
+        for i in range(1,12):
+            mm2.setFamilyId("G%d"%i,i+30)
+        mm2.setFamilyId("H1",100)
+        mm2.setFamilyId("FAMILLE_ZERO",0)
+        mm2.setFamiliesOnGroup("myGRP",["G2","G6"])
+        mm2.setFamiliesOnGroup("myGRP2",["G4","G7"])
+        mm2.setFamilyFieldArr(1,DataArrayInt([112,113,114,115,116]))
+        mm2.setRenumFieldArr(1,DataArrayInt([122,123,124,125,126]))
+        #
+        mm=MEDFileUMesh.Aggregate([mm1,mm2])
+        #######
+        def CheckMesh(tester,mm):
+            cooExp=DataArrayDouble([(1,2,10),(3,4,11),(5,6,12),(7,8,13),(9,10,30),(11,12,31),(13,14,32),(15,16,33),(17,18,34)]) ; cooExp.setInfoOnComponents(["aa [m]","bbb [kg]","cccc [MW]"])
+            tester.assertTrue(mm.getCoords().isEqual(cooExp,1e-12))
+            tester.assertTrue(mm[0].getNodalConnectivity().isEqual(DataArrayInt([14,0,1,2,3,14,4,5,6,7,14,104,105,106,107,14,108,109,110,111,14,112,113,114,115,16,8,9,10,11,12,13,16,14,15,16,17,18,19,16,20,21,22,23,24,25,16,116,117,118,119,120,121])))
+            tester.assertTrue(mm[0].getNodalConnectivityIndex().isEqual(DataArrayInt([0,5,10,15,20,25,32,39,46,53])))
+            tester.assertTrue(mm[-1].getNodalConnectivity().isEqual(DataArrayInt([3,0,1,2,3,3,4,5,3,104,105,106,3,107,108,109,3,110,111,112,4,6,7,8,9,4,10,11,12,13,4,14,15,16,17,4,18,19,20,21,4,113,114,115,116,4,117,118,119,120,4,121,122,123,124,4,125,126,127,128,4,129,130,131,132])))
+            tester.assertTrue(mm[-1].getNodalConnectivityIndex().isEqual(DataArrayInt([0,4,8,12,16,20,25,30,35,40,45,50,55,60,65])))
+            tester.assertTrue(mm.getFamilyFieldAtLevel(0).isEqual(DataArrayInt([1,2,40,41,42,3,4,5,43])))
+            tester.assertTrue(mm.getNumberFieldAtLevel(0).isEqual(DataArrayInt([11,12,50,51,52,13,14,15,53])))
+            tester.assertTrue(mm.getFamilyFieldAtLevel(-1).isEqual(DataArrayInt([6,7,200,201,202,8,9,10,11,203,204,205,206,207])))
+            tester.assertTrue(mm.getNumberFieldAtLevel(-1).isEqual(DataArrayInt([16,17,300,301,302,18,19,20,21,303,304,305,306,307])))
+            refFamIds=[("FAMILLE_ZERO",0),('F1',1),('F2',2),('F3',3),('F4',4),('F5',5),('F6',6),('F7',7),('F8',8),('F9',9),('G1',31),('G10',40),('G11',41),('G2',32),('G3',33),('G4',34),('G5',35),('G6',36),('G7',37),('G8',38),('G9',39),("H1",100)]
+            tester.assertEqual(set(mm.getFamiliesNames()),set([elt[0] for elt in refFamIds]))
+            tester.assertEqual(set([mm.getFamilyId(elt) for elt in mm.getFamiliesNames()]),set([elt[1] for elt in refFamIds]))
+            tester.assertEqual(mm.getGroupsNames(),('myGRP','myGRP1','myGRP2'))
+            tester.assertEqual(mm.getAllDistributionOfTypes(),[(NORM_TRI3,5),(NORM_QUAD4,9),(NORM_TETRA4,5),(NORM_PENTA6,4),(NORM_ERROR,9)])
+            pass
+        CheckMesh(self,mm)
+        ##
+        fieldName="zeField"
+        t1=(2.3,3,5)
+        t2=(5.6,7,12)
+        infoc=["dd [W]","eee [kA]"]
+        ##
+        fmts1=MEDFileFieldMultiTS()
+        f1ts1=MEDFileField1TS()
+        f1_1=MEDCouplingFieldDouble(ON_CELLS) ; f1_1.setMesh(mm1[0]) ; f1_1.setName(fieldName)
+        arr1=DataArrayDouble([(10,110),(11,111),(12,112),(13,113),(14,114)])
+        arr1.setInfoOnComponents(infoc)
+        f1_1.setArray(arr1) ; f1_1.setTime(*t1) ; f1_1.setTimeUnit("ms")
+        f1_1.checkConsistencyLight()
+        f1ts1.setFieldNoProfileSBT(f1_1)
+        #
+        f1_2=MEDCouplingFieldDouble(ON_CELLS) ; f1_2.setMesh(mm1[-1]) ; f1_2.setName(fieldName)
+        arr2=DataArrayDouble([(15,115),(16,116),(17,117),(18,118),(19,119),(20,120)])
+        arr2.setInfoOnComponents(infoc)
+        f1_2.setArray(arr2) ; f1_2.setTime(*t1) ; f1_2.setTimeUnit("ms")
+        f1_2.checkConsistencyLight()
+        f1ts1.setFieldNoProfileSBT(f1_2)
+        f1_3=MEDCouplingFieldDouble(ON_NODES) ; f1_3.setMesh(mm1[0]) ; f1_3.setName(fieldName)
+        arr3=DataArrayDouble([(21,121),(22,122),(23,123),(24,124)])
+        arr3.setInfoOnComponents(infoc)
+        f1_3.setArray(arr3) ; f1_3.setTime(*t1) ; f1_3.setTimeUnit("ms")
+        f1_3.checkConsistencyLight()
+        f1ts1.setFieldNoProfileSBT(f1_3)
+        fmts1.pushBackTimeStep(f1ts1)
+        #
+        f1ts2=f1ts1.deepCopy()
+        f1ts2.setTime(t2[1],t2[2],t2[0])
+        f1ts2.getUndergroundDataArray()[:]+=2000
+        fmts1.pushBackTimeStep(f1ts2)
+        ### fmts2
+        fmts2=MEDFileFieldMultiTS()
+        f1ts3=MEDFileField1TS()
+        f2_1=MEDCouplingFieldDouble(ON_CELLS) ; f2_1.setMesh(mm2[0]) ; f2_1.setName(fieldName)
+        arr4=DataArrayDouble([(50,150),(51,151),(52,152),(53,153)])
+        arr4.setInfoOnComponents(infoc)
+        f2_1.setArray(arr4) ; f2_1.setTime(*t1) ; f2_1.setTimeUnit("ms")
+        f2_1.checkConsistencyLight()
+        f1ts3.setFieldNoProfileSBT(f2_1)
+        f2_2=MEDCouplingFieldDouble(ON_CELLS) ; f2_2.setMesh(mm2[-1]) ; f2_2.setName(fieldName)
+        arr5=DataArrayDouble([(54,154),(55,155),(56,156),(57,157),(158,158),(59,159),(60,160),(61,161)])
+        arr5.setInfoOnComponents(infoc)
+        f2_2.setArray(arr5) ; f2_2.setTime(*t1) ; f2_2.setTimeUnit("ms")
+        f2_2.checkConsistencyLight()
+        f1ts3.setFieldNoProfileSBT(f2_2)
+        f2_3=MEDCouplingFieldDouble(ON_NODES) ; f2_3.setMesh(mm2[0]) ; f2_3.setName(fieldName)
+        arr6=DataArrayDouble([(62,162),(63,163),(64,164),(65,165),(66,166)])
+        arr6.setInfoOnComponents(infoc)
+        f2_3.setArray(arr6) ; f2_3.setTime(*t1) ; f2_3.setTimeUnit("ms")
+        f2_3.checkConsistencyLight()
+        f1ts3.setFieldNoProfileSBT(f2_3)
+        fmts2.pushBackTimeStep(f1ts3)
+        #
+        f1ts4=f1ts3.deepCopy()
+        f1ts4.setTime(t2[1],t2[2],t2[0])
+        f1ts4.getUndergroundDataArray()[:]+=2000
+        fmts2.pushBackTimeStep(f1ts4)
+        #
+        mfd1=MEDFileData()
+        mfd1.setMeshes(MEDFileMeshes())
+        mfd1.getMeshes().pushMesh(mm1)
+        mfd1.setFields(MEDFileFields())
+        mfd1.getFields().pushField(fmts1)
+        #
+        mfd2=MEDFileData()
+        mfd2.setMeshes(MEDFileMeshes())
+        mfd2.getMeshes().pushMesh(mm2)
+        mfd2.setFields(MEDFileFields())
+        mfd2.getFields().pushField(fmts2)
+        # ze Call !
+        mfd=MEDFileData.Aggregate([mfd1,mfd2])
+        def CheckMFD(tester,mfd):
+            tester.assertEqual(len(mfd.getMeshes()),1)
+            tester.assertEqual(len(mfd.getFields()),1)
+            CheckMesh(self,mfd.getMeshes()[0])
+            tester.assertEqual(len(mfd.getFields()[0]),2)
+            zeF1=mfd.getFields()[0][0]
+            zeF1_1=zeF1.getFieldOnMeshAtLevel(ON_CELLS,0,mfd.getMeshes()[0])
+            ref=MEDCouplingFieldDouble.MergeFields([f1_1,f2_1])
+            o2n=ref.getMesh().deepCopy().sortCellsInMEDFileFrmt()
+            ref.renumberCells(o2n)
+            tester.assertTrue(ref.isEqual(zeF1_1,1e-12,1e-12))
+            zeF1_2=zeF1.getFieldOnMeshAtLevel(ON_CELLS,-1,mfd.getMeshes()[0])
+            ref=MEDCouplingFieldDouble.MergeFields([f1_2,f2_2])
+            o2n=ref.getMesh().deepCopy().sortCellsInMEDFileFrmt()
+            ref.renumberCells(o2n)
+            tester.assertTrue(ref.isEqual(zeF1_2,1e-12,1e-12))
+            zeF1_3=zeF1.getFieldOnMeshAtLevel(ON_NODES,0,mfd.getMeshes()[0])
+            ref=MEDCouplingFieldDouble.MergeFields([f1_3,f2_3])
+            o2n=ref.getMesh().deepCopy().sortCellsInMEDFileFrmt()
+            ref.renumberCells(o2n)
+            tester.assertTrue(ref.isEqual(zeF1_3,1e-12,1e-12))
+            #
+            zeF2=mfd.getFields()[0][1]
+            zeF2_1=zeF2.getFieldOnMeshAtLevel(ON_CELLS,0,mfd.getMeshes()[0])
+            ref=MEDCouplingFieldDouble.MergeFields([f1_1,f2_1])
+            o2n=ref.getMesh().deepCopy().sortCellsInMEDFileFrmt()
+            ref.renumberCells(o2n)
+            ref.setTime(*t2) ; ref.getArray()[:]+=2000
+            tester.assertTrue(ref.isEqual(zeF2_1,1e-12,1e-12))
+            zeF2_2=zeF2.getFieldOnMeshAtLevel(ON_CELLS,-1,mfd.getMeshes()[0])
+            ref=MEDCouplingFieldDouble.MergeFields([f1_2,f2_2])
+            o2n=ref.getMesh().deepCopy().sortCellsInMEDFileFrmt()
+            ref.renumberCells(o2n)
+            ref.setTime(*t2) ; ref.getArray()[:]+=2000
+            tester.assertTrue(ref.isEqual(zeF2_2,1e-12,1e-12))
+            zeF2_3=zeF2.getFieldOnMeshAtLevel(ON_NODES,0,mfd.getMeshes()[0])
+            ref=MEDCouplingFieldDouble.MergeFields([f1_3,f2_3])
+            o2n=ref.getMesh().deepCopy().sortCellsInMEDFileFrmt()
+            ref.renumberCells(o2n)
+            ref.setTime(*t2) ; ref.getArray()[:]+=2000
+            tester.assertTrue(ref.isEqual(zeF2_3,1e-12,1e-12))
+        CheckMFD(self,mfd)
+        mfd1.write(fname1,2) ; mfd2.write(fname2,2)
+        mfd=MEDFileData.Aggregate([MEDFileData(fname1),MEDFileData(fname2)])
+        CheckMFD(self,mfd)
+        pass
     
     pass
 
index 6c0fb4ae715bd1a580bede60f496b64f4f9ca7b9..9df1cb801a82838371eeb58baf06ea15a9cdad2a 100644 (file)
@@ -197,6 +197,20 @@ static PyObject *convertFieldDoubleVecToPy(const std::vector<MEDCoupling::MEDCou
   return ret;
 }
 
+PyObject *convertVecPairIntToPy(const std::vector< std::pair<int,int> >& vec)
+{
+  PyObject *ret(PyList_New(vec.size()));
+  int rk=0;
+  for(std::vector< std::pair<int,int> >::const_iterator iter=vec.begin();iter!=vec.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 *convertVecPairVecStToPy(const std::vector< std::pair<std::vector<std::string>, std::string > >& vec)
 {
   int sz=(int)vec.size();