Salome HOME
On the road of last imps for MEDReader
authorageay <ageay>
Wed, 17 Jul 2013 10:53:17 +0000 (10:53 +0000)
committerageay <ageay>
Wed, 17 Jul 2013 10:53:17 +0000 (10:53 +0000)
src/MEDCoupling/MEDCouplingMemArray.cxx
src/MEDCoupling/MEDCouplingMemArray.hxx
src/MEDCoupling/MEDCouplingStructuredMesh.cxx
src/MEDCoupling/MEDCouplingStructuredMesh.hxx
src/MEDCoupling_Swig/MEDCouplingCommon.i
src/MEDLoader/MEDFileField.cxx
src/MEDLoader/MEDFileFieldOverView.cxx
src/MEDLoader/MEDFileFieldOverView.hxx
src/MEDLoader/MEDFileMesh.cxx
src/MEDLoader/MEDFileMesh.hxx

index b5dd7300f7f12119403989e236734f7e6bbe0449..bbeeaf46acc2c7035d55eb08002d8c1cfd015fec 100644 (file)
@@ -6161,6 +6161,52 @@ bool DataArrayInt::isEqualWithoutConsideringStrAndOrder(const DataArrayInt& othe
   return a->isEqualWithoutConsideringStr(*b);
 }
 
