]> SALOME platform Git repositories - tools/medcoupling.git/commitdiff
Salome HOME
Implemenatation of MEDFileFields::linearToQuadratic + Remapper is now dealing with...
authorAnthony Geay <anthony.geay@edf.fr>
Tue, 2 Jan 2018 15:32:59 +0000 (16:32 +0100)
committerAnthony Geay <anthony.geay@edf.fr>
Thu, 4 Jan 2018 12:41:53 +0000 (13:41 +0100)
29 files changed:
src/INTERP_KERNEL/Bases/InterpKernelAssert.hxx [new file with mode: 0644]
src/INTERP_KERNEL/BoundingBox.cxx
src/INTERP_KERNEL/BoundingBox.hxx
src/INTERP_KERNEL/CMakeLists.txt
src/INTERP_KERNEL/Interpolation1D0D.cxx [new file with mode: 0644]
src/INTERP_KERNEL/Interpolation1D0D.hxx [new file with mode: 0644]
src/INTERP_KERNEL/Interpolation1D0D.txx [new file with mode: 0644]
src/INTERP_KERNEL/InterpolationUtils.hxx
src/INTERP_KERNEL/MeshElement.txx
src/MEDCoupling/MEDCouplingMemArray.cxx
src/MEDCoupling/MEDCouplingNormalizedUnstructuredMesh.txx
src/MEDCoupling/MEDCouplingRefCountObject.cxx
src/MEDCoupling/MEDCouplingRefCountObject.hxx
src/MEDCoupling/MEDCouplingRemapper.cxx
src/MEDCoupling/Test/MEDCouplingBasicsTestInterp.cxx
src/MEDCoupling_Swig/MEDCouplingRefCountObject.i
src/MEDCoupling_Swig/MEDCouplingRemapperTest.py
src/MEDLoader/MEDFileField.cxx
src/MEDLoader/MEDFileField.hxx
src/MEDLoader/MEDFileField.txx
src/MEDLoader/MEDFileField1TS.hxx
src/MEDLoader/MEDFileFieldGlobs.cxx
src/MEDLoader/MEDFileFieldInternal.cxx
src/MEDLoader/MEDFileFieldInternal.hxx
src/MEDLoader/MEDFileFieldVisitor.hxx
src/MEDLoader/Swig/MEDLoaderCommon.i
src/MEDLoader/Swig/MEDLoaderTest3.py
src/PyWrapping/TestPyWrapGathered_medcoupling.py
src/PyWrapping/medcoupling_pycode

diff --git a/src/INTERP_KERNEL/Bases/InterpKernelAssert.hxx b/src/INTERP_KERNEL/Bases/InterpKernelAssert.hxx
new file mode 100644 (file)
index 0000000..51daf42
--- /dev/null
@@ -0,0 +1,34 @@
+// Copyright (C) 2018  CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 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 __INTERPKERNELASSERT_HXX__
+#define __INTERPKERNELASSERT_HXX__
+
+#include "InterpKernelException.hxx"
+
+#include <sstream>
+
+#define IKAssert(a) { bool verdict(a);           \
+    if(!verdict) { std::ostringstream osszz; osszz << "Assertion \"" << #a << "\" failed into " << __FILE__ << " at line " << __LINE__ << " !"; throw INTERP_KERNEL::Exception(osszz.str()); } }
+
+#define IKAssertMsg(a,b) { bool verdict(a);           \
+    if(!verdict) { std::ostringstream osszz; osszz << "Assertion \"" << #a << "\" failed into " << __FILE__ << " at line " << __LINE__ << " with message \"" << b << "\" !"; throw INTERP_KERNEL::Exception(osszz.str()); } }
+
+#endif
index f8c640b25af90009965745d7fb120c6bdd76821c..b20ca410064ad655a57070fe5adfcf6c3dd776b4 100644 (file)
@@ -162,4 +162,14 @@ namespace INTERP_KERNEL
     return valid;
   }
 
+  void BoundingBox::toCompactData(double data[6]) const
+  {
+    data[0]=_coords[XMIN];
+    data[1]=_coords[XMAX];
+    data[2]=_coords[YMIN];
+    data[3]=_coords[YMAX];
+    data[4]=_coords[ZMIN];
+    data[5]=_coords[ZMAX];
+  }
+
 }
index f64da9a2ca41e78a943aaf1bb5f6285ee5f5985f..450e4bcf90d5c49e70106d05824f8e246bfa49c7 100644 (file)
@@ -53,6 +53,8 @@ namespace INTERP_KERNEL
 
     inline void dumpCoords() const;
 
+    void toCompactData(double data[6]) const;
+
   private:
     
     bool isValid() const;
