Salome HOME
Merge from V6_main 19/03/2013
[tools/medcoupling.git] / src / MEDCoupling / MEDCouplingFieldDouble.cxx
index f2fb7e1bda84e3c35bcf7b6a0e68bdce61ecf409..95206301afa3e4091554e666554d59caeb4a1dcd 100644 (file)
@@ -26,6 +26,8 @@
 #include "MEDCouplingAutoRefCountObjectPtr.hxx"
 #include "MEDCouplingNatureOfField.hxx"
 
+#include "InterpKernelAutoPtr.hxx"
+
 #include <sstream>
 #include <limits>
 #include <algorithm>
@@ -54,7 +56,7 @@ MEDCouplingFieldDouble *MEDCouplingFieldDouble::New(TypeOfField type, TypeOfTime
  
  * \return a newly allocated field the caller should deal with.
  */
-MEDCouplingFieldDouble *MEDCouplingFieldDouble::New(const MEDCouplingFieldTemplate *ft, TypeOfTimeDiscretization td)
+MEDCouplingFieldDouble *MEDCouplingFieldDouble::New(const MEDCouplingFieldTemplateft, TypeOfTimeDiscretization td)
 {
   return new MEDCouplingFieldDouble(ft,td);
 }
@@ -176,13 +178,13 @@ MEDCouplingFieldDouble *MEDCouplingFieldDouble::buildNewTimeReprFromThis(TypeOfT
 /*!
  * Copy tiny info (component names, name, description) but warning the underlying mesh is not renamed (for safety reason).
  */
-void MEDCouplingFieldDouble::copyTinyStringsFrom(const MEDCouplingFieldDouble *other) throw(INTERP_KERNEL::Exception)
+void MEDCouplingFieldDouble::copyTinyStringsFrom(const MEDCouplingField *other) throw(INTERP_KERNEL::Exception)
 {
-  if(other)
+  MEDCouplingField::copyTinyStringsFrom(other);
+  const MEDCouplingFieldDouble *otherC=dynamic_cast<const MEDCouplingFieldDouble *>(other);
+  if(otherC)
     {
-      setName(other->_name.c_str());
-      setDescription(other->_desc.c_str());
-      _time_discr->copyTinyStringsFrom(*other->_time_discr);
+      _time_discr->copyTinyStringsFrom(*otherC->_time_discr);
     }
 }
 
@@ -196,6 +198,13 @@ void MEDCouplingFieldDouble::copyTinyAttrFrom(const MEDCouplingFieldDouble *othe
     {
       _time_discr->copyTinyAttrFrom(*other->_time_discr);
     }
+  
+}
+
+void MEDCouplingFieldDouble::copyAllTinyAttrFrom(const MEDCouplingFieldDouble *other) throw(INTERP_KERNEL::Exception)
+{
+  copyTinyStringsFrom(other);
+  copyTinyAttrFrom(other);
 }
 
 std::string MEDCouplingFieldDouble::simpleRepr() const
@@ -205,7 +214,7 @@ std::string MEDCouplingFieldDouble::simpleRepr() const
   ret << "Description of field is : \"" << getDescription() << "\"\n";
   ret << "FieldDouble space discretization is : " << _type->getStringRepr() << "\n";
   ret << "FieldDouble time discretization is : " << _time_discr->getStringRepr() << "\n";
-  ret << "FieldDouble nature of field is : " << MEDCouplingNatureOfField::getRepr(_nature) << "\n";
+  ret << "FieldDouble nature of field is : " << MEDCouplingNatureOfField::GetRepr(_nature) << "\n";
   if(getArray())
     {
       int nbOfCompo=getArray()->getNumberOfComponents();
@@ -537,12 +546,12 @@ MEDCouplingFieldDouble::MEDCouplingFieldDouble(TypeOfField type, TypeOfTimeDiscr
 {
 }
 
-MEDCouplingFieldDouble::MEDCouplingFieldDouble(const MEDCouplingFieldTemplate *ft, TypeOfTimeDiscretization td):MEDCouplingField(*ft),
+MEDCouplingFieldDouble::MEDCouplingFieldDouble(const MEDCouplingFieldTemplate& ft, TypeOfTimeDiscretization td):MEDCouplingField(ft),
                                                                                                                 _time_discr(MEDCouplingTimeDiscretization::New(td))
 {
 }
 
-MEDCouplingFieldDouble::MEDCouplingFieldDouble(const MEDCouplingFieldDouble& other, bool deepCopy):MEDCouplingField(other),
+MEDCouplingFieldDouble::MEDCouplingFieldDouble(const MEDCouplingFieldDouble& other, bool deepCopy):MEDCouplingField(other,deepCopy),
                                                                                                    _time_discr(other._time_discr->performCpy(deepCopy))
 {
 }
@@ -744,17 +753,44 @@ double MEDCouplingFieldDouble::normMax() const throw(INTERP_KERNEL::Exception)
  * \a this is expected to be a field with exactly \b one component. If not an exception will be thrown.
  * To getAverageValue on vector field applyFunc is needed before. This method looks only \b default array \b and \b only \b default.
  * If default array does not exist, an exception will be thrown.
+ * 
+ * \param [out] res the location where the result will be stored. \a res is expected to be a location with \c this->getNumberOfComponents() places available.
+ * \param [in] isWAbs specifies if abs is applied on measure on underlying mesh before performing computation. For a user already sure that all cells of its underlying mesh
+ *                    are all well oriented this parameter can be set to false to be 'faster'. By default this parameter is true.
  */
-double MEDCouplingFieldDouble::getWeightedAverageValue() const throw(INTERP_KERNEL::Exception)
+void MEDCouplingFieldDouble::getWeightedAverageValue(double *res, bool isWAbs) const throw(INTERP_KERNEL::Exception)
 {
   if(getArray()==0)
     throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::getWeightedAverageValue : no default array defined !");
-  MEDCouplingFieldDouble *w=buildMeasureField(true);
+  MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> w=buildMeasureField(isWAbs);
   double deno=w->getArray()->accumulate(0);
-  w->getArray()->multiplyEqual(getArray());
-  double res=w->getArray()->accumulate(0);
-  w->decrRef();
-  return res/deno;
+  MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> arr=getArray()->deepCpy();
+  arr->multiplyEqual(w->getArray());
+  std::transform(arr->begin(),arr->end(),arr->getPointer(),std::bind2nd(std::multiplies<double>(),1./deno));
+  arr->accumulate(res);
+}
+
+/*!
+ * This method returns the average value in \a this weighted by ParaMEDMEM::MEDCouplingField::buildMeasureField.
+ * \a this is expected to be a field with exactly \b one component. If not an exception will be thrown.
+ * To getAverageValue on vector field applyFunc is needed before. This method looks only \b default array \b and \b only \b default.
+ * If default array does not exist, an exception will be thrown.
+ * 
+ * \param [in] compId The component id that should be in [0, \c this->getNumberOfComponents() ). If not an INTERP_KERNEL::Exception will be thrown.
+ * \param [in] isWAbs specifies if abs is applied on measure on underlying mesh before performing computation. For a user already sure that all cells of its underlying mesh
+ *                    are all well oriented this parameter can be set to false to be 'faster'. By default this parameter is true in C++ not in python (overloading confusion).
+ */
+double MEDCouplingFieldDouble::getWeightedAverageValue(int compId, bool isWAbs) const throw(INTERP_KERNEL::Exception)
+{
+  int nbComps=getArray()->getNumberOfComponents();
+  if(compId<0 || compId>=nbComps)
+    {
+      std::ostringstream oss; oss << "MEDCouplingFieldDouble::getWeightedAverageValue : Invalid compId specified : No such nb of components ! Should be in [0," << nbComps << ") !";
+      throw INTERP_KERNEL::Exception(oss.str().c_str());
+    }
+  INTERP_KERNEL::AutoPtr<double> res=new double[nbComps];
+  getWeightedAverageValue(res,isWAbs);
+  return res[compId];
 }
 
 /*!
@@ -769,21 +805,14 @@ double MEDCouplingFieldDouble::normL1(int compId) const throw(INTERP_KERNEL::Exc
   if(!_mesh)
     throw INTERP_KERNEL::Exception("No mesh underlying this field to perform normL1");
   int nbComps=getArray()->getNumberOfComponents();
-  if(compId>=nbComps)
-    throw INTERP_KERNEL::Exception("Invalid compId specified : No such nb of components !");
-  double *res=new double[nbComps];
-  try
+  if(compId<0 || compId>=nbComps)
     {
-      _type->normL1(_mesh,getArray(),res);
+      std::ostringstream oss; oss << "MEDCouplingFieldDouble::normL1 : Invalid compId specified : No such nb of components ! Should be in [0," << nbComps << ") !";
+      throw INTERP_KERNEL::Exception(oss.str().c_str());
     }
-  catch(INTERP_KERNEL::Exception& e)
-    {
-      delete [] res;
-      throw e;
-    }
-  double ret=res[compId];
-  delete [] res;
-  return ret;
+  INTERP_KERNEL::AutoPtr<double> res=new double[nbComps];
+  _type->normL1(_mesh,getArray(),res);
+  return res[compId];
 }
 
 /*!
@@ -812,21 +841,14 @@ double MEDCouplingFieldDouble::normL2(int compId) const throw(INTERP_KERNEL::Exc
   if(!_mesh)
     throw INTERP_KERNEL::Exception("No mesh underlying this field to perform normL2");
   int nbComps=getArray()->getNumberOfComponents();
-  if(compId>=nbComps)
-    throw INTERP_KERNEL::Exception("Invalid compId specified : No such nb of components !");
-  double *res=new double[nbComps];
-  try
+  if(compId<0 || compId>=nbComps)
     {
-      _type->normL2(_mesh,getArray(),res);
+      std::ostringstream oss; oss << "MEDCouplingFieldDouble::normL2 : Invalid compId specified : No such nb of components ! Should be in [0," << nbComps << ") !";
+      throw INTERP_KERNEL::Exception(oss.str().c_str());
     }
-  catch(INTERP_KERNEL::Exception& e)
-    {
-      delete [] res;
-      throw e;
-    }
-  double ret=res[compId];
-  delete [] res;
-  return ret;
+  INTERP_KERNEL::AutoPtr<double> res=new double[nbComps];
+  _type->normL2(_mesh,getArray(),res);
+  return res[compId];
 }
 
 /*!
@@ -846,34 +868,27 @@ void MEDCouplingFieldDouble::normL2(double *res) const throw(INTERP_KERNEL::Exce
 /*!
  * Returns the accumulation (the sum) of comId_th component of each tuples weigthed by the field
  * returns by getWeightingField relative of the _type of field of default array.
- * This method is usefull to check the conservativity of interpolation method.
+ * This method is useful to check the conservativity of interpolation method.
  */
 double MEDCouplingFieldDouble::integral(int compId, bool isWAbs) const throw(INTERP_KERNEL::Exception)
 {
   if(!_mesh)
     throw INTERP_KERNEL::Exception("No mesh underlying this field to perform integral");
   int nbComps=getArray()->getNumberOfComponents();
-  if(compId>=nbComps)
-    throw INTERP_KERNEL::Exception("Invalid compId specified : No such nb of components !");
-  double *res=new double[nbComps];
-  try
+  if(compId<0 || compId>=nbComps)
     {
-      _type->integral(_mesh,getArray(),isWAbs,res);
+      std::ostringstream oss; oss << "MEDCouplingFieldDouble::integral : Invalid compId specified : No such nb of components ! Should be in [0," << nbComps << ") !";
+      throw INTERP_KERNEL::Exception(oss.str().c_str());
     }
-  catch(INTERP_KERNEL::Exception& e)
-    {
-      delete [] res;
-      throw e;
-    }
-  double ret=res[compId];
-  delete [] res;
-  return ret;
+  INTERP_KERNEL::AutoPtr<double> res=new double[nbComps];
+  _type->integral(_mesh,getArray(),isWAbs,res);
+  return res[compId];
 }
 
 /*!
  * Returns the accumulation (the sum) of each tuples weigthed by the field
  * returns by getWeightingField relative of the _type of field of default array.
- * This method is usefull to check the conservativity of interpolation method.
+ * This method is useful to check the conservativity of interpolation method.
  */
 void MEDCouplingFieldDouble::integral(bool isWAbs, double *res) const throw(INTERP_KERNEL::Exception)
 {