]> SALOME platform Git repositories - modules/med.git/commitdiff
Salome HOME
On the road of the ParaMEDReader. MEDLoader can load partially a MEDFileUMesh from...
authorAnthony Geay <anthony.geay@edf.fr>
Fri, 26 Sep 2014 13:08:35 +0000 (15:08 +0200)
committerAnthony Geay <anthony.geay@edf.fr>
Fri, 26 Sep 2014 13:08:35 +0000 (15:08 +0200)
19 files changed:
src/MEDCoupling/MEDCoupling1GTUMesh.cxx
src/MEDCoupling/MEDCoupling1GTUMesh.hxx
src/MEDCoupling/MEDCouplingMemArray.hxx
src/MEDCoupling/MEDCouplingPointSet.hxx
src/MEDCoupling/MEDCouplingUMesh.cxx
src/MEDCoupling/MEDCouplingUMesh.hxx
src/MEDCoupling_Swig/MEDCouplingBasicsTest.py
src/MEDCoupling_Swig/MEDCouplingCommon.i
src/MEDLoader/MEDFileMesh.cxx
src/MEDLoader/MEDFileMesh.hxx
src/MEDLoader/MEDFileMeshElt.cxx
src/MEDLoader/MEDFileMeshElt.hxx
src/MEDLoader/MEDFileMeshLL.cxx
src/MEDLoader/MEDFileMeshLL.hxx
src/MEDLoader/Swig/MEDLoaderCommon.i
src/MEDLoader/Swig/MEDLoaderTest3.py
src/ParaMEDLoader/CMakeLists.txt
src/ParaMEDLoader/ParaMEDFileMesh.cxx [new file with mode: 0644]
src/ParaMEDLoader/ParaMEDFileMesh.hxx [new file with mode: 0644]

index ec244e6c427a7cb5163f8546e9c73f85ce35b48e..5c9b32456e90af479f2a1f16d08a20247eb7c2cd 100644 (file)
@@ -1005,6 +1005,29 @@ struct MEDCouplingAccVisit
 
 /// @endcond
 
+/*!
+ * This method returns all node ids used in \b this. The data array returned has to be dealt by the caller.
+ * The returned node ids are sortes ascendingly. This method is closed to MEDCoupling1SGTUMesh::getNodeIdsInUse except
+ * the format of returned DataArrayInt instance.
+ *
+ * \return a newly allocated DataArrayInt sorted ascendingly of fetched node ids.
+ * \sa MEDCoupling1SGTUMesh::getNodeIdsInUse
+ */
+DataArrayInt *MEDCoupling1SGTUMesh::computeFetchedNodeIds() const
+{
+  checkCoherencyOfConnectivity();
+  int nbNodes(getNumberOfNodes());
+  std::vector<bool> fetchedNodes(nbNodes,false);
+  computeNodeIdsAlg(fetchedNodes);
+  int sz((int)std::count(fetchedNodes.begin(),fetchedNodes.end(),true));
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(sz,1);
+  int *retPtr(ret->getPointer());
+  for(int i=0;i<nbNodes;i++)
+    if(fetchedNodes[i])
+      *retPtr++=i;
+  return ret.retn();
+}
+
 /*!
  * Finds nodes not used in any cell and returns an array giving a new id to every node
  * by excluding the unused nodes, for which the array holds -1. The result array is
@@ -1017,13 +1040,14 @@ struct MEDCouplingAccVisit
  *  \throw If the coordinates array is not set.
  *  \throw If the nodal connectivity of cells is not defined.
  *  \throw If the nodal connectivity includes an invalid id.
+ *  \sa MEDCoupling1SGTUMesh::computeFetchedNodeIds
  */
 DataArrayInt *MEDCoupling1SGTUMesh::getNodeIdsInUse(int& nbrOfNodesInUse) const
 {
   nbrOfNodesInUse=-1;
   int nbOfNodes=getNumberOfNodes();
   int nbOfCells=getNumberOfCells();
-  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New());
   ret->alloc(nbOfNodes,1);
   int *traducer=ret->getPointer();
   std::fill(traducer,traducer+nbOfNodes,-1);
@@ -1043,6 +1067,33 @@ DataArrayInt *MEDCoupling1SGTUMesh::getNodeIdsInUse(int& nbrOfNodesInUse) const
   return ret.retn();
 }
 
+/*!
+ *  Same than renumberNodesInConn(const int *) except that here the format of old-to-new traducer is using map instead
+ *  of array. This method is dedicated for renumbering from a big set of nodes the a tiny set of nodes which is the case during extraction
+ *  of a big mesh.
+ */
+void MEDCoupling1SGTUMesh::renumberNodesInConn(const std::map<int,int>& newNodeNumbersO2N)
+{
+  getNumberOfCells();//only to check that all is well defined.
+  int *begPtr(_conn->getPointer());
+  int nbElt(_conn->getNumberOfTuples());
+  int *endPtr(begPtr+nbElt);
+  for(int *it=begPtr;it!=endPtr;it++)
+    {
+      std::map<int,int>::const_iterator it2(newNodeNumbersO2N.find(*it));
+      if(it2!=newNodeNumbersO2N.end())
+        {
+          *it=(*it2).second;
+        }
+      else
+        {
+          std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::renumberNodesInConn : At pos #" << std::distance(begPtr,it) << " of nodal connectivity value is " << *it << ". Not in map !";
+          throw INTERP_KERNEL::Exception(oss.str().c_str());
+        }
+    }
+  updateTime();
+}
+
 /*!
  * Changes ids of nodes within the nodal connectivity arrays according to a permutation
  * array in "Old to New" mode. The node coordinates array is \b not changed by this method.
@@ -1229,20 +1280,16 @@ MEDCouplingPointSet *MEDCoupling1SGTUMesh::buildPartOfMySelfKeepCoords2(int star
 void MEDCoupling1SGTUMesh::computeNodeIdsAlg(std::vector<bool>& nodeIdsInUse) const
 {
   int sz((int)nodeIdsInUse.size());
-  int nbCells(getNumberOfCells());
-  int nbOfNodesPerCell(getNumberOfNodesPerCell());
-  const int *w(_conn->begin());
-  for(int i=0;i<nbCells;i++)
-    for(int j=0;j<nbOfNodesPerCell;j++,w++)
-      {
-        if(*w>=0 && *w<sz)
-          nodeIdsInUse[*w]=true;
-        else
-          {
-            std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::computeNodeIdsAlg : At cell #" << i << " presence of node id #" << *w << " should be in [0," << sz << ") !";
-            throw INTERP_KERNEL::Exception(oss.str().c_str());
-          }
-      }
+  for(const int *conn=_conn->begin();conn!=_conn->end();conn++)
+    {
+      if(*conn>=0 && *conn<sz)
+       nodeIdsInUse[*conn]=true;
+      else
+        {
+          std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::computeFetchedNodeIds : At pos #" << std::distance(_conn->begin(),conn) << " value is " << *conn << " must be in [0," << sz << ") !";
+          throw INTERP_KERNEL::Exception(oss.str().c_str());
+        }
+    }
 }
 
 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::buildSetInstanceFromThis(int spaceDim) const
@@ -2779,21 +2826,21 @@ MEDCouplingPointSet *MEDCoupling1DGTUMesh::buildPartOfMySelfKeepCoords2(int star
 
 void MEDCoupling1DGTUMesh::computeNodeIdsAlg(std::vector<bool>& nodeIdsInUse) const
 {
+  checkCoherency2();
   int sz((int)nodeIdsInUse.size());
-  int nbCells(getNumberOfCells());
-  const int *w(_conn->begin()),*wi(_conn_indx->begin());
-  for(int i=0;i<nbCells;i++,wi++)
-    for(const int *pt=w+wi[0];pt!=w+wi[1];pt++)
-      if(*pt!=-1)
+  for(const int *conn=_conn->begin();conn!=_conn->end();conn++)
+    {
+      if(*conn>=0 && *conn<sz)
+        nodeIdsInUse[*conn]=true;
+      else
         {
-          if(*pt>=0 && *pt<sz)
-            nodeIdsInUse[*pt]=true;
-          else
+          if(*conn!=-1)
             {
-              std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeNodeIdsAlg : At cell #" << i << " presence of node id #" << *pt << " should be in [0," << sz << ") !";
+              std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeNodeIdsAlg : At pos #" << std::distance(_conn->begin(),conn) << " value is " << *conn << " must be in [0," << sz << ") !";
               throw INTERP_KERNEL::Exception(oss.str().c_str());
             }
         }
+    }
 }
 
 void MEDCoupling1DGTUMesh::getReverseNodalConnectivity(DataArrayInt *revNodal, DataArrayInt *revNodalIndx) const
@@ -2972,6 +3019,35 @@ void MEDCoupling1DGTUMesh::unserialization(const std::vector<double>& tinyInfoD,
   _conn_indx->finishUnserialization(tinyInfo4,littleStrings4);
 }
 
+/*!
+ * Finds nodes not used in any cell and returns an array giving a new id to every node
+ * by excluding the unused nodes, for which the array holds -1. The result array is
+ * a mapping in "Old to New" mode.
+ *  \param [out] nbrOfNodesInUse - number of node ids present in the nodal connectivity.
+ *  \return DataArrayInt * - a new instance of DataArrayInt. Its length is \a
+ *          this->getNumberOfNodes(). It holds for each node of \a this mesh either -1
+ *          if the node is unused or a new id else. The caller is to delete this
+ *          array using decrRef() as it is no more needed.
+ *  \throw If the coordinates array is not set.
+ *  \throw If the nodal connectivity of cells is not defined.
+ *  \throw If the nodal connectivity includes an invalid id.
+ *  \sa MEDCoupling1DGTUMesh::computeFetchedNodeIds
+ */
+DataArrayInt *MEDCoupling1DGTUMesh::computeFetchedNodeIds() const
+{
+  checkCoherency2();
+  int nbNodes(getNumberOfNodes());
+  std::vector<bool> fetchedNodes(nbNodes,false);
+  computeNodeIdsAlg(fetchedNodes);
+  int sz((int)std::count(fetchedNodes.begin(),fetchedNodes.end(),true));
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(sz,1);
+  int *retPtr(ret->getPointer());
+  for(int i=0;i<nbNodes;i++)
+    if(fetchedNodes[i])
+      *retPtr++=i;
+  return ret.retn();
+}
+
 /*!
  * Finds nodes not used in any cell and returns an array giving a new id to every node
  * by excluding the unused nodes, for which the array holds -1. The result array is
@@ -2984,6 +3060,7 @@ void MEDCoupling1DGTUMesh::unserialization(const std::vector<double>& tinyInfoD,
  *  \throw If the coordinates array is not set.
  *  \throw If the nodal connectivity of cells is not defined.
  *  \throw If the nodal connectivity includes an invalid id.
+ *  \sa MEDCoupling1DGTUMesh::computeFetchedNodeIds
  */
 DataArrayInt *MEDCoupling1DGTUMesh::getNodeIdsInUse(int& nbrOfNodesInUse) const
 {
@@ -3016,6 +3093,41 @@ DataArrayInt *MEDCoupling1DGTUMesh::getNodeIdsInUse(int& nbrOfNodesInUse) const
   return ret.retn();
 }
 
