Salome HOME
Merge from V6_main 12/04/2013
[tools/medcoupling.git] / src / MEDLoader / MEDFileField.cxx
index d1da7a2b8bc7b61f45c4b33d04ae70e816cdb7a4..fce2b6b6cc853b918fec7b2194d01ecac51a11e1 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2012  CEA/DEN, EDF R&D
+// Copyright (C) 2007-2013  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
@@ -1063,6 +1063,8 @@ std::vector<int> MEDFileFieldPerMeshPerType::addNewEntryIfNecessaryGauss(const M
   if(!disc2)
     throw INTERP_KERNEL::Exception("addNewEntryIfNecessaryGauss : invalid call to this method ! Internal Error !");
   const DataArrayInt *da=disc2->getArrayOfDiscIds();
+  if(!da)
+    throw INTERP_KERNEL::Exception("addNewEntryIfNecessaryGauss (no profile) : no localization ids per cell array available ! The input Gauss node field is maybe invalid !");
   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> da2=da->selectByTupleId2(offset,offset+nbOfCells,1);
   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> retTmp=da2->getDifferentValues();
   if(retTmp->presenceOfValue(-1))
@@ -1133,6 +1135,8 @@ std::vector<int> MEDFileFieldPerMeshPerType::addNewEntryIfNecessaryGauss(const M
   if(!disc2)
     throw INTERP_KERNEL::Exception("addNewEntryIfNecessaryGauss : invalid call to this method ! Internal Error !");
   const DataArrayInt *da=disc2->getArrayOfDiscIds();
+  if(!da)
+    throw INTERP_KERNEL::Exception("addNewEntryIfNecessaryGauss : no localization ids per cell array available ! The input Gauss node field is maybe invalid !");
   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> da2=da->selectByTupleIdSafe(subCells->getConstPointer(),subCells->getConstPointer()+subCells->getNumberOfTuples());
   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> retTmp=da2->getDifferentValues();
   if(retTmp->presenceOfValue(-1))
@@ -2217,7 +2221,7 @@ MEDCouplingFieldDouble *MEDFileFieldPerMesh::finishFieldNode2(const MEDFileField
   MEDCouplingAutoRefCountObjectPtr<MEDCouplingMesh> mesh2=mesh->buildPartAndReduceNodes(cellIds->getConstPointer(),cellIds->getConstPointer()+cellIds->getNbOfElems(),arr2);
   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> arr3(arr2);
   int nnodes=mesh2->getNumberOfNodes();
-  if(nnodes==da->getNbOfElems())
+  if(nnodes==(int)da->getNbOfElems())
     {
       MEDCouplingAutoRefCountObjectPtr<DataArrayInt> da3=da->transformWithIndArrR(arr2->begin(),arr2->end());
       ret->getArray()->renumberInPlace(da3->getConstPointer());
@@ -3667,7 +3671,7 @@ MEDCouplingFieldDouble *MEDFileField1TSWithoutSDA::getFieldOnMeshAtLevel(TypeOfF
         //no need to test _field_per_mesh.empty() because geMeshName has already done it
         if(cellRenum)
           {
-            if(cellRenum->getNbOfElems()!=mesh->getNumberOfCells())
+            if((int)cellRenum->getNbOfElems()!=mesh->getNumberOfCells())
               {
                 std::ostringstream oss; oss << "MEDFileField1TSWithoutSDA::getFieldOnMeshAtLevel : Request of simple renumbering but it seems that underlying mesh \"" << mesh->getName() << "\" of requested field ";
                 oss << "\"" << getName() << "\" has partial renumbering (some geotype has no renumber) !";
@@ -3685,7 +3689,7 @@ MEDCouplingFieldDouble *MEDFileField1TSWithoutSDA::getFieldOnMeshAtLevel(TypeOfF
           throw INTERP_KERNEL::Exception(msg1);
         if(nodeRenum)
           {
-            if(nodeRenum->getNbOfElems()!=mesh->getNumberOfNodes())
+            if((int)nodeRenum->getNbOfElems()!=mesh->getNumberOfNodes())
               {
                 std::ostringstream oss; oss << "MEDFileField1TSWithoutSDA::getFieldOnMeshAtLevel : Request of simple renumbering but it seems that underlying mesh \"" << mesh->getName() << "\" of requested field ";
                 oss << "\"" << getName() << "\" not defined on all nodes !";
@@ -3860,6 +3864,26 @@ const DataArrayDouble *MEDFileField1TSWithoutSDA::getOrCreateAndGetArray() const
   return ret2;
 }
 
+/*!
+ * This methods returns a new instance (to be dealt by the caller).
+ * This method returns for the first field in the file \a fileName the first time step of this first field, if
+ * such field exists and time step exists. If not, an INTERP_KERNEL::Exception will be thrown.
+ */
+MEDFileField1TS *MEDFileField1TS::New(const char *fileName) throw(INTERP_KERNEL::Exception)
+{
+  return new MEDFileField1TS(fileName);
+}
+
+/*!
+ * This methods returns a new instance (to be dealt by the caller).
+ * This method returns the first time step of the field \a fieldName in file \a fieldName, if
+ * such field exists. If not, an INTERP_KERNEL::Exception will be thrown.
+ */
+MEDFileField1TS *MEDFileField1TS::New(const char *fileName, const char *fieldName) throw(INTERP_KERNEL::Exception)
+{
+  return new MEDFileField1TS(fileName,fieldName);
+}
+
 MEDFileField1TS *MEDFileField1TS::New(const char *fileName, const char *fieldName, int iteration, int order) throw(INTERP_KERNEL::Exception)
 {
   return new MEDFileField1TS(fileName,fieldName,iteration,order);
@@ -3913,47 +3937,91 @@ void MEDFileField1TS::write(const char *fileName, int mode) const throw(INTERP_K
   writeLL(fid);
 }
 
-MEDFileField1TS::MEDFileField1TS(const char *fileName, const char *fieldName, int iteration, int order) throw(INTERP_KERNEL::Exception)
-try:MEDFileFieldGlobsReal(fileName),_content(MEDFileField1TSWithoutSDA::New(fieldName,-1,-1,iteration,order,std::vector<std::string>()))
+MEDFileField1TS::MEDFileField1TS(const char *fileName) throw(INTERP_KERNEL::Exception)
+try:MEDFileFieldGlobsReal(fileName)
 {
   MEDFileUtilities::CheckFileForRead(fileName);
   MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName,MED_ACC_RDONLY);
-  int nbFields=MEDnField(fid);
   med_field_type typcha;
-  bool found=false;
-  std::vector<std::string> fns(nbFields);
-  int nbOfStep2=-1;
-  for(int i=0;i<nbFields && !found;i++)
+  //
+  int nbFields=MEDnField(fid);
+  if(nbFields<1)
     {
-      int ncomp=MEDfieldnComponent(fid,i+1);
-      INTERP_KERNEL::AutoPtr<char> comp=MEDLoaderBase::buildEmptyString(ncomp*MED_SNAME_SIZE);
-      INTERP_KERNEL::AutoPtr<char> unit=MEDLoaderBase::buildEmptyString(ncomp*MED_SNAME_SIZE);
-      INTERP_KERNEL::AutoPtr<char> dtunit=MEDLoaderBase::buildEmptyString(MED_LNAME_SIZE);
-      INTERP_KERNEL::AutoPtr<char> nomcha=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
-      INTERP_KERNEL::AutoPtr<char> nomMaa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
-      med_bool localMesh;
-      int nbOfStep;
-      MEDfieldInfo(fid,i+1,nomcha,nomMaa,&localMesh,&typcha,comp,unit,dtunit,&nbOfStep);
-      std::string tmp(nomcha);
-      fns[i]=tmp;
-      found=(tmp==fieldName);
-      if(found)
-        {
-          nbOfStep2=nbOfStep;
-          std::string mname=MEDLoaderBase::buildStringFromFortran(nomMaa,MED_NAME_SIZE);
-          std::vector<std::string> infos(ncomp);
-          for(int j=0;j<ncomp;j++)
-            infos[j]=MEDLoaderBase::buildUnionUnit((char *)comp+j*MED_SNAME_SIZE,MED_SNAME_SIZE,(char *)unit+j*MED_SNAME_SIZE,MED_SNAME_SIZE);
-          _content->getOrCreateAndGetArray()->setInfoAndChangeNbOfCompo(infos);
-        }
+      std::ostringstream oss; oss << "MEDFileField1TS(fileName) : no field present in file \'" << fileName << "\' !";
+      throw INTERP_KERNEL::Exception(oss.str().c_str());
     }
-  if(!found)
+  int ncomp=MEDfieldnComponent(fid,1);
+  INTERP_KERNEL::AutoPtr<char> comp=MEDLoaderBase::buildEmptyString(ncomp*MED_SNAME_SIZE);
+  INTERP_KERNEL::AutoPtr<char> unit=MEDLoaderBase::buildEmptyString(ncomp*MED_SNAME_SIZE);
+  INTERP_KERNEL::AutoPtr<char> dtunit=MEDLoaderBase::buildEmptyString(MED_LNAME_SIZE);
+  INTERP_KERNEL::AutoPtr<char> nomcha=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
+  INTERP_KERNEL::AutoPtr<char> nomMaa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
+  med_bool localMesh;
+  int nbOfStep;
+  MEDfieldInfo(fid,1,nomcha,nomMaa,&localMesh,&typcha,comp,unit,dtunit,&nbOfStep);
+  std::string fieldName(nomcha);
+  if(nbOfStep<1)
     {
-      std::ostringstream oss; oss << "No such field '" << fieldName << "' in file '" << fileName << "' ! Available fields are : ";
-      std::copy(fns.begin(),fns.end(),std::ostream_iterator<std::string>(oss," "));
+      std::ostringstream oss; oss << "MEDFileField1TS(fileName) : file \'" << fileName << "\' contains field with name \'" << fieldName << "\' but there is no time steps on it !";
       throw INTERP_KERNEL::Exception(oss.str().c_str());
     }
-  found=false;
+  std::vector<std::string> infos(ncomp);
+  for(int j=0;j<ncomp;j++)
+    infos[j]=MEDLoaderBase::buildUnionUnit((char *)comp+j*MED_SNAME_SIZE,MED_SNAME_SIZE,(char *)unit+j*MED_SNAME_SIZE,MED_SNAME_SIZE);
+  _content=MEDFileField1TSWithoutSDA::New(fieldName.c_str(),-1,-1,-1/*iteration*/,-1/*order*/,std::vector<std::string>());
+  _content->getOrCreateAndGetArray()->setInfoAndChangeNbOfCompo(infos);
+  //
+  med_int numdt,numit;
+  med_float dt;
+  MEDfieldComputingStepInfo(fid,fieldName.c_str(),1,&numdt,&numit,&dt);
+  _content->setTime(numdt,numit,dt);
+  _content->_csit=1;
+  _content->_field_type=MEDFileUtilities::TraduceFieldType(typcha);
+  _content->finishLoading(fid);
+  //
+  loadGlobals(fid);
+}
+catch(INTERP_KERNEL::Exception& e)
+  {
+    throw e;
+  }
+
+MEDFileField1TS::MEDFileField1TS(const char *fileName, const char *fieldName) throw(INTERP_KERNEL::Exception)
+try:MEDFileFieldGlobsReal(fileName),_content(MEDFileField1TSWithoutSDA::New(fieldName,-1,-1,-1/*iteration*/,-1/*order*/,std::vector<std::string>()))
+{
+  MEDFileUtilities::CheckFileForRead(fileName);
+  MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName,MED_ACC_RDONLY);
+  med_field_type typcha;
+  int nbSteps=locateField(fid,fileName,fieldName,typcha);
+  if(nbSteps<1)
+    {
+      std::ostringstream oss; oss << "MEDFileField1TS(fileName,fieldName) : file \'" << fileName << "\' contains field with name \'" << fieldName << "\' but there is no time steps on it !";
+      throw INTERP_KERNEL::Exception(oss.str().c_str());
+    }
+  //
+  med_int numdt,numit;
+  med_float dt;
+  MEDfieldComputingStepInfo(fid,fieldName,1,&numdt,&numit,&dt);
+  _content->setTime(numdt,numit,dt);
+  _content->_csit=1;
+  _content->_field_type=MEDFileUtilities::TraduceFieldType(typcha);
+  _content->finishLoading(fid);
+  //
+  loadGlobals(fid);
+}
+catch(INTERP_KERNEL::Exception& e)
+  {
+    throw e;
+  }
+
+MEDFileField1TS::MEDFileField1TS(const char *fileName, const char *fieldName, int iteration, int order) throw(INTERP_KERNEL::Exception)
+try:MEDFileFieldGlobsReal(fileName),_content(MEDFileField1TSWithoutSDA::New(fieldName,-1,-1,iteration,order,std::vector<std::string>()))
+{
+  MEDFileUtilities::CheckFileForRead(fileName);
+  MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName,MED_ACC_RDONLY);
+  med_field_type typcha;
+  int nbOfStep2=locateField(fid,fileName,fieldName,typcha);
+  bool found=false;
   std::vector< std::pair<int,int> > dtits(nbOfStep2);
   for(int i=0;i<nbOfStep2 && !found;i++)
     {
@@ -4006,6 +4074,52 @@ MEDFileField1TS::MEDFileField1TS():_content(new MEDFileField1TSWithoutSDA)
 {
 }
 
+/*!
+ * This method throws an INTERP_KERNEL::Exception if \a fieldName field is not in file pointed by \a fid and with name \a fileName.
+ * 
+ * \param [out]
+ * \return in case of success the number of time steps available for the field with name \a fieldName.
+ */
+int MEDFileField1TS::locateField(med_idt fid, const char *fileName, const char *fieldName, med_field_type& typcha) throw(INTERP_KERNEL::Exception)
+{
+  int nbFields=MEDnField(fid);
+  bool found=false;
+  std::vector<std::string> fns(nbFields);
+  int nbOfStep2=-1;
+  for(int i=0;i<nbFields && !found;i++)
+    {
+      int ncomp=MEDfieldnComponent(fid,i+1);
+      INTERP_KERNEL::AutoPtr<char> comp=MEDLoaderBase::buildEmptyString(ncomp*MED_SNAME_SIZE);
+      INTERP_KERNEL::AutoPtr<char> unit=MEDLoaderBase::buildEmptyString(ncomp*MED_SNAME_SIZE);
+      INTERP_KERNEL::AutoPtr<char> dtunit=MEDLoaderBase::buildEmptyString(MED_LNAME_SIZE);
+      INTERP_KERNEL::AutoPtr<char> nomcha=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
+      INTERP_KERNEL::AutoPtr<char> nomMaa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
+      med_bool localMesh;
+      int nbOfStep;
+      MEDfieldInfo(fid,i+1,nomcha,nomMaa,&localMesh,&typcha,comp,unit,dtunit,&nbOfStep);
+      std::string tmp(nomcha);
+      fns[i]=tmp;
+      found=(tmp==fieldName);
+      if(found)
+        {
+          nbOfStep2=nbOfStep;
+          std::string mname=MEDLoaderBase::buildStringFromFortran(nomMaa,MED_NAME_SIZE);
+          std::vector<std::string> infos(ncomp);
+          for(int j=0;j<ncomp;j++)
+            infos[j]=MEDLoaderBase::buildUnionUnit((char *)comp+j*MED_SNAME_SIZE,MED_SNAME_SIZE,(char *)unit+j*MED_SNAME_SIZE,MED_SNAME_SIZE);
+          _content->getOrCreateAndGetArray()->setInfoAndChangeNbOfCompo(infos);
+        }
+    }
+  if(!found)
+    {
+      std::ostringstream oss; oss << "No such field '" << fieldName << "' in file '" << fileName << "' ! Available fields are : ";
+      for(std::vector<std::string>::const_iterator it=fns.begin();it!=fns.end();it++)
+        oss << "\"" << *it << "\" ";
+      throw INTERP_KERNEL::Exception(oss.str().c_str());
+    }
+  return nbOfStep2;
+}
+
 /*!
  * This method returns all profiles whose name is non empty used.
  * \b WARNING If profile is used several times it will be reported \b only \b once.