index 7fe1bd1163a4b5b1a21a21c560a6bf4379271e6b..159c4edef06acf9b3bda933ff6ebf646c7e66885 100644 (file)
@@ -37,6 +37,7 @@ SET(interpkernel_SOURCES
   Interpolation3D.cxx
   Interpolation2D3D.cxx
   Interpolation3D1D.cxx
+  Interpolation1D0D.cxx
   MeshElement.cxx
   InterpKernelMeshQuality.cxx
   InterpKernelCellSimplify.cxx
diff --git a/src/INTERP_KERNEL/Interpolation1D0D.cxx b/src/INTERP_KERNEL/Interpolation1D0D.cxx
new file mode 100644 (file)
index 0000000..1e7862c
--- /dev/null
@@ -0,0 +1,57 @@
+// Copyright (C) 2018  CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+// Author : Anthony GEAY (EDF R&D)
+
+#include "Interpolation1D0D.hxx"
+#include "Interpolation1D0D.txx"
+
+namespace INTERP_KERNEL
+{
+  /**
+   * \class Interpolation1D0D
+   * \brief Class used to calculate the interpolation between a 1D mesh and 0D mesh (in 3D space)
+   * Can be seen as a specialization of Interpolation3D, and allows notably the adjustment of bounind boxes.
+   * 
+   */
+
+  Interpolation1D0D::Interpolation1D0D()
+  {}
+
+  Interpolation1D0D::Interpolation1D0D(const InterpolationOptions& io):Interpolation<Interpolation1D0D>(io)
+  {}
+
+  /**
+   * Inspired from PlanarIntersector<MyMeshType,MyMatrix>::adjustBoundingBoxes
+   */
+  void Interpolation1D0D::adjustBoundingBoxes(std::vector<double>& bbox)
+  {
+    const int SPACE_DIM = 3;
+    const double adj(getPrecision());// here precision is used instead of getBoundingBoxAdjustment and getBoundingBoxAdjustmentAbs because in the context only precision is relevant
+
+    long size = bbox.size()/(2*SPACE_DIM);
+    for (int i=0; i<size; i++)
+      {
+        for(int idim=0; idim<SPACE_DIM; idim++)
+          {
+            bbox[i*2*SPACE_DIM+2*idim  ] -= adj;
+            bbox[i*2*SPACE_DIM+2*idim+1] += adj;
+          }
+      }
+  }
+}
diff --git a/src/INTERP_KERNEL/Interpolation1D0D.hxx b/src/INTERP_KERNEL/Interpolation1D0D.hxx
new file mode 100644 (file)
index 0000000..5eba49f
--- /dev/null
@@ -0,0 +1,45 @@
+// Copyright (C) 2018  CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+// Author : A Geay (EDF R&D)
+
+#ifndef __INTERPOLATION1D0D_HXX__
+#define __INTERPOLATION1D0D_HXX__
+
+#include "INTERPKERNELDefines.hxx"
+#include "Interpolation.hxx"
+#include "NormalizedUnstructuredMesh.hxx"
+#include "InterpolationOptions.hxx"
+
+#include <vector>
+
+namespace INTERP_KERNEL
+{
+  class INTERPKERNEL_EXPORT Interpolation1D0D : public Interpolation<Interpolation1D0D>
+  {
+  public:
+    Interpolation1D0D();
+    Interpolation1D0D(const InterpolationOptions& io);
+    template<class MyMeshType, class MatrixType>
+    int interpolateMeshes(const MyMeshType& srcMesh, const MyMeshType& targetMesh, MatrixType& result, const std::string& method);
+  private:
+    void adjustBoundingBoxes(std::vector<double>& bbox);
+  };
+}
+
+#endif
diff --git a/src/INTERP_KERNEL/Interpolation1D0D.txx b/src/INTERP_KERNEL/Interpolation1D0D.txx
new file mode 100644 (file)
index 0000000..7c62140
--- /dev/null
@@ -0,0 +1,123 @@
+// Copyright (C) 2018  CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 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 __INTERPOLATION1D0D_TXX__
+#define __INTERPOLATION1D0D_TXX__
+
+#include "Interpolation1D0D.hxx"
+#include "Interpolation.txx"
+#include "MeshElement.txx"
+#include "PointLocator3DIntersectorP0P0.txx"
+#include "PointLocator3DIntersectorP0P1.txx"
+#include "PointLocator3DIntersectorP1P0.txx"
+#include "PointLocator3DIntersectorP1P1.txx"
+#include "Log.hxx"
+
+#include "BBTree.txx"
+
+#include "InterpKernelAssert.hxx"
+
+namespace INTERP_KERNEL
+{
+  /**
+   *  Very similar to Interpolation3D::interpolateMeshes, except for the bounding boxes that can be
+   *  adjusted in a similar fashion as in InterpolationPlanar::performAdjustmentOfBB()
+   **/
+  template<class MyMeshType, class MatrixType>
+  int Interpolation1D0D::interpolateMeshes(const MyMeshType& srcMesh, const MyMeshType& targetMesh, MatrixType& result, const std::string& method)
+  {
+#if __cplusplus >= 201103L
+    constexpr int SPACEDIM=MyMeshType::MY_SPACEDIM;
+    using ConnType=typename MyMeshType::MyConnType;
+    IKAssert(SPACEDIM==3);
+
+    if(InterpolationOptions::getIntersectionType() != PointLocator)
+      INTERP_KERNEL::Exception("Invalid 1D/0D intersection type specified : must be PointLocator.");
+
+    std::string methC ( InterpolationOptions::filterInterpolationMethod(method) );
+    if(methC!="P1P1")
+      throw Exception("Invalid method chosen must be in \"P1P1\".");
+
+    const double epsilon(getPrecision());
+    // create MeshElement objects corresponding to each element of the two meshes
+    const unsigned long numSrcElems(srcMesh.getNumberOfElements()), numTargetElems(targetMesh.getNumberOfElements());
+
+    LOG(2, "Source mesh has " << numSrcElems << " elements and target mesh has " << numTargetElems << " elements ");
+
+    std::vector<MeshElement<ConnType>*> srcElems(numSrcElems);
+
+    std::map<MeshElement<ConnType>*, int> indices;
+
+    for(unsigned long i = 0 ; i < numSrcElems ; ++i)
+      srcElems[i] = new MeshElement<ConnType>(i, srcMesh);       
+
+    // create empty maps for all source elements
+    result.resize(targetMesh.getNumberOfNodes());
+
+    // create BBTree structure
+    // - get bounding boxes
+    std::vector<double> bboxes(2*SPACEDIM*numSrcElems);
+    int* srcElemIdx = new int[numSrcElems];
+    for(unsigned long i = 0; i < numSrcElems ; ++i)
+      {
+        // get source bboxes in right order
+        srcElems[i]->getBoundingBox()->toCompactData(bboxes.data()+6*i);
+        srcElemIdx[i] = srcElems[i]->getIndex();
+      }
+
+    adjustBoundingBoxes(bboxes);
+    const double *bboxPtr(nullptr);
+    if(numSrcElems>0)
+      bboxPtr=&bboxes[0];
+    BBTree<SPACEDIM,ConnType> tree(bboxPtr, srcElemIdx, 0, numSrcElems);
+    const ConnType *trgConnPtr(targetMesh.getConnectivityPtr()),*trgConnIPtr(targetMesh.getConnectivityIndexPtr());
+    const ConnType *srcConnPtr(srcMesh.getConnectivityPtr()),*srcConnIPtr(srcMesh.getConnectivityIndexPtr());
+    const double *trgCooPtr(targetMesh.getCoordinatesPtr()),*srcCooPtr(srcMesh.getCoordinatesPtr());
+    for(unsigned long i = 0; i < numTargetElems; ++i)
+      {
+        IKAssert(trgConnIPtr[i+1]==i+1 && trgConnIPtr[i]==i);
+        std::vector<ConnType> srcSegCondidates;
+        const double *trgCellPosition(trgCooPtr+SPACEDIM*trgConnPtr[i]);
+        typename MatrixType::value_type& resRow(result[trgConnPtr[i]]);
+        tree.getElementsAroundPoint(trgCellPosition, srcSegCondidates);
+        for(auto srcSeg: srcSegCondidates)
+          {
+            IKAssertMsg(srcConnIPtr[srcSeg+1]==2*(srcSeg+1) && srcConnIPtr[srcSeg]==2*srcSeg,"Only implemented for linear 1D source");
+            double bc0(0.),bc1(0.);
+            ConnType srcNode0(srcConnPtr[2*srcSeg]),srcNode1(srcConnPtr[2*srcSeg+1]);
+            if(IsPointOn3DSeg(srcCooPtr+SPACEDIM*srcNode0,srcCooPtr+SPACEDIM*srcNode1,trgCellPosition,epsilon,bc0,bc1))
+              {
+                resRow.insert(std::make_pair(srcNode0,bc0));
+                resRow.insert(std::make_pair(srcNode1,bc1));
+                continue;
+              }
+          }
+      }
+    delete [] srcElemIdx;
+    for(unsigned long i = 0 ; i < numSrcElems ; ++i)
+      delete srcElems[i];
+    return srcMesh.getNumberOfNodes();
+  }
+#else
+  throw INTERP_KERNEL::Exception("Go buying a C++11 compiler :)");
+#endif
+}
+
+#endif
index e222e1b078c85a50b3b7590a471c8294f3ced8a8..fad2faea7cbc4c9ad9b684ba61524f3469094cd9 100644 (file)
@@ -68,7 +68,7 @@ namespace INTERP_KERNEL
   /*   calcul la surface d'un triangle                  */
   /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ */
 
-  inline double Surf_Tri(const double* P_1,const double* P_2,const double* P_3)
+  inline double Surf_Tri(const double *P_1,const double *P_2,const double *P_3)
   {
     double A=(P_3[1]-P_1[1])*(P_2[0]-P_1[0])-(P_2[1]-P_1[1])*(P_3[0]-P_1[0]);
     double Surface = 0.5*fabs(A);
@@ -83,9 +83,9 @@ namespace INTERP_KERNEL
   //fonction qui calcul le determinant des vecteurs: P3P1 et P3P2
   //(cf doc CGAL).
 
-  inline double mon_determinant(const doubleP_1,
-                                const double*  P_2,
-                                const doubleP_3)
+  inline double mon_determinant(const double *P_1,
+                                const double *P_2,
+                                const double *P_3)
   {
     double mon_det=(P_1[0]-P_3[0])*(P_2[1]-P_3[1])-(P_2[0]-P_3[0])*(P_1[1]-P_3[1]);
     return mon_det;
@@ -98,8 +98,7 @@ namespace INTERP_KERNEL
   {
     double X=P_1[0]-P_2[0];
     double Y=P_1[1]-P_2[1];
-    double norme=sqrt(X*X+Y*Y);
-    return norme;
+    return sqrt(X*X+Y*Y);
   }
 
   /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ */
@@ -536,6 +535,29 @@ namespace INTERP_KERNEL
       }
   }
 
+  /*!
+   * Compute barycentric coords of point \a point relative to segment S [segStart,segStop] in 3D space.
+   * If point \a point is further from S than eps false is returned.
+   * If point \a point projection on S is outside S false is also returned.
+   * If point \a point is closer from S than eps and its projection inside S true is returned and \a bc0 and \a bc1 output parameter set.
+   */
+  inline bool IsPointOn3DSeg(const double segStart[3], const double segStop[3], const double point[3], double eps, double& bc0, double& bc1)
+  {
+    double AB[3]={segStop[0]-segStart[0],segStop[1]-segStart[1],segStop[2]-segStart[2]},AP[3]={point[0]-segStart[0],point[1]-segStart[1],point[2]-segStart[2]};
+    double l_AB(sqrt(AB[0]*AB[0]+AB[1]*AB[1]+AB[2]*AB[2]));
+    double AP_dot_AB((AP[0]*AB[0]+AP[1]*AB[1]+AP[2]*AB[2])/(l_AB*l_AB));
+    double projOfPOnAB[3]={segStart[0]+AP_dot_AB*AB[0],segStart[1]+AP_dot_AB*AB[1],segStart[2]+AP_dot_AB*AB[2]};
+    double V_dist_P_AB[3]={point[0]-projOfPOnAB[0],point[1]-projOfPOnAB[1],point[2]-projOfPOnAB[2]};
+    double dist_P_AB(sqrt(V_dist_P_AB[0]*V_dist_P_AB[0]+V_dist_P_AB[1]*V_dist_P_AB[1]+V_dist_P_AB[2]*V_dist_P_AB[2]));
+    if(dist_P_AB>=eps)
+      return false;//to far from segment [segStart,segStop]
+    if(AP_dot_AB<-eps || AP_dot_AB>1.+eps)
+      return false;
+    AP_dot_AB=std::max(AP_dot_AB,0.); AP_dot_AB=std::min(AP_dot_AB,1.);
+    bc0=1.-AP_dot_AB; bc1=AP_dot_AB;
+    return true;
+  }
+
   /*!
    * Calculate pseudo barycentric coordinates of a point p with respect to the quadrangle vertices.
    * This method makes the assumption that:
index e2796abad2f62379e37c3dbd89a16006cab92e51..552ab2625525a613668e1ffe0449007dff4493a1 100644 (file)
@@ -61,8 +61,6 @@ namespace INTERP_KERNEL
     delete _box;
   }
 
-  
-
   /////////////////////////////////////////////////////////////////////
   /// ElementBBoxOrder                                    /////////////
   /////////////////////////////////////////////////////////////////////
index 1c20ae77a9f198dd182c98c20607c6e5faa5e5a2..9f04fa9f6d82e8cabe947fc0cfa2a9c60bc6f0ce 100644 (file)
@@ -4257,6 +4257,11 @@ DataArrayInt *DataArrayInt::checkAndPreparePermutation() const
  * inversely.
  * In case of success (no throw) : \c ids1->renumber(ret)->isEqual(ids2) where \a ret is the return of this method.
  *
+ * \b Example:
+ * - \a ids1 : [3,1,103,4,6,10,-7,205]
+ * - \a ids2 : [-7,1,205,10,6,3,103,4]
+ * - \a return is : [5,1,6,7,4,3,0,2] because ids2[5]==ids1[0], ids2[1]==ids1[1], ids2[6]==ids1[2]...
+ *
  * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
  *          array using decrRef() as it is no more needed.
  * \throw If either ids1 or ids2 is null not allocated or not with one components.
index ce207679edc9e4443c874401c80416505dfebdf1..111b6186cb3776cf513ac447c6d1a7bef740cd51 100644 (file)
@@ -22,6 +22,7 @@
 #define __MEDCOUPLINGNORMALIZEDUNSTRUCTUREDMESH_TXX__
 
 #include "MEDCouplingNormalizedUnstructuredMesh.hxx"
+#include "InterpKernelAssert.hxx"
 
 #include "MEDCouplingUMesh.hxx"
 #include "MEDCoupling1GTUMesh.hxx"
@@ -124,6 +125,7 @@ MEDCouplingNormalizedUnstructuredMesh<SPACEDIM,MESHDIM>::~MEDCouplingNormalizedU
 template<int SPACEDIM,int MESHDIM>
 void MEDCouplingNormalizedUnstructuredMesh<SPACEDIM,MESHDIM>::prepare()
 {
+  IKAssert(_mesh->getSpaceDimension()==SPACEDIM);
   const MEDCoupling::MEDCouplingUMesh *m1(dynamic_cast<const MEDCoupling::MEDCouplingUMesh *>(_mesh));
   if(m1)
     {
index 725c1cf19a17212cac7b6c5e2827276e4f4debef..b7e08b45aa54556587edca3bd70a1e51899e9c7e 100644 (file)
@@ -75,6 +75,15 @@ const char *MEDCoupling::MEDCouplingByteOrderStr()
     return BIGENDIAN_STR;
 }
 
+bool MEDCoupling::IsCXX11Compiled()
+{
+#if __cplusplus >= 201103L
+  return true;
+#else
+  return false;
+#endif
+}
+
 //=
 
 std::size_t BigMemoryObject::getHeapMemorySize() const
index 7fdf91f538d0a2dad02af990070961f805d80e71..b0fb54ce1c639821b524782b87efafed864760f6 100644 (file)
@@ -64,7 +64,8 @@ namespace MEDCoupling
   MEDCOUPLING_EXPORT int MEDCouplingSizeOfVoidStar();
   MEDCOUPLING_EXPORT bool MEDCouplingByteOrder();
   MEDCOUPLING_EXPORT const char *MEDCouplingByteOrderStr();
-
+  MEDCOUPLING_EXPORT bool IsCXX11Compiled();
+  
   class BigMemoryObject
   {
   public:
index b6407f88b7a76dfe4d87a609c5bbe75a47e1f9f0..808a25e03b01bd5f11e8f6fb10d8e48210df8634 100644 (file)
@@ -36,6 +36,7 @@
 #include "Interpolation2D1D.txx"
 #include "Interpolation2D3D.txx"
 #include "Interpolation3D1D.txx"
+#include "Interpolation1D0D.txx"
 #include "InterpolationCU.txx"
 #include "InterpolationCC.txx"
 
@@ -440,6 +441,15 @@ int MEDCouplingRemapper::prepareInterpKernelOnlyUU()
       INTERP_KERNEL::Interpolation3D1D interpolation(*this);
       nbCols=interpolation.interpolateMeshes(source_mesh_wrapper,target_mesh_wrapper,_matrix,method);
     }
+  else if(srcMeshDim==1 && trgMeshDim==0 && srcSpaceDim==3)
+    {
+      if(getIntersectionType()!=INTERP_KERNEL::PointLocator)
+        throw INTERP_KERNEL::Exception("Invalid interpolation requested between 1D and 0D into 3D space ! Select PointLocator as intersection type !");
+      MEDCouplingNormalizedUnstructuredMesh<3,3> source_mesh_wrapper(src_mesh);
+      MEDCouplingNormalizedUnstructuredMesh<3,3> target_mesh_wrapper(target_mesh);
+      INTERP_KERNEL::Interpolation1D0D interpolation(*this);
+      nbCols=interpolation.interpolateMeshes(source_mesh_wrapper,target_mesh_wrapper,_matrix,method);
+    }
   else if(srcMeshDim==1 && trgMeshDim==3 && srcSpaceDim==3)
     {
       if(getIntersectionType()!=INTERP_KERNEL::PointLocator)
index 71d30669a1826b4896354d1a65f4d19fcabe0cbb..683a8d1959838715444ca6050c8b134bcb7cb8a5 100644 (file)
@@ -1465,7 +1465,7 @@ void MEDCouplingBasicsTestInterp::test3DInterpP0P0Empty()
   sourceMesh->allocateCells(0);
   sourceMesh->finishInsertingCells();
   DataArrayDouble *myCoords=DataArrayDouble::New();
-  myCoords->alloc(0,0);
+  myCoords->alloc(0,2);
   sourceMesh->setCoords(myCoords);
   myCoords->decrRef();
   MEDCouplingUMesh *targetMesh=MEDCouplingUMesh::New();
index fa29e6032415beaf0db0e8e00c0dbb70bf39c175..031f0c380697c1740d9e5cb6a48b5eada59e6436 100644 (file)
@@ -62,7 +62,8 @@ namespace MEDCoupling
   int MEDCouplingSizeOfVoidStar();
   bool MEDCouplingByteOrder();
   const char *MEDCouplingByteOrderStr();
-
+  bool IsCXX11Compiled();
+  
   class BigMemoryObject
   {
   public:
index b00dc71ef730857386b0b83edc15582ee396338e..a0a0b01a3e1d98be66957aff9b36eaf88c92875b 100644 (file)
@@ -1155,6 +1155,51 @@ class MEDCouplingBasicsTest(unittest.TestCase):
         self.assertEqual(1, len(rmp.getCrudeMatrix()[0]))
         pass
 
+    @unittest.skipUnless(MEDCouplingHasNumPyBindings() and MEDCouplingHasSciPyBindings() and IsCXX11Compiled(),"requires numpy AND scipy AND C++11")
+    def testP1P1PL3DSpaceFrom1DTo0D(self):
+        from scipy.sparse import csr_matrix
+        from numpy import array
+
+        def generateTrg(eps):
+            trgArr=DataArrayDouble([(0.5,0.5,0.5),(0.2,0.2,0.2),(0.9,0.9,0.9),(0.7+eps*sqrt(3),0.7-eps*sqrt(3),0.7)])
+            trg=MEDCouplingUMesh("trg",0) ; trg.setCoords(trgArr)
+            trg.allocateCells()
+            RenumTrg=[2,3,0,1]
+            for rt in RenumTrg:
+                trg.insertNextCell(NORM_POINT1,[rt])
+            return trg
+
+        srcArr=DataArrayDouble([(0.,0.,1.),(0.,0.,0.),(1.,1.,1.)])
+        src=MEDCouplingUMesh("src",1) ; src.setCoords(srcArr)
+        src.allocateCells()
+        src.insertNextCell(NORM_SEG2,[1,2])
+        #
+        trg=generateTrg(1e-7)# trg point 3 of trg cell 1 is NOT closer enough to source edge #1 -> not intercepted
+        #
+        rem=MEDCouplingRemapper()
+        rem.setIntersectionType(PointLocator)
+        self.assertEqual(rem.prepare(src,trg,"P1P1"),1)
+        mat=rem.getCrudeCSRMatrix()
+        row=array([2,2, 0,0, 1,1]) # here no ref to point 3 !
+        col=array([1,2, 1,2, 1,2])
+        data=array([0.1,0.9, 0.5,0.5, 0.8,0.2])
+        mExp=csr_matrix((data,(row,col)),shape=(4,3))
+        delta=abs(mExp-mat)
+        self.assertAlmostEqual(delta.sum(),0.,14)
+        #
+        trg=generateTrg(1e-14) # trg point 3 of trg cell 1 is closer enough to source edge #1 -> intercepted
+        rem=MEDCouplingRemapper()
+        rem.setIntersectionType(PointLocator)
+        self.assertEqual(rem.prepare(src,trg,"P1P1"),1)
+        mat=rem.getCrudeCSRMatrix()
+        row=array([2,2, 3,3, 0,0, 1,1]) # here ref to target point 3 
+        col=array([1,2, 1,2, 1,2, 1,2])
+        data=array([0.1,0.9, 0.3,0.7, 0.5,0.5, 0.8,0.2])
+        mExp2=csr_matrix((data,(row,col)),shape=(4,3))
+        delta2=abs(mExp2-mat)
+        self.assertAlmostEqual(delta2.sum(),0.,14)
+        pass
+
     def checkMatrix(self,mat1,mat2,nbCols,eps):
         self.assertEqual(len(mat1),len(mat2))
         for i in range(len(mat1)):
index f4c906f8b77c57c8c5d7377555d8c214258e6809..c310994f7a32e8965e87d3300b3f6dcc25d3d6a6 100644 (file)
@@ -607,6 +607,212 @@ void MEDFileFields::accept(MEDFileFieldVisitor& visitor) const
       }
 }
 
+class MEDFileFieldLin2QuadVisitor : public MEDFileFieldVisitor
+{
+public:
+  MEDFileFieldLin2QuadVisitor(const MEDFileUMesh *lin, const MEDFileUMesh *quad, const MEDFileFieldGlobsReal *linGlobs, MEDFileFields* outFs):_lin(lin),_quad(quad),_lin_globs(linGlobs),_out_fs(outFs),_gt(INTERP_KERNEL::NORM_ERROR),_1ts_update_requested(false) { }
+  void newFieldEntry(const MEDFileAnyTypeFieldMultiTSWithoutSDA *field) { if(field->getMeshName()!=_lin->getName()) return; _cur_fmts=MEDFileFieldMultiTS::New(); }
+  void endFieldEntry(const MEDFileAnyTypeFieldMultiTSWithoutSDA *field) { if(_cur_fmts.isNotNull()) { if(_cur_fmts->getNumberOfTS()>0) _out_fs->pushField(_cur_fmts); } }
+  //
+  void newTimeStepEntry(const MEDFileAnyTypeField1TSWithoutSDA *ts);
+  void endTimeStepEntry(const MEDFileAnyTypeField1TSWithoutSDA *ts);
+  //
+  void newMeshEntry(const MEDFileFieldPerMesh *fpm);
+  void endMeshEntry(const MEDFileFieldPerMesh *fpm) { }
+  //
+  void newPerMeshPerTypeEntry(const MEDFileFieldPerMeshPerTypeCommon *pmpt);
+  void endPerMeshPerTypeEntry(const MEDFileFieldPerMeshPerTypeCommon *pmpt) { }
+  //
+  void newPerMeshPerTypePerDisc(const MEDFileFieldPerMeshPerTypePerDisc *pmptpd);
+private:
+  void updateData(MEDFileFieldPerMeshPerTypePerDisc *pmtd);
+private:
+  const MEDFileUMesh *_lin;
+  const MEDFileUMesh *_quad;
+  const MEDFileFieldGlobsReal *_lin_globs;
+  MEDFileFields *_out_fs;
+  MCAuto<MEDFileFieldMultiTS> _cur_fmts;
+  MCAuto<MEDFileField1TS> _cur_f1ts;
+  INTERP_KERNEL::NormalizedCellType _gt;
+  // Info on 1TS modification
+  bool _1ts_update_requested;
+  // Cache of matrix to compute faster the values on newly created points
+  std::string _pfl;
+  MCAuto<DataArrayInt> _matrix;
+  MCAuto<DataArrayInt> _new_pts_ids;
+};
+
+void MEDFileFieldLin2QuadVisitor::newPerMeshPerTypePerDisc(const MEDFileFieldPerMeshPerTypePerDisc *pmptpd)
+{
+  if(_cur_f1ts.isNull())
+    return;
+  if(pmptpd->getType()!=ON_NODES)
+    throw INTERP_KERNEL::Exception("Not managed yet for ON_CELLS ON_GAUSS_NE and ON_GAUSS_PT");
+  _1ts_update_requested=true;
+  MEDFileAnyTypeField1TSWithoutSDA *ct(_cur_f1ts->contentNotNullBase());
+  int locId(pmptpd->getFather()->locIdOfLeaf(pmptpd));
+  MEDFileFieldPerMeshPerTypePerDisc *pmtdToModify(ct->getLeafGivenMeshAndTypeAndLocId(_lin->getName(),_gt,locId));
+  std::string pflName(pmptpd->getProfile());
+  if(pflName==_pfl && _matrix.isNotNull())
+    {
+      updateData(pmtdToModify);
+      return ;
+    }
+  _pfl=pflName; _matrix.nullify(); _new_pts_ids.nullify();
+  MCAuto<DataArrayInt> pfl;
+  if(pflName.empty())
+    pfl=DataArrayInt::Range(0,pmptpd->getNumberOfVals(),1);
+  else
+    pfl=_lin_globs->getProfile(pflName)->deepCopy();
+  {
+     MCAuto<MEDCouplingUMesh> mesh3D(_lin->getMeshAtLevel(0)),mesh3DQuadratic(_quad->getMeshAtLevel(0));
+     MCAuto<DataArrayInt> cellIds(mesh3D->getCellIdsLyingOnNodes(pfl->begin(),pfl->end(),true));
+     MCAuto<MEDCouplingUMesh> mesh3DQuadraticRestricted(mesh3DQuadratic->buildPartOfMySelf(cellIds->begin(),cellIds->end(),true));
+     MCAuto<DataArrayInt> mesh3DQuadraticRestrictedNodeIds(mesh3DQuadraticRestricted->computeFetchedNodeIds());
+     MCAuto<DataArrayInt> orphansNodes;
+     {
+       MCAuto<MEDCouplingUMesh> tmp1(mesh3D->buildPartOfMySelf(cellIds->begin(),cellIds->end(),true));
+       MCAuto<DataArrayInt> tmp2(tmp1->computeFetchedNodeIds());
+       orphansNodes=pfl->buildSubstraction(tmp2);
+     }
+     mesh3DQuadraticRestrictedNodeIds->checkMonotonic(true);
+     _new_pts_ids=mesh3DQuadraticRestrictedNodeIds->buildSubstraction(pfl);
+     MCAuto<MEDCoupling1SGTUMesh> allSeg3;
+     {
+       MCAuto<DataArrayInt> a,b,c,d;
+       MCAuto<MEDCouplingUMesh> seg3Tmp(mesh3DQuadraticRestricted->explodeIntoEdges(a,b,c,d));
+       allSeg3=MEDCoupling1SGTUMesh::New(seg3Tmp);
+     }
+     if(allSeg3->getCellModelEnum()!=INTERP_KERNEL::NORM_SEG3)
+       throw INTERP_KERNEL::Exception("MEDFileFieldLin2QuadVisitor::newPerMeshPerTypePerDisc : invalid situation where SEG3 expected !");
+     MCAuto<DataArrayInt> midPts,cellSeg3Ids;
+     {
+       DataArrayInt *nodeConn(allSeg3->getNodalConnectivity());
+       nodeConn->rearrange(3);
+       {
+         std::vector<int> v(1,2);
+         midPts=nodeConn->keepSelectedComponents(v);
+       }
+       cellSeg3Ids=DataArrayInt::FindPermutationFromFirstToSecond(midPts,_new_pts_ids);
+       {
+         std::vector<int> v(2); v[0]=0; v[1]=1;
+         MCAuto<DataArrayInt> tmp(nodeConn->keepSelectedComponents(v));
+         _matrix=tmp->selectByTupleId(cellSeg3Ids->begin(),cellSeg3Ids->end());
+       }
+       nodeConn->rearrange(1);
+     }
+     updateData(pmtdToModify);
+  }
+}
+
+void MEDFileFieldLin2QuadVisitor::updateData(MEDFileFieldPerMeshPerTypePerDisc *pmtd)
+{
+  pmtd->incrementNbOfVals(_new_pts_ids->getNumberOfTuples());
+}
+
+void MEDFileFieldLin2QuadVisitor::newPerMeshPerTypeEntry(const MEDFileFieldPerMeshPerTypeCommon *pmpt)
+{
+  const MEDFileFieldPerMeshPerType *pmpt2(dynamic_cast<const MEDFileFieldPerMeshPerType *>(pmpt));
+  if(!pmpt2)
+    throw INTERP_KERNEL::Exception("MEDFileFieldLin2QuadVisitor::newPerMeshPerTypeEntry : not managed for structure elements !");
+  if(pmpt2->getNumberOfLoc()!=1)
+    throw INTERP_KERNEL::Exception("MEDFileFieldLin2QuadVisitor::newPerMeshPerTypeEntry : not managed for multi discr per timestep !");
+  _gt=pmpt->getGeoType();
+}
+
+void MEDFileFieldLin2QuadVisitor::newMeshEntry(const MEDFileFieldPerMesh *fpm)
+{
+  if(fpm->getMeshName()!=_lin->getName())
+    throw INTERP_KERNEL::Exception("MEDFileFieldLin2QuadVisitor::newMeshEntry : mismatch into meshName !");
+}
+
+void MEDFileFieldLin2QuadVisitor::newTimeStepEntry(const MEDFileAnyTypeField1TSWithoutSDA *ts)
+{
+  _1ts_update_requested=false;
+  if(!ts)
+    return ;
+  const MEDFileField1TSWithoutSDA *tsd(dynamic_cast<const MEDFileField1TSWithoutSDA *>(ts));
+  if(!tsd)
+    return ;
+  MCAuto<MEDFileAnyTypeField1TSWithoutSDA> contentCpy(ts->deepCopy());
+  MCAuto<MEDFileField1TSWithoutSDA> contentCpy2(DynamicCastSafe<MEDFileAnyTypeField1TSWithoutSDA,MEDFileField1TSWithoutSDA>(contentCpy));
+  if(contentCpy2.isNull())
+    return;
+  _cur_f1ts=MEDFileField1TS::New(*contentCpy2,true);
+  _cur_f1ts->shallowCpyGlobs(*_lin_globs);
+}
+
+void MEDFileFieldLin2QuadVisitor::endTimeStepEntry(const MEDFileAnyTypeField1TSWithoutSDA *ts)
+{
+  if(_cur_f1ts.isNull())
+    return ;
+  if(_1ts_update_requested)
+    {
+      if(!_pfl.empty())
+        {
+          int locId(_cur_f1ts->getLocalizationId(_pfl));
+          DataArrayInt *pfl(_cur_f1ts->getProfile(_pfl));
+          MCAuto<DataArrayInt> newPfl;
+          {
+            std::vector<const DataArrayInt *> vs(2);
+            vs[0]=pfl; vs[1]=_new_pts_ids;
+            newPfl=DataArrayInt::Aggregate(vs);
+          }
+          newPfl->setName(_pfl);
+          {
+            std::vector<int> locToKill(1,locId);
+            _cur_f1ts->killLocalizationIds(locToKill);
+          }
+          _cur_f1ts->appendProfile(newPfl);
+        }
+      DataArrayDouble *arr(_cur_f1ts->getUndergroundDataArray());
+      MCAuto<DataArrayDouble> res;
+      {
+        std::vector<int> v(1,0),v2(1,1);
+        MCAuto<DataArrayInt> pts0(_matrix->keepSelectedComponents(v));
+        MCAuto<DataArrayInt> pts1(_matrix->keepSelectedComponents(v2));
+        MCAuto<DataArrayDouble> part0(arr->selectByTupleId(*pts0));
+        MCAuto<DataArrayDouble> part1(arr->selectByTupleId(*pts1));
+        res=DataArrayDouble::Add(part0,part1);
+        res->applyLin(0.5,0.);
+      }
+      res=DataArrayDouble::Aggregate(arr,res);
+      _cur_f1ts->setArray(res);
+    }
+  if(_cur_fmts.isNotNull())
+    { _cur_fmts->pushBackTimeStep(_cur_f1ts); }
+  _1ts_update_requested=false;
+}
+
+/*!
+ * \a newQuad is expected to be the result of MEDFileUMesh::linearToQuadratic of \a oldLin
+ */
+MCAuto<MEDFileFields> MEDFileFields::linearToQuadratic(const MEDFileMeshes *oldLin, const MEDFileMeshes *newQuad) const
+{
+  if(!oldLin || !newQuad)
+    throw INTERP_KERNEL::Exception("MEDFileFields::linearToQuadratic : input meshes must be non NULL !");
+  MCAuto<MEDFileFields> ret(MEDFileFields::New());
+  for(int i=0;i<oldLin->getNumberOfMeshes();i++)
+    {
+      MEDFileMesh *mm(oldLin->getMeshAtPos(i));
+      if(!mm)
+        continue;
+      MEDFileUMesh *mmu(dynamic_cast<MEDFileUMesh *>(mm));
+      if(!mmu)
+        continue;
+      MEDFileMesh *mmq(newQuad->getMeshWithName(mmu->getName()));
+      MEDFileUMesh *mmqu(dynamic_cast<MEDFileUMesh *>(mmq));
+      if(!mmqu)
+        {
+          std::ostringstream oss; oss << "MEDFileFields::linearToQuadratic : mismatch of name between input meshes for name \"" << mmu->getName() << "\"";
+          throw INTERP_KERNEL::Exception(oss.str());
+        }
+      MEDFileFieldLin2QuadVisitor vis(mmu,mmqu,this,ret);
+      accept(vis);
+    }
+  return ret;
+}
+
 MEDFileAnyTypeFieldMultiTS *MEDFileFields::getFieldAtPos(int i) const
 {
   if(i<0 || i>=(int)_fields.size())
index 724a5332160941d28900343ecaa0ae14b0193ef7..f173681e83596f41cb4075832d85dd07530ff4ef 100644 (file)
@@ -123,6 +123,7 @@ namespace MEDCoupling
     MEDLOADER_EXPORT bool changeMeshNames(const std::vector< std::pair<std::string,std::string> >& modifTab);
     MEDLOADER_EXPORT bool renumberEntitiesLyingOnMesh(const std::string& meshName, const std::vector<int>& oldCode, const std::vector<int>& newCode, const DataArrayInt *renumO2N);
     MEDLOADER_EXPORT void accept(MEDFileFieldVisitor& visitor) const;
+    MEDLOADER_EXPORT MCAuto<MEDFileFields> linearToQuadratic(const MEDFileMeshes *oldLin, const MEDFileMeshes *newQuad) const;
   public:
     MEDLOADER_EXPORT MEDFileFields *extractPart(const std::map<int, MCAuto<DataArrayInt> >& extractDef, MEDFileMesh *mm) const;
   public:
index e3ba8eeb8b73a72b4109c2728da48b0fe06e4cd0..ab4a0d17826d548c9790faf0ebd143e7cb155967 100644 (file)
@@ -199,6 +199,16 @@ namespace MEDCoupling
       }
   }
 
