]> SALOME platform Git repositories - tools/medcoupling.git/commitdiff
Salome HOME
Extend the lib to support orphan nodes in profiles.
authorageay <ageay>
Wed, 5 Feb 2014 07:20:25 +0000 (07:20 +0000)
committerageay <ageay>
Wed, 5 Feb 2014 07:20:25 +0000 (07:20 +0000)
Extend the lib to support umeshes with no cells.

src/MEDLoader/MEDFileFieldOverView.cxx
src/MEDLoader/MEDFileFieldOverView.hxx
src/MEDLoader/MEDFileMeshLL.cxx
src/MEDLoader/Swig/MEDLoaderTest4.py

index 825a780e57708903c583d795b7d5dbf975257f4c..0412026a30b06b42ed3d6ef654690f1679a2d8c4 100644 (file)
@@ -55,9 +55,12 @@ MEDFileMeshStruct::MEDFileMeshStruct(const MEDFileMesh *mesh):_mesh(mesh)
   std::vector<int> levs(mesh->getNonEmptyLevels());
   _name=mesh->getName();
   _nb_nodes=mesh->getNumberOfNodes();
-  _geo_types_distrib.resize(levs.size());
-  for(std::vector<int>::const_iterator lev=levs.begin();lev!=levs.end();lev++)
-    _geo_types_distrib[-(*lev)]=mesh->getDistributionOfTypes(*lev);
+  if(!levs.empty())
+    {
+      _geo_types_distrib.resize(-(*std::min_element(levs.begin(),levs.end()))+1);
+      for(std::vector<int>::const_iterator lev=levs.begin();lev!=levs.end();lev++)
+        _geo_types_distrib[-(*lev)]=mesh->getDistributionOfTypes(*lev);
+    }
 }
 
 int MEDFileMeshStruct::getLevelOfGeoType(INTERP_KERNEL::NormalizedCellType t) const
@@ -176,6 +179,8 @@ bool MEDMeshMultiLev::isFastlyTheSameStruct(const MEDFileField1TSStructItem& fst
       const DataArrayInt *nr(_node_reduction);
       if(pflName.empty() && !nr)
         return true;
+      if(!pflName.empty() && !nr)
+        return false;
       if(pflName==nr->getName())
         return true;
       return false;
@@ -543,6 +548,51 @@ DataArray *MEDMeshMultiLev::constructDataArray(const MEDFileField1TSStructItem&
     }
 }
 
+/*!
+ * This method is called to add NORM_POINT1 cells in \a this so that orphan nodes in \a verticesToAdd will be fetched.
+ */
+void MEDMeshMultiLev::appendVertices(const DataArrayInt *verticesToAdd, DataArrayInt *nr)
+{
+  int nbOfVertices(verticesToAdd->getNumberOfTuples());
+  std::size_t sz(_pfls.size());
+  _pfls.resize(sz+1);
+  _geo_types.resize(sz+1,INTERP_KERNEL::NORM_POINT1);
+  _nb_entities.resize(sz+1,nbOfVertices);
+  _node_reduction=nr; nr->incrRef();
+  _nb_nodes+=nbOfVertices;
+  const DataArrayInt *cf(_cell_fam_ids),*cn(_cell_num_ids),*nf(_node_fam_ids),*nn(_node_num_ids);
+  if(cf)
+    {
+      MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp;
+      std::vector<const DataArrayInt *> a(2);
+      a[0]=cf;
+      if(nf)
+        tmp=nf->selectByTupleIdSafe(verticesToAdd->begin(),verticesToAdd->end());
+      else
+        {
+          tmp=DataArrayInt::New(); tmp->alloc(nbOfVertices,1); tmp->fillWithZero();
+        }
+      a[1]=tmp;
+      _cell_fam_ids=DataArrayInt::Aggregate(a);
+      _cell_fam_ids_nocpy=false;
+    }
+  if(cn)
+    {
+      MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp;
+      std::vector<const DataArrayInt *> a(2);
+      a[0]=cn;
+      if(nn)
+        tmp=nn->selectByTupleIdSafe(verticesToAdd->begin(),verticesToAdd->end());
+      else
+        {
+          tmp=DataArrayInt::New(); tmp->alloc(nbOfVertices,1); tmp->fillWithZero();
+        }
+      a[1]=tmp;
+      _cell_num_ids=DataArrayInt::Aggregate(a);
+      _cell_num_ids_nocpy=false;
+    }
+}
+
 MEDMeshMultiLev::MEDMeshMultiLev():_nb_nodes(0),_cell_fam_ids_nocpy(false)
 {
 }
@@ -583,6 +633,10 @@ MEDUMeshMultiLev::MEDUMeshMultiLev(const MEDFileUMesh *m, const std::vector<int>
       v.insert(v.end(),vTmp.begin(),vTmp.end());
     }
   std::size_t sz(v.size());
+  if(v.empty())
+    {
+      _coords=m->getCoords(); _coords->incrRef();
+    }
   _parts.resize(sz);
   _pfls.resize(sz);
   _geo_types.resize(sz);
@@ -619,7 +673,7 @@ MEDUMeshMultiLev::MEDUMeshMultiLev(const MEDFileUMesh *m, const std::vector<int>
           if(!tmps[i])
             f=false;
         }
-      if(f)
+      if(f && !tmps.empty())
         _cell_fam_ids=DataArrayInt::Aggregate(tmps);
     }
   _cell_num_ids_nocpy=(levs.size()==1);
@@ -642,7 +696,7 @@ MEDUMeshMultiLev::MEDUMeshMultiLev(const MEDFileUMesh *m, const std::vector<int>
           if(!tmps[i])
             n=false;
         }
-      if(n)
+      if(n && !tmps.empty())
         _cell_num_ids=DataArrayInt::Aggregate(tmps);
     }
   // node part