+/*!
+ * This method compares content of input vector \a v and \a this.
+ * If for each id in \a this v[id]==True and for all other ids id2 not in \a this v[id2]==False, true is returned.
+ * For performance reasons \a this is expected to be sorted ascendingly. If not an exception will be thrown.
+ *
+ * \param [in] v - the vector of 'flags' to be compared with \a this.
+ *
+ * \throw If \a this is not sorted ascendingly.
+ * \throw If \a this has not exactly one component.
+ * \throw If \a this is not allocated.
+ */
+bool DataArrayInt::isFittingWith(const std::vector<bool>& v) const throw(INTERP_KERNEL::Exception)
+{
+  checkAllocated();
+  if(getNumberOfComponents()!=1)
+    throw INTERP_KERNEL::Exception("DataArrayInt::isFittingWith : number of components of this should be equal to one !");
+  int nbOfTuples(getNumberOfTuples());
+  const int *w(begin()),*end2(end());
+  int refVal=-std::numeric_limits<int>::max();
+  int i=0;
+  std::vector<bool>::const_iterator it(v.begin());
+  for(;it!=v.end();it++,i++)
+    {
+      if(*it)
+        {
+          if(w!=end2)
+            {
+              if(*w++==i)
+                {
+                  if(i>refVal)
+                    refVal=i;
+                  else
+                    {
+                      std::ostringstream oss; oss << "DataArrayInt::isFittingWith : At pos #" << std::distance(begin(),w-1) << " this is not sorted ascendingly !";
+                      throw INTERP_KERNEL::Exception(oss.str().c_str());
+                    }
+                }
+              return false;
+            }
+          else
+            return false;
+        }
+    }
+  return w==end2;
+}
+
 /*!
  * Sorts values of the array.
  *  \param [in] asc - \a true means ascending order, \a false, descending.
index 1f2bc2c2cf5f5fb80059d322142d74e071a310e3..7a8a03013082d1efbba30d10ffcc90dcbb8af7fd 100644 (file)
@@ -436,6 +436,7 @@ namespace ParaMEDMEM
     MEDCOUPLING_EXPORT bool isEqualIfNotWhy(const DataArrayInt& other, std::string& reason) const throw(INTERP_KERNEL::Exception);
     MEDCOUPLING_EXPORT bool isEqualWithoutConsideringStr(const DataArrayInt& other) const throw(INTERP_KERNEL::Exception);
     MEDCOUPLING_EXPORT bool isEqualWithoutConsideringStrAndOrder(const DataArrayInt& other) const throw(INTERP_KERNEL::Exception);
+    MEDCOUPLING_EXPORT bool isFittingWith(const std::vector<bool>& v) const throw(INTERP_KERNEL::Exception);
     MEDCOUPLING_EXPORT DataArrayInt *buildPermutationArr(const DataArrayInt& other) const throw(INTERP_KERNEL::Exception);
     MEDCOUPLING_EXPORT void sort(bool asc=true) throw(INTERP_KERNEL::Exception);
     MEDCOUPLING_EXPORT void reverse() throw(INTERP_KERNEL::Exception);
index 842b3e3e040fba70935902fadd5ca630c3f1cc8e..ed497f7a64e355b33403a1eb31ef3fd084d16dc8 100644 (file)
@@ -56,7 +56,12 @@ bool MEDCouplingStructuredMesh::isEqualIfNotWhy(const MEDCouplingMesh *other, do
 
 INTERP_KERNEL::NormalizedCellType MEDCouplingStructuredMesh::getTypeOfCell(int cellId) const
 {
-  switch(getMeshDimension())
+  return GetGeoTypeGivenMeshDimension(getMeshDimension());
+}
+
+INTERP_KERNEL::NormalizedCellType MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(int meshDim) throw(INTERP_KERNEL::Exception)
+{
+  switch(meshDim)
     {
     case 3:
       return INTERP_KERNEL::NORM_HEXA8;
@@ -65,7 +70,7 @@ INTERP_KERNEL::NormalizedCellType MEDCouplingStructuredMesh::getTypeOfCell(int c
     case 1:
       return INTERP_KERNEL::NORM_SEG2;
     default:
-      throw INTERP_KERNEL::Exception("Unexpected dimension for MEDCouplingCurveLinearMesh::getTypeOfCell !");
+      throw INTERP_KERNEL::Exception("Unexpected dimension for MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension !");
     }
 }
 
index b04db7adde241d2aacdabbd3c070b680f9136709..07c73d71ee4ef0ab43c692cf2bb153caaf902a03 100644 (file)
@@ -36,6 +36,7 @@ namespace ParaMEDMEM
     DataArrayInt *computeNbOfNodesPerCell() const throw(INTERP_KERNEL::Exception);
     DataArrayInt *computeNbOfFacesPerCell() const throw(INTERP_KERNEL::Exception);
     static void GetPosFromId(int nodeId, int meshDim, const int *split, int *res);
+    static INTERP_KERNEL::NormalizedCellType GetGeoTypeGivenMeshDimension(int meshDim) throw(INTERP_KERNEL::Exception);
     void getNodeIdsOfCell(int cellId, std::vector<int>& conn) const;
     std::size_t getHeapMemorySize() const;
     void copyTinyStringsFrom(const MEDCouplingMesh *other) throw(INTERP_KERNEL::Exception);
index af81565d14bbcb3cfc1cbba9dc7f327bba8bec5f..bee74173eb3deadc2106adafccfcb37ec70d4880 100644 (file)
@@ -2926,6 +2926,7 @@ namespace ParaMEDMEM
   public:
     int getCellIdFromPos(int i, int j, int k) const throw(INTERP_KERNEL::Exception);
     int getNodeIdFromPos(int i, int j, int k) const throw(INTERP_KERNEL::Exception);
+    static INTERP_KERNEL::NormalizedCellType GetGeoTypeGivenMeshDimension(int meshDim) throw(INTERP_KERNEL::Exception);
   };
 
   //== MEDCouplingCMesh
index 20fedf5cc14c199be7a51780e1f241adeaa641c4..4d3851f142d23cc71bd287b528554f51b4d9c10a 100644 (file)
@@ -8293,23 +8293,23 @@ std::vector< std::vector<MEDFileAnyTypeFieldMultiTS *> > MEDFileAnyTypeFieldMult
   std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileFastCellSupportComparator> > cmps;
   std::vector< std::vector<MEDFileAnyTypeFieldMultiTS *> > retCell=SplitPerCommonSupportNotNodesAlg(vectFMTSNotNodes,mesh,cmps);
   ret=retCell;
-  i=0;
   for(std::vector<MEDFileAnyTypeFieldMultiTS *>::const_iterator it2=vectFMTSNodes.begin();it2!=vectFMTSNodes.end();it2++)
     {
+      i=0;
       for(std::vector< std::vector<MEDFileAnyTypeFieldMultiTS *> >::const_iterator it0=retCell.begin();it0!=retCell.end();it0++,i++)
         {
           if((*it0).empty())
             throw INTERP_KERNEL::Exception("MEDFileAnyTypeFieldMultiTS::SplitPerCommonSupport : internal error !");
+          if(cmps[i]->isCompatibleWithNodesDiscr(*it2))
+            ret[i].push_back(*it2);
         }
-      std::vector<MEDFileAnyTypeFieldMultiTS *> elt(1,*it2);
-      ret.push_back(elt);
     }
-  
   return ret;
 }
 
 /*!
  * WARNING no check here. The caller must be sure that all items in vectFMTS are coherent each other in time steps, only one same spatial discretization and not ON_NODES.
+ * \param [out] cmps - same size than the returned vector.
  */
 std::vector< std::vector<MEDFileAnyTypeFieldMultiTS *> > MEDFileAnyTypeFieldMultiTS::SplitPerCommonSupportNotNodesAlg(const std::vector<MEDFileAnyTypeFieldMultiTS *>& vectFMTS, const MEDFileMesh *mesh, std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileFastCellSupportComparator> >& cmps) throw(INTERP_KERNEL::Exception)
 {
index e5a067b80e5e93b6508be4ee7766875071bb9136..cfdd4202b518d421aafb407b6dd7bc38a35f3618 100644 (file)
@@ -49,6 +49,22 @@ MEDFileMeshStruct::MEDFileMeshStruct(const MEDFileMesh *mesh):_mesh(mesh)
     }
 }
 