+/*!
+ *  Same than renumberNodesInConn(const int *) except that here the format of old-to-new traducer is using map instead
+ *  of array. This method is dedicated for renumbering from a big set of nodes the a tiny set of nodes which is the case during extraction
+ *  of a big mesh.
+ */
+void MEDCoupling1DGTUMesh::renumberNodesInConn(const std::map<int,int>& newNodeNumbersO2N)
+{
+  getNumberOfCells();//only to check that all is well defined.
+  //
+  int nbElemsIn(getNumberOfNodes()),nbOfTuples(_conn->getNumberOfTuples());
+  int *pt(_conn->getPointer());
+  for(int i=0;i<nbOfTuples;i++,pt++)
+    {
+      if(*pt==-1) continue;
+      if(*pt>=0 && *pt<nbElemsIn)
+        {
+          std::map<int,int>::const_iterator it(newNodeNumbersO2N.find(*pt));
+          if(it!=newNodeNumbersO2N.end())
+            *pt=(*it).second;
+          else
+            {
+              std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::renumberNodesInConn : At pos #" << i << " of connectivity, node id is " << *pt << ". Not in keys of input map !";
+              throw INTERP_KERNEL::Exception(oss.str().c_str());
+            }
+        }
+      else
+        {
+          std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::renumberNodesInConn : error on tuple #" << i << " value is " << *pt << " and indirectionnal array as a size equal to " << nbElemsIn;
+          throw INTERP_KERNEL::Exception(oss.str().c_str());
+        }
+    }
+  //
+  updateTime();
+}
+
 /*!
  * Changes ids of nodes within the nodal connectivity arrays according to a permutation
  * array in "Old to New" mode. The node coordinates array is \b not changed by this method.
@@ -3030,9 +3142,8 @@ void MEDCoupling1DGTUMesh::renumberNodesInConn(const int *newNodeNumbersO2N)
 {
   getNumberOfCells();//only to check that all is well defined.
   //
-  int nbElemsIn=getNumberOfNodes();
-  int nbOfTuples=_conn->getNumberOfTuples();
-  int *pt=_conn->getPointer();
+  int nbElemsIn(getNumberOfNodes()),nbOfTuples(_conn->getNumberOfTuples());
+  int *pt(_conn->getPointer());
   for(int i=0;i<nbOfTuples;i++,pt++)
     {
       if(*pt==-1) continue;
@@ -3044,7 +3155,6 @@ void MEDCoupling1DGTUMesh::renumberNodesInConn(const int *newNodeNumbersO2N)
           throw INTERP_KERNEL::Exception(oss.str().c_str());
         }
     }
-  _conn->declareAsNew();
   //
   updateTime();
 }
index 4637c1146cb88650b86a10a6fe08d94631c34338..50169f5abeddf95de43d4f1642b310c59304950f 100644 (file)
@@ -128,7 +128,9 @@ namespace ParaMEDMEM
     MEDCOUPLING_EXPORT void getReverseNodalConnectivity(DataArrayInt *revNodal, DataArrayInt *revNodalIndx) const;
     MEDCOUPLING_EXPORT void checkFullyDefined() const;
     MEDCOUPLING_EXPORT bool isEmptyMesh(const std::vector<int>& tinyInfo) const;
+    MEDCOUPLING_EXPORT DataArrayInt *computeFetchedNodeIds() const;
     MEDCOUPLING_EXPORT DataArrayInt *getNodeIdsInUse(int& nbrOfNodesInUse) const;
+    MEDCOUPLING_EXPORT void renumberNodesInConn(const std::map<int,int>& newNodeNumbersO2N);
     MEDCOUPLING_EXPORT void renumberNodesInConn(const int *newNodeNumbersO2N);
     MEDCOUPLING_EXPORT void fillCellIdsToKeepFromNodeIds(const int *begin, const int *end, bool fullyIn, DataArrayInt *&cellIdsKeptArr) const;
     MEDCOUPLING_EXPORT int getNumberOfNodesInCell(int cellId) const;
@@ -218,7 +220,9 @@ namespace ParaMEDMEM
     MEDCOUPLING_EXPORT void getReverseNodalConnectivity(DataArrayInt *revNodal, DataArrayInt *revNodalIndx) const;
     MEDCOUPLING_EXPORT void checkFullyDefined() const;
     MEDCOUPLING_EXPORT bool isEmptyMesh(const std::vector<int>& tinyInfo) const;
+    MEDCOUPLING_EXPORT DataArrayInt *computeFetchedNodeIds() const;
     MEDCOUPLING_EXPORT DataArrayInt *getNodeIdsInUse(int& nbrOfNodesInUse) const;
+    MEDCOUPLING_EXPORT void renumberNodesInConn(const std::map<int,int>& newNodeNumbersO2N);
     MEDCOUPLING_EXPORT void renumberNodesInConn(const int *newNodeNumbersO2N);
     MEDCOUPLING_EXPORT void fillCellIdsToKeepFromNodeIds(const int *begin, const int *end, bool fullyIn, DataArrayInt *&cellIdsKeptArr) const;
     MEDCOUPLING_EXPORT int getNumberOfNodesInCell(int cellId) const;
index bfd8228454f303deffe039dbdb77d5436cb90555..dedfb16d1c03a21d437cabd3b52b4d95e78be3c8 100644 (file)
@@ -284,7 +284,7 @@ namespace ParaMEDMEM
     MEDCOUPLING_EXPORT double getIJSafe(int tupleId, int compoId) const;
     MEDCOUPLING_EXPORT void setIJ(int tupleId, int compoId, double newVal) { _mem[tupleId*_info_on_compo.size()+compoId]=newVal; declareAsNew(); }
     MEDCOUPLING_EXPORT void setIJSilent(int tupleId, int compoId, double newVal) { _mem[tupleId*_info_on_compo.size()+compoId]=newVal; }
-    MEDCOUPLING_EXPORT double *getPointer() { return _mem.getPointer(); }
+    MEDCOUPLING_EXPORT double *getPointer() { return _mem.getPointer(); declareAsNew(); }
     MEDCOUPLING_EXPORT static void SetArrayIn(DataArrayDouble *newArray, DataArrayDouble* &arrayToSet);
     MEDCOUPLING_EXPORT const double *getConstPointer() const { return _mem.getConstPointer(); }
     MEDCOUPLING_EXPORT DataArrayDoubleIterator *iterator();
@@ -527,7 +527,7 @@ namespace ParaMEDMEM
     MEDCOUPLING_EXPORT int back() const;
     MEDCOUPLING_EXPORT void setIJ(int tupleId, int compoId, int newVal) { _mem[tupleId*_info_on_compo.size()+compoId]=newVal; declareAsNew(); }
     MEDCOUPLING_EXPORT void setIJSilent(int tupleId, int compoId, int newVal) { _mem[tupleId*_info_on_compo.size()+compoId]=newVal; }
-    MEDCOUPLING_EXPORT int *getPointer() { return _mem.getPointer(); }
+    MEDCOUPLING_EXPORT int *getPointer() { return _mem.getPointer(); declareAsNew(); }
     MEDCOUPLING_EXPORT static void SetArrayIn(DataArrayInt *newArray, DataArrayInt* &arrayToSet);
     MEDCOUPLING_EXPORT const int *getConstPointer() const { return _mem.getConstPointer(); }
     MEDCOUPLING_EXPORT DataArrayIntIterator *iterator();
@@ -727,7 +727,7 @@ namespace ParaMEDMEM
     MEDCOUPLING_EXPORT char back() const;
     MEDCOUPLING_EXPORT void setIJ(int tupleId, int compoId, char newVal) { _mem[tupleId*_info_on_compo.size()+compoId]=newVal; declareAsNew(); }
     MEDCOUPLING_EXPORT void setIJSilent(int tupleId, int compoId, char newVal) { _mem[tupleId*_info_on_compo.size()+compoId]=newVal; }
-    MEDCOUPLING_EXPORT char *getPointer() { return _mem.getPointer(); }
+    MEDCOUPLING_EXPORT char *getPointer() { return _mem.getPointer(); declareAsNew(); }
     MEDCOUPLING_EXPORT const char *getConstPointer() const { return _mem.getConstPointer(); }
     MEDCOUPLING_EXPORT const char *begin() const { return getConstPointer(); }
     MEDCOUPLING_EXPORT const char *end() const { return getConstPointer()+getNbOfElems(); }
index c9bdc4e5588caf245e15ef5e6fc0005177adfb8d..59307c6a86d0b0cff9ed484a848bbd95cd945b1e 100644 (file)
@@ -24,6 +24,7 @@
 #include "MEDCoupling.hxx"
 #include "MEDCouplingMesh.hxx"
 
+#include <map>
 #include <vector>
 
 namespace INTERP_KERNEL
@@ -119,9 +120,11 @@ namespace ParaMEDMEM
     MEDCOUPLING_EXPORT virtual DataArrayInt *findBoundaryNodes() const = 0;
     MEDCOUPLING_EXPORT virtual MEDCouplingPointSet *buildBoundaryMesh(bool keepCoords) const = 0;
     MEDCOUPLING_EXPORT virtual int getNumberOfNodesInCell(int cellId) const = 0;
+    MEDCOUPLING_EXPORT virtual DataArrayInt *computeFetchedNodeIds() const = 0;
     MEDCOUPLING_EXPORT virtual DataArrayInt *getNodeIdsInUse(int& nbrOfNodesInUse) const = 0;
     MEDCOUPLING_EXPORT virtual void fillCellIdsToKeepFromNodeIds(const int *begin, const int *end, bool fullyIn, DataArrayInt *&cellIdsKeptArr) const = 0;
     MEDCOUPLING_EXPORT virtual void renumberNodesInConn(const int *newNodeNumbersO2N) = 0;
+    MEDCOUPLING_EXPORT virtual void renumberNodesInConn(const std::map<int,int>& newNodeNumbersO2N) = 0;
     MEDCOUPLING_EXPORT virtual void renumberNodes(const int *newNodeNumbers, int newNbOfNodes);
     MEDCOUPLING_EXPORT virtual void renumberNodes2(const int *newNodeNumbers, int newNbOfNodes);
     MEDCOUPLING_EXPORT virtual bool isEmptyMesh(const std::vector<int>& tinyInfo) const = 0;
index d8ba414535e787e130d6a99626f70354f4cb6d31..41784fb2fbebfd2e81d0110352b4853e7e87ce7b 100644 (file)
@@ -1425,10 +1425,8 @@ DataArrayInt *MEDCouplingUMesh::computeFetchedNodeIds() const
  */
 void MEDCouplingUMesh::computeNodeIdsAlg(std::vector<bool>& nodeIdsInUse) const
 {
-  int nbOfNodes=(int)nodeIdsInUse.size();
-  int nbOfCells=getNumberOfCells();
-  const int *connIndex=_nodal_connec_index->getConstPointer();
-  const int *conn=_nodal_connec->getConstPointer();
+  int nbOfNodes((int)nodeIdsInUse.size()),nbOfCells(getNumberOfCells());
+  const int *connIndex(_nodal_connec_index->getConstPointer()),*conn(_nodal_connec->getConstPointer());
   for(int i=0;i<nbOfCells;i++)
     for(int j=connIndex[i]+1;j<connIndex[i+1];j++)
       if(conn[j]>=0)
@@ -1437,7 +1435,7 @@ void MEDCouplingUMesh::computeNodeIdsAlg(std::vector<bool>& nodeIdsInUse) const
             nodeIdsInUse[conn[j]]=true;
           else
             {
-              std::ostringstream oss; oss << "MEDCouplingUMesh::getNodeIdsInUse : In cell #" << i  << " presence of node id " <<  conn[j] << " not in [0," << nbOfNodes << ") !";
+              std::ostringstream oss; oss << "MEDCouplingUMesh::computeNodeIdsAlg : In cell #" << i  << " presence of node id " <<  conn[j] << " not in [0," << nbOfNodes << ") !";
               throw INTERP_KERNEL::Exception(oss.str().c_str());
             }
         }