@@ -759,7 +813,6 @@ void MEDUMeshMultiLev::selectPartOfNodes(const DataArrayInt *pflNodes)
    std::vector< const DataArrayInt *> aa(sz);
    for(std::size_t i=0;i<sz;i++)
      {
-       
        const DataArrayInt *pfl(_pfls[i]);
        MEDCouplingAutoRefCountObjectPtr<MEDCoupling1GTUMesh> m(_parts[i]);
        if(pfl)
@@ -776,9 +829,21 @@ void MEDUMeshMultiLev::selectPartOfNodes(const DataArrayInt *pflNodes)
        else
          _pfls[i]=cellIdsSafe;
      }
-   _node_reduction=DataArrayInt::Aggregate(aa);
+   if(!aa.empty())
+     _node_reduction=DataArrayInt::Aggregate(aa);//general case
+   else
+     _node_reduction=pflNodes->deepCpy();//case where no cells in read mesh.
    _node_reduction->sort(true);
    _node_reduction=_node_reduction->buildUnique();
+   if(_node_reduction->getNumberOfTuples()==pflNodes->getNumberOfTuples())
+     return ;//This is the classical case where the input node profile corresponds perfectly to a subset of cells in _parts
+   if(_node_reduction->getNumberOfTuples()>pflNodes->getNumberOfTuples())
+     throw INTERP_KERNEL::Exception("MEDUMeshMultiLev::selectPartOfNodes : internal error in MEDCoupling during cell select from a list of nodes !");
+   // Here the cells available in _parts is not enough to cover all the nodes in pflNodes. So adding vertices cells in _parts...
+   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> pflNodes2(pflNodes->deepCpy());
+   pflNodes2->sort(true);
+   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> diff(pflNodes2->buildSubstractionOptimized(_node_reduction));
+   appendVertices(diff,pflNodes2);
 }
 
 MEDMeshMultiLev *MEDUMeshMultiLev::prepare() const
@@ -786,7 +851,7 @@ MEDMeshMultiLev *MEDUMeshMultiLev::prepare() const
   return new MEDUMeshMultiLev(*this);
 }
 
-MEDUMeshMultiLev::MEDUMeshMultiLev(const MEDUMeshMultiLev& other):MEDMeshMultiLev(other),_parts(other._parts)
+MEDUMeshMultiLev::MEDUMeshMultiLev(const MEDUMeshMultiLev& other):MEDMeshMultiLev(other),_parts(other._parts),_coords(other._coords)
 {
 }
 
