Salome HOME
[Intersect2D] Keep flexibility on orientation of mesh2
[tools/medcoupling.git] / src / MEDLoader / MEDFileMeshLL.cxx
index 0d5aa1ca95dd96b8babedc744aed97e1b62caec3..ecef4f432b53bb2fb110e495607668ffb65cffed 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2020  CEA/DEN, EDF R&D
+// Copyright (C) 2007-2021  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
@@ -34,6 +34,7 @@
 #include <set>
 #include <iomanip>
 
+// From MEDLOader.cxx TU
 extern med_geometry_type typmai[MED_N_CELL_FIXED_GEO];
 extern INTERP_KERNEL::NormalizedCellType typmai2[MED_N_CELL_FIXED_GEO];
 extern med_geometry_type typmainoeud[1];
@@ -104,7 +105,7 @@ double MeshCls::checkMeshTimeStep(med_idt fid, const std::string& mName, int nst
 {
   bool found=false;
   med_int numdt,numit;
-  med_float dtt;
+  med_float dtt=0.0;
   std::vector< std::pair<int,int> > p(nstep);
   for(int i=0;i<nstep;i++)
     {
@@ -171,7 +172,7 @@ std::vector<const BigMemoryObject *> MEDFileMeshL2::getDirectChildrenWithNull()
 
 INTERP_KERNEL::AutoCppPtr<MeshOrStructMeshCls> MEDFileMeshL2::GetMeshIdFromName(med_idt fid, const std::string& mName, MEDCoupling::MEDCouplingMeshType& meshType, MEDCoupling::MEDCouplingAxisType& axType, int& dt, int& it, std::string& dtunit1)
 {
-  med_mesh_type type_maillage;
+  med_mesh_type type_maillage=MED_UNDEF_MESH_TYPE;
   char maillage_description[MED_COMMENT_SIZE+1];
   char dtunit[MED_LNAME_SIZE+1];
   med_int spaceDim,dim;
@@ -182,7 +183,7 @@ INTERP_KERNEL::AutoCppPtr<MeshOrStructMeshCls> MEDFileMeshL2::GetMeshIdFromName(
   med_sorting_type stype;
   std::vector<std::string> ms;
   med_int nstep;
-  med_axis_type axistype;
+  med_axis_type axistype=MED_UNDEF_AXIS_TYPE;
   for(int i=0;i<n && found==0;i++)
     {
       med_int naxis(MEDmeshnAxis(fid,i+1));
@@ -298,10 +299,10 @@ void MEDFileMeshL2::ReadFamiliesAndGrps(med_idt fid, const std::string& meshName
       INTERP_KERNEL::AutoPtr<char> gro=new char[MED_LNAME_SIZE*ngro+1];
       MEDfamily23Info(fid,meshName.c_str(),i+1,nomfam,attide,attval,attdes,&numfam,gro);
       std::string famName(MEDLoaderBase::buildStringFromFortran(nomfam,MED_NAME_SIZE));
-      std::vector<std::string> grps(ngro);
+      std::vector<std::string> grps2(ngro);
       for(int j=0;j<ngro;j++)
-        grps[j]=MEDLoaderBase::buildStringFromFortran(gro+j*MED_LNAME_SIZE,MED_LNAME_SIZE);
-      crudeFams[i]=std::pair<std::string,std::pair<mcIdType,std::vector<std::string> > >(famName,std::pair<mcIdType,std::vector<std::string> >(numfam,grps));
+        grps2[j]=MEDLoaderBase::buildStringFromFortran(gro+j*MED_LNAME_SIZE,MED_LNAME_SIZE);
+      crudeFams[i]=std::pair<std::string,std::pair<mcIdType,std::vector<std::string> > >(famName,std::pair<mcIdType,std::vector<std::string> >(numfam,grps2));
     }
   RenameFamiliesFromFileToMemInternal(crudeFams);
   for(std::vector< std::pair<std::string,std::pair<mcIdType,std::vector<std::string> > > >::const_iterator it0=crudeFams.begin();it0!=crudeFams.end();it0++)
@@ -559,13 +560,26 @@ void MEDFileUMeshL2::loadPart(med_idt fid, const MeshOrStructMeshCls *mId, const
   for(std::vector< std::vector< MCAuto<MEDFileUMeshPerType> > >::const_iterator it0=_per_type_mesh.begin();it0!=_per_type_mesh.end();it0++)
     for(std::vector< MCAuto<MEDFileUMeshPerType> >::const_iterator it1=(*it0).begin();it1!=(*it0).end();it1++)
       (*it1)->getMesh()->computeNodeIdsAlg(fetchedNodeIds);
-  mcIdType nMin(ToIdType(std::distance(fetchedNodeIds.begin(),std::find(fetchedNodeIds.begin(),fetchedNodeIds.end(),true))));
-  mcIdType nMax(ToIdType(std::distance(fetchedNodeIds.rbegin(),std::find(fetchedNodeIds.rbegin(),fetchedNodeIds.rend(),true))));
-  nMax=nCoords-nMax;
-  for(std::vector< std::vector< MCAuto<MEDFileUMeshPerType> > >::const_iterator it0=_per_type_mesh.begin();it0!=_per_type_mesh.end();it0++)
-    for(std::vector< MCAuto<MEDFileUMeshPerType> >::const_iterator it1=(*it0).begin();it1!=(*it0).end();it1++)
-      (*it1)->getMesh()->renumberNodesWithOffsetInConn(-nMin);
-  loadPartCoords(fid,infosOnComp,mName,dt,it,nMin,nMax);
+  if(!mrs || mrs->getNumberOfCoordsLoadSessions()==1)
+  {
+    mcIdType nMin(ToIdType(std::distance(fetchedNodeIds.begin(),std::find(fetchedNodeIds.begin(),fetchedNodeIds.end(),true))));
+    mcIdType nMax(ToIdType(std::distance(fetchedNodeIds.rbegin(),std::find(fetchedNodeIds.rbegin(),fetchedNodeIds.rend(),true))));
+    nMax=nCoords-nMax;
+    for(std::vector< std::vector< MCAuto<MEDFileUMeshPerType> > >::const_iterator it0=_per_type_mesh.begin();it0!=_per_type_mesh.end();it0++)
+      for(std::vector< MCAuto<MEDFileUMeshPerType> >::const_iterator it1=(*it0).begin();it1!=(*it0).end();it1++)
+        (*it1)->getMesh()->renumberNodesWithOffsetInConn(-nMin);
+    this->loadPartCoords(fid,infosOnComp,mName,dt,it,nMin,nMax);
+  }
+  else
+  {
+    mcIdType nbOfCooLS(mrs->getNumberOfCoordsLoadSessions());
+    MCAuto<DataArrayIdType> fni(DataArrayIdType::BuildListOfSwitchedOn(fetchedNodeIds));
+    MCAuto< MapKeyVal<mcIdType, mcIdType> > o2n(fni->invertArrayN2O2O2NOptimized());
+    for(std::vector< std::vector< MCAuto<MEDFileUMeshPerType> > >::const_iterator it0=_per_type_mesh.begin();it0!=_per_type_mesh.end();it0++)
+      for(std::vector< MCAuto<MEDFileUMeshPerType> >::const_iterator it1=(*it0).begin();it1!=(*it0).end();it1++)
+        (*it1)->getMesh()->renumberNodesInConn(o2n->data());
+    this->loadPartCoordsSlice(fid,infosOnComp,mName,dt,it,fni,nbOfCooLS);
+  }
 }
 
 void MEDFileUMeshL2::loadConnectivity(med_idt fid, int mdim, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
@@ -648,7 +662,8 @@ void MEDFileUMeshL2::loadCoords(med_idt fid, const std::vector<std::string>& inf
     _coords->setInfoOnComponent(i,infosOnComp[i]);
 }
 
-void MEDFileUMeshL2::loadPartCoords(med_idt fid, const std::vector<std::string>& infosOnComp, const std::string& mName, int dt, int it, mcIdType nMin, mcIdType nMax)
+void MEDFileUMeshL2::LoadPartCoords(med_idt fid, const std::vector<std::string>& infosOnComp, const std::string& mName, int dt, int it, mcIdType nMin, mcIdType nMax,
+MCAuto<DataArrayDouble>& _coords, MCAuto<PartDefinition>& _part_coords, MCAuto<DataArrayIdType>& _fam_coords, MCAuto<DataArrayIdType>& _num_coords, MCAuto<DataArrayAsciiChar>& _name_coords)
 {
   med_bool changement,transformation;
   med_int spaceDim((int)infosOnComp.size()),nCoords(MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,MED_COORDINATE,MED_NO_CMODE,&changement,&transformation));
@@ -673,7 +688,7 @@ void MEDFileUMeshL2::loadPartCoords(med_idt fid, const std::vector<std::string>&
       _fam_coords=FromMedIntArray<mcIdType>(miFamCoord);
     }
   else
-    _fam_coords=0;
+    _fam_coords=nullptr;
   if(MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NO_GEOTYPE,MED_NUMBER,MED_NODAL,&changement,&transformation)>0)
     {
       MCAuto<DataArrayMedInt> miNumCoord=DataArrayMedInt::New();
@@ -682,7 +697,7 @@ void MEDFileUMeshL2::loadPartCoords(med_idt fid, const std::vector<std::string>&
       _num_coords=FromMedIntArray<mcIdType>(miNumCoord);
     }
   else
-    _num_coords=0;
+    _num_coords=nullptr;
   if(MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NO_GEOTYPE,MED_NAME,MED_NODAL,&changement,&transformation)>0)
     {
       _name_coords=DataArrayAsciiChar::New();
@@ -691,11 +706,81 @@ void MEDFileUMeshL2::loadPartCoords(med_idt fid, const std::vector<std::string>&
       _name_coords->reAlloc(nbNodesToLoad);//not a bug to avoid the memory corruption due to last \0 at the end
     }
   else
-    _name_coords=0;
+    _name_coords=nullptr;
   MEDfilterClose(&filter2);
   _coords->setInfoOnComponents(infosOnComp);
 }
 
+/*!
+ * For performance reasons LoadPartCoordsArray method calls LoadPartCoords
+ */
+void MEDFileUMeshL2::LoadPartCoordsArray(med_idt fid, const std::vector<std::string>& infosOnComp, const std::string& mName, int dt, int it, const DataArrayIdType *nodeIds,
+MCAuto<DataArrayDouble>& _coords, MCAuto<DataArrayIdType>& _fam_coords, MCAuto<DataArrayIdType>& _num_coords, MCAuto<DataArrayAsciiChar>& _name_coords)
+{
+  MCAuto<PartDefinition> useless;
+  nodeIds->checkAllocated();
+  nodeIds->checkNbOfComps(1,"loadPartCoordsSlice : Only one component expected !");
+  mcIdType nMin(0),nMax(0);
+  if(!nodeIds->empty())
+  { nMin = nodeIds->front(); nMax = nodeIds->back()+1; }
+  LoadPartCoords(fid,infosOnComp,mName,dt,it,nMin,nMax,_coords,useless,_fam_coords,_num_coords,_name_coords);
+  if(nodeIds->empty())
+    return ;
+  MCAuto<DataArrayIdType> nodeIds2(nodeIds->deepCopy());
+  nodeIds2->applyLin(1,-nMin);
+  _coords = _coords->selectByTupleIdSafe(nodeIds2->begin(),nodeIds2->end());
+  if(_fam_coords.isNotNull())
+    _fam_coords = _fam_coords->selectByTupleIdSafe(nodeIds2->begin(),nodeIds2->end());
+  if(_num_coords.isNotNull())
+    _num_coords = _num_coords->selectByTupleIdSafe(nodeIds2->begin(),nodeIds2->end());
+  if(_name_coords.isNotNull())
+    {
+      MCAuto<DataArrayChar> tmp(_name_coords->selectByTupleIdSafe(nodeIds2->begin(),nodeIds2->end()));
+      _name_coords = DynamicCastSafe<DataArrayChar,DataArrayAsciiChar>( tmp );
+    }
+}
+
+void MEDFileUMeshL2::loadPartCoords(med_idt fid, const std::vector<std::string>& infosOnComp, const std::string& mName, int dt, int it, mcIdType nMin, mcIdType nMax)
+{
+  LoadPartCoords(fid,infosOnComp,mName,dt,it,nMin,nMax,_coords,_part_coords,_fam_coords,_num_coords,_name_coords);
+}
+
+void MEDFileUMeshL2::loadPartCoordsSlice(med_idt fid, const std::vector<std::string>& infosOnComp, const std::string& mName, int dt, int it, const DataArrayIdType *nodeIds, mcIdType nbOfCoordLS)
+{
+  nodeIds->checkAllocated();
+  nodeIds->checkNbOfComps(1,"loadPartCoordsSlice : Only one component expected !");
+  if(nodeIds->empty())
+    return ;
+  if( nbOfCoordLS<1 )
+    throw INTERP_KERNEL::Exception("MEDFileUMeshL2::loadPartCoordsSlice : nb of coords load session must be >=1 !");
+  mcIdType nMin(nodeIds->front()),nMax(nodeIds->back()+1);
+  std::vector< MCAuto<DataArrayDouble> > coords(nbOfCoordLS);
+  std::vector< MCAuto<DataArrayIdType> > famCoords(nbOfCoordLS);
+  std::vector< MCAuto<DataArrayIdType> > numCoords(nbOfCoordLS);
+  std::vector< MCAuto<DataArrayAsciiChar> > nameCoords(nbOfCoordLS);
+  for(mcIdType ipart = 0 ; ipart < nbOfCoordLS ; ++ipart)
+    {
+      mcIdType partStart,partStop;
+      DataArray::GetSlice(nMin,nMax,1,ipart,nbOfCoordLS,partStart,partStop);
+      MCAuto<DataArrayIdType> idsNodeIdsToKeep(nodeIds->findIdsInRange(partStart,partStop));
+      MCAuto<DataArrayIdType> nodeIdsToKeep( nodeIds->selectByTupleIdSafe(idsNodeIdsToKeep->begin(),idsNodeIdsToKeep->end()) );
+      LoadPartCoordsArray(fid,infosOnComp,mName,dt,it,nodeIdsToKeep,coords[ipart],famCoords[ipart],numCoords[ipart],nameCoords[ipart]);
+    }
+  _coords = DataArrayDouble::Aggregate(ToConstVect<DataArrayDouble>(coords));
+  if(famCoords[0].isNotNull())
+    _fam_coords = DataArrayIdType::Aggregate(ToConstVect<DataArrayIdType>(famCoords));
+  if(numCoords[0].isNotNull())
+    _num_coords = DataArrayIdType::Aggregate(ToConstVect<DataArrayIdType>(numCoords));
+  if(nameCoords[0].isNotNull())
+  {
+    std::vector< MCAuto<DataArrayChar> > nameCoords2(nameCoords.begin(),nameCoords.end());
+    std::for_each(nameCoords2.begin(),nameCoords2.end(),[](MCAuto<DataArrayChar>& elt){ elt->incrRef(); });
+    MCAuto<DataArrayChar> tmp( DataArrayChar::Aggregate(ToConstVect<DataArrayChar>(nameCoords2)) );
+    _name_coords = DynamicCastSafe<DataArrayChar,DataArrayAsciiChar>( tmp );
+  }
+  _part_coords = DataArrayPartDefinition::New( const_cast<DataArrayIdType *>(nodeIds) );
+}
+
 void MEDFileUMeshL2::sortTypes()
 {
   std::set<int> mdims;
@@ -1489,8 +1574,17 @@ void MEDFileUMeshSplitL1::TraduceFamilyNumber(const std::vector< std::vector<mcI
 void MEDFileUMeshSplitL1::computeRevNum() const
 {
   mcIdType pos;
-  mcIdType maxValue=_num->getMaxValue(pos);
-  _rev_num=_num->invertArrayN2O2O2N(maxValue+1);
+  if(!_num->empty())
+  {
+    mcIdType maxValue=_num->getMaxValue(pos);
+    _rev_num=_num->invertArrayN2O2O2N(maxValue+1);
+  }
+  else
+  {
+    _rev_num = DataArrayIdType::New();
+    _rev_num->alloc(0,1);
+  }
+  
 }
 
 //=
@@ -1632,6 +1726,16 @@ std::vector<MEDCoupling1GTUMesh *> MEDFileUMeshAggregateCompute::getParts() cons
   return retrievePartsWithoutComputation();
 }
 
+void MEDFileUMeshAggregateCompute::highlightUsedNodes(std::vector<bool>& nodesToBeHighlighted) const
+{
+  if(_mp_time<_m_time)
+    forceComputationOfPartsFromUMesh();
+  for(auto part : this->_m_parts)
+  {
+    part->computeNodeIdsAlg(nodesToBeHighlighted);
+  }
+}
+
 MEDCoupling1GTUMesh *MEDFileUMeshAggregateCompute::retrievePartWithoutComputation(INTERP_KERNEL::NormalizedCellType gt) const
 {
   std::vector<MEDCoupling1GTUMesh *> v(retrievePartsWithoutComputation());
@@ -1683,6 +1787,9 @@ void MEDFileUMeshAggregateCompute::renumberNodesInConnWithoutComputation(const m
       if(!m)
         return;
       m->renumberNodesInConn(newNodeNumbersO2N);
+      // if _mp_time == _m_time notify for future clients that _m_parts is obsolete
+      _m_parts.clear();
+      _m_time = std::max(_m_time,_mp_time+1);
     }
 }