+  template<class T>
+  void MEDFileField1TSTemplateWithoutSDA<T>::copyTimeInfoFrom(const typename Traits<T>::FieldType *mcf)
+  {
+    if(!mcf)
+      throw INTERP_KERNEL::Exception("MEDFileField1TSTemplateWithoutSDA<T>::copyTimeInfoFrom : input field is nullptr !");
+    int b(0),c(0);
+    double a(mcf->getTime(b,c));
+    setTime(b,c,a);
+  }
+
   ///////////////////////////////////////////////////////
 
   template<class T>
@@ -397,6 +407,12 @@ namespace MEDCoupling
     return ReturnSafelyTypedDataArray(arr);
   }
 
+  template<class T>
+  void MEDFileTemplateField1TS<T>::setArray(DataArray *arr)
+  {
+    return contentNotNull()->setArray(arr);
+  }
+
   template<class T>
   typename Traits<T>::ArrayType *MEDFileTemplateField1TS<T>::getUndergroundDataArray() const
   {
@@ -438,6 +454,12 @@ namespace MEDCoupling
     return ret.retn();
   }
 
+  template<class T>
+  void MEDFileTemplateField1TS<T>::copyTimeInfoFrom(const typename Traits<T>::FieldType *mcf)
+  {
+    contentNotNull()->copyTimeInfoFrom(mcf);
+  }
+
   /*!
    * This is the simplest version to fetch a field for MED structure. One drawback : if \a this is a complex field (multi spatial discretization inside a same field) this method will throw exception and more advance
    * method should be called (getFieldOnMeshAtLevel for example).
index 961fc75068f8bf3a47d1b2c394e6437749dcaf94..54f75f887312c9e8cc78c4385d8a4310e5cd85e6 100644 (file)
@@ -160,6 +160,7 @@ namespace MEDCoupling
     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);
+    MEDLOADER_EXPORT void copyTimeInfoFrom(const typename Traits<T>::FieldType *mcf);
   protected:
     MCAuto< typename Traits<T>::ArrayType > _arr;
   };
@@ -349,11 +350,13 @@ namespace MEDCoupling
   public:
     MEDLOADER_EXPORT static typename Traits<T>::ArrayType *ReturnSafelyTypedDataArray(MCAuto<DataArray>& arr);
     MEDLOADER_EXPORT typename Traits<T>::ArrayType *getFieldWithProfile(TypeOfField type, int meshDimRelToMax, const MEDFileMesh *mesh, DataArrayInt *&pfl) const;
+    MEDLOADER_EXPORT void setArray(DataArray *arr);
     MEDLOADER_EXPORT typename Traits<T>::ArrayType *getUndergroundDataArray() const;
     MEDLOADER_EXPORT typename Traits<T>::ArrayType *getUndergroundDataArrayExt(std::vector< std::pair<std::pair<INTERP_KERNEL::NormalizedCellType,int>,std::pair<int,int> > >& entries) const;
     MEDLOADER_EXPORT static MCAuto<typename Traits<T>::FieldType> SetDataArrayInField(MEDCouplingFieldDouble *f, MCAuto<DataArray>& arr);
     MEDLOADER_EXPORT static MCAuto<MEDCouplingFieldDouble> ToFieldTemplateWithTime(const typename Traits<T>::FieldType *f);
   public:
+    MEDLOADER_EXPORT void copyTimeInfoFrom(const typename Traits<T>::FieldType *mcf);
     MEDLOADER_EXPORT typename Traits<T>::FieldType *field(const MEDFileMesh *mesh) const;
     MEDLOADER_EXPORT typename Traits<T>::FieldType *getFieldAtLevel(TypeOfField type, int meshDimRelToMax, int renumPol=0) const;
     MEDLOADER_EXPORT typename Traits<T>::FieldType *getFieldAtTopLevel(TypeOfField type, int renumPol=0) const;
index 11a46ae5d47f2d512cbd49a757537d3636a3abbf..990cd88013a4ef230f5668128120c2f5a22daab6 100644 (file)
@@ -432,7 +432,7 @@ MEDFileFieldLoc& MEDFileFieldGlobs::getLocalization(const std::string& locName)
 }
 
 /*!
- * The returned value is never null.
+ * The returned value is never null. Borrowed reference returned.
  */
 DataArrayInt *MEDFileFieldGlobs::getProfile(const std::string& pflName)
 {
@@ -1119,7 +1119,7 @@ MEDFileFieldLoc& MEDFileFieldGlobsReal::getLocalization(const std::string& locNa
 /*!
  * Returns a profile array, apt for modification, by its name.
  *  \param [in] pflName - the name of the profile of interest.
- *  \return DataArrayInt * - a non-const pointer to the profile array having the name \a pflName.
+ *  \return DataArrayInt * - Borrowed reference - a non-const pointer to the profile array having the name \a pflName.
  *  \throw If there is no a profile named \a pflName.
  */
 DataArrayInt *MEDFileFieldGlobsReal::getProfile(const std::string& pflName)
@@ -1130,7 +1130,7 @@ DataArrayInt *MEDFileFieldGlobsReal::getProfile(const std::string& pflName)
 /*!
  * Returns a profile array, apt for modification, by its id.
  *  \param [in] pflId - the id of the profile of interest.
- *  \return DataArrayInt * - a non-const pointer to the profile array having the id \a pflId.
+ *  \return DataArrayInt * - Borrowed reference - a non-const pointer to the profile array having the id \a pflId.
  *  \throw If there is no a profile with id \a pflId.
  */
 DataArrayInt *MEDFileFieldGlobsReal::getProfileFromId(int pflId)
index 6df10f498d5490a9d1157f424e7d43fe2190de32..2a138059bf61b80ead5e4880aa494ede61c3e1e1 100644 (file)
@@ -807,6 +807,13 @@ int MEDFileFieldPerMeshPerTypePerDisc::getNumberOfTuples() const
   return _end-_start;
 }
 
+void MEDFileFieldPerMeshPerTypePerDisc::incrementNbOfVals(int deltaNbVal)
+{
+  int nbi((_end-_start)/_nval);
+  _nval+=deltaNbVal;
+  _end+=nbi*deltaNbVal;
+}
+
 DataArray *MEDFileFieldPerMeshPerTypePerDisc::getOrCreateAndGetArray()
 {
   return _father->getOrCreateAndGetArray();
@@ -1605,6 +1612,18 @@ const MEDFileFieldPerMeshPerTypePerDisc *MEDFileFieldPerMeshPerTypeCommon::getLe
   return static_cast<const MEDFileFieldPerMeshPerTypePerDisc*>(0);
 }
 
+int MEDFileFieldPerMeshPerTypeCommon::locIdOfLeaf(const MEDFileFieldPerMeshPerTypePerDisc *leaf) const
+{
+  int ret(0);
+  for(std::vector< MCAuto<MEDFileFieldPerMeshPerTypePerDisc> >::const_iterator it=_field_pm_pt_pd.begin();it!=_field_pm_pt_pd.end();it++,ret++)
+    {
+      const MEDFileFieldPerMeshPerTypePerDisc *cand(*it);
+      if(cand==leaf)
+        return ret;
+    }
+  throw INTERP_KERNEL::Exception("MEDFileFieldPerMeshPerTypeCommon::locIdOfLeaf : not found such a leaf in this !");
+}
+
 void MEDFileFieldPerMeshPerTypeCommon::fillValues(int& startEntryId, std::vector< std::pair<std::pair<INTERP_KERNEL::NormalizedCellType,int>,std::pair<int,int> > >& entries) const
 {
   int i=0;
index afa3dc9da497c8c9556bdc963100e7b27522b4cb..8c2e4790399e508888447ffc5c887ad14d4bd434 100644 (file)
@@ -162,6 +162,7 @@ namespace MEDCoupling
     int getEnd() const { return _end; }
     void setEnd(int endd) { _end=endd; }
     int getNumberOfVals() const { return _nval; }
+    void incrementNbOfVals(int deltaNbVal);
     DataArray *getOrCreateAndGetArray();
     const DataArray *getOrCreateAndGetArray() const;
     const std::vector<std::string>& getInfo() const;
@@ -252,6 +253,7 @@ namespace MEDCoupling
     MEDFileFieldPerMeshPerTypePerDisc *getLeafGivenLocId(int locId);
     const MEDFileFieldPerMeshPerTypePerDisc *getLeafGivenLocId(int locId) const;
     int getNumberOfLoc() const { return _field_pm_pt_pd.size(); }
+    int locIdOfLeaf(const MEDFileFieldPerMeshPerTypePerDisc *leaf) 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);
index 9ad13e9f6dfa196b9aca27a2dd1f9b17e49e4585..47269e3a985c5952c1a48e43592f8b47273d0f5b 100644 (file)
@@ -48,6 +48,7 @@ namespace MEDCoupling
     virtual void endPerMeshPerTypeEntry(const MEDFileFieldPerMeshPerTypeCommon *pmpt) = 0;
     //
     virtual void newPerMeshPerTypePerDisc(const MEDFileFieldPerMeshPerTypePerDisc *pmptpd) = 0;
+    virtual ~MEDFileFieldVisitor() { }
   };
 }
 
index e68c6c6251cfbe1bb09847f97554ec57cba166fd..014eade6eeda7ddd943fdb07d6ac28070f6be2cb 100644 (file)
@@ -160,6 +160,7 @@ using namespace MEDCoupling;
 %newobject MEDCoupling::MEDFileFields::partOfThisOnStructureElements;
 %newobject MEDCoupling::MEDFileFields::__iter__;
 %newobject MEDCoupling::MEDFileFields::extractPart;
+%newobject MEDCoupling::MEDFileFields::linearToQuadratic;
 
 %newobject MEDCoupling::MEDFileWritableStandAlone::serialize;
 %newobject MEDCoupling::MEDFileAnyTypeFieldMultiTS::New;
@@ -2221,6 +2222,7 @@ namespace MEDCoupling
     static MEDFileField1TS *New(DataArrayByte *db) throw(INTERP_KERNEL::Exception);
     static MEDFileField1TS *New();
     MEDCoupling::MEDFileIntField1TS *convertToInt(bool isDeepCpyGlobs=true) const throw(INTERP_KERNEL::Exception);
+    void copyTimeInfoFrom(MEDCouplingFieldDouble *mcf) throw(INTERP_KERNEL::Exception);
     MEDCouplingFieldDouble *field(const MEDFileMesh *mesh) const throw(INTERP_KERNEL::Exception);
     MEDCouplingFieldDouble *getFieldAtLevel(TypeOfField type, int meshDimRelToMax, int renumPol=0) const throw(INTERP_KERNEL::Exception);
     MEDCouplingFieldDouble *getFieldAtTopLevel(TypeOfField type, int renumPol=0) const throw(INTERP_KERNEL::Exception);
@@ -2338,6 +2340,7 @@ namespace MEDCoupling
     //
     void setFieldNoProfileSBT(const MEDCouplingFieldInt *field) throw(INTERP_KERNEL::Exception);
     void setFieldProfile(const MEDCouplingFieldInt *field, const MEDFileMesh *mesh, int meshDimRelToMax, const DataArrayInt *profile) throw(INTERP_KERNEL::Exception);
+    void copyTimeInfoFrom(MEDCouplingFieldInt *mcf) throw(INTERP_KERNEL::Exception);
     MEDCouplingFieldInt *field(const MEDFileMesh *mesh) const throw(INTERP_KERNEL::Exception);
     MEDCouplingFieldInt *getFieldAtLevel(TypeOfField type, int meshDimRelToMax, int renumPol=0) const throw(INTERP_KERNEL::Exception);
     MEDCouplingFieldInt *getFieldAtTopLevel(TypeOfField type, int renumPol=0) const throw(INTERP_KERNEL::Exception);
@@ -2408,6 +2411,7 @@ namespace MEDCoupling
     //
     void setFieldNoProfileSBT(const MEDCouplingFieldFloat *field) throw(INTERP_KERNEL::Exception);
     void setFieldProfile(const MEDCouplingFieldFloat *field, const MEDFileMesh *mesh, int meshDimRelToMax, const DataArrayInt *profile) throw(INTERP_KERNEL::Exception);
+    void copyTimeInfoFrom(MEDCouplingFieldFloat *mcf) throw(INTERP_KERNEL::Exception);
     MEDCouplingFieldFloat *field(const MEDFileMesh *mesh) const throw(INTERP_KERNEL::Exception);
     MEDCouplingFieldFloat *getFieldAtLevel(TypeOfField type, int meshDimRelToMax, int renumPol=0) const throw(INTERP_KERNEL::Exception);
     MEDCouplingFieldFloat *getFieldAtTopLevel(TypeOfField type, int renumPol=0) const throw(INTERP_KERNEL::Exception);
@@ -3408,6 +3412,12 @@ namespace MEDCoupling
            convertToMapIntDataArrayInt(extractDef,extractDefCpp);
            return self->extractPart(extractDefCpp,mm);
          }
+
+         MEDFileFields *linearToQuadratic(const MEDFileMeshes *oldLin, const MEDFileMeshes *newQuad) const throw(INTERP_KERNEL::Exception)
+         {
+           MCAuto<MEDFileFields> ret(self->linearToQuadratic(oldLin,newQuad));
+           return ret.retn();
+         }
        }
   };
 
index e61c9028a04718769eb39b492000a4794c19907d..f970090ea773a024612d2360233988768865d73e 100644 (file)
@@ -576,6 +576,10 @@ class MEDLoaderTest3(unittest.TestCase):
         ff1.setTime(3,4,2.3)
         itt,orr,ti=ff1.getTime()
         self.assertEqual(3,itt); self.assertEqual(4,orr); self.assertAlmostEqual(2.3,ti,14);