+int MEDFileMeshStruct::getLevelOfGeoType(INTERP_KERNEL::NormalizedCellType t) const throw(INTERP_KERNEL::Exception)
+{
+  int j=0;
+  for(std::vector< std::vector<int> >::const_iterator it1=_geo_types_distrib.begin();it1!=_geo_types_distrib.end();it1++,j--)
+    {
+      std::size_t sz=(*it1).size();
+      if(sz%3!=0)
+        throw INTERP_KERNEL::Exception("MEDFileMeshStruct::getLevelOfGeoType : internal error in code !");
+      std::size_t nbGeo=sz/3;
+      for(std::size_t i=0;i<nbGeo;i++)
+        if((*it1)[3*i]==(int)t)
+          return j;
+    }
+  throw INTERP_KERNEL::Exception("MEDFileMeshStruct::getLevelOfGeoType : The specified geometric type is not present in the mesh structure !");
+}
+
 int MEDFileMeshStruct::getNumberOfElemsOfGeoType(INTERP_KERNEL::NormalizedCellType t) const throw(INTERP_KERNEL::Exception)
 {
   for(std::vector< std::vector<int> >::const_iterator it1=_geo_types_distrib.begin();it1!=_geo_types_distrib.end();it1++)
@@ -64,8 +80,28 @@ int MEDFileMeshStruct::getNumberOfElemsOfGeoType(INTERP_KERNEL::NormalizedCellTy
   throw INTERP_KERNEL::Exception("The specified geometric type is not present in the mesh structure !");
 }
 
+int MEDFileMeshStruct::getNumberOfLevs() const
+{
+  return (int)_geo_types_distrib.size();
+}
+
+int MEDFileMeshStruct::getNumberOfGeoTypesInLev(int relativeLev) const throw(INTERP_KERNEL::Exception)
+{
+  int pos(-relativeLev);
+  if(pos<0 || pos>=_geo_types_distrib.size())
+    throw INTERP_KERNEL::Exception("MEDFileMeshStruct::getNumberOfGeoTypesInLev : invalid level specified !");
+  std::size_t sz=_geo_types_distrib[pos].size();
+  if(sz%3!=0)
+    throw INTERP_KERNEL::Exception("MEDFileMeshStruct::getNumberOfGeoTypesInLev : internal error in code !");
+  return (int)(sz/3);
+}
+
 //=
 
+MEDFileField1TSStructItem2::MEDFileField1TSStructItem2()
+{
+}
+
 MEDFileField1TSStructItem2::MEDFileField1TSStructItem2(INTERP_KERNEL::NormalizedCellType a, const std::pair<int,int>& b, const std::string& c, const std::string& d):_geo_type(a),_start_end(b),_pfl(DataArrayInt::New()),_loc(d),_nb_of_entity(-1)
 {
   _pfl->setName(c.c_str());
@@ -95,6 +131,11 @@ void MEDFileField1TSStructItem2::checkWithMeshStructForGaussPT(MEDFileMeshStruct
   checkInRange(nbOfEnt,loc.getNumberOfGaussPoints(),globs);
 }
 
+std::string MEDFileField1TSStructItem2::getPflName() const
+{
+  return _pfl->getName();
+}
+
 /*!
  * \param [in] nbOfEntity - number of entity that can be either cells or nodes. Not other possiblity.
  * \param [in] nip - number of integration points. 1 for ON_CELLS and NO_NODES
@@ -125,9 +166,72 @@ bool MEDFileField1TSStructItem2::operator==(const MEDFileField1TSStructItem2& ot
   return _geo_type==other._geo_type && _start_end==other._start_end && _pfl->getName()==other._pfl->getName();
 }
 
+bool MEDFileField1TSStructItem2::isCellSupportEqual(const MEDFileField1TSStructItem2& other) const throw(INTERP_KERNEL::Exception)
+{
+  if(_geo_type!=other._geo_type)
+    return false;
+  if(_nb_of_entity!=other._nb_of_entity)
+    return false;
+  if((_pfl->getName().empty() && !other._pfl->getName().empty()) || (!_pfl->getName().empty() && other._pfl->getName().empty()))
+    return false;
+  if(_pfl->getName().empty() && other._pfl->getName().empty())
+    return true;
+  return _pfl->isEqualWithoutConsideringStr(*other._pfl);
+}
+
+/*!
+ * \a objs must be non empty. \a objs should contain items having same geometric type.
+ */
+MEDFileField1TSStructItem2 MEDFileField1TSStructItem2::BuildAggregationOf(const std::vector<const MEDFileField1TSStructItem2 *>& objs, const MEDFileFieldGlobs *globs) throw(INTERP_KERNEL::Exception)
+{
+  if(objs.empty())
+    throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem2::BuildAggregationOf : empty input !");
+  if(objs.size()==1)
+    return MEDFileField1TSStructItem2(*objs[0]);
+  INTERP_KERNEL::NormalizedCellType gt(objs[0]->_geo_type);
+  int nbEntityRef(objs[0]->_nb_of_entity);
+  std::size_t sz(objs.size());
+  std::vector<const DataArrayInt *> arrs(sz);
+  for(std::size_t i=0;i<sz;i++)
+    {
+      const MEDFileField1TSStructItem2 *obj(objs[i]);
+      if(gt!=obj->_geo_type)
+        throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem2::BuildAggregationOf : invalid situation ! All input must have the same geo type !");
+      if(nbEntityRef!=obj->_nb_of_entity)
+        throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem2::BuildAggregationOf : invalid situation ! All input must have the global nb of entity !");
+      if(obj->_pfl->getName().empty())
+        throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem2::BuildAggregationOf : invalid situation ! Several same geo type chunk must all lie on profiles !");
+      arrs[i]=globs->getProfile(obj->_pfl->getName().c_str());
+      MEDCouplingAutoRefCountObjectPtr<DataArrayInt> arr(DataArrayInt::Aggregate(arrs));
+      arr->sort();
+      int oldNbTuples(arr->getNumberOfTuples());
+      arr=arr->buildUnique();
+      if(oldNbTuples!=arr->getNumberOfTuples())
+        throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem2::BuildAggregationOf : some entities are present several times !");
+      if(arr->isIdentity() && oldNbTuples==nbEntityRef)
+        {
+          std::pair<int,int> p(0,nbEntityRef);
+          std::string a,b;
+          MEDFileField1TSStructItem2 ret(gt,p,a,b);
+          ret._nb_of_entity=nbEntityRef;
+          return ret;
+        }
+      else
+        {
+          arr->setName("???");
+          std::pair<int,int> p(0,oldNbTuples);
+          std::string a,b;
+          MEDFileField1TSStructItem2 ret(gt,p,a,b);
+          ret._nb_of_entity=nbEntityRef;
+          ret._pfl=arr;
+          return ret;
+        }
+    }
+}
+
 //=
 
-MEDFileField1TSStructItem::MEDFileField1TSStructItem(TypeOfField a, const std::vector< MEDFileField1TSStructItem2 >& b):_type(a),_items(b)
+MEDFileField1TSStructItem::MEDFileField1TSStructItem(TypeOfField a, const std::vector< MEDFileField1TSStructItem2 >& b):_computed(false),_type(a),_items(b)
 {
 }
 
@@ -178,6 +282,18 @@ bool MEDFileField1TSStructItem::operator==(const MEDFileField1TSStructItem& othe
   return true;
 }
 
+bool MEDFileField1TSStructItem::isCellSupportEqual(const MEDFileField1TSStructItem& other) const throw(INTERP_KERNEL::Exception)
+{
+  if(_type!=other._type)
+    return false;
+  if(_items.size()!=other._items.size())
+    return false;
+  for(std::size_t i=0;i<_items.size();i++)
+    if(!(_items[i].isCellSupportEqual(other._items[i])))
+      return false;
+  return true;
+}
+
 bool MEDFileField1TSStructItem::isEntityCell() const
 {
   if(_type==ON_NODES)
@@ -214,7 +330,95 @@ MEDFileField1TSStructItem MEDFileField1TSStructItem::simplifyMeOnCellEntity(cons
       ret._type=ON_CELLS;
       return ret;
     }
-  return *this;
+  std::size_t sz(m.size());
+  std::vector< MEDFileField1TSStructItem2 > items(sz);
+  for(i=0;i<sz;i++)
+    {
+      const std::vector<std::size_t>& ids=m[i].second;
+      std::vector<const MEDFileField1TSStructItem2 *>objs(ids.size());
+      for(std::size_t j=0;j<ids.size();j++)
+        objs[j]=&_items[j];
+      items[i]=MEDFileField1TSStructItem2::BuildAggregationOf(objs,globs);
+    }
+  MEDFileField1TSStructItem ret(ON_CELLS,items);
+  ret._computed=true;
+  return ret;
+}
+
+/*!
+ * \a this is expected to be ON_CELLS and simplified.
+ */
+bool MEDFileField1TSStructItem::isCompatibleWithNodesDiscr(const MEDFileField1TSStructItem& other, const MEDFileMeshStruct *meshSt, const MEDFileFieldGlobs *globs) const throw(INTERP_KERNEL::Exception)
+{
+  if(other._type!=ON_NODES)
+    throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem::isCompatibleWithNodesDiscr : other must be on nodes !");
+  if(other._items.size()!=1)
+    throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem::isCompatibleWithNodesDiscr : other is on nodes but number of subparts !");
+  int theFirstLevFull;
+  bool ret0=isFullyOnExactlyOneLev(meshSt,theFirstLevFull);
+  const MEDFileField1TSStructItem2& otherNodeIt(other._items[0]);
+  if(otherNodeIt.getPflName().empty())
+    {//on all nodes
+      if(!ret0)
+        return false;
+      return theFirstLevFull==0;
+    }
+  else
+    {
+      const DataArrayInt *pfl=globs->getProfile(otherNodeIt.getPflName().c_str());
+      MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cpyPfl(pfl->deepCpy());
+      cpyPfl->sort();
+      int nbOfNodes(meshSt->getNumberOfNodes());
+      if(cpyPfl->isIdentity() && cpyPfl->getNumberOfTuples()==nbOfNodes)
+        {//on all nodes also !
+          if(!ret0)
+            return false;
+          return theFirstLevFull==0;
+        }
+      std::vector<bool> nodesFetched(nbOfNodes,false);
+      meshSt->getTheMesh()->whichAreNodesFetched(*this,globs,nodesFetched);
+      return cpyPfl->isFittingWith(nodesFetched);
+    }
+}
+
+bool MEDFileField1TSStructItem::isFullyOnExactlyOneLev(const MEDFileMeshStruct *meshSt, int& theFirstLevFull) const throw(INTERP_KERNEL::Exception)
+{
+  if(_type!=ON_CELLS)
+    throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem::isFullyOnExactlyOneLev : works only for ON_CELLS discretization !");
+  if(_items.empty())
+    throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem::isFullyOnExactlyOneLev : items vector is empty !");
+  int nbOfLevs(meshSt->getNumberOfLevs());
+  if(nbOfLevs==0)
+    throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem::isFullyOnExactlyOneLev : no levels in input mesh structure !");
+  theFirstLevFull=1;
+  int nbOfGT=0;
+  bool firstShot(true);
+  std::set<INTERP_KERNEL::NormalizedCellType> gts;
+  for(std::vector< MEDFileField1TSStructItem2 >::const_iterator it=_items.begin();it!=_items.end();it++)
+    {
+      if(!(*it).getPflName().empty())
+        return false;
+      INTERP_KERNEL::NormalizedCellType gt;
+      if(gts.find(gt)!=gts.end())
+        throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem::isFullyOnExactlyOneLev : internal error !");
+      gts.insert(gt);
+      int pos(meshSt->getLevelOfGeoType((*it).getGeo()));
+      if(firstShot)
+        theFirstLevFull=pos;
+      else
+        if(theFirstLevFull!=pos)
+          return false;
+      firstShot=false;
+      nbOfGT++;
+    }
+  return nbOfGT==meshSt->getNumberOfGeoTypesInLev(theFirstLevFull);
+}
+
+const MEDFileField1TSStructItem2& MEDFileField1TSStructItem::operator[](std::size_t i) const throw(INTERP_KERNEL::Exception)
+{
+  if(i<0 || i>=_items.size())
+    throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem::operator[] : input is not in valid range !");
+  return _items[i];
 }
 
 //=
@@ -236,7 +440,7 @@ void MEDFileField1TSStruct::checkWithMeshStruct(MEDFileMeshStruct *mst, const ME
   _already_checked.back().checkWithMeshStruct(mst,globs);
 }
 
-bool MEDFileField1TSStruct::isEqualConsideringThePast(const MEDFileAnyTypeField1TS *other) throw(INTERP_KERNEL::Exception)
+bool MEDFileField1TSStruct::isEqualConsideringThePast(const MEDFileAnyTypeField1TS *other) const throw(INTERP_KERNEL::Exception)
 {
   MEDFileField1TSStructItem b(BuildItemFrom(other));
   for(std::vector<MEDFileField1TSStructItem>::const_iterator it=_already_checked.begin();it!=_already_checked.end();it++)
@@ -247,6 +451,9 @@ bool MEDFileField1TSStruct::isEqualConsideringThePast(const MEDFileAnyTypeField1
   return false;
 }
 
+/*!
+ * Not const because \a other structure will be added to the \c _already_checked attribute in case of success.
+ */
 bool MEDFileField1TSStruct::isSupportSameAs(const MEDFileAnyTypeField1TS *other) throw(INTERP_KERNEL::Exception)
 {
   if(_already_checked.empty())
@@ -254,7 +461,49 @@ bool MEDFileField1TSStruct::isSupportSameAs(const MEDFileAnyTypeField1TS *other)
   MEDFileField1TSStructItem b(BuildItemFrom(other));
   if(!_already_checked[0].isEntityCell() || !b.isEntityCell())
     throw INTERP_KERNEL::Exception("MEDFileField1TSStruct::isSupportSameAs : only available on cell entities !");
-  return false;
+  MEDFileField1TSStructItem other1(b.simplifyMeOnCellEntity(other->contentNotNull()));
+  int found=-1,i=0;
+  for(std::vector<MEDFileField1TSStructItem>::const_iterator it=_already_checked.begin();it!=_already_checked.end();it++,i++)
+    if((*it).isComputed())
+      { found=i; break; }
+  bool ret(false);
+  if(found==-1)
+    {
+      MEDFileField1TSStructItem this1(_already_checked[0].simplifyMeOnCellEntity(other->contentNotNull()));
+      ret=this1.isCellSupportEqual(other1);
+      if(ret)
+        _already_checked.push_back(this1);
+    }
+  else
+    ret=_already_checked[found].isCellSupportEqual(other1);
+  if(ret)
+    _already_checked.push_back(b);
+  return ret;
+}
+
+bool MEDFileField1TSStruct::isCompatibleWithNodesDiscr(const MEDFileAnyTypeField1TS *other, const MEDFileMeshStruct *meshSt) throw(INTERP_KERNEL::Exception)
+{
+  if(_already_checked.empty())
+    throw INTERP_KERNEL::Exception("MEDFileField1TSStruct::isCompatibleWithNodesDiscr : no ref !");
+  if(!_already_checked[0].isEntityCell())
+    throw INTERP_KERNEL::Exception("MEDFileField1TSStruct::isCompatibleWithNodesDiscr : only available on cell entities !");
+  MEDFileField1TSStructItem other1(BuildItemFrom(other));
+  //
+  int found=-1,i=0;
+  for(std::vector<MEDFileField1TSStructItem>::const_iterator it=_already_checked.begin();it!=_already_checked.end();it++,i++)
+    if((*it).isComputed())
+      { found=i; break; }
+  bool ret(false);
+  if(found==-1)
+    {
+      MEDFileField1TSStructItem this1(_already_checked[0].simplifyMeOnCellEntity(other->contentNotNull()));
+      ret=this1.isCompatibleWithNodesDiscr(other1,meshSt,other->contentNotNull());
+      if(ret)
+        _already_checked.push_back(this1);
+    }
+  else
+    ret=_already_checked[found].isCompatibleWithNodesDiscr(other1,meshSt,other->contentNotNull());
+  return true;//tony
 }
 
 std::size_t MEDFileField1TSStruct::getHeapMemorySize() const
@@ -333,7 +582,7 @@ bool MEDFileFastCellSupportComparator::isEqual(const MEDFileAnyTypeFieldMultiTS
   int nbPts=other->getNumberOfTS();
   if(nbPts!=(int)_f1ts_cmps.size())
     {
-      std::ostringstream oss; oss << "MEDFileFastCellSupportComparator::isEqualRegardingPast : unexpected nb of time steps in  input ! Should be " << _f1ts_cmps.size() << " it is in reality " << nbPts << " !";
+      std::ostringstream oss; oss << "MEDFileFastCellSupportComparator::isEqual : unexpected nb of time steps in  input ! Should be " << _f1ts_cmps.size() << " it is in reality " << nbPts << " !";
       throw INTERP_KERNEL::Exception(oss.str().c_str());
     }
   for(int i=0;i<nbPts;i++)
@@ -345,3 +594,20 @@ bool MEDFileFastCellSupportComparator::isEqual(const MEDFileAnyTypeFieldMultiTS
     }
   return true;
 }
+
+bool MEDFileFastCellSupportComparator::isCompatibleWithNodesDiscr(const MEDFileAnyTypeFieldMultiTS *other) throw(INTERP_KERNEL::Exception)
+{
+  int nbPts=other->getNumberOfTS();
+  if(nbPts!=(int)_f1ts_cmps.size())
+    {
+      std::ostringstream oss; oss << "MEDFileFastCellSupportComparator::isCompatibleWithNodesDiscr : unexpected nb of time steps in  input ! Should be " << _f1ts_cmps.size() << " it is in reality " << nbPts << " !";
+      throw INTERP_KERNEL::Exception(oss.str().c_str());
+    }
+  for(int i=0;i<nbPts;i++)
+    {
+      MEDCouplingAutoRefCountObjectPtr<MEDFileAnyTypeField1TS> elt=other->getTimeStepAtPos(i);
+      if(!_f1ts_cmps[i]->isCompatibleWithNodesDiscr(elt,_mesh_comp))
+        return false;
+    }
+  return true;
+}
index cd063f43e5d60a2ed00fdd0147707d5976512919..161b092c696a5574f15fe0c722c5a5a421c8255c 100644 (file)
@@ -42,8 +42,12 @@ namespace ParaMEDMEM
   public:
     static MEDFileMeshStruct *New(const MEDFileMesh *mesh);
     std::size_t getHeapMemorySize() const;
+    const MEDFileMesh *getTheMesh() const { return _mesh; }
     int getNumberOfNodes() const { return _nb_nodes; }
     int getNumberOfElemsOfGeoType(INTERP_KERNEL::NormalizedCellType t) const throw(INTERP_KERNEL::Exception);
+    int getLevelOfGeoType(INTERP_KERNEL::NormalizedCellType t) const throw(INTERP_KERNEL::Exception);
+    int getNumberOfLevs() const;
+    int getNumberOfGeoTypesInLev(int relativeLev) const throw(INTERP_KERNEL::Exception);
   private:
     MEDFileMeshStruct(const MEDFileMesh *mesh);
   private:
@@ -56,15 +60,19 @@ namespace ParaMEDMEM
   class MEDFileField1TSStructItem2
   {
   public:
+    MEDFileField1TSStructItem2();
     MEDFileField1TSStructItem2(INTERP_KERNEL::NormalizedCellType a, const std::pair<int,int>& b, const std::string& pfl, const std::string& loc);
     void checkWithMeshStructForCells(MEDFileMeshStruct *mst, const MEDFileFieldGlobs *globs) throw(INTERP_KERNEL::Exception);
     void checkWithMeshStructForGaussNE(MEDFileMeshStruct *mst, const MEDFileFieldGlobs *globs) throw(INTERP_KERNEL::Exception);
     void checkWithMeshStructForGaussPT(MEDFileMeshStruct *mst, const MEDFileFieldGlobs *globs) throw(INTERP_KERNEL::Exception);
     //
     INTERP_KERNEL::NormalizedCellType getGeo() const { return _geo_type; }
+    std::string getPflName() const;
     //! warning this method also set _nb_of_entity attribute !
     void checkInRange(int nbOfEntity, int nip, const MEDFileFieldGlobs *globs) throw(INTERP_KERNEL::Exception);
     bool operator==(const MEDFileField1TSStructItem2& other) const throw(INTERP_KERNEL::Exception);
+    bool isCellSupportEqual(const MEDFileField1TSStructItem2& other) const throw(INTERP_KERNEL::Exception);
+    static MEDFileField1TSStructItem2 BuildAggregationOf(const std::vector<const MEDFileField1TSStructItem2 *>& objs, const MEDFileFieldGlobs *globs) throw(INTERP_KERNEL::Exception);
   private:
     INTERP_KERNEL::NormalizedCellType _geo_type;
     std::pair<int,int> _start_end;
@@ -80,9 +88,16 @@ namespace ParaMEDMEM
     void checkWithMeshStruct(MEDFileMeshStruct *mst, const MEDFileFieldGlobs *globs) throw(INTERP_KERNEL::Exception);
     bool operator==(const MEDFileField1TSStructItem& other) const throw(INTERP_KERNEL::Exception);
     bool isEntityCell() const;
+    bool isComputed() const { return _computed; }
+    std::size_t getNumberOfItems() const { return _items.size(); }
+    const MEDFileField1TSStructItem2& operator[](std::size_t i) const throw(INTERP_KERNEL::Exception);
     //
+    bool isCellSupportEqual(const MEDFileField1TSStructItem& other) const throw(INTERP_KERNEL::Exception);
     MEDFileField1TSStructItem simplifyMeOnCellEntity(const MEDFileFieldGlobs *globs) const throw(INTERP_KERNEL::Exception);
+    bool isCompatibleWithNodesDiscr(const MEDFileField1TSStructItem& other, const MEDFileMeshStruct *meshSt, const MEDFileFieldGlobs *globs) const throw(INTERP_KERNEL::Exception);
+    bool isFullyOnExactlyOneLev(const MEDFileMeshStruct *meshSt, int& theFirstLevFull) const throw(INTERP_KERNEL::Exception);
   private:
+    bool _computed;
     TypeOfField _type;
     std::vector< MEDFileField1TSStructItem2 > _items;
   };
@@ -93,8 +108,9 @@ namespace ParaMEDMEM
     static MEDFileField1TSStruct *New(const MEDFileAnyTypeField1TS *ref) throw(INTERP_KERNEL::Exception);
     void checkWithMeshStruct(MEDFileMeshStruct *mst, const MEDFileFieldGlobs *globs) throw(INTERP_KERNEL::Exception);
     std::size_t getHeapMemorySize() const;
-    bool isEqualConsideringThePast(const MEDFileAnyTypeField1TS *other) throw(INTERP_KERNEL::Exception);
+    bool isEqualConsideringThePast(const MEDFileAnyTypeField1TS *other) const throw(INTERP_KERNEL::Exception);
     bool isSupportSameAs(const MEDFileAnyTypeField1TS *other) throw(INTERP_KERNEL::Exception);
+    bool isCompatibleWithNodesDiscr(const MEDFileAnyTypeField1TS *other, const MEDFileMeshStruct *meshSt) throw(INTERP_KERNEL::Exception);
   private:
     MEDFileField1TSStruct(const MEDFileAnyTypeField1TS *ref);
     static MEDFileField1TSStructItem BuildItemFrom(const MEDFileAnyTypeField1TS *ref);
@@ -107,6 +123,7 @@ namespace ParaMEDMEM
   public:
     static MEDFileFastCellSupportComparator *New(const MEDFileMesh *m, const MEDFileAnyTypeFieldMultiTS *ref) throw(INTERP_KERNEL::Exception);
     bool isEqual(const MEDFileAnyTypeFieldMultiTS *other) throw(INTERP_KERNEL::Exception);
+    bool isCompatibleWithNodesDiscr(const MEDFileAnyTypeFieldMultiTS *other) throw(INTERP_KERNEL::Exception);
     std::size_t getHeapMemorySize() const;
   private:
     MEDFileFastCellSupportComparator(const MEDFileMesh *m, const MEDFileAnyTypeFieldMultiTS *ref);
index 74a40b7f0443866c973a137b50c5211237253715..6e17704e6661555b84bfc211954feaec4aac5374 100644 (file)
@@ -20,6 +20,8 @@
 
 #include "MEDFileMesh.hxx"
 #include "MEDFileUtilities.hxx"
+#include "MEDFileFieldOverView.hxx"
+#include "MEDFileField.hxx"
 #include "MEDLoader.hxx"
 #include "MEDLoaderBase.hxx"
 
@@ -2616,6 +2618,34 @@ int MEDFileUMesh::getNumberOfNodes() const throw(INTERP_KERNEL::Exception)
   return coo->getNumberOfTuples();
 }
 
+void MEDFileUMesh::whichAreNodesFetched(const MEDFileField1TSStructItem& st, const MEDFileFieldGlobs *globs, std::vector<bool>& nodesFetched) const throw(INTERP_KERNEL::Exception)
+{
+  /*if(st.getNumberOfItems()!=1)
+    throw INTERP_KERNEL::Exception("MEDFileUMesh::whichAreNodesFetched : The sturture of field is not lying on single geo type ! it is not managed yet for structured mesh !");
+  if(st[0].getGeo()!=MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(getMeshDimension()))
+    throw INTERP_KERNEL::Exception("MEDFileUMesh::whichAreNodesFetched : The sturture of field is not lying on expected geo type !");
+  if(getNumberOfNodes()!=(int)nodesFetched.size())
+    throw INTERP_KERNEL::Exception("MEDFileUMesh::whichAreNodesFetched : invalid size of array !");
+  if(st.getPflName().empty())
+    {
+      std::fill(nodesFetched.begin(),nodesFetched.end(),true);
+      return ;
+    }
+  const DataArrayInt *arr(globs->getProfile(st.getPflName().c_str()));
+  const MEDCouplingStructuredMesh *cmesh=getStructuredMesh();//cmesh not null because getNumberOfNodes called before
+  int sz(nodesFetched.size());
+  for(const int *work=arr->begin();work!=arr->end();work++)
+    {
+      std::vector<int> conn;
+      cmesh->getNodeIdsOfCell(*work,conn);
+      for(std::vector<int>::const_iterator it=conn.begin();it!=conn.end();it++)
+        if(*it>=0 && *it<sz)
+          nodesFetched[*it]=true;
+        else
+          throw INTERP_KERNEL::Exception("MEDFileUMesh::whichAreNodesFetched : internal error !");
+          }*/
+}
+
 /*!
  * Returns the optional numbers of mesh entities of a given dimension transformed using
  * DataArrayInt::invertArrayN2O2O2N().
@@ -4311,6 +4341,34 @@ int MEDFileStructuredMesh::getNumberOfNodes() const throw(INTERP_KERNEL::Excepti
   return cmesh->getNumberOfNodes();
 }
 
+void MEDFileStructuredMesh::whichAreNodesFetched(const MEDFileField1TSStructItem& st, const MEDFileFieldGlobs *globs, std::vector<bool>& nodesFetched) const throw(INTERP_KERNEL::Exception)
+{
+  if(st.getNumberOfItems()!=1)
+    throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::whichAreNodesFetched : The sturture of field is not lying on single geo type ! it is not managed yet for structured mesh !");
+  if(st[0].getGeo()!=MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(getMeshDimension()))
+    throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::whichAreNodesFetched : The sturture of field is not lying on expected geo type !");
+  if(getNumberOfNodes()!=(int)nodesFetched.size())
+    throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::whichAreNodesFetched : invalid size of array !");
+  if(st[0].getPflName().empty())
+    {
+      std::fill(nodesFetched.begin(),nodesFetched.end(),true);
+      return ;
+    }
+  const DataArrayInt *arr(globs->getProfile(st[0].getPflName().c_str()));
+  const MEDCouplingStructuredMesh *cmesh=getStructuredMesh();//cmesh not null because getNumberOfNodes called before
+  int sz(nodesFetched.size());
+  for(const int *work=arr->begin();work!=arr->end();work++)
+    {
+      std::vector<int> conn;
+      cmesh->getNodeIdsOfCell(*work,conn);
+      for(std::vector<int>::const_iterator it=conn.begin();it!=conn.end();it++)
+        if(*it>=0 && *it<sz)
+          nodesFetched[*it]=true;
+        else
+          throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::whichAreNodesFetched : internal error !");
+    }
+}
+
 med_geometry_type MEDFileStructuredMesh::GetGeoTypeFromMeshDim(int meshDim) throw(INTERP_KERNEL::Exception)
 {
   med_geometry_type geoTypeReq=MED_NONE;
index 1d69a413ad8922b6a6ee33eb0097760d94771055..f6fde111334c1c012cbe058ab0334f793af345c3 100644 (file)
@@ -31,6 +31,9 @@
 
 namespace ParaMEDMEM
 {
+  class MEDFileFieldGlobs;
+  class MEDFileField1TSStructItem;
+  
   class MEDLOADER_EXPORT MEDFileMesh : public RefCountObject, public MEDFileWritable
   {
   public:
@@ -70,6 +73,7 @@ namespace ParaMEDMEM
     virtual void write(med_idt fid) const throw(INTERP_KERNEL::Exception);
     virtual int getSizeAtLevel(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception) = 0;
     virtual MEDCouplingMesh *getGenMeshAtLevel(int meshDimRelToMax, bool renum=false) const throw(INTERP_KERNEL::Exception) = 0;
+    virtual void whichAreNodesFetched(const MEDFileField1TSStructItem& st, const MEDFileFieldGlobs *globs, std::vector<bool>& nodesFetched) const throw(INTERP_KERNEL::Exception) = 0;
     //
     bool areFamsEqual(const MEDFileMesh *other, std::string& what) const;
     bool areGrpsEqual(const MEDFileMesh *other, std::string& what) const;
@@ -207,6 +211,7 @@ namespace ParaMEDMEM
     const DataArrayInt *getRevNumberFieldAtLevel(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception);
     const DataArrayAsciiChar *getNameFieldAtLevel(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception);
     int getNumberOfNodes() const throw(INTERP_KERNEL::Exception);
+    void whichAreNodesFetched(const MEDFileField1TSStructItem& st, const MEDFileFieldGlobs *globs, std::vector<bool>& nodesFetched) const throw(INTERP_KERNEL::Exception);
     std::vector<int> getNonEmptyLevels() const;
     std::vector<int> getNonEmptyLevelsExt() const;
     std::vector<int> getFamArrNonEmptyLevelsExt() const;
@@ -301,6 +306,7 @@ namespace ParaMEDMEM
     MEDCouplingMesh *getGenMeshAtLevel(int meshDimRelToMax, bool renum=false) const throw(INTERP_KERNEL::Exception);
     int getSizeAtLevel(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception);
     int getNumberOfNodes() const throw(INTERP_KERNEL::Exception);
+    void whichAreNodesFetched(const MEDFileField1TSStructItem& st, const MEDFileFieldGlobs *globs, std::vector<bool>& nodesFetched) const throw(INTERP_KERNEL::Exception);
     // tools
     bool unPolyze(std::vector<int>& oldCode, std::vector<int>& newCode, DataArrayInt *& o2nRenumCell) throw(INTERP_KERNEL::Exception);
   protected: