]> SALOME platform Git repositories - tools/medcoupling.git/commitdiff
Salome HOME
MEDMEM Industrialization 2008
authoreap <eap@opencascade.com>
Wed, 17 Dec 2008 17:42:50 +0000 (17:42 +0000)
committereap <eap@opencascade.com>
Wed, 17 Dec 2008 17:42:50 +0000 (17:42 +0000)
  Check field nature at attaching
-  void DEC::attachLocalField(const ParaFIELD* field)
+  void DEC::attachLocalField(const ParaFIELD* field, const string& method)

src/ParaMEDMEM/DEC.cxx
src/ParaMEDMEM/DEC.hxx

index 4e09289bc0d3f907094747517d9651bcd78cae6b..42d057550d8eb93b8b8e2cb5ecfb4c3bdbfffa18 100644 (file)
@@ -3,6 +3,7 @@
 #include "BlockTopology.hxx"
 #include "ComponentTopology.hxx"
 #include "ParaFIELD.hxx"
+#include "ParaSUPPORT.hxx"
 #include "DEC.hxx"
 #include "ICoCoField.hxx"
 #include "ICoCoMEDField.hxx"
@@ -80,11 +81,16 @@ namespace ParaMEDMEM
     If the processor is on the receiving end of the DEC, the field
     will be updated by a recvData() call.
     Reversely, if the processor is on the sending end, the field will be read, possibly transformed, and sent appropriately to the other side.
+
+    The \a field nature should correspond to interpolation \a method.
   */
-  void DEC::attachLocalField(const ParaFIELD* field) 
+  void DEC::attachLocalField(const ParaFIELD* field, const string& method
   {
     _local_field=field;
     _comm_interface=&(field->getTopology()->getProcGroup()->getCommInterface());
+
+    setMethod( method );
+    compareFieldAndMethod();
   }
 
   /*! Attaches a local field to a DEC. The method will test whether the processor
@@ -95,9 +101,11 @@ namespace ParaMEDMEM
     will be updated by a recvData() call.
     Reversely, if the processor is on the sending end, the field will be read, possibly transformed,
     and sent appropriately to the other side.
+
+    The \a field nature should correspond to interpolation \a method.
   */
 
-  void DEC::attachLocalField(MEDMEM::FIELD<double>* field) 
+  void DEC::attachLocalField(MEDMEM::FIELD<double>* field, const string& method
   {
     ProcessorGroup* local_group;
     if (_source_group->containsMyRank())
@@ -110,6 +118,9 @@ namespace ParaMEDMEM
     _local_field= new ParaFIELD(field, *local_group);
     _owns_field=true;
     _comm_interface=&(local_group->getCommInterface());
+
+    setMethod( method );
+    compareFieldAndMethod();
   }
 
   /*! 
@@ -121,14 +132,15 @@ namespace ParaMEDMEM
     - a ICoCo::MEDField, that is created from a MEDMEM structure
     - a ICOCo::TrioField, that is created from tables extracted from a TRIO-U structure.
 
+    The \a field nature should correspond to interpolation \a method.
   */
 
-  void DEC::attachLocalField(const ICoCo::Field* field)
+  void DEC::attachLocalField(const ICoCo::Field* field, const string& method)
   {
     const ICoCo::MEDField* medfield =dynamic_cast<const ICoCo::MEDField*> (field);
     if(medfield !=0)
     {
-      attachLocalField(medfield->getField());
+      attachLocalField(medfield->getField(), method);
       return;
     }
     const ICoCo::TrioField* triofield=dynamic_cast<const ICoCo::TrioField*> (field);
@@ -139,7 +151,7 @@ namespace ParaMEDMEM
       else localgroup=_target_group;
       _icoco_field=new ICoCo::MEDField(*const_cast<ICoCo::TrioField* >(triofield), *localgroup);
       //                               _owns_field = true;
-      attachLocalField(_icoco_field);
+      attachLocalField(_icoco_field, method);
       return;
     }
     throw MEDMEM::MEDEXCEPTION("incompatible field type");
@@ -186,5 +198,53 @@ namespace ParaMEDMEM
       }
     }
   }
+  //================================================================================
+  /*!
+    Throws an exception if nature of the attached local field does not correspond to
+    interpolation method
+   */
+  //================================================================================
+
+  void DEC::compareFieldAndMethod() const
+  {
+    if (_local_field)
+    {
+      MED_EN::medEntityMesh entity = _local_field->getSupport()->getSupport()->getEntity();
+      if ( getMethod() == "P0" ) {
+        if ( entity != MED_EN::MED_CELL )
+          throw MEDMEM::MEDEXCEPTION("Field support and interpolation method mismatch."
+                                     " For P0 interpolation, field must be on MED_CELL's");
+        if ( _local_field->getField()->getGaussPresence() )
+          throw MEDMEM::MEDEXCEPTION("Field nature and interpolation method mismatch."
+                                     " For P0 interpolation, field must have one value per cell");
+      }
+      else if ( getMethod() == "P1" ) {
+        if ( entity != MED_EN::MED_NODE )
+          throw MEDMEM::MEDEXCEPTION("Field support and interpolation method mismatch."
+                                     " For P1 interpolation, field must be on MED_NODE's");
+        if ( _local_field->getField()->getGaussPresence() )
+          throw MEDMEM::MEDEXCEPTION("Field nature and interpolation method mismatch."
+                                     " For P1 interpolation, field must have one value per node");
+      }
+      else if ( getMethod() == "P1d" ) {
+        if ( entity != MED_EN::MED_CELL )
+          throw MEDMEM::MEDEXCEPTION("Field support and interpolation method mismatch."
+                                     " For P1d interpolation, field must be on MED_CELL's");
+        if ( !_local_field->getField()->getGaussPresence() )
+          throw MEDMEM::MEDEXCEPTION("Field nature and interpolation method mismatch."
+                                     " For P1d interpolation, field must have several values per cell");
+        MED_EN::medGeometryElement type = _local_field->getSupport()->getSupport()->getTypes()[0];
+        if ( _local_field->getField()->getNumberOfGaussPoints( type ) != type%100 )
+          throw MEDMEM::MEDEXCEPTION("Field nature and interpolation method mismatch."
+                                     " For P1d interpolation, number of values per cell "
+                                     "must be equal to number of nodes per cell");
+        if ( _target_group->containsMyRank() )
+          throw MEDMEM::MEDEXCEPTION("Projection to P1d field not supported");
+      }
+      else {
+        throw MEDMEM::MEDEXCEPTION("Unknown interpolation method. Possible methods: P0, P1, P1d");
+      }
+    }
+  }
   /*! @} */
 }
index e621e0eb63ed01d0c3c42cf75a451316901c6d49..983d5eaa024637037f49cd274bd627d37ed45feb 100644 (file)
@@ -20,9 +20,9 @@ namespace ParaMEDMEM
        public:
                DEC():_local_field(0){}
                DEC(ProcessorGroup& local_group, ProcessorGroup& distant_group); 
-               void attachLocalField( MEDMEM::FIELD<double>* field);
-               void attachLocalField(const ParaFIELD* field);
-               void attachLocalField(const ICoCo::Field* field);
+               void attachLocalField( MEDMEM::FIELD<double>* field, const string& method ="P0");
+               void attachLocalField(const ParaFIELD*        field, const string& method ="P0");
+               void attachLocalField(const ICoCo::Field*     field, const string& method ="P0");
                
                virtual void prepareSourceDE()=0;
                virtual void prepareTargetDE()=0;
@@ -33,6 +33,9 @@ namespace ParaMEDMEM
                virtual void computeProcGroup(){}
                void renormalizeTargetField();
        protected:
+
+               void compareFieldAndMethod() const;
+
                const ParaFIELD* _local_field;
                //! Processor group representing the union of target and source processors
                ProcessorGroup* _union_group;