]> SALOME platform Git repositories - tools/medcoupling.git/commitdiff
Salome HOME
Management of nature of AMR fields + Debug of createPatchesFromCriterionML.
authorgeay <anthony.geay@cea.fr>
Wed, 11 Jun 2014 15:29:45 +0000 (17:29 +0200)
committergeay <anthony.geay@cea.fr>
Wed, 11 Jun 2014 15:29:45 +0000 (17:29 +0200)
src/MEDCoupling/MEDCouplingAMRAttribute.cxx
src/MEDCoupling/MEDCouplingAMRAttribute.hxx
src/MEDCoupling/MEDCouplingCartesianAMRMesh.cxx
src/MEDCoupling/MEDCouplingCartesianAMRMesh.hxx
src/MEDCoupling/MEDCouplingStructuredMesh.cxx
src/MEDCoupling/MEDCouplingStructuredMesh.hxx
src/MEDCoupling_Swig/MEDCouplingBasicsTest.py
src/MEDCoupling_Swig/MEDCouplingCommon.i

index 7060446acf8ce4852940451837fd716adbcbbcd3..96dbe2d07980f82281c45dba76338e35534fab02 100644 (file)
@@ -36,14 +36,14 @@ void DataArrayDoubleCollection::allocTuples(int nbOfTuples)
 {
   std::size_t sz(_arrs.size());
   for(std::size_t i=0;i<sz;i++)
-    _arrs[i]->reAlloc(nbOfTuples);
+    _arrs[i].first->reAlloc(nbOfTuples);
 }
 
 void DataArrayDoubleCollection::dellocTuples()
 {
   std::size_t sz(_arrs.size());
   for(std::size_t i=0;i<sz;i++)
-    _arrs[i]->reAlloc(0);
+    _arrs[i].first->reAlloc(0);
 }
 
 void DataArrayDoubleCollection::spillInfoOnComponents(const std::vector< std::vector<std::string> >& compNames)
@@ -54,17 +54,26 @@ void DataArrayDoubleCollection::spillInfoOnComponents(const std::vector< std::ve
   for(std::size_t i=0;i<sz;i++)
     {
       const std::vector<std::string>& names(compNames[i]);
-      _arrs[i]->setInfoOnComponents(names);
+      _arrs[i].first->setInfoOnComponents(names);
     }
 }
 
+void DataArrayDoubleCollection::spillNatures(const std::vector<NatureOfField>& nfs)
+{
+  std::size_t sz(_arrs.size());
+  if(sz!=nfs.size())
+    throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::spillNatures : first size of vector of NatureOfField has to be equal to the number of fields defined !");
+  for(std::size_t i=0;i<sz;i++)
+    _arrs[i].second=nfs[i];
+}
+
 std::vector<DataArrayDouble *> DataArrayDoubleCollection::retrieveFields() const
 {
   std::size_t sz(_arrs.size());
   std::vector<DataArrayDouble *> ret(sz);
   for(std::size_t i=0;i<sz;i++)
     {
-      const DataArrayDouble *tmp(_arrs[i]);
+      const DataArrayDouble *tmp(_arrs[i].first);
       ret[i]=const_cast<DataArrayDouble *>(tmp);
       if(ret[i])
         ret[i]->incrRef();
@@ -75,9 +84,9 @@ std::vector<DataArrayDouble *> DataArrayDoubleCollection::retrieveFields() const
 const DataArrayDouble *DataArrayDoubleCollection::getFieldWithName(const std::string& name) const
 {
   std::vector<std::string> vec;
-  for(std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> >::const_iterator it=_arrs.begin();it!=_arrs.end();it++)
+  for(std::vector< std::pair< MEDCouplingAutoRefCountObjectPtr<DataArrayDouble>, NatureOfField > >::const_iterator it=_arrs.begin();it!=_arrs.end();it++)
     {
-      const DataArrayDouble *obj(*it);
+      const DataArrayDouble *obj((*it).first);
       if(obj)
         {
           if(obj->getName()==name)
@@ -99,7 +108,10 @@ void DataArrayDoubleCollection::SynchronizeFineToCoarse(int ghostLev, const MEDC
   if(fine->_arrs.size()!=sz)
     throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeFineToCoarse : the input DataArrayDouble collection must have the same size !");
   for(std::size_t i=0;i<sz;i++)
-    fatherOfFineMesh->fillCellFieldComingFromPatchGhost(patchId,fine->_arrs[i],coarse->_arrs[i],ghostLev);
+    {
+      CheckSameNatures(fine->_arrs[i].second,coarse->_arrs[i].second);
+      fatherOfFineMesh->fillCellFieldComingFromPatchGhost(patchId,fine->_arrs[i].first,coarse->_arrs[i].first,ghostLev,IsConservativeNature(coarse->_arrs[i].second));
+    }
 }
 
 void DataArrayDoubleCollection::SynchronizeCoarseToFine(int ghostLev, const MEDCouplingCartesianAMRMeshGen *fatherOfFineMesh, int patchId, const DataArrayDoubleCollection *coarse, DataArrayDoubleCollection *fine)
@@ -110,7 +122,10 @@ void DataArrayDoubleCollection::SynchronizeCoarseToFine(int ghostLev, const MEDC
   if(fine->_arrs.size()!=sz)
     throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeCoarseToFine : the input DataArrayDouble collection must have the same size !");
   for(std::size_t i=0;i<sz;i++)
-    fatherOfFineMesh->fillCellFieldOnPatchGhost(patchId,coarse->_arrs[i],fine->_arrs[i],ghostLev);
+    {
+      CheckSameNatures(fine->_arrs[i].second,coarse->_arrs[i].second);
+      fatherOfFineMesh->fillCellFieldOnPatchGhost(patchId,coarse->_arrs[i].first,fine->_arrs[i].first,ghostLev,IsConservativeNature(coarse->_arrs[i].second));
+    }
 }
 
 void DataArrayDoubleCollection::SynchronizeFineEachOther(int patchId, int ghostLev, const MEDCouplingCartesianAMRMeshGen *fatherOfFineMesh, const std::vector<const MEDCouplingCartesianAMRMeshGen *>& children, const std::vector<DataArrayDoubleCollection *>& fieldsOnFine)
@@ -133,7 +148,7 @@ void DataArrayDoubleCollection::SynchronizeFineEachOther(int patchId, int ghostL
     {
       std::vector<const DataArrayDouble *> arrs(sz);
       for(std::size_t j=0;j<sz;j++)
-        arrs[j]=fieldsOnFine[j]->_arrs[i];
+        arrs[j]=fieldsOnFine[j]->_arrs[i].first;
       fatherOfFineMesh->fillCellFieldOnPatchOnlyGhostAdv(patchId,ghostLev,arrs);
     }
 }
@@ -150,8 +165,8 @@ void DataArrayDoubleCollection::SynchronizeGhostZoneOfOneUsingTwo(int ghostLev,
     throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeGhostZoneOfOneUsingTwo : size of DataArrayDouble Collection must be the same !");
   for(std::size_t i=0;i<sz;i++)
     {
-      const DataArrayDouble *zeArrWhichGhostsWillBeUpdated(p1dac->_arrs[i]);
-      MEDCouplingCartesianAMRPatch::UpdateNeighborsOfOneWithTwoMixedLev(ghostLev,p1,p2,const_cast<DataArrayDouble *>(zeArrWhichGhostsWillBeUpdated),p2dac->_arrs[i]);
+      const DataArrayDouble *zeArrWhichGhostsWillBeUpdated(p1dac->_arrs[i].first);
+      MEDCouplingCartesianAMRPatch::UpdateNeighborsOfOneWithTwoMixedLev(ghostLev,p1,p2,const_cast<DataArrayDouble *>(zeArrWhichGhostsWillBeUpdated),p2dac->_arrs[i].first);
     }
 }
 
@@ -163,7 +178,7 @@ void DataArrayDoubleCollection::SynchronizeCoarseToFineOnlyInGhostZone(int ghost
   if(fine->_arrs.size()!=sz)
     throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeCoarseToFineOnlyInGhostZone : the input DataArrayDouble collection must have the same size !");
   for(std::size_t i=0;i<sz;i++)
-    fatherOfFineMesh->fillCellFieldOnPatchOnlyOnGhostZone(patchId,coarse->_arrs[i],fine->_arrs[i],ghostLev);
+    fatherOfFineMesh->fillCellFieldOnPatchOnlyOnGhostZone(patchId,coarse->_arrs[i].first,fine->_arrs[i].first,ghostLev);
 }
 
 void DataArrayDoubleCollection::synchronizeMyGhostZoneUsing(int ghostLev, const DataArrayDoubleCollection& other, const MEDCouplingCartesianAMRPatch *thisp, const MEDCouplingCartesianAMRPatch *otherp, const MEDCouplingCartesianAMRMeshGen *father) const
@@ -173,7 +188,7 @@ void DataArrayDoubleCollection::synchronizeMyGhostZoneUsing(int ghostLev, const
   if(other._arrs.size()!=sz)
     throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::synchronizeMyGhostZoneUsing : sizes of collections must match !");
   for(std::size_t i=0;i<sz;i++)
-    father->fillCellFieldOnPatchOnlyOnGhostZoneWith(ghostLev,thisp,otherp,thisNC->_arrs[i],other._arrs[i]);
+    father->fillCellFieldOnPatchOnlyOnGhostZoneWith(ghostLev,thisp,otherp,thisNC->_arrs[i].first,other._arrs[i].first);
 }
 
 void DataArrayDoubleCollection::synchronizeMyGhostZoneUsingExt(int ghostLev, const DataArrayDoubleCollection& other, const MEDCouplingCartesianAMRPatch *thisp, const MEDCouplingCartesianAMRPatch *otherp) const
@@ -183,7 +198,7 @@ void DataArrayDoubleCollection::synchronizeMyGhostZoneUsingExt(int ghostLev, con
   if(other._arrs.size()!=sz)
     throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::synchronizeMyGhostZoneUsingExt : sizes of collections must match !");
   for(std::size_t i=0;i<sz;i++)
-    MEDCouplingCartesianAMRPatch::UpdateNeighborsOfOneWithTwoExt(ghostLev,thisp,otherp,thisNC->_arrs[i],other._arrs[i]);
+    MEDCouplingCartesianAMRPatch::UpdateNeighborsOfOneWithTwoExt(ghostLev,thisp,otherp,thisNC->_arrs[i].first,other._arrs[i].first);
 }
 
 DataArrayDoubleCollection::DataArrayDoubleCollection(const std::vector< std::pair<std::string,int> >& fieldNames):_arrs(fieldNames.size())
@@ -193,10 +208,11 @@ DataArrayDoubleCollection::DataArrayDoubleCollection(const std::vector< std::pai
   for(std::size_t i=0;i<sz;i++)
     {
       const std::pair<std::string,int>& info(fieldNames[i]);
-      _arrs[i]=DataArrayDouble::New();
-      _arrs[i]->alloc(0,info.second);
-      _arrs[i]->setName(info.first);
+      _arrs[i].first=DataArrayDouble::New();
+      _arrs[i].first->alloc(0,info.second);
+      _arrs[i].first->setName(info.first);
       names[i]=info.second;
+      _arrs[i].second=ConservativeVolumic;
     }
   CheckDiscriminantNames(names);
 }
@@ -211,9 +227,9 @@ std::size_t DataArrayDoubleCollection::getHeapMemorySizeWithoutChildren() const
 std::vector<const BigMemoryObject *> DataArrayDoubleCollection::getDirectChildren() const
 {
   std::vector<const BigMemoryObject *> ret;
-  for(std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> >::const_iterator it=_arrs.begin();it!=_arrs.end();it++)
+  for(std::vector< std::pair< MEDCouplingAutoRefCountObjectPtr<DataArrayDouble>, NatureOfField > >::const_iterator it=_arrs.begin();it!=_arrs.end();it++)
     {
-      const DataArrayDouble *pt(*it);
+      const DataArrayDouble *pt((*it).first);
       if(pt)
         ret.push_back(pt);
     }
@@ -222,9 +238,9 @@ std::vector<const BigMemoryObject *> DataArrayDoubleCollection::getDirectChildre
 
 void DataArrayDoubleCollection::updateTime() const
 {
-  for(std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> >::const_iterator it=_arrs.begin();it!=_arrs.end();it++)
+  for(std::vector< std::pair< MEDCouplingAutoRefCountObjectPtr<DataArrayDouble>, NatureOfField > >::const_iterator it=_arrs.begin();it!=_arrs.end();it++)
     {
-      const DataArrayDouble *pt(*it);
+      const DataArrayDouble *pt((*it).first);
       if(pt)
         updateTimeWith(*pt);
     }
@@ -237,6 +253,26 @@ void DataArrayDoubleCollection::CheckDiscriminantNames(const std::vector<std::st
     throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::CheckDiscriminantNames : The names of fields must be different each other ! It is not the case !");
 }
 
+bool DataArrayDoubleCollection::IsConservativeNature(NatureOfField n)
+{
+  CheckValidNature(n);
+  return n==RevIntegral || n==IntegralGlobConstraint;
+}
+
+void DataArrayDoubleCollection::CheckSameNatures(NatureOfField n1, NatureOfField n2)
+{
+  CheckValidNature(n1);
+  CheckValidNature(n2);
+  if(n1!=n2)
+    throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::CheckSameNatures : natures are not the same !");
+}
+
+void DataArrayDoubleCollection::CheckValidNature(NatureOfField n)
+{
+  if(n!=ConservativeVolumic && n!=Integral && n!=IntegralGlobConstraint && n!=RevIntegral)
+    throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::CheckValidNature : unrecognized nature !");
+}
+
 MEDCouplingGridCollection *MEDCouplingGridCollection::New(const std::vector<const MEDCouplingCartesianAMRMeshGen *>& ms, const std::vector< std::pair<std::string,int> >& fieldNames)
 {
   return new MEDCouplingGridCollection(ms,fieldNames);
@@ -273,6 +309,12 @@ void MEDCouplingGridCollection::spillInfoOnComponents(const std::vector< std::ve
     (*it).second->spillInfoOnComponents(compNames);
 }
 
+void MEDCouplingGridCollection::spillNatures(const std::vector<NatureOfField>& nfs)
+{
+  for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++)
+    (*it).second->spillNatures(nfs);
+}
+
 bool MEDCouplingGridCollection::presenceOf(const MEDCouplingCartesianAMRMeshGen *m, int& pos) const
 {
   int ret(0);
@@ -541,6 +583,17 @@ void MEDCouplingAMRAttribute::spillInfoOnComponents(const std::vector< std::vect
     (*it)->spillInfoOnComponents(compNames);
 }
 
+/*!
+ * Assign nature for each fields in \a this.
+ * \param [in] nfs
+ */
+void MEDCouplingAMRAttribute::spillNatures(const std::vector<NatureOfField>& nfs)
+{
+  _tlc.checkConst();
+  for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> >::iterator it=_levs.begin();it!=_levs.end();it++)
+    (*it)->spillNatures(nfs);
+}
+
 /*!
  * This method returns all DataArrayDouble instances lying on the specified mesh \a mesh.
  * If \a mesh is not part of the progeny of god father object given at construction of \a this an exception will be thrown.
@@ -667,7 +720,7 @@ MEDCouplingFieldDouble *MEDCouplingAMRAttribute::buildCellFieldOnWithoutGhost(ME
   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> arr2(DataArrayDouble::New());
   arr2->alloc(mesh->getImageMesh()->getNumberOfCells(),arr->getNumberOfComponents());
   std::vector< std::pair<int,int> > cgs2(MEDCouplingStructuredMesh::GetCompactFrmtFromDimensions(cgs));
-  MEDCouplingCartesianAMRPatch::ApplyGhostOnCompactFrmt(cgs2,_ghost_lev);
+  MEDCouplingStructuredMesh::ApplyGhostOnCompactFrmt(cgs2,_ghost_lev);
   std::vector<int> fakeFactors(mesh->getImageMesh()->getSpaceDimension(),1);
   MEDCouplingIMesh::SpreadCoarseToFine(arr,cgsWG,arr2,cgs2,fakeFactors);
   arr2->copyStringInfoFrom(*arr);
index ad0783064d3a12aacedfa798e245df7646c5d342..deb5aba72af6c32d16bf4dcd53f0b12bb9c11fb4 100644 (file)
@@ -22,6 +22,7 @@
 #define __MEDCOUPLINGAMRATTRIBUTE_HXX__
 
 #include "MEDCoupling.hxx"
+#include "MEDCouplingNatureOfFieldEnum"
 #include "MEDCouplingCartesianAMRMesh.hxx"
 
 namespace ParaMEDMEM
@@ -34,6 +35,7 @@ namespace ParaMEDMEM
     void allocTuples(int nbOfTuples);
     void dellocTuples();
     void spillInfoOnComponents(const std::vector< std::vector<std::string> >& compNames);
+    void spillNatures(const std::vector<NatureOfField>& nfs);
     std::vector<DataArrayDouble *> retrieveFields() const;
     const DataArrayDouble *getFieldWithName(const std::string& name) const;
     static void SynchronizeFineToCoarse(int ghostLev, const MEDCouplingCartesianAMRMeshGen *fatherOfFineMesh, int patchId, const DataArrayDoubleCollection *fine, DataArrayDoubleCollection *coarse);
@@ -49,8 +51,11 @@ namespace ParaMEDMEM
     std::vector<const BigMemoryObject *> getDirectChildren() const;
     void updateTime() const;
     static void CheckDiscriminantNames(const std::vector<std::string>& names);
+    static bool IsConservativeNature(NatureOfField n);
+    static void CheckSameNatures(NatureOfField n1, NatureOfField n2);
+    static void CheckValidNature(NatureOfField n);
   private:
-    std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> > _arrs;
+    std::vector< std::pair< MEDCouplingAutoRefCountObjectPtr<DataArrayDouble>, NatureOfField > > _arrs;
   };
 
   class MEDCouplingGridCollection : public RefCountObject, public TimeLabel
@@ -60,6 +65,7 @@ namespace ParaMEDMEM
     void alloc(int ghostLev);
     void dealloc();
     void spillInfoOnComponents(const std::vector< std::vector<std::string> >& compNames);
+    void spillNatures(const std::vector<NatureOfField>& nfs);
     bool presenceOf(const MEDCouplingCartesianAMRMeshGen *m, int& pos) const;
     const DataArrayDoubleCollection& getFieldsAt(int pos) const;
     static void SynchronizeFineToCoarse(int ghostLev, const MEDCouplingGridCollection *fine, const MEDCouplingGridCollection *coarse);
@@ -86,6 +92,7 @@ namespace ParaMEDMEM
     MEDCOUPLING_EXPORT static MEDCouplingAMRAttribute *New(MEDCouplingCartesianAMRMeshGen *gf, const std::vector< std::pair<std::string,int> >& fieldNames, int ghostLev);
     MEDCOUPLING_EXPORT static MEDCouplingAMRAttribute *New(MEDCouplingCartesianAMRMeshGen *gf, const std::vector< std::pair<std::string, std::vector<std::string> > >& fieldNames, int ghostLev);
     MEDCOUPLING_EXPORT void spillInfoOnComponents(const std::vector< std::vector<std::string> >& compNames);
+    MEDCOUPLING_EXPORT void spillNatures(const std::vector<NatureOfField>& nfs);
     MEDCOUPLING_EXPORT std::vector<DataArrayDouble *> retrieveFieldsOn(MEDCouplingCartesianAMRMeshGen *mesh) const;
     MEDCOUPLING_EXPORT const DataArrayDouble *getFieldOn(MEDCouplingCartesianAMRMeshGen *mesh, const std::string& fieldName) const;
     MEDCOUPLING_EXPORT MEDCouplingFieldDouble *buildCellFieldOnRecurseWithoutOverlapWithoutGhost(MEDCouplingCartesianAMRMeshGen *mesh, const std::string& fieldName) const;
index 34fb21fec5fcd3dce4d72e6e6c3180873356248b..7a5298327278718eb799b5c62afd48e9ac577c48 100644 (file)
@@ -463,7 +463,7 @@ void MEDCouplingCartesianAMRPatch::UpdateNeighborsOfOneWithTwoInternal(int ghost
   std::vector< std::pair<int,int> > tmp0,tmp1,tmp2;
   MEDCouplingStructuredMesh::ChangeReferenceFromGlobalOfCompactFrmt(p1,p2,tmp0,false);//tmp0=[(3,4),(1,2)]
   ApplyFactorsOnCompactFrmt(tmp0,factors);//tmp0=[(12,16),(4,8)]
-  ApplyGhostOnCompactFrmt(tmp0,ghostLev);//tmp0=[(13,17),(5,9)]
+  MEDCouplingStructuredMesh::ApplyGhostOnCompactFrmt(tmp0,ghostLev);//tmp0=[(13,17),(5,9)]
   std::vector< std::pair<int,int> > interstRange(MEDCouplingStructuredMesh::IntersectRanges(tmp0,rangeCoarse));//interstRange=[(13,14),(5,9)]
   MEDCouplingStructuredMesh::ChangeReferenceFromGlobalOfCompactFrmt(p2,p1,tmp1,false);//tmp1=[(-3,0),(-1,1)]
   ApplyFactorsOnCompactFrmt(tmp1,factors);//tmp1=[(-12,-4),(-4,0)]
@@ -493,22 +493,6 @@ void MEDCouplingCartesianAMRPatch::ApplyFactorsOnCompactFrmt(std::vector< std::p
     }
 }
 
-/*!
- * \param [in,out] partBeforeFact - the part of a image mesh in compact format that will be put in ghost reference.
- * \param [in] ghostSize - the ghost size of zone for all axis.
- */
-void MEDCouplingCartesianAMRPatch::ApplyGhostOnCompactFrmt(std::vector< std::pair<int,int> >& partBeforeFact, int ghostSize)
-{
-  if(ghostSize<0)
-    throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRPatch::ApplyGhostOnCompactFrmt : ghost size must be >= 0 !");
-  std::size_t sz(partBeforeFact.size());
-  for(std::size_t i=0;i<sz;i++)
-    {
-      partBeforeFact[i].first+=ghostSize;
-      partBeforeFact[i].second+=ghostSize;
-    }
-}
-
 /*!
  * This method is different than ApplyGhostOnCompactFrmt. The \a partBeforeFact parameter is enlarger contrary to ApplyGhostOnCompactFrmt.
  *
@@ -1078,7 +1062,7 @@ void MEDCouplingCartesianAMRMeshGen::createPatchesFromCriterionML(const std::vec
       if(!bso[i])
         throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMeshGen::createPatchesFromCriterionML : presence of a NULL BoxSplittingOptions in input vector !");
       //
-      std::vector<MEDCouplingCartesianAMRPatchGen *> elts(retrieveGridsAt((int)(nbOfLevs-1)));
+      std::vector<MEDCouplingCartesianAMRPatchGen *> elts(retrieveGridsAt((int)(i)));
       std::size_t sz(elts.size());
       std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingCartesianAMRPatchGen> > elts2(sz);
       std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> > elts3(sz);
@@ -1198,12 +1182,17 @@ DataArrayDouble *MEDCouplingCartesianAMRMeshGen::createCellFieldOnPatch(int patc
  *
  * \sa createCellFieldOnPatch, fillCellFieldComingFromPatch
  */
-void MEDCouplingCartesianAMRMeshGen::fillCellFieldOnPatch(int patchId, const DataArrayDouble *cellFieldOnThis, DataArrayDouble *cellFieldOnPatch) const
+void MEDCouplingCartesianAMRMeshGen::fillCellFieldOnPatch(int patchId, const DataArrayDouble *cellFieldOnThis, DataArrayDouble *cellFieldOnPatch, bool isConservative) const
 {
   if(!cellFieldOnThis || !cellFieldOnThis->isAllocated())
     throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMesh::createCellFieldOnPatch : the input cell field array is NULL or not allocated !");
   const MEDCouplingCartesianAMRPatch *patch(getPatch(patchId));
   MEDCouplingIMesh::SpreadCoarseToFine(cellFieldOnThis,_mesh->getCellGridStructure(),cellFieldOnPatch,patch->getBLTRRange(),getFactors());
+  if(isConservative)
+    {
+      int fact(MEDCouplingStructuredMesh::DeduceNumberOfGivenStructure(getFactors()));
+      std::transform(cellFieldOnPatch->begin(),cellFieldOnPatch->end(),cellFieldOnPatch->getPointer(),std::bind2nd(std::multiplies<double>(),1./((double)fact)));
+    }
 }
 
 /*!
@@ -1217,12 +1206,17 @@ void MEDCouplingCartesianAMRMeshGen::fillCellFieldOnPatch(int patchId, const Dat
  *
  * \sa fillCellFieldOnPatch, fillCellFieldOnPatchGhostAdv
  */
-void MEDCouplingCartesianAMRMeshGen::fillCellFieldOnPatchGhost(int patchId, const DataArrayDouble *cellFieldOnThis, DataArrayDouble *cellFieldOnPatch, int ghostLev) const
+void MEDCouplingCartesianAMRMeshGen::fillCellFieldOnPatchGhost(int patchId, const DataArrayDouble *cellFieldOnThis, DataArrayDouble *cellFieldOnPatch, int ghostLev, bool isConservative) const
 {
   if(!cellFieldOnThis || !cellFieldOnThis->isAllocated())
     throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMesh::createCellFieldOnPatchGhost : the input cell field array is NULL or not allocated !");
   const MEDCouplingCartesianAMRPatch *patch(getPatch(patchId));
   MEDCouplingIMesh::SpreadCoarseToFineGhost(cellFieldOnThis,_mesh->getCellGridStructure(),cellFieldOnPatch,patch->getBLTRRange(),getFactors(),ghostLev);
+  if(isConservative)
+    {
+      int fact(MEDCouplingStructuredMesh::DeduceNumberOfGivenStructure(getFactors()));
+      std::transform(cellFieldOnPatch->begin(),cellFieldOnPatch->end(),cellFieldOnPatch->getPointer(),std::bind2nd(std::multiplies<double>(),1./((double)fact)));
+    }
 }
 
 /*!
@@ -1254,7 +1248,7 @@ void MEDCouplingCartesianAMRMeshGen::fillCellFieldOnPatchOnlyOnGhostZone(int pat
  *
  * \sa fillCellFieldOnPatchOnlyGhostAdv
  */
-void MEDCouplingCartesianAMRMeshGen::fillCellFieldOnPatchGhostAdv(int patchId, const DataArrayDouble *cellFieldOnThis, int ghostLev, const std::vector<const DataArrayDouble *>& arrsOnPatches) const
+void MEDCouplingCartesianAMRMeshGen::fillCellFieldOnPatchGhostAdv(int patchId, const DataArrayDouble *cellFieldOnThis, int ghostLev, const std::vector<const DataArrayDouble *>& arrsOnPatches, bool isConservative) const
 {
   int nbp(getNumberOfPatches());
   if(nbp!=(int)arrsOnPatches.size())
@@ -1264,7 +1258,7 @@ void MEDCouplingCartesianAMRMeshGen::fillCellFieldOnPatchGhostAdv(int patchId, c
     }
   DataArrayDouble *theFieldToFill(const_cast<DataArrayDouble *>(arrsOnPatches[patchId]));
   // first, do as usual
-  fillCellFieldOnPatchGhost(patchId,cellFieldOnThis,theFieldToFill,ghostLev);
+  fillCellFieldOnPatchGhost(patchId,cellFieldOnThis,theFieldToFill,ghostLev,isConservative);
   fillCellFieldOnPatchOnlyGhostAdv(patchId,ghostLev,arrsOnPatches);
 }
 
@@ -1303,17 +1297,23 @@ void MEDCouplingCartesianAMRMeshGen::fillCellFieldOnPatchOnlyOnGhostZoneWith(int
  * \param [in] patchId - The id of the patch \a cellFieldOnThis has to be put on.
  * \param [in] cellFieldOnPatch - The array of the cell field on patch with id \a patchId.
  * \param [in,out] cellFieldOnThis The array of the cell field on \a this to be updated only on the part concerning the patch with id \a patchId.
+ * \param [in] isConservative - true if the field needs to be conserved. false if maximum principle has to be applied.
  *
  * \throw if \a patchId is not in [ 0 , \c this->getNumberOfPatches() )
  * \throw if \a cellFieldOnPatch is NULL or not allocated
  * \sa createCellFieldOnPatch, MEDCouplingIMesh::CondenseFineToCoarse,fillCellFieldComingFromPatchGhost
  */
-void MEDCouplingCartesianAMRMeshGen::fillCellFieldComingFromPatch(int patchId, const DataArrayDouble *cellFieldOnPatch, DataArrayDouble *cellFieldOnThis) const
+void MEDCouplingCartesianAMRMeshGen::fillCellFieldComingFromPatch(int patchId, const DataArrayDouble *cellFieldOnPatch, DataArrayDouble *cellFieldOnThis, bool isConservative) const
 {
   if(!cellFieldOnPatch || !cellFieldOnPatch->isAllocated())
       throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMesh::fillCellFieldComingFromPatch : the input cell field array is NULL or not allocated !");
   const MEDCouplingCartesianAMRPatch *patch(getPatch(patchId));
   MEDCouplingIMesh::CondenseFineToCoarse(_mesh->getCellGridStructure(),cellFieldOnPatch,patch->getBLTRRange(),getFactors(),cellFieldOnThis);
+  if(!isConservative)
+    {
+      int fact(MEDCouplingStructuredMesh::DeduceNumberOfGivenStructure(getFactors()));
+      MEDCouplingStructuredMesh::MultiplyPartOf(_mesh->getCellGridStructure(),patch->getBLTRRange(),1./((double)fact),cellFieldOnThis);
+    }
 }
 
 /*!
@@ -1324,17 +1324,23 @@ void MEDCouplingCartesianAMRMeshGen::fillCellFieldComingFromPatch(int patchId, c
  * \param [in] cellFieldOnPatch - The array of the cell field on patch with id \a patchId.
  * \param [in,out] cellFieldOnThis The array of the cell field on \a this to be updated only on the part concerning the patch with id \a patchId.
  * \param [in] ghostLev The size of ghost zone (must be >= 0 !)
+ * \param [in] isConservative - true if the field needs to be conserved. false if maximum principle has to be applied.
  *
  * \throw if \a patchId is not in [ 0 , \c this->getNumberOfPatches() )
  * \throw if \a cellFieldOnPatch is NULL or not allocated
  * \sa fillCellFieldComingFromPatch
  */
-void MEDCouplingCartesianAMRMeshGen::fillCellFieldComingFromPatchGhost(int patchId, const DataArrayDouble *cellFieldOnPatch, DataArrayDouble *cellFieldOnThis, int ghostLev) const
+void MEDCouplingCartesianAMRMeshGen::fillCellFieldComingFromPatchGhost(int patchId, const DataArrayDouble *cellFieldOnPatch, DataArrayDouble *cellFieldOnThis, int ghostLev, bool isConservative) const
 {
   if(!cellFieldOnPatch || !cellFieldOnPatch->isAllocated())
     throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMesh::fillCellFieldComingFromPatchGhost : the input cell field array is NULL or not allocated !");
   const MEDCouplingCartesianAMRPatch *patch(getPatch(patchId));
   MEDCouplingIMesh::CondenseFineToCoarseGhost(_mesh->getCellGridStructure(),cellFieldOnPatch,patch->getBLTRRange(),getFactors(),cellFieldOnThis,ghostLev);
+  if(!isConservative)
+    {
+      int fact(MEDCouplingStructuredMesh::DeduceNumberOfGivenStructure(getFactors()));
+      MEDCouplingStructuredMesh::MultiplyPartOfByGhost(_mesh->getCellGridStructure(),patch->getBLTRRange(),ghostLev,1./((double)fact),cellFieldOnThis);
+    }
 }
 
 /*!
@@ -1465,7 +1471,7 @@ DataArrayDouble *MEDCouplingCartesianAMRMeshGen::extractGhostFrom(int ghostSz, c
   std::vector<int> st(_mesh->getCellGridStructure());
   std::vector< std::pair<int,int> > p(MEDCouplingStructuredMesh::GetCompactFrmtFromDimensions(st));
   std::transform(st.begin(),st.end(),st.begin(),std::bind2nd(std::plus<int>(),2*ghostSz));
-  MEDCouplingCartesianAMRPatch::ApplyGhostOnCompactFrmt(p,ghostSz);
+  MEDCouplingStructuredMesh::ApplyGhostOnCompactFrmt(p,ghostSz);
   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret(MEDCouplingStructuredMesh::ExtractFieldOfDoubleFrom(st,arr,p));
   return ret.retn();
 }
index 4bd30990c3330965dad84f76293e01fa387e1fb1..1c911beef216717726d6403b39d4482459a19f2e 100644 (file)
@@ -96,7 +96,6 @@ namespace ParaMEDMEM
     static void UpdateNeighborsOfOneWithTwoInternal(int ghostLev, const std::vector<int>& factors, const std::vector< std::pair<int,int> >&p1 ,const std::vector< std::pair<int,int> >&p2, DataArrayDouble *dataOnP1, const DataArrayDouble *dataOnP2);
   public:
     static void ApplyFactorsOnCompactFrmt(std::vector< std::pair<int,int> >& partBeforeFact, const std::vector<int>& factors);
-    static void ApplyGhostOnCompactFrmt(std::vector< std::pair<int,int> >& partBeforeFact, int ghostSize);
     static void ApplyAllGhostOnCompactFrmt(std::vector< std::pair<int,int> >& partBeforeFact, int ghostSize);
   private:
     //! bottom left/top right cell range relative to \a _father
@@ -171,17 +170,17 @@ namespace ParaMEDMEM
     MEDCOUPLING_EXPORT bool isPatchInNeighborhoodOf(int patchId1, int patchId2, int ghostLev) const;
     MEDCOUPLING_EXPORT DataArrayDouble *createCellFieldOnPatch(int patchId, const DataArrayDouble *cellFieldOnThis) const;
     // coarse to fine
-    MEDCOUPLING_EXPORT void fillCellFieldOnPatch(int patchId, const DataArrayDouble *cellFieldOnThis, DataArrayDouble *cellFieldOnPatch) const;
-    MEDCOUPLING_EXPORT void fillCellFieldOnPatchGhost(int patchId, const DataArrayDouble *cellFieldOnThis, DataArrayDouble *cellFieldOnPatch, int ghostLev) const;
+    MEDCOUPLING_EXPORT void fillCellFieldOnPatch(int patchId, const DataArrayDouble *cellFieldOnThis, DataArrayDouble *cellFieldOnPatch, bool isConservative=true) const;
+    MEDCOUPLING_EXPORT void fillCellFieldOnPatchGhost(int patchId, const DataArrayDouble *cellFieldOnThis, DataArrayDouble *cellFieldOnPatch, int ghostLev, bool isConservative=true) const;
     MEDCOUPLING_EXPORT void fillCellFieldOnPatchOnlyOnGhostZone(int patchId, const DataArrayDouble *cellFieldOnThis, DataArrayDouble *cellFieldOnPatch, int ghostLev) const;
     // coarse to fine + fine to fine
-    MEDCOUPLING_EXPORT void fillCellFieldOnPatchGhostAdv(int patchId, const DataArrayDouble *cellFieldOnThis, int ghostLev, const std::vector<const DataArrayDouble *>& arrsOnPatches) const;
+    MEDCOUPLING_EXPORT void fillCellFieldOnPatchGhostAdv(int patchId, const DataArrayDouble *cellFieldOnThis, int ghostLev, const std::vector<const DataArrayDouble *>& arrsOnPatches, bool isConservative=true) const;
     // fine to fine
     MEDCOUPLING_EXPORT void fillCellFieldOnPatchOnlyGhostAdv(int patchId, int ghostLev, const std::vector<const DataArrayDouble *>& arrsOnPatches) const;
     MEDCOUPLING_EXPORT void fillCellFieldOnPatchOnlyOnGhostZoneWith(int ghostLev, const MEDCouplingCartesianAMRPatch *patchToBeModified, const MEDCouplingCartesianAMRPatch *neighborPatch, DataArrayDouble *cellFieldOnPatch, const DataArrayDouble *cellFieldNeighbor) const;
     // fine to coarse
-    MEDCOUPLING_EXPORT void fillCellFieldComingFromPatch(int patchId, const DataArrayDouble *cellFieldOnPatch, DataArrayDouble *cellFieldOnThis) const;
-    MEDCOUPLING_EXPORT void fillCellFieldComingFromPatchGhost(int patchId, const DataArrayDouble *cellFieldOnPatch, DataArrayDouble *cellFieldOnThis, int ghostLev) const;
+    MEDCOUPLING_EXPORT void fillCellFieldComingFromPatch(int patchId, const DataArrayDouble *cellFieldOnPatch, DataArrayDouble *cellFieldOnThis, bool isConservative=true) const;
+    MEDCOUPLING_EXPORT void fillCellFieldComingFromPatchGhost(int patchId, const DataArrayDouble *cellFieldOnPatch, DataArrayDouble *cellFieldOnThis, int ghostLev, bool isConservative=true) const;
     //
     MEDCOUPLING_EXPORT DataArrayInt *findPatchesInTheNeighborhoodOf(int patchId, int ghostLev) const;
     //
index 52e9a274a39961df521a21a9e6f4bd9e9ebd24de..ebc71739d87730d4fed275aaa67c844d2047bc7c 100644 (file)
@@ -1725,7 +1725,7 @@ std::vector<int> MEDCouplingStructuredMesh::FindTranslationFrom(const std::vecto
  * If the range contains invalid values regarding sructure an exception will be thrown.
  *
  * \return DataArrayInt * - a new object.
- * \sa MEDCouplingStructuredMesh::IsPartStructured, MEDCouplingStructuredMesh::DeduceNumberOfGivenRangeInCompactFrmt, SwitchOnIdsFrom, ExtractFieldOfBoolFrom, ExtractFieldOfDoubleFrom
+ * \sa MEDCouplingStructuredMesh::IsPartStructured, MEDCouplingStructuredMesh::DeduceNumberOfGivenRangeInCompactFrmt, SwitchOnIdsFrom, ExtractFieldOfBoolFrom, ExtractFieldOfDoubleFrom, MultiplyPartOf
  */
 DataArrayInt *MEDCouplingStructuredMesh::BuildExplicitIdsFrom(const std::vector<int>& st, const std::vector< std::pair<int,int> >& partCompactFormat)
 {
@@ -1739,7 +1739,7 @@ DataArrayInt *MEDCouplingStructuredMesh::BuildExplicitIdsFrom(const std::vector<
         throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::BuildExplicitIdsFrom : invalid input range 1 !");
       if(partCompactFormat[i].second<0 || partCompactFormat[i].second>st[i])
         throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::BuildExplicitIdsFrom : invalid input range 2 !");
-      if(partCompactFormat[i].second<=partCompactFormat[i].first)
+      if(partCompactFormat[i].second<partCompactFormat[i].first)
         throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::BuildExplicitIdsFrom : invalid input range 3 !");
       dims[i]=partCompactFormat[i].second-partCompactFormat[i].first;
       nbOfItems*=dims[i];
@@ -1785,6 +1785,148 @@ DataArrayInt *MEDCouplingStructuredMesh::BuildExplicitIdsFrom(const std::vector<
   return ret.retn();
 }
 
+/*!
+ * This method multiplies by \a factor values in tuples located by \a part in \a da.
+ *
+ * \param [in] st - the structure of grid ( \b without considering ghost cells).
+ * \param [in] part - the part in the structure ( \b without considering ghost cells) contained in grid whose structure is defined by \a st.
+ * \param [in] factor - the factor, the tuples in \a da will be multiply by.
+ * \param [in,out] da - The DataArray in wich only tuples specified by \a part will be modified.
+ *
+ * \sa BuildExplicitIdsFrom
+ */
+void MEDCouplingStructuredMesh::MultiplyPartOf(const std::vector<int>& st, const std::vector< std::pair<int,int> >& part, double factor, DataArrayDouble *da)
+{
+  if(!da || !da->isAllocated())
+    throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::MultiplyPartOf : DataArrayDouble instance must be not NULL and allocated !");
+  if(st.size()!=part.size())
+    throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::MultiplyPartOf : input arrays must have the same size !");
+  std::vector<int> dims(st.size());
+  for(std::size_t i=0;i<st.size();i++)
+    {
+      if(part[i].first<0 || part[i].first>st[i])
+        throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::MultiplyPartOf : invalid input range 1 !");
+      if(part[i].second<0 || part[i].second>st[i])
+        throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::MultiplyPartOf : invalid input range 2 !");
+      if(part[i].second<part[i].first)
+        throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::MultiplyPartOf : invalid input range 3 !");
+      dims[i]=part[i].second-part[i].first;
+    }
+  int nbOfTuplesExp(MEDCouplingStructuredMesh::DeduceNumberOfGivenStructure(st)),nbCompo(da->getNumberOfComponents());
+  if(da->getNumberOfTuples()!=nbOfTuplesExp)
+    {
+      std::ostringstream oss; oss << "MEDCouplingStructuredMesh::MultiplyPartOf : invalid nb of tuples ! Expected " << nbOfTuplesExp << " having " << da->getNumberOfTuples() << " !";
+      throw INTERP_KERNEL::Exception(oss.str().c_str());
+    }
+  double *pt(da->getPointer());
+  switch(st.size())
+  {
+    case 3:
+      {
+        for(int i=0;i<dims[2];i++)
+          {
+            int a=(part[2].first+i)*st[0]*st[1];
+            for(int j=0;j<dims[1];j++)
+              {
+                int b=(part[1].first+j)*st[0];
+                for(int k=0;k<dims[0];k++)
+                  {
+                    int offset(part[0].first+k+b+a);
+                    std::transform(pt+nbCompo*offset,pt+nbCompo*(offset+1),pt+nbCompo*offset,std::bind2nd(std::multiplies<double>(),factor));
+                  }
+              }
+          }
+        break;
+      }
+    case 2:
+      {
+        for(int j=0;j<dims[1];j++)
+          {
+            int b=(part[1].first+j)*st[0];
+            for(int k=0;k<dims[0];k++)
+              {
+                int offset(part[0].first+k+b);
+                std::transform(pt+nbCompo*offset,pt+nbCompo*(offset+1),pt+nbCompo*offset,std::bind2nd(std::multiplies<double>(),factor));
+              }
+          }
+        break;
+      }
+    case 1:
+      {
+        for(int k=0;k<dims[0];k++)
+          {
+            int offset(part[0].first+k);
+            std::transform(pt+nbCompo*offset,pt+nbCompo*(offset+1),pt+nbCompo*offset,std::bind2nd(std::multiplies<double>(),factor));
+          }
+        break;
+      }
+    default:
+      throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::MultiplyPartOf : Dimension supported are 1,2 or 3 !");
+  }
+}
+
+/*!
+ * This method multiplies by \a factor values in tuples located by \a part in \a da.
+ *
+ * \param [in] st - the structure of grid ( \b without considering ghost cells).
+ * \param [in] part - the part in the structure ( \b without considering ghost cells) contained in grid whose structure is defined by \a st.
+ * \param [in] ghostSize - \a ghostSize must be >= 0.
+ * \param [in] factor - the factor, the tuples in \a da will be multiply by.
+ * \param [in,out] da - The DataArray in wich only tuples specified by \a part will be modified.
+ *
+ * \sa MultiplyPartOf, PutInGhostFormat
+ */
+void MEDCouplingStructuredMesh::MultiplyPartOfByGhost(const std::vector<int>& st, const std::vector< std::pair<int,int> >& part, int ghostSize, double factor, DataArrayDouble *da)
+{
+  std::vector<int> stWG;
+  std::vector< std::pair<int,int> > partWG;
+  PutInGhostFormat(ghostSize,st,part,stWG,partWG);
+  MultiplyPartOf(stWG,partWG,factor,da);
+}
+
+/*!
+ * This method multiplies by \a factor values in tuples located by \a part in \a da.
+ *
+ * \param [in] st - the structure of grid ( \b without considering ghost cells).
+ * \param [in] part - the part in the structure ( \b without considering ghost cells) contained in grid whose structure is defined by \a st.
+ * \param [in] ghostSize - \a ghostSize must be >= 0.
+ * \param [out] stWithGhost - the structure considering ghost cells.
+ * \param [out] partWithGhost - the part considering the ghost cells.
+ *
+ * \sa MultiplyPartOf, PutInGhostFormat
+ */
+void MEDCouplingStructuredMesh::PutInGhostFormat(int ghostSize, const std::vector<int>& st, const std::vector< std::pair<int,int> >& part, std::vector<int>& stWithGhost, std::vector< std::pair<int,int> >&partWithGhost)
+{
+  if(ghostSize<0)
+    throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::PutInGhostFormat : ghost size must be >= 0 !");
+  std::size_t dim(part.size());
+  if(st.size()!=dim)
+    throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::PutInGhostFormat : the dimension of input vectors must be the same !");
+  for(std::size_t i=0;i<dim;i++)
+    if(part[i].first<0 || part[i].first>part[i].second || part[i].second>st[i])
+      throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::PutInGhostFormat : the specified part is invalid ! The begin must be >= 0 and <= end ! The end must be <= to the size at considered dimension !");
+  stWithGhost.resize(st.size());
+  std::transform(st.begin(),st.end(),stWithGhost.begin(),std::bind2nd(std::plus<int>(),2*ghostSize));
+  partWithGhost=part;
+  ApplyGhostOnCompactFrmt(partWithGhost,ghostSize);
+}
+
+/*!
+ * \param [in,out] partBeforeFact - the part of a image mesh in compact format that will be put in ghost reference.
+ * \param [in] ghostSize - the ghost size of zone for all axis.
+ */
+void MEDCouplingStructuredMesh::ApplyGhostOnCompactFrmt(std::vector< std::pair<int,int> >& partBeforeFact, int ghostSize)
+{
+  if(ghostSize<0)
+    throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::ApplyGhostOnCompactFrmt : ghost size must be >= 0 !");
+  std::size_t sz(partBeforeFact.size());
+  for(std::size_t i=0;i<sz;i++)
+    {
+      partBeforeFact[i].first+=ghostSize;
+      partBeforeFact[i].second+=ghostSize;
+    }
+}
+
 int MEDCouplingStructuredMesh::GetNumberOfCellsOfSubLevelMesh(const std::vector<int>& cgs, int mdim)
 {
   int ret(0);
index 64be4422bedb290638ee8633d26ea7fdebfb2aa0..990ca735087b1b71d27b4942a8bdd597ce82470b 100644 (file)
@@ -83,6 +83,10 @@ namespace ParaMEDMEM
     MEDCOUPLING_EXPORT static std::vector< std::pair<int,int> > TranslateCompactFrmt(const std::vector< std::pair<int,int> >& part, const std::vector<int>& translation);
     MEDCOUPLING_EXPORT static std::vector<int> FindTranslationFrom(const std::vector< std::pair<int,int> >& startingFrom, const std::vector< std::pair<int,int> >& goingTo);
     MEDCOUPLING_EXPORT static DataArrayInt *BuildExplicitIdsFrom(const std::vector<int>& st, const std::vector< std::pair<int,int> >& partCompactFormat);
+    MEDCOUPLING_EXPORT static void MultiplyPartOf(const std::vector<int>& st, const std::vector< std::pair<int,int> >& part, double factor, DataArrayDouble *da);
+    MEDCOUPLING_EXPORT static void MultiplyPartOfByGhost(const std::vector<int>& st, const std::vector< std::pair<int,int> >& part, int ghostSize, double factor, DataArrayDouble *da);
+    MEDCOUPLING_EXPORT static void PutInGhostFormat(int ghostSize, const std::vector<int>& st, const std::vector< std::pair<int,int> >& part, std::vector<int>& stWithGhost, std::vector< std::pair<int,int> >&partWithGhost);
+    MEDCOUPLING_EXPORT static void ApplyGhostOnCompactFrmt(std::vector< std::pair<int,int> >& partBeforeFact, int ghostSize);
     MEDCOUPLING_EXPORT static DataArrayInt *Build1GTNodalConnectivity(const int *nodeStBg, const int *nodeStEnd);
     MEDCOUPLING_EXPORT static DataArrayInt *Build1GTNodalConnectivityOfSubLevelMesh(const int *nodeStBg, const int *nodeStEnd);
     MEDCOUPLING_EXPORT static DataArrayInt *ComputeCornersGhost(const std::vector<int>& st, int ghostLev);
index a5d151cf46460a17fbb633ca88942d9830079b4f..7e3a7696421a366566e3463253a9a71c9747f256 100644 (file)
@@ -15188,8 +15188,8 @@ class MEDCouplingBasicsTest(unittest.TestCase):
         l=[da0,da1,da2,da3,da4]
         lCpy=[elt.deepCpy() for elt in l]
         l2=[DataArrayDouble.Meld(elt,3*elt) for elt in l]
-        amr.fillCellFieldOnPatchGhostAdv(0,da,1,l)
-        amr.fillCellFieldOnPatchGhostAdv(0,DataArrayDouble.Meld(da,3*da),1,l2)
+        amr.fillCellFieldOnPatchGhostAdv(0,da,1,l,False)
+        amr.fillCellFieldOnPatchGhostAdv(0,DataArrayDouble.Meld(da,3*da),1,l2,False)
         amr.fillCellFieldOnPatchOnlyOnGhostZone(0,da,lCpy[0],1)
         #
         f=MEDCouplingFieldDouble(ON_CELLS) ; f.setMesh(amr.getImageMesh().buildWithGhost(1)) ; f.setArray(da) ; f.setName("all")
@@ -15228,8 +15228,8 @@ class MEDCouplingBasicsTest(unittest.TestCase):
         l=[da0,da1]
         lCpy=[elt.deepCpy() for elt in l]
         l2=[DataArrayDouble.Meld(elt,3*elt) for elt in l]
-        amr.fillCellFieldOnPatchGhostAdv(0,da,1,l)
-        amr.fillCellFieldOnPatchGhostAdv(0,DataArrayDouble.Meld(da,3*da),1,l2)
+        amr.fillCellFieldOnPatchGhostAdv(0,da,1,l,False)
+        amr.fillCellFieldOnPatchGhostAdv(0,DataArrayDouble.Meld(da,3*da),1,l2,False)
         amr.fillCellFieldOnPatchOnlyOnGhostZone(0,da,lCpy[0],1)
         #
         f=MEDCouplingFieldDouble(ON_CELLS) ; f.setMesh(amr.getImageMesh().buildWithGhost(1)) ; f.setArray(da) ; f.setName("all")
index 46c8523f23817d7123643d028c050e2dd75f5349..d63d8bcbf7d3dd79a8d52410098b7f146f30d9c0 100644 (file)
@@ -2906,6 +2906,33 @@ namespace ParaMEDMEM
         return MEDCouplingStructuredMesh::BuildExplicitIdsFrom(tmp5,inp);
       }
 
+      static void MultiplyPartOf(const std::vector<int>& st, PyObject *part, double factor, DataArrayDouble *da) throw(INTERP_KERNEL::Exception)
+      {
+        std::vector< std::pair<int,int> > inp;
+        convertPyToVectorPairInt(part,inp);
+        MEDCouplingStructuredMesh::MultiplyPartOf(st,inp,factor,da);
+      }
+
+      static void MultiplyPartOfByGhost(const std::vector<int>& st, PyObject *part, int ghostSize, double factor, DataArrayDouble *da) throw(INTERP_KERNEL::Exception)
+      {
+        std::vector< std::pair<int,int> > inp;
+        convertPyToVectorPairInt(part,inp);
+        MEDCouplingStructuredMesh::MultiplyPartOfByGhost(st,inp,ghostSize,factor,da);
+      }
+
+      static PyObject *PutInGhostFormat(int ghostSize, const std::vector<int>& st, PyObject *part) throw(INTERP_KERNEL::Exception)
+      {
+        std::vector< std::pair<int,int> > inp;
+        convertPyToVectorPairInt(part,inp);
+        std::vector<int> stWithGhost;
+        std::vector< std::pair<int,int> > partWithGhost;
+        MEDCouplingStructuredMesh::PutInGhostFormat(ghostSize,st,inp,stWithGhost,partWithGhost);
+        PyObject *ret(PyTuple_New(2));
+        PyTuple_SetItem(ret,0,convertIntArrToPyList2(stWithGhost));
+        PyTuple_SetItem(ret,1,convertFromVectorPairInt(partWithGhost));
+        return ret;
+      }
+
       static DataArrayDouble *ExtractFieldOfDoubleFrom(const std::vector<int>& st, const DataArrayDouble *fieldOfDbl, PyObject *partCompactFormat) throw(INTERP_KERNEL::Exception)
       {
         std::vector< std::pair<int,int> > inp;
@@ -4919,12 +4946,12 @@ namespace ParaMEDMEM
     void createPatchesFromCriterion(const INTERP_KERNEL::BoxSplittingOptions& bso, const DataArrayByte *criterion, const std::vector<int>& factors) throw(INTERP_KERNEL::Exception);
     void createPatchesFromCriterion(const INTERP_KERNEL::BoxSplittingOptions& bso, const DataArrayDouble *criterion, const std::vector<int>& factors, double eps) throw(INTERP_KERNEL::Exception);
     DataArrayDouble *createCellFieldOnPatch(int patchId, const DataArrayDouble *cellFieldOnThis) const throw(INTERP_KERNEL::Exception);
-    void fillCellFieldOnPatch(int patchId, const DataArrayDouble *cellFieldOnThis, DataArrayDouble *cellFieldOnPatch) const throw(INTERP_KERNEL::Exception);
-    void fillCellFieldOnPatchGhost(int patchId, const DataArrayDouble *cellFieldOnThis, DataArrayDouble *cellFieldOnPatch, int ghostLev) const throw(INTERP_KERNEL::Exception);
+    void fillCellFieldOnPatch(int patchId, const DataArrayDouble *cellFieldOnThis, DataArrayDouble *cellFieldOnPatch, bool isConservative=true) const throw(INTERP_KERNEL::Exception);
+    void fillCellFieldOnPatchGhost(int patchId, const DataArrayDouble *cellFieldOnThis, DataArrayDouble *cellFieldOnPatch, int ghostLev, bool isConservative=true) const throw(INTERP_KERNEL::Exception);
     void fillCellFieldOnPatchOnlyOnGhostZone(int patchId, const DataArrayDouble *cellFieldOnThis, DataArrayDouble *cellFieldOnPatch, int ghostLev) const throw(INTERP_KERNEL::Exception);
     void fillCellFieldOnPatchOnlyOnGhostZoneWith(int ghostLev, const MEDCouplingCartesianAMRPatch *patchToBeModified, const MEDCouplingCartesianAMRPatch *neighborPatch, DataArrayDouble *cellFieldOnPatch, const DataArrayDouble *cellFieldNeighbor) const;
-    void fillCellFieldComingFromPatch(int patchId, const DataArrayDouble *cellFieldOnPatch, DataArrayDouble *cellFieldOnThis) const throw(INTERP_KERNEL::Exception);
-    void fillCellFieldComingFromPatchGhost(int patchId, const DataArrayDouble *cellFieldOnPatch, DataArrayDouble *cellFieldOnThis, int ghostLev) const throw(INTERP_KERNEL::Exception);
+    void fillCellFieldComingFromPatch(int patchId, const DataArrayDouble *cellFieldOnPatch, DataArrayDouble *cellFieldOnThis, bool isConservative=true) const throw(INTERP_KERNEL::Exception);
+    void fillCellFieldComingFromPatchGhost(int patchId, const DataArrayDouble *cellFieldOnPatch, DataArrayDouble *cellFieldOnThis, int ghostLev, bool isConservative=true) const throw(INTERP_KERNEL::Exception);
     DataArrayInt *findPatchesInTheNeighborhoodOf(int patchId, int ghostLev) const throw(INTERP_KERNEL::Exception);
     %extend
     {
@@ -5023,11 +5050,11 @@ namespace ParaMEDMEM
         return ret;
       }
 
-      void fillCellFieldOnPatchGhostAdv(int patchId, const DataArrayDouble *cellFieldOnThis, int ghostLev, PyObject *arrsOnPatches) const throw(INTERP_KERNEL::Exception)
+      void fillCellFieldOnPatchGhostAdv(int patchId, const DataArrayDouble *cellFieldOnThis, int ghostLev, PyObject *arrsOnPatches, bool isConservative=true) const throw(INTERP_KERNEL::Exception)
       {
         std::vector<const ParaMEDMEM::DataArrayDouble *> arrsOnPatches2;
         convertFromPyObjVectorOfObj<const ParaMEDMEM::DataArrayDouble *>(arrsOnPatches,SWIGTYPE_p_ParaMEDMEM__DataArrayDouble,"DataArrayDouble",arrsOnPatches2);
-        self->fillCellFieldOnPatchGhostAdv(patchId,cellFieldOnThis,ghostLev,arrsOnPatches2);
+        self->fillCellFieldOnPatchGhostAdv(patchId,cellFieldOnThis,ghostLev,arrsOnPatches2,isConservative);
       }
 
       void fillCellFieldOnPatchOnlyGhostAdv(int patchId, int ghostLev, PyObject *arrsOnPatches) const
@@ -5131,6 +5158,18 @@ namespace ParaMEDMEM
         convertPyToVectorOfVectorOfString(compNames,compNamesCpp);
         self->spillInfoOnComponents(compNamesCpp);
       }
+
+      void spillNatures(PyObject *nfs) throw(INTERP_KERNEL::Exception)
+      {
+        std::vector<int> inp0;
+        if(!fillIntVector(nfs,inp0))
+          throw INTERP_KERNEL::Exception("wrap of MEDCouplingAMRAttribute::spillNatures : vector of NatureOfField enum expected !");
+        std::size_t sz(inp0.size());
+        std::vector<NatureOfField> inp00(sz);
+        for(std::size_t i=0;i<sz;i++)
+          inp00[i]=(NatureOfField)inp0[i];
+        self->spillNatures(inp00);
+      }
       
       PyObject *retrieveFieldsOn(MEDCouplingCartesianAMRMeshGen *mesh) const throw(INTERP_KERNEL::Exception)
       {