@@ -805,11 +870,11 @@ MEDUMeshMultiLev::MEDUMeshMultiLev(const MEDStructuredMeshMultiLev& other, const
  */
 bool MEDUMeshMultiLev::buildVTUArrays(DataArrayDouble *& coords, DataArrayByte *&types, DataArrayInt *&cellLocations, DataArrayInt *& cells, DataArrayInt *&faceLocations, DataArrayInt *&faces) const
 {
+  const DataArrayDouble *tmp(0);
   if(_parts.empty())
-    throw INTERP_KERNEL::Exception("MEDUMeshMultiLev::getVTUArrays : empty array !");
-  if(!(const MEDCoupling1GTUMesh *)_parts[0])
-    throw INTERP_KERNEL::Exception("MEDUMeshMultiLev::getVTUArrays : first part is null !");
-  const DataArrayDouble *tmp(_parts[0]->getCoords());
+    tmp=_coords;
+  else
+    tmp=_parts[0]->getCoords();
   if(!tmp)
     throw INTERP_KERNEL::Exception("MEDUMeshMultiLev::getVTUArrays : the coordinates are null !");
   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> a(const_cast<DataArrayDouble *>(tmp)); tmp->incrRef();
@@ -952,6 +1017,11 @@ void MEDUMeshMultiLev::reorderNodesIfNecessary(MEDCouplingAutoRefCountObjectPtr<
   const DataArrayInt *nr(_node_reduction);
   if(!nr)
     return ;
+  if(nodalConnVTK->empty() && !polyhedNodalConnVTK)
+    {
+      coords=(coords->selectByTupleIdSafe(nr->begin(),nr->end()));
+      return ;
+    }
   int sz(coords->getNumberOfTuples());
   std::vector<bool> b(sz,false);
   const int *work(nodalConnVTK->begin()),*endW(nodalConnVTK->end());
@@ -1022,6 +1092,25 @@ void MEDUMeshMultiLev::reorderNodesIfNecessary(MEDCouplingAutoRefCountObjectPtr<
   coords=(coords->selectByTupleIdSafe(nr->begin(),nr->end()));
 }
 
+
+void MEDUMeshMultiLev::appendVertices(const DataArrayInt *verticesToAdd, DataArrayInt *nr)
+{
+  int nbOfCells(verticesToAdd->getNumberOfTuples());//it is not a bug cells are NORM_POINT1
+  MEDMeshMultiLev::appendVertices(verticesToAdd,nr);
+  MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> elt(MEDCoupling1SGTUMesh::New("",INTERP_KERNEL::NORM_POINT1));
+  elt->allocateCells(nbOfCells);
+  for(int i=0;i<nbOfCells;i++)
+    {
+      int pt(verticesToAdd->getIJ(i,0));
+      elt->insertNextCell(&pt,&pt+1);
+    }
+  if(_parts.empty())
+    throw INTERP_KERNEL::Exception("MEDUMeshMultiLev::appendVertices : parts are empty !");
+  elt->setCoords(_parts[0]->getCoords());
+  MEDCouplingAutoRefCountObjectPtr<MEDCoupling1GTUMesh> elt2((MEDCoupling1SGTUMesh *)elt); elt2->incrRef();
+  _parts.push_back(elt2);
+}
+
 //=
 
 MEDStructuredMeshMultiLev::MEDStructuredMeshMultiLev():_is_internal(true)
index d1c6b1cc61445a4a5c927c9f8394d845c8cf2f7f..4e5167da983224695e76d64c610dbe3026a43cd5 100644 (file)
@@ -96,6 +96,7 @@ namespace ParaMEDMEM
   protected:
     std::string getPflNameOfId(int id) const;
     DataArray *constructDataArray(const MEDFileField1TSStructItem& fst, const MEDFileFieldGlobsReal *globs, const DataArray *vals) const;
+    virtual void appendVertices(const DataArrayInt *verticesToAdd, DataArrayInt *nr);
   protected:
     MEDMeshMultiLev();
     MEDMeshMultiLev(const MEDMeshMultiLev& other);
@@ -131,6 +132,8 @@ namespace ParaMEDMEM
     MEDMeshMultiLev *prepare() const;
     MEDUMeshMultiLev(const MEDStructuredMeshMultiLev& other, const MEDCouplingAutoRefCountObjectPtr<MEDCoupling1GTUMesh>& part);
     MEDLOADER_EXPORT bool buildVTUArrays(DataArrayDouble *& coords, DataArrayByte *&types, DataArrayInt *&cellLocations, DataArrayInt *& cells, DataArrayInt *&faceLocations, DataArrayInt *&faces) const;
+  protected:
+    void appendVertices(const DataArrayInt *verticesToAdd, DataArrayInt *nr);
   private:
     void reorderNodesIfNecessary(MEDCouplingAutoRefCountObjectPtr<DataArrayDouble>& coords, DataArrayInt *nodalConnVTK, DataArrayInt *polyhedNodalConnVTK) const;
   private:
@@ -139,6 +142,8 @@ namespace ParaMEDMEM
     MEDUMeshMultiLev(const MEDFileUMesh *m, const std::vector<INTERP_KERNEL::NormalizedCellType>& gts, const std::vector<const DataArrayInt *>& pfls, const std::vector<int>& nbEntities);
   private:
     std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCoupling1GTUMesh> > _parts;
+    //! this attribute is used only for mesh with no cells but having coordinates. For classical umeshes those pointer is equal to pointer of coordinates of instances in this->_parts.
+    MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> _coords;
   };
 
   class MEDStructuredMeshMultiLev : public MEDMeshMultiLev
index 6784cb264a7732e292742568917791e0ed026635..c03e12cf920c76b1f85e50ff4de2853347105731 100644 (file)
@@ -1132,7 +1132,7 @@ void MEDFileUMeshAggregateCompute::forceComputationOfPartsFromUMesh() const
   _m_parts.resize(sz);
   for(std::size_t i=0;i<sz;i++)
     _m_parts[i]=MEDCoupling1GTUMesh::New(ms[i]);
-  _mp_time=std::max(_mp_time,_m_time)+1;
+  _mp_time=std::max(_mp_time,_m_time);
 }
 
 std::size_t MEDFileUMeshAggregateCompute::getTimeOfThis() const
index e73a7e6dbd0c0b121c56d08cc9311efa697848d9..88d57ede576479897e3b13e42d454d48bf9b6736 100644 (file)
@@ -3688,6 +3688,436 @@ class MEDLoaderTest4(unittest.TestCase):
         self.assertTrue(v.isEqual(vExp,1e-12)) # <- THE test is here !!!
         del fff0
         pass
+
+    def test26(self):
+        """ Test focused on field on nodes (here f0Node and f1Node) lying on a profile of nodes that do not match perfectly a sub set of cells of its underlying mesh. See bug EDF 2405 and 2177.
+        For this type of fields the support will contain only vertices.
+        """
+        fname="ForMEDReader26.med"
+        coords=DataArrayDouble([(0.,0.,0.),(1.,0.,0.),(2.,0.,0.),(3.,0.,0.),(0.,1.,0.),(1.,1.,0.),(2.,1.,0.),(3.,1.,0.),(0.,2.,0.),(1.,2.,0.),(2.,2.,0.),(3.,2.,0.),(0.,3.,0.),(1.,3.,0.),(2.,3.,0.),(3.,3.,0.)])
+        m0=MEDCouplingUMesh("mesh",2)
+        m0.allocateCells()
+        for elt in [[2,6,3],[6,7,3],[9,6,5],[9,10,6]]:
+            m0.insertNextCell(NORM_TRI3,elt)
+            pass
+        for elt in [[0,4,5,1],[1,5,6,2],[4,8,9,5],[6,10,11,7],[8,12,13,9],[9,13,14,10],[10,14,15,11]]:
+            m0.insertNextCell(NORM_QUAD4,elt)
+            pass
+        m0.setCoords(coords)
+        ##
+        mm=MEDFileUMesh()
+        mm.setMeshAtLevel(0,m0)
+        mm.setFamilyFieldArr(0,DataArrayInt([-1,-2,-3,-4,-5,-6,-7,-8,-9,-10,-11]))
+        mm.setFamilyFieldArr(1,DataArrayInt([1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]))
+        #
+        f1ts0Node=MEDFileField1TS()
+        f1ts1Node=MEDFileField1TS()
+        f1ts2Cell=MEDFileField1TS()
+        f1ts3Cell=MEDFileField1TS()
+        f1ts4Cell=MEDFileField1TS()
+        f1ts5Node=MEDFileField1TS()
+        #
+        pfl0=DataArrayInt([4,5,6,8,9,12]) ; pfl0.setName("pfl0")
+        pfl1=DataArrayInt([0,1,4,5,7,10]) ; pfl1.setName("pfl1")
+        pfl2=DataArrayInt([0,1,2,3,4,5,6,7,10,11,14,15]) ; pfl2.setName("pfl2")
+        #
+        f0Node=MEDCouplingFieldDouble(ON_NODES) ; f0Node.setName("f0Node")
+        arr0=DataArrayDouble(6) ; arr0.iota()
+        f0Node.setArray(arr0)
+        f1ts0Node.setFieldProfile(f0Node,mm,0,pfl0)
+        #
+        f1Node=MEDCouplingFieldDouble(ON_NODES) ; f1Node.setName("f1Node")
+        arr1=DataArrayDouble(6) ; arr1.iota() ; arr1.reverse()
+        f1Node.setArray(arr1)
+        f1ts1Node.setFieldProfile(f1Node,mm,0,pfl0)
+        #
+        f2Cell=MEDCouplingFieldDouble(ON_CELLS) ; f2Cell.setName("f2Cell")
+        arr2=DataArrayDouble([2,3,0,1,4,5])
+        f2Cell.setArray(arr2)
+        f1ts2Cell.setFieldProfile(f2Cell,mm,0,pfl1)
+        #
+        f3Cell=MEDCouplingFieldDouble(ON_CELLS) ; f3Cell.setName("f3Cell")
+        arr3=DataArrayDouble([5,4,3,2,1,0])
+        f3Cell.setArray(arr3)
+        f1ts3Cell.setFieldProfile(f3Cell,mm,0,pfl1)
+        #
+        f4Cell=MEDCouplingFieldDouble(ON_CELLS) ; f4Cell.setName("f4Cell")
+        arr4=DataArrayDouble([2,2,0,1,1,0])
+        f4Cell.setArray(arr4)
+        f1ts4Cell.setFieldProfile(f4Cell,mm,0,pfl1)
+        #
+        f5Node=MEDCouplingFieldDouble(ON_NODES) ; f5Node.setName("f5Node")
+        arr5=DataArrayDouble([0,1,2,3,10,11,13,2,11,1,10,0])
+        f5Node.setArray(arr5)
+        f1ts5Node.setFieldProfile(f5Node,mm,0,pfl2)
+        #
+        fs=MEDFileFields()
+        for f in [f1ts0Node,f1ts1Node,f1ts2Cell,f1ts3Cell,f1ts4Cell,f1ts5Node]:
+            fmts=MEDFileFieldMultiTS()
+            fmts.pushBackTimeStep(f)
+            fs.pushField(fmts)
+            pass
+        mm.write(fname,2)
+        fs.write(fname,0)
+        ########## GO for reading in MEDReader,by not loading all. Mesh is fully loaded but not fields values
+        ms=MEDFileMeshes(fname)
+        fields=MEDFileFields(fname,False)
+        fields_per_mesh=[fields.partOfThisLyingOnSpecifiedMeshName(meshName) for meshName in ms.getMeshesNames()]
+        allFMTSLeavesToDisplay=[]
+        for fields in fields_per_mesh:
+            allFMTSLeavesToDisplay2=[]
+            for fmts in fields:
+                allFMTSLeavesToDisplay2+=fmts.splitDiscretizations()
+                pass
+            allFMTSLeavesToDisplay.append(allFMTSLeavesToDisplay2)
+            pass
+        self.assertEqual(len(allFMTSLeavesToDisplay),1)
+        self.assertEqual(len(allFMTSLeavesToDisplay[0]),6)
+        allFMTSLeavesPerTimeSeries=MEDFileAnyTypeFieldMultiTS.SplitIntoCommonTimeSeries(sum(allFMTSLeavesToDisplay,[]))
+        self.assertEqual(len(allFMTSLeavesPerTimeSeries),1)
+        self.assertEqual(len(allFMTSLeavesPerTimeSeries[0]),6)
+        allFMTSLeavesPerCommonSupport1=MEDFileAnyTypeFieldMultiTS.SplitPerCommonSupport(allFMTSLeavesToDisplay[0],ms[ms.getMeshesNames()[0]])
+        self.assertEqual(len(allFMTSLeavesPerCommonSupport1),2)
+        self.assertEqual(len(allFMTSLeavesPerCommonSupport1[0][0]),4)
+        self.assertEqual(len(allFMTSLeavesPerCommonSupport1[1][0]),2)# <- the smart one is here
+        #
+        mst=MEDFileMeshStruct.New(ms[0])
+        #
+        fcscp=allFMTSLeavesPerCommonSupport1[1][1]
+        mml=fcscp.buildFromScratchDataSetSupport(0,fields)
+        mml2=mml.prepare()
+        self.assertTrue(isinstance(mml2,MEDUMeshMultiLev))
+        ncc,a0,a1,a2,a3,a4,a5=mml2.buildVTUArrays()
+        self.assertTrue(not ncc)
+        self.assertTrue(a0.isEqual(DataArrayDouble([0.,1.,0.,1.,1.,0.,2.,1.,0.,0.,2.,0.,1.,2.,0.,0.,3.,0.],6,3),1e-12))
+        self.assertTrue(a1.isEqual(DataArrayByte([5,9,1])))
+        self.assertTrue(a2.isEqual(DataArrayInt([0,4,9])))
+        self.assertTrue(a3.isEqual(DataArrayInt([3,4,2,1,4,0,3,4,1,1,5])))
+        self.assertTrue(a4 is None)
+        self.assertTrue(a5 is None)
+        a6,a7=mml2.retrieveFamilyIdsOnCells()
+        self.assertTrue(a6.isEqual(DataArrayInt([-3,-7,13])))
+        self.assertTrue(not a7) # copy here because profile on cells
+        a8,a9=mml2.retrieveNumberIdsOnCells()
+        self.assertTrue(a8 is None)
+        self.assertTrue(a9) # no copy here because no number field
+        a10,a11=mml2.retrieveFamilyIdsOnNodes()
+        self.assertTrue(a10.isEqual(DataArrayInt([5,6,7,9,10,13])))
+        self.assertTrue(not a11) # copy here
+        a12,a13=mml2.retrieveNumberIdsOnNodes()
+        self.assertTrue(a12 is None)
+        self.assertTrue(a13) # no copy here because no number field
+        #
+        fff0=allFMTSLeavesPerCommonSupport1[1][0][0][0]
+        fsst=MEDFileField1TSStructItem.BuildItemFrom(fff0,mst)
+        fff0.loadArraysIfNecessary()
+        v=mml2.buildDataArray(fsst,fields,fff0.getUndergroundDataArray())
+        self.assertEqual(fff0.getName(),"f0Node")
+        self.assertEqual(v.getHiddenCppPointer(),fff0.getUndergroundDataArray().getHiddenCppPointer())
+        vExp=DataArrayDouble([0.,1.,2.,3.,4.,5.])
+        self.assertTrue(v.isEqual(vExp,1e-12)) # <- THE test is here !!!
+        #
+        fff1=allFMTSLeavesPerCommonSupport1[1][0][1][0]
+        fsst=MEDFileField1TSStructItem.BuildItemFrom(fff1,mst)
+        fff1.loadArraysIfNecessary()
+        v=mml2.buildDataArray(fsst,fields,fff1.getUndergroundDataArray())
+        self.assertEqual(fff1.getName(),"f1Node")
+        self.assertEqual(v.getHiddenCppPointer(),fff1.getUndergroundDataArray().getHiddenCppPointer())
+        vExp=DataArrayDouble([5.,4.,3.,2.,1.,0.])
+        self.assertTrue(v.isEqual(vExp,1e-12)) # <- THE test is here !!!
+        pass
+
+    def test27(self):
+        """ This test defines 2 fields f0 and f1 on nodes lying on an unstructured mesh with no cells.
+        f0 is a field on all nodes. f1 is a partial field on nodes.
+        """
+        fname="ForMEDReader27.med"
+        coords=DataArrayDouble([(0.,0.,0.),(1.,0.,0.),(2.,0.,0.),(3.,0.,0.),(0.,1.,0.),(1.,1.,0.),(2.,1.,0.),(3.,1.,0.),(0.,2.,0.),(1.,2.,0.),(2.,2.,0.),(3.,2.,0.),(0.,3.,0.),(1.,3.,0.),(2.,3.,0.),(3.,3.,0.)])
+        m0=MEDCouplingUMesh("mesh",2)
+        m0.allocateCells()
+        m0.setCoords(coords)
+        ##
+        mm=MEDFileUMesh()
+        mm.setMeshAtLevel(0,m0)
+        mm.setFamilyFieldArr(1,DataArrayInt([1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]))
+        #
+        f1ts0=MEDFileField1TS()
+        f1ts1=MEDFileField1TS()
+        #
+        f0=MEDCouplingFieldDouble(ON_NODES) ; f0.setMesh(m0) ; f0.setName("f0NoPfl")
+        arr0=DataArrayDouble([0.,1.,2.,3.,1.,1.5,2.2,3.1,2.,2.2,3.,3.1,3.,3.1,3.5,4.])
+        f0.setArray(arr0)
+        f0.checkCoherency()
+        f1ts0.setFieldNoProfileSBT(f0)
+        self.assertEqual(f1ts0.getMeshName(),"mesh")
+        #
+        pfl1=DataArrayInt([0,1,2,3,4,5,6,8,9,12]) ; pfl1.setName("pfl1")
+        f1=MEDCouplingFieldDouble(ON_NODES) ; f1.setName("f1Pfl")
+        arr1=DataArrayDouble([3.,2.,1.,0.,2.,1.5,0.,1.,0.,0.2])
+        f1.setArray(arr1)
+        f1ts1.setFieldProfile(f1,mm,0,pfl1)
+        self.assertEqual(f1ts1.getMeshName(),"mesh")
+        #
+        fs=MEDFileFields()
+        fmts0=MEDFileFieldMultiTS()
+        fmts0.pushBackTimeStep(f1ts0)
+        fmts1=MEDFileFieldMultiTS()
+        fmts1.pushBackTimeStep(f1ts1)
+        fs.pushField(fmts0) ; fs.pushField(fmts1)
+        self.assertEqual(fs[0].getMeshName(),"mesh")
+        self.assertEqual(fs[1].getMeshName(),"mesh")
+        mm.write(fname,2)
+        fs.write(fname,0)
+        ########## GO for reading in MEDReader,by not loading all. Mesh is fully loaded but not fields values
+        ms=MEDFileMeshes(fname)
+        fields=MEDFileFields(fname,False)
+        self.assertEqual(fields[0].getMeshName(),"mesh")
+        self.assertEqual(fields[1].getMeshName(),"mesh")
+        fields_per_mesh=[fields.partOfThisLyingOnSpecifiedMeshName(meshName) for meshName in ms.getMeshesNames()]
+        self.assertEqual(fields_per_mesh[0][0].getMeshName(),"mesh")
+        self.assertEqual(fields_per_mesh[0][1].getMeshName(),"mesh")
+        allFMTSLeavesToDisplay=[]
+        for fields in fields_per_mesh:
+            allFMTSLeavesToDisplay2=[]
+            for fmts in fields:
+                allFMTSLeavesToDisplay2+=fmts.splitDiscretizations()
+                pass
+            allFMTSLeavesToDisplay.append(allFMTSLeavesToDisplay2)
+            pass
+        self.assertEqual(len(allFMTSLeavesToDisplay),1)
+        self.assertEqual(len(allFMTSLeavesToDisplay[0]),2)
+        allFMTSLeavesPerTimeSeries=MEDFileAnyTypeFieldMultiTS.SplitIntoCommonTimeSeries(sum(allFMTSLeavesToDisplay,[]))
+        self.assertEqual(len(allFMTSLeavesPerTimeSeries),1)
+        self.assertEqual(len(allFMTSLeavesPerTimeSeries[0]),2)
+        allFMTSLeavesPerCommonSupport1=MEDFileAnyTypeFieldMultiTS.SplitPerCommonSupport(allFMTSLeavesToDisplay[0],ms[ms.getMeshesNames()[0]])
+        self.assertEqual(len(allFMTSLeavesPerCommonSupport1),2)
+        self.assertEqual(len(allFMTSLeavesPerCommonSupport1[0][0]),1)
+        self.assertEqual(len(allFMTSLeavesPerCommonSupport1[1][0]),1)
+        #
+        mst=MEDFileMeshStruct.New(ms[0])
+        #
+        fcscp=allFMTSLeavesPerCommonSupport1[0][1]
+        mml=fcscp.buildFromScratchDataSetSupport(0,fields)
+        mml2=mml.prepare()
+        self.assertTrue(isinstance(mml2,MEDUMeshMultiLev))
+        ncc,a0,a1,a2,a3,a4,a5=mml2.buildVTUArrays()
+        self.assertTrue(ncc)
+        self.assertTrue(a0.isEqual(DataArrayDouble([(0.,0.,0.),(1.,0.,0.),(2.,0.,0.),(3.,0.,0.),(0.,1.,0.),(1.,1.,0.),(2.,1.,0.),(3.,1.,0.),(0.,2.,0.),(1.,2.,0.),(2.,2.,0.),(3.,2.,0.),(0.,3.,0.),(1.,3.,0.),(2.,3.,0.),(3.,3.,0.)]),1e-12))
+        self.assertTrue(a1.isEqual(DataArrayByte([])))
+        self.assertTrue(a2.isEqual(DataArrayInt([])))
+        self.assertTrue(a3.isEqual(DataArrayInt([])))
+        self.assertTrue(a4 is None)
+        self.assertTrue(a5 is None)
+        #
+        fff0=allFMTSLeavesPerCommonSupport1[0][0][0][0]
+        fsst=MEDFileField1TSStructItem.BuildItemFrom(fff0,mst)
+        fff0.loadArraysIfNecessary()
+        v=mml2.buildDataArray(fsst,fields,fff0.getUndergroundDataArray())
+        self.assertEqual(fff0.getName(),"f0NoPfl")
+        self.assertEqual(v.getHiddenCppPointer(),fff0.getUndergroundDataArray().getHiddenCppPointer())
+        vExp=DataArrayDouble([0.,1.,2.,3.,1.,1.5,2.2,3.1,2.,2.2,3.,3.1,3.,3.1,3.5,4])
+        self.assertTrue(v.isEqual(vExp,1e-12))
+        #
+        fcscp=allFMTSLeavesPerCommonSupport1[1][1]
+        mml=fcscp.buildFromScratchDataSetSupport(0,fields)
+        mml2=mml.prepare()
+        self.assertTrue(isinstance(mml2,MEDUMeshMultiLev))
+        ncc,a0,a1,a2,a3,a4,a5=mml2.buildVTUArrays()
+        self.assertTrue(not ncc)
+        self.assertTrue(a0.isEqual(DataArrayDouble([(0,0,0),(1,0,0),(2,0,0),(3,0,0),(0,1,0),(1,1,0),(2,1,0),(0,2,0),(1,2,0),(0,3,0)]),1e-12))
+        self.assertTrue(a1.isEqual(DataArrayByte([])))
+        self.assertTrue(a2.isEqual(DataArrayInt([])))
+        self.assertTrue(a3.isEqual(DataArrayInt([])))
+        self.assertTrue(a4 is None)
+        self.assertTrue(a5 is None)
+        fff1=allFMTSLeavesPerCommonSupport1[1][0][0][0]
+        fsst=MEDFileField1TSStructItem.BuildItemFrom(fff1,mst)
+        fff1.loadArraysIfNecessary()
+        v=mml2.buildDataArray(fsst,fields,fff1.getUndergroundDataArray())
+        self.assertEqual(fff1.getName(),"f1Pfl")
+        self.assertNotEqual(v.getHiddenCppPointer(),fff1.getUndergroundDataArray().getHiddenCppPointer()) # pointers are not equal because Profile
+        vExp=DataArrayDouble([3.,2.,1.,0.,2.,1.5,0.,1.,0.,0.2])
+        self.assertTrue(v.isEqual(vExp,1e-12))
+        pass
+
+    def test28(self):
+        """ This test defines 2 fields f0,f1,f2,f3 lying on an unstructured mesh whith cells including NORM_POINT1.
+        Both f0 and f1 are on NODES and f2 and f3 are on cells. f1 and f2 share the same support.
+        f0 is on a nodal support that is not matchable with any cells (including NORM_POINT1)
+        This test is a more aggressive version of test26.
+        """
+        fname="ForMEDReader28.med"
+        coords=DataArrayDouble([(0.,0.,0.),(1.,0.,0.),(2.,0.,0.),(3.,0.,0.),(0.,1.,0.),(1.,1.,0.),(2.,1.,0.),(3.,1.,0.),(0.,2.,0.),(1.,2.,0.),(2.,2.,0.),(3.,2.,0.),(0.,3.,0.),(1.,3.,0.),(2.,3.,0.),(3.,3.,0.)])
+        m0=MEDCouplingUMesh("mesh",2)
+        m0.allocateCells()
+        for elt in [[2,6,3],[6,7,3],[9,6,5],[9,10,6]]:
+            m0.insertNextCell(NORM_TRI3,elt)
+            pass
+        for elt in [[0,4,5,1],[1,5,6,2],[4,8,9,5],[6,10,11,7],[8,12,13,9],[9,13,14,10],[10,14,15,11]]:
+            m0.insertNextCell(NORM_QUAD4,elt)
+            pass
+        m0.setCoords(coords)
+        m2=MEDCouplingUMesh("mesh",0) ; m2.setCoords(coords)
+        m2.allocateCells()
+        for elt in [[8],[13]]:
+            m2.insertNextCell(NORM_POINT1,elt)
+            pass
+        ##
+        mm=MEDFileUMesh()
+        mm.setMeshAtLevel(0,m0)
+        mm.setMeshAtLevel(-2,m2)
+        mm.setFamilyFieldArr(0,DataArrayInt([-1,-2,-3,-4,-5,-6,-7,-8,-9,-10,-11]))
+        mm.setFamilyFieldArr(-2,DataArrayInt([-12,-13]))
+        mm.setFamilyFieldArr(1,DataArrayInt([1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]))
+        #
+        f1ts0Node=MEDFileField1TS()
+        f1ts1Node=MEDFileField1TS()
+        f1ts2Cell=MEDFileField1TS()
+        f1ts3Cell=MEDFileField1TS()
+        #
+        pfl0=DataArrayInt([4,5,6,8,9,12]) ; pfl0.setName("pfl0")
+        pfl1=DataArrayInt([0,1,4,5,7,10]) ; pfl1.setName("pfl1")
+        pfl2=DataArrayInt([0,1,2,3,4,5,6,7,10,11,14,15]) ; pfl2.setName("pfl2")
+        #
+        f0Node=MEDCouplingFieldDouble(ON_NODES) ; f0Node.setName("f0Node")
+        arr0=DataArrayDouble(6) ; arr0.iota()
+        f0Node.setArray(arr0)
+        f1ts0Node.setFieldProfile(f0Node,mm,0,pfl0)
+        #
+        f1Node=MEDCouplingFieldDouble(ON_NODES) ; f1Node.setName("f1Node")
+        arr1=DataArrayDouble(12) ; arr1.iota() ; arr1.reverse()
+        f1Node.setArray(arr1)
+        f1ts1Node.setFieldProfile(f1Node,mm,0,pfl2)
+        #
+        f2Cell=MEDCouplingFieldDouble(ON_CELLS) ; f2Cell.setName("f2Cell")
+        arr2=DataArrayDouble([2,3,0,1,4,5])
+        f2Cell.setArray(arr2)
+        f1ts2Cell.setFieldProfile(f2Cell,mm,0,pfl1)
+        #
+        f3Cell=MEDCouplingFieldDouble(ON_CELLS) ; f3Cell.setName("f3Cell")
+        arr3=DataArrayDouble([5,4,3,2,1,0]) ; f3Cell.setArray(arr3)
+        f1ts3Cell.setFieldProfile(f3Cell,mm,0,pfl1)
+        f3Cell.setMesh(m2)
+        arr3=DataArrayDouble([-1.1,-3.1]) ; f3Cell.setArray(arr3)
+        f1ts3Cell.setFieldNoProfileSBT(f3Cell)
+        #
+        fs=MEDFileFields()
+        for f in [f1ts0Node,f1ts1Node,f1ts2Cell,f1ts3Cell]:
+            fmts=MEDFileFieldMultiTS()
+            fmts.pushBackTimeStep(f)
+            fs.pushField(fmts)
+            pass
+        mm.write(fname,2)
+        fs.write(fname,0)
+        ########## GO for reading in MEDReader,by not loading all. Mesh is fully loaded but not fields values
+        ms=MEDFileMeshes(fname)
+        fields=MEDFileFields(fname,False)
+        fields_per_mesh=[fields.partOfThisLyingOnSpecifiedMeshName(meshName) for meshName in ms.getMeshesNames()]
+        allFMTSLeavesToDisplay=[]
+        for fields in fields_per_mesh:
+            allFMTSLeavesToDisplay2=[]
+            for fmts in fields:
+                allFMTSLeavesToDisplay2+=fmts.splitDiscretizations()
+                pass
+            allFMTSLeavesToDisplay.append(allFMTSLeavesToDisplay2)
+            pass
+        self.assertEqual(len(allFMTSLeavesToDisplay),1)
+        self.assertEqual(len(allFMTSLeavesToDisplay[0]),4)
+        allFMTSLeavesPerTimeSeries=MEDFileAnyTypeFieldMultiTS.SplitIntoCommonTimeSeries(sum(allFMTSLeavesToDisplay,[]))
+        self.assertEqual(len(allFMTSLeavesPerTimeSeries),1)
+        self.assertEqual(len(allFMTSLeavesPerTimeSeries[0]),4)
+        allFMTSLeavesPerCommonSupport1=MEDFileAnyTypeFieldMultiTS.SplitPerCommonSupport(allFMTSLeavesToDisplay[0],ms[ms.getMeshesNames()[0]])
+        self.assertEqual(len(allFMTSLeavesPerCommonSupport1),3)
+        self.assertEqual(len(allFMTSLeavesPerCommonSupport1[0][0]),2)
+        self.assertEqual(len(allFMTSLeavesPerCommonSupport1[1][0]),1)
+        self.assertEqual(len(allFMTSLeavesPerCommonSupport1[2][0]),1)
+        #
+        mst=MEDFileMeshStruct.New(ms[0])
+        #
+        fcscp=allFMTSLeavesPerCommonSupport1[2][1]
+        mml=fcscp.buildFromScratchDataSetSupport(0,fields)
+        mml2=mml.prepare()
+        self.assertTrue(isinstance(mml2,MEDUMeshMultiLev))
+        ncc,a0,a1,a2,a3,a4,a5=mml2.buildVTUArrays()
+        self.assertTrue(not ncc)
+        self.assertTrue(a0.isEqual(DataArrayDouble([0.,1.,0.,1.,1.,0.,2.,1.,0.,0.,2.,0.,1.,2.,0.,0.,3.,0.],6,3),1e-12))
+        self.assertTrue(a1.isEqual(DataArrayByte([5,9,1,1])))
+        self.assertTrue(a2.isEqual(DataArrayInt([0,4,9,11])))
+        self.assertTrue(a3.isEqual(DataArrayInt([3,4,2,1,4,0,3,4,1,1,3,1,5])))
+        self.assertTrue(a4 is None)
+        self.assertTrue(a5 is None)
+        a6,a7=mml2.retrieveFamilyIdsOnCells()
+        self.assertTrue(a6.isEqual(DataArrayInt([-3,-7,-12,13])))
+        self.assertTrue(not a7) # copy here because profile on cells
+        a8,a9=mml2.retrieveNumberIdsOnCells()
+        self.assertTrue(a8 is None)
+        self.assertTrue(a9) # no copy here because no number field
+        a10,a11=mml2.retrieveFamilyIdsOnNodes()
+        self.assertTrue(a10.isEqual(DataArrayInt([5,6,7,9,10,13])))
+        self.assertTrue(not a11) # copy here
+        a12,a13=mml2.retrieveNumberIdsOnNodes()
+        self.assertTrue(a12 is None)
+        self.assertTrue(a13) # no copy here because no number field
+        #
+        fff0=allFMTSLeavesPerCommonSupport1[2][0][0][0]
+        fsst=MEDFileField1TSStructItem.BuildItemFrom(fff0,mst)
+        fff0.loadArraysIfNecessary()
+        v=mml2.buildDataArray(fsst,fields,fff0.getUndergroundDataArray())
+        self.assertEqual(fff0.getName(),"f0Node")
+        self.assertEqual(v.getHiddenCppPointer(),fff0.getUndergroundDataArray().getHiddenCppPointer())
+        vExp=DataArrayDouble([0.,1.,2.,3.,4.,5.])
+        self.assertTrue(v.isEqual(vExp,1e-12)) # <- THE test is here !!!
+        ###
+        fcscp=allFMTSLeavesPerCommonSupport1[0][1]
+        mml=fcscp.buildFromScratchDataSetSupport(0,fields)
+        mml2=mml.prepare()
+        self.assertTrue(isinstance(mml2,MEDUMeshMultiLev))
+        ncc,a0,a1,a2,a3,a4,a5=mml2.buildVTUArrays()
+        self.assertTrue(not ncc)
+        self.assertTrue(a0.isEqual(DataArrayDouble([(0,0,0),(1,0,0),(2,0,0),(3,0,0),(0,1,0),(1,1,0),(2,1,0),(3,1,0),(2,2,0),(3,2,0),(2,3,0),(3,3,0)]),1e-12))
+        self.assertTrue(a1.isEqual(DataArrayByte([5,5,9,9,9,9])))
+        self.assertTrue(a2.isEqual(DataArrayInt([0,4,8,13,18,23])))
+        self.assertTrue(a3.isEqual(DataArrayInt([3,2,6,3,3,6,7,3,4,0,4,5,1,4,1,5,6,2,4,6,8,9,7,4,8,10,11,9])))
+        self.assertTrue(a4 is None)
+        self.assertTrue(a5 is None)
+        fff1=allFMTSLeavesPerCommonSupport1[0][0][0][0]
+        fsst=MEDFileField1TSStructItem.BuildItemFrom(fff1,mst)
+        fff1.loadArraysIfNecessary()
+        v=mml2.buildDataArray(fsst,fields,fff1.getUndergroundDataArray())
+        self.assertEqual(fff1.getName(),"f2Cell")
+        self.assertNotEqual(v.getHiddenCppPointer(),fff0.getUndergroundDataArray().getHiddenCppPointer())
+        vExp=DataArrayDouble([2,3,0,1,4,5])
+        self.assertTrue(v.isEqual(vExp,1e-12))
+        fff2=allFMTSLeavesPerCommonSupport1[0][0][1][0]
+        fsst=MEDFileField1TSStructItem.BuildItemFrom(fff2,mst)
+        fff2.loadArraysIfNecessary()
+        v=mml2.buildDataArray(fsst,fields,fff2.getUndergroundDataArray())
+        self.assertEqual(fff2.getName(),"f1Node")
+        self.assertNotEqual(v.getHiddenCppPointer(),fff0.getUndergroundDataArray().getHiddenCppPointer())
+        vExp=DataArrayDouble([11,10,9,8,7,6,5,4,3,2,1,0])
+        self.assertTrue(v.isEqual(vExp,1e-12))
+        ###
+        fcscp=allFMTSLeavesPerCommonSupport1[1][1]
+        mml=fcscp.buildFromScratchDataSetSupport(0,fields)
+        mml2=mml.prepare()
+        self.assertTrue(isinstance(mml2,MEDUMeshMultiLev))
+        ncc,a0,a1,a2,a3,a4,a5=mml2.buildVTUArrays()
+        self.assertTrue(ncc)# here all the 16 nodes are taken
+        self.assertTrue(a0.isEqual(DataArrayDouble([(0.,0.,0.),(1.,0.,0.),(2.,0.,0.),(3.,0.,0.),(0.,1.,0.),(1.,1.,0.),(2.,1.,0.),(3.,1.,0.),(0.,2.,0.),(1.,2.,0.),(2.,2.,0.),(3.,2.,0.),(0.,3.,0.),(1.,3.,0.),(2.,3.,0.),(3.,3.,0.)]),1e-12))
+        self.assertTrue(a1.isEqual(DataArrayByte([1,1,5,5,9,9,9,9])))
+        self.assertTrue(a2.isEqual(DataArrayInt([0,2,4,8,12,17,22,27])))
+        self.assertTrue(a3.isEqual(DataArrayInt([1,8,1,13,3,2,6,3,3,6,7,3,4,0,4,5,1,4,1,5,6,2,4,6,10,11,7,4,10,14,15,11])))
+        self.assertTrue(a4 is None)
+        self.assertTrue(a5 is None)
+        fff3=allFMTSLeavesPerCommonSupport1[1][0][0][0]
+        fsst=MEDFileField1TSStructItem.BuildItemFrom(fff3,mst)
+        fff3.loadArraysIfNecessary()
+        v=mml2.buildDataArray(fsst,fields,fff3.getUndergroundDataArray())
+        self.assertEqual(fff3.getName(),"f3Cell")
+        self.assertNotEqual(v.getHiddenCppPointer(),fff0.getUndergroundDataArray().getHiddenCppPointer())
+        vExp=DataArrayDouble([-1.1,-3.1,5,4,3,2,1,0])
+        self.assertTrue(v.isEqual(vExp,1e-12))
+        pass
     pass
 
 unittest.main()