@@ -1460,12 +1458,12 @@ void MEDCouplingUMesh::computeNodeIdsAlg(std::vector<bool>& nodeIdsInUse) const
  *  \ref cpp_mcumesh_getNodeIdsInUse "Here is a C++ example".<br>
  *  \ref  py_mcumesh_getNodeIdsInUse "Here is a Python example".
  *  \endif
- * \sa computeNodeIdsAlg()
+ * \sa computeFetchedNodeIds, computeNodeIdsAlg()
  */
 DataArrayInt *MEDCouplingUMesh::getNodeIdsInUse(int& nbrOfNodesInUse) const
 {
   nbrOfNodesInUse=-1;
-  int nbOfNodes=getNumberOfNodes();
+  int nbOfNodes(getNumberOfNodes());
   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
   ret->alloc(nbOfNodes,1);
   int *traducer=ret->getPointer();
@@ -2499,6 +2497,39 @@ void MEDCouplingUMesh::duplicateNodes(const int *nodeIdsToDuplicateBg, const int
   duplicateNodesInConn(nodeIdsToDuplicateBg,nodeIdsToDuplicateEnd,nbOfNodes);
 }
 
+/*!
+ *  Same than renumberNodesInConn(const int *) except that here the format of old-to-new traducer is using map instead
+ *  of array. This method is dedicated for renumbering from a big set of nodes the a tiny set of nodes which is the case during extraction
+ *  of a big mesh.
+ */
+void MEDCouplingUMesh::renumberNodesInConn(const std::map<int,int>& newNodeNumbersO2N)
+{
+  checkConnectivityFullyDefined();
+  int *conn(getNodalConnectivity()->getPointer());
+  const int *connIndex(getNodalConnectivityIndex()->getConstPointer());
+  int nbOfCells=getNumberOfCells();
+  for(int i=0;i<nbOfCells;i++)
+    for(int iconn=connIndex[i]+1;iconn!=connIndex[i+1];iconn++)
+      {
+        int& node=conn[iconn];
+        if(node>=0)//avoid polyhedron separator
+          {
+            std::map<int,int>::const_iterator it(newNodeNumbersO2N.find(node));
+            if(it!=newNodeNumbersO2N.end())
+              {
+                node=(*it).second;
+              }
+            else
+              {
+                std::ostringstream oss; oss << "MEDCouplingUMesh::renumberNodesInConn(map) : presence in connectivity for cell #" << i << " of node #" << node << " : Not in map !";
+                throw INTERP_KERNEL::Exception(oss.str().c_str());
+              }
+          }
+      }
+  _nodal_connec->declareAsNew();
+  updateTime();
+}
+
 /*!
  * Changes ids of nodes within the nodal connectivity arrays according to a permutation
  * array in "Old to New" mode. The node coordinates array is \b not changed by this method.
index 7f3aa5d7b0876bbcc69f474540dfebb327fab06a..38adadf3d9c88bae953a4b56c73c8457ffd0e863 100644 (file)
@@ -140,6 +140,7 @@ namespace ParaMEDMEM
     MEDCOUPLING_EXPORT void findNodesToDuplicate(const MEDCouplingUMesh& otherDimM1OnSameCoords, DataArrayInt *& nodeIdsToDuplicate,
                                                  DataArrayInt *& cellIdsNeededToBeRenum, DataArrayInt *& cellIdsNotModified) const;
     MEDCOUPLING_EXPORT void duplicateNodes(const int *nodeIdsToDuplicateBg, const int *nodeIdsToDuplicateEnd);
+    MEDCOUPLING_EXPORT void renumberNodesInConn(const std::map<int,int>& newNodeNumbersO2N);
     MEDCOUPLING_EXPORT void renumberNodesInConn(const int *newNodeNumbersO2N);
     MEDCOUPLING_EXPORT void shiftNodeNumbersInConn(int delta);
     MEDCOUPLING_EXPORT void duplicateNodesInConn(const int *nodeIdsToDuplicateBg, const int *nodeIdsToDuplicateEnd, int offset);
index 19301bb7d4680e3efd9825fd4c9f3e19a6692ac1..0587b0f97a8e79915c3ec5842448341314d59a98 100644 (file)
@@ -15905,6 +15905,20 @@ class MEDCouplingBasicsTest(unittest.TestCase):
         self.assertTrue(d.isEqual(DataArrayDouble([(7.,7.),(7.,7.),(7.,7.)]),1e-12))
         pass
 
+    def testSwig2PointSetComputeFetchedNodeIds1(self):
+        arr=DataArrayDouble(6) ; arr.iota()
+        m=MEDCouplingCMesh() ; m.setCoords(arr,arr,arr)
+        m=m.buildUnstructured()
+        m0=m[[0,1,5,6,25,26,30,31,124]]
+        ref=DataArrayInt([0,1,2,6,7,8,12,13,14,36,37,38,42,43,44,48,49,50,72,73,74,78,79,80,84,85,86,172,173,178,179,208,209,214,215])
+        self.assertTrue(m0.computeFetchedNodeIds().isEqual(ref))
+        self.assertTrue(MEDCoupling1SGTUMesh(m0).computeFetchedNodeIds().isEqual(ref))
+        self.assertEqual(m0.getAllGeoTypes(),[NORM_HEXA8])
+        m0.convertAllToPoly()
+        self.assertEqual(m0.getAllGeoTypes(),[NORM_POLYHED])
+        self.assertTrue(MEDCoupling1DGTUMesh(m0).computeFetchedNodeIds().isEqual(ref))
+        pass
+
     pass
 
 if __name__ == '__main__':
index b0928bc9202afc0cf1fcef65f99bd493d3c0be7b..01bc5e64c46ef1852b9f157e81d4f1a1f2044a28 100644 (file)
@@ -245,6 +245,7 @@ using namespace INTERP_KERNEL;
 %newobject ParaMEDMEM::MEDCouplingPointSet::getCellIdsLyingOnNodes;
 %newobject ParaMEDMEM::MEDCouplingPointSet::deepCpyConnectivityOnly;
 %newobject ParaMEDMEM::MEDCouplingPointSet::getBoundingBoxForBBTree;
+%newobject ParaMEDMEM::MEDCouplingPointSet::computeFetchedNodeIds;
 %newobject ParaMEDMEM::MEDCouplingPointSet::ComputeNbOfInteractionsWithSrcCells;
 %newobject ParaMEDMEM::MEDCouplingPointSet::__getitem__;
 %newobject ParaMEDMEM::MEDCouplingUMesh::New;
@@ -269,7 +270,6 @@ using namespace INTERP_KERNEL;
 %newobject ParaMEDMEM::MEDCouplingUMesh::sortCellsInMEDFileFrmt;
 %newobject ParaMEDMEM::MEDCouplingUMesh::getRenumArrForMEDFileFrmt;
 %newobject ParaMEDMEM::MEDCouplingUMesh::convertCellArrayPerGeoType;
-%newobject ParaMEDMEM::MEDCouplingUMesh::computeFetchedNodeIds;
 %newobject ParaMEDMEM::MEDCouplingUMesh::getRenumArrForConsecutiveCellTypesSpec;
 %newobject ParaMEDMEM::MEDCouplingUMesh::buildDirectionVectorField;
 %newobject ParaMEDMEM::MEDCouplingUMesh::convertLinearCellsToQuadratic;
@@ -1040,6 +1040,7 @@ namespace ParaMEDMEM
       static DataArrayDouble *MergeNodesArray(const MEDCouplingPointSet *m1, const MEDCouplingPointSet *m2) throw(INTERP_KERNEL::Exception);
       static MEDCouplingPointSet *BuildInstanceFromMeshType(MEDCouplingMeshType type) throw(INTERP_KERNEL::Exception);
       static DataArrayInt *ComputeNbOfInteractionsWithSrcCells(const MEDCouplingPointSet *srcMesh, const MEDCouplingPointSet *trgMesh, double eps) throw(INTERP_KERNEL::Exception);
+      virtual DataArrayInt *computeFetchedNodeIds() const throw(INTERP_KERNEL::Exception);
       virtual int getNumberOfNodesInCell(int cellId) const throw(INTERP_KERNEL::Exception);
       virtual MEDCouplingPointSet *buildBoundaryMesh(bool keepCoords) const throw(INTERP_KERNEL::Exception);
       virtual DataArrayInt *getCellsInBoundingBox(const INTERP_KERNEL::DirectedBoundingBox& bbox, double eps) throw(INTERP_KERNEL::Exception);
@@ -1631,7 +1632,6 @@ namespace ParaMEDMEM
     DataArrayInt *sortCellsInMEDFileFrmt() throw(INTERP_KERNEL::Exception);
     DataArrayInt *getRenumArrForMEDFileFrmt() const throw(INTERP_KERNEL::Exception);
     DataArrayInt *convertCellArrayPerGeoType(const DataArrayInt *da) const throw(INTERP_KERNEL::Exception);
-    DataArrayInt *computeFetchedNodeIds() const throw(INTERP_KERNEL::Exception);
     MEDCouplingUMesh *buildDescendingConnectivity(DataArrayInt *desc, DataArrayInt *descIndx, DataArrayInt *revDesc, DataArrayInt *revDescIndx) const throw(INTERP_KERNEL::Exception);
     MEDCouplingUMesh *buildDescendingConnectivity2(DataArrayInt *desc, DataArrayInt *descIndx, DataArrayInt *revDesc, DataArrayInt *revDescIndx) const throw(INTERP_KERNEL::Exception);
     MEDCouplingUMesh *explode3DMeshTo1D(DataArrayInt *desc, DataArrayInt *descIndx, DataArrayInt *revDesc, DataArrayInt *revDescIndx) const throw(INTERP_KERNEL::Exception);
index 95a94758522fa26a4d14c9e4c1c047fe3fb424d9..aad1dfd60c5b3d7026f5661aa430eb3c9955b421 100644 (file)
@@ -1983,6 +1983,40 @@ MEDFileUMesh *MEDFileUMesh::New()
   return new MEDFileUMesh;
 }
 
+/*!
+ * This method loads from file with name \a fileName the mesh called \a mName as New does. The difference is that
+ * here only a part of cells contained in the file will be loaded. The selection of cell is specified using the two consecutive parameters
+ * \a types and \a slicPerTyp. This method allows to load from a mesh (typically huge) in a MED file a part of cells of that mesh.
+ * The part of cells is specified using triplet (start,stop,step) for each geometric type. Only nodes lying on selected cells will be loaded to reduce
+ * at most the memory consumtion.
+ *
+ * \param [in] fileName - the name of the file.
+ * \param [in] mName - the name of the mesh to be read.
+ * \param [in] types - the list of the geo types of which some part will be taken. A geometric type in \a types must appear only once at most.
+ * \param [in] slicPerType - an array of size 3 times larger than \a types that specifies for each type in \a types (in the same order) resp the start, the stop and the step.
+ * \param [in] dt - the iteration, that is to say the first element of the pair that locates the asked time step.
+ * \param [in] it - the order, that is to say the second element of the pair that locates the asked time step.
+ * \param [in] mrs - the request for what to be loaded.
+ * \return MEDFileUMesh * - a new instance of MEDFileUMesh. The caller is to delete this mesh using decrRef() as it is no more needed.
+ */
+MEDFileUMesh *MEDFileUMesh::LoadPartOf(const std::string& fileName, const std::string& mName, const std::vector<INTERP_KERNEL::NormalizedCellType>& types, const std::vector<int>& slicPerTyp, int dt, int it, MEDFileMeshReadSelector *mrs)
+{
+  MEDFileUtilities::CheckFileForRead(fileName);
+  MEDFileUtilities::AutoFid fid(MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY));
+  return MEDFileUMesh::LoadPartOf(fid,mName,types,slicPerTyp,dt,it,mrs);
+}
+
+/*!
+ * Please refer to the other MEDFileUMesh::LoadPartOf method that has the same semantic and the same parameter (excepted the first).
+ * This method is \b NOT wrapped into python.
+ */
+MEDFileUMesh *MEDFileUMesh::LoadPartOf(med_idt fid, const std::string& mName, const std::vector<INTERP_KERNEL::NormalizedCellType>& types, const std::vector<int>& slicPerTyp, int dt, int it, MEDFileMeshReadSelector *mrs)
+{
+  MEDCouplingAutoRefCountObjectPtr<MEDFileUMesh> ret(MEDFileUMesh::New());
+  ret->loadPartUMeshFromFile(fid,mName,types,slicPerTyp,dt,it,mrs);
+  return ret.retn();
+}
+
 std::size_t MEDFileUMesh::getHeapMemorySizeWithoutChildren() const
 {
   std::size_t ret(MEDFileMesh::getHeapMemorySizeWithoutChildren());
@@ -2192,19 +2226,52 @@ catch(INTERP_KERNEL::Exception& e)
     throw e;
 }
 