+        f1.setTime(5.5,7,8)
+        ff1.copyTimeInfoFrom(f1)
+        itt,orr,ti=ff1.getTime()
+        self.assertEqual(7,itt); self.assertEqual(8,orr); self.assertAlmostEqual(5.5,ti,14);
         da,infos=ff1.getUndergroundDataArrayExt()
         f2.getArray().setName(da.getName())#da has the same name than f2
         self.assertTrue(da.isEqual(f2.getArray(),1e-12))
@@ -6191,6 +6195,44 @@ class MEDLoaderTest3(unittest.TestCase):
         if os.path.exists(errfname):
             os.remove(errfname)
         pass
+
+    def testFieldsLinearToQuadratic(self):
+        arr=DataArrayDouble([0,1])
+        m=MEDCouplingCMesh();
+        m.setCoords(arr,arr,arr)
+        m=m.buildUnstructured()
+        m2=m.deepCopy()
+        m2.translate([2,0,0])
+        m3=MEDCouplingUMesh.MergeUMeshes([m,m2])
+        m3.setName("mesh")
+        mm=MEDFileUMesh()
+        mm[0]=m3
+        mmq=mm.linearToQuadratic(0)
+        mms=MEDFileMeshes() ; mms.pushMesh(mm)
+        mmsq=MEDFileMeshes() ; mmsq.pushMesh(mmq)
+        #
+        f=MEDCouplingFieldDouble(ON_NODES)
+        f.setName("field")
+        f.setMesh(m3)
+        f.setTime(3.,1,2)
+        arr=DataArrayDouble(m3.getNumberOfNodes())
+        arr.iota()
+        f.setArray(arr)
+        f1ts=MEDFileField1TS()
+        f1ts.setFieldNoProfileSBT(f)
+        fmts=MEDFileFieldMultiTS()
+        fmts.pushBackTimeStep(f1ts)
+        fs=MEDFileFields()
+        fs.pushField(fmts)
+        fs2=fs.linearToQuadratic(mms,mmsq)
+        #
+        fToTest=fs2[0][0].field(mmq)
+        self.assertEqual(fToTest.getTime(),[3.,1,2])
+        mTest=MEDCoupling1SGTUMesh(fToTest.getMesh())
+        self.assertTrue(mTest.getNodalConnectivity().isEqual(DataArrayInt([1,0,2,3,5,4,6,7,16,17,18,19,20,21,22,23,24,25,26,27,9,8,10,11,13,12,14,15,28,29,30,31,32,33,34,35,36,37,38,39])))
+        self.assertTrue(mTest.getCoords().isEqual(DataArrayDouble([0.,0.,0.,1.,0.,0.,0.,1.,0.,1.,1.,0.,0.,0.,1.,1.,0.,1.,0.,1.,1.,1.,1.,1.,2.,0.,0.,3.,0.,0.,2.,1.,0.,3.,1.,0.,2.,0.,1.,3.,0.,1.,2.,1.,1.,3.,1.,1.,0.5, 0.,0.,0.,0.5, 0.,0.5, 1.,0.,1.,0.5, 0.,0.5, 0.,1.,0.,0.5, 1.,0.5, 1.,1.,1.,0.5, 1.,1.,0.,0.5, 0.,0.,0.5, 0.,1.,0.5, 1.,1.,0.5, 2.5, 0.,0.,2.,0.5, 0.,2.5, 1.,0.,3.,0.5, 0.,2.5, 0.,1.,2.,0.5, 1.,2.5, 1.,1.,3.,0.5, 1.,3.,0.,0.5, 2.,0.,0.5, 2.,1.,0.5, 3.,1.,0.5],40,3),1e-12))
+        self.assertTrue(fToTest.getArray().isEqual(DataArrayDouble([0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,0.5,1,2.5,2,4.5,5,6.5,6,3,2,4,5,8.5,9,10.5,10,12.5,13,14.5,14,11,10,12,13]),1e-12))
+        pass
     
     pass
 
