Salome HOME
Merge from V6_main 12/04/2013
[tools/medcoupling.git] / src / MEDCoupling / MEDCouplingField.cxx
index da93e7a6e1d555a5e33489db2ddc15ec0c1d89a5..967caf41407b34f10e1fb98a9d26a512d413359e 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
@@ -45,7 +45,7 @@ bool MEDCouplingField::isEqualIfNotWhy(const MEDCouplingField *other, double mes
     }
   if(_nature!=other->_nature)
     {
-      oss << "Field nature differ : this nature = \"" << MEDCouplingNatureOfField::getRepr(_nature) << "\" and other nature = \"" << MEDCouplingNatureOfField::getRepr(other->_nature) << "\" !";
+      oss << "Field nature differ : this nature = \"" << MEDCouplingNatureOfField::GetRepr(_nature) << "\" and other nature = \"" << MEDCouplingNatureOfField::GetRepr(other->_nature) << "\" !";
       reason=oss.str();
       return false;
     }
@@ -77,6 +77,10 @@ bool MEDCouplingField::isEqual(const MEDCouplingField *other, double meshPrec, d
 
 bool MEDCouplingField::isEqualWithoutConsideringStr(const MEDCouplingField *other, double meshPrec, double valsPrec) const
 {
+  if(!other)
+    throw INTERP_KERNEL::Exception("MEDCouplingField::isEqualWithoutConsideringStr : input field is NULL !");
+  if(!_type)
+    throw INTERP_KERNEL::Exception("MEDCouplingField::isEqualWithoutConsideringStr : spatial discretization of this is NULL !");
   if(!_type->isEqualWithoutConsideringStr(other->_type,valsPrec))
     return false;
   if(_nature!=other->_nature)
@@ -97,6 +101,8 @@ bool MEDCouplingField::isEqualWithoutConsideringStr(const MEDCouplingField *othe
  */
 bool MEDCouplingField::areCompatibleForMerge(const MEDCouplingField *other) const
 {
+  if(!other)
+    throw INTERP_KERNEL::Exception("MEDCouplingField::areCompatibleForMerge : input field is NULL !");
   if(!_type->isEqual(other->_type,1.))
     return false;
   if(_nature!=other->_nature)
@@ -112,6 +118,8 @@ bool MEDCouplingField::areCompatibleForMerge(const MEDCouplingField *other) cons
  */
 bool MEDCouplingField::areStrictlyCompatible(const MEDCouplingField *other) const
 {
+  if(!other)
+    throw INTERP_KERNEL::Exception("MEDCouplingField::areStrictlyCompatible : input field is NULL !");
   if(!_type->isEqual(other->_type,1.e-12))
     return false;
   if(_nature!=other->_nature)
@@ -161,6 +169,7 @@ NatureOfField MEDCouplingField::getNature() const
  */
 void MEDCouplingField::setNature(NatureOfField nat) throw(INTERP_KERNEL::Exception)
 {
+  MEDCouplingNatureOfField::GetRepr(nat);//generate a throw if nat not recognized
   _nature=nat;
 }
 
@@ -174,6 +183,8 @@ DataArrayDouble *MEDCouplingField::getLocalizationOfDiscr() const throw(INTERP_K
 {
   if(!_mesh)
     throw INTERP_KERNEL::Exception("MEDCouplingField::getLocalizationOfDiscr : No mesh set !");
+  if(!((const MEDCouplingFieldDiscretization *)_type))
+    throw INTERP_KERNEL::Exception("MEDCouplingField::getLocalizationOfDiscr : No spatial discretization set !");
   return _type->getLocalizationOfDiscValues(_mesh);
 }
 
@@ -183,8 +194,10 @@ DataArrayDouble *MEDCouplingField::getLocalizationOfDiscr() const throw(INTERP_K
  */
 MEDCouplingFieldDouble *MEDCouplingField::buildMeasureField(bool isAbs) const throw(INTERP_KERNEL::Exception)
 {
-  if(_mesh==0)
-    throw INTERP_KERNEL::Exception("MEDCouplingField::getMeasureField : no mesh defined !!!");
+  if(!_mesh)
+    throw INTERP_KERNEL::Exception("MEDCouplingField::buildMeasureField : no mesh defined !");
+  if(!((const MEDCouplingFieldDiscretization *)_type))
+    throw INTERP_KERNEL::Exception("MEDCouplingField::buildMeasureField : No spatial discretization set !");
   return _type->getMeasureField(_mesh,isAbs);
 }
 
@@ -195,6 +208,7 @@ void MEDCouplingField::setMesh(const MEDCouplingMesh *mesh)
       if(_mesh)
         _mesh->decrRef();
       _mesh=mesh;
+      declareAsNew();
       if(_mesh)
         {
           _mesh->incrRef();
@@ -216,6 +230,8 @@ void MEDCouplingField::setGaussLocalizationOnType(INTERP_KERNEL::NormalizedCellT
 {
   if(!_mesh)
     throw INTERP_KERNEL::Exception("Mesh has to be set before calling setGaussLocalizationOnType method !");
+  if(!((const MEDCouplingFieldDiscretization *)_type))
+    throw INTERP_KERNEL::Exception("Spatial discretization not set ! Impossible to call setGaussLocalizationOnType method !");
   _type->setGaussLocalizationOnType(_mesh,type,refCoo,gsCoo,wg);
 }
 
@@ -234,6 +250,8 @@ void MEDCouplingField::setGaussLocalizationOnCells(const int *begin, const int *
 {
   if(!_mesh)
     throw INTERP_KERNEL::Exception("Mesh has to be set before calling setGaussLocalizationOnCells method !");
+  if(!((const MEDCouplingFieldDiscretization *)_type))
+    throw INTERP_KERNEL::Exception("Spatial discretization not set ! Impossible to call setGaussLocalizationOnCells method !");
   _type->setGaussLocalizationOnCells(_mesh,begin,end,refCoo,gsCoo,wg);
 }
 
@@ -244,6 +262,8 @@ void MEDCouplingField::clearGaussLocalizations()
 {
   if(!_mesh)
     throw INTERP_KERNEL::Exception("Mesh has to be set before calling clearGaussLocalizations method !");
+  if(!((const MEDCouplingFieldDiscretization *)_type))
+    throw INTERP_KERNEL::Exception("Spatial discretization not set ! Impossible to call clearGaussLocalizations method !");
   _type->clearGaussLocalizations();
 }
 
@@ -257,6 +277,8 @@ MEDCouplingGaussLocalization& MEDCouplingField::getGaussLocalization(int locId)
 {
   if(!_mesh)
     throw INTERP_KERNEL::Exception("Mesh has to be set before calling getGaussLocalization method !");
+  if(!((const MEDCouplingFieldDiscretization *)_type))
+    throw INTERP_KERNEL::Exception("Spatial discretization not set ! Impossible to call getGaussLocalization method !");
   return _type->getGaussLocalization(locId);
 }
 
@@ -269,6 +291,8 @@ int MEDCouplingField::getGaussLocalizationIdOfOneType(INTERP_KERNEL::NormalizedC
 {
   if(!_mesh)
     throw INTERP_KERNEL::Exception("Mesh has to be set before calling getGaussLocalizationIdOfOneType method !");
+  if(!((const MEDCouplingFieldDiscretization *)_type))
+    throw INTERP_KERNEL::Exception("Spatial discretization not set ! Impossible to call getGaussLocalizationIdOfOneType method !");
   return _type->getGaussLocalizationIdOfOneType(type);
 }
 
@@ -276,6 +300,8 @@ std::set<int> MEDCouplingField::getGaussLocalizationIdsOfOneType(INTERP_KERNEL::
 {
   if(!_mesh)
     throw INTERP_KERNEL::Exception("Mesh has to be set before calling getGaussLocalizationIdsOfOneType method !");
+  if(!((const MEDCouplingFieldDiscretization *)_type))
+    throw INTERP_KERNEL::Exception("Spatial discretization not set ! Impossible to call getGaussLocalizationIdsOfOneType method !");
   return _type->getGaussLocalizationIdsOfOneType(type);
 }
 
@@ -287,6 +313,8 @@ int MEDCouplingField::getNbOfGaussLocalization() const throw(INTERP_KERNEL::Exce
 {
   if(!_mesh)
     throw INTERP_KERNEL::Exception("Mesh has to be set before calling getNbOfGaussLocalization method !");
+  if(!((const MEDCouplingFieldDiscretization *)_type))
+    throw INTERP_KERNEL::Exception("Spatial discretization not set ! Impossible to call getNbOfGaussLocalization method !");
   return _type->getNbOfGaussLocalization();
 }
 
@@ -299,6 +327,8 @@ int MEDCouplingField::getGaussLocalizationIdOfOneCell(int cellId) const throw(IN
 {
   if(!_mesh)
     throw INTERP_KERNEL::Exception("Mesh has to be set before calling getGaussLocalizationIdOfOneCell method !");
+  if(!((const MEDCouplingFieldDiscretization *)_type))
+    throw INTERP_KERNEL::Exception("Spatial discretization not set ! Impossible to call getGaussLocalizationIdOfOneCell method !");
   return _type->getGaussLocalizationIdOfOneCell(cellId);
 }
 
@@ -314,6 +344,8 @@ void MEDCouplingField::getCellIdsHavingGaussLocalization(int locId, std::vector<
   cellIds.clear();
   if(!_mesh)
     throw INTERP_KERNEL::Exception("Mesh has to be set before calling getGaussLocalizationIdOfOneCell method !");
+  if(!((const MEDCouplingFieldDiscretization *)_type))
+    throw INTERP_KERNEL::Exception("Spatial discretization not set ! Impossible to call getCellIdsHavingGaussLocalization method !");
   _type->getCellIdsHavingGaussLocalization(locId,cellIds);
 }
 
@@ -327,6 +359,8 @@ const MEDCouplingGaussLocalization& MEDCouplingField::getGaussLocalization(int l
 {
   if(!_mesh)
     throw INTERP_KERNEL::Exception("Mesh has to be set before calling getGaussLocalization method !");
+  if(!((const MEDCouplingFieldDiscretization *)_type))
+    throw INTERP_KERNEL::Exception("Spatial discretization not set ! Impossible to call getGaussLocalization method !");
   return _type->getGaussLocalization(locId);
 }
 
@@ -344,31 +378,58 @@ MEDCouplingField::MEDCouplingField(TypeOfField type):_nature(NoNature),_mesh(0),
 {
 }
 
-MEDCouplingField::MEDCouplingField(const MEDCouplingField& other):RefCountObject(other),_name(other._name),_desc(other._desc),_nature(other._nature),
-                                                                  _mesh(0),_type(other._type->clone())
+MEDCouplingField::MEDCouplingField(const MEDCouplingField& other, bool deepCopy):RefCountObject(other),_name(other._name),_desc(other._desc),_nature(other._nature),
+                                                                                 _mesh(0),_type(0)
 {
   if(other._mesh)
     {
       _mesh=other._mesh;
       _mesh->incrRef();
     }
+  if(deepCopy)
+    _type=other._type->clone();
+  else
+    _type=other._type;
 }
 
 /*!
  * This method returns a submesh of 'mesh' instance constituting cell ids contained in array defined as an interval [start;end).
- * @param di is an array returned that specifies entity ids (nodes, cells ids...) in mesh 'mesh' of entity in returned submesh.
+ * @param di is an array returned that specifies entity ids (nodes, cells, Gauss points... ) in array.
+ * 
+ * \sa MEDCouplingField::buildSubMeshDataRange
  */
 MEDCouplingMesh *MEDCouplingField::buildSubMeshData(const int *start, const int *end, DataArrayInt *&di) const
 {
+  if(!((const MEDCouplingFieldDiscretization *)_type))
+    throw INTERP_KERNEL::Exception("Spatial discretization not set ! Impossible to call buildSubMeshData method !");
   return _type->buildSubMeshData(_mesh,start,end,di);
 }
 
+/*!
+ * This method returns a submesh of 'mesh' instance constituting cell ids defined by a range given by the 3 following inputs \a begin, \a end and \a step.
+ * 
+ * \param [out] beginOut Valid only if \a di is NULL
+ * \param [out] endOut Valid only if \a di is NULL
+ * \param [out] stepOut Valid only if \a di is NULL
+ * \param [out] di is an array returned that specifies entity ids (nodes, cells, Gauss points... ) in array if no output range is foundable.
+ * 
+ * \sa MEDCouplingField::buildSubMeshData
+ */
+MEDCouplingMesh *MEDCouplingField::buildSubMeshDataRange(int begin, int end, int step, int& beginOut, int& endOut, int& stepOut, DataArrayInt *&di) const
+{
+  if(!((const MEDCouplingFieldDiscretization *)_type))
+    throw INTERP_KERNEL::Exception("Spatial discretization not set ! Impossible to call buildSubMeshDataRange method !");
+  return _type->buildSubMeshDataRange(_mesh,begin,end,step,beginOut,endOut,stepOut,di);
+}
+
 /*!
  * This method returns tuples ids implied by the mesh selection of the  cell ids contained in array defined as an interval [start;end).
  * \return a newly allocated DataArrayInt instance containing tuples ids.
  */
 DataArrayInt *MEDCouplingField::computeTupleIdsToSelectFromCellIds(const int *startCellIds, const int *endCellIds) const
 {
+  if(!((const MEDCouplingFieldDiscretization *)_type))
+    throw INTERP_KERNEL::Exception("Spatial discretization not set ! Impossible to call computeTupleIdsToSelectFromCellIds method !");
   return _type->computeTupleIdsToSelectFromCellIds(_mesh,startCellIds,endCellIds);
 }
 
@@ -378,20 +439,46 @@ DataArrayInt *MEDCouplingField::computeTupleIdsToSelectFromCellIds(const int *st
  */
 int MEDCouplingField::getNumberOfTuplesExpected() const throw(INTERP_KERNEL::Exception)
 {
+  if(!((const MEDCouplingFieldDiscretization *)_type))
+    throw INTERP_KERNEL::Exception("Spatial discretization not set ! Impossible to call getNumberOfTuplesExpected method !");
   if(_mesh)
     return _type->getNumberOfTuples(_mesh);
   else
     throw INTERP_KERNEL::Exception("MEDCouplingField::getNumberOfTuplesExpected : Empty mesh !");
 }
 
+void MEDCouplingField::setDiscretization(MEDCouplingFieldDiscretization *newDisc)
+{
+  bool needUpdate=(const MEDCouplingFieldDiscretization *)_type!=newDisc;
+  _type=newDisc;
+  if(newDisc)
+    newDisc->incrRef();
+  if(needUpdate)
+    declareAsNew();
+}
+
 /*!
  * This method returns number of mesh placed expected regarding its discretization and its _mesh attribute.
  * This method expected a not null _mesh instance. If null, an exception will be thrown.
  */
 int MEDCouplingField::getNumberOfMeshPlacesExpected() const throw(INTERP_KERNEL::Exception)
 {
+  if(!((const MEDCouplingFieldDiscretization *)_type))
+    throw INTERP_KERNEL::Exception("Spatial discretization not set ! Impossible to call getNumberOfMeshPlacesExpected method !");
   if(_mesh)
     return _type->getNumberOfMeshPlaces(_mesh);
   else
     throw INTERP_KERNEL::Exception("MEDCouplingField::getNumberOfMeshPlacesExpected : Empty mesh !");
 }
+
+/*!
+ * Copy tiny info (component names, name, description) but warning the underlying mesh is not renamed (for safety reason).
+ */
+void MEDCouplingField::copyTinyStringsFrom(const MEDCouplingField *other) throw(INTERP_KERNEL::Exception)
+{
+  if(other)
+    {
+      setName(other->_name.c_str());
+      setDescription(other->_desc.c_str());    
+    }
+}