+/*!
+ * This method loads only a part of specified cells (given by range of cell ID per geometric type)
+ * See MEDFileUMesh::LoadPartOf for detailed description.
+ *
+ * \sa loadUMeshFromFile
+ */
+void MEDFileUMesh::loadPartUMeshFromFile(med_idt fid, const std::string& mName, const std::vector<INTERP_KERNEL::NormalizedCellType>& types, const std::vector<int>& slicPerTyp, int dt, int it, MEDFileMeshReadSelector *mrs)
+{
+  MEDFileUMeshL2 loaderl2;
+  ParaMEDMEM::MEDCouplingMeshType meshType;
+  int dummy0,dummy1;
+  std::string dummy2;
+  int mid(MEDFileUMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy0,dummy1,dummy2));
+  if(meshType!=UNSTRUCTURED)
+    {
+      std::ostringstream oss; oss << "loadPartUMeshFromFile : Trying to load as unstructured an existing mesh with name '" << mName << "' !";
+      throw INTERP_KERNEL::Exception(oss.str().c_str());
+    }
+  loaderl2.loadPart(fid,mid,mName,types,slicPerTyp,dt,it,mrs);
+  dispatchLoadedPart(fid,loaderl2,mName,mrs);
+}
+
+/*!
+ * This method loads \b all \b the \b mesh \a mName in the file with \a fid descriptor.
+ *
+ * \sa loadPartUMeshFromFile
+ */
 void MEDFileUMesh::loadUMeshFromFile(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
 {
   MEDFileUMeshL2 loaderl2;
   ParaMEDMEM::MEDCouplingMeshType meshType;
   int dummy0,dummy1;
   std::string dummy2;
-  int mid=MEDFileUMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy0,dummy1,dummy2);
+  int mid(MEDFileUMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy0,dummy1,dummy2));
   if(meshType!=UNSTRUCTURED)
     {
       std::ostringstream oss; oss << "Trying to load as unstructured an existing mesh with name '" << mName << "' !";
       throw INTERP_KERNEL::Exception(oss.str().c_str());
     }
   loaderl2.loadAll(fid,mid,mName,dt,it,mrs);