index dd39f8dae1ed16fef1e7744a80fc6bb92077b0e5..4c91bab5b7659d7150a41dedabfddcd6c39123d4 100644 (file)
@@ -98,6 +98,27 @@ class medcouplingTest(unittest.TestCase):
         interface=CommInterface()
         pass
 
+    def test5(self):
+        f=MEDCouplingFieldDouble(ON_NODES)
+        f.setTime(1.25,3,6)
+        a,b,c=f.getTime()
+        self.assertEqual(b,3) ; self.assertEqual(c,6) ; self.assertAlmostEqual(a,1.25,14);
+        f1ts=MEDFileField1TS()
+        f1ts.setTime(10,13,10.75)
+        f.copyTimeInfoFrom(f1ts)
+        a,b,c=f.getTime()
+        self.assertEqual(b,10) ; self.assertEqual(c,13) ; self.assertAlmostEqual(a,10.75,14);
+        f2=MEDCouplingFieldInt(ON_NODES)
+        f2.copyTimeInfoFrom(f1ts)
+        a,b,c=f2.getTime()
+        self.assertEqual(b,10) ; self.assertEqual(c,13) ; self.assertAlmostEqual(a,10.75,14);
+        f3=MEDCouplingFieldFloat(ON_NODES)
+        f3.copyTimeInfoFrom(f1ts)
+        a,b,c=f3.getTime()
+        self.assertEqual(b,10) ; self.assertEqual(c,13) ; self.assertAlmostEqual(a,10.75,14);
+        pass
+        
+
     def partitionerTesterHelper(self,algoSelected):
         arr=DataArrayDouble(10) ; arr.iota()
         m=MEDCouplingCMesh() ; m.setCoords(arr,arr)
index a3dfe1a20cdd8546aa4fb08706a91041c50df741..a286b9116d2d59c61126e449dd12186a705ed24a 100644 (file)
@@ -82,10 +82,19 @@ def MEDCouplingMesh_write(self,fileName):
 
 def MEDCouplingField_write(self,fileName):
     MEDCouplingWriterHelper(self,fileName,WriteField)
+    
+def MEDCouplingFieldT_copyTimeInfoFrom(self,mlf1ts):
+    assert(isinstance(mlf1ts,MEDFileAnyTypeField1TS))
+    a,b,c=mlf1ts.getTime()
+    self.setTime(c,a,b)
+    pass
         
 MEDCouplingMesh.write=MEDCouplingMesh_write
 del MEDCouplingMesh_write
 MEDCouplingField.write=MEDCouplingField_write
 del MEDCouplingField_write
-
+MEDCouplingFieldDouble.copyTimeInfoFrom=MEDCouplingFieldT_copyTimeInfoFrom
+MEDCouplingFieldInt.copyTimeInfoFrom=MEDCouplingFieldT_copyTimeInfoFrom
+MEDCouplingFieldFloat.copyTimeInfoFrom=MEDCouplingFieldT_copyTimeInfoFrom
+del MEDCouplingFieldT_copyTimeInfoFrom
 %}