Salome HOME
Release checking constraints on field nature when performing multiply, abn/field_nature
authorabn <adrien.bruneton@cea.fr>
Mon, 14 Sep 2015 14:17:50 +0000 (16:17 +0200)
committerabn <adrien.bruneton@cea.fr>
Mon, 14 Sep 2015 14:17:50 +0000 (16:17 +0200)
divide, etc ... operations.

src/MEDCoupling/MEDCouplingField.cxx
src/MEDCoupling/MEDCouplingField.hxx
src/MEDCoupling/MEDCouplingFieldDouble.cxx
src/MEDCoupling_Swig/MEDCouplingBasicsTest.py

index cd635943b41884f155ca2c041410ec26dccdae78..52164a9adb454fd1ddf22e03403fb1f588b02b57 100644 (file)
@@ -145,6 +145,21 @@ bool MEDCouplingField::areStrictlyCompatible(const MEDCouplingField *other) cons
   return _mesh==other->_mesh;
 }
 
+/*!
+ * This method is less strict than MEDCouplingField::areStrictlyCompatible method.
+ * The difference is that the nature is not checked.
+ * This method is used for multiplication and division on fields to operate a first check before attempting operation.
+ */
+bool MEDCouplingField::areStrictlyCompatibleForMulDiv(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;
+  return _mesh==other->_mesh;
+}
+
+
 void MEDCouplingField::updateTime() const
 {
   if(_mesh)
index c1b7efb58d63fe21d7f5c8ff5c19c969a0d0e856..9154f56c2221524f8221e1e8a8ac7e9bc30918ae 100644 (file)
@@ -47,6 +47,7 @@ namespace ParaMEDMEM
     MEDCOUPLING_EXPORT virtual void checkCoherency() const = 0;
     MEDCOUPLING_EXPORT virtual bool areCompatibleForMerge(const MEDCouplingField *other) const;
     MEDCOUPLING_EXPORT virtual bool areStrictlyCompatible(const MEDCouplingField *other) const;
+    MEDCOUPLING_EXPORT virtual bool areStrictlyCompatibleForMulDiv(const MEDCouplingField *other) const;
     MEDCOUPLING_EXPORT virtual bool isEqualIfNotWhy(const MEDCouplingField *other, double meshPrec, double valsPrec, std::string& reason) const;
     MEDCOUPLING_EXPORT virtual bool isEqual(const MEDCouplingField *other, double meshPrec, double valsPrec) const;
     MEDCOUPLING_EXPORT virtual bool isEqualWithoutConsideringStr(const MEDCouplingField *other, double meshPrec, double valsPrec) const;
index ee65744690f7f35bc2b6f1fb343e0ef05b459da7..b62261758b13128698674f07f82eff32873b47fe 100644 (file)
@@ -534,12 +534,12 @@ bool MEDCouplingFieldDouble::areStrictlyCompatible(const MEDCouplingField *other
 }
 
 /*!
- * Method with same principle than MEDCouplingFieldDouble::areStrictlyCompatible method except that
+ * Method with same principle than MEDCouplingFieldDouble::areStrictlyCompatibleForMulDiv method except that
  * number of components between \a this and 'other' can be different here (for operator*).
  */
 bool MEDCouplingFieldDouble::areCompatibleForMul(const MEDCouplingField *other) const
 {
-  if(!MEDCouplingField::areStrictlyCompatible(other))
+  if(!MEDCouplingField::areStrictlyCompatibleForMulDiv(other))
     return false;
   const MEDCouplingFieldDouble *otherC=dynamic_cast<const MEDCouplingFieldDouble *>(other);
   if(!otherC)
@@ -550,12 +550,12 @@ bool MEDCouplingFieldDouble::areCompatibleForMul(const MEDCouplingField *other)
 }
 
 /*!
- * Method with same principle than MEDCouplingFieldDouble::areStrictlyCompatible method except that
+ * Method with same principle than MEDCouplingFieldDouble::areStrictlyCompatibleForMulDiv method except that
  * number of components between \a this and 'other' can be different here (for operator/).
  */
 bool MEDCouplingFieldDouble::areCompatibleForDiv(const MEDCouplingField *other) const
 {
-  if(!MEDCouplingField::areStrictlyCompatible(other))
+  if(!MEDCouplingField::areStrictlyCompatibleForMulDiv(other))
     return false;
   const MEDCouplingFieldDouble *otherC=dynamic_cast<const MEDCouplingFieldDouble *>(other);
   if(!otherC)
@@ -2772,7 +2772,7 @@ void MEDCouplingFieldDouble::sortPerTuple(bool asc)
 MEDCouplingFieldDouble *MEDCouplingFieldDouble::MergeFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2)
 {
   if(!f1->areCompatibleForMerge(f2))
-    throw INTERP_KERNEL::Exception("Fields are not compatible ; unable to apply MergeFields on them !");
+    throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply MergeFields on them ! Check support mesh, field nature, and spatial and time discretisation.");
   const MEDCouplingMesh *m1(f1->getMesh()),*m2(f2->getMesh());
   if(!f1->_time_discr)
     throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::MergeFields : no time discr of f1 !");
@@ -2823,7 +2823,7 @@ MEDCouplingFieldDouble *MEDCouplingFieldDouble::MergeFields(const std::vector<co
     throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::MergeFields : presence of NULL instance in first place of input vector !");
   for(;it!=a.end();it++)
     if(!ref->areCompatibleForMerge(*it))
-      throw INTERP_KERNEL::Exception("Fields are not compatible ; unable to apply MergeFields on them !");
+      throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply MergeFields on them! Check support mesh, field nature, and spatial and time discretisation.");
   for(int i=0;i<(int)a.size();i++)
     {
       if(a[i]->getMesh())
@@ -2864,7 +2864,7 @@ MEDCouplingFieldDouble *MEDCouplingFieldDouble::MergeFields(const std::vector<co
 MEDCouplingFieldDouble *MEDCouplingFieldDouble::MeldFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2)
 {
   if(!f1->areCompatibleForMeld(f2))
-    throw INTERP_KERNEL::Exception("Fields are not compatible ; unable to apply MeldFields on them !");
+    throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply MeldFields on them ! Check support mesh, field nature, and spatial and time discretisation.");
   MEDCouplingTimeDiscretization *td=f1->_time_discr->meld(f2->_time_discr);
   td->copyTinyAttrFrom(*f1->_time_discr);
   MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret=new MEDCouplingFieldDouble(f1->getNature(),td,f1->_type->clone());
@@ -2890,11 +2890,11 @@ MEDCouplingFieldDouble *MEDCouplingFieldDouble::DotFields(const MEDCouplingField
 {
   if(!f1)
     throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::DotFields : input field is NULL !");
-  if(!f1->areStrictlyCompatible(f2))
-    throw INTERP_KERNEL::Exception("Fields are not compatible ; unable to apply DotFields on them !");
+  if(!f1->areStrictlyCompatibleForMulDiv(f2))
+    throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply DotFields on them!  Check support mesh, and spatial and time discretisation.");
   MEDCouplingTimeDiscretization *td=f1->_time_discr->dot(f2->_time_discr);
   td->copyTinyAttrFrom(*f1->_time_discr);
-  MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(f1->getNature(),td,f1->_type->clone());
+  MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(NoNature,td,f1->_type->clone());
   ret->setMesh(f1->getMesh());
   return ret;
 }
@@ -2921,11 +2921,11 @@ MEDCouplingFieldDouble *MEDCouplingFieldDouble::CrossProductFields(const MEDCoup
 {
   if(!f1)
     throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::CrossProductFields : input field is NULL !");
-  if(!f1->areStrictlyCompatible(f2))
-    throw INTERP_KERNEL::Exception("Fields are not compatible ; unable to apply CrossProductFields on them !");
+  if(!f1->areStrictlyCompatibleForMulDiv(f2))
+    throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply CrossProductFields on them! Check support mesh, and spatial and time discretisation.");
   MEDCouplingTimeDiscretization *td=f1->_time_discr->crossProduct(f2->_time_discr);
   td->copyTinyAttrFrom(*f1->_time_discr);
-  MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret=new MEDCouplingFieldDouble(f1->getNature(),td,f1->_type->clone());
+  MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret=new MEDCouplingFieldDouble(NoNature,td,f1->_type->clone());
   ret->setMesh(f1->getMesh());
   return ret.retn();
 }
@@ -2952,7 +2952,7 @@ MEDCouplingFieldDouble *MEDCouplingFieldDouble::MaxFields(const MEDCouplingField
   if(!f1)
     throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::MaxFields : input field is NULL !");
   if(!f1->areStrictlyCompatible(f2))
-    throw INTERP_KERNEL::Exception("Fields are not compatible ; unable to apply MaxFields on them !");
+    throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply MaxFields on them! Check support mesh, field nature, and spatial and time discretisation.");
   MEDCouplingTimeDiscretization *td=f1->_time_discr->max(f2->_time_discr);
   td->copyTinyAttrFrom(*f1->_time_discr);
   MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret=new MEDCouplingFieldDouble(f1->getNature(),td,f1->_type->clone());
@@ -2982,7 +2982,7 @@ MEDCouplingFieldDouble *MEDCouplingFieldDouble::MinFields(const MEDCouplingField
   if(!f1)
     throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::MinFields : input field is NULL !");
   if(!f1->areStrictlyCompatible(f2))
-    throw INTERP_KERNEL::Exception("Fields are not compatible ; unable to apply MinFields on them !");
+    throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply MinFields on them! Check support mesh, field nature, and spatial and time discretisation.");
   MEDCouplingTimeDiscretization *td=f1->_time_discr->min(f2->_time_discr);
   td->copyTinyAttrFrom(*f1->_time_discr);
   MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret=new MEDCouplingFieldDouble(f1->getNature(),td,f1->_type->clone());
@@ -3028,7 +3028,7 @@ MEDCouplingFieldDouble *MEDCouplingFieldDouble::AddFields(const MEDCouplingField
   if(!f1)
     throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::AddFields : input field is NULL !");
   if(!f1->areStrictlyCompatible(f2))
-    throw INTERP_KERNEL::Exception("Fields are not compatible ; unable to apply AddFields on them !");
+    throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply AddFields on them! Check support mesh, field nature, and spatial and time discretisation.");
   MEDCouplingTimeDiscretization *td=f1->_time_discr->add(f2->_time_discr);
   td->copyTinyAttrFrom(*f1->_time_discr);
   MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret=new MEDCouplingFieldDouble(f1->getNature(),td,f1->_type->clone());
@@ -3049,7 +3049,7 @@ MEDCouplingFieldDouble *MEDCouplingFieldDouble::AddFields(const MEDCouplingField
 const MEDCouplingFieldDouble &MEDCouplingFieldDouble::operator+=(const MEDCouplingFieldDouble& other)
 {
   if(!areStrictlyCompatible(&other))
-    throw INTERP_KERNEL::Exception("Fields are not compatible ; unable to apply += on them !");
+    throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply += on them! Check support mesh, field nature, and spatial and time discretisation.");
   _time_discr->addEqual(other._time_discr);
   return *this;
 }
@@ -3072,7 +3072,7 @@ MEDCouplingFieldDouble *MEDCouplingFieldDouble::SubstractFields(const MEDCouplin
   if(!f1)
     throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::SubstractFields : input field is NULL !");
   if(!f1->areStrictlyCompatible(f2))
-    throw INTERP_KERNEL::Exception("Fields are not compatible ; unable to apply SubstractFields on them !");
+    throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply SubstractFields on them! Check support mesh, field nature, and spatial and time discretisation.");
   MEDCouplingTimeDiscretization *td=f1->_time_discr->substract(f2->_time_discr);
   td->copyTinyAttrFrom(*f1->_time_discr);
   MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret=new MEDCouplingFieldDouble(f1->getNature(),td,f1->_type->clone());
@@ -3093,7 +3093,7 @@ MEDCouplingFieldDouble *MEDCouplingFieldDouble::SubstractFields(const MEDCouplin
 const MEDCouplingFieldDouble &MEDCouplingFieldDouble::operator-=(const MEDCouplingFieldDouble& other)
 {
   if(!areStrictlyCompatible(&other))
-    throw INTERP_KERNEL::Exception("Fields are not compatible ; unable to apply -= on them !");
+    throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply -= on them! Check support mesh, field nature, and spatial and time discretisation.");
   _time_discr->substractEqual(other._time_discr);
   return *this;
 }
@@ -3111,11 +3111,11 @@ const MEDCouplingFieldDouble &MEDCouplingFieldDouble::operator-=(const MEDCoupli
  * The two fields must have same number of tuples and same underlying mesh.
  *  \param [in] f1 - a factor field.
  *  \param [in] f2 - another factor field.
- *  \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble.
+ *  \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble, with no nature set.
  *          The caller is to delete this result field using decrRef() as it is no more
  *          needed.
  *  \throw If either \a f1 or \a f2 is NULL.
- *  \throw If the fields are not compatible for production (areCompatibleForMul()),
+ *  \throw If the fields are not compatible for multiplication (areCompatibleForMul()),
  *         i.e. they differ not only in values and possibly number of components.
  */
 MEDCouplingFieldDouble *MEDCouplingFieldDouble::MultiplyFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2)
@@ -3123,10 +3123,10 @@ MEDCouplingFieldDouble *MEDCouplingFieldDouble::MultiplyFields(const MEDCoupling
   if(!f1)
     throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::MultiplyFields : input field is NULL !");
   if(!f1->areCompatibleForMul(f2))
-    throw INTERP_KERNEL::Exception("Fields are not compatible ; unable to apply MultiplyFields on them !");
+    throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply MultiplyFields on them! Check support mesh, and spatial and time discretisation.");
   MEDCouplingTimeDiscretization *td=f1->_time_discr->multiply(f2->_time_discr);
   td->copyTinyAttrFrom(*f1->_time_discr);
-  MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret=new MEDCouplingFieldDouble(f1->getNature(),td,f1->_type->clone());
+  MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret=new MEDCouplingFieldDouble(NoNature,td,f1->_type->clone());
   ret->setMesh(f1->getMesh());
   return ret.retn();
 }
@@ -3144,19 +3144,20 @@ MEDCouplingFieldDouble *MEDCouplingFieldDouble::MultiplyFields(const MEDCoupling
  *
  * The two fields must have same number of tuples and same underlying mesh.
  *  \param [in] other - an field to multiply to \a this one.
- *  \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble.
+ *  \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble, with no nature set.
  *          The caller is to delete this result field using decrRef() as it is no more
  *          needed.
  *  \throw If \a other is NULL.
- *  \throw If the fields are not strictly compatible for production
+ *  \throw If the fields are not strictly compatible for multiplication
  *         (areCompatibleForMul()),
  *         i.e. they differ not only in values and possibly in number of components.
  */
 const MEDCouplingFieldDouble &MEDCouplingFieldDouble::operator*=(const MEDCouplingFieldDouble& other)
 {
   if(!areCompatibleForMul(&other))
-    throw INTERP_KERNEL::Exception("Fields are not compatible ; unable to apply *= on them !");
+    throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply *= on them! Check support mesh, and spatial and time discretisation.");
   _time_discr->multiplyEqual(other._time_discr);
+  _nature = NoNature;
   return *this;
 }
 
@@ -3171,7 +3172,7 @@ const MEDCouplingFieldDouble &MEDCouplingFieldDouble::operator*=(const MEDCoupli
  *
  *  \param [in] f1 - a numerator field.
  *  \param [in] f2 - a denominator field.
- *  \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble.
+ *  \return MEDCouplingFieldDouble * - the new instance of MEDCouplingFieldDouble, with no nature set.
  *          The caller is to delete this result field using decrRef() as it is no more
  *          needed.
  *  \throw If either \a f1 or \a f2 is NULL.
@@ -3183,10 +3184,10 @@ MEDCouplingFieldDouble *MEDCouplingFieldDouble::DivideFields(const MEDCouplingFi
   if(!f1)
     throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::DivideFields : input field is NULL !");
   if(!f1->areCompatibleForDiv(f2))
-    throw INTERP_KERNEL::Exception("Fields are not compatible ; unable to apply DivideFields on them !");
+    throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply DivideFields on them! Check support mesh, and spatial and time discretisation.");
   MEDCouplingTimeDiscretization *td=f1->_time_discr->divide(f2->_time_discr);
   td->copyTinyAttrFrom(*f1->_time_discr);
-  MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret=new MEDCouplingFieldDouble(f1->getNature(),td,f1->_type->clone());
+  MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret=new MEDCouplingFieldDouble(NoNature,td,f1->_type->clone());
   ret->setMesh(f1->getMesh());
   return ret.retn();
 }
@@ -3211,8 +3212,9 @@ MEDCouplingFieldDouble *MEDCouplingFieldDouble::DivideFields(const MEDCouplingFi
 const MEDCouplingFieldDouble &MEDCouplingFieldDouble::operator/=(const MEDCouplingFieldDouble& other)
 {
   if(!areCompatibleForDiv(&other))
-    throw INTERP_KERNEL::Exception("Fields are not compatible ; unable to apply /= on them !");
+    throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply /= on them! Check support mesh, and spatial and time discretisation.");
   _time_discr->divideEqual(other._time_discr);
+  _nature = NoNature;
   return *this;
 }
 
@@ -3226,10 +3228,10 @@ MEDCouplingFieldDouble *MEDCouplingFieldDouble::PowFields(const MEDCouplingField
   if(!f1)
     throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::PowFields : input field is NULL !");
   if(!f1->areCompatibleForMul(f2))
-    throw INTERP_KERNEL::Exception("Fields are not compatible ; unable to apply PowFields on them !");
+    throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply PowFields on them! Check support mesh, and spatial and time discretisation.");
   MEDCouplingTimeDiscretization *td=f1->_time_discr->pow(f2->_time_discr);
   td->copyTinyAttrFrom(*f1->_time_discr);
-  MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret=new MEDCouplingFieldDouble(f1->getNature(),td,f1->_type->clone());
+  MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret=new MEDCouplingFieldDouble(NoNature,td,f1->_type->clone());
   ret->setMesh(f1->getMesh());
   return ret.retn();
 }
@@ -3247,8 +3249,9 @@ MEDCouplingFieldDouble *MEDCouplingFieldDouble::operator^(const MEDCouplingField
 const MEDCouplingFieldDouble &MEDCouplingFieldDouble::operator^=(const MEDCouplingFieldDouble& other)
 {
   if(!areCompatibleForDiv(&other))
-    throw INTERP_KERNEL::Exception("Fields are not compatible ; unable to apply /= on them !");
+    throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply ^= on them!  Check support mesh, and spatial and time discretisation.");
   _time_discr->powEqual(other._time_discr);
+  _nature = NoNature;
   return *this;
 }
 
index da4aca8b94a433e7e783d19a9e8110380e165496..18118dc7534bb852563033fb71251591ff905882 100644 (file)
@@ -670,6 +670,62 @@ class MEDCouplingBasicsTest(unittest.TestCase):
         self.assertRaises(InterpKernelException,field.setNature,Integral);
         self.assertRaises(InterpKernelException,field.setNature,IntegralGlobConstraint);
         pass
+      
+    def testNatureOperations(self):
+        """ Check nature constraints on field operations """
+        m = MEDCouplingCMesh()
+        m.setCoordsAt(0, DataArrayDouble([1.0,2.0,3.0]))
+        m.setCoordsAt(1, DataArrayDouble([1.0,2.0,3.0]))
+        m = m.buildUnstructured()
+        f1, f2 = MEDCouplingFieldDouble.New(ON_CELLS, NO_TIME), MEDCouplingFieldDouble.New(ON_CELLS, NO_TIME)
+        f1.setNature(Integral)
+        f2.setNature(ConservativeVolumic)
+        self.assertEqual(Integral, f1.getNature())
+        self.assertEqual(ConservativeVolumic, f2.getNature())
+        
+        da = DataArrayDouble([1.0,2.0,3.0,4.0])
+        f1.setMesh(m); f2.setMesh(m)
+        f1.setArray(da); f2.setArray(da.deepCpy())
+        # All this should complain about nature:
+        self.assertRaises(InterpKernelException, f1.__add__, f2)
+        self.assertRaises(InterpKernelException, f1.__iadd__, f2)
+        self.assertRaises(InterpKernelException, f1.__sub__, f2)
+        self.assertRaises(InterpKernelException, f1.__isub__, f2)
+        self.assertRaises(InterpKernelException, f1.__radd__, f2)
+        self.assertRaises(InterpKernelException, f1.__rsub__, f2)
+        self.assertRaises(InterpKernelException, MEDCouplingFieldDouble.AddFields, f1, f2)
+        self.assertRaises(InterpKernelException, MEDCouplingFieldDouble.SubstractFields, f1, f2)
+        self.assertRaises(InterpKernelException, MEDCouplingFieldDouble.MaxFields, f1, f2)
+        self.assertRaises(InterpKernelException, MEDCouplingFieldDouble.MinFields, f1, f2)
+        # Not those ones:
+        f3 = MEDCouplingFieldDouble.MultiplyFields(f1,f2)
+        self.assertEqual(NoNature, f3.getNature())
+        f3 = f1*f2
+        self.assertEqual(NoNature, f3.getNature())
+        f1Tmp = f1.deepCpy(); f1Tmp.setMesh(m);  f1Tmp *= f2
+        self.assertEqual(NoNature, f1Tmp.getNature())
+        f3 = MEDCouplingFieldDouble.DivideFields(f1,f2)
+        self.assertEqual(NoNature, f3.getNature())
+        f3 = f1/f2
+        self.assertEqual(NoNature, f3.getNature())
+        f1Tmp = f1.deepCpy();  f1Tmp.setMesh(m);  f1Tmp /= f2
+        self.assertEqual(NoNature, f1Tmp.getNature())
+#         f3 = MEDCouplingFieldDouble.PowFields(f1,f2)
+#         self.assertEqual(NoNature, f3.getNature())
+        f3 = f1**f2
+        self.assertEqual(NoNature, f3.getNature())
+        f1Tmp = f1.deepCpy();  f1Tmp.setMesh(m);  f1Tmp **= f2
+        self.assertEqual(NoNature, f1Tmp.getNature())
+        f3 = MEDCouplingFieldDouble.DotFields(f1,f2)
+        self.assertEqual(NoNature, f3.getNature())
+        f3 = f1.dot(f2)
+        self.assertEqual(NoNature, f3.getNature())
+        
+        da = DataArrayDouble.Meld([da, da, da])
+        f1.setArray(da); f2.setArray(da.deepCpy())
+        f3 = MEDCouplingFieldDouble.CrossProductFields(f1,f2)
+        self.assertEqual(NoNature, f3.getNature())
+        f3 = f1.crossProduct(f2)
 
     def testBuildSubMeshData(self):
         targetMesh=MEDCouplingDataForTest.build2DTargetMesh_1()