+  dispatchLoadedPart(fid,loaderl2,mName,mrs);
+
+}
+
+void MEDFileUMesh::dispatchLoadedPart(med_idt fid, const MEDFileUMeshL2& loaderl2, const std::string& mName, MEDFileMeshReadSelector *mrs)
+{
   int lev=loaderl2.getNumberOfLevels();
   _ms.resize(lev);
   for(int i=0;i<lev;i++)
index c2a0eeab706632334c0e606b345ad9297dc75aa6..a25401aea92ea82c52c5967d07010ca4991981bd 100644 (file)
@@ -200,6 +200,8 @@ namespace ParaMEDMEM
     MEDLOADER_EXPORT static MEDFileUMesh *New(const std::string& fileName, const std::string& mName, int dt=-1, int it=-1, MEDFileMeshReadSelector *mrs=0);
     MEDLOADER_EXPORT static MEDFileUMesh *New(const std::string& fileName, MEDFileMeshReadSelector *mrs=0);
     MEDLOADER_EXPORT static MEDFileUMesh *New();
+    MEDLOADER_EXPORT static MEDFileUMesh *LoadPartOf(const std::string& fileName, const std::string& mName, const std::vector<INTERP_KERNEL::NormalizedCellType>& types, const std::vector<int>& slicPerTyp, int dt=-1, int it=-1, MEDFileMeshReadSelector *mrs=0);
+    MEDLOADER_EXPORT static MEDFileUMesh *LoadPartOf(med_idt fid, const std::string& mName, const std::vector<INTERP_KERNEL::NormalizedCellType>& types, const std::vector<int>& slicPerTyp, int dt=-1, int it=-1, MEDFileMeshReadSelector *mrs=0);
     MEDLOADER_EXPORT std::size_t getHeapMemorySizeWithoutChildren() const;
     MEDLOADER_EXPORT std::vector<const BigMemoryObject *> getDirectChildrenWithNull() const;
     MEDLOADER_EXPORT MEDFileMesh *createNewEmpty() const;
@@ -284,7 +286,9 @@ namespace ParaMEDMEM
     void writeLL(med_idt fid) const;
     MEDFileUMesh();
     MEDFileUMesh(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs);
+    void loadPartUMeshFromFile(med_idt fid, const std::string& mName, const std::vector<INTERP_KERNEL::NormalizedCellType>& types, const std::vector<int>& slicPerTyp, int dt=-1, int it=-1, MEDFileMeshReadSelector *mrs=0);
     void loadUMeshFromFile(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs);
+    void dispatchLoadedPart(med_idt fid, const MEDFileUMeshL2& loaderl2, const std::string& mName, MEDFileMeshReadSelector *mrs);
     const MEDFileUMeshSplitL1 *getMeshAtLevSafe(int meshDimRelToMaxExt) const;
     MEDFileUMeshSplitL1 *getMeshAtLevSafe(int meshDimRelToMaxExt);
     void checkMeshDimCoherency(int meshDim, int meshDimRelToMax) const;
index 00980e5b13f8f33db74b2ebf06bccebd5702a753..ce16d0da1797ec81a53129dc1d7ec7287a78d397 100644 (file)
@@ -23,6 +23,7 @@
 
 #include "MEDCouplingUMesh.hxx"
 
+#include "InterpKernelException.hxx"
 #include "InterpKernelAutoPtr.hxx"
 #include "CellModel.hxx"
 
@@ -40,6 +41,20 @@ MEDFileUMeshPerType *MEDFileUMeshPerType::New(med_idt fid, const char *mName, in
   return new MEDFileUMeshPerType(fid,mName,dt,it,mdim,geoElt,geoElt2,whichEntity,mrs);
 }
 
+MEDFileUMeshPerType *MEDFileUMeshPerType::NewPart(med_idt fid, const char *mName, int dt, int it, int mdim, INTERP_KERNEL::NormalizedCellType geoElt2, int strt, int stp, int step, MEDFileMeshReadSelector *mrs)
+{
+  int geoElt2i((int)geoElt2);
+  if(geoElt2i<0 || geoElt2i>=34)
+    throw INTERP_KERNEL::Exception("MEDFileUMeshPerType::NewPart : Not recognized MEDCoupling/MEDLoader geometric type !");
+  med_geometry_type geoElt(typmai3[geoElt2]);
+  med_entity_type whichEntity;
+  if(!isExisting(fid,mName,dt,it,geoElt,whichEntity))
+    throw INTERP_KERNEL::Exception("MEDFileUMeshPerType::NewPart : The specified geo type is not present in the specified mesh !");
+  MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshPerType> ret(new MEDFileUMeshPerType);
+  ret->loadPart(fid,mName,dt,it,mdim,geoElt,geoElt2,whichEntity,strt,stp,step,mrs);
+  return ret.retn();
+}
+
 std::size_t MEDFileUMeshPerType::getHeapMemorySizeWithoutChildren() const
 {
   return 0;
@@ -62,8 +77,7 @@ bool MEDFileUMeshPerType::isExisting(med_idt fid, const char *mName, int dt, int
   for(int i=0;i<3;i++)
     {
       med_bool changement,transformation;
-      int tmp=MEDmeshnEntity(fid,mName,dt,it,entities[i],geoElt,MED_CONNECTIVITY,MED_NODAL,
-          &changement,&transformation);
+      int tmp=MEDmeshnEntity(fid,mName,dt,it,entities[i],geoElt,MED_CONNECTIVITY,MED_NODAL,&changement,&transformation);
       if(tmp>nbOfElt)
         {
           nbOfElt=tmp;
@@ -80,13 +94,16 @@ int MEDFileUMeshPerType::getDim() const
   return _m->getMeshDimension();
 }
 
+MEDFileUMeshPerType::MEDFileUMeshPerType()
+{
+}
+
 MEDFileUMeshPerType::MEDFileUMeshPerType(med_idt fid, const char *mName, int dt, int it, int mdim, med_geometry_type geoElt, INTERP_KERNEL::NormalizedCellType type,
                                          med_entity_type entity, MEDFileMeshReadSelector *mrs):_entity(entity)
 {
   med_bool changement,transformation;
-  int curNbOfElem=MEDmeshnEntity(fid,mName,dt,it,entity,geoElt,MED_CONNECTIVITY,MED_NODAL,
-      &changement,&transformation);
-  const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(type);
+  int curNbOfElem(MEDmeshnEntity(fid,mName,dt,it,entity,geoElt,MED_CONNECTIVITY,MED_NODAL,&changement,&transformation));
+  const INTERP_KERNEL::CellModel& cm(INTERP_KERNEL::CellModel::GetCellModel(type));
   if(!cm.isDynamic())
     {
       loadFromStaticType(fid,mName,dt,it,mdim,curNbOfElem,geoElt,type,entity,mrs);
@@ -101,13 +118,27 @@ MEDFileUMeshPerType::MEDFileUMeshPerType(med_idt fid, const char *mName, int dt,
   loadPolyh(fid,mName,dt,it,mdim,curNbOfElem,geoElt,entity,mrs);
 }
 
+void MEDFileUMeshPerType::loadPart(med_idt fid, const char *mName, int dt, int it, int mdim, med_geometry_type geoElt, INTERP_KERNEL::NormalizedCellType type,
+                                   med_entity_type entity, int strt, int end, int step, MEDFileMeshReadSelector *mrs)
+{
+  med_bool changement,transformation;
+  int curNbOfElem(MEDmeshnEntity(fid,mName,dt,it,entity,geoElt,MED_CONNECTIVITY,MED_NODAL,&changement,&transformation));
+  const INTERP_KERNEL::CellModel& cm(INTERP_KERNEL::CellModel::GetCellModel(type));
+  if(!cm.isDynamic())
+    {
+      loadPartStaticType(fid,mName,dt,it,mdim,curNbOfElem,geoElt,type,entity,strt,end,step,mrs);
+    }
+  else
+    throw INTERP_KERNEL::Exception("MEDFileUMeshPerType::loadPart : not implemented yet for the dynamic type !");
+}
+
 void MEDFileUMeshPerType::loadFromStaticType(med_idt fid, const char *mName, int dt, int it, int mdim, int curNbOfElem, med_geometry_type geoElt, INTERP_KERNEL::NormalizedCellType type,
                                              med_entity_type entity, MEDFileMeshReadSelector *mrs)
 {
   _m=MEDCoupling1SGTUMesh::New(mName,type);
   MEDCoupling1SGTUMesh *mc(dynamic_cast<MEDCoupling1SGTUMesh *>((MEDCoupling1GTUMesh *)_m));
   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> conn(DataArrayInt::New());
-  int nbOfNodesPerCell=mc->getNumberOfNodesPerCell();
+  int nbOfNodesPerCell(mc->getNumberOfNodesPerCell());
   conn->alloc(nbOfNodesPerCell*curNbOfElem,1);
   MEDmeshElementConnectivityRd(fid,mName,dt,it,entity,geoElt,MED_NODAL,MED_FULL_INTERLACE,conn->getPointer());
   std::transform(conn->begin(),conn->end(),conn->getPointer(),std::bind2nd(std::plus<int>(),-1));
@@ -115,6 +146,31 @@ void MEDFileUMeshPerType::loadFromStaticType(med_idt fid, const char *mName, int
   loadCommonPart(fid,mName,dt,it,mdim,curNbOfElem,geoElt,entity,mrs);
 }
 
+void MEDFileUMeshPerType::loadPartStaticType(med_idt fid, const char *mName, int dt, int it, int mdim, int curNbOfElem, med_geometry_type geoElt, INTERP_KERNEL::NormalizedCellType type,
+                                             med_entity_type entity, int strt, int end, int step, MEDFileMeshReadSelector *mrs)
+{
+  if(strt<0)
+    throw INTERP_KERNEL::Exception("MEDFileUMeshPerType::loadPartStaticType : start pos is negative !");
+  if(end>curNbOfElem)
+    throw INTERP_KERNEL::Exception("MEDFileUMeshPerType::loadPartStaticType : end is after the authorized range !");
+  int nbOfEltsToLoad(DataArray::GetNumberOfItemGivenBES(strt,end,step,"MEDFileUMeshPerType::loadPartStaticType"));
+  _m=MEDCoupling1SGTUMesh::New(mName,type);
+  MEDCoupling1SGTUMesh *mc(dynamic_cast<MEDCoupling1SGTUMesh *>((MEDCoupling1GTUMesh *)_m));
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> conn(DataArrayInt::New());
+  int nbOfNodesPerCell(mc->getNumberOfNodesPerCell());
+  conn->alloc(nbOfNodesPerCell*nbOfEltsToLoad,1);
+  med_filter filter=MED_FILTER_INIT;
+  MEDfilterBlockOfEntityCr(fid,/*nentity*/curNbOfElem,/*nvaluesperentity*/1,/*nconstituentpervalue*/nbOfNodesPerCell,
+                           MED_ALL_CONSTITUENT,MED_FULL_INTERLACE,MED_COMPACT_STMODE,MED_NO_PROFILE,
+                           /*start*/strt+1,/*stride*/step,/*count*/1,/*blocksize*/nbOfEltsToLoad,
+                           /*lastblocksize=useless because count=1*/0,&filter);
+  MEDmeshElementConnectivityAdvancedRd(fid,mName,dt,it,entity,geoElt,MED_NODAL,&filter,conn->getPointer());
+  MEDfilterClose(&filter);
+  std::transform(conn->begin(),conn->end(),conn->getPointer(),std::bind2nd(std::plus<int>(),-1));
+  mc->setNodalConnectivity(conn);
+  loadPartOfCellCommonPart(fid,mName,strt,end,step,dt,it,mdim,curNbOfElem,geoElt,entity,mrs);
+}
+
 void MEDFileUMeshPerType::loadCommonPart(med_idt fid, const char *mName, int dt, int it, int mdim, int curNbOfElem, med_geometry_type geoElt,
                                          med_entity_type entity, MEDFileMeshReadSelector *mrs)
 {
@@ -156,6 +212,65 @@ void MEDFileUMeshPerType::loadCommonPart(med_idt fid, const char *mName, int dt,
     }
 }
 
+void MEDFileUMeshPerType::loadPartOfCellCommonPart(med_idt fid, const char *mName, int strt, int stp, int step, int dt, int it, int mdim, int curNbOfElem, med_geometry_type geoElt, med_entity_type entity, MEDFileMeshReadSelector *mrs)
+{
+  med_bool changement,transformation;
+  _fam=0;
+  int nbOfEltsToLoad(DataArray::GetNumberOfItemGivenBES(strt,stp,step,"MEDFileUMeshPerType::loadPartOfCellCommonPart"));
+  if(MEDmeshnEntity(fid,mName,dt,it,entity,geoElt,MED_FAMILY_NUMBER,MED_NODAL,&changement,&transformation)>0)
+    {
+      if(!mrs || mrs->isCellFamilyFieldReading())
+        {
+          _fam=DataArrayInt::New();
+          _fam->alloc(nbOfEltsToLoad,1);
+          med_filter filter=MED_FILTER_INIT;
+          MEDfilterBlockOfEntityCr(fid,/*nentity*/curNbOfElem,/*nvaluesperentity*/1,/*nconstituentpervalue*/1,
+                                   MED_ALL_CONSTITUENT,MED_FULL_INTERLACE,MED_COMPACT_STMODE,MED_NO_PROFILE,
+                                   /*start*/strt+1,/*stride*/step,/*count*/1,/*blocksize*/nbOfEltsToLoad,
+                                   /*lastblocksize=useless because count=1*/0,&filter);
+          if(MEDmeshEntityAttributeAdvancedRd(fid,mName,MED_FAMILY_NUMBER,dt,it,entity,geoElt,&filter,_fam->getPointer())!=0)
+            _fam->fillWithZero();
+          MEDfilterClose(&filter);
+        }
+    }
+  _num=0;
+  if(MEDmeshnEntity(fid,mName,dt,it,entity,geoElt,MED_NUMBER,MED_NODAL,&changement,&transformation)>0)
+    {
+      if(!mrs || mrs->isCellNumFieldReading())
+        {
+          _num=DataArrayInt::New();
+          _num->alloc(nbOfEltsToLoad,1);
+          med_filter filter=MED_FILTER_INIT;
+          MEDfilterBlockOfEntityCr(fid,/*nentity*/curNbOfElem,/*nvaluesperentity*/1,/*nconstituentpervalue*/1,
+                                   MED_ALL_CONSTITUENT,MED_FULL_INTERLACE,MED_COMPACT_STMODE,MED_NO_PROFILE,
+                                   /*start*/strt+1,/*stride*/step,/*count*/1,/*blocksize*/nbOfEltsToLoad,
+                                   /*lastblocksize=useless because count=1*/0,&filter);
+          if(MEDmeshEntityAttributeAdvancedRd(fid,mName,MED_NUMBER,dt,it,entity,geoElt,&filter,_num->getPointer())!=0)
+            _num->fillWithZero();
+          MEDfilterClose(&filter);
+        }
+    }
+  _names=0;
+  if(MEDmeshnEntity(fid,mName,dt,it,entity,geoElt,MED_NAME,MED_NODAL,&changement,&transformation)>0)
+    {
+      if(!mrs || mrs->isCellNameFieldReading())
+        {
+          _names=DataArrayAsciiChar::New();
+          _names->alloc(nbOfEltsToLoad+1,MED_SNAME_SIZE);//not a bug to avoid the memory corruption due to last \0 at the end
+          med_filter filter=MED_FILTER_INIT;
+          MEDfilterBlockOfEntityCr(fid,/*nentity*/curNbOfElem,/*nvaluesperentity*/1,/*nconstituentpervalue*/1,
+                                   MED_ALL_CONSTITUENT,MED_FULL_INTERLACE,MED_COMPACT_STMODE,MED_NO_PROFILE,
+                                   /*start*/strt+1,/*stride*/step,/*count*/1,/*blocksize*/nbOfEltsToLoad,
+                                   /*lastblocksize=useless because count=1*/0,&filter);
+          if(MEDmeshEntityAttributeAdvancedRd(fid,mName,MED_NAME,dt,it,entity,geoElt,&filter,_names->getPointer())!=0)
+            _names=0;
+          else
+            _names->reAlloc(nbOfEltsToLoad);//not a bug to avoid the memory corruption due to last \0 at the end
+          MEDfilterClose(&filter);
+        }
+    }
+}
+
 void MEDFileUMeshPerType::loadPolyg(med_idt fid, const char *mName, int dt, int it, int mdim, int arraySize, med_geometry_type geoElt,
                                     med_entity_type entity, MEDFileMeshReadSelector *mrs)
 {
index 93be1e33865fc4b3934175a9777732736bf7fa09..ed795f1596222beead40cfe3afd71bb64a4f36bf 100644 (file)
@@ -38,6 +38,7 @@ namespace ParaMEDMEM
   {
   public:
     static MEDFileUMeshPerType *New(med_idt fid, const char *mName, int dt, int it, int mdim, med_geometry_type geoElt, INTERP_KERNEL::NormalizedCellType geoElt2, MEDFileMeshReadSelector *mrs);
+    static MEDFileUMeshPerType *NewPart(med_idt fid, const char *mName, int dt, int it, int mdim, INTERP_KERNEL::NormalizedCellType geoElt2, int strt, int stp, int step, MEDFileMeshReadSelector *mrs);
     static bool isExisting(med_idt fid, const char *mName, int dt, int it, med_geometry_type geoElt, med_entity_type& whichEntity);
     std::size_t getHeapMemorySizeWithoutChildren() const;
     std::vector<const BigMemoryObject *> getDirectChildrenWithNull() const;
@@ -48,15 +49,21 @@ namespace ParaMEDMEM
     const DataArrayAsciiChar *getNames() const { return _names; }
     static void Write(med_idt fid, const std::string& mname, int mdim, const MEDCoupling1GTUMesh *m, const DataArrayInt *fam, const DataArrayInt *num, const DataArrayAsciiChar *names);
   private:
+    MEDFileUMeshPerType();
     MEDFileUMeshPerType(med_idt fid, const char *mName, int dt, int it, int mdim, med_geometry_type geoElt, INTERP_KERNEL::NormalizedCellType type,
                         med_entity_type entity, MEDFileMeshReadSelector *mrs);
+    void loadPart(med_idt fid, const char *mName, int dt, int it, int mdim, med_geometry_type geoElt, INTERP_KERNEL::NormalizedCellType type,
+                  med_entity_type entity, int strt, int end, int step, MEDFileMeshReadSelector *mrs);
     void loadFromStaticType(med_idt fid, const char *mName, int dt, int it, int mdim, int curNbOfElem, med_geometry_type geoElt, INTERP_KERNEL::NormalizedCellType type,
                             med_entity_type entity, MEDFileMeshReadSelector *mrs);
+    void loadPartStaticType(med_idt fid, const char *mName, int dt, int it, int mdim, int curNbOfElem, med_geometry_type geoElt, INTERP_KERNEL::NormalizedCellType type,
+                            med_entity_type entity, int strt, int end, int step, MEDFileMeshReadSelector *mrs);
     void loadPolyg(med_idt fid, const char *mName, int dt, int it, int mdim, int arraySize, med_geometry_type geoElt,
                    med_entity_type entity, MEDFileMeshReadSelector *mrs);
     void loadPolyh(med_idt fid, const char *mName, int dt, int it, int mdim, int connFaceLgth, med_geometry_type geoElt,
                    med_entity_type entity, MEDFileMeshReadSelector *mrs);
     void loadCommonPart(med_idt fid, const char *mName, int dt, int it, int mdim, int curNbOfElem, med_geometry_type geoElt, med_entity_type entity, MEDFileMeshReadSelector *mrs);
+    void loadPartOfCellCommonPart(med_idt fid, const char *mName, int strt, int stp, int step, int dt, int it, int mdim, int curNbOfElem, med_geometry_type geoElt, med_entity_type entity, MEDFileMeshReadSelector *mrs);
   private:
     MEDCouplingAutoRefCountObjectPtr<MEDCoupling1GTUMesh> _m;
     MEDCouplingAutoRefCountObjectPtr<DataArrayInt> _num;
index bd8aff2c43787e62328672ba2703859bb02c38f4..344f61447cdc6c7a4a73d86a8eb5d8a0ff0223a8 100644 (file)
@@ -243,45 +243,100 @@ MEDFileUMeshL2::MEDFileUMeshL2()
 {
 }
 
-void MEDFileUMeshL2::loadAll(med_idt fid, int mId, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
+std::vector<std::string> MEDFileUMeshL2::loadCommonPart(med_idt fid, int mId, const std::string& mName, int dt, int it, int& Mdim)
 {
+  Mdim=-3;
   _name.set(mName.c_str());
   int nstep;
-  int Mdim;
   ParaMEDMEM::MEDCouplingMeshType meshType;
-  std::vector<std::string> infosOnComp=getAxisInfoOnMesh(fid,mId,mName.c_str(),meshType,nstep,Mdim);
+  std::vector<std::string> ret(getAxisInfoOnMesh(fid,mId,mName.c_str(),meshType,nstep,Mdim));
   if(nstep==0)
-    return ;
+    {
+      Mdim=-4;
+      return std::vector<std::string>();
+    }
   if(meshType!=UNSTRUCTURED)
     throw INTERP_KERNEL::Exception("Invalid mesh type ! You are expected an unstructured one whereas in file it is not an unstructured !");
   _time=CheckMeshTimeStep(fid,mName,nstep,dt,it);
   _iteration=dt;
   _order=it;
+  return ret;
+}
+
+void MEDFileUMeshL2::loadAll(med_idt fid, int mId, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
+{
+  int Mdim;
+  std::vector<std::string> infosOnComp(loadCommonPart(fid,mId,mName,dt,it,Mdim));
+  if(Mdim==-4)
+    return ;
   loadConnectivity(fid,Mdim,mName,dt,it,mrs);//to improve check (dt,it) coherency
   loadCoords(fid,mId,infosOnComp,mName,dt,it);
 }
 
+void MEDFileUMeshL2::loadPart(med_idt fid, int mId, const std::string& mName, const std::vector<INTERP_KERNEL::NormalizedCellType>& types, const std::vector<int>& slicPerTyp, int dt, int it, MEDFileMeshReadSelector *mrs)
+{
+  int Mdim;
+  std::vector<std::string> infosOnComp(loadCommonPart(fid,mId,mName,dt,it,Mdim));
+  if(Mdim==-4)
+    return ;
+  loadPartOfConnectivity(fid,Mdim,mName,types,slicPerTyp,dt,it,mrs);
+  med_bool changement,transformation;
+  int nCoords(MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,MED_COORDINATE,MED_NO_CMODE,&changement,&transformation));
+  std::vector<bool> fetchedNodeIds(nCoords,false);
+  for(std::vector< std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshPerType> > >::const_iterator it0=_per_type_mesh.begin();it0!=_per_type_mesh.end();it0++)
+    for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshPerType> >::const_iterator it1=(*it0).begin();it1!=(*it0).end();it1++)
+      (*it1)->getMesh()->computeNodeIdsAlg(fetchedNodeIds);
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> n2o(DataArrayInt::BuildListOfSwitchedOn(fetchedNodeIds));
+  std::map<int,int> o2n;
+  int newId(0);
+  for(const int *it0=n2o->begin();it0!=n2o->end();it0++,newId++)
+    o2n[*it0]=newId;
+  for(std::vector< std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshPerType> > >::const_iterator it0=_per_type_mesh.begin();it0!=_per_type_mesh.end();it0++)
+    for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshPerType> >::const_iterator it1=(*it0).begin();it1!=(*it0).end();it1++)
+      (*it1)->getMesh()->renumberNodesInConn(o2n);
+  loadPartCoords(fid,mId,infosOnComp,mName,dt,it,n2o);
+}
+
 void MEDFileUMeshL2::loadConnectivity(med_idt fid, int mdim, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
 {
   _per_type_mesh.resize(1);
   _per_type_mesh[0].clear();
   for(int j=0;j<MED_N_CELL_FIXED_GEO;j++)
     {
-      MEDFileUMeshPerType *tmp=MEDFileUMeshPerType::New(fid,mName.c_str(),dt,it,mdim,typmai[j],typmai2[j],mrs);
+      MEDFileUMeshPerType *tmp(MEDFileUMeshPerType::New(fid,mName.c_str(),dt,it,mdim,typmai[j],typmai2[j],mrs));
       if(tmp)
         _per_type_mesh[0].push_back(tmp);
     }
   sortTypes();
 }
 
+void MEDFileUMeshL2::loadPartOfConnectivity(med_idt fid, int mdim, const std::string& mName, const std::vector<INTERP_KERNEL::NormalizedCellType>& types, const std::vector<int>& slicPerTyp, int dt, int it, MEDFileMeshReadSelector *mrs)
+{
+  std::size_t nbOfTypes(types.size());
+  if(slicPerTyp.size()!=3*nbOfTypes)
+    throw INTERP_KERNEL::Exception("MEDFileUMeshL2::loadPartOfConnectivity : The size of slicPerTyp array is expected to be equal to 3 times size of array types !");
+  std::set<INTERP_KERNEL::NormalizedCellType> types2(types.begin(),types.end());
+  if(types2.size()!=nbOfTypes)
+    throw INTERP_KERNEL::Exception("MEDFileUMeshL2::loadPartOfConnectivity : the geometric types in types array must appear once !");
+  _per_type_mesh.resize(1);
+  _per_type_mesh[0].clear();
+  for(std::size_t ii=0;ii<nbOfTypes;ii++)
+    {
+      int strt(slicPerTyp[3*ii+0]),stp(slicPerTyp[3*ii+1]),step(slicPerTyp[3*ii+2]);
+      MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshPerType> tmp(MEDFileUMeshPerType::NewPart(fid,mName.c_str(),dt,it,mdim,types[ii],strt,stp,step,mrs));
+      _per_type_mesh[0].push_back(tmp);
+    }
+  sortTypes();
+}
+
 void MEDFileUMeshL2::loadCoords(med_idt fid, int mId, const std::vector<std::string>& infosOnComp, const std::string& mName, int dt, int it)
 {
-  int spaceDim=infosOnComp.size();
+  int spaceDim((int)infosOnComp.size());
   med_bool changement,transformation;
-  int nCoords=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,MED_COORDINATE,MED_NO_CMODE,&changement,&transformation);
+  int nCoords(MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,MED_COORDINATE,MED_NO_CMODE,&changement,&transformation));
   _coords=DataArrayDouble::New();
   _coords->alloc(nCoords,spaceDim);
-  double *coordsPtr=_coords->getPointer();
+  double *coordsPtr(_coords->getPointer());
   MEDmeshNodeCoordinateRd(fid,mName.c_str(),dt,it,MED_FULL_INTERLACE,coordsPtr);
   if(MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NO_GEOTYPE,MED_FAMILY_NUMBER,MED_NODAL,&changement,&transformation)>0)
     {
@@ -312,6 +367,57 @@ void MEDFileUMeshL2::loadCoords(med_idt fid, int mId, const std::vector<std::str
     _coords->setInfoOnComponent(i,infosOnComp[i]);
 }
 
+/*!
+ * \param [in] n2o - List all ids to be selected. \b WARNING it is an input parameter \b but non const because the array is modified during the treatment of this
+ *                   method. But at the end of the method the state is the same as those before entering in the method (except time label !). This is the consequence of FORTRAN <-> C mode.
+ */
+void MEDFileUMeshL2::loadPartCoords(med_idt fid, int mId, const std::vector<std::string>& infosOnComp, const std::string& mName, int dt, int it, DataArrayInt *n2o)
+{
+  if(!n2o || !n2o->isAllocated() || n2o->getNumberOfComponents()!=1)
+    throw INTERP_KERNEL::Exception("MEDFileUMeshL2::loadPartCoords : n2o must be not NULL and allocated and with one component !");
+  med_bool changement,transformation;
+  int spaceDim((int)infosOnComp.size()),nbNodesToLoad(n2o->getNumberOfTuples()),nCoords(MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,MED_COORDINATE,MED_NO_CMODE,&changement,&transformation));
+  _coords=DataArrayDouble::New();
+  _coords->alloc(nbNodesToLoad,spaceDim);
+  med_filter filter=MED_FILTER_INIT,filter2=MED_FILTER_INIT;
+  n2o->applyLin(1,1);//C -> FORTRAN
+  MEDfilterEntityCr(fid,/*nentity*/nCoords,/*nvaluesperentity*/1,/*nconstituentpervalue*/spaceDim,
+                    /*constituentselect*/MED_ALL_CONSTITUENT,MED_FULL_INTERLACE,MED_COMPACT_STMODE,
+                    /*profilename*/MED_NO_PROFILE,/*filterarraysize*/nbNodesToLoad,/*filterarray*/n2o->begin(),&filter);
+  MEDmeshNodeCoordinateAdvancedRd(fid,mName.c_str(),dt,it,&filter,_coords->getPointer());
+  MEDfilterClose(&filter);
+  MEDfilterEntityCr(fid,nCoords,1,1,MED_ALL_CONSTITUENT,MED_FULL_INTERLACE,MED_COMPACT_STMODE,
+                    MED_NO_PROFILE,nbNodesToLoad,n2o->begin(),&filter2);
+  if(MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NO_GEOTYPE,MED_FAMILY_NUMBER,MED_NODAL,&changement,&transformation)>0)
+    {
+      _fam_coords=DataArrayInt::New();
+      _fam_coords->alloc(nbNodesToLoad,1);
+      MEDmeshEntityAttributeAdvancedRd(fid,mName.c_str(),MED_FAMILY_NUMBER,dt,it,MED_NODE,MED_NO_GEOTYPE,&filter2,_fam_coords->getPointer());
+    }
+  else
+    _fam_coords=0;
+  if(MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NO_GEOTYPE,MED_NUMBER,MED_NODAL,&changement,&transformation)>0)
+    {
+      _num_coords=DataArrayInt::New();
+      _num_coords->alloc(nbNodesToLoad,1);
+      MEDmeshEntityAttributeAdvancedRd(fid,mName.c_str(),MED_NUMBER,dt,it,MED_NODE,MED_NO_GEOTYPE,&filter2,_num_coords->getPointer());
+    }
+  else
+    _num_coords=0;
+  if(MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NO_GEOTYPE,MED_NAME,MED_NODAL,&changement,&transformation)>0)
+    {
+      _name_coords=DataArrayAsciiChar::New();
+      _name_coords->alloc(nbNodesToLoad+1,MED_SNAME_SIZE);//not a bug to avoid the memory corruption due to last \0 at the end
+      MEDmeshEntityAttributeAdvancedRd(fid,mName.c_str(),MED_NAME,dt,it,MED_NODE,MED_NO_GEOTYPE,&filter2,_name_coords->getPointer());
+      _name_coords->reAlloc(nbNodesToLoad);//not a bug to avoid the memory corruption due to last \0 at the end
+    }
+  else
+    _name_coords=0;
+  n2o->applyLin(1,-1);//FORTRAN -> C
+  MEDfilterClose(&filter2);
+  _coords->setInfoOnComponents(infosOnComp);
+}
+
 void MEDFileUMeshL2::sortTypes()
 {
   std::set<int> mdims;
index ffb34e35adbb41099fdab47473124cc2c788fa0a..d2863a5075c653f6b398efad85c93bce67fc1e58 100644 (file)
@@ -50,7 +50,7 @@ namespace ParaMEDMEM
     const char *getTimeUnit() const { return _dt_unit.getReprForWrite(); }
     int getIteration() const { return _iteration; }
     int getOrder() const { return _order; }
-    double getTime() { return _time; }
+    double getTime() const { return _time; }
     std::vector<std::string> getAxisInfoOnMesh(med_idt fid, int mId, const std::string& mName, ParaMEDMEM::MEDCouplingMeshType& meshType, int& nstep, int& Mdim);
     static int GetMeshIdFromName(med_idt fid, const std::string& mName, ParaMEDMEM::MEDCouplingMeshType& meshType, int& dt, int& it, std::string& dtunit1);
     static double CheckMeshTimeStep(med_idt fid, const std::string& mname, int nstep, int dt, int it);
@@ -70,9 +70,13 @@ namespace ParaMEDMEM
   {
   public:
     MEDFileUMeshL2();
+    std::vector<std::string> loadCommonPart(med_idt fid, int mId, const std::string& mName, int dt, int it, int& Mdim);
     void loadAll(med_idt fid, int mId, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs);
+    void loadPart(med_idt fid, int mId, const std::string& mName, const std::vector<INTERP_KERNEL::NormalizedCellType>& types, const std::vector<int>& slicPerTyp, int dt, int it, MEDFileMeshReadSelector *mrs);
     void loadConnectivity(med_idt fid, int mdim, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs);
+    void loadPartOfConnectivity(med_idt fid, int mdim, const std::string& mName, const std::vector<INTERP_KERNEL::NormalizedCellType>& types, const std::vector<int>& slicPerTyp, int dt, int it, MEDFileMeshReadSelector *mrs);
     void loadCoords(med_idt fid, int mId, const std::vector<std::string>& infosOnComp, const std::string& mName, int dt, int it);
+    void loadPartCoords(med_idt fid, int mId, const std::vector<std::string>& infosOnComp, const std::string& mName, int dt, int it, DataArrayInt *n2o);
     int getNumberOfLevels() const { return _per_type_mesh.size(); }
     bool emptyLev(int levId) const { return _per_type_mesh[levId].empty(); }
     const std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshPerType> >& getLev(int levId) const { return _per_type_mesh[levId]; }
index 7a53ab79b46b65fcb48c4c4d134a0d2df767b793..3efbfad259a6cc4c4f597338e81f23105b5688dd 100644 (file)
@@ -95,6 +95,7 @@ using namespace ParaMEDMEM;
 %newobject ParaMEDMEM::MEDFileMesh::computeAllFamilyIdsInUse;
 %newobject ParaMEDMEM::MEDFileStructuredMesh::getImplicitFaceMesh;
 %newobject ParaMEDMEM::MEDFileUMesh::New;
+%newobject ParaMEDMEM::MEDFileUMesh::LoadPartOf;
 %newobject ParaMEDMEM::MEDFileUMesh::getCoords;
 %newobject ParaMEDMEM::MEDFileUMesh::getGroup;
 %newobject ParaMEDMEM::MEDFileUMesh::getGroups;
@@ -783,6 +784,17 @@ namespace ParaMEDMEM
          {
            return MEDFileUMesh::New();
          }
+
+         static MEDFileUMesh *LoadPartOf(const std::string& fileName, const std::string& mName, PyObject *types, const std::vector<int>& slicPerTyp, int dt=-1, int it=-1, MEDFileMeshReadSelector *mrs=0) throw(INTERP_KERNEL::Exception)
+         {
+           std::vector<int> typesCpp1;
+           convertPyToNewIntArr3(types,typesCpp1);
+           std::size_t sz(typesCpp1.size());
+           std::vector<INTERP_KERNEL::NormalizedCellType> typesCpp2(sz);
+           for(std::size_t ii=0;ii<sz;ii++)
+             typesCpp2[ii]=(INTERP_KERNEL::NormalizedCellType)typesCpp1[ii];
+           return MEDFileUMesh::LoadPartOf(fileName,mName,typesCpp2,slicPerTyp,dt,it,mrs);
+         }
          
          PyObject *getRevNumberFieldAtLevel(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception)
          {
index 9bc14349ce4d6f0086d883bd684e53f81b601643..1500fb32ee775e1bae29aa7c729990e4bbc878e8 100644 (file)
@@ -3648,6 +3648,89 @@ class MEDLoaderTest(unittest.TestCase):
         self.assertTrue(f1ts.getUndergroundDataArray().isEqual(DataArrayDouble([0.,1.,2.,3.,4.,5.,6.,7.,8.,9.,10.,11.,12.,13.,14.,15.,16.,17.,18.,19.,20.,21.,22.,23.,24.]),1e-12))
         pass
 
+    def testMEDFileUMeshLoadPart1(self):
+        """ This method tests MEDFileUMesh.LoadPart that loads only a part of a specified mesh in a MED file. The part is specfied using a slice of cell ids. Only nodes on which cells lies are loaded to reduce at most the amount of
+        memory of the returned instance.
+        """
+        fileName="Pyfile81.med"
+        arr=DataArrayDouble(6) ; arr.iota()
+        m=MEDCouplingCMesh() ; m.setCoords(arr,arr)
+        m=m.buildUnstructured()
+        m.setName("Mesh")
+        m.changeSpaceDimension(3,0.)
+        infos=["aa [b]","cc [de]","gg [klm]"]
+        m.getCoords().setInfoOnComponents(infos)
+        m.checkCoherency2()
+        mm=MEDFileUMesh()
+        mm.setMeshAtLevel(0,m)
+        m1=MEDCouplingCMesh() ; m1.setCoords(arr) ; m1.setName("Mesh") 
+        m1=m1.buildUnstructured() ; m1.setCoords(m.getCoords())
+        mm.setMeshAtLevel(-1,m1)
+        renum0=DataArrayInt([3,6,7,10,11,0,2,1,9,8,5,4,12,13,14,24,23,22,21,20,19,18,17,16,15])
+        famField0=DataArrayInt([-3,-6,-7,-10,-11,0,-2,-1,-9,-8,-5,-4,-12,-13,-14,-24,-23,-22,-21,-20,-19,-18,-17,-16,-15])
+        namesCellL0=DataArrayAsciiChar(25,16)
+        namesCellL0[:]=["Cell#%.3d        "%(i) for i in xrange(25)]
+        renumM1=DataArrayInt([3,4,0,2,1])
+        famFieldM1=DataArrayInt([-3,-4,0,-2,-1])
+        mm.setRenumFieldArr(0,renum0)
+        mm.setFamilyFieldArr(0,famField0)
+        #mm.setNameFieldAtLevel(0,namesCellL0)
+        mm.setRenumFieldArr(-1,renumM1)
+        mm.setFamilyFieldArr(-1,famFieldM1)
+        renum1=DataArrayInt([13,16,17,20,21,10,12,11,19,18,15,14,22,23,24,34,33,32,31,30,29,28,27,26,25,45,44,43,42,41,40,39,38,37,36,35])
+        famField1=DataArrayInt([-13,-16,-17,-20,-21,-10,-12,-11,-19,-18,-15,-14,-22,-23,-24,-34,-33,-32,-31,-30,-29,-28,-27,-26,-25,-45,-44,-43,-42,-41,-40,-39,-38,-37,-36,-35])
+        namesNodes=DataArrayAsciiChar(36,16)
+        namesNodes[:]=["Node#%.3d        "%(i) for i in xrange(36)]
+        mm.setRenumFieldArr(1,renum1)
+        mm.setFamilyFieldArr(1,famField1)
+        #mm.setNameFieldAtLevel(1,namesNodes)
+        mm.setFamilyId("Fam7",77)
+        mm.setFamilyId("Fam8",88)
+        mm.setGroupsOnFamily("Fam7",["Grp0","Grp1"])
+        mm.setGroupsOnFamily("Fam8",["Grp1","Grp2"])
+        mm.write(fileName,2)
+        #
+        mm0=MEDFileUMesh.LoadPartOf(fileName,"Mesh",[NORM_QUAD4],[0,10,1])
+        assert(mm0.getAllGeoTypes()==[NORM_QUAD4])
+        assert(mm0.getDirectUndergroundSingleGeoTypeMesh(NORM_QUAD4).getNodalConnectivity().isEqual(DataArrayInt([1,0,6,7,2,1,7,8,3,2,8,9,4,3,9,10,5,4,10,11,7,6,12,13,8,7,13,14,9,8,14,15,10,9,15,16,11,10,16,17])))
+        coo=DataArrayDouble([(0,0,0),(1,0,0),(2,0,0),(3,0,0),(4,0,0),(5,0,0),(0,1,0),(1,1,0),(2,1,0),(3,1,0),(4,1,0),(5,1,0),(0,2,0),(1,2,0),(2,2,0),(3,2,0),(4,2,0),(5,2,0)]) ; coo.setInfoOnComponents(infos)
+        assert(mm0.getCoords().isEqual(coo,1e-12))
+        assert(mm0.getFamilyFieldAtLevel(0).isEqual(famField0[:10]))
+        assert(mm0.getNumberFieldAtLevel(0).isEqual(renum0[:10]))
+        #assert(mm0.getNameFieldAtLevel(0).isEqual(namesCellL0[:10]))
+        assert(mm0.getFamilyFieldAtLevel(1).isEqual(famField1[:18]))
+        assert(mm0.getNumberFieldAtLevel(1).isEqual(renum1[:18]))
+        #assert(mm0.getNameFieldAtLevel(1).isEqual(namesNodes[:18]))
+        #
+        mm1=MEDFileUMesh.LoadPartOf(fileName,"Mesh",[NORM_QUAD4],[11,25,1])
+        assert(mm1.getAllGeoTypes()==[NORM_QUAD4])
+        assert(mm1.getDirectUndergroundSingleGeoTypeMesh(NORM_QUAD4).getNodalConnectivity().isEqual(DataArrayInt([1,0,6,7,2,1,7,8,3,2,8,9,4,3,9,10,6,5,11,12,7,6,12,13,8,7,13,14,9,8,14,15,10,9,15,16,12,11,17,18,13,12,18,19,14,13,19,20,15,14,20,21,16,15,21,22])))
+        coo=DataArrayDouble([(1,2,0),(2,2,0),(3,2,0),(4,2,0),(5,2,0),(0,3,0),(1,3,0),(2,3,0),(3,3,0),(4,3,0),(5,3,0),(0,4,0),(1,4,0),(2,4,0),(3,4,0),(4,4,0),(5,4,0),(0,5,0),(1,5,0),(2,5,0),(3,5,0),(4,5,0),(5,5,0)]) ; coo.setInfoOnComponents(infos)
+        assert(mm1.getCoords().isEqual(coo,1e-12))
+        assert(mm1.getFamilyFieldAtLevel(0).isEqual(famField0[11:]))
+        assert(mm1.getNumberFieldAtLevel(0).isEqual(renum0[11:]))
+        #assert(mm1.getNameFieldAtLevel(0).isEqual(namesCellL0[11:]))
+        assert(mm1.getFamilyFieldAtLevel(1).isEqual(famField1[13:]))
+        assert(mm1.getNumberFieldAtLevel(1).isEqual(renum1[13:]))
+        #assert(mm1.getNameFieldAtLevel(1).isEqual(namesNodes[13:]))
+        #
+        mm2=MEDFileUMesh.LoadPartOf(fileName,"Mesh",[NORM_SEG2,NORM_QUAD4],[0,5,1,1,10,1])
+        assert(mm2.getAllGeoTypes()==[NORM_QUAD4,NORM_SEG2])
+        assert(mm2.getFamilyFieldAtLevel(0).isEqual(famField0[1:10]))
+        assert(mm2.getNumberFieldAtLevel(0).isEqual(renum0[1:10]))
+        #assert(mm2.getNameFieldAtLevel(0).isEqual(namesCellL0[1:10]))
+        assert(mm2.getFamilyFieldAtLevel(-1).isEqual(famFieldM1))
+        assert(mm2.getNumberFieldAtLevel(-1).isEqual(renumM1))
+        assert(mm2.getNameFieldAtLevel(-1) is None)
+        assert(mm2.getDirectUndergroundSingleGeoTypeMesh(NORM_QUAD4).getNodalConnectivity().isEqual(DataArrayInt([2,1,7,8,3,2,8,9,4,3,9,10,5,4,10,11,7,6,12,13,8,7,13,14,9,8,14,15,10,9,15,16,11,10,16,17])))
+        assert(mm2.getDirectUndergroundSingleGeoTypeMesh(NORM_SEG2).getNodalConnectivity().isEqual(DataArrayInt([0,1,1,2,2,3,3,4,4,5])))
+        coo=DataArrayDouble([(0,0,0),(1,0,0),(2,0,0),(3,0,0),(4,0,0),(5,0,0),(0,1,0),(1,1,0),(2,1,0),(3,1,0),(4,1,0),(5,1,0),(0,2,0),(1,2,0),(2,2,0),(3,2,0),(4,2,0),(5,2,0)]) ; coo.setInfoOnComponents(infos)
+        assert(mm2.getCoords().isEqual(coo,1e-12))
+        assert(mm2.getFamilyFieldAtLevel(1).isEqual(famField1[:18]))
+        assert(mm2.getNumberFieldAtLevel(1).isEqual(renum1[:18]))
+        #assert(mm2.getNameFieldAtLevel(1).isEqual(namesNodes[:18]))
+        pass
+
     pass
 
 unittest.main()
index d9a0a23f30c6fc0d5807712fe5630f107f2e5f8f..60a2261cdf5138852fb3c70ad243e0850a0ccefa 100644 (file)
@@ -18,7 +18,7 @@
 #
 # Author : Anthony Geay (CEA/DEN)
 
-ADD_DEFINITIONS(${HDF5_DEFINITIONS} ${MEDFILE_DEFINITIONS})
+ADD_DEFINITIONS(${HDF5_DEFINITIONS} ${MEDFILE_DEFINITIONS} ${MPI_DEFINITIONS})
 
 INCLUDE_DIRECTORIES(
   ${MPI_INCLUDE_DIRS}
@@ -34,6 +34,7 @@ INCLUDE_DIRECTORIES(
 
 SET(paramedloader_SOURCES
   ParaMEDLoader.cxx
+  ParaMEDFileMesh.cxx
   )
 
 ADD_LIBRARY(paramedloader SHARED ${paramedloader_SOURCES})
diff --git a/src/ParaMEDLoader/ParaMEDFileMesh.cxx b/src/ParaMEDLoader/ParaMEDFileMesh.cxx
new file mode 100644 (file)
index 0000000..80d6b1b
--- /dev/null
@@ -0,0 +1,68 @@
+// Copyright (C) 2007-2014  CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 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 "ParaMEDFileMesh.hxx"
+#include "MEDCouplingAutoRefCountObjectPtr.hxx"
+#include "MEDFileMesh.hxx"
+#include "MEDFileMeshLL.hxx"
+#include "MEDLoader.hxx"
+
+using namespace ParaMEDMEM;
+
+MEDFileMesh *ParaMEDFileMesh::New(const MPI_Comm com, const MPI_Info nfo, const std::string& fileName, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
+{
+  MEDFileUtilities::CheckFileForRead(fileName);
+  ParaMEDMEM::MEDCouplingMeshType meshType;
+  MEDFileUtilities::AutoFid fid(MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY));
+  int dummy0,dummy1;
+  std::string dummy2;
+  MEDFileMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy0,dummy1,dummy2);
+  switch(meshType)
+  {
+    case UNSTRUCTURED:
+      {
+        return ParaMEDFileUMesh::New(com,nfo,fileName,mName,dt,it,mrs);
+      }
+    default:
+      throw INTERP_KERNEL::Exception("ParaMEDFileMesh::New : only unstructured mesh supported for the moment !");
+  }
+}
+
+MEDFileUMesh *ParaMEDFileUMesh::New(const MPI_Comm com, const MPI_Info nfo, const std::string& fileName, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
+{
+  MEDCouplingAutoRefCountObjectPtr<MEDFileUMesh> ret(MEDFileUMesh::New());
+  MEDFileUtilities::AutoFid fid(MEDparFileOpen(fileName.c_str(),MED_ACC_RDONLY,com,nfo));
+  //
+  int meshDim, spaceDim, numberOfNodes;
+  std::vector< std::vector< std::pair<INTERP_KERNEL::NormalizedCellType,int> > > typesDistrib(MEDLoader::GetUMeshGlobalInfo(fileName,mName,meshDim,spaceDim,numberOfNodes));
+  return ret.retn();
+}
+
+MEDFileMeshes *ParaMEDFileMeshes::New(const MPI_Comm com, const MPI_Info nfo, const std::string& fileName)
+{
+  std::vector<std::string> ms(MEDLoader::GetMeshNames(fileName));
+  MEDCouplingAutoRefCountObjectPtr<MEDFileMeshes> ret(MEDFileMeshes::New());
+  for(std::vector<std::string>::const_iterator it=ms.begin();it!=ms.end();it++)
+    {
+      MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> mesh(ParaMEDFileMesh::New(com,nfo,fileName,(*it)));
+      ret->pushMesh(mesh);
+    }
+  return ret.retn();
+}
diff --git a/src/ParaMEDLoader/ParaMEDFileMesh.hxx b/src/ParaMEDLoader/ParaMEDFileMesh.hxx
new file mode 100644 (file)
index 0000000..52d5697
--- /dev/null
@@ -0,0 +1,54 @@
+// Copyright (C) 2007-2014  CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 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 __PARAMEDFILEMESH_HXX__
+#define __PARAMEDFILEMESH_HXX__
+
+#include "mpi.h"
+
+#include <string>
+
+namespace ParaMEDMEM
+{
+  class MEDFileMesh;
+  class MEDFileUMesh;
+  class MEDFileMeshes;
+  class MEDFileMeshReadSelector;
+
+  class ParaMEDFileMesh
+  {
+  public:
+    static MEDFileMesh *New(const MPI_Comm com, const MPI_Info nfo, const std::string& fileName, const std::string& mName, int dt=-1, int it=-1, MEDFileMeshReadSelector *mrs=0);
+  };
+
+  class ParaMEDFileUMesh
+  {
+  public:
+    static MEDFileUMesh *New(const MPI_Comm com, const MPI_Info nfo, const std::string& fileName, const std::string& mName, int dt=-1, int it=-1, MEDFileMeshReadSelector *mrs=0);
+  };
+
+  class ParaMEDFileMeshes
+  {
+  public:
+    static MEDFileMeshes *New(const MPI_Comm com, const MPI_Info nfo, const std::string& fileName);
+  };
+}
+
+#endif