]> SALOME platform Git repositories - tools/medcoupling.git/commitdiff
Salome HOME
Merge from V6_main 13/12/2012 BR_KERNEL_REFACTORING V7_1_0_pre
authorvsr <vsr@opencascade.com>
Thu, 13 Dec 2012 10:43:47 +0000 (10:43 +0000)
committervsr <vsr@opencascade.com>
Thu, 13 Dec 2012 10:43:47 +0000 (10:43 +0000)
93 files changed:
CMakeLists.txt
doc/doxygen/Makefile.am
src/INTERP_KERNEL/CMakeLists.txt
src/INTERP_KERNEL/CellModel.cxx
src/INTERP_KERNEL/ExprEval/InterpKernelExprParser.cxx
src/INTERP_KERNEL/ExprEval/InterpKernelFunction.cxx
src/INTERP_KERNEL/ExprEval/InterpKernelFunction.hxx
src/INTERP_KERNEL/ExprEval/InterpKernelValue.cxx
src/INTERP_KERNEL/ExprEval/InterpKernelValue.hxx
src/INTERP_KERNEL/GaussPoints/InterpKernelGaussCoords.cxx
src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DComposedEdge.cxx
src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DComposedEdge.hxx
src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DQuadraticPolygon.cxx
src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DQuadraticPolygon.hxx
src/INTERP_KERNEL/Interpolation3D2D.txx
src/INTERP_KERNEL/InterpolationCC.hxx
src/INTERP_KERNEL/InterpolationCC.txx
src/INTERP_KERNEL/InterpolationCU.txx
src/INTERP_KERNEL/TetraAffineTransform.cxx
src/INTERP_KERNEL/VolSurfFormulae.hxx
src/INTERP_KERNEL/VolSurfUser.txx
src/INTERP_KERNELTest/SingleElementPlanarTests.cxx
src/INTERP_KERNELTest/UnitTetra3D2DIntersectionTest.cxx
src/MED/CMakeLists.txt
src/MEDCoupling/CMakeLists.txt
src/MEDCoupling/MEDCouplingCMesh.cxx
src/MEDCoupling/MEDCouplingField.cxx
src/MEDCoupling/MEDCouplingField.hxx
src/MEDCoupling/MEDCouplingFieldDiscretization.cxx
src/MEDCoupling/MEDCouplingFieldDiscretization.hxx
src/MEDCoupling/MEDCouplingFieldDouble.cxx
src/MEDCoupling/MEDCouplingFieldDouble.hxx
src/MEDCoupling/MEDCouplingMemArray.cxx
src/MEDCoupling/MEDCouplingMemArray.hxx
src/MEDCoupling/MEDCouplingMesh.cxx
src/MEDCoupling/MEDCouplingMesh.hxx
src/MEDCoupling/MEDCouplingRefCountObject.cxx
src/MEDCoupling/MEDCouplingRefCountObject.hxx
src/MEDCoupling/MEDCouplingRemapper.cxx
src/MEDCoupling/MEDCouplingRemapper.hxx
src/MEDCoupling/MEDCouplingUMesh.cxx
src/MEDCoupling/MEDCouplingUMesh.hxx
src/MEDCoupling/Makefile.am
src/MEDCoupling/Test/MEDCouplingBasicsTest1.cxx
src/MEDCoupling/Test/MEDCouplingBasicsTest2.cxx
src/MEDCoupling/Test/MEDCouplingBasicsTest3.cxx
src/MEDCoupling/Test/MEDCouplingBasicsTest4.cxx
src/MEDCoupling/Test/MEDCouplingBasicsTest5.cxx
src/MEDCoupling/Test/MEDCouplingBasicsTest5.hxx
src/MEDCoupling_Swig/MEDCouplingBasicsTest.py
src/MEDCoupling_Swig/MEDCouplingCommon.i
src/MEDCoupling_Swig/MEDCouplingRemapperTest.py
src/MEDCoupling_Swig/MEDCouplingTypemaps.i
src/MEDLoader/MEDFileData.cxx
src/MEDLoader/MEDFileField.cxx
src/MEDLoader/MEDFileField.hxx
src/MEDLoader/MEDFileMesh.cxx
src/MEDLoader/MEDFileMeshLL.cxx
src/MEDLoader/MEDLoader.cxx
src/MEDLoader/MEDLoader.hxx
src/MEDLoader/Swig/MEDLoaderTest3.py
src/MEDMEMCppTest/CMakeLists.txt
src/MEDOP/cmp/CMakeLists.txt
src/MEDOP/doc/models/medop.xmi
src/MEDOP/doc/sphinx/CMakeLists.txt
src/MEDOP/doc/sphinx/Makefile.am
src/MEDOP/doc/sphinx/_static/medop.css [new file with mode: 0644]
src/MEDOP/doc/sphinx/_static/xmed.css [deleted file]
src/MEDOP/doc/sphinx/conf.py.in
src/MEDOP/doc/sphinx/index.rst
src/MEDOP/doc/sphinx/medop-definitions.rst [new file with mode: 0644]
src/MEDOP/doc/sphinx/medop-develguide.rst [new file with mode: 0644]
src/MEDOP/doc/sphinx/medop-prototype-develguide.rst [new file with mode: 0644]
src/MEDOP/doc/sphinx/medop-prototype-medmem.rst [new file with mode: 0644]
src/MEDOP/doc/sphinx/medop-prototype-overview.rst [new file with mode: 0644]
src/MEDOP/doc/sphinx/medop-references.rst [new file with mode: 0644]
src/MEDOP/doc/sphinx/medop-specifications.rst [new file with mode: 0644]
src/MEDOP/doc/sphinx/medop-userguide.rst [new file with mode: 0644]
src/MEDOP/doc/sphinx/medop-workingnotes-2010.rst [new file with mode: 0644]
src/MEDOP/doc/sphinx/medop-workingnotes-2011.rst [new file with mode: 0644]
src/MEDOP/doc/sphinx/medop-workingnotes-2012.rst [new file with mode: 0644]
src/MEDOP/doc/sphinx/salomedoc.rst [deleted file]
src/MEDOP/doc/sphinx/xmed-definitions.rst [deleted file]
src/MEDOP/doc/sphinx/xmed-develguide.rst [deleted file]
src/MEDOP/doc/sphinx/xmed-prototype-develguide.rst [deleted file]
src/MEDOP/doc/sphinx/xmed-prototype-medmem.rst [deleted file]
src/MEDOP/doc/sphinx/xmed-prototype-overview.rst [deleted file]
src/MEDOP/doc/sphinx/xmed-references.rst [deleted file]
src/MEDOP/doc/sphinx/xmed-specifications.rst [deleted file]
src/MEDOP/doc/sphinx/xmed-userguide.rst [deleted file]
src/MEDOP/doc/sphinx/xmed-workingnotes-2010.rst [deleted file]
src/MEDOP/doc/sphinx/xmed-workingnotes-2011.rst [deleted file]
src/MEDOP/doc/sphinx/xmed-workingnotes-2012.rst [deleted file]

index a431ab0ba0b748d496427fa7bb3f5baa48317dea..39e1b2347011c6e46461f552287ac994abbf8271 100644 (file)
@@ -24,7 +24,7 @@ IF(COMMAND cmake_policy)
 ENDIF(COMMAND cmake_policy)
 
 ENABLE_TESTING()
-SET(VERSION "6.5.0")
+SET(VERSION "7.0.0")
 SET(VERSION_DEV "1")
 SET(WITH_MEDMEMGUI "0")
 
index af129916444e6bf147e9b8ef1655e4df1edf7265..10599e26c6693e8c1249959080e0f824fdcd6c0c 100644 (file)
@@ -23,9 +23,18 @@ include $(top_srcdir)/adm_local/unix/make_common_starter.am
 
 DOX_INPUT_FILE = Doxyfile_med_user
 
+DOX_EXTRA_FILES = medcouplingexamples.dox
+
 guidocdir = $(docdir)/gui/MED
 guidoc_DATA = images/head.png
 
+# documentation
+html-local: $(DOXY_INPUT_FILE) $(DOX_EXTRA_FILES)
+       @doxygen $(DOX_INPUT_FILE)
+
+%.dox: %.doxy
+       @python $(srcdir)/BuildPyExamplesFromCPP.py $< $(top_builddir)/doc/doxygen
+
 install-data-local : html-local
        @if test -d doc_ref_user; then                                  \
        $(INSTALL) -d $(DESTDIR)$(docdir)/gui/MED;                      \
@@ -41,7 +50,7 @@ uninstall-local:
        rm -rf $(DESTDIR)$(docdir)/gui/MED
 
 clean-local:
-       rm -rf doc_ref_user log_user
+       rm -rf doc_ref_user log_user $(DOX_EXTRA_FILES)
 
 EXTRA_DIST += figures \
              main.dox \
@@ -70,5 +79,6 @@ EXTRA_DIST += figures \
              static/footer.html \
              static/doxygen.css \
              images \
-             BuildPyExamplesFromCPP.py \
-             medcouplingexamples.doxy
+             BuildPyExamplesFromCPP.py
+
+EXTRA_DIST += $(DOX_EXTRA_FILES:%.dox=%.doxy)
index 8d9d2463a16270b3eb8a63cee32611a4c5186322..02d8637bdfd75b635defc98d29520c01acb148a3 100644 (file)
@@ -65,8 +65,13 @@ INCLUDE_DIRECTORIES(
   ${CMAKE_CURRENT_SOURCE_DIR}/GaussPoints
   )
 
+SET(PLATFORM_MMAP)
+IF(NOT WINDOWS)
+  SET(PLATFORM_MMAP "-D_POSIX_MAPPED_FILES")
+ENDIF(NOT WINDOWS)
+
 ADD_LIBRARY(interpkernel SHARED ${interpkernel_SOURCES})
-SET_TARGET_PROPERTIES(interpkernel PROPERTIES COMPILE_FLAGS "${PLATFORM_DEFINITIONS}")
+SET_TARGET_PROPERTIES(interpkernel PROPERTIES COMPILE_FLAGS "${PLATFORM_DEFINITIONS} ${PLATFORM_MMAP}")
 TARGET_LINK_LIBRARIES(interpkernel ${PLATFORM_LIBS})
 INSTALL(TARGETS interpkernel DESTINATION ${MED_salomelib_LIBS})
 
index 13781012362e08ae725a3a00227935775738a433..6a027a81990dc74a0211972229b7f598368e7d18 100644 (file)
@@ -419,8 +419,8 @@ namespace INTERP_KERNEL
             else
               {
                 sonNodalConn[0]=nodalConn[sonId];
-                sonNodalConn[1]=nodalConn[(sonId+1)%lgth];
-                sonNodalConn[2]=nodalConn[sonId+lgth];
+                sonNodalConn[1]=nodalConn[(sonId+1)%(lgth/2)];
+                sonNodalConn[2]=nodalConn[sonId+(lgth/2)];
                 return 3;
               }
           }
index e75a2e5f47c6adc2f02db8b3ec8be2fdd0589d55..a8d02a3b5ac47b03c5baefabea86b30c203b009f 100644 (file)
@@ -1009,7 +1009,7 @@ void ExprParser::compileX86_64LowLev(std::vector<std::string>& ass) const
 void LeafExprVal::compileX86(std::vector<std::string>& ass) const
 {
   ass.push_back("sub esp,8");
-  int *b=(int *)&_value,*c=(int *)&_value;
+  const int *b=reinterpret_cast<const int *>(&_value),*c=reinterpret_cast<const int *>(&_value);
   c++;
   std::ostringstream oss;
   oss << std::hex;
@@ -1025,7 +1025,7 @@ void LeafExprVal::compileX86(std::vector<std::string>& ass) const
 void LeafExprVal::compileX86_64(std::vector<std::string>& ass) const
 {
   ass.push_back("sub rsp,8");
-  int *b=(int *)&_value,*c=(int *)&_value;
+  const int *b=reinterpret_cast<const int *>(&_value),*c=reinterpret_cast<const int *>(&_value);
   c++;
   std::ostringstream oss;
   oss << std::hex;
index c8e4d5b8dc19b752b0648d6321efe2244f5f1071..6e4f13e7b0fbce0157cfa5374c8ba782f378714a 100644 (file)
@@ -37,6 +37,18 @@ const char SinFunction::REPR[]="sin";
 
 const char TanFunction::REPR[]="tan";
 
+const char ACosFunction::REPR[]="acos";
+
+const char ASinFunction::REPR[]="asin";
+
+const char ATanFunction::REPR[]="atan";
+
+const char CoshFunction::REPR[]="cosh";
+
+const char SinhFunction::REPR[]="sinh";
+
+const char TanhFunction::REPR[]="tanh";
+
 const char SqrtFunction::REPR[]="sqrt";
 
 const char AbsFunction::REPR[]="abs";
@@ -95,6 +107,18 @@ Function *FunctionsFactory::buildUnaryFuncFromString(const char *type) throw(INT
     return new SinFunction;
   if(tmp==TanFunction::REPR)
     return new TanFunction;
+  if(tmp==ACosFunction::REPR)
+    return new ACosFunction;
+  if(tmp==ASinFunction::REPR)
+    return new ASinFunction;
+  if(tmp==ATanFunction::REPR)
+    return new ATanFunction;
+  if(tmp==CoshFunction::REPR)
+    return new CoshFunction;
+  if(tmp==SinhFunction::REPR)
+    return new SinhFunction;
+  if(tmp==TanhFunction::REPR)
+    return new TanhFunction;
   if(tmp==SqrtFunction::REPR)
     return new SqrtFunction;
   if(tmp==AbsFunction::REPR)
@@ -312,6 +336,156 @@ bool TanFunction::isACall() const
   return true;
 }
 
+ACosFunction::~ACosFunction()
+{
+}
+
+void ACosFunction::operate(std::vector<Value *>& stack) const throw(INTERP_KERNEL::Exception)
+{
+  Value *val=stack.back();
+  val->acos();
+}
+
+void ACosFunction::operateX86(std::vector<std::string>& asmb) const throw(INTERP_KERNEL::Exception)
+{
+  throw INTERP_KERNEL::Exception("Assembly Not implemented yet !");
+}
+
+const char *ACosFunction::getRepr() const
+{
+  return REPR;
+}
+
+bool ACosFunction::isACall() const
+{
+  return true;
+}
+
+ASinFunction::~ASinFunction()
+{
+}
+
+void ASinFunction::operate(std::vector<Value *>& stack) const throw(INTERP_KERNEL::Exception)
+{
+  Value *val=stack.back();
+  val->asin();
+}
+
+void ASinFunction::operateX86(std::vector<std::string>& asmb) const throw(INTERP_KERNEL::Exception)
+{
+  throw INTERP_KERNEL::Exception("Assembly Not implemented yet !");
+}
+
+const char *ASinFunction::getRepr() const
+{
+  return REPR;
+}
+
+bool ASinFunction::isACall() const
+{
+  return true;
+}
+
+ATanFunction::~ATanFunction()
+{
+}
+
+void ATanFunction::operate(std::vector<Value *>& stack) const throw(INTERP_KERNEL::Exception)
+{
+  Value *val=stack.back();
+  val->atan();
+}
+
+void ATanFunction::operateX86(std::vector<std::string>& asmb) const throw(INTERP_KERNEL::Exception)
+{
+  throw INTERP_KERNEL::Exception("Assembly Not implemented yet !");
+}
+
+const char *ATanFunction::getRepr() const
+{
+  return REPR;
+}
+
+bool ATanFunction::isACall() const
+{
+  return true;
+}
+
+CoshFunction::~CoshFunction()
+{
+}
+
+void CoshFunction::operate(std::vector<Value *>& stack) const throw(INTERP_KERNEL::Exception)
+{
+  Value *val=stack.back();
+  val->cosh();
+}
+
+void CoshFunction::operateX86(std::vector<std::string>& asmb) const throw(INTERP_KERNEL::Exception)
+{
+  throw INTERP_KERNEL::Exception("Assembly Not implemented yet !");
+}
+
+const char *CoshFunction::getRepr() const
+{
+  return REPR;
+}
+
+bool CoshFunction::isACall() const
+{
+  return true;
+}
+
+SinhFunction::~SinhFunction()
+{
+}
+
+void SinhFunction::operate(std::vector<Value *>& stack) const throw(INTERP_KERNEL::Exception)
+{
+  Value *val=stack.back();
+  val->sinh();
+}
+
+void SinhFunction::operateX86(std::vector<std::string>& asmb) const throw(INTERP_KERNEL::Exception)
+{
+  throw INTERP_KERNEL::Exception("Assembly Not implemented yet !");
+}
+
+const char *SinhFunction::getRepr() const
+{
+  return REPR;
+}
+
+bool SinhFunction::isACall() const
+{
+  return true;
+}
+
+TanhFunction::~TanhFunction()
+{
+}
+
+void TanhFunction::operate(std::vector<Value *>& stack) const throw(INTERP_KERNEL::Exception)
+{
+  Value *val=stack.back();
+  val->tanh();
+}
+
+void TanhFunction::operateX86(std::vector<std::string>& asmb) const throw(INTERP_KERNEL::Exception)
+{
+  throw INTERP_KERNEL::Exception("Assembly Not implemented yet !");
+}
+
+const char *TanhFunction::getRepr() const
+{
+  return REPR;
+}
+
+bool TanhFunction::isACall() const
+{
+  return true;
+}
+
 SqrtFunction::~SqrtFunction()
 {
 }
index f49c7594303c42938b811afe329a78610ecfe7f7..b63382683c4b7894984ee70d27f8cfb216644fea 100644 (file)
@@ -131,6 +131,78 @@ namespace INTERP_KERNEL
     static const char REPR[];
   };
 
+  class INTERPKERNEL_EXPORT ACosFunction : public UnaryFunction
+  {
+  public:
+    ~ACosFunction();
+    void operate(std::vector<Value *>& stack) const throw(INTERP_KERNEL::Exception);
+    void operateX86(std::vector<std::string>& asmb) const throw(INTERP_KERNEL::Exception);
+    const char *getRepr() const;
+    bool isACall() const;
+  public:
+    static const char REPR[];
+  };
+
+  class INTERPKERNEL_EXPORT ASinFunction : public UnaryFunction
+  {
+  public:
+    ~ASinFunction();
+    void operate(std::vector<Value *>& stack) const throw(INTERP_KERNEL::Exception);
+    void operateX86(std::vector<std::string>& asmb) const throw(INTERP_KERNEL::Exception);
+    const char *getRepr() const;
+    bool isACall() const;
+  public:
+    static const char REPR[];
+  };
+
+  class INTERPKERNEL_EXPORT ATanFunction : public UnaryFunction
+  {
+  public:
+    ~ATanFunction();
+    void operate(std::vector<Value *>& stack) const throw(INTERP_KERNEL::Exception);
+    void operateX86(std::vector<std::string>& asmb) const throw(INTERP_KERNEL::Exception);
+    const char *getRepr() const;
+    bool isACall() const;
+  public:
+    static const char REPR[];
+  };
+
+  class INTERPKERNEL_EXPORT CoshFunction : public UnaryFunction
+  {
+  public:
+    ~CoshFunction();
+    void operate(std::vector<Value *>& stack) const throw(INTERP_KERNEL::Exception);
+    void operateX86(std::vector<std::string>& asmb) const throw(INTERP_KERNEL::Exception);
+    const char *getRepr() const;
+    bool isACall() const;
+  public:
+    static const char REPR[];
+  };
+
+  class INTERPKERNEL_EXPORT SinhFunction : public UnaryFunction
+  {
+  public:
+    ~SinhFunction();
+    void operate(std::vector<Value *>& stack) const throw(INTERP_KERNEL::Exception);
+    void operateX86(std::vector<std::string>& asmb) const throw(INTERP_KERNEL::Exception);
+    const char *getRepr() const;
+    bool isACall() const;
+  public:
+    static const char REPR[];
+  };
+
+  class INTERPKERNEL_EXPORT TanhFunction : public UnaryFunction
+  {
+  public:
+    ~TanhFunction();
+    void operate(std::vector<Value *>& stack) const throw(INTERP_KERNEL::Exception);
+    void operateX86(std::vector<std::string>& asmb) const throw(INTERP_KERNEL::Exception);
+    const char *getRepr() const;
+    bool isACall() const;
+  public:
+    static const char REPR[];
+  };
+
   class INTERPKERNEL_EXPORT SqrtFunction : public UnaryFunction
   {
   public:
index 6564cfd252f78c6ae4207949cd156471016f3413..3a24ef6da5154512a1d3f2e1b514914429e7cd84 100644 (file)
@@ -80,6 +80,36 @@ void ValueDouble::tan() throw(INTERP_KERNEL::Exception)
   _data=std::tan(_data);
 }
 
+void ValueDouble::acos() throw(INTERP_KERNEL::Exception)
+{
+  _data=std::acos(_data);
+}
+
+void ValueDouble::asin() throw(INTERP_KERNEL::Exception)
+{
+  _data=std::asin(_data);
+}
+
+void ValueDouble::atan() throw(INTERP_KERNEL::Exception)
+{
+  _data=std::atan(_data);
+}
+
+void ValueDouble::cosh() throw(INTERP_KERNEL::Exception)
+{
+  _data=std::cosh(_data);
+}
+
+void ValueDouble::sinh() throw(INTERP_KERNEL::Exception)
+{
+  _data=std::sinh(_data);
+}
+
+void ValueDouble::tanh() throw(INTERP_KERNEL::Exception)
+{
+  _data=std::tanh(_data);
+}
+
 void ValueDouble::abs() throw(INTERP_KERNEL::Exception)
 {
   if(_data<0.)
@@ -229,6 +259,36 @@ void ValueUnit::tan() throw(INTERP_KERNEL::Exception)
   unsupportedOp(TanFunction::REPR);
 }
 
+void ValueUnit::acos() throw(INTERP_KERNEL::Exception)
+{
+  unsupportedOp(ACosFunction::REPR);
+}
+
+void ValueUnit::asin() throw(INTERP_KERNEL::Exception)
+{
+  unsupportedOp(ASinFunction::REPR);
+}
+
+void ValueUnit::atan() throw(INTERP_KERNEL::Exception)
+{
+  unsupportedOp(ATanFunction::REPR);
+}
+
+void ValueUnit::cosh() throw(INTERP_KERNEL::Exception)
+{
+  unsupportedOp(CoshFunction::REPR);
+}
+
+void ValueUnit::sinh() throw(INTERP_KERNEL::Exception)
+{
+  unsupportedOp(SinhFunction::REPR);
+}
+
+void ValueUnit::tanh() throw(INTERP_KERNEL::Exception)
+{
+  unsupportedOp(TanhFunction::REPR);
+}
+
 void ValueUnit::abs() throw(INTERP_KERNEL::Exception)
 {
   unsupportedOp(AbsFunction::REPR);
@@ -395,6 +455,48 @@ void ValueDoubleExpr::tan() throw(INTERP_KERNEL::Exception)
   std::transform(_dest_data,_dest_data+_sz_dest_data,_dest_data,std::ptr_fun<double,double>(std::tan));
 }
 
+void ValueDoubleExpr::acos() throw(INTERP_KERNEL::Exception)
+{
+  double *it=std::find_if(_dest_data,_dest_data+_sz_dest_data,std::bind2nd(std::less<double>(),-1.));
+  if(it!=_dest_data+_sz_dest_data)
+    throw INTERP_KERNEL::Exception("Trying to apply acos on < 1. value !");
+  it=std::find_if(_dest_data,_dest_data+_sz_dest_data,std::bind2nd(std::greater<double>(),1.));
+  if(it!=_dest_data+_sz_dest_data)
+    throw INTERP_KERNEL::Exception("Trying to apply acos on > 1. value !");
+  std::transform(_dest_data,_dest_data+_sz_dest_data,_dest_data,std::ptr_fun<double,double>(std::acos));
+}
+
+void ValueDoubleExpr::asin() throw(INTERP_KERNEL::Exception)
+{
+   double *it=std::find_if(_dest_data,_dest_data+_sz_dest_data,std::bind2nd(std::less<double>(),-1.));
+   if(it!=_dest_data+_sz_dest_data)
+    throw INTERP_KERNEL::Exception("Trying to apply asin on < 1. value !");
+  it=std::find_if(_dest_data,_dest_data+_sz_dest_data,std::bind2nd(std::greater<double>(),1.));
+  if(it!=_dest_data+_sz_dest_data)
+    throw INTERP_KERNEL::Exception("Trying to apply asin on > 1. value !");
+  std::transform(_dest_data,_dest_data+_sz_dest_data,_dest_data,std::ptr_fun<double,double>(std::asin));
+}
+
+void ValueDoubleExpr::atan() throw(INTERP_KERNEL::Exception)
+{
+  std::transform(_dest_data,_dest_data+_sz_dest_data,_dest_data,std::ptr_fun<double,double>(std::atan));
+}
+
+void ValueDoubleExpr::cosh() throw(INTERP_KERNEL::Exception)
+{
+  std::transform(_dest_data,_dest_data+_sz_dest_data,_dest_data,std::ptr_fun<double,double>(std::cosh));
+}
+
+void ValueDoubleExpr::sinh() throw(INTERP_KERNEL::Exception)
+{
+  std::transform(_dest_data,_dest_data+_sz_dest_data,_dest_data,std::ptr_fun<double,double>(std::sinh));
+}
+
+void ValueDoubleExpr::tanh() throw(INTERP_KERNEL::Exception)
+{
+  std::transform(_dest_data,_dest_data+_sz_dest_data,_dest_data,std::ptr_fun<double,double>(std::tanh));
+}
+
 void ValueDoubleExpr::abs() throw(INTERP_KERNEL::Exception)
 {
   std::transform(_dest_data,_dest_data+_sz_dest_data,_dest_data,std::ptr_fun<double,double>(fabs));
index 71d5bf0f07727efab5a87609bd740d11d3e1de03..36c484b04bd6841b456236eb25b20d60b1b56b2b 100644 (file)
@@ -41,6 +41,12 @@ namespace INTERP_KERNEL
     virtual void cos() throw(INTERP_KERNEL::Exception) = 0;
     virtual void sin() throw(INTERP_KERNEL::Exception) = 0;
     virtual void tan() throw(INTERP_KERNEL::Exception) = 0;
+    virtual void acos() throw(INTERP_KERNEL::Exception) = 0;
+    virtual void asin() throw(INTERP_KERNEL::Exception) = 0;
+    virtual void atan() throw(INTERP_KERNEL::Exception) = 0;
+    virtual void cosh() throw(INTERP_KERNEL::Exception) = 0;
+    virtual void sinh() throw(INTERP_KERNEL::Exception) = 0;
+    virtual void tanh() throw(INTERP_KERNEL::Exception) = 0;
     virtual void abs() throw(INTERP_KERNEL::Exception) = 0;
     virtual void exp() throw(INTERP_KERNEL::Exception) = 0;
     virtual void ln() throw(INTERP_KERNEL::Exception) = 0;
@@ -74,6 +80,12 @@ namespace INTERP_KERNEL
     void cos() throw(INTERP_KERNEL::Exception);
     void sin() throw(INTERP_KERNEL::Exception);
     void tan() throw(INTERP_KERNEL::Exception);
+    void acos() throw(INTERP_KERNEL::Exception);
+    void asin() throw(INTERP_KERNEL::Exception);
+    void atan() throw(INTERP_KERNEL::Exception);
+    void cosh() throw(INTERP_KERNEL::Exception);
+    void sinh() throw(INTERP_KERNEL::Exception);
+    void tanh() throw(INTERP_KERNEL::Exception);
     void abs() throw(INTERP_KERNEL::Exception);
     void exp() throw(INTERP_KERNEL::Exception);
     void ln() throw(INTERP_KERNEL::Exception);
@@ -112,6 +124,12 @@ namespace INTERP_KERNEL
     void cos() throw(INTERP_KERNEL::Exception);
     void sin() throw(INTERP_KERNEL::Exception);
     void tan() throw(INTERP_KERNEL::Exception);
+    void acos() throw(INTERP_KERNEL::Exception);
+    void asin() throw(INTERP_KERNEL::Exception);
+    void atan() throw(INTERP_KERNEL::Exception);
+    void cosh() throw(INTERP_KERNEL::Exception);
+    void sinh() throw(INTERP_KERNEL::Exception);
+    void tanh() throw(INTERP_KERNEL::Exception);
     void abs() throw(INTERP_KERNEL::Exception);
     void exp() throw(INTERP_KERNEL::Exception);
     void ln() throw(INTERP_KERNEL::Exception);
@@ -152,6 +170,12 @@ namespace INTERP_KERNEL
     void cos() throw(INTERP_KERNEL::Exception);
     void sin() throw(INTERP_KERNEL::Exception);
     void tan() throw(INTERP_KERNEL::Exception);
+    void acos() throw(INTERP_KERNEL::Exception);
+    void asin() throw(INTERP_KERNEL::Exception);
+    void atan() throw(INTERP_KERNEL::Exception);
+    void cosh() throw(INTERP_KERNEL::Exception);
+    void sinh() throw(INTERP_KERNEL::Exception);
+    void tanh() throw(INTERP_KERNEL::Exception);
     void abs() throw(INTERP_KERNEL::Exception);
     void exp() throw(INTERP_KERNEL::Exception);
     void ln() throw(INTERP_KERNEL::Exception);
index 57e9c936aea16eeba53c0f24320cb1297f2a6371..0fa9d7b5acde60717db21bbc867748548e7bf597 100644 (file)
@@ -359,7 +359,7 @@ void GaussInfo::initLocalInfo() throw (INTERP_KERNEL::Exception)
 
       if(!aSatify)
         {
-          hexa8aInit();
+          hexa8bInit();
           aSatify = isSatisfy();
           CHECK_MACRO;
         }
@@ -373,7 +373,7 @@ void GaussInfo::initLocalInfo() throw (INTERP_KERNEL::Exception)
 
       if(!aSatify)
         {
-          hexa20aInit();
+          hexa20bInit();
           aSatify = isSatisfy();
           CHECK_MACRO;
         }
index ed800c1b89e217706e60e87e4c20405eeeb53cf2..960ce5183a3cab1fca1989bcdea55b87dd4ab7b5 100644 (file)
@@ -136,6 +136,21 @@ void ComposedEdge::initLocations() const
     (*iter)->initLocations();
 }
 
+void ComposedEdge::initLocationsWithOther(const ComposedEdge& other) const
+{
+  std::set<Edge *> s1,s2;
+  for(std::list<ElementaryEdge *>::const_iterator it1=_sub_edges.begin();it1!=_sub_edges.end();it1++)
+    s1.insert((*it1)->getPtr());
+  for(std::list<ElementaryEdge *>::const_iterator it2=other._sub_edges.begin();it2!=other._sub_edges.end();it2++)
+    s2.insert((*it2)->getPtr());
+  initLocations();
+  other.initLocations();
+  std::vector<Edge *> s3;
+  std::set_intersection(s1.begin(),s1.end(),s2.begin(),s2.end(),std::back_insert_iterator< std::vector<Edge *> >(s3));
+  for(std::vector<Edge *>::const_iterator it3=s3.begin();it3!=s3.end();it3++)
+    (*it3)->declareOn();
+}
+
 ComposedEdge *ComposedEdge::clone() const
 {
   return new ComposedEdge(*this);
@@ -256,6 +271,8 @@ void ComposedEdge::unApplyGlobalSimilarityExt(ComposedEdge& other, double xBary,
     (*iter)->unApplySimilarity(xBary,yBary,fact);
   for(std::list<ElementaryEdge *>::iterator iter=_sub_edges.begin();iter!=_sub_edges.end();iter++)
     (*iter)->unApplySimilarity(xBary,yBary,fact);
+  for(std::list<ElementaryEdge *>::iterator iter=other._sub_edges.begin();iter!=other._sub_edges.end();iter++)
+    (*iter)->unApplySimilarity(xBary,yBary,fact);
 }
 
 double ComposedEdge::normalizeExt(ComposedEdge *other, double& xBary, double& yBary)
index 8fbf7bd2e8932a7091b6eac2dd782c5085d3f762..e3bf49f182f9a2301225169236dfd6962e544919 100644 (file)
@@ -50,6 +50,7 @@ namespace INTERP_KERNEL
     bool presenceOfOn() const;
     bool presenceOfQuadraticEdge() const;
     void initLocations() const;
+    void initLocationsWithOther(const ComposedEdge& other) const;
     ComposedEdge *clone() const;
     bool isNodeIn(Node *n) const;
     double getArea() const;
index 66e3a9b500825da1c5ae4623120714184a03f6c1..b0ee4f1c2a4aeb9426135812efa49fa48d375c01 100644 (file)
@@ -392,13 +392,37 @@ void QuadraticPolygon::appendSubEdgeFromCrudeDataArray(Edge *baseEdge, std::size
  */
 void QuadraticPolygon::buildFromCrudeDataArray2(const std::map<int,INTERP_KERNEL::Node *>& mapp, bool isQuad, const int *nodalBg, const double *coords, const int *descBg, const int *descEnd, const std::vector<std::vector<int> >& intersectEdges,
                                                 const INTERP_KERNEL::QuadraticPolygon& pol1, const int *descBg1, const int *descEnd1, const std::vector<std::vector<int> >& intersectEdges1,
-                                                const std::vector< std::vector<int> >& colinear1)
+                                                const std::vector< std::vector<int> >& colinear1,
+                                                std::map<int,std::vector<INTERP_KERNEL::ElementaryEdge *> >& alreadyExistingIn2)
 {
   std::size_t nbOfSeg=std::distance(descBg,descEnd);
   for(std::size_t i=0;i<nbOfSeg;i++)//loop over all edges of pol2
     {
       bool direct=descBg[i]>0;
       int edgeId=abs(descBg[i])-1;//current edge id of pol2
+      std::map<int,std::vector<INTERP_KERNEL::ElementaryEdge *> >::const_iterator it1=alreadyExistingIn2.find(descBg[i]),it2=alreadyExistingIn2.find(-descBg[i]);
+      if(it1!=alreadyExistingIn2.end() || it2!=alreadyExistingIn2.end())
+        {
+          bool sameDir=(it1!=alreadyExistingIn2.end());
+          const std::vector<INTERP_KERNEL::ElementaryEdge *>& edgesAlreadyBuilt=sameDir?(*it1).second:(*it2).second;
+          if(sameDir)
+            {
+              for(std::vector<INTERP_KERNEL::ElementaryEdge *>::const_iterator it3=edgesAlreadyBuilt.begin();it3!=edgesAlreadyBuilt.end();it3++)
+                {
+                  Edge *ee=(*it3)->getPtr(); ee->incrRef();
+                  pushBack(new ElementaryEdge(ee,(*it3)->getDirection()));
+                }
+            }
+          else
+            {
+              for(std::vector<INTERP_KERNEL::ElementaryEdge *>::const_reverse_iterator it4=edgesAlreadyBuilt.rbegin();it4!=edgesAlreadyBuilt.rend();it4++)
+                {
+                  Edge *ee=(*it4)->getPtr(); ee->incrRef();
+                  pushBack(new ElementaryEdge(ee,!(*it4)->getDirection()));
+                }
+            }
+          continue;
+        }
       bool directos=colinear1[edgeId].empty();
       std::vector<std::pair<int,std::pair<bool,int> > > idIns1;
       int offset1=0;
@@ -420,7 +444,14 @@ void QuadraticPolygon::buildFromCrudeDataArray2(const std::map<int,INTERP_KERNEL
         }
       if(directos)
         {//no subpart of edge 'edgeId' of pol2 is in pol1 so let's operate the same thing that QuadraticPolygon::buildFromCrudeDataArray method
+          std::size_t oldSz=_sub_edges.size();
           appendEdgeFromCrudeDataArray(i,mapp,isQuad,nodalBg,coords,descBg,descEnd,intersectEdges);
+          std::size_t newSz=_sub_edges.size();
+          std::size_t zeSz=newSz-oldSz;
+          alreadyExistingIn2[descBg[i]].resize(zeSz);
+          std::list<ElementaryEdge *>::const_reverse_iterator it5=_sub_edges.rbegin();
+          for(std::size_t p=0;p<zeSz;p++,it5++)
+            alreadyExistingIn2[descBg[i]][zeSz-p-1]=*it5;
         }
       else
         {//there is subpart of edge 'edgeId' of pol2 inside pol1
@@ -434,7 +465,7 @@ void QuadraticPolygon::buildFromCrudeDataArray2(const std::map<int,INTERP_KERNEL
               bool direct1;//store if needed the direction in 1
               int offset2;
               std::size_t nbOfSubEdges1;
-              for(std::vector<std::pair<int,std::pair<bool,int> > >::const_iterator it=idIns1.begin();it!=idIns1.end();it++)
+              for(std::vector<std::pair<int,std::pair<bool,int> > >::const_iterator it=idIns1.begin();it!=idIns1.end() && !found;it++)
                 {
                   int idIn1=(*it).first;//store if needed the cell id in 1
                   direct1=(*it).second.first;
@@ -459,15 +490,69 @@ void QuadraticPolygon::buildFromCrudeDataArray2(const std::map<int,INTERP_KERNEL
                   Node *end=(*mapp.find(idEnd)).second;
                   ElementaryEdge *e=ElementaryEdge::BuildEdgeFromCrudeDataArray(true,start,end);
                   pushBack(e);
+                  alreadyExistingIn2[descBg[i]].push_back(e);
                 }
               else
                 {//the current subedge of edge 'edgeId' of pol2 is part of the colinear edge 'idIn1' of pol1 -> reuse Edge instance of pol1
                   ElementaryEdge *e=pol1[offset1+(direct1?offset2:nbOfSubEdges1-offset2-1)];
                   Edge *ee=e->getPtr();
-                  ee->incrRef(); ee->declareOn();
-                  pushBack(new ElementaryEdge(ee,!(direct1^direction11)));
+                  ee->incrRef();
+                  ElementaryEdge *e2=new ElementaryEdge(ee,!(direct1^direction11));
+                  pushBack(e2);
+                  alreadyExistingIn2[descBg[i]].push_back(e2);
+                }
+            }
+        }
+    }
+}
+
+/*!
+ * Method expected to be called on pol2. Every params not suffixed by numbered are supposed to refer to pol2 (this).
+ */
+void QuadraticPolygon::updateLocOfEdgeFromCrudeDataArray2(const int *descBg, const int *descEnd, const std::vector<std::vector<int> >& intersectEdges, const INTERP_KERNEL::QuadraticPolygon& pol1, const int *descBg1, const int *descEnd1, const std::vector<std::vector<int> >& intersectEdges1, const std::vector< std::vector<int> >& colinear1) const
+{
+  std::size_t nbOfSeg=std::distance(descBg,descEnd);
+  for(std::size_t i=0;i<nbOfSeg;i++)//loop over all edges of pol2
+    {
+      bool direct=descBg[i]>0;
+      int edgeId=abs(descBg[i])-1;//current edge id of pol2
+      const std::vector<int>& c=colinear1[edgeId];
+      if(c.empty())
+        continue;
+      const std::vector<int>& subEdge=intersectEdges[edgeId];
+      std::size_t nbOfSubEdges=subEdge.size()/2;
+      //
+      std::size_t nbOfEdgesIn1=std::distance(descBg1,descEnd1);
+      int offset1=0;
+      for(std::size_t j=0;j<nbOfEdgesIn1;j++)
+        {
+          int edgeId1=abs(descBg1[j])-1;
+          if(std::find(c.begin(),c.end(),edgeId1)!=c.end())
+            {
+              for(std::size_t k=0;k<nbOfSubEdges;k++)
+                {
+                  int idBg=direct?subEdge[2*k]:subEdge[2*nbOfSubEdges-2*k-1];
+                  int idEnd=direct?subEdge[2*k+1]:subEdge[2*nbOfSubEdges-2*k-2];
+                  int idIn1=edgeId1;
+                  bool direct1=descBg1[j]>0;
+                  const std::vector<int>& subEdge1PossiblyAlreadyIn1=intersectEdges1[idIn1];
+                  std::size_t nbOfSubEdges1=subEdge1PossiblyAlreadyIn1.size()/2;
+                  int offset2=0;
+                  bool found=false;
+                  for(std::size_t kk=0;kk<nbOfSubEdges1 && !found;kk++)
+                    {
+                      found=(subEdge1PossiblyAlreadyIn1[2*kk]==idBg && subEdge1PossiblyAlreadyIn1[2*kk+1]==idEnd) || (subEdge1PossiblyAlreadyIn1[2*kk]==idEnd && subEdge1PossiblyAlreadyIn1[2*kk+1]==idBg);
+                      if(!found)
+                        offset2++;
+                    }
+                  if(found)
+                    {
+                      ElementaryEdge *e=pol1[offset1+(direct1?offset2:nbOfSubEdges1-offset2-1)];
+                      e->getPtr()->declareOn();
+                    }
                 }
             }
+          offset1+=intersectEdges1[edgeId1].size()/2;//offset1 is used to find the INTERP_KERNEL::Edge * instance into pol1 that will be part of edge into pol2
         }
     }
 }
@@ -505,17 +590,33 @@ void QuadraticPolygon::appendCrudeData(const std::map<INTERP_KERNEL::Node *,int>
 /*!
  * This method make the hypothesis that 'this' and 'other' are splited at the minimum into edges that are fully IN, OUT or ON.
  * This method returns newly created polygons in 'conn' and 'connI' and the corresponding ids ('idThis','idOther') are stored respectively into 'nbThis' and 'nbOther'.
+ * @param [in,out] edgesThis, parameter that keep informed the caller abount the edges in this not shared by the result of intersection of \a this with \a other
+ * @param [in,out] edgesBoundaryOther, parameter that strores all edges in result of intersection that are not 
  */
-void QuadraticPolygon::buildPartitionsAbs(QuadraticPolygon& other, const std::map<INTERP_KERNEL::Node *,int>& mapp, int idThis, int idOther, int offset, std::vector<double>& addCoordsQuadratic, std::vector<int>& conn, std::vector<int>& connI, std::vector<int>& nbThis, std::vector<int>& nbOther)
+void QuadraticPolygon::buildPartitionsAbs(QuadraticPolygon& other, std::set<INTERP_KERNEL::Edge *>& edgesThis, std::set<INTERP_KERNEL::Edge *>& edgesBoundaryOther, const std::map<INTERP_KERNEL::Node *,int>& mapp, int idThis, int idOther, int offset, std::vector<double>& addCoordsQuadratic, std::vector<int>& conn, std::vector<int>& connI, std::vector<int>& nbThis, std::vector<int>& nbOther)
 {
   double xBaryBB, yBaryBB;
   double fact=normalizeExt(&other, xBaryBB, yBaryBB);
   //Locate 'this' relative to 'other'
-  other.performLocatingOperation(*this);
+  other.performLocatingOperationSlow(*this);
   std::vector<QuadraticPolygon *> res=buildIntersectionPolygons(other,*this);
   for(std::vector<QuadraticPolygon *>::iterator it=res.begin();it!=res.end();it++)
     {
       (*it)->appendCrudeData(mapp,xBaryBB,yBaryBB,fact,offset,addCoordsQuadratic,conn,connI);
+      INTERP_KERNEL::IteratorOnComposedEdge it1(*it);
+      for(it1.first();!it1.finished();it1.next())
+        {
+          Edge *e=it1.current()->getPtr();
+          if(edgesThis.find(e)!=edgesThis.end())
+            edgesThis.erase(e);
+          else
+            {
+              if(edgesBoundaryOther.find(e)!=edgesBoundaryOther.end())
+                edgesBoundaryOther.erase(e);
+              else
+                edgesBoundaryOther.insert(e);
+            }
+        }
       nbThis.push_back(idThis);
       nbOther.push_back(idOther);
       delete *it;
@@ -796,6 +897,16 @@ void QuadraticPolygon::performLocatingOperation(QuadraticPolygon& pol2) const
     }
 }
 
+void QuadraticPolygon::performLocatingOperationSlow(QuadraticPolygon& pol2) const
+{
+  IteratorOnComposedEdge it(&pol2);
+  for(it.first();!it.finished();it.next())
+    {
+      ElementaryEdge *cur=it.current();
+      cur->locateFullyMySelfAbsolute(*this);
+    }
+}
+
 /*!
  * Given 2 polygons 'pol1' and 'pol2' (localized) the resulting polygons are returned.
  *
@@ -829,7 +940,7 @@ std::vector<QuadraticPolygon *> QuadraticPolygon::buildIntersectionPolygons(cons
 std::list<QuadraticPolygon *> QuadraticPolygon::zipConsecutiveInSegments() const
 {
   std::list<QuadraticPolygon *> ret;
-  IteratorOnComposedEdge it((ComposedEdge *)this);
+  IteratorOnComposedEdge it(const_cast<QuadraticPolygon *>(this));
   int nbOfTurns=recursiveSize();
   int i=0;
   if(!it.goToNextInOn(false,i,nbOfTurns))
@@ -990,3 +1101,121 @@ std::list<QuadraticPolygon *>::iterator QuadraticPolygon::CheckInList(Node *n, s
       return iter;
   return iEnd;
 }
+
+void QuadraticPolygon::ComputeResidual(const QuadraticPolygon& pol1, const std::set<Edge *>& notUsedInPol1, const std::set<Edge *>& edgesInPol2OnBoundary, const std::map<INTERP_KERNEL::Node *,int>& mapp, int offset, int idThis,
+                                       std::vector<double>& addCoordsQuadratic, std::vector<int>& conn, std::vector<int>& connI, std::vector<int>& nb1, std::vector<int>& nb2)
+{
+  pol1.initLocations();
+  for(std::set<Edge *>::const_iterator it=notUsedInPol1.begin();it!=notUsedInPol1.end();it++)
+    { (*it)->initLocs(); (*it)->declareOn(); }
+  for(std::set<Edge *>::const_iterator it=edgesInPol2OnBoundary.begin();it!=edgesInPol2OnBoundary.end();it++)
+    { (*it)->initLocs(); (*it)->declareIn(); }
+  ////
+  std::set<Edge *> notUsedInPol1L(notUsedInPol1);
+  IteratorOnComposedEdge it(const_cast<QuadraticPolygon *>(&pol1));
+  int sz=pol1.size();
+  std::list<QuadraticPolygon *> pol1Zip;
+  if(pol1.size()==(int)notUsedInPol1.size() && edgesInPol2OnBoundary.empty())
+    {
+      pol1.appendCrudeData(mapp,0.,0.,1.,offset,addCoordsQuadratic,conn,connI); nb1.push_back(idThis); nb2.push_back(-1);
+      return ;
+    }
+  while(!notUsedInPol1L.empty())
+    {
+      for(int i=0;i<sz && (it.current()->getStartNode()->getLoc()!=IN_1 || it.current()->getLoc()!=FULL_ON_1);i++)
+        it.nextLoop();
+      if(it.current()->getStartNode()->getLoc()!=IN_1 || it.current()->getLoc()!=FULL_ON_1)
+        throw INTERP_KERNEL::Exception("Presence of a target polygon fully included in source polygon ! The partition of this leads to a non simply connex cell (with hole) ! Impossible ! Such resulting cell cannot be stored in MED cell format !");
+      QuadraticPolygon *tmp1=new QuadraticPolygon;
+      do
+        {
+          Edge *ee=it.current()->getPtr();
+          if(ee->getLoc()==FULL_ON_1)
+            {
+              ee->incrRef(); notUsedInPol1L.erase(ee);
+              tmp1->pushBack(new ElementaryEdge(ee,it.current()->getDirection()));    
+            }
+          it.nextLoop();
+        }
+      while(it.current()->getStartNode()->getLoc()!=IN_1 && !notUsedInPol1L.empty());
+      pol1Zip.push_back(tmp1);
+    }
+  ////
+  std::list<QuadraticPolygon *> retPolsUnderContruction;
+  std::list<Edge *> edgesInPol2OnBoundaryL(edgesInPol2OnBoundary.begin(),edgesInPol2OnBoundary.end());
+  std::map<QuadraticPolygon *, std::list<QuadraticPolygon *> > pol1ZipConsumed;
+  while(!pol1Zip.empty() || !edgesInPol2OnBoundaryL.empty())
+    {
+      for(std::list<QuadraticPolygon *>::iterator it1=retPolsUnderContruction.begin();it1!=retPolsUnderContruction.end();)
+        {
+          if((*it1)->getStartNode()==(*it1)->getEndNode())
+            {
+              it1++;
+              continue;
+            }
+          Node *curN=(*it1)->getEndNode();
+          bool smthHappened=false;
+          for(std::list<Edge *>::iterator it2=edgesInPol2OnBoundaryL.begin();it2!=edgesInPol2OnBoundaryL.end();)
+            {
+              if(curN==(*it2)->getStartNode())
+                { (*it2)->incrRef(); (*it1)->pushBack(new ElementaryEdge(*it2,true)); curN=(*it2)->getEndNode(); smthHappened=true; it2=edgesInPol2OnBoundaryL.erase(it2); }
+              else if(curN==(*it2)->getEndNode())
+                { (*it2)->incrRef(); (*it1)->pushBack(new ElementaryEdge(*it2,false)); curN=(*it2)->getStartNode(); smthHappened=true; it2=edgesInPol2OnBoundaryL.erase(it2); }
+              else
+                it2++;
+            }
+          if(smthHappened)
+            {
+              for(std::list<QuadraticPolygon *>::iterator it3=pol1Zip.begin();it3!=pol1Zip.end();)
+                {
+                  if(curN==(*it3)->getStartNode())
+                    {
+                      for(std::list<ElementaryEdge *>::const_iterator it4=(*it3)->_sub_edges.begin();it4!=(*it3)->_sub_edges.end();it4++)
+                        { (*it4)->getPtr()->incrRef(); bool dir=(*it4)->getDirection(); (*it1)->pushBack(new ElementaryEdge((*it4)->getPtr(),dir)); }
+                      smthHappened=true;
+                      pol1ZipConsumed[*it1].push_back(*it3);
+                      curN=(*it3)->getEndNode();
+                      it3=pol1Zip.erase(it3);
+                    }
+                  else
+                    it3++;
+                }
+            }
+          if(!smthHappened)
+            {
+              for(std::list<ElementaryEdge *>::const_iterator it5=(*it1)->_sub_edges.begin();it5!=(*it1)->_sub_edges.end();it5++)
+                {
+                  Edge *ee=(*it5)->getPtr();
+                  if(edgesInPol2OnBoundary.find(ee)!=edgesInPol2OnBoundary.end())
+                    edgesInPol2OnBoundaryL.push_back(ee);
+                }
+              for(std::list<QuadraticPolygon *>::iterator it6=pol1ZipConsumed[*it1].begin();it6!=pol1ZipConsumed[*it1].end();it6++)
+                pol1Zip.push_front(*it6);
+              pol1ZipConsumed.erase(*it1);
+              delete *it1;
+              it1=retPolsUnderContruction.erase(it1);
+            }
+        }
+      if(!pol1Zip.empty())
+        {
+          QuadraticPolygon *tmp=new QuadraticPolygon;
+          QuadraticPolygon *first=*(pol1Zip.begin());
+          for(std::list<ElementaryEdge *>::const_iterator it4=first->_sub_edges.begin();it4!=first->_sub_edges.end();it4++)
+            { (*it4)->getPtr()->incrRef(); bool dir=(*it4)->getDirection(); tmp->pushBack(new ElementaryEdge((*it4)->getPtr(),dir)); }
+          pol1ZipConsumed[tmp].push_back(first);
+          retPolsUnderContruction.push_back(tmp);
+          pol1Zip.erase(pol1Zip.begin());
+        }
+    }
+  for(std::list<QuadraticPolygon *>::iterator it1=retPolsUnderContruction.begin();it1!=retPolsUnderContruction.end();it1++)
+    {
+      if((*it1)->getStartNode()==(*it1)->getEndNode())
+        {
+          (*it1)->appendCrudeData(mapp,0.,0.,1.,offset,addCoordsQuadratic,conn,connI); nb1.push_back(idThis); nb2.push_back(-1);
+          for(std::list<QuadraticPolygon *>::iterator it6=pol1ZipConsumed[*it1].begin();it6!=pol1ZipConsumed[*it1].end();it6++)
+            delete *it6;
+          delete *it1;
+          it1=retPolsUnderContruction.erase(it1);
+        }
+    }
+}
index d98b20dcdc68d8e7844941d1668777fd97092cb5..9f154aa2204ea372b9bf2e59058437e3ab34aa51 100644 (file)
@@ -62,12 +62,14 @@ namespace INTERP_KERNEL
                                  const int *descBg, const int *descEnd, const std::vector<std::vector<int> >& intersectEdges);
     void buildFromCrudeDataArray2(const std::map<int,INTERP_KERNEL::Node *>& mapp, bool isQuad, const int *nodalBg, const double *coords, const int *descBg, const int *descEnd, const std::vector<std::vector<int> >& intersectEdges,
                                   const INTERP_KERNEL::QuadraticPolygon& pol1, const int *descBg1, const int *descEnd1, const std::vector<std::vector<int> >& intersectEdges1,
-                                  const std::vector< std::vector<int> >& colinear1);
+                                  const std::vector< std::vector<int> >& colinear1,
+                                  std::map<int,std::vector<INTERP_KERNEL::ElementaryEdge *> >& alreadyExistingIn2);
+    void updateLocOfEdgeFromCrudeDataArray2(const int *descBg, const int *descEnd, const std::vector<std::vector<int> >& intersectEdges, const INTERP_KERNEL::QuadraticPolygon& pol1, const int *descBg1, const int *descEnd1, const std::vector<std::vector<int> >& intersectEdges1, const std::vector< std::vector<int> >& colinear1) const;
     void appendEdgeFromCrudeDataArray(std::size_t edgeId, const std::map<int,INTERP_KERNEL::Node *>& mapp, bool isQuad, const int *nodalBg, const double *coords,
                                       const int *descBg,  const int *descEnd, const std::vector<std::vector<int> >& intersectEdges);
     void appendSubEdgeFromCrudeDataArray(Edge *baseEdge, std::size_t j, bool direct, int edgeId, const std::vector<int>& subEdge, const std::map<int,INTERP_KERNEL::Node *>& mapp);
     void appendCrudeData(const std::map<INTERP_KERNEL::Node *,int>& mapp, double xBary, double yBary, double fact, int offset, std::vector<double>& addCoordsQuadratic, std::vector<int>& conn, std::vector<int>& connI) const;
-    void buildPartitionsAbs(QuadraticPolygon& other, const std::map<INTERP_KERNEL::Node *,int>& mapp, int idThis, int idOther, int offset,
+    void buildPartitionsAbs(QuadraticPolygon& other, std::set<INTERP_KERNEL::Edge *>& edgesThis, std::set<INTERP_KERNEL::Edge *>& edgesBoundaryOther, const std::map<INTERP_KERNEL::Node *,int>& mapp, int idThis, int idOther, int offset,
                             std::vector<double>& addCoordsQuadratic, std::vector<int>& conn, std::vector<int>& connI, std::vector<int>& nb1, std::vector<int>& nb2);
     //
     double intersectWith(const QuadraticPolygon& other) const;
@@ -78,9 +80,12 @@ namespace INTERP_KERNEL
     void intersectForPoint(const QuadraticPolygon& other, std::vector< int >& numberOfCreatedPointsPerEdge) const;
   public://Only public for tests reasons
     void performLocatingOperation(QuadraticPolygon& pol2) const;
+    void performLocatingOperationSlow(QuadraticPolygon& pol2) const;
     static void SplitPolygonsEachOther(QuadraticPolygon& pol1, QuadraticPolygon& pol2, int& nbOfSplits);
     std::vector<QuadraticPolygon *> buildIntersectionPolygons(const QuadraticPolygon& pol1, const QuadraticPolygon& pol2) const;
     bool amIAChanceToBeCompletedBy(const QuadraticPolygon& pol1Splitted, const QuadraticPolygon& pol2NotSplitted, bool& direction);
+    static void ComputeResidual(const QuadraticPolygon& pol1, const std::set<Edge *>& notUsedInPol1, const std::set<Edge *>& edgesInPol2OnBoundary, const std::map<INTERP_KERNEL::Node *,int>& mapp, int offset, int idThis,
+                                std::vector<double>& addCoordsQuadratic, std::vector<int>& conn, std::vector<int>& connI, std::vector<int>& nb1, std::vector<int>& nb2);
   protected:
     std::list<QuadraticPolygon *> zipConsecutiveInSegments() const;
     void dumpInXfigFile(std::ostream& stream, int resolution, const Bounds& box) const;
index b971d8978cbf282a5360446e5789f60f5e4de933..b780a5606d8f17def75324da1d132157b918ad2f 100644 (file)
@@ -92,15 +92,18 @@ namespace INTERP_KERNEL
         switch(InterpolationOptions::getIntersectionType())
           {
           case Triangulation:
-             intersector=new Polyhedron3D2DIntersectorP0P0<MyMeshType,MyMatrixType>(targetMesh,
-                                                                                    srcMesh,
-                                                                                    dimCaracteristic,
-                                                                                    getPrecision(),
-                                                                                    intersectFaces,
-                                                                                    getSplittingPolicy());
+            intersector=new Polyhedron3D2DIntersectorP0P0<MyMeshType,MyMatrixType>(targetMesh,
+                                                                                   srcMesh,
+                                                                                   dimCaracteristic,
+                                                                                   getPrecision(),
+                                                                                   intersectFaces,
+                                                                                   getSplittingPolicy());
+            break;
+          case PointLocator:
+            intersector=new PointLocator3DIntersectorP0P0<MyMeshType,MyMatrixType>(targetMesh,srcMesh,getPrecision());
             break;
           default:
-            throw INTERP_KERNEL::Exception("Invalid 3D intersection type for P0P0 interp specified : must be Triangulation.");
+            throw INTERP_KERNEL::Exception("Invalid 3D to 2D intersection type for P0P0 interp specified : must be Triangulation or PointLocator.");
           }
       }
     else
index 88bbc00a1cdb7ec43e721258f990081a642396de..e3c409592786a72ecb977181ee6cba1307819a9a 100644 (file)
@@ -39,7 +39,7 @@ namespace INTERP_KERNEL
 //     static const NumberingPolicy numPol=MyMeshType::My_numPol;
   public:
     InterpolationCC();
-    //InterpolationCC(const InterpolationOptions& io);
+    InterpolationCC(const InterpolationOptions& io);
     template<class MyMeshType, class MatrixType>
     int interpolateMeshes(const MyMeshType& srcMesh, const MyMeshType& targetMesh, MatrixType& result, const char *method);
 
index da4ec44f157227a147fabc34358d39243b7ad78e..84a9259865579d2d09af978ca9f8e4b40968ac11 100644 (file)
@@ -40,6 +40,10 @@ namespace INTERP_KERNEL
   {
   }
 
+  InterpolationCC::InterpolationCC(const InterpolationOptions& io):Interpolation<InterpolationCC>(io)
+  {
+  }
+
   //================================================================================
   /*!
    * \brief An 1D intersection result
index f9528e1857062d5e157a4e2e47fe87e1fe09aeaa..af2cf5fae4256fe33d9da473763fb394524edfbb 100644 (file)
@@ -148,7 +148,7 @@ namespace INTERP_KERNEL
         bool doItersect = true;
         for ( int j = 0; j < dim && doItersect; ++j )
           doItersect =
-            bb[j*2]   < src_coords[j][ src_nb_coords[0]-1 ] - eps &&
+            bb[j*2]   < src_coords[j][ src_nb_coords[j]-1 ] - eps &&
             bb[j*2+1] > src_coords[j][0] + eps;
         if ( !doItersect )
           continue; // no intersection
index 5c8ac1b6e19cc20d74ddc9f9c031f33d0e8247f6..0ca3f599e0efd5a33ffba1454701ea6735b7bd8e 100644 (file)
@@ -253,9 +253,9 @@ namespace INTERP_KERNEL
         // form standard base vector i
         const double b[3] = 
           {
-            int(i == 0),
-            int(i == 1),
-            int(i == 2)
+            double ( int(i == 0) ),
+            double ( int(i == 1) ),
+            double ( int(i == 2) ),
           };
 
         LOG(6,  "b = [" << b[0] << ", " << b[1] << ", " << b[2] << "]");
index b7ad4fdb568ed4a8afaa7859d4391dbde09daee9..c5973706805361c56cf960d17a2f1c4e1c007b72 100644 (file)
 #define __VOLSURFFORMULAE_HXX__
 
 #include "InterpolationUtils.hxx"
+#include "InterpKernelException.hxx"
+#include "InterpKernelGeo2DQuadraticPolygon.hxx"
 
+#include <sstream>
 #include <cmath>
 
 namespace INTERP_KERNEL
@@ -34,6 +37,9 @@ namespace INTERP_KERNEL
                                       int spaceDim);
 
 
+  inline double calculateAreaForQPolyg(const double **coords, int nbOfPtsInPolygs,
+                                       int spaceDim);
+
   inline double calculateLgthForSeg2(const double *p1, const double *p2, int spaceDim)
   {
     if(spaceDim==1)
@@ -199,6 +205,31 @@ namespace INTERP_KERNEL
     return ret;
   }
 
+  double calculateAreaForQPolyg(const double **coords, int nbOfPtsInPolygs, int spaceDim)
+  {
+    
+    if(nbOfPtsInPolygs%2==0)
+      {
+        if(spaceDim==2)
+          {
+            std::vector<Node *> nodes(nbOfPtsInPolygs);
+            for(int i=0;i<nbOfPtsInPolygs;i++)
+              nodes[i]=new Node(coords[i][0],coords[i][1]);
+            QuadraticPolygon *pol=QuadraticPolygon::BuildArcCirclePolygon(nodes);
+            double ret=pol->getArea();
+            delete pol;
+            return -ret;
+          }
+        else
+          return calculateAreaForPolyg(coords,nbOfPtsInPolygs/2,spaceDim);
+      }
+    else
+      {
+        std::ostringstream oss; oss << "INTERP_KERNEL::calculateAreaForQPolyg : nb of points in quadratic polygon is " << nbOfPtsInPolygs << " should be even !";
+        throw INTERP_KERNEL::Exception(oss.str().c_str());
+      }
+  }
+
   // ==========================
   // Calculate Volume for Tetra
   // ==========================
index 5e4f6129dc9015b689620ac97e65dcf6dd623855..adfb965529daf74ce558756d8e8f303962548a26 100644 (file)
@@ -42,8 +42,6 @@ namespace INTERP_KERNEL
           return INTERP_KERNEL::calculateLgthForSeg2(coords+(SPACEDIM*N1),coords+(SPACEDIM*N2),SPACEDIM);
         }
       case INTERP_KERNEL::NORM_TRI3 :
-      case INTERP_KERNEL::NORM_TRI6 :
-      case INTERP_KERNEL::NORM_TRI7 :
         {
           int N1 = OTT<ConnType,numPol>::coo2C(connec[0]);
           int N2 = OTT<ConnType,numPol>::coo2C(connec[1]);
@@ -56,9 +54,20 @@ namespace INTERP_KERNEL
         }
         break;
             
+      case INTERP_KERNEL::NORM_TRI6 :
+      case INTERP_KERNEL::NORM_TRI7 :
+        {
+          const double *pts[6];
+          pts[0] = coords+SPACEDIM*OTT<ConnType,numPol>::coo2C(connec[0]);
+          pts[1] = coords+SPACEDIM*OTT<ConnType,numPol>::coo2C(connec[1]);
+          pts[2] = coords+SPACEDIM*OTT<ConnType,numPol>::coo2C(connec[2]);
+          pts[3] = coords+SPACEDIM*OTT<ConnType,numPol>::coo2C(connec[3]);
+          pts[4] = coords+SPACEDIM*OTT<ConnType,numPol>::coo2C(connec[4]);
+          pts[5] = coords+SPACEDIM*OTT<ConnType,numPol>::coo2C(connec[5]);
+          return INTERP_KERNEL::calculateAreaForQPolyg(pts,6,SPACEDIM);
+        }
+        break;
       case INTERP_KERNEL::NORM_QUAD4 :
-      case INTERP_KERNEL::NORM_QUAD8 :
-      case INTERP_KERNEL::NORM_QUAD9 :
         {
           int N1 = OTT<ConnType,numPol>::coo2C(connec[0]);
           int N2 = OTT<ConnType,numPol>::coo2C(connec[1]);
@@ -72,7 +81,21 @@ namespace INTERP_KERNEL
                                                      SPACEDIM);
         }
         break;
-            
+      case INTERP_KERNEL::NORM_QUAD8 :
+      case INTERP_KERNEL::NORM_QUAD9 :  
+        {
+          const double *pts[8];
+          pts[0] = coords+SPACEDIM*OTT<ConnType,numPol>::coo2C(connec[0]);
+          pts[1] = coords+SPACEDIM*OTT<ConnType,numPol>::coo2C(connec[1]);
+          pts[2] = coords+SPACEDIM*OTT<ConnType,numPol>::coo2C(connec[2]);
+          pts[3] = coords+SPACEDIM*OTT<ConnType,numPol>::coo2C(connec[3]);
+          pts[4] = coords+SPACEDIM*OTT<ConnType,numPol>::coo2C(connec[4]);
+          pts[5] = coords+SPACEDIM*OTT<ConnType,numPol>::coo2C(connec[5]);
+          pts[6] = coords+SPACEDIM*OTT<ConnType,numPol>::coo2C(connec[6]);
+          pts[7] = coords+SPACEDIM*OTT<ConnType,numPol>::coo2C(connec[7]);
+          return INTERP_KERNEL::calculateAreaForQPolyg(pts,8,SPACEDIM);
+        }
+        break;
       case INTERP_KERNEL::NORM_POLYGON :
         {          
           const double **pts=new const double *[lgth];
@@ -83,6 +106,15 @@ namespace INTERP_KERNEL
           return val;
         }
         break;
+      case INTERP_KERNEL::NORM_QPOLYG :
+        {
+          const double **pts=new const double *[lgth];
+          for(int inod=0;inod<lgth;inod++)
+            pts[inod] = coords+SPACEDIM*OTT<ConnType,numPol>::coo2C(connec[inod]);
+          double val=INTERP_KERNEL::calculateAreaForQPolyg(pts,lgth,SPACEDIM);
+          delete [] pts;
+          return val;
+        }
       case INTERP_KERNEL::NORM_TETRA4 :
       case INTERP_KERNEL::NORM_TETRA10 :
         {
index a8b13882ec99cf977b4f594b227ab267553cf83b..64e07e045410103cc65fcde95bb31b3b9a76c1ab 100644 (file)
@@ -230,6 +230,9 @@ namespace INTERP_TEST
   void SingleElementPlanarTests::identicalSquares()
   {
     INTERP_KERNEL::PolygonAlgorithms<2> intersector (_Epsilon, _Precision);;
+    /*
+      ////////////////// TEST DESACTIVATED by A. GEAY because memory fault : 
+      // conditional jump INTERP_KERNEL::PolygonAlgorithms<2>::intersectConvexPolygons(double const*, double const*, int, int) (PolygonAlgorithms.txx:629)
     std::deque< double > actual_result = intersector.intersectConvexPolygons(_square1,_square1,4,4);
     std::deque< double > expected_result;
 
@@ -240,6 +243,7 @@ namespace INTERP_TEST
 
     CPPUNIT_ASSERT_MESSAGE("Identical squares test failed (CONVEX)", 
                            (INTERP_KERNEL::checkEqualPolygons<std::deque<double>,2>(&actual_result, &expected_result, _Epsilon)));
+    */
   }
   void SingleElementPlanarTests::identicalSquares_Triangulation()
   {
index 366d40ca67df25e9417fe3026c82c6e1d939e8f5..b4511ea1c7b11031f863bc38b679859f39f2b44c 100644 (file)
@@ -74,7 +74,7 @@ namespace INTERP_TEST
                                                       precision,
                                                       listOfTetraFacesTreated,
                                                       listOfTetraFacesColinear);
-
+    delete targetTetra;
     CPPUNIT_ASSERT_DOUBLES_EQUAL(40.,surface,precision);
 
     CPPUNIT_ASSERT_EQUAL(4,(int)listOfTetraFacesTreated.size());
@@ -120,7 +120,7 @@ namespace INTERP_TEST
                                                       precision,
                                                       listOfTetraFacesTreated,
                                                       listOfTetraFacesColinear);
-
+    delete targetTetra;
     CPPUNIT_ASSERT_DOUBLES_EQUAL(40.,surface,precision);
 
     CPPUNIT_ASSERT_EQUAL(4,(int)listOfTetraFacesTreated.size());
@@ -165,7 +165,7 @@ namespace INTERP_TEST
                                                       precision,
                                                       listOfTetraFacesTreated,
                                                       listOfTetraFacesColinear);
-
+    delete targetTetra;
     CPPUNIT_ASSERT_DOUBLES_EQUAL(2.5,surface,precision);
 
     CPPUNIT_ASSERT_EQUAL(0,(int)listOfTetraFacesTreated.size());
index 0fdffb561acf0eb2921055175bff28a92459066a..e3898153e711a363d5091c70d1a79e2db5ea6e81 100644 (file)
@@ -24,6 +24,7 @@ INCLUDE_DIRECTORIES(
   ${PTHREAD_INCLUDE_DIRS}
   ${XDR_INCLUDE_DIRS}
   ${KERNEL_ROOT_DIR}/include/salome
+  ${CMAKE_CURRENT_BINARY_DIR}/../..
   ${CMAKE_CURRENT_BINARY_DIR}/../../idl
   ${CMAKE_CURRENT_SOURCE_DIR}/../MEDMEM_I
   ${CMAKE_CURRENT_SOURCE_DIR}/../MEDMEM
index e2513eb99bb2fe38d6d47f377ebe1f4549d99af3..ad1c6fa2b4f20addc470ee3f5504e4168fd7bfe4 100644 (file)
@@ -21,6 +21,7 @@
 ADD_SUBDIRECTORY(Test)
 
 INCLUDE_DIRECTORIES(
+  ${CMAKE_CURRENT_BINARY_DIR}/../..
   ${CMAKE_CURRENT_SOURCE_DIR}/../INTERP_KERNEL
   ${CMAKE_CURRENT_SOURCE_DIR}/../INTERP_KERNEL/Bases
   ${CMAKE_CURRENT_SOURCE_DIR}/../INTERP_KERNEL/Geometric2D
index bd6233b93535f961bc25e89d36b22004632c7673..2276b4d28e2e46353802dc9c68cfe20b6f0407b7 100644 (file)
@@ -519,6 +519,8 @@ DataArrayDouble *MEDCouplingCMesh::getCoordsAt(int i) throw(INTERP_KERNEL::Excep
 
 void MEDCouplingCMesh::setCoordsAt(int i, const DataArrayDouble *arr) throw(INTERP_KERNEL::Exception)
 {
+  if(arr)
+    arr->checkNbOfComps(1,"MEDCouplingCMesh::setCoordsAt");
   DataArrayDouble **thisArr[3]={&_x_array,&_y_array,&_z_array};
   if(i<0 || i>2)
     throw INTERP_KERNEL::Exception("Invalid rank specified must be 0 or 1 or 2.");
@@ -535,6 +537,12 @@ void MEDCouplingCMesh::setCoordsAt(int i, const DataArrayDouble *arr) throw(INTE
 
 void MEDCouplingCMesh::setCoords(const DataArrayDouble *coordsX, const DataArrayDouble *coordsY, const DataArrayDouble *coordsZ)
 {
+  if(coordsX)
+    coordsX->checkNbOfComps(1,"MEDCouplingCMesh::setCoords : coordsX");
+  if(coordsY)
+    coordsY->checkNbOfComps(1,"MEDCouplingCMesh::setCoords : coordsY");
+  if(coordsZ)
+    coordsZ->checkNbOfComps(1,"MEDCouplingCMesh::setCoords : coordsZ");
   if(_x_array)
     _x_array->decrRef();
   _x_array=const_cast<DataArrayDouble *>(coordsX);
index 08eb6970b29e1744561a2adbefcf106d4d5c117a..805b4a7c595cadaf29bb122ea82bf394f2829c4a 100644 (file)
@@ -260,6 +260,13 @@ int MEDCouplingField::getGaussLocalizationIdOfOneType(INTERP_KERNEL::NormalizedC
   return _type->getGaussLocalizationIdOfOneType(type);
 }
 
+std::set<int> MEDCouplingField::getGaussLocalizationIdsOfOneType(INTERP_KERNEL::NormalizedCellType type) const throw(INTERP_KERNEL::Exception)
+{
+  if(!_mesh)
+    throw INTERP_KERNEL::Exception("Mesh has to be set before calling getGaussLocalizationIdsOfOneType method !");
+  return _type->getGaussLocalizationIdsOfOneType(type);
+}
+
 /*!
  * This method returns number of Gauss localization available. Implicitely all ids in [0,getNbOfGaussLocalization()) is a valid Gauss localisation id.
  * This method throws an exception if there is no mesh, invalid FieldDescription (different from Gauss)
index 439743ad56539c7b5265c3a6d946b30b33608686..69e6752ee7f4d15a61d9416dc46944c0a7a1659b 100644 (file)
@@ -65,6 +65,7 @@ namespace ParaMEDMEM
     DataArrayInt *computeTupleIdsToSelectFromCellIds(const int *startCellIds, const int *endCellIds) const;
     const MEDCouplingFieldDiscretization *getDiscretization() const { return _type; }
     MEDCouplingFieldDiscretization *getDiscretization() { return _type; }
+    void setDiscretization(MEDCouplingFieldDiscretization *newDisc) { _type=newDisc; }
     int getNumberOfTuplesExpected() const throw(INTERP_KERNEL::Exception);
     int getNumberOfMeshPlacesExpected() const throw(INTERP_KERNEL::Exception);
     // Gauss point specific methods
@@ -75,6 +76,7 @@ namespace ParaMEDMEM
     void clearGaussLocalizations();
     MEDCouplingGaussLocalization& getGaussLocalization(int locId) throw(INTERP_KERNEL::Exception);
     int getGaussLocalizationIdOfOneType(INTERP_KERNEL::NormalizedCellType type) const throw(INTERP_KERNEL::Exception);
+    std::set<int> getGaussLocalizationIdsOfOneType(INTERP_KERNEL::NormalizedCellType type) const throw(INTERP_KERNEL::Exception);
     int getNbOfGaussLocalization() const throw(INTERP_KERNEL::Exception);
     int getGaussLocalizationIdOfOneCell(int cellId) const throw(INTERP_KERNEL::Exception);
     void getCellIdsHavingGaussLocalization(int locId, std::vector<int>& cellIds) const throw(INTERP_KERNEL::Exception);
index 2739ca421baee04a9a10e8fda3d0d6a09ed36dd7..80b9d6a63177265ab2e73b3eaa2edfbdb5195a4e 100644 (file)
@@ -113,6 +113,14 @@ bool MEDCouplingFieldDiscretization::isEqualWithoutConsideringStr(const MEDCoupl
   return isEqual(other,eps);
 }
 
+/*!
+ * For all field discretization excepted GaussPts the [ \a startCellIds, \a endCellIds ) has no impact on the cloned instance.
+ */
+MEDCouplingFieldDiscretization *MEDCouplingFieldDiscretization::clonePart(const int *startCellIds, const int *endCellIds) const
+{
+  return clone();
+}
+
 /*!
  * Excepted for MEDCouplingFieldDiscretizationPerCell no underlying TimeLabel object : nothing to do in generally.
  */
@@ -281,16 +289,21 @@ int MEDCouplingFieldDiscretization::getGaussLocalizationIdOfOneType(INTERP_KERNE
   throw INTERP_KERNEL::Exception("Invalid method for the corresponding field discretization : available only for GaussPoint discretization !");
 }
 
+std::set<int> MEDCouplingFieldDiscretization::getGaussLocalizationIdsOfOneType(INTERP_KERNEL::NormalizedCellType type) const throw(INTERP_KERNEL::Exception)
+{
+  throw INTERP_KERNEL::Exception("Invalid method for the corresponding field discretization : available only for GaussPoint discretization !");
+}
+
 void MEDCouplingFieldDiscretization::getCellIdsHavingGaussLocalization(int locId, std::vector<int>& cellIds) const throw(INTERP_KERNEL::Exception)
 {
   throw INTERP_KERNEL::Exception("Invalid method for the corresponding field discretization : available only for GaussPoint discretization !");
 }
 
-void MEDCouplingFieldDiscretization::renumberEntitiesFromO2NArr(double eps, const int *old2NewPtr, DataArrayDouble *arr, const char *msg)
+void MEDCouplingFieldDiscretization::RenumberEntitiesFromO2NArr(double eps, const int *old2NewPtr, int newNbOfEntity, DataArrayDouble *arr, const char *msg)
 {
   int oldNbOfElems=arr->getNumberOfTuples();
   int nbOfComp=arr->getNumberOfComponents();
-  int newNbOfTuples=(*std::max_element(old2NewPtr,old2NewPtr+oldNbOfElems))+1;
+  int newNbOfTuples=newNbOfEntity;
   DataArrayDouble *arrCpy=arr->deepCpy();
   const double *ptSrc=arrCpy->getConstPointer();
   arr->reAlloc(newNbOfTuples);
@@ -324,7 +337,7 @@ void MEDCouplingFieldDiscretization::renumberEntitiesFromO2NArr(double eps, cons
   arrCpy->decrRef();
 }
 
-void MEDCouplingFieldDiscretization::renumberEntitiesFromN2OArr(const int *new2OldPtr, int new2OldSz, DataArrayDouble *arr, const char *msg)
+void MEDCouplingFieldDiscretization::RenumberEntitiesFromN2OArr(const int *new2OldPtr, int new2OldSz, DataArrayDouble *arr, const char *msg)
 {
   int nbOfComp=arr->getNumberOfComponents();
   DataArrayDouble *arrCpy=arr->deepCpy();
@@ -482,18 +495,18 @@ DataArrayDouble *MEDCouplingFieldDiscretizationP0::getValueOnMulti(const DataArr
 /*!
  * Nothing to do. It's not a bug.
  */
-void MEDCouplingFieldDiscretizationP0::renumberValuesOnNodes(double , const int *, DataArrayDouble *) const
+void MEDCouplingFieldDiscretizationP0::renumberValuesOnNodes(double , const int *, int newNbOfNodes, DataArrayDouble *) const
 {
 }
 
-void MEDCouplingFieldDiscretizationP0::renumberValuesOnCells(double epsOnVals, const MEDCouplingMesh *mesh, const int *old2New, DataArrayDouble *arr) const
+void MEDCouplingFieldDiscretizationP0::renumberValuesOnCells(double epsOnVals, const MEDCouplingMesh *mesh, const int *old2New, int newSz, DataArrayDouble *arr) const
 {
-  renumberEntitiesFromO2NArr(epsOnVals,old2New,arr,"Cell");
+  RenumberEntitiesFromO2NArr(epsOnVals,old2New,newSz,arr,"Cell");
 }
 
 void MEDCouplingFieldDiscretizationP0::renumberValuesOnCellsR(const MEDCouplingMesh *mesh, const int *new2old, int newSz, DataArrayDouble *arr) const
 {
-  renumberEntitiesFromN2OArr(new2old,newSz,arr,"Cell");
+  RenumberEntitiesFromN2OArr(new2old,newSz,arr,"Cell");
 }
 
 /*!
@@ -607,15 +620,15 @@ DataArrayInt *MEDCouplingFieldDiscretizationOnNodes::computeTupleIdsToSelectFrom
   return umesh2->computeFetchedNodeIds();
 }
 
-void MEDCouplingFieldDiscretizationOnNodes::renumberValuesOnNodes(double epsOnVals, const int *old2NewPtr, DataArrayDouble *arr) const
+void MEDCouplingFieldDiscretizationOnNodes::renumberValuesOnNodes(double epsOnVals, const int *old2NewPtr, int newNbOfNodes, DataArrayDouble *arr) const
 {
-  renumberEntitiesFromO2NArr(epsOnVals,old2NewPtr,arr,"Node");
+  RenumberEntitiesFromO2NArr(epsOnVals,old2NewPtr,newNbOfNodes,arr,"Node");
 }
 
 /*!
  * Nothing to do it's not a bug.
  */
-void MEDCouplingFieldDiscretizationOnNodes::renumberValuesOnCells(double epsOnVals, const MEDCouplingMesh *mesh, const int *old2New, DataArrayDouble *arr) const
+void MEDCouplingFieldDiscretizationOnNodes::renumberValuesOnCells(double epsOnVals, const MEDCouplingMesh *mesh, const int *old2New, int newSz, DataArrayDouble *arr) const
 {
 }
 
@@ -748,11 +761,16 @@ MEDCouplingFieldDiscretizationPerCell::~MEDCouplingFieldDiscretizationPerCell()
     _discr_per_cell->decrRef();
 }
 
-MEDCouplingFieldDiscretizationPerCell::MEDCouplingFieldDiscretizationPerCell(const MEDCouplingFieldDiscretizationPerCell& other):_discr_per_cell(0)
+MEDCouplingFieldDiscretizationPerCell::MEDCouplingFieldDiscretizationPerCell(const MEDCouplingFieldDiscretizationPerCell& other, const int *startCellIds, const int *endCellIds):_discr_per_cell(0)
 {
   DataArrayInt *arr=other._discr_per_cell;
   if(arr)
-    _discr_per_cell=arr->deepCpy();
+    {
+      if(startCellIds==0 && endCellIds==0)
+        _discr_per_cell=arr->deepCpy();
+      else
+        _discr_per_cell=arr->selectByTupleIdSafe(startCellIds,endCellIds);
+    }
 }
 
 void MEDCouplingFieldDiscretizationPerCell::updateTime() const
@@ -849,7 +867,7 @@ MEDCouplingFieldDiscretizationGauss::MEDCouplingFieldDiscretizationGauss()
 {
 }
 
-MEDCouplingFieldDiscretizationGauss::MEDCouplingFieldDiscretizationGauss(const MEDCouplingFieldDiscretizationGauss& other):MEDCouplingFieldDiscretizationPerCell(other),_loc(other._loc)
+MEDCouplingFieldDiscretizationGauss::MEDCouplingFieldDiscretizationGauss(const MEDCouplingFieldDiscretizationGauss& other, const int *startCellIds, const int *endCellIds):MEDCouplingFieldDiscretizationPerCell(other,startCellIds,endCellIds),_loc(other._loc)
 {
 }
 
@@ -905,6 +923,11 @@ MEDCouplingFieldDiscretization *MEDCouplingFieldDiscretizationGauss::clone() con
   return new MEDCouplingFieldDiscretizationGauss(*this);
 }
 
+MEDCouplingFieldDiscretization *MEDCouplingFieldDiscretizationGauss::clonePart(const int *startCellIds, const int *endCellIds) const
+{
+  return new MEDCouplingFieldDiscretizationGauss(*this,startCellIds,endCellIds);
+}
+
 std::string MEDCouplingFieldDiscretizationGauss::getStringRepr() const
 {
   std::ostringstream oss; oss << REPR << "." << std::endl;
@@ -951,13 +974,25 @@ int MEDCouplingFieldDiscretizationGauss::getNumberOfMeshPlaces(const MEDCoupling
 DataArrayInt *MEDCouplingFieldDiscretizationGauss::getOffsetArr(const MEDCouplingMesh *mesh) const
 {
   int nbOfTuples=mesh->getNumberOfCells();
-  DataArrayInt *ret=DataArrayInt::New();
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
   ret->alloc(nbOfTuples+1,1);
   int *retPtr=ret->getPointer();
   const int *start=_discr_per_cell->getConstPointer();
+  if(_discr_per_cell->getNumberOfTuples()!=nbOfTuples)
+    throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationGauss::getOffsetArr : mismatch between the mesh and the discretization ids array length !");
+  int maxPossible=(int)_loc.size();
   retPtr[0]=0;
   for(int i=0;i<nbOfTuples;i++,start++)
-    retPtr[i+1]=retPtr[i]+_loc[*start].getNumberOfGaussPt();
+    {
+      if(*start>=0 && *start<maxPossible)
+        retPtr[i+1]=retPtr[i]+_loc[*start].getNumberOfGaussPt();
+      else
+        {
+          std::ostringstream oss; oss << "MEDCouplingFieldDiscretizationGauss::getOffsetArr : At position #" << i << " the locid = " << *start << " whereas it should be in [0," << maxPossible << ") !";
+          throw INTERP_KERNEL::Exception(oss.str().c_str());
+        }
+    }
+  ret->incrRef();
   return ret;
 }
 
@@ -999,7 +1034,7 @@ DataArrayDouble *MEDCouplingFieldDiscretizationGauss::getLocalizationOfDiscValue
   DataArrayDouble *ret=DataArrayDouble::New();
   int spaceDim=mesh->getSpaceDimension();
   ret->alloc(nbOfTuples,spaceDim);
-  std::vector< std::vector<int> > locIds;
+  std::vector< int > locIds;
   std::vector<DataArrayInt *> parts=splitIntoSingleGaussDicrPerCellType(locIds);
   std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > parts2(parts.size());
   std::copy(parts.begin(),parts.end(),parts2.begin());
@@ -1013,21 +1048,17 @@ DataArrayDouble *MEDCouplingFieldDiscretizationGauss::getLocalizationOfDiscValue
   for(std::size_t i=0;i<parts2.size();i++)
     {
       INTERP_KERNEL::GaussCoords calculator;
-      for(std::vector<int>::const_iterator it=locIds[i].begin();it!=locIds[i].end();it++)
-        {
-          const MEDCouplingGaussLocalization& cli=_loc[*it];//curLocInfo
-          INTERP_KERNEL::NormalizedCellType typ=cli.getType();
-          const std::vector<double>& wg=cli.getWeights();
-          calculator.addGaussInfo(typ,INTERP_KERNEL::CellModel::GetCellModel(typ).getDimension(),
+      //
+      const MEDCouplingGaussLocalization& cli=_loc[locIds[i]];//curLocInfo
+      INTERP_KERNEL::NormalizedCellType typ=cli.getType();
+      const std::vector<double>& wg=cli.getWeights();
+      calculator.addGaussInfo(typ,INTERP_KERNEL::CellModel::GetCellModel(typ).getDimension(),
                                   &cli.getGaussCoords()[0],(int)wg.size(),&cli.getRefCoords()[0],
                                   INTERP_KERNEL::CellModel::GetCellModel(typ).getNumberOfNodes());
-        }
+      //
       int nbt=parts2[i]->getNumberOfTuples();
       for(const int *w=parts2[i]->getConstPointer();w!=parts2[i]->getConstPointer()+nbt;w++)
-        {
-          const MEDCouplingGaussLocalization& cli=_loc[*w];
-          calculator.calculateCoords(cli.getType(),coords,spaceDim,conn+connI[*w]+1,valsToFill+spaceDim*(ptrOffsets[*w]));
-        }
+        calculator.calculateCoords(cli.getType(),coords,spaceDim,conn+connI[*w]+1,valsToFill+spaceDim*(ptrOffsets[*w]));
     }
   ret->copyStringInfoFrom(*umesh->getCoords());
   return ret;
@@ -1196,7 +1227,7 @@ DataArrayInt *MEDCouplingFieldDiscretizationGauss::computeTupleIdsToSelectFromCe
   int *retPtr=nbOfNodesPerCell->getPointer();
   const int *pt=_discr_per_cell->getConstPointer();
   int nbMaxOfLocId=(int)_loc.size();
-  for(int i=0;i<nbOfCells;i++,retPtr++)
+  for(int i=0;i<nbOfCells;i++,retPtr++,pt++)
     {
       if(*pt>=0 && *pt<nbMaxOfLocId)
         *retPtr=_loc[*pt].getNumberOfGaussPt();
@@ -1209,11 +1240,11 @@ DataArrayInt *MEDCouplingFieldDiscretizationGauss::computeTupleIdsToSelectFromCe
 /*!
  * No implementation needed !
  */
-void MEDCouplingFieldDiscretizationGauss::renumberValuesOnNodes(double , const int *, DataArrayDouble *) const
+void MEDCouplingFieldDiscretizationGauss::renumberValuesOnNodes(double , const int *, int newNbOfNodes, DataArrayDouble *) const
 {
 }
 
-void MEDCouplingFieldDiscretizationGauss::renumberValuesOnCells(double epsOnVals, const MEDCouplingMesh *mesh, const int *old2New, DataArrayDouble *arr) const
+void MEDCouplingFieldDiscretizationGauss::renumberValuesOnCells(double epsOnVals, const MEDCouplingMesh *mesh, const int *old2New, int newSz, DataArrayDouble *arr) const
 {
   throw INTERP_KERNEL::Exception("Not implemented yet !");
 }
@@ -1303,6 +1334,16 @@ int MEDCouplingFieldDiscretizationGauss::getGaussLocalizationIdOfOneCell(int cel
 }
 
 int MEDCouplingFieldDiscretizationGauss::getGaussLocalizationIdOfOneType(INTERP_KERNEL::NormalizedCellType type) const throw(INTERP_KERNEL::Exception)
+{
+  std::set<int> ret=getGaussLocalizationIdsOfOneType(type);
+  if(ret.empty())
+    throw INTERP_KERNEL::Exception("No gauss discretization found for the specified type !");
+  if(ret.size()>1)
+    throw INTERP_KERNEL::Exception("Several gauss discretizations have been found for the specified type !");
+  return *ret.begin();
+}
+
+std::set<int> MEDCouplingFieldDiscretizationGauss::getGaussLocalizationIdsOfOneType(INTERP_KERNEL::NormalizedCellType type) const throw(INTERP_KERNEL::Exception)
 {
   if(!_discr_per_cell)
     throw INTERP_KERNEL::Exception("No Gauss localization still set !");
@@ -1311,11 +1352,7 @@ int MEDCouplingFieldDiscretizationGauss::getGaussLocalizationIdOfOneType(INTERP_
   for(std::vector<MEDCouplingGaussLocalization>::const_iterator iter=_loc.begin();iter!=_loc.end();iter++,id++)
     if((*iter).getType()==type)
       ret.insert(id);
-  if(ret.empty())
-    throw INTERP_KERNEL::Exception("No gauss discretization found for the specified type !");
-  if(ret.size()>1)
-    throw INTERP_KERNEL::Exception("Several gauss discretizations have been found for the specified type !");
-  return *ret.begin();
+  return ret;
 }
 
 void MEDCouplingFieldDiscretizationGauss::getCellIdsHavingGaussLocalization(int locId, std::vector<int>& cellIds) const throw(INTERP_KERNEL::Exception)
@@ -1383,8 +1420,8 @@ void MEDCouplingFieldDiscretizationGauss::zipGaussLocalizations()
 {
   const int *start=_discr_per_cell->getConstPointer();
   int nbOfTuples=_discr_per_cell->getNumberOfTuples();
-  int *tmp=new int[_loc.size()];
-  std::fill(tmp,tmp+_loc.size(),-2);
+  INTERP_KERNEL::AutoPtr<int> tmp=new int[_loc.size()];
+  std::fill((int *)tmp,(int *)tmp+_loc.size(),-2);
   for(const int *w=start;w!=start+nbOfTuples;w++)
     if(*w>=0)
       tmp[*w]=1;
@@ -1393,19 +1430,16 @@ void MEDCouplingFieldDiscretizationGauss::zipGaussLocalizations()
     if(tmp[i]!=-2)
       tmp[i]=fid++;
   if(fid==(int)_loc.size())
-    {//no zip needed
-      delete [] tmp;
-      return;
-    }
+    return;
   // zip needed
   int *start2=_discr_per_cell->getPointer();
   for(int *w2=start2;w2!=start2+nbOfTuples;w2++)
-    *w2=tmp[*w2];
+    if(*w2>=0)
+      *w2=tmp[*w2];
   std::vector<MEDCouplingGaussLocalization> tmpLoc;
   for(int i=0;i<(int)_loc.size();i++)
     if(tmp[i]!=-2)
       tmpLoc.push_back(_loc[tmp[i]]);
-  delete [] tmp;
   _loc=tmpLoc;
 }
 
@@ -1419,56 +1453,11 @@ void MEDCouplingFieldDiscretizationGauss::zipGaussLocalizations()
  * 
  * If no descretization is set in 'this' and exception will be thrown.
  */
-std::vector<DataArrayInt *> MEDCouplingFieldDiscretizationGauss::splitIntoSingleGaussDicrPerCellType(std::vector< std::vector<int> >& locIds) const throw(INTERP_KERNEL::Exception)
+std::vector<DataArrayInt *> MEDCouplingFieldDiscretizationGauss::splitIntoSingleGaussDicrPerCellType(std::vector<int>& locIds) const throw(INTERP_KERNEL::Exception)
 {
   if(!_discr_per_cell)
     throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationGauss::splitIntoSingleGaussDicrPerCellType : no descretization set !");
-  locIds.clear();
-  std::vector<DataArrayInt *> ret;
-  const int *discrPerCell=_discr_per_cell->getConstPointer();
-  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret2=_discr_per_cell->getIdsNotEqual(-1);
-  int nbOfTuplesSet=ret2->getNumberOfTuples();
-  std::list<int> idsRemaining(ret2->getConstPointer(),ret2->getConstPointer()+nbOfTuplesSet);
-  std::list<int>::iterator it=idsRemaining.begin();
-  while(it!=idsRemaining.end())
-    {
-      std::vector<int> ids;
-      std::set<int> curLocIds;
-      std::set<INTERP_KERNEL::NormalizedCellType> curCellTypes;
-      while(it!=idsRemaining.end())
-        {
-          int curDiscrId=discrPerCell[*it];
-          INTERP_KERNEL::NormalizedCellType typ=_loc[curDiscrId].getType();
-          if(curCellTypes.find(typ)!=curCellTypes.end())
-            {
-              if(curLocIds.find(curDiscrId)!=curLocIds.end())
-                {
-                  curLocIds.insert(curDiscrId);
-                  curCellTypes.insert(typ);
-                  ids.push_back(*it);
-                  it=idsRemaining.erase(it);
-                }
-              else
-                it++;
-            }
-          else
-            {
-              curLocIds.insert(curDiscrId);
-              curCellTypes.insert(typ);
-              ids.push_back(*it);
-              it=idsRemaining.erase(it);
-            }
-        }
-      it=idsRemaining.begin();
-      ret.resize(ret.size()+1);
-      DataArrayInt *part=DataArrayInt::New();
-      part->alloc((int)ids.size(),1);
-      std::copy(ids.begin(),ids.end(),part->getPointer());
-      ret.back()=part;
-      locIds.resize(locIds.size()+1);
-      locIds.back().insert(locIds.back().end(),curLocIds.begin(),curLocIds.end());
-    }
-  return ret;
+  return _discr_per_cell->partitionByDifferentValues(locIds);
 }
 
 MEDCouplingFieldDiscretizationGaussNE::MEDCouplingFieldDiscretizationGaussNE()
@@ -1661,11 +1650,11 @@ DataArrayInt *MEDCouplingFieldDiscretizationGaussNE::computeTupleIdsToSelectFrom
 /*!
  * No implementation needed !
  */
-void MEDCouplingFieldDiscretizationGaussNE::renumberValuesOnNodes(double , const int *, DataArrayDouble *) const
+void MEDCouplingFieldDiscretizationGaussNE::renumberValuesOnNodes(double , const int *, int newNbOfNodes, DataArrayDouble *) const
 {
 }
 
-void MEDCouplingFieldDiscretizationGaussNE::renumberValuesOnCells(double epsOnVals, const MEDCouplingMesh *mesh, const int *old2New, DataArrayDouble *arr) const
+void MEDCouplingFieldDiscretizationGaussNE::renumberValuesOnCells(double epsOnVals, const MEDCouplingMesh *mesh, const int *old2New, int newSz, DataArrayDouble *arr) const
 {
   throw INTERP_KERNEL::Exception("Not implemented yet !");
 }
@@ -1774,7 +1763,7 @@ DataArrayDouble *MEDCouplingFieldDiscretizationKriging::computeVectorOfCoefficie
 {
   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> coords=getLocalizationOfDiscValues(mesh);
   int nbOfPts=coords->getNumberOfTuples();
-  int dimension=coords->getNumberOfComponents();
+  //int dimension=coords->getNumberOfComponents();
   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> matrix=coords->buildEuclidianDistanceDenseMatrix();
   operateOnDenseMatrix(mesh->getSpaceDimension(),nbOfPts*nbOfPts,matrix->getPointer());
   // Drift
index df43d95277b35b88f76c16117cd50c163994f8c5..6efe4aae111377fbae9ca47eb5e6fd28137e0838 100644 (file)
@@ -29,6 +29,7 @@
 #include "MEDCouplingGaussLocalization.hxx"
 #include "MEDCouplingAutoRefCountObjectPtr.hxx"
 
+#include <set>
 #include <vector>
 
 namespace ParaMEDMEM
@@ -51,6 +52,7 @@ namespace ParaMEDMEM
     virtual bool isEqualIfNotWhy(const MEDCouplingFieldDiscretization *other, double eps, std::string& reason) const = 0;
     virtual bool isEqualWithoutConsideringStr(const MEDCouplingFieldDiscretization *other, double eps) const;
     virtual MEDCouplingFieldDiscretization *clone() const = 0;
+    virtual MEDCouplingFieldDiscretization *clonePart(const int *startCellIds, const int *endCellIds) const;
     virtual std::string getStringRepr() const = 0;
     virtual const char *getRepr() const = 0;
     virtual int getNumberOfTuples(const MEDCouplingMesh *mesh) const = 0;
@@ -74,8 +76,8 @@ namespace ParaMEDMEM
     virtual DataArrayDouble *getValueOnMulti(const DataArrayDouble *arr, const MEDCouplingMesh *mesh, const double *loc, int nbOfPoints) const = 0;
     virtual DataArrayInt *computeTupleIdsToSelectFromCellIds(const MEDCouplingMesh *mesh, const int *startCellIds, const int *endCellIds) const = 0;
     virtual MEDCouplingMesh *buildSubMeshData(const MEDCouplingMesh *mesh, const int *start, const int *end, DataArrayInt *&di) const = 0;
-    virtual void renumberValuesOnNodes(double epsOnVals, const int *old2New, DataArrayDouble *arr) const = 0;
-    virtual void renumberValuesOnCells(double epsOnVals, const MEDCouplingMesh *mesh, const int *old2New, DataArrayDouble *arr) const = 0;
+    virtual void renumberValuesOnNodes(double epsOnVals, const int *old2New, int newNbOfNodes, DataArrayDouble *arr) const = 0;
+    virtual void renumberValuesOnCells(double epsOnVals, const MEDCouplingMesh *mesh, const int *old2New, int newSz, DataArrayDouble *arr) const = 0;
     virtual void renumberValuesOnCellsR(const MEDCouplingMesh *mesh, const int *new2old, int newSz, DataArrayDouble *arr) const = 0;
     virtual void getSerializationIntArray(DataArrayInt *& arr) const;
     virtual void getTinySerializationIntInformation(std::vector<int>& tinyInfo) const;
@@ -91,13 +93,14 @@ namespace ParaMEDMEM
     virtual int getNbOfGaussLocalization() const throw(INTERP_KERNEL::Exception);
     virtual int getGaussLocalizationIdOfOneCell(int cellId) const throw(INTERP_KERNEL::Exception);
     virtual int getGaussLocalizationIdOfOneType(INTERP_KERNEL::NormalizedCellType type) const throw(INTERP_KERNEL::Exception);
+    virtual std::set<int> getGaussLocalizationIdsOfOneType(INTERP_KERNEL::NormalizedCellType type) const throw(INTERP_KERNEL::Exception);
     virtual void getCellIdsHavingGaussLocalization(int locId, std::vector<int>& cellIds) const throw(INTERP_KERNEL::Exception);
     virtual const MEDCouplingGaussLocalization& getGaussLocalization(int locId) const throw(INTERP_KERNEL::Exception);
     virtual ~MEDCouplingFieldDiscretization();
   protected:
     MEDCouplingFieldDiscretization();
-    static void renumberEntitiesFromO2NArr(double epsOnVals, const int *old2NewPtr, DataArrayDouble *arr, const char *msg);
-    static void renumberEntitiesFromN2OArr(const int *new2OldPtr, int new2OldSz, DataArrayDouble *arr, const char *msg);
+    static void RenumberEntitiesFromO2NArr(double epsOnVals, const int *old2NewPtr, int newNbOfEntity, DataArrayDouble *arr, const char *msg);
+    static void RenumberEntitiesFromN2OArr(const int *new2OldPtr, int new2OldSz, DataArrayDouble *arr, const char *msg);
   protected:
     double _precision;
     static const double DFLT_PRECISION;
@@ -125,8 +128,8 @@ namespace ParaMEDMEM
     void getValueOn(const DataArrayDouble *arr, const MEDCouplingMesh *mesh, const double *loc, double *res) const;
     void getValueOnPos(const DataArrayDouble *arr, const MEDCouplingMesh *mesh, int i, int j, int k, double *res) const;
     DataArrayDouble *getValueOnMulti(const DataArrayDouble *arr, const MEDCouplingMesh *mesh, const double *loc, int nbOfPoints) const;
-    void renumberValuesOnNodes(double epsOnVals, const int *old2New, DataArrayDouble *arr) const;
-    void renumberValuesOnCells(double epsOnVals, const MEDCouplingMesh *mesh, const int *old2New, DataArrayDouble *arr) const;
+    void renumberValuesOnNodes(double epsOnVals, const int *old2New, int newNbOfNodes, DataArrayDouble *arr) const;
+    void renumberValuesOnCells(double epsOnVals, const MEDCouplingMesh *mesh, const int *old2New, int newSz, DataArrayDouble *arr) const;
     void renumberValuesOnCellsR(const MEDCouplingMesh *mesh, const int *new2old, int newSz, DataArrayDouble *arr) const;
     MEDCouplingMesh *buildSubMeshData(const MEDCouplingMesh *mesh, const int *start, const int *end, DataArrayInt *&di) const;
     DataArrayInt *computeTupleIdsToSelectFromCellIds(const MEDCouplingMesh *mesh, const int *startCellIds, const int *endCellIds) const;
@@ -149,8 +152,8 @@ namespace ParaMEDMEM
     void checkCoherencyBetween(const MEDCouplingMesh *mesh, const DataArrayDouble *da) const throw(INTERP_KERNEL::Exception);
     MEDCouplingMesh *buildSubMeshData(const MEDCouplingMesh *mesh, const int *start, const int *end, DataArrayInt *&di) const;
     DataArrayInt *computeTupleIdsToSelectFromCellIds(const MEDCouplingMesh *mesh, const int *startCellIds, const int *endCellIds) const;
-    void renumberValuesOnNodes(double epsOnVals, const int *old2New, DataArrayDouble *arr) const;
-    void renumberValuesOnCells(double epsOnVals, const MEDCouplingMesh *mesh, const int *old2New, DataArrayDouble *arr) const;
+    void renumberValuesOnNodes(double epsOnVals, const int *old2New, int newNbOfNodes, DataArrayDouble *arr) const;
+    void renumberValuesOnCells(double epsOnVals, const MEDCouplingMesh *mesh, const int *old2New, int newSz, DataArrayDouble *arr) const;
     void renumberValuesOnCellsR(const MEDCouplingMesh *mesh, const int *new2old, int newSz, DataArrayDouble *arr) const;
   public:
     void getValueOnPos(const DataArrayDouble *arr, const MEDCouplingMesh *mesh, int i, int j, int k, double *res) const;
@@ -185,7 +188,7 @@ namespace ParaMEDMEM
     const DataArrayInt *getArrayOfDiscIds() const;
   protected:
     MEDCouplingFieldDiscretizationPerCell();
-    MEDCouplingFieldDiscretizationPerCell(const MEDCouplingFieldDiscretizationPerCell& other);
+    MEDCouplingFieldDiscretizationPerCell(const MEDCouplingFieldDiscretizationPerCell& other, const int *startCellIds, const int *endCellIds);
     ~MEDCouplingFieldDiscretizationPerCell();
     void updateTime() const;
     void checkCoherencyBetween(const MEDCouplingMesh *mesh, const DataArrayDouble *da) const throw(INTERP_KERNEL::Exception);
@@ -208,6 +211,7 @@ namespace ParaMEDMEM
     bool isEqualIfNotWhy(const MEDCouplingFieldDiscretization *other, double eps, std::string& reason) const;
     bool isEqualWithoutConsideringStr(const MEDCouplingFieldDiscretization *other, double eps) const;
     MEDCouplingFieldDiscretization *clone() const;
+    MEDCouplingFieldDiscretization *clonePart(const int *startCellIds, const int *endCellIds) const;
     std::string getStringRepr() const;
     const char *getRepr() const;
     int getNumberOfTuples(const MEDCouplingMesh *mesh) const;
@@ -232,8 +236,8 @@ namespace ParaMEDMEM
     DataArrayDouble *getValueOnMulti(const DataArrayDouble *arr, const MEDCouplingMesh *mesh, const double *loc, int nbOfPoints) const;
     MEDCouplingMesh *buildSubMeshData(const MEDCouplingMesh *mesh, const int *start, const int *end, DataArrayInt *&di) const;
     DataArrayInt *computeTupleIdsToSelectFromCellIds(const MEDCouplingMesh *mesh, const int *startCellIds, const int *endCellIds) const;
-    void renumberValuesOnNodes(double epsOnVals, const int *old2New, DataArrayDouble *arr) const;
-    void renumberValuesOnCells(double epsOnVals, const MEDCouplingMesh *mesh, const int *old2New, DataArrayDouble *arr) const;
+    void renumberValuesOnNodes(double epsOnVals, const int *old2New, int newNbOfNodes, DataArrayDouble *arr) const;
+    void renumberValuesOnCells(double epsOnVals, const MEDCouplingMesh *mesh, const int *old2New, int newSz, DataArrayDouble *arr) const;
     void renumberValuesOnCellsR(const MEDCouplingMesh *mesh, const int *new2old, int newSz, DataArrayDouble *arr) const;
     void setGaussLocalizationOnType(const MEDCouplingMesh *m, INTERP_KERNEL::NormalizedCellType type, const std::vector<double>& refCoo,
                                     const std::vector<double>& gsCoo, const std::vector<double>& wg) throw(INTERP_KERNEL::Exception);
@@ -244,12 +248,13 @@ namespace ParaMEDMEM
     int getNbOfGaussLocalization() const throw(INTERP_KERNEL::Exception);
     int getGaussLocalizationIdOfOneCell(int cellId) const throw(INTERP_KERNEL::Exception);
     int getGaussLocalizationIdOfOneType(INTERP_KERNEL::NormalizedCellType type) const throw(INTERP_KERNEL::Exception);
+    std::set<int> getGaussLocalizationIdsOfOneType(INTERP_KERNEL::NormalizedCellType type) const throw(INTERP_KERNEL::Exception);
     void getCellIdsHavingGaussLocalization(int locId, std::vector<int>& cellIds) const throw(INTERP_KERNEL::Exception);
     const MEDCouplingGaussLocalization& getGaussLocalization(int locId) const throw(INTERP_KERNEL::Exception);
-    std::vector<DataArrayInt *> splitIntoSingleGaussDicrPerCellType(std::vector< std::vector<int> >& locIds) const throw(INTERP_KERNEL::Exception);
+    std::vector<DataArrayInt *> splitIntoSingleGaussDicrPerCellType(std::vector< int >& locIds) const throw(INTERP_KERNEL::Exception);
     DataArrayInt *buildNbOfGaussPointPerCellField() const throw(INTERP_KERNEL::Exception);
   protected:
-    MEDCouplingFieldDiscretizationGauss(const MEDCouplingFieldDiscretizationGauss& other);
+    MEDCouplingFieldDiscretizationGauss(const MEDCouplingFieldDiscretizationGauss& other, const int *startCellIds=0, const int *endCellIds=0);
     void zipGaussLocalizations();
     int getOffsetOfCell(int cellId) const throw(INTERP_KERNEL::Exception);
     void checkLocalizationId(int locId) const throw(INTERP_KERNEL::Exception);
@@ -289,8 +294,8 @@ namespace ParaMEDMEM
     DataArrayDouble *getValueOnMulti(const DataArrayDouble *arr, const MEDCouplingMesh *mesh, const double *loc, int nbOfPoints) const;
     MEDCouplingMesh *buildSubMeshData(const MEDCouplingMesh *mesh, const int *start, const int *end, DataArrayInt *&di) const;
     DataArrayInt *computeTupleIdsToSelectFromCellIds(const MEDCouplingMesh *mesh, const int *startCellIds, const int *endCellIds) const;
-    void renumberValuesOnNodes(double epsOnVals, const int *old2New, DataArrayDouble *arr) const;
-    void renumberValuesOnCells(double epsOnVals, const MEDCouplingMesh *mesh, const int *old2New, DataArrayDouble *arr) const;
+    void renumberValuesOnNodes(double epsOnVals, const int *old2New, int newNbOfNodes, DataArrayDouble *arr) const;
+    void renumberValuesOnCells(double epsOnVals, const MEDCouplingMesh *mesh, const int *old2New, int newSz, DataArrayDouble *arr) const;
     void renumberValuesOnCellsR(const MEDCouplingMesh *mesh, const int *new2old, int newSz, DataArrayDouble *arr) const;
   protected:
     MEDCouplingFieldDiscretizationGaussNE(const MEDCouplingFieldDiscretizationGaussNE& other);
index 170cf2ecbbaf6b7ab4bbeb5ddb5c6d05a02e13b2..36c10e825a45c29781756d585d5a48db3bf53fb5 100644 (file)
@@ -345,8 +345,9 @@ void MEDCouplingFieldDouble::renumberNodes(const int *old2NewBg) throw(INTERP_KE
     throw INTERP_KERNEL::Exception("Invalid mesh to apply renumberNodes on it !");
   int nbOfNodes=meshC->getNumberOfNodes();
   MEDCouplingAutoRefCountObjectPtr<MEDCouplingPointSet> meshC2((MEDCouplingPointSet *)meshC->deepCpy());
-  renumberNodesWithoutMesh(old2NewBg);
-  meshC2->renumberNodes(old2NewBg,*std::max_element(old2NewBg,old2NewBg+nbOfNodes)+1);
+  int newNbOfNodes=*std::max_element(old2NewBg,old2NewBg+nbOfNodes)+1;
+  renumberNodesWithoutMesh(old2NewBg,newNbOfNodes);
+  meshC2->renumberNodes(old2NewBg,newNbOfNodes);
   setMesh(meshC2);
 }
 
@@ -355,13 +356,13 @@ void MEDCouplingFieldDouble::renumberNodes(const int *old2NewBg) throw(INTERP_KE
  * This method performs half job of MEDCouplingFieldDouble::renumberNodes. That is to say no permutation of cells is done on underlying mesh.
  * That is to say, the field content is changed by this method.
  */
-void MEDCouplingFieldDouble::renumberNodesWithoutMesh(const int *old2NewBg, double eps) throw(INTERP_KERNEL::Exception)
+void MEDCouplingFieldDouble::renumberNodesWithoutMesh(const int *old2NewBg, int newNbOfNodes, double eps) throw(INTERP_KERNEL::Exception)
 {
   std::vector<DataArrayDouble *> arrays;
   _time_discr->getArrays(arrays);
   for(std::vector<DataArrayDouble *>::const_iterator iter=arrays.begin();iter!=arrays.end();iter++)
     if(*iter)
-      _type->renumberValuesOnNodes(eps,old2NewBg,*iter);
+      _type->renumberValuesOnNodes(eps,old2NewBg,newNbOfNodes,*iter);
 }
 
 /*!
@@ -435,11 +436,13 @@ MEDCouplingFieldDouble *MEDCouplingFieldDouble::buildSubPart(const DataArrayInt
 MEDCouplingFieldDouble *MEDCouplingFieldDouble::buildSubPart(const int *partBg, const int *partEnd) const throw(INTERP_KERNEL::Exception)
 {
   DataArrayInt *arrSelect;
-  MEDCouplingMesh *m=_type->buildSubMeshData(_mesh,partBg,partEnd,arrSelect);
+  MEDCouplingAutoRefCountObjectPtr<MEDCouplingMesh> m=_type->buildSubMeshData(_mesh,partBg,partEnd,arrSelect);
   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> arrSelect2(arrSelect);
   MEDCouplingFieldDouble *ret=clone(false);//quick shallow copy.
+  const MEDCouplingFieldDiscretization *disc=getDiscretization();
+  if(disc)
+    ret->setDiscretization(disc->clonePart(partBg,partEnd));
   ret->setMesh(m);
-  m->decrRef();
   std::vector<DataArrayDouble *> arrays;
   _time_discr->getArrays(arrays);
   std::vector<DataArrayDouble *> arrs;
@@ -1196,18 +1199,13 @@ void MEDCouplingFieldDouble::changeUnderlyingMesh(const MEDCouplingMesh *other,
 {
   if(_mesh==0 || other==0)
     throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::changeUnderlyingMesh : is expected to operate on not null meshes !");
-  DataArrayInt *cellCor,*nodeCor;
+  DataArrayInt *cellCor=0,*nodeCor=0;
   other->checkGeoEquivalWith(_mesh,levOfCheck,prec,cellCor,nodeCor);
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellCor2(cellCor),nodeCor2(nodeCor);
   if(cellCor)
-    {
-      renumberCellsWithoutMesh(cellCor->getConstPointer(),false);
-      cellCor->decrRef();
-    }
+    renumberCellsWithoutMesh(cellCor->getConstPointer(),false);
   if(nodeCor)
-    {
-      renumberNodesWithoutMesh(nodeCor->getConstPointer());
-      nodeCor->decrRef();
-    }
+    renumberNodesWithoutMesh(nodeCor->getConstPointer(),_mesh->getNumberOfNodes());
   setMesh(const_cast<MEDCouplingMesh *>(other));
 }
 
@@ -1247,7 +1245,7 @@ bool MEDCouplingFieldDouble::mergeNodes(double eps, double epsOnVals) throw(INTE
   _time_discr->getArrays(arrays);
   for(std::vector<DataArrayDouble *>::const_iterator iter=arrays.begin();iter!=arrays.end();iter++)
     if(*iter)
-      _type->renumberValuesOnNodes(epsOnVals,arr->getConstPointer(),*iter);
+      _type->renumberValuesOnNodes(epsOnVals,arr->getConstPointer(),meshC2->getNumberOfNodes(),*iter);
   setMesh(meshC2);
   return true;
 }
@@ -1272,7 +1270,7 @@ bool MEDCouplingFieldDouble::mergeNodes2(double eps, double epsOnVals) throw(INT
   _time_discr->getArrays(arrays);
   for(std::vector<DataArrayDouble *>::const_iterator iter=arrays.begin();iter!=arrays.end();iter++)
     if(*iter)
-      _type->renumberValuesOnNodes(epsOnVals,arr->getConstPointer(),*iter);
+      _type->renumberValuesOnNodes(epsOnVals,arr->getConstPointer(),meshC2->getNumberOfNodes(),*iter);
   setMesh(meshC2);
   return true;
 }
@@ -1296,7 +1294,7 @@ bool MEDCouplingFieldDouble::zipCoords(double epsOnVals) throw(INTERP_KERNEL::Ex
       _time_discr->getArrays(arrays);
       for(std::vector<DataArrayDouble *>::const_iterator iter=arrays.begin();iter!=arrays.end();iter++)
         if(*iter)
-          _type->renumberValuesOnNodes(epsOnVals,arr->getConstPointer(),*iter);
+          _type->renumberValuesOnNodes(epsOnVals,arr->getConstPointer(),meshC2->getNumberOfNodes(),*iter);
       setMesh(meshC2);
       return true;
     }
@@ -1322,7 +1320,7 @@ bool MEDCouplingFieldDouble::zipConnectivity(int compType, double epsOnVals) thr
       _time_discr->getArrays(arrays);
       for(std::vector<DataArrayDouble *>::const_iterator iter=arrays.begin();iter!=arrays.end();iter++)
         if(*iter)
-          _type->renumberValuesOnCells(epsOnVals,meshC,arr->getConstPointer(),*iter);
+          _type->renumberValuesOnCells(epsOnVals,meshC,arr->getConstPointer(),meshC2->getNumberOfCells(),*iter);
       setMesh(meshC2);
       return true;
     }
index 3eac19dceb18b4e19d43a1960bc1eecc4dba57cc..45a553b6b7a9ecf3e494578c8dd3e907bdf6306a 100644 (file)
@@ -51,7 +51,7 @@ namespace ParaMEDMEM
     void renumberCells(const int *old2NewBg, bool check=true) throw(INTERP_KERNEL::Exception);
     void renumberCellsWithoutMesh(const int *old2NewBg, bool check=true) throw(INTERP_KERNEL::Exception);
     void renumberNodes(const int *old2NewBg) throw(INTERP_KERNEL::Exception);
-    void renumberNodesWithoutMesh(const int *old2NewBg, double eps=1e-15) throw(INTERP_KERNEL::Exception);
+    void renumberNodesWithoutMesh(const int *old2NewBg, int newNbOfNodes, double eps=1e-15) throw(INTERP_KERNEL::Exception);
     DataArrayInt *getIdsInRange(double vmin, double vmax) const throw(INTERP_KERNEL::Exception);
     MEDCouplingFieldDouble *buildSubPart(const DataArrayInt *part) const throw(INTERP_KERNEL::Exception);
     MEDCouplingFieldDouble *buildSubPart(const int *partBg, const int *partEnd) const throw(INTERP_KERNEL::Exception);
index a112e3edad4a4cce8654e2b2eb4a0e05711931ef..9081b8ecb6c24b03487835a280c3cd2b60e52323 100644 (file)
@@ -28,6 +28,7 @@
 #include <cmath>
 #include <limits>
 #include <numeric>
+#include <algorithm>
 #include <functional>
 
 typedef double (*MYFUNCPTR)(double);
@@ -68,10 +69,9 @@ void DataArrayDouble::findCommonTuplesAlg(const double *bbox, int nbNodes, int l
 }
 
 template<int SPACEDIM>
-void DataArrayDouble::findTupleIdsNearTuplesAlg(const BBTree<SPACEDIM,int>& myTree, const double *pos, int nbOfTuples, double eps,
-                                                std::vector<int>& c, std::vector<int>& cI) const
+void DataArrayDouble::FindTupleIdsNearTuplesAlg(const BBTree<SPACEDIM,int>& myTree, const double *pos, int nbOfTuples, double eps,
+                                                std::vector<int>& c, std::vector<int>& cI)
 {
-  const double *coordsPtr=getConstPointer();
   for(int i=0;i<nbOfTuples;i++)
     {
       std::vector<int> intersectingElems;
@@ -171,6 +171,13 @@ void DataArray::reprWithoutNameStream(std::ostream& stream) const
   stream << "\n";
 }
 
+std::string DataArray::cppRepr(const char *varName) const throw(INTERP_KERNEL::Exception)
+{
+  std::ostringstream ret;
+  reprCppStream(varName,ret);
+  return ret.str();
+}
+
 void DataArray::setInfoOnComponents(const std::vector<std::string>& info) throw(INTERP_KERNEL::Exception)
 {
   if(getNumberOfComponents()!=(int)info.size())
@@ -720,6 +727,24 @@ void DataArrayDouble::reprZipWithoutNameStream(std::ostream& stream) const
   _mem.reprZip(getNumberOfComponents(),stream);
 }
 
+void DataArrayDouble::reprCppStream(const char *varName, std::ostream& stream) const
+{
+  int nbTuples=getNumberOfTuples(),nbComp=getNumberOfComponents();
+  const double *data=getConstPointer();
+  stream.precision(17);
+  stream << "DataArrayDouble *" << varName << "=DataArrayDouble::New();" << std::endl;
+  if(nbTuples*nbComp>=1)
+    {
+      stream << "const double " << varName << "Data[" << nbTuples*nbComp << "]={";
+      std::copy(data,data+nbTuples*nbComp-1,std::ostream_iterator<double>(stream,","));
+      stream << data[nbTuples*nbComp-1] << "};" << std::endl;
+      stream << varName << "->useArray(" << varName << "Data,false,CPP_DEALLOC," << nbTuples << "," << nbComp << ");" << std::endl;
+    }
+  else
+    stream << varName << "->alloc(" << nbTuples << "," << nbComp << ");" << std::endl;
+  stream << varName << "->setName(\"" << getName() << "\");" << std::endl;
+}
+
 bool DataArrayDouble::isEqualIfNotWhy(const DataArrayDouble& other, double prec, std::string& reason) const
 {
   if(!areInfoEqualsIfNotWhy(other,reason))
@@ -1739,19 +1764,19 @@ void DataArrayDouble::computeTupleIdsNearTuples(const DataArrayDouble *other, do
     case 3:
       {
         BBTree<3,int> myTree(bbox->getConstPointer(),0,0,getNumberOfTuples(),eps/10);
-        findTupleIdsNearTuplesAlg<3>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,c,cI);
+        FindTupleIdsNearTuplesAlg<3>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,c,cI);
         break;
       }
     case 2:
       {
         BBTree<2,int> myTree(bbox->getConstPointer(),0,0,getNumberOfTuples(),eps/10);
-        findTupleIdsNearTuplesAlg<2>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,c,cI);
+        FindTupleIdsNearTuplesAlg<2>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,c,cI);
         break;
       }
     case 1:
       {
         BBTree<1,int> myTree(bbox->getConstPointer(),0,0,getNumberOfTuples(),eps/10);
-        findTupleIdsNearTuplesAlg<1>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,c,cI);
+        FindTupleIdsNearTuplesAlg<1>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,c,cI);
         break;
       }
     default:
@@ -3553,6 +3578,23 @@ void DataArrayInt::reprZipWithoutNameStream(std::ostream& stream) const
   _mem.reprZip(getNumberOfComponents(),stream);
 }
 
+void DataArrayInt::reprCppStream(const char *varName, std::ostream& stream) const
+{
+  int nbTuples=getNumberOfTuples(),nbComp=getNumberOfComponents();
+  const int *data=getConstPointer();
+  stream << "DataArrayInt *" << varName << "=DataArrayInt::New();" << std::endl;
+  if(nbTuples*nbComp>=1)
+    {
+      stream << "const int " << varName << "Data[" << nbTuples*nbComp << "]={";
+      std::copy(data,data+nbTuples*nbComp-1,std::ostream_iterator<int>(stream,","));
+      stream << data[nbTuples*nbComp-1] << "};" << std::endl;
+      stream << varName << "->useArray(" << varName << "Data,false,CPP_DEALLOC," << nbTuples << "," << nbComp << ");" << std::endl;
+    }
+  else
+    stream << varName << "->alloc(" << nbTuples << "," << nbComp << ");" << std::endl;
+  stream << varName << "->setName(\"" << getName() << "\");" << std::endl;
+}
+
 /*!
  * This method expects a number of components equal to 1.
  * This method sweeps all the values (tuples) in 'this' (it should be allocated) and for each value v is replaced by
@@ -3891,7 +3933,7 @@ DataArrayInt *DataArrayInt::renumberR(const int *new2Old) const
 }
 
 /*!
- * Idem DataArrayDouble::renumber method except that the number of tuples is reduced.
+ * Idem DataArrayInt::renumber method except that the number of tuples is reduced.
  * That is to say that it is expected that newNbOfTuple<this->getNumberOfTuples().
  * ['old2New','old2New'+getNumberOfTuples()) defines a range containing old to new array. For every negative value in ['old2NewBg','old2New'getNumberOfTuples()) the corresponding tuple is
  * omitted.
@@ -5468,6 +5510,30 @@ DataArrayInt *DataArrayInt::buildIntersection(const DataArrayInt *other) const t
   return BuildIntersection(arrs);
 }
 
+/*!
+ * This method can be applied on allocated with one component DataArrayInt instance.
+ * This method is typically relevant for sorted arrays. All consecutive duplicated items in \a this will appear only once in returned DataArrayInt instance.
+ * Example : if \a this contains [1,2,2,3,3,3,3,4,5,5,7,7,7,19] the returned array will contain [1,2,3,4,5,7,19]
+ * 
+ * \return a newly allocated array that contain the result of the unique operation applied on \a this.
+ * \throw if \a this is not allocated or if \a this has not exactly one component.
+ */
+DataArrayInt *DataArrayInt::buildUnique() const throw(INTERP_KERNEL::Exception)
+{
+  checkAllocated();
+  if(getNumberOfComponents()!=1)
+     throw INTERP_KERNEL::Exception("DataArrayInt::buildUnique : only single component allowed !");
+  int nbOfTuples=getNumberOfTuples();
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=deepCpy();
+  int *data=tmp->getPointer();
+  int *last=std::unique(data,data+nbOfTuples);
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
+  ret->alloc(std::distance(data,last),1);
+  std::copy(data,last,ret->getPointer());
+  ret->incrRef();
+  return ret;
+}
+
 /*!
  * This method could be usefull for returned DataArrayInt marked as index. Some methods that generate such DataArrayInt instances:
  * - ParaMEDMEM::MEDCouplingUMesh::buildDescendingConnectivity
@@ -5729,13 +5795,50 @@ DataArrayInt *DataArrayInt::duplicateEachTupleNTimes(int nbTimes) const throw(IN
 }
 
 /*!
- * This method returns all different values found in 'this'.
+ * This method returns all different values found in \a this. This method throws if \a this has not been allocated.
+ * But the number of components can be different from one.
  */
 std::set<int> DataArrayInt::getDifferentValues() const throw(INTERP_KERNEL::Exception)
 {
   checkAllocated();
   std::set<int> ret;
-  ret.insert(getConstPointer(),getConstPointer()+getNbOfElems());
+  ret.insert(begin(),end());
+  return ret;
+}
+
+/*!
+ * This method is a refinement of DataArrayInt::getDifferentValues because it returns not only different values in \a this but also, for each of
+ * them it tells which tuple id have this id.
+ * This method works only on arrays with one component (if it is not the case call DataArrayInt::rearrange(1) ).
+ * This method returns two arrays having same size.
+ * The instances of DataArrayInt in the returned vector have be specially allocated and computed by this method. Each of them should be dealt by the caller of this method.
+ * Example : if this is equal to [1,0,1,2,0,2,2,-3,2] -> differentIds=[-3,0,1,2] and returned array will be equal to [[7],[1,4],[0,2],[3,5,6,8]]
+ */
+std::vector<DataArrayInt *> DataArrayInt::partitionByDifferentValues(std::vector<int>& differentIds) const throw(INTERP_KERNEL::Exception)
+{
+  checkAllocated();
+  if(getNumberOfComponents()!=1)
+    throw INTERP_KERNEL::Exception("DataArrayInt::partitionByDifferentValues : this should have only one component !");
+  int id=0;
+  std::map<int,int> m,m2,m3;
+  for(const int *w=begin();w!=end();w++)
+    m[*w]++;
+  differentIds.resize(m.size());
+  std::vector<DataArrayInt *> ret(m.size());
+  std::vector<int *> retPtr(m.size());
+  for(std::map<int,int>::const_iterator it=m.begin();it!=m.end();it++,id++)
+    {
+      m2[(*it).first]=id;
+      ret[id]=DataArrayInt::New();
+      ret[id]->alloc((*it).second,1);
+      retPtr[id]=ret[id]->getPointer();
+      differentIds[id]=(*it).first;
+    }
+  id=0;
+  for(const int *w=begin();w!=end();w++,id++)
+    {
+      retPtr[m2[*w]][m3[*w]++]=id;
+    }
   return ret;
 }
 
index 675a563ec7afd27401713c0a79b56d0ad0b67f24..6b8b5853f6b0cbc2f33abc5343f06fe02080a61c 100644 (file)
@@ -98,6 +98,7 @@ namespace ParaMEDMEM
     MEDCOUPLING_EXPORT bool areInfoEqualsIfNotWhy(const DataArray& other, std::string& reason) const;
     MEDCOUPLING_EXPORT bool areInfoEquals(const DataArray& other) const;
     MEDCOUPLING_EXPORT void reprWithoutNameStream(std::ostream& stream) const;
+    MEDCOUPLING_EXPORT std::string cppRepr(const char *varName) const throw(INTERP_KERNEL::Exception);
     MEDCOUPLING_EXPORT std::string getName() const { return _name; }
     MEDCOUPLING_EXPORT const std::vector<std::string> &getInfoOnComponents() const { return _info_on_compo; }
     MEDCOUPLING_EXPORT std::vector<std::string> &getInfoOnComponents() { return _info_on_compo; }
@@ -112,8 +113,7 @@ namespace ParaMEDMEM
     MEDCOUPLING_EXPORT int getNumberOfTuples() const { return _nb_of_tuples; }
     MEDCOUPLING_EXPORT int getNbOfElems() const { return ((int)_info_on_compo.size())*_nb_of_tuples; }
     MEDCOUPLING_EXPORT void checkNbOfTuples(int nbOfTuples, const char *msg) const throw(INTERP_KERNEL::Exception);
-    MEDCOUPLING_EXPORT 
-void checkNbOfComps(int nbOfCompo, const char *msg) const throw(INTERP_KERNEL::Exception);
+    MEDCOUPLING_EXPORT void checkNbOfComps(int nbOfCompo, const char *msg) const throw(INTERP_KERNEL::Exception);
     MEDCOUPLING_EXPORT void checkNbOfTuplesAndComp(const DataArray& other, const char *msg) const throw(INTERP_KERNEL::Exception);
     MEDCOUPLING_EXPORT void checkNbOfTuplesAndComp(int nbOfTuples, int nbOfCompo, const char *msg) const throw(INTERP_KERNEL::Exception);
     MEDCOUPLING_EXPORT void checkNbOfElems(int nbOfElems, const char *msg) const throw(INTERP_KERNEL::Exception);
@@ -122,6 +122,7 @@ void checkNbOfComps(int nbOfCompo, const char *msg) const throw(INTERP_KERNEL::E
     MEDCOUPLING_EXPORT static int GetPosOfItemGivenBESRelativeNoThrow(int value, int begin, int end, int step) throw(INTERP_KERNEL::Exception);
     MEDCOUPLING_EXPORT static std::string GetVarNameFromInfo(const std::string& info) throw(INTERP_KERNEL::Exception);
     MEDCOUPLING_EXPORT static std::string GetUnitFromInfo(const std::string& info) throw(INTERP_KERNEL::Exception);
+    MEDCOUPLING_EXPORT virtual void reprCppStream(const char *varName, std::ostream& stream) const = 0;
   protected:
     DataArray():_nb_of_tuples(-1) { }
   protected:
@@ -170,6 +171,7 @@ namespace ParaMEDMEM
     MEDCOUPLING_EXPORT void reprZipStream(std::ostream& stream) const;
     MEDCOUPLING_EXPORT void reprWithoutNameStream(std::ostream& stream) const;
     MEDCOUPLING_EXPORT void reprZipWithoutNameStream(std::ostream& stream) const;
+    MEDCOUPLING_EXPORT void reprCppStream(const char *varName, std::ostream& stream) const;
     MEDCOUPLING_EXPORT bool isEqual(const DataArrayDouble& other, double prec) const;
     MEDCOUPLING_EXPORT bool isEqualIfNotWhy(const DataArrayDouble& other, double prec, std::string& reason) const;
     MEDCOUPLING_EXPORT bool isEqualWithoutConsideringStr(const DataArrayDouble& other, double prec) const;
@@ -292,8 +294,8 @@ namespace ParaMEDMEM
     template<int SPACEDIM>
     void findCommonTuplesAlg(const double *bbox, int nbNodes, int limitNodeId, double prec, std::vector<int>& c, std::vector<int>& cI) const;
     template<int SPACEDIM>
-    void findTupleIdsNearTuplesAlg(const BBTree<SPACEDIM,int>& myTree, const double *pos, int nbOfTuples, double eps,
-                                   std::vector<int>& c, std::vector<int>& cI) const;
+    static void FindTupleIdsNearTuplesAlg(const BBTree<SPACEDIM,int>& myTree, const double *pos, int nbOfTuples, double eps,
+                                          std::vector<int>& c, std::vector<int>& cI);
   private:
     DataArrayDouble() { }
   private:
@@ -365,6 +367,7 @@ namespace ParaMEDMEM
     MEDCOUPLING_EXPORT void reprZipStream(std::ostream& stream) const;
     MEDCOUPLING_EXPORT void reprWithoutNameStream(std::ostream& stream) const;
     MEDCOUPLING_EXPORT void reprZipWithoutNameStream(std::ostream& stream) const;
+    MEDCOUPLING_EXPORT void reprCppStream(const char *varName, std::ostream& stream) const;
     MEDCOUPLING_EXPORT void transformWithIndArr(const int *indArrBg, const int *indArrEnd) throw(INTERP_KERNEL::Exception);
     MEDCOUPLING_EXPORT DataArrayInt *transformWithIndArrR(const int *indArrBg, const int *indArrEnd) const throw(INTERP_KERNEL::Exception);
     MEDCOUPLING_EXPORT void splitByValueRange(const int *arrBg, const int *arrEnd,
@@ -455,6 +458,7 @@ namespace ParaMEDMEM
     MEDCOUPLING_EXPORT DataArrayInt *buildSubstraction(const DataArrayInt *other) const throw(INTERP_KERNEL::Exception);
     MEDCOUPLING_EXPORT DataArrayInt *buildUnion(const DataArrayInt *other) const throw(INTERP_KERNEL::Exception);
     MEDCOUPLING_EXPORT DataArrayInt *buildIntersection(const DataArrayInt *other) const throw(INTERP_KERNEL::Exception);
+    MEDCOUPLING_EXPORT DataArrayInt *buildUnique() const throw(INTERP_KERNEL::Exception);
     MEDCOUPLING_EXPORT DataArrayInt *deltaShiftIndex() const throw(INTERP_KERNEL::Exception);
     MEDCOUPLING_EXPORT void computeOffsets() throw(INTERP_KERNEL::Exception);
     MEDCOUPLING_EXPORT void computeOffsets2() throw(INTERP_KERNEL::Exception);
@@ -463,6 +467,7 @@ namespace ParaMEDMEM
     MEDCOUPLING_EXPORT DataArrayInt *findIdInRangeForEachTuple(const DataArrayInt *ranges) const throw(INTERP_KERNEL::Exception);
     MEDCOUPLING_EXPORT DataArrayInt *duplicateEachTupleNTimes(int nbTimes) const throw(INTERP_KERNEL::Exception);
     MEDCOUPLING_EXPORT std::set<int> getDifferentValues() const throw(INTERP_KERNEL::Exception);
+    MEDCOUPLING_EXPORT std::vector<DataArrayInt *> partitionByDifferentValues(std::vector<int>& differentIds) const throw(INTERP_KERNEL::Exception);
     MEDCOUPLING_EXPORT void useArray(const int *array, bool ownership, DeallocType type, int nbOfTuple, int nbOfCompo);
     MEDCOUPLING_EXPORT void useExternalArrayWithRWAccess(const int *array, int nbOfTuple, int nbOfCompo);
     MEDCOUPLING_EXPORT void writeOnPlace(int id, int element0, const int *others, int sizeOfOthers) { _mem.writeOnPlace(id,element0,others,sizeOfOthers); }
index d226fd90dbba65c58f64984a755f0f9463937791..e0a9c788393126f7b60ef01f48999fd7ca64e620 100644 (file)
@@ -392,6 +392,18 @@ int MEDCouplingMesh::GetDimensionOfGeometricType(INTERP_KERNEL::NormalizedCellTy
   return (int) cm.getDimension();
 }
 
+/*!
+ * \param [in] type the geometric type for which the representation is asked.
+ * \return the string representation corresponding to the input geometric type \a type.
+ * 
+ * \throw if type is equal to \c INTERP_KERNEL::NORM_ERROR or to an unexisting geometric type.
+ */
+const char *MEDCouplingMesh::GetReprOfGeometricType(INTERP_KERNEL::NormalizedCellType type) throw(INTERP_KERNEL::Exception)
+{
+  const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(type);
+  return cm.getRepr();
+}
+
 void MEDCouplingMesh::getCellsContainingPoint(const double *pos, double eps, std::vector<int>& elts) const
 {
   int ret=getCellContainingPoint(pos,eps);
index 988ab77e9b12b717b2e25fa62669d5b080193211..2febf8c6b45bcd399432c20d544ac77db0850e3a 100644 (file)
@@ -118,6 +118,7 @@ namespace ParaMEDMEM
     static MEDCouplingMesh *MergeMeshes(const MEDCouplingMesh *mesh1, const MEDCouplingMesh *mesh2) throw(INTERP_KERNEL::Exception);
     static MEDCouplingMesh *MergeMeshes(std::vector<const MEDCouplingMesh *>& meshes) throw(INTERP_KERNEL::Exception);
     static int GetDimensionOfGeometricType(INTERP_KERNEL::NormalizedCellType type) throw(INTERP_KERNEL::Exception);
+    static const char *GetReprOfGeometricType(INTERP_KERNEL::NormalizedCellType type) throw(INTERP_KERNEL::Exception);
     //serialisation-unserialization
     virtual void getTinySerializationInformation(std::vector<double>& tinyInfoD, std::vector<int>& tinyInfo, std::vector<std::string>& littleStrings) const = 0;
     virtual void resizeForUnserialization(const std::vector<int>& tinyInfo, DataArrayInt *a1, DataArrayDouble *a2, std::vector<std::string>& littleStrings) const = 0;
index af387699bd6034d2fe42dc97a37f4501ce36e58e..e5561245655379e801d0133e61774463499b9c64 100644 (file)
 // Author : Anthony Geay (CEA/DEN)
 
 #include "MEDCouplingRefCountObject.hxx"
+#include "MED_version.h"
 
 using namespace ParaMEDMEM;
 
+const char *ParaMEDMEM::MEDCouplingVersionStr()
+{
+  return SALOMEMED_VERSION_STR;
+}
+
+int ParaMEDMEM::MEDCouplingVersion()
+{
+  return SALOMEMED_VERSION;
+}
+
+void ParaMEDMEM::MEDCouplingVersionMajMinRel(int& maj, int& minor, int& releas)
+{
+  int ver=SALOMEMED_VERSION;
+  maj=(ver & 0xFF0000) >> 16;
+  minor=(ver & 0xFF00) >> 8;
+  releas=(ver & 0xFF);
+}
+
 RefCountObject::RefCountObject():_cnt(1)
 {
 }
index f9084503e7618159511a81609646d2ba786613e5..c6eb6825a1b588640dbb0b777cbfe3f7e38ac7d8 100644 (file)
@@ -50,6 +50,10 @@ namespace ParaMEDMEM
 
   typedef bool (*FunctionToEvaluate)(const double *pos, double *res);
 
+  MEDCOUPLING_EXPORT const char *MEDCouplingVersionStr();
+  MEDCOUPLING_EXPORT int MEDCouplingVersion();
+  MEDCOUPLING_EXPORT void MEDCouplingVersionMajMinRel(int& maj, int& minor, int& releas);
+
   class MEDCOUPLING_EXPORT RefCountObject
   {
   protected:
index 0ef48eec7fb1ef0154f0dd4df3ca82f1068e1f08..8a489b1390c67bf9cd965067c8b57aa961a3a355 100644 (file)
@@ -24,7 +24,9 @@
 #include "MEDCouplingFieldTemplate.hxx"
 #include "MEDCouplingFieldDiscretization.hxx"
 #include "MEDCouplingExtrudedMesh.hxx"
+#include "MEDCouplingCMesh.hxx"
 #include "MEDCouplingNormalizedUnstructuredMesh.txx"
+#include "MEDCouplingNormalizedCartesianMesh.txx"
 
 #include "Interpolation1D.txx"
 #include "Interpolation2DCurve.hxx"
@@ -33,6 +35,8 @@
 #include "Interpolation3DSurf.hxx"
 #include "Interpolation2D1D.txx"
 #include "Interpolation3D2D.txx"
+#include "InterpolationCU.txx"
+#include "InterpolationCC.txx"
 
 using namespace ParaMEDMEM;
 
@@ -55,6 +59,12 @@ int MEDCouplingRemapper::prepare(const MEDCouplingMesh *srcMesh, const MEDCoupli
     {
     case 85://Unstructured-Unstructured
       return prepareUU(method);
+    case 87://Unstructured-Cartesian
+      return prepareUC(method);
+    case 117://Cartesian-Unstructured
+      return prepareCU(method);
+    case 119://Cartesian-Cartesian
+      return prepareCC(method);
     case 136://Extruded-Extruded
       return prepareEE(method);
     default:
@@ -232,7 +242,7 @@ int MEDCouplingRemapper::prepareUU(const char *method) throw(INTERP_KERNEL::Exce
       INTERP_KERNEL::Interpolation3D interpolation(*this);
       std::vector<std::map<int,double> > matrixTmp;
       nbCols=interpolation.interpolateMeshes(target_mesh_wrapper,source_mesh_wrapper,matrixTmp,method);
-      reverseMatrix(matrixTmp,nbCols,_matrix);
+      ReverseMatrix(matrixTmp,nbCols,_matrix);
       nbCols=matrixTmp.size();
     }
   else if(srcMeshDim==2 && trgMeshDim==1 && srcSpaceDim==2)
@@ -251,7 +261,7 @@ int MEDCouplingRemapper::prepareUU(const char *method) throw(INTERP_KERNEL::Exce
           INTERP_KERNEL::Interpolation2D1D interpolation(*this);
           std::vector<std::map<int,double> > matrixTmp;
           nbCols=interpolation.interpolateMeshes(target_mesh_wrapper,source_mesh_wrapper,matrixTmp,method);
-          reverseMatrix(matrixTmp,nbCols,_matrix);
+          ReverseMatrix(matrixTmp,nbCols,_matrix);
           nbCols=matrixTmp.size();
           INTERP_KERNEL::Interpolation2D1D::DuplicateFacesType duplicateFaces=interpolation.retrieveDuplicateFaces();
           if(!duplicateFaces.empty())
@@ -275,7 +285,7 @@ int MEDCouplingRemapper::prepareUU(const char *method) throw(INTERP_KERNEL::Exce
           INTERP_KERNEL::Interpolation2D interpolation(*this);
           std::vector<std::map<int,double> > matrixTmp;
           nbCols=interpolation.interpolateMeshes(target_mesh_wrapper,source_mesh_wrapper,matrixTmp,method);
-          reverseMatrix(matrixTmp,nbCols,_matrix);
+          ReverseMatrix(matrixTmp,nbCols,_matrix);
           nbCols=matrixTmp.size();
         }
       else
@@ -322,7 +332,7 @@ int MEDCouplingRemapper::prepareUU(const char *method) throw(INTERP_KERNEL::Exce
       INTERP_KERNEL::Interpolation3D2D interpolation(*this);
       std::vector<std::map<int,double> > matrixTmp;
       nbCols=interpolation.interpolateMeshes(target_mesh_wrapper,source_mesh_wrapper,matrixTmp,method);
-      reverseMatrix(matrixTmp,nbCols,_matrix);
+      ReverseMatrix(matrixTmp,nbCols,_matrix);
       nbCols=matrixTmp.size();
       INTERP_KERNEL::Interpolation3D2D::DuplicateFacesType duplicateFaces=interpolation.retrieveDuplicateFaces();
       if(!duplicateFaces.empty())
@@ -426,6 +436,163 @@ int MEDCouplingRemapper::prepareEE(const char *method) throw(INTERP_KERNEL::Exce
   return 1;
 }
 
+int MEDCouplingRemapper::prepareUC(const char *method) throw(INTERP_KERNEL::Exception)
+{
+  std::string methodCpp(method);
+  if(methodCpp!="P0P0")
+    throw INTERP_KERNEL::Exception("MEDCouplingRemapper::prepareUC : only P0P0 interpolation supported for the moment !");
+  INTERP_KERNEL::Interpolation<INTERP_KERNEL::Interpolation3D>::checkAndSplitInterpolationMethod(method,_src_method,_target_method);
+  MEDCouplingUMesh *src_mesh=static_cast<MEDCouplingUMesh *>(_src_mesh);
+  MEDCouplingCMesh *target_mesh=static_cast<MEDCouplingCMesh *>(_target_mesh);
+  const int srcMeshDim=src_mesh->getMeshDimension();
+  const int srcSpceDim=src_mesh->getSpaceDimension();
+  const int trgMeshDim=target_mesh->getMeshDimension();
+  if(srcMeshDim!=srcSpceDim || srcMeshDim!=trgMeshDim)
+    throw INTERP_KERNEL::Exception("MEDCouplingRemapper::prepareUC : space dim of src unstructured should be equal to mesh dim of src unstructured and should be equal also equal to trg cartesian dimension !");
+  std::vector<std::map<int,double> > res;
+  switch(srcMeshDim)
+    {
+    case 1:
+      {
+        MEDCouplingNormalizedCartesianMesh<1> targetWrapper(target_mesh);
+        MEDCouplingNormalizedUnstructuredMesh<1,1> sourceWrapper(src_mesh);
+        INTERP_KERNEL::InterpolationCU myInterpolator(*this);
+        myInterpolator.interpolateMeshes(targetWrapper,sourceWrapper,res,"P0P0");
+        break;
+      }
+    case 2:
+      {
+        MEDCouplingNormalizedCartesianMesh<2> targetWrapper(target_mesh);
+        MEDCouplingNormalizedUnstructuredMesh<2,2> sourceWrapper(src_mesh);
+        INTERP_KERNEL::InterpolationCU myInterpolator(*this);
+        myInterpolator.interpolateMeshes(targetWrapper,sourceWrapper,res,"P0P0");
+        break;
+      }
+    case 3:
+      {
+        MEDCouplingNormalizedCartesianMesh<3> targetWrapper(target_mesh);
+        MEDCouplingNormalizedUnstructuredMesh<3,3> sourceWrapper(src_mesh);
+        INTERP_KERNEL::InterpolationCU myInterpolator(*this);
+        myInterpolator.interpolateMeshes(targetWrapper,sourceWrapper,res,"P0P0");
+        break;
+      }
+    default:
+      throw INTERP_KERNEL::Exception("MEDCouplingRemapper::prepareUC : only dimension 1 2 or 3 supported !");
+    }
+  ReverseMatrix(res,target_mesh->getNumberOfCells(),_matrix);
+  nullifiedTinyCoeffInCrudeMatrixAbs(0.);
+  //
+  _deno_multiply.clear();
+  _deno_multiply.resize(_matrix.size());
+  _deno_reverse_multiply.clear();
+  _deno_reverse_multiply.resize(src_mesh->getNumberOfCells());
+  declareAsNew();
+  return 1;
+}
+
+int MEDCouplingRemapper::prepareCU(const char *method) throw(INTERP_KERNEL::Exception)
+{
+  std::string methodCpp(method);
+  if(methodCpp!="P0P0")
+    throw INTERP_KERNEL::Exception("MEDCouplingRemapper::prepareCU : only P0P0 interpolation supported for the moment !");
+  INTERP_KERNEL::Interpolation<INTERP_KERNEL::Interpolation3D>::checkAndSplitInterpolationMethod(method,_src_method,_target_method);
+  MEDCouplingCMesh *src_mesh=static_cast<MEDCouplingCMesh *>(_src_mesh);
+  MEDCouplingUMesh *target_mesh=static_cast<MEDCouplingUMesh *>(_target_mesh);
+  const int srcMeshDim=src_mesh->getMeshDimension();
+  const int trgMeshDim=target_mesh->getMeshDimension();
+  const int trgSpceDim=target_mesh->getSpaceDimension();
+  if(trgMeshDim!=trgSpceDim || trgMeshDim!=srcMeshDim)
+    throw INTERP_KERNEL::Exception("MEDCouplingRemapper::prepareCU : space dim of target unstructured should be equal to mesh dim of target unstructured and should be equal also equal to source cartesian dimension !");
+  switch(srcMeshDim)
+    {
+    case 1:
+      {
+        MEDCouplingNormalizedCartesianMesh<1> sourceWrapper(src_mesh);
+        MEDCouplingNormalizedUnstructuredMesh<1,1> targetWrapper(target_mesh);
+        INTERP_KERNEL::InterpolationCU myInterpolator(*this);
+        myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,_matrix,"P0P0");
+        break;
+      }
+    case 2:
+      {
+        MEDCouplingNormalizedCartesianMesh<2> sourceWrapper(src_mesh);
+        MEDCouplingNormalizedUnstructuredMesh<2,2> targetWrapper(target_mesh);
+        INTERP_KERNEL::InterpolationCU myInterpolator(*this);
+        myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,_matrix,"P0P0");
+        break;
+      }
+    case 3:
+      {
+        MEDCouplingNormalizedCartesianMesh<3> sourceWrapper(src_mesh);
+        MEDCouplingNormalizedUnstructuredMesh<3,3> targetWrapper(target_mesh);
+        INTERP_KERNEL::InterpolationCU myInterpolator(*this);
+        myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,_matrix,"P0P0");
+        break;
+      }
+    default:
+      throw INTERP_KERNEL::Exception("MEDCouplingRemapper::prepareCU : only dimension 1 2 or 3 supported !");
+    }
+  nullifiedTinyCoeffInCrudeMatrixAbs(0.);
+  //
+  _deno_multiply.clear();
+  _deno_multiply.resize(_matrix.size());
+  _deno_reverse_multiply.clear();
+  _deno_reverse_multiply.resize(src_mesh->getNumberOfCells());
+  declareAsNew();
+  return 1;
+}
+
+int MEDCouplingRemapper::prepareCC(const char *method) throw(INTERP_KERNEL::Exception)
+{
+  std::string methodCpp(method);
+  if(methodCpp!="P0P0")
+    throw INTERP_KERNEL::Exception("MEDCouplingRemapper::prepareCC : only P0P0 interpolation supported for the moment !");
+  INTERP_KERNEL::Interpolation<INTERP_KERNEL::Interpolation3D>::checkAndSplitInterpolationMethod(method,_src_method,_target_method);
+  MEDCouplingCMesh *src_mesh=static_cast<MEDCouplingCMesh *>(_src_mesh);
+  MEDCouplingCMesh *target_mesh=static_cast<MEDCouplingCMesh *>(_target_mesh);
+  const int srcMeshDim=src_mesh->getMeshDimension();
+  const int trgMeshDim=target_mesh->getMeshDimension();
+  if(trgMeshDim!=srcMeshDim)
+    throw INTERP_KERNEL::Exception("MEDCouplingRemapper::prepareCC : dim of target cartesian should be equal to dim of source cartesian dimension !");
+  switch(srcMeshDim)
+    {
+    case 1:
+      {
+        MEDCouplingNormalizedCartesianMesh<1> sourceWrapper(src_mesh);
+        MEDCouplingNormalizedCartesianMesh<1> targetWrapper(target_mesh);
+        INTERP_KERNEL::InterpolationCC myInterpolator(*this);
+        myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,_matrix,"P0P0");
+        break;
+      }
+    case 2:
+      {
+        MEDCouplingNormalizedCartesianMesh<2> sourceWrapper(src_mesh);
+        MEDCouplingNormalizedCartesianMesh<2> targetWrapper(target_mesh);
+        INTERP_KERNEL::InterpolationCC myInterpolator(*this);
+        myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,_matrix,"P0P0");
+        break;
+      }
+    case 3:
+      {
+        MEDCouplingNormalizedCartesianMesh<3> sourceWrapper(src_mesh);
+        MEDCouplingNormalizedCartesianMesh<3> targetWrapper(target_mesh);
+        INTERP_KERNEL::InterpolationCC myInterpolator(*this);
+        myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,_matrix,"P0P0");
+        break;
+      }
+    default:
+      throw INTERP_KERNEL::Exception("MEDCouplingRemapper::prepareCC : only dimension 1 2 or 3 supported !");
+    }
+  nullifiedTinyCoeffInCrudeMatrixAbs(0.);
+  //
+  _deno_multiply.clear();
+  _deno_multiply.resize(_matrix.size());
+  _deno_reverse_multiply.clear();
+  _deno_reverse_multiply.resize(src_mesh->getNumberOfCells());
+  declareAsNew();
+  return 1;
+}
+
 void MEDCouplingRemapper::updateTime() const
 {
 }
@@ -494,7 +661,7 @@ void MEDCouplingRemapper::computeDenoFromScratch(NatureOfField nat, const MEDCou
     {
     case ConservativeVolumic:
       {
-        computeRowSumAndColSum(_matrix,_deno_multiply,_deno_reverse_multiply);
+        ComputeRowSumAndColSum(_matrix,_deno_multiply,_deno_reverse_multiply);
         break;
       }
     case Integral:
@@ -526,7 +693,7 @@ void MEDCouplingRemapper::computeDenoFromScratch(NatureOfField nat, const MEDCou
       }
     case IntegralGlobConstraint:
       {
-        computeColSumAndRowSum(_matrix,_deno_multiply,_deno_reverse_multiply);
+        ComputeColSumAndRowSum(_matrix,_deno_multiply,_deno_reverse_multiply);
         break;
       }
     case RevIntegral:
@@ -607,7 +774,7 @@ void MEDCouplingRemapper::computeReverseProduct(const double *inputPointer, int
       std::fill(resPointer+idx*inputNbOfCompo,resPointer+(idx+1)*inputNbOfCompo,dftValue);
 }
 
-void MEDCouplingRemapper::reverseMatrix(const std::vector<std::map<int,double> >& matIn, int nbColsMatIn, std::vector<std::map<int,double> >& matOut)
+void MEDCouplingRemapper::ReverseMatrix(const std::vector<std::map<int,double> >& matIn, int nbColsMatIn, std::vector<std::map<int,double> >& matOut)
 {
   matOut.resize(nbColsMatIn);
   int id=0;
@@ -616,7 +783,7 @@ void MEDCouplingRemapper::reverseMatrix(const std::vector<std::map<int,double> >
       matOut[(*iter2).first][id]=(*iter2).second;
 }
 
-void MEDCouplingRemapper::computeRowSumAndColSum(const std::vector<std::map<int,double> >& matrixDeno,
+void MEDCouplingRemapper::ComputeRowSumAndColSum(const std::vector<std::map<int,double> >& matrixDeno,
                                                  std::vector<std::map<int,double> >& deno, std::vector<std::map<int,double> >& denoReverse)
 {
   std::map<int,double> values;
@@ -640,7 +807,7 @@ void MEDCouplingRemapper::computeRowSumAndColSum(const std::vector<std::map<int,
     }
 }
 
-void MEDCouplingRemapper::computeColSumAndRowSum(const std::vector<std::map<int,double> >& matrixDeno,
+void MEDCouplingRemapper::ComputeColSumAndRowSum(const std::vector<std::map<int,double> >& matrixDeno,
                                                  std::vector<std::map<int,double> >& deno, std::vector<std::map<int,double> >& denoReverse)
 {
   std::map<int,double> values;
index c2005df8e26a8e477a5a635f99f8591c060743de..41948c2fbedd5b3eae0dcbb84a6fafa1b42f8637 100644 (file)
@@ -65,6 +65,9 @@ namespace ParaMEDMEM
   private:
     int prepareUU(const char *method) throw(INTERP_KERNEL::Exception);
     int prepareEE(const char *method) throw(INTERP_KERNEL::Exception);
+    int prepareUC(const char *method) throw(INTERP_KERNEL::Exception);
+    int prepareCU(const char *method) throw(INTERP_KERNEL::Exception);
+    int prepareCC(const char *method) throw(INTERP_KERNEL::Exception);
     void updateTime() const;
     void releaseData(bool matrixSuppression);
     void transferUnderground(const MEDCouplingFieldDouble *srcField, MEDCouplingFieldDouble *targetField, bool isDftVal, double dftValue) throw(INTERP_KERNEL::Exception);
@@ -76,11 +79,11 @@ namespace ParaMEDMEM
                                                     const std::vector< std::map<int,double> >& m2D,
                                                     const int *corrCellIdSrc, int nbOf2DCellsSrc, int nbOf1DCellsSrc,
                                                     const int *corrCellIdTrg);
-    static void reverseMatrix(const std::vector<std::map<int,double> >& matIn, int nbColsMatIn,
+    static void ReverseMatrix(const std::vector<std::map<int,double> >& matIn, int nbColsMatIn,
                               std::vector<std::map<int,double> >& matOut);
-    static void computeRowSumAndColSum(const std::vector<std::map<int,double> >& matrixDeno,
+    static void ComputeRowSumAndColSum(const std::vector<std::map<int,double> >& matrixDeno,
                                        std::vector<std::map<int,double> >& deno, std::vector<std::map<int,double> >& denoReverse);
-    static void computeColSumAndRowSum(const std::vector<std::map<int,double> >& matrixDeno,
+    static void ComputeColSumAndRowSum(const std::vector<std::map<int,double> >& matrixDeno,
                                        std::vector<std::map<int,double> >& deno, std::vector<std::map<int,double> >& denoReverse);
   private:
     MEDCouplingMesh *_src_mesh;
index d8f87ad56216febabd1b67931b1a43b818c7b675..dae38283f988e8ce48a70638fe7c81cc4942ac6f 100644 (file)
@@ -1062,7 +1062,6 @@ void MEDCouplingUMesh::simplifyPolyhedra(double eps) throw(INTERP_KERNEL::Except
     throw INTERP_KERNEL::Exception("MEDCouplingUMesh::simplifyPolyhedra : works on meshdimension 3 and spaceDimension 3 !");
   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> coords=getCoords()->deepCpy();
   coords->recenterForMaxPrecision(eps);
-  const double *coordsPtr=coords->getConstPointer();
   //
   int nbOfCells=getNumberOfCells();
   const int *conn=_nodal_connec->getConstPointer();
@@ -1612,7 +1611,6 @@ bool MEDCouplingUMesh::areCellsIncludedIn2(const MEDCouplingUMesh *other, DataAr
     }
   int thisNbCells=getNumberOfCells();
   int otherNbCells=other->getNumberOfCells();
-  int nbOfCells=mesh->getNumberOfCells();
   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> arr2=DataArrayInt::New();
   arr2->alloc(otherNbCells,1);
   arr2->fillWithZero();
@@ -1794,9 +1792,7 @@ void MEDCouplingUMesh::setPartOfMySelf(const int *cellIdsBg, const int *cellIdsE
     }
   int nbOfCells=getNumberOfCells();
   bool easyAssign=true;
-  const int *conn=_nodal_connec->getConstPointer();
   const int *connI=_nodal_connec_index->getConstPointer();
-  const int *connOther=otherOnSameCoordsThanThis._nodal_connec->getConstPointer();
   const int *connIOther=otherOnSameCoordsThanThis._nodal_connec_index->getConstPointer();
   for(const int *it=cellIdsBg;it!=cellIdsEnd && easyAssign;it++,connIOther++)
     {
@@ -1845,9 +1841,7 @@ void MEDCouplingUMesh::setPartOfMySelf2(int start, int end, int step, const MEDC
     }
   int nbOfCells=getNumberOfCells();
   bool easyAssign=true;
-  const int *conn=_nodal_connec->getConstPointer();
   const int *connI=_nodal_connec_index->getConstPointer();
-  const int *connOther=otherOnSameCoordsThanThis._nodal_connec->getConstPointer();
   const int *connIOther=otherOnSameCoordsThanThis._nodal_connec_index->getConstPointer();
   int it=start;
   for(int i=0;i<nbOfCellsToModify && easyAssign;i++,it+=step,connIOther++)
@@ -2486,7 +2480,13 @@ INTERP_KERNEL::NormalizedCellType MEDCouplingUMesh::getTypeOfCell(int cellId) co
 {
   const int *ptI=_nodal_connec_index->getConstPointer();
   const int *pt=_nodal_connec->getConstPointer();
-  return (INTERP_KERNEL::NormalizedCellType) pt[ptI[cellId]];
+  if(cellId>=0 && cellId<_nodal_connec_index->getNbOfElems()-1)
+    return (INTERP_KERNEL::NormalizedCellType) pt[ptI[cellId]];
+  else
+    {
+      std::ostringstream oss; oss << "MEDCouplingUMesh::getTypeOfCell : Requesting type of cell #" << cellId << " but it should be in [0," << _nodal_connec_index->getNbOfElems()-1 << ") !";
+      throw INTERP_KERNEL::Exception(oss.str().c_str());
+    }
 }
 
 /*!
@@ -2604,6 +2604,27 @@ std::string MEDCouplingUMesh::advancedRepr() const
   return ret.str();
 }
 
+/*!
+ * This method returns a C++ code that is a dump of \a this.
+ * This method will throw if this is not fully defined.
+ */
+std::string MEDCouplingUMesh::cppRepr() const throw(INTERP_KERNEL::Exception)
+{
+  static const char coordsName[]="coords";
+  static const char connName[]="conn";
+  static const char connIName[]="connI";
+  checkFullyDefined();
+  std::ostringstream ret; ret << "// coordinates" << std::endl;
+  _coords->reprCppStream(coordsName,ret); ret << std::endl << "// connectivity" << std::endl;
+  _nodal_connec->reprCppStream(connName,ret); ret << std::endl;
+  _nodal_connec_index->reprCppStream(connIName,ret); ret << std::endl;
+  ret << "MEDCouplingUMesh *mesh=MEDCouplingUMesh::New(\"" << getName() << "\"," << getMeshDimension() << ");" << std::endl;
+  ret << "mesh->setCoords(" << coordsName << ");" << std::endl;
+  ret << "mesh->setConnectivity(" << connName << "," << connIName << ",true);" << std::endl;
+  ret << coordsName << "->decrRef(); " << connName << "->decrRef(); " << connIName << "->decrRef();" << std::endl;
+  return ret.str();
+}
+
 std::string MEDCouplingUMesh::reprConnectivityOfThis() const
 {
   std::ostringstream ret;
@@ -3341,10 +3362,10 @@ MEDCouplingUMesh *MEDCouplingUMesh::buildSlice3DSurf(const double *origin, const
 {
   checkFullyDefined();
   if(getMeshDimension()!=2 || getSpaceDimension()!=3)
-    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::buildSlice3D works on umeshes with meshdim equal to 2 and spaceDim equal to 3 !");
+    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::buildSlice3DSurf works on umeshes with meshdim equal to 2 and spaceDim equal to 3 !");
   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> candidates=getCellIdsCrossingPlane(origin,vec,eps);
   if(candidates->empty())
-    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::buildSlice3D : No 3D cells in this intercepts the specified plane considering bounding boxes !");
+    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::buildSlice3DSurf : No 3D surf cells in this intercepts the specified plane considering bounding boxes !");
   std::vector<int> nodes;
   std::vector<int> cellIds1D;
   MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> subMesh=static_cast<MEDCouplingUMesh*>(buildPartOfMySelf(candidates->begin(),candidates->end(),false));
@@ -5220,10 +5241,17 @@ DataArrayInt *MEDCouplingUMesh::checkTypeConsistencyAndContig(const std::vector<
 }
 
 /*!
- * This method makes the hypothesis that 'this' is sorted by type. If not an exception will be thrown.
- * This method is the opposite of MEDCouplingUMesh::checkTypeConsistencyAndContig method. Given a list of cells in 'profile' it returns a list of profiles sorted by geo type.
- * This method has 1 input 'profile' and 2 outputs 'code' and 'idsPerType'.
- * @throw if 'profile' has not exactly one component. It throws too, if 'profile' contains some values not in [0,getNumberOfCells()) or if 'this' is not fully defined
+ * This method makes the hypothesis that \at this is sorted by type. If not an exception will be thrown.
+ * This method is the opposite of MEDCouplingUMesh::checkTypeConsistencyAndContig method. Given a list of cells in \a profile it returns a list of sub-profiles sorted by geo type.
+ * The result is put in the array \a idsPerType. In the returned parameter \a code, foreach i \a code[3*i+2] refers (if different from -1) to a location into the \a idsPerType.
+ * This method has 1 input \a profile and 3 outputs \a code' \a idsInPflPerType and \a idsPerType.
+ * 
+ * @param [out] code is a vector of size 3*n where n is the number of different geometric type in \a this \b reduced to the profile \a profile. \a code has exactly the same semantic than in MEDCouplingUMesh::checkTypeConsistencyAndContig method.
+ * @param [out] idsInPflPerType is a vector of size of different geometric type in the subpart defined by \a profile of \a this ( equal to \a code.size()/3). For each i,
+ *              \a idsInPflPerType[i] stores the tuple ids in \a profile that correspond to the geometric type code[3*i+0]
+ * @param [out] idsPerType is a vector of size of different sub profiles needed to be defined to represent the profile \a profile for a given geometric type.
+ *              This vector can be empty in case of all geometric type cells are fully covered in ascending in the given input \a profile.
+ * @throw if \a profile has not exactly one component. It throws too, if \a profile contains some values not in [0,getNumberOfCells()) or if 'this' is not fully defined
  */
 void MEDCouplingUMesh::splitProfilePerType(const DataArrayInt *profile, std::vector<int>& code, std::vector<DataArrayInt *>& idsInPflPerType, std::vector<DataArrayInt *>& idsPerType) const throw(INTERP_KERNEL::Exception)
 {
@@ -5641,32 +5669,45 @@ DataArrayInt *MEDCouplingUMesh::convertCellArrayPerGeoType(const DataArrayInt *d
 
 /*!
  * This method reduced number of cells of this by keeping cells whose type is different from 'type' and if type=='type'
+ * This method \b works \b for mesh sorted by type.
  * cells whose ids is in 'idsPerGeoType' array.
  * This method conserves coords and name of mesh.
  */
 MEDCouplingUMesh *MEDCouplingUMesh::keepSpecifiedCells(INTERP_KERNEL::NormalizedCellType type, const int *idsPerGeoTypeBg, const int *idsPerGeoTypeEnd) const
 {
-  std::vector<int> idsTokeep;
-  int nbOfCells=getNumberOfCells();
-  int j=0;
-  for(int i=0;i<nbOfCells;i++)
-    if(getTypeOfCell(i)!=type)
-      idsTokeep.push_back(i);
-    else
+  std::vector<int> code=getDistributionOfTypes();
+  std::size_t nOfTypesInThis=code.size()/3;
+  int sz=0,szOfType=0;
+  for(std::size_t i=0;i<nOfTypesInThis;i++)
+    {
+      if(code[3*i]!=type)
+        sz+=code[3*i+1];
+      else
+        szOfType=code[3*i+1];
+    }
+  for(const int *work=idsPerGeoTypeBg;work!=idsPerGeoTypeEnd;work++)
+    if(*work<0 || *work>=szOfType)
       {
-        if(std::find(idsPerGeoTypeBg,idsPerGeoTypeEnd,j)!=idsPerGeoTypeEnd)
-          idsTokeep.push_back(i);
-        j++;
+        std::ostringstream oss; oss << "MEDCouplingUMesh::keepSpecifiedCells : Request on type " << type << " at place #" << std::distance(idsPerGeoTypeBg,work) << " value " << *work;
+        oss << ". It should be in [0," << szOfType << ") !";
+        throw INTERP_KERNEL::Exception(oss.str().c_str());
       }
-  MEDCouplingPointSet *ret=buildPartOfMySelf(&idsTokeep[0],&idsTokeep[0]+idsTokeep.size(),true);
-  MEDCouplingUMesh *ret2=dynamic_cast<MEDCouplingUMesh *>(ret);
-  if(!ret2)
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> idsTokeep=DataArrayInt::New(); idsTokeep->alloc(sz+(int)std::distance(idsPerGeoTypeBg,idsPerGeoTypeEnd),1);
+  int *idsPtr=idsTokeep->getPointer();
+  int offset=0;
+  for(std::size_t i=0;i<nOfTypesInThis;i++)
     {
-      ret->decrRef();
-      return 0;
+      if(code[3*i]!=type)
+        for(int j=0;j<code[3*i+1];j++)
+          *idsPtr++=offset+j;
+      else
+        idsPtr=std::transform(idsPerGeoTypeBg,idsPerGeoTypeEnd,idsPtr,std::bind2nd(std::plus<int>(),offset));
+      offset+=code[3*i+1];
     }
-  ret2->copyTinyInfoFrom(this);
-  return ret2;
+  MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> ret=static_cast<MEDCouplingUMesh *>(buildPartOfMySelf(idsTokeep->begin(),idsTokeep->end(),true));
+  ret->copyTinyInfoFrom(this);
+  ret->incrRef();
+  return ret;
 }
 
 /*!
@@ -6570,7 +6611,7 @@ void MEDCouplingUMesh::writeVTKLL(std::ostream& ofs, const std::string& cellData
   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> connectivity=DataArrayInt::New(); connectivity->alloc(_nodal_connec->getNumberOfTuples()-nbOfCells,1);
   int *w1=faceoffsets->getPointer(),*w2=types->getPointer(),*w3=offsets->getPointer(),*w4=connectivity->getPointer();
   int szFaceOffsets=0,szConn=0;
-  for(int i=0;i<nbOfCells;i++,w1++,w2++,*w3++)
+  for(int i=0;i<nbOfCells;i++,w1++,w2++,w3++)
     {
       *w2=cPtr[cIPtr[i]];
       if((INTERP_KERNEL::NormalizedCellType)cPtr[cIPtr[i]]!=INTERP_KERNEL::NORM_POLYHED)
@@ -6602,13 +6643,13 @@ void MEDCouplingUMesh::writeVTKLL(std::ostream& ofs, const std::string& cellData
           {
             int nbFaces=std::count(cPtr+cIPtr[i]+1,cPtr+cIPtr[i+1],-1)+1;
             *w1++=nbFaces;
-            const int *w4=cPtr+cIPtr[i]+1,*w5=0;
+            const int *w6=cPtr+cIPtr[i]+1,*w5=0;
             for(int j=0;j<nbFaces;j++)
               {
-                w5=std::find(w4,cPtr+cIPtr[i+1],-1);
-                *w1++=(int)std::distance(w4,w5);
-                w1=std::copy(w4,w5,w1);
-                w4=w5+1;
+                w5=std::find(w6,cPtr+cIPtr[i+1],-1);
+                *w1++=(int)std::distance(w6,w5);
+                w1=std::copy(w6,w5,w1);
+                w6=w5+1;
               }
           }
       faces->writeVTK(ofs,8,"Int32","faces");
@@ -6707,24 +6748,35 @@ void MEDCouplingUMesh::BuildIntersecting2DCellsFromEdges(double eps, const MEDCo
       MEDCouplingUMeshBuildQPFromMesh3(coo1,offset1,coo2,offset2,addCoords,desc1+descIndx1[i],desc1+descIndx1[i+1],intesctEdges1,/* output */mapp,mappRev);
       pol1.buildFromCrudeDataArray(mappRev,cm.isQuadratic(),conn1+connI1[i]+1,coo1,
                                    desc1+descIndx1[i],desc1+descIndx1[i+1],intesctEdges1);
-      std::vector<int> crTmp,crITmp;
-      crITmp.push_back(crI.back());
-      for(std::vector<int>::const_iterator it2=candidates2.begin();it2!=candidates2.end();it2++)
+      //
+      std::set<INTERP_KERNEL::Edge *> edges1;// store all edges of pol1 that are NOT consumed by intersect cells. If any after iteration over candidates2 -> a part of pol1 should appear in result
+      std::set<INTERP_KERNEL::Edge *> edgesBoundary2;// store all edges that are on boundary of (pol2 intersect pol1) minus edges on pol1.
+      INTERP_KERNEL::IteratorOnComposedEdge it1(&pol1);
+      for(it1.first();!it1.finished();it1.next())
+        edges1.insert(it1.current()->getPtr());
+      //
+      std::map<int,std::vector<INTERP_KERNEL::ElementaryEdge *> > edgesIn2ForShare;
+      std::vector<INTERP_KERNEL::QuadraticPolygon> pol2s(candidates2.size());
+      int ii=0;
+      for(std::vector<int>::const_iterator it2=candidates2.begin();it2!=candidates2.end();it2++,ii++)
         {
-          INTERP_KERNEL::QuadraticPolygon pol2;
-          pol1.initLocations();
-          MEDCouplingUMeshBuildQPFromMesh3(coo1,offset1,coo2,offset2,addCoords,desc2+descIndx2[*it2],desc2+descIndx2[*it2+1],intesctEdges2,/* output */mapp,mappRev);
           INTERP_KERNEL::NormalizedCellType typ2=(INTERP_KERNEL::NormalizedCellType)conn2[connI2[*it2]];
           const INTERP_KERNEL::CellModel& cm2=INTERP_KERNEL::CellModel::GetCellModel(typ2);
-          pol2.buildFromCrudeDataArray2(mappRev,cm2.isQuadratic(),conn2+connI2[*it2]+1,coo2,desc2+descIndx2[*it2],desc2+descIndx2[*it2+1],intesctEdges2,
-                                        pol1,desc1+descIndx1[i],desc1+descIndx1[i+1],intesctEdges1,colinear2);
+          MEDCouplingUMeshBuildQPFromMesh3(coo1,offset1,coo2,offset2,addCoords,desc2+descIndx2[*it2],desc2+descIndx2[*it2+1],intesctEdges2,/* output */mapp,mappRev);
+          pol2s[ii].buildFromCrudeDataArray2(mappRev,cm2.isQuadratic(),conn2+connI2[*it2]+1,coo2,desc2+descIndx2[*it2],desc2+descIndx2[*it2+1],intesctEdges2,
+                                             pol1,desc1+descIndx1[i],desc1+descIndx1[i+1],intesctEdges1,colinear2,edgesIn2ForShare);
+        }
+      ii=0;
+      for(std::vector<int>::const_iterator it2=candidates2.begin();it2!=candidates2.end();it2++,ii++)
+        {
+          pol1.initLocationsWithOther(pol2s[ii]);
+          pol2s[ii].updateLocOfEdgeFromCrudeDataArray2(desc2+descIndx2[*it2],desc2+descIndx2[*it2+1],intesctEdges2,pol1,desc1+descIndx1[i],desc1+descIndx1[i+1],intesctEdges1,colinear2);
           //MEDCouplingUMeshAssignOnLoc(pol1,pol2,desc1+descIndx1[i],desc1+descIndx1[i+1],intesctEdges1,desc2+descIndx2[*it2],desc2+descIndx2[*it2+1],intesctEdges2,colinear2);
-          pol1.buildPartitionsAbs(pol2,mapp,i,*it2,offset3,addCoordsQuadratic,cr,crI,cNb1,cNb2);
+          pol1.buildPartitionsAbs(pol2s[ii],edges1,edgesBoundary2,mapp,i,*it2,offset3,addCoordsQuadratic,cr,crI,cNb1,cNb2);
         }
-      if(!crTmp.empty())
+      if(!edges1.empty())
         {
-          cr.insert(cr.end(),crTmp.begin(),crTmp.end());
-          crI.insert(crI.end(),crITmp.begin()+1,crITmp.end());
+          INTERP_KERNEL::QuadraticPolygon::ComputeResidual(pol1,edges1,edgesBoundary2,mapp,offset3,i,addCoordsQuadratic,cr,crI,cNb1,cNb2);
         }
       for(std::map<int,INTERP_KERNEL::Node *>::const_iterator it=mappRev.begin();it!=mappRev.end();it++)
         (*it).second->decrRef();
@@ -7096,6 +7148,8 @@ bool MEDCouplingUMesh::BuildConvexEnvelopOf2DCellJarvis(const double *coords, co
               return true;
             }
         }
+      else
+        throw INTERP_KERNEL::Exception("MEDCouplingUMesh::BuildConvexEnvelopOf2DCellJarvis : invalid 2D cell connectivity !");
     }
   else
     throw INTERP_KERNEL::Exception("MEDCouplingUMesh::BuildConvexEnvelopOf2DCellJarvis : invalid 2D cell connectivity !");
@@ -7501,7 +7555,6 @@ MEDCouplingUMesh *MEDCouplingUMesh::buildSpreadZonesWithPoly() const throw(INTER
   int spaceDim=getSpaceDimension();
   if(mdim!=spaceDim)
     throw INTERP_KERNEL::Exception("MEDCouplingUMesh::buildSpreadZonesWithPoly : meshdimension and spacedimension do not match !");
-  int nbCells=getNumberOfCells();
   std::vector<DataArrayInt *> partition=partitionBySpreadZone();
   std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > partitionAuto; partitionAuto.reserve(partition.size());
   std::copy(partition.begin(),partition.end(),std::back_insert_iterator<std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > >(partitionAuto));
index eb28c5a309ccc4c9115eecfde6f963efdf9046ae..7da64ee503f7b51ffcd1abf92bad0c82a2bfcbc4 100644 (file)
@@ -74,6 +74,7 @@ namespace ParaMEDMEM
     MEDCOUPLING_EXPORT DataArrayInt *getCellIdsFullyIncludedInNodeIds(const int *partBg, const int *partEnd) const;
     MEDCOUPLING_EXPORT std::string simpleRepr() const;
     MEDCOUPLING_EXPORT std::string advancedRepr() const;
+    MEDCOUPLING_EXPORT std::string cppRepr() const throw(INTERP_KERNEL::Exception);
     MEDCOUPLING_EXPORT std::string reprConnectivityOfThis() const;
     MEDCOUPLING_EXPORT MEDCouplingUMesh *buildSetInstanceFromThis(int spaceDim) const throw(INTERP_KERNEL::Exception);
     MEDCOUPLING_EXPORT int getNumberOfNodesInCell(int cellId) const;
index 77b16226db23de1f8970310624a252d913a95ffe..2434ecf7d40ae46d7fb180aa89dd33dcab484752 100644 (file)
@@ -56,7 +56,7 @@ dist_libmedcoupling_la_SOURCES = \
 libmedcoupling_la_LDFLAGS= 
 
 libmedcoupling_la_CPPFLAGS=  @CXXTMPDPTHFLAGS@ \
-       -I$(srcdir) -I$(srcdir)/../INTERP_KERNEL/Bases \
+       -I$(top_builddir) -I$(srcdir) -I$(srcdir)/../INTERP_KERNEL/Bases \
        -I$(srcdir)/../INTERP_KERNEL -I$(srcdir)/../INTERP_KERNEL/Geometric2D \
        -I$(srcdir)/../INTERP_KERNEL/ExprEval -I$(srcdir)/../INTERP_KERNEL/GaussPoints
 
index b1b83ca9e18c78a00dd09d6e5c2e6c3d96f9e3b0..9a55bea575f206a4bffc91bbebd2cf45ac1999ea 100644 (file)
@@ -106,7 +106,7 @@ void MEDCouplingBasicsTest1::testArray3()
   DataArrayDouble *arr4=DataArrayDouble::New();
   arr4->alloc(7,2);
   double *tmp2=arr4->getPointer();
-  const int arr4Ref[14]={0.8,10.8,1.9,11.9,2.1,12.1,3.2,13.2,4.3,14.3,5.4,15.4,6.5,16.5};
+  const double arr4Ref[14]={0.8,10.8,1.9,11.9,2.1,12.1,3.2,13.2,4.3,14.3,5.4,15.4,6.5,16.5};
   std::copy(arr4Ref,arr4Ref+14,tmp2);
   CPPUNIT_ASSERT_EQUAL(7,arr4->getNumberOfTuples());
   CPPUNIT_ASSERT_EQUAL(2,arr4->getNumberOfComponents());
index 89cf9818f87b03f573cf044a5eb5ac4c6246e58f..f6953bbd88142de3ece2c114ba2e2fcfc4ef7fdc 100644 (file)
@@ -53,6 +53,7 @@ void MEDCouplingBasicsTest2::testGaussPointField1()
   CPPUNIT_ASSERT_EQUAL(5,f->getNumberOfMeshPlacesExpected());
   CPPUNIT_ASSERT_EQUAL(0,f->getNbOfGaussLocalization());
   f->setGaussLocalizationOnType(INTERP_KERNEL::NORM_TRI3,_refCoo1,_gsCoo1,_wg1);
+  f->setGaussLocalizationOnType(INTERP_KERNEL::NORM_TRI3,_refCoo1,_gsCoo1,_wg1); // not a bug only to check that it works well
   CPPUNIT_ASSERT_THROW(f->setGaussLocalizationOnType(INTERP_KERNEL::NORM_QUAD4,_refCoo1,_gsCoo1,_wg1),INTERP_KERNEL::Exception);
   CPPUNIT_ASSERT_EQUAL(1,f->getNbOfGaussLocalization());
   const double refCoo2[8]={ 0.,0., 1.,0., 1.,1., 0.,1. };
index ce2fc84ecc57f0bc43809a71fcfcaef206d91817..fcc86c4ac9454d9d38e51e45dbc937648c46651b 100644 (file)
@@ -1388,9 +1388,9 @@ void MEDCouplingBasicsTest3::testExtrudedMesh5()
   DataArrayDouble *d=DataArrayDouble::New();
   d->alloc(13,1);
   d->iota();
-  MEDCouplingCMesh *e=MEDCouplingCMesh::New();
-  e->setCoordsAt(0,d);
-  MEDCouplingUMesh *f=e->buildUnstructured();
+  MEDCouplingCMesh *ee=MEDCouplingCMesh::New();
+  ee->setCoordsAt(0,d);
+  MEDCouplingUMesh *f=ee->buildUnstructured();
   DataArrayDouble *g=f->getCoords()->applyFunc(2,"3.5*IVec+x/6*3.14159265359*JVec");
   CPPUNIT_ASSERT_THROW(f->getCoords()->applyFunc(2,"3.5*IVec+x/6*3.14159265359*KVec"),INTERP_KERNEL::Exception); // KVec refers to component #2 and there is only 2 components !
   DataArrayDouble *h=g->fromPolarToCart();
@@ -1425,7 +1425,7 @@ void MEDCouplingBasicsTest3::testExtrudedMesh5()
   h->decrRef();
   g->decrRef();
   f->decrRef();
-  e->decrRef();
+  ee->decrRef();
   d->decrRef();
   c->decrRef();
   b->decrRef();
index f781b061a3bc1b506d6676dbe4ae303e185370ef..e422be808d08be5c64c369a321945463744942be 100644 (file)
@@ -2020,22 +2020,22 @@ void MEDCouplingBasicsTest4::testIntersect2DMeshesTmp1()
   // End of construction of input meshes m1bis and m2 -> start of specific part of the test
   DataArrayInt *d1=0,*d2=0;
   MEDCouplingUMesh *m3=MEDCouplingUMesh::Intersect2DMeshes(m1bis,m2,1e-10,d1,d2);
-  const int expected1[5]={0,1,1,2,2};
-  const int expected2[5]={0,0,1,1,2};
-  CPPUNIT_ASSERT_EQUAL(5,d1->getNumberOfTuples());
-  CPPUNIT_ASSERT_EQUAL(5,d2->getNumberOfTuples());
-  CPPUNIT_ASSERT_EQUAL(5,m3->getNumberOfCells());
+  const int expected1[8]={0,0,1,1,1,2,2,2};
+  const int expected2[8]={0,-1,0,1,-1,1,2,-1};
+  CPPUNIT_ASSERT_EQUAL(8,d1->getNumberOfTuples());
+  CPPUNIT_ASSERT_EQUAL(8,d2->getNumberOfTuples());
+  CPPUNIT_ASSERT_EQUAL(8,m3->getNumberOfCells());
   CPPUNIT_ASSERT_EQUAL(22,m3->getNumberOfNodes());
   CPPUNIT_ASSERT_EQUAL(2,m3->getSpaceDimension());
-  CPPUNIT_ASSERT(std::equal(expected1,expected1+5,d1->getConstPointer()));
-  CPPUNIT_ASSERT(std::equal(expected2,expected2+5,d2->getConstPointer()));
-  const int expected3[25]={5,17,1,16,12,5,18,1,17,13,5,19,2,18,13,5,20,2,19,14,5,21,3,20,14};
-  const int expected4[6]={0,5,10,15,20,25};
+  CPPUNIT_ASSERT(std::equal(expected1,expected1+8,d1->getConstPointer()));
+  CPPUNIT_ASSERT(std::equal(expected2,expected2+8,d2->getConstPointer()));
+  const int expected3[44]={5,17,1,16,12,5,16,0,4,5,17,12,5,18,1,17,13,5,19,2,18,13,5,17,5,6,19,13,5,20,2,19,14,5,21,3,20,14,5,19,6,7,21,14};
+  const int expected4[9]={0,5,12,17,22,28,33,38,44};
   const double expected5[44]={-1.0,2.0,1.0,2.0,2.0,2.0,4.0,2.0,-1.0,4.0,1.0,4.0,2.0,4.0,4.0,4.0,-0.5,-1.5,1.5,-1.5,2.5,-1.5,4.5,-1.5,-0.5,2.5,1.5,2.5,2.5,2.5,4.5,2.5,-0.5,2.0,1.0,2.5,1.5,2.0,2.0,2.5,2.5,2.0,4.0,2.5};
-  CPPUNIT_ASSERT_EQUAL(25,m3->getNodalConnectivity()->getNumberOfTuples());
-  CPPUNIT_ASSERT_EQUAL(6,m3->getNodalConnectivityIndex()->getNumberOfTuples());
-  CPPUNIT_ASSERT(std::equal(expected3,expected3+25,m3->getNodalConnectivity()->getConstPointer()));
-  CPPUNIT_ASSERT(std::equal(expected4,expected4+6,m3->getNodalConnectivityIndex()->getConstPointer()));
+  CPPUNIT_ASSERT_EQUAL(44,m3->getNodalConnectivity()->getNumberOfTuples());
+  CPPUNIT_ASSERT_EQUAL(9,m3->getNodalConnectivityIndex()->getNumberOfTuples());
+  CPPUNIT_ASSERT(std::equal(expected3,expected3+44,m3->getNodalConnectivity()->getConstPointer()));
+  CPPUNIT_ASSERT(std::equal(expected4,expected4+9,m3->getNodalConnectivityIndex()->getConstPointer()));
   for(int i=0;i<44;i++)
     CPPUNIT_ASSERT_DOUBLES_EQUAL(expected5[i],m3->getCoords()->getIJ(0,i),1e-12);
   d1->decrRef();
@@ -2187,23 +2187,23 @@ void MEDCouplingBasicsTest4::testIntersect2DMeshesTmp3()
   DataArrayInt *d1=0,*d2=0;
   MEDCouplingUMesh *m3=MEDCouplingUMesh::Intersect2DMeshes(m1,m2,1e-10,d1,d2);
   m3->unPolyze();
-  const int expected1[12]={0,1,1,2,3,3,4,5,5,6,7,7};
-  const int expected2[12]={0,0,1,2,2,3,4,4,5,6,6,7};
-  CPPUNIT_ASSERT_EQUAL(12,d1->getNumberOfTuples());
-  CPPUNIT_ASSERT_EQUAL(12,d2->getNumberOfTuples());
-  CPPUNIT_ASSERT_EQUAL(12,m3->getNumberOfCells());
-  CPPUNIT_ASSERT_EQUAL(88,m3->getNumberOfNodes());
+  const int expected1[16]={0,1,1,1,2,3,3,3,4,5,5,5,6,7,7,7};
+  const int expected2[16]={0,0,1,-1,2,2,3,-1,4,4,5,-1,6,6,7,-1};
+  CPPUNIT_ASSERT_EQUAL(16,d1->getNumberOfTuples());
+  CPPUNIT_ASSERT_EQUAL(16,d2->getNumberOfTuples());
+  CPPUNIT_ASSERT_EQUAL(16,m3->getNumberOfCells());
+  CPPUNIT_ASSERT_EQUAL(104,m3->getNumberOfNodes());
   CPPUNIT_ASSERT_EQUAL(2,m3->getSpaceDimension());
-  CPPUNIT_ASSERT(std::equal(expected1,expected1+12,d1->getConstPointer()));
-  CPPUNIT_ASSERT(std::equal(expected2,expected2+12,d2->getConstPointer()));
-  const int expected3[100]={6,28,1,25,44,45,46,8,26,1,28,27,47,48,49,50,8,40,2,26,27,51,52,53,54,6,28,25,5,55,56,57,8,28,5,32,31,58,59,60,61,8,32,6,41,31,62,63,64,65,6,25,37,5,66,67,68,8,32,5,37,36,69,70,71,72,8,42,6,32,36,73,74,75,76,6,1,37,25,77,78,79,8,37,1,26,38,80,81,82,83,8,26,2,43,38,84,85,86,87};
-  const int expected4[13]={0,7,16,25,32,41,50,57,66,75,82,91,100};
-  const double expected5[176]={0.,0.,1.,0.,1.5,0.,0.,1.,0.,1.5,-1.,0.,-1.5,0.,0.,-1.,0.,-1.5,0.5,0.,1.25,0.,0.7071067811865476,0.7071067811865476,1.0606601717798214,1.0606601717798214,0.,0.5,0.,1.25,-0.7071067811865476,0.7071067811865476,-1.0606601717798214,1.0606601717798214,-0.5,0.,-1.25,0.,-0.7071067811865476,-0.7071067811865476,-1.0606601717798214,-1.0606601717798214,0.,-0.5,0.,-1.25,0.7071067811865476,-0.7071067811865476,1.0606601717798214,-1.0606601717798214,0.,0.,1.1,0.,1.1,1.,0.,1.,1.7,0.,1.7,1.,-1.1,1.,-1.1,0.,-1.7,0.,-1.7,1.,-1.7,-1.,-1.1,-1.,0.,-1.,1.1,-1.,1.7,-1.,1.118033988749895,1.,-1.118033988749895,1.,-1.118033988749895,-1.,1.118033988749895,-1.,0.7071067811865477,0.7071067811865476,0.5,0.,0.,0.5,1.05,0.,0.7071067811865475,0.7071067811865477,0.55,1.,1.1,0.5,1.4012585384440737,0.535233134659635,1.3,0.,1.1,0.5,1.1090169943749475,1.,0.,0.5,-0.5,0.,-0.7071067811865477,0.7071067811865476,-0.7071067811865475,0.7071067811865477,-1.05,0.,-1.1,0.5,-0.55,1.,-1.3,0.,-1.4012585384440737,0.5352331346596344,-1.1090169943749475,1.,-1.1,0.5,0.,-0.5,-0.7071067811865475,-0.7071067811865477,-0.5,0.,-1.05,0.,-0.7071067811865478,-0.7071067811865475,-0.55,-1.,-1.1,-0.5,-1.4012585384440732,-0.5352331346596354,-1.3,0.,-1.1,-0.5,-1.1090169943749475,-1.,0.7071067811865475,-0.7071067811865477,0.,-0.5,0.5,0.,0.7071067811865477,-0.7071067811865475,1.05,0.,1.1,-0.5,0.55,-1.,1.3,0.,1.4012585384440737,-0.535233134659635,1.1090169943749475,-1.,1.1,-0.5};
-  CPPUNIT_ASSERT_EQUAL(100,m3->getNodalConnectivity()->getNumberOfTuples());
-  CPPUNIT_ASSERT_EQUAL(13,m3->getNodalConnectivityIndex()->getNumberOfTuples());
-  CPPUNIT_ASSERT(std::equal(expected3,expected3+100,m3->getNodalConnectivity()->getConstPointer()));
-  CPPUNIT_ASSERT(std::equal(expected4,expected4+13,m3->getNodalConnectivityIndex()->getConstPointer()));
-  for(int i=0;i<176;i++)
+  CPPUNIT_ASSERT(std::equal(expected1,expected1+16,d1->getConstPointer()));
+  CPPUNIT_ASSERT(std::equal(expected2,expected2+16,d2->getConstPointer()));
+  const int expected3[136]={6,28,1,25,44,45,46,8,26,1,28,27,47,48,49,50,8,40,2,26,27,51,52,53,54,8,28,4,40,27,55,56,57,58,6,28,25,5,59,60,61,8,28,5,32,31,62,63,64,65,8,32,6,41,31,66,67,68,69,8,41,4,28,31,70,71,72,73,6,25,37,5,74,75,76,8,32,5,37,36,77,78,79,80,8,42,6,32,36,81,82,83,84,8,37,8,42,36,85,86,87,88,6,1,37,25,89,90,91,8,37,1,26,38,92,93,94,95,8,26,2,43,38,96,97,98,99,8,43,8,37,38,100,101,102,103};
+  const int expected4[17]={0,7,16,25,34,41,50,59,68,75,84,93,102,109,118,127,136};
+  const double expected5[208]={0.,0.,1.,0.,1.5,0.,0.,1.,0.,1.5,-1.,0.,-1.5,0.,0.,-1.,0.,-1.5,0.5,0.,1.25,0.,0.7071067811865476,0.7071067811865476,1.0606601717798214,1.0606601717798214,0.,0.5,0.,1.25,-0.7071067811865476,0.7071067811865476,-1.0606601717798214,1.0606601717798214,-0.5,0.,-1.25,0.,-0.7071067811865476,-0.7071067811865476,-1.0606601717798214,-1.0606601717798214,0.,-0.5,0.,-1.25,0.7071067811865476,-0.7071067811865476,1.0606601717798214,-1.0606601717798214,0.,0.,1.1,0.,1.1,1.,0.,1.,1.7,0.,1.7,1.,-1.1,1.,-1.1,0.,-1.7,0.,-1.7,1.,-1.7,-1.,-1.1,-1.,0.,-1.,1.1,-1.,1.7,-1.,1.118033988749895,1.,-1.118033988749895,1.,-1.118033988749895,-1.,1.118033988749895,-1.,0.7071067811865477,0.7071067811865476,0.5,0.,0.,0.5,1.05,0.,0.7071067811865475,0.7071067811865477,0.55,1.,1.1,0.5,1.4012585384440737,0.535233134659635,1.3,0.,1.1,0.5,1.1090169943749475,1.,0.,1.25,0.6123724356957946,1.369306393762915,1.1090169943749475,1.,0.55,1.,0.,0.5,-0.5,0.,-0.7071067811865477,0.7071067811865476,-0.7071067811865475,0.7071067811865477,-1.05,0.,-1.1,0.5,-0.55,1.,-1.3,0.,-1.4012585384440737,0.5352331346596344,-1.1090169943749475,1.,-1.1,0.5,-0.6123724356957941,1.3693063937629155,0.,1.25,-0.55,1.,-1.1090169943749475,1.,0.,-0.5,-0.7071067811865475,-0.7071067811865477,-0.5,0.,-1.05,0.,-0.7071067811865478,-0.7071067811865475,-0.55,-1.,-1.1,-0.5,-1.4012585384440734,-0.5352331346596354,-1.3,0.,-1.1,-0.5,-1.1090169943749475,-1.,0.,-1.25,-0.6123724356957945,-1.369306393762915,-1.1090169943749475,-1.,-0.55,-1.,0.7071067811865475,-0.7071067811865477,0.,-0.5,0.5,0.,0.7071067811865477,-0.7071067811865475,1.05,0.,1.1,-0.5,0.55,-1.,1.3,0.,1.4012585384440737,-0.535233134659635,1.1090169943749475,-1.,1.1,-0.5,0.6123724356957946,-1.369306393762915,0.,-1.25,0.55,-1.,1.1090169943749475,-1.0};
+  CPPUNIT_ASSERT_EQUAL(136,m3->getNodalConnectivity()->getNumberOfTuples());
+  CPPUNIT_ASSERT_EQUAL(17,m3->getNodalConnectivityIndex()->getNumberOfTuples());
+  CPPUNIT_ASSERT(std::equal(expected3,expected3+136,m3->getNodalConnectivity()->getConstPointer()));
+  CPPUNIT_ASSERT(std::equal(expected4,expected4+17,m3->getNodalConnectivityIndex()->getConstPointer()));
+  for(int i=0;i<208;i++)
     CPPUNIT_ASSERT_DOUBLES_EQUAL(expected5[i],m3->getCoords()->getIJ(0,i),1e-12);
   d1->decrRef();
   d2->decrRef();
index 5e0d2a25343704387530c3824f8c1c5a71a04931..9e98601c0517d764fb9302a2bf320da2e21a252c 100644 (file)
@@ -126,23 +126,23 @@ void MEDCouplingBasicsTest5::testIntersect2DMeshesTmp4()
   DataArrayInt *d1=0,*d2=0;
   MEDCouplingUMesh *m3=MEDCouplingUMesh::Intersect2DMeshes(m2,m1,1e-10,d1,d2);
   m3->unPolyze();
-  const int expected1[12]={0,0,1,2,2,3,4,4,5,6,6,7};
-  const int expected2[12]={0,1,1,2,3,3,4,5,5,6,7,7};
-  CPPUNIT_ASSERT_EQUAL(12,d1->getNumberOfTuples());
-  CPPUNIT_ASSERT_EQUAL(12,d2->getNumberOfTuples());
-  CPPUNIT_ASSERT_EQUAL(12,m3->getNumberOfCells());
-  CPPUNIT_ASSERT_EQUAL(88,m3->getNumberOfNodes());
+  const int expected1[16]={0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7};
+  const int expected2[16]={0,1,1,-1,2,3,3,-1,4,5,5,-1,6,7,7,-1};
+  CPPUNIT_ASSERT_EQUAL(16,d1->getNumberOfTuples());
+  CPPUNIT_ASSERT_EQUAL(16,d2->getNumberOfTuples());
+  CPPUNIT_ASSERT_EQUAL(16,m3->getNumberOfCells());
+  CPPUNIT_ASSERT_EQUAL(104,m3->getNumberOfNodes());
   CPPUNIT_ASSERT_EQUAL(2,m3->getSpaceDimension());
-  CPPUNIT_ASSERT(std::equal(expected1,expected1+12,d1->getConstPointer()));
-  CPPUNIT_ASSERT(std::equal(expected2,expected2+12,d2->getConstPointer()));
-  const int expected3[100]={6,16,15,18,44,45,46,8,18,2,1,16,47,48,49,50,8,17,1,2,40,51,52,53,54,6,18,15,20,55,56,57,8,20,7,6,18,58,59,60,61,8,41,6,7,21,62,63,64,65,6,20,15,22,66,67,68,8,22,11,7,20,69,70,71,72,8,21,7,11,42,73,74,75,76,6,22,15,16,77,78,79,8,16,1,13,22,80,81,82,83,8,43,13,1,17,84,85,86,87};
-  const int expected4[13]={0,7,16,25,32,41,50,57,66,75,82,91,100};
-  const double expected5[176]={0.,0.,1.1,0.,1.1,1.,0.,1.,1.7,0.,1.7,1.,-1.1,1.,-1.1,0.,-1.7,0.,-1.7,1.,-1.7,-1.,-1.1,-1.,0.,-1.,1.1,-1.,1.7,-1.,0.,0.,1.,0.,1.5,0.,0.,1.,0.,1.5,-1.,0.,-1.5,0.,0.,-1.,0.,-1.5,0.5,0.,1.25,0.,0.7071067811865476,0.7071067811865476,1.0606601717798214,1.0606601717798214,0.,0.5,0.,1.25,-0.7071067811865476,0.7071067811865476,-1.0606601717798214,1.0606601717798214,-0.5,0.,-1.25,0.,-0.7071067811865476,-0.7071067811865476,-1.0606601717798214,-1.0606601717798214,0.,-0.5,0.,-1.25,0.7071067811865476,-0.7071067811865476,1.0606601717798214,-1.0606601717798214,1.1180339887498951,1.,-1.1180339887498951,1.,-1.1180339887498951,-1.,1.1180339887498951,-1.,0.5,0.,0.,0.5,0.7071067811865477,0.7071067811865476,0.55,1.,1.1,0.5,1.05,0.,0.7071067811865477,0.7071067811865477,1.3,0.,1.1,0.5,1.1090169943749475,1.,1.4012585384440737,0.535233134659635,0.,0.5,-0.5,0.,-0.7071067811865477,0.7071067811865476,-1.05,0.,-1.1,0.5,-0.55,1.,-0.7071067811865477,0.7071067811865477,-1.1090169943749475,1.,-1.1,0.5,-1.3,0.,-1.4012585384440737,0.5352331346596344,-0.5,0.,0.,-0.5,-0.7071067811865475,-0.7071067811865477,-0.55,-1.,-1.1,-0.5,-1.05,0.,-0.7071067811865479,-0.7071067811865476,-1.3,0.,-1.1,-0.5,-1.1090169943749475,-1.,-1.4012585384440734,-0.5352331346596354,0.,-0.5,0.5,0.,0.7071067811865475,-0.7071067811865477,1.05,0.,1.1,-0.5,0.55,-1.,0.7071067811865477,-0.7071067811865476,1.1090169943749475,-1.,1.1,-0.5,1.3,0.,1.4012585384440737,-0.535233134659635};
-  CPPUNIT_ASSERT_EQUAL(100,m3->getNodalConnectivity()->getNumberOfTuples());
-  CPPUNIT_ASSERT_EQUAL(13,m3->getNodalConnectivityIndex()->getNumberOfTuples());
-  CPPUNIT_ASSERT(std::equal(expected3,expected3+100,m3->getNodalConnectivity()->getConstPointer()));
-  CPPUNIT_ASSERT(std::equal(expected4,expected4+13,m3->getNodalConnectivityIndex()->getConstPointer()));
-  for(int i=0;i<176;i++)
+  CPPUNIT_ASSERT(std::equal(expected1,expected1+16,d1->getConstPointer()));
+  CPPUNIT_ASSERT(std::equal(expected2,expected2+16,d2->getConstPointer()));
+  const int expected3[136]={6,16,15,18,44,45,46,8,18,2,1,16,47,48,49,50,8,17,1,2,40,51,52,53,54,8,40,5,4,17,55,56,57,58,6,18,15,20,59,60,61,8,20,7,6,18,62,63,64,65,8,41,6,7,21,66,67,68,69,8,21,8,9,41,70,71,72,73,6,20,15,22,74,75,76,8,22,11,7,20,77,78,79,80,8,21,7,11,42,81,82,83,84,8,42,10,8,21,85,86,87,88,6,22,15,16,89,90,91,8,16,1,13,22,92,93,94,95,8,43,13,1,17,96,97,98,99,8,17,4,14,43,100,101,102,103};
+  const int expected4[17]={0,7,16,25,34,41,50,59,68,75,84,93,102,109,118,127,136};
+  const double expected5[208]={0.,0.,1.1, 0.,1.1,1.,0.,1.,1.7,0.,1.7,1.,-1.1,1.,-1.1,0.,-1.7,0.,-1.7,1.,-1.7,-1.,-1.1,-1.,0.,-1.,1.1,-1.,1.7,-1.,0.,0.,1.,0.,1.5,0.,0.,1.,0.,1.5,-1.,0.,-1.5,0.,0.,-1.,0.,-1.5,0.5,0.,1.25,0.,0.7071067811865476,0.7071067811865476,1.0606601717798214,1.0606601717798214,0.,0.5,0.,1.25,-0.7071067811865476,0.7071067811865476,-1.0606601717798214,1.0606601717798214,-0.5,0.,-1.25,0.,-0.7071067811865476,-0.7071067811865476,-1.0606601717798214,-1.0606601717798214,0.,-0.5,0.,-1.25,0.7071067811865476,-0.7071067811865476,1.0606601717798214,-1.0606601717798214,1.1180339887498951,1.,-1.1180339887498951,1.,-1.1180339887498951,-1.,1.1180339887498951,-1.,0.5,0.,0.,0.5,0.7071067811865477,0.7071067811865476,0.55,1.,1.1,0.5,1.05,0.,0.7071067811865477,0.7071067811865475,1.3,0.,1.1,0.5,1.1090169943749475,1.,1.4012585384440737,0.535233134659635,1.4090169943749475,1.,1.7,0.5,1.6,0.,1.4012585384440737,0.535233134659635,0.,0.5,-0.5,0.,-0.7071067811865477,0.7071067811865476,-1.05,0.,-1.1,0.5,-0.55,1.,-0.7071067811865478,0.7071067811865475,-1.1090169943749475,1.,-1.1,0.5,-1.3,0.,-1.4012585384440737,0.5352331346596344,-1.6,0.,-1.7,0.5,-1.4090169943749475,1.,-1.4012585384440737,0.5352331346596344,-0.5,0.,0.,-0.5,-0.7071067811865475,-0.7071067811865477,-0.55,-1.,-1.1,-0.5,-1.05,0.,-0.7071067811865475,-0.7071067811865477,-1.3,0.,-1.1,-0.5,-1.1090169943749475,-1.,-1.4012585384440734,-0.5352331346596354,-1.4090169943749475,-1.,-1.7,-0.5,-1.6,0.,-1.4012585384440732,-0.5352331346596354,0.,-0.5,0.5,0.,0.7071067811865475,-0.7071067811865477,1.05,0.,1.1,-0.5,0.55,-1.,0.7071067811865475,-0.7071067811865477,1.1090169943749475,-1.,1.1,-0.5,1.3,0.,1.4012585384440737,-0.535233134659635,1.6,0.,1.7,-0.5,1.4090169943749475,-1.,1.4012585384440737,-0.535233134659635};
+  CPPUNIT_ASSERT_EQUAL(136,m3->getNodalConnectivity()->getNumberOfTuples());
+  CPPUNIT_ASSERT_EQUAL(17,m3->getNodalConnectivityIndex()->getNumberOfTuples());
+  CPPUNIT_ASSERT(std::equal(expected3,expected3+136,m3->getNodalConnectivity()->getConstPointer()));
+  CPPUNIT_ASSERT(std::equal(expected4,expected4+17,m3->getNodalConnectivityIndex()->getConstPointer()));
+  for(int i=0;i<208;i++)
     CPPUNIT_ASSERT_DOUBLES_EQUAL(expected5[i],m3->getCoords()->getIJ(0,i),1e-12);
   d1->decrRef();
   d2->decrRef();
@@ -1554,3 +1554,121 @@ void MEDCouplingBasicsTest5::testDuplicateEachTupleNTimes1()
   d4->decrRef();
   d5->decrRef();
 }
+
+void MEDCouplingBasicsTest5::testIntersect2DMeshesTmp5()
+{
+  // coordinates
+  DataArrayDouble *coords=DataArrayDouble::New();
+  const double coordsData[376]={41,0,42,0,0,42,0,41,41.5,0,29.698484809834998,29.698484809834994,0,41.5,28.991378028648452,28.991378028648445,-42,0,-41,0,-29.698484809834994,29.698484809834998,-41.5,0,-28.991378028648445,28.991378028648452,0,-42,0,-41,-29.698484809835001,-29.698484809834994,0,-41.5,-28.991378028648455,-28.991378028648445,29.698484809834987,-29.698484809835001,28.991378028648441,-28.991378028648455,43,0,0,43,42.5,0,30.405591591021544,30.40559159102154,0,42.5,-43,0,-30.40559159102154,30.405591591021544,-42.5,0,0,-43,-30.405591591021551,-30.40559159102154,0,-42.5,30.405591591021537,-30.405591591021551,44,0,0,44,43.5,0,31.112698372208094,31.112698372208087,0,43.5,-44,0,-31.112698372208087,31.112698372208094,-43.5,0,0,-44,-31.112698372208097,-31.112698372208087,0,-43.5,31.112698372208083,-31.112698372208097,45,0,0,45,44.5,0,31.81980515339464,31.819805153394636,0,44.5,-45,0,-31.819805153394636,31.81980515339464,-44.5,0,0,-45,-31.819805153394647,-31.819805153394636,0,-44.5,31.819805153394629,-31.819805153394647,47,0,0,47,46,0,33.234018715767739,33.234018715767732,0,46,-47,0,-33.234018715767732,33.234018715767739,-46,0,0,-47,-33.234018715767739,-33.234018715767732,0,-46,33.234018715767725,-33.234018715767739,49,0,0,49,48,0,34.648232278140831,34.648232278140824,0,48,-49,0,-34.648232278140824,34.648232278140831,-48,0,0,-49,-34.648232278140839,-34.648232278140824,0,-48,34.648232278140817,-34.648232278140839,51,0,0,51,50,0,36.062445840513924,36.062445840513924,0,50,-51,0,-36.062445840513924,36.062445840513924,-50,0,0,-51,-36.062445840513931,-36.062445840513924,0,-50,36.062445840513917,-36.062445840513931,53,0,0,53,52,0,37.476659402887023,37.476659402887016,0,52,-53,0,-37.476659402887016,37.476659402887023,-52,0,0,-53,-37.47665940288703,-37.476659402887016,0,-52,37.476659402887009,-37.47665940288703,55,0,0,55,54,0,38.890872965260115,38.890872965260108,0,54,-55,0,-38.890872965260108,38.890872965260115,-54,0,0,-55,-38.890872965260122,-38.890872965260108,0,-54,38.890872965260101,-38.890872965260122,59,0,0,59,57,0,41.719300090006307,41.7193000900063,0,57,-59,0,-41.7193000900063,41.719300090006307,-57,0,0,-59,-41.719300090006314,-41.7193000900063,0,-57,41.719300090006293,-41.719300090006314,63,0,0,63,61,0,44.547727214752499,44.547727214752491,0,61,-63,0,-44.547727214752491,44.547727214752499,-61,0,0,-63,-44.547727214752506,-44.547727214752491,0,-61,44.547727214752484,-44.547727214752506,67,0,0,67,65,0,47.37615433949869,47.376154339498683,0,65,-67,0,-47.376154339498683,47.37615433949869,-65,0,0,-67,-47.376154339498697,-47.376154339498683,0,-65,47.376154339498676,-47.376154339498697,71,0,0,71,69,0,50.204581464244875,50.204581464244868,0,69,-71,0,-50.204581464244868,50.204581464244875,-69,0,0,-71,-50.204581464244889,-50.204581464244868,0,-69,50.20458146424486,-50.204581464244889,75,0,0,75,73,0,53.033008588991066,53.033008588991059,0,73,-75,0,-53.033008588991059,53.033008588991066,-73,0,0,-75,-53.033008588991073,-53.033008588991059,0,-73,53.033008588991052,-53.033008588991073,80,0,0,80,77.5,0,56.568542494923804,56.568542494923797,0,77.5,-80,0,-56.568542494923797,56.568542494923804,-77.5,0,0,-80,-56.568542494923818,-56.568542494923797,0,-77.5,56.56854249492379,-56.568542494923818};
+  coords->useArray(coordsData,false,CPP_DEALLOC,188,2);
+  coords->setName("");
+  DataArrayInt *conn=DataArrayInt::New();
+  const int connData[540]={8,0,1,2,3,4,5,6,7,8,3,2,8,9,6,10,11,12,8,9,8,13,14,11,15,16,17,8,14,13,1,0,16,18,4,19,8,1,20,21,2,22,23,24,5,8,2,21,25,8,24,26,27,10,8,8,25,28,13,27,29,30,15,8,13,28,20,1,30,31,22,18,8,20,32,33,21,34,35,36,23,8,21,33,37,25,36,38,39,26,8,25,37,40,28,39,41,42,29,8,28,40,32,20,42,43,34,31,8,32,44,45,33,46,47,48,35,8,33,45,49,37,48,50,51,38,8,37,49,52,40,51,53,54,41,8,40,52,44,32,54,55,46,43,8,44,56,57,45,58,59,60,47,8,45,57,61,49,60,62,63,50,8,49,61,64,52,63,65,66,53,8,52,64,56,44,66,67,58,55,8,56,68,69,57,70,71,72,59,8,57,69,73,61,72,74,75,62,8,61,73,76,64,75,77,78,65,8,64,76,68,56,78,79,70,67,8,68,80,81,69,82,83,84,71,8,69,81,85,73,84,86,87,74,8,73,85,88,76,87,89,90,77,8,76,88,80,68,90,91,82,79,8,80,92,93,81,94,95,96,83,8,81,93,97,85,96,98,99,86,8,85,97,100,88,99,101,102,89,8,88,100,92,80,102,103,94,91,8,92,104,105,93,106,107,108,95,8,93,105,109,97,108,110,111,98,8,97,109,112,100,111,113,114,101,8,100,112,104,92,114,115,106,103,8,104,116,117,105,118,119,120,107,8,105,117,121,109,120,122,123,110,8,109,121,124,112,123,125,126,113,8,112,124,116,104,126,127,118,115,8,116,128,129,117,130,131,132,119,8,117,129,133,121,132,134,135,122,8,121,133,136,124,135,137,138,125,8,124,136,128,116,138,139,130,127,8,128,140,141,129,142,143,144,131,8,129,141,145,133,144,146,147,134,8,133,145,148,136,147,149,150,137,8,136,148,140,128,150,151,142,139,8,140,152,153,141,154,155,156,143,8,141,153,157,145,156,158,159,146,8,145,157,160,148,159,161,162,149,8,148,160,152,140,162,163,154,151,8,152,164,165,153,166,167,168,155,8,153,165,169,157,168,170,171,158,8,157,169,172,160,171,173,174,161,8,160,172,164,152,174,175,166,163,8,164,176,177,165,178,179,180,167,8,165,177,181,169,180,182,183,170,8,169,181,184,172,183,185,186,173,8,172,184,176,164,186,187,178,175};
+  conn->useArray(connData,false,CPP_DEALLOC,540,1);
+  conn->setName("");
+  DataArrayInt *connI=DataArrayInt::New();
+  const int connIData[61]={0,9,18,27,36,45,54,63,72,81,90,99,108,117,126,135,144,153,162,171,180,189,198,207,216,225,234,243,252,261,270,279,288,297,306,315,324,333,342,351,360,369,378,387,396,405,414,423,432,441,450,459,468,477,486,495,504,513,522,531,540};
+  connI->useArray(connIData,false,CPP_DEALLOC,61,1);
+  connI->setName("");
+  //
+  MEDCouplingUMesh *m1=MEDCouplingUMesh::New("Fix",2);
+  m1->setCoords(coords);
+  m1->setConnectivity(conn,connI,true);
+  coords->decrRef(); conn->decrRef(); connI->decrRef();
+  //
+  coords=DataArrayDouble::New();
+  const double coordsData2[84]={46.5,-2.5,53.5,-2.5,53.5,2.5,46.5,2.5,50,-2.5,53.5,0,50,2.5,46.5,0,60.5,-2.5,60.5,2.5,57,-2.5,60.5,0,57,2.5,53.5,7.5,46.5,7.5,53.5,5,50,7.5,46.5,5,60.5,7.5,60.5,5,57,7.5,-2,47,2,47,2,53,-2,53,0,47,2,50,0,53,-2,50,6,47,6,53,4,47,6,50,4,53,2,59,-2,59,2,56,0,59,-2,56,6,59,6,56,4,59};
+  coords->useArray(coordsData2,false,CPP_DEALLOC,42,2);  
+  coords->setName("");
+  // connectivity
+  conn=DataArrayInt::New();
+  const int connData2[72]={8,0,1,2,3,4,5,6,7,8,1,8,9,2,10,11,12,5,8,3,2,13,14,6,15,16,17,8,2,9,18,13,12,19,20,15,8,21,22,23,24,25,26,27,28,8,22,29,30,23,31,32,33,26,8,24,23,34,35,27,36,37,38,8,23,30,39,34,33,40,41,36};
+  conn->useArray(connData2,false,CPP_DEALLOC,72,1);
+  conn->setName("");
+  connI=DataArrayInt::New();
+  const int connIData2[9]={0,9,18,27,36,45,54,63,72};
+  connI->useArray(connIData2,false,CPP_DEALLOC,9,1);
+  connI->setName("");
+  MEDCouplingUMesh *m2=MEDCouplingUMesh::New("Mobile",2);
+  m2->setCoords(coords);
+  m2->setConnectivity(conn,connI,true);
+  coords->decrRef(); conn->decrRef(); connI->decrRef();
+  //
+  DataArrayInt *d1=0,*d2=0;
+  MEDCouplingUMesh *m3=MEDCouplingUMesh::Intersect2DMeshes(m1,m2,1e-10,d1,d2);
+  CPPUNIT_ASSERT_EQUAL(105,m3->getNumberOfCells());
+  CPPUNIT_ASSERT_EQUAL(105,d1->getNumberOfTuples());
+  CPPUNIT_ASSERT_EQUAL(105,d2->getNumberOfTuples());
+  CPPUNIT_ASSERT_EQUAL(704,m3->getNumberOfNodes());
+  //
+  const double areaExpected[105]={-65.18804756198824,-65.18804756198824,-65.18804756198824,-65.18804756198824,-66.75884388878285,-66.75884388878285,-66.7588438887833,-66.75884388878308,-68.32964021557768,-68.32964021557768,-68.32964021557814,-68.32964021557791,-69.9004365423732,-69.9004365423732,-69.90043654237297,-69.90043654237297,-1.194568659706448,-1.0869994447159463,-142.2316939607081,-144.51326206513068,-144.5132620651309,-1.1945686597064424,-143.3186934054243,-5.002264310862817,-10.0261332846393,-3.9727823117092953,-7.290862524642649,-124.504404940456,-3.9727823117093237,-146.82366506060032,-150.79644737231024,-5.002264310862776,-145.79418306144626,-5.00208651738126,-10.054764051268958,-4.001067863263231,-8.027932154428669,-129.99378209314813,-4.001067863263216,-153.07856481622616,-157.0796326794898,-5.0020865173811915,-152.07754616210832,-5.001928880064381,-10.050590216368969,-4.00098721602491,-8.025810856794209,-136.28350081741684,-4.000987216024939,-159.36183077064402,-163.36281798667005,-5.0019288800643285,-158.36088910660442,-1.2991516319851801,-3.702636830195414,-3.7815130030068254,-6.265364371195623,-0.02516260900254963,-0.6553944641345026,-3.975752765070567,-7.368528340442765,-142.57249927881398,-0.02516260900254963,-3.9757527650706095,-165.64508791977525,-169.64600329384803,-1.299151631985167,-3.7026368301953885,-164.6442148316677,-10.00321285677458,-20.08414323176165,-8.001644468035863,-16.042954878437143,-304.0096070742277,-8.00164446803587,-350.1399180412005,-358.1415625092368,-10.003212856774468,-348.13834965246224,-3.794150313030109,-8.65049239704272,-0.02260276689354157,-0.5885167811200915,-370.2185414798688,-0.022602766893559393,-383.2517009710623,-383.2743037379555,-3.7941503130300576,-379.48015342492505,-408.40704496667513,-408.4070449666742,-408.4070449666742,-408.4070449666742,-433.53978619538975,-433.5397861953902,-433.5397861953911,-433.53978619539066,-458.67252742410983,-458.6725274241094,-458.67252742410983,-458.6725274241089,-608.6835766330232,-608.6835766330232,-608.6835766330232,-608.6835766330241};
+  const int expected1[105]={0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,16,16,17,18,19,19,20,20,20,20,20,21,21,22,23,23,24,24,24,24,24,25,25,26,27,27,28,28,28,28,28,29,29,30,31,31,32,32,32,32,32,32,32,32,32,33,33,33,34,35,35,35,36,36,36,36,36,37,37,38,39,39,40,40,40,40,40,41,41,42,43,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59};
+  const int expected2[105]={-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,0,2,-1,-1,-1,0,-1,0,2,4,5,-1,4,-1,-1,0,-1,0,2,4,5,-1,4,-1,-1,0,-1,0,2,4,5,-1,4,-1,-1,0,-1,0,1,2,3,4,5,6,7,-1,4,6,-1,-1,0,1,-1,1,3,6,7,-1,6,-1,-1,1,-1,1,3,6,7,-1,6,-1,-1,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1};
+  MEDCouplingFieldDouble *f3f=m3->getMeasureField(ON_CELLS);
+  const double *f3=f3f->getArray()->getConstPointer();
+  for(int i=0;i<105;i++)
+    {
+      CPPUNIT_ASSERT_DOUBLES_EQUAL(areaExpected[i],f3[i],1e-10);
+      CPPUNIT_ASSERT_EQUAL(expected1[i],d1->getIJ(i,0));
+      CPPUNIT_ASSERT_EQUAL(expected2[i],d2->getIJ(i,0));
+    }
+  //
+  f3f->decrRef();
+  m3->decrRef();
+  d1->decrRef();
+  d2->decrRef();
+  m2->decrRef();
+  m1->decrRef();
+}
+
+void MEDCouplingBasicsTest5::testDAIBuildUnique1()
+{
+  DataArrayInt *d=DataArrayInt::New();
+  const int dData[14]={1,2,2,3,3,3,3,4,5,5,7,7,7,19};
+  d->useArray(dData,false,CPP_DEALLOC,14,1);
+  const int expectedData[7]={1,2,3,4,5,7,19};
+  //
+  DataArrayInt *e=d->buildUnique();
+  CPPUNIT_ASSERT_EQUAL(7,e->getNumberOfTuples());
+  CPPUNIT_ASSERT_EQUAL(1,e->getNumberOfComponents());
+  for(int i=0;i<7;i++)
+    CPPUNIT_ASSERT_EQUAL(expectedData[i],e->getIJ(i,0));
+  //
+  e->decrRef();
+  d->decrRef();
+}
+
+void MEDCouplingBasicsTest5::testDAIPartitionByDifferentValues1()
+{
+  const int data[9]={1,0,1,2,0,2,2,-3,2};
+  const int expected1[4]={-3,0,1,2};
+  const int expected2_0[1]={7};
+  const int expected2_1[2]={1,4};
+  const int expected2_2[2]={0,2};
+  const int expected2_3[4]={3,5,6,8};
+  DataArrayInt *d=DataArrayInt::New();
+  d->useArray(data,false,CPP_DEALLOC,9,1);
+  std::vector<int> f;
+  static const int nbOfOutputsExpected=4;
+  std::vector<DataArrayInt *> e=d->partitionByDifferentValues(f);
+  d->decrRef();
+  CPPUNIT_ASSERT_EQUAL(nbOfOutputsExpected,(int)e.size());
+  CPPUNIT_ASSERT_EQUAL(nbOfOutputsExpected,(int)f.size());
+  for(int i=0;i<nbOfOutputsExpected;i++)
+    {
+      CPPUNIT_ASSERT_EQUAL(expected1[i],f[i]);
+    }
+  CPPUNIT_ASSERT_EQUAL(1,e[0]->getNbOfElems());
+  CPPUNIT_ASSERT_EQUAL(2,e[1]->getNbOfElems());
+  CPPUNIT_ASSERT_EQUAL(2,e[2]->getNbOfElems());
+  CPPUNIT_ASSERT_EQUAL(4,e[3]->getNbOfElems());
+  CPPUNIT_ASSERT_EQUAL(1,e[0]->getNumberOfComponents());
+  CPPUNIT_ASSERT_EQUAL(1,e[1]->getNumberOfComponents());
+  CPPUNIT_ASSERT_EQUAL(1,e[2]->getNumberOfComponents());
+  CPPUNIT_ASSERT_EQUAL(1,e[3]->getNumberOfComponents());
+  CPPUNIT_ASSERT(std::equal(expected2_0,expected2_0+1,e[0]->begin()));
+  CPPUNIT_ASSERT(std::equal(expected2_1,expected2_1+2,e[1]->begin()));
+  CPPUNIT_ASSERT(std::equal(expected2_2,expected2_2+2,e[2]->begin()));
+  CPPUNIT_ASSERT(std::equal(expected2_3,expected2_3+4,e[3]->begin()));
+  e[0]->decrRef(); e[1]->decrRef(); e[2]->decrRef(); e[3]->decrRef();
+}
index 0bc8432f6d1cded094c786a937768b616294b33d..1ee856333a77f0c01e8cade367922aa76ff27f8c 100644 (file)
@@ -66,6 +66,9 @@ namespace ParaMEDMEM
     CPPUNIT_TEST( testUnPolyze3 );
     CPPUNIT_TEST( testKrSpatialDiscretization1 );
     CPPUNIT_TEST( testDuplicateEachTupleNTimes1 );
+    CPPUNIT_TEST( testIntersect2DMeshesTmp5 );
+    CPPUNIT_TEST( testDAIBuildUnique1 );
+    CPPUNIT_TEST( testDAIPartitionByDifferentValues1 );
     CPPUNIT_TEST_SUITE_END();
   public:
     void testUMeshTessellate2D1();
@@ -98,6 +101,9 @@ namespace ParaMEDMEM
     void testUnPolyze3();
     void testKrSpatialDiscretization1();
     void testDuplicateEachTupleNTimes1();
+    void testIntersect2DMeshesTmp5();
+    void testDAIBuildUnique1();
+    void testDAIPartitionByDifferentValues1();
   };
 }
 
index 4f63e6fd3fd5f32e6ad69db3c74014280e6204c9..bc59a44def7662ccf5e8c429ecbc9191d590c7c6 100644 (file)
@@ -1993,6 +1993,7 @@ class MEDCouplingBasicsTest(unittest.TestCase):
         self.assertEqual(5,f.getNumberOfMeshPlacesExpected());
         self.assertEqual(0,f.getNbOfGaussLocalization());
         f.setGaussLocalizationOnType(NORM_TRI3,_refCoo1,_gsCoo1,_wg1);
+        f.setGaussLocalizationOnType(NORM_TRI3,_refCoo1,_gsCoo1,_wg1); # not a bug only to check that it works well
         self.assertRaises(InterpKernelException,f.setGaussLocalizationOnType,NORM_QUAD4,_refCoo1,_gsCoo1,_wg1)
         self.assertEqual(1,f.getNbOfGaussLocalization());
         refCoo2=[ 0.,0., 1.,0., 1.,1., 0.,1. ]
@@ -8218,20 +8219,20 @@ class MEDCouplingBasicsTest(unittest.TestCase):
         m2.translate([0.5,0.5])
         #
         m3,d1,d2=MEDCouplingUMesh.Intersect2DMeshes(m1bis,m2,1e-10)
-        expected1=[0,1,1,2,2]
-        expected2=[0,0,1,1,2]
-        self.assertEqual(5,d1.getNumberOfTuples());
-        self.assertEqual(5,d2.getNumberOfTuples());
-        self.assertEqual(5,m3.getNumberOfCells());
+        expected1=[0,0,1,1,1,2,2,2]
+        expected2=[0,-1,0,1,-1,1,2,-1]
+        self.assertEqual(8,d1.getNumberOfTuples());
+        self.assertEqual(8,d2.getNumberOfTuples());
+        self.assertEqual(8,m3.getNumberOfCells());
         self.assertEqual(22,m3.getNumberOfNodes());
         self.assertEqual(2,m3.getSpaceDimension());
         self.assertEqual(expected1,d1.getValues());
         self.assertEqual(expected2,d2.getValues());
-        expected3=[5,17,1,16,12,5,18,1,17,13,5,19,2,18,13,5,20,2,19,14,5,21,3,20,14]
-        expected4=[0,5,10,15,20,25]
+        expected3=[5,17,1,16,12,5,16,0,4,5,17,12,5,18,1,17,13,5,19,2,18,13,5,17,5,6,19,13,5,20,2,19,14,5,21,3,20,14,5,19,6,7,21,14]
+        expected4=[0,5,12,17,22,28,33,38,44]
         expected5=[-1.0,2.0,1.0,2.0,2.0,2.0,4.0,2.0,-1.0,4.0,1.0,4.0,2.0,4.0,4.0,4.0,-0.5,-1.5,1.5,-1.5,2.5,-1.5,4.5,-1.5,-0.5,2.5,1.5,2.5,2.5,2.5,4.5,2.5,-0.5,2.0,1.0,2.5,1.5,2.0,2.0,2.5,2.5,2.0,4.0,2.5]
-        self.assertEqual(25,m3.getNodalConnectivity().getNumberOfTuples());
-        self.assertEqual(6,m3.getNodalConnectivityIndex().getNumberOfTuples());
+        self.assertEqual(44,m3.getNodalConnectivity().getNumberOfTuples());
+        self.assertEqual(9,m3.getNodalConnectivityIndex().getNumberOfTuples());
         self.assertEqual(expected3,m3.getNodalConnectivity().getValues());
         self.assertEqual(expected4,m3.getNodalConnectivityIndex().getValues());
         for i in xrange(44):
@@ -8345,23 +8346,23 @@ class MEDCouplingBasicsTest(unittest.TestCase):
         m3,d1,d2=MEDCouplingUMesh.Intersect2DMeshes(m1,m2,1e-10)
         m3.unPolyze()
         #
-        expected1=[0,1,1,2,3,3,4,5,5,6,7,7]
-        expected2=[0,0,1,2,2,3,4,4,5,6,6,7]
-        self.assertEqual(12,d1.getNumberOfTuples());
-        self.assertEqual(12,d2.getNumberOfTuples());
-        self.assertEqual(12,m3.getNumberOfCells());
-        self.assertEqual(88,m3.getNumberOfNodes());
+        expected1=[0,1,1,1,2,3,3,3,4,5,5,5,6,7,7,7]
+        expected2=[0,0,1,-1,2,2,3,-1,4,4,5,-1,6,6,7,-1]
+        self.assertEqual(16,d1.getNumberOfTuples());
+        self.assertEqual(16,d2.getNumberOfTuples());
+        self.assertEqual(16,m3.getNumberOfCells());
+        self.assertEqual(104,m3.getNumberOfNodes());
         self.assertEqual(2,m3.getSpaceDimension());
         self.assertEqual(expected1,d1.getValues());
         self.assertEqual(expected2,d2.getValues());
-        expected3=[6,28,1,25,44,45,46,8,26,1,28,27,47,48,49,50,8,40,2,26,27,51,52,53,54,6,28,25,5,55,56,57,8,28,5,32,31,58,59,60,61,8,32,6,41,31,62,63,64,65,6,25,37,5,66,67,68,8,32,5,37,36,69,70,71,72,8,42,6,32,36,73,74,75,76,6,1,37,25,77,78,79,8,37,1,26,38,80,81,82,83,8,26,2,43,38,84,85,86,87]
-        expected4=[0,7,16,25,32,41,50,57,66,75,82,91,100]
-        expected5=[0.,0.,1.,0.,1.5,0.,0.,1.,0.,1.5,-1.,0.,-1.5,0.,0.,-1.,0.,-1.5,0.5,0.,1.25,0.,0.7071067811865476,0.7071067811865476,1.0606601717798214,1.0606601717798214,0.,0.5,0.,1.25,-0.7071067811865476,0.7071067811865476,-1.0606601717798214,1.0606601717798214,-0.5,0.,-1.25,0.,-0.7071067811865476,-0.7071067811865476,-1.0606601717798214,-1.0606601717798214,0.,-0.5,0.,-1.25,0.7071067811865476,-0.7071067811865476,1.0606601717798214,-1.0606601717798214,0.,0.,1.1,0.,1.1,1.,0.,1.,1.7,0.,1.7,1.,-1.1,1.,-1.1,0.,-1.7,0.,-1.7,1.,-1.7,-1.,-1.1,-1.,0.,-1.,1.1,-1.,1.7,-1.,1.118033988749895,1.,-1.118033988749895,1.,-1.118033988749895,-1.,1.118033988749895,-1.,0.7071067811865477,0.7071067811865476,0.5,0.,0.,0.5,1.05,0.,0.7071067811865475,0.7071067811865477,0.55,1.,1.1,0.5,1.4012585384440737,0.535233134659635,1.3,0.,1.1,0.5,1.1090169943749475,1.,0.,0.5,-0.5,0.,-0.7071067811865477,0.7071067811865476,-0.7071067811865475,0.7071067811865477,-1.05,0.,-1.1,0.5,-0.55,1.,-1.3,0.,-1.4012585384440737,0.5352331346596344,-1.1090169943749475,1.,-1.1,0.5,0.,-0.5,-0.7071067811865475,-0.7071067811865477,-0.5,0.,-1.05,0.,-0.7071067811865478,-0.7071067811865475,-0.55,-1.,-1.1,-0.5,-1.4012585384440732,-0.5352331346596354,-1.3,0.,-1.1,-0.5,-1.1090169943749475,-1.,0.7071067811865475,-0.7071067811865477,0.,-0.5,0.5,0.,0.7071067811865477,-0.7071067811865475,1.05,0.,1.1,-0.5,0.55,-1.,1.3,0.,1.4012585384440737,-0.535233134659635,1.1090169943749475,-1.,1.1,-0.5]
-        self.assertEqual(100,m3.getNodalConnectivity().getNumberOfTuples());
-        self.assertEqual(13,m3.getNodalConnectivityIndex().getNumberOfTuples());
+        expected3=[6,28,1,25,44,45,46,8,26,1,28,27,47,48,49,50,8,40,2,26,27,51,52,53,54,8,28,4,40,27,55,56,57,58,6,28,25,5,59,60,61,8,28,5,32,31,62,63,64,65,8,32,6,41,31,66,67,68,69,8,41,4,28,31,70,71,72,73,6,25,37,5,74,75,76,8,32,5,37,36,77,78,79,80,8,42,6,32,36,81,82,83,84,8,37,8,42,36,85,86,87,88,6,1,37,25,89,90,91,8,37,1,26,38,92,93,94,95,8,26,2,43,38,96,97,98,99,8,43,8,37,38,100,101,102,103]
+        expected4=[0,7,16,25,34,41,50,59,68,75,84,93,102,109,118,127,136]
+        expected5=[0.,0.,1.,0.,1.5,0.,0.,1.,0.,1.5,-1.,0.,-1.5,0.,0.,-1.,0.,-1.5,0.5,0.,1.25,0.,0.7071067811865476,0.7071067811865476,1.0606601717798214,1.0606601717798214,0.,0.5,0.,1.25,-0.7071067811865476,0.7071067811865476,-1.0606601717798214,1.0606601717798214,-0.5,0.,-1.25,0.,-0.7071067811865476,-0.7071067811865476,-1.0606601717798214,-1.0606601717798214,0.,-0.5,0.,-1.25,0.7071067811865476,-0.7071067811865476,1.0606601717798214,-1.0606601717798214,0.,0.,1.1,0.,1.1,1.,0.,1.,1.7,0.,1.7,1.,-1.1,1.,-1.1,0.,-1.7,0.,-1.7,1.,-1.7,-1.,-1.1,-1.,0.,-1.,1.1,-1.,1.7,-1.,1.118033988749895,1.,-1.118033988749895,1.,-1.118033988749895,-1.,1.118033988749895,-1.,0.7071067811865477,0.7071067811865476,0.5,0.,0.,0.5,1.05,0.,0.7071067811865475,0.7071067811865477,0.55,1.,1.1,0.5,1.4012585384440737,0.535233134659635,1.3,0.,1.1,0.5,1.1090169943749475,1.,0.,1.25,0.6123724356957946,1.369306393762915,1.1090169943749475,1.,0.55,1.,0.,0.5,-0.5,0.,-0.7071067811865477,0.7071067811865476,-0.7071067811865475,0.7071067811865477,-1.05,0.,-1.1,0.5,-0.55,1.,-1.3,0.,-1.4012585384440737,0.5352331346596344,-1.1090169943749475,1.,-1.1,0.5,-0.6123724356957941,1.3693063937629155,0.,1.25,-0.55,1.,-1.1090169943749475,1.,0.,-0.5,-0.7071067811865475,-0.7071067811865477,-0.5,0.,-1.05,0.,-0.7071067811865478,-0.7071067811865475,-0.55,-1.,-1.1,-0.5,-1.4012585384440734,-0.5352331346596354,-1.3,0.,-1.1,-0.5,-1.1090169943749475,-1.,0.,-1.25,-0.6123724356957945,-1.369306393762915,-1.1090169943749475,-1.,-0.55,-1.,0.7071067811865475,-0.7071067811865477,0.,-0.5,0.5,0.,0.7071067811865477,-0.7071067811865475,1.05,0.,1.1,-0.5,0.55,-1.,1.3,0.,1.4012585384440737,-0.535233134659635,1.1090169943749475,-1.,1.1,-0.5,0.6123724356957946,-1.369306393762915,0.,-1.25,0.55,-1.,1.1090169943749475,-1.0]
+        self.assertEqual(136,m3.getNodalConnectivity().getNumberOfTuples());
+        self.assertEqual(17,m3.getNodalConnectivityIndex().getNumberOfTuples());
         self.assertEqual(expected3,m3.getNodalConnectivity().getValues());
         self.assertEqual(expected4,m3.getNodalConnectivityIndex().getValues());
-        for i in xrange(176):
+        for i in xrange(208):
             self.assertAlmostEqual(expected5[i],m3.getCoords().getIJ(0,i),12);
             pass
         pass
@@ -8445,23 +8446,23 @@ class MEDCouplingBasicsTest(unittest.TestCase):
         m3,d1,d2=MEDCouplingUMesh.Intersect2DMeshes(m2,m1,1e-10)
         m3.unPolyze()
         #
-        expected1=[0,0,1,2,2,3,4,4,5,6,6,7]
-        expected2=[0,1,1,2,3,3,4,5,5,6,7,7]
-        self.assertEqual(12,d1.getNumberOfTuples());
-        self.assertEqual(12,d2.getNumberOfTuples());
-        self.assertEqual(12,m3.getNumberOfCells());
-        self.assertEqual(88,m3.getNumberOfNodes());
+        expected1=[0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7]
+        expected2=[0,1,1,-1,2,3,3,-1,4,5,5,-1,6,7,7,-1]
+        self.assertEqual(16,d1.getNumberOfTuples());
+        self.assertEqual(16,d2.getNumberOfTuples());
+        self.assertEqual(16,m3.getNumberOfCells());
+        self.assertEqual(104,m3.getNumberOfNodes());
         self.assertEqual(2,m3.getSpaceDimension());
         self.assertEqual(expected1,d1.getValues());
         self.assertEqual(expected2,d2.getValues());
-        expected3=[6,16,15,18,44,45,46,8,18,2,1,16,47,48,49,50,8,17,1,2,40,51,52,53,54,6,18,15,20,55,56,57,8,20,7,6,18,58,59,60,61,8,41,6,7,21,62,63,64,65,6,20,15,22,66,67,68,8,22,11,7,20,69,70,71,72,8,21,7,11,42,73,74,75,76,6,22,15,16,77,78,79,8,16,1,13,22,80,81,82,83,8,43,13,1,17,84,85,86,87]
-        expected4=[0,7,16,25,32,41,50,57,66,75,82,91,100]
-        expected5=[0.,0.,1.1,0.,1.1,1.,0.,1.,1.7,0.,1.7,1.,-1.1,1.,-1.1,0.,-1.7,0.,-1.7,1.,-1.7,-1.,-1.1,-1.,0.,-1.,1.1,-1.,1.7,-1.,0.,0.,1.,0.,1.5,0.,0.,1.,0.,1.5,-1.,0.,-1.5,0.,0.,-1.,0.,-1.5,0.5,0.,1.25,0.,0.7071067811865476,0.7071067811865476,1.0606601717798214,1.0606601717798214,0.,0.5,0.,1.25,-0.7071067811865476,0.7071067811865476,-1.0606601717798214,1.0606601717798214,-0.5,0.,-1.25,0.,-0.7071067811865476,-0.7071067811865476,-1.0606601717798214,-1.0606601717798214,0.,-0.5,0.,-1.25,0.7071067811865476,-0.7071067811865476,1.0606601717798214,-1.0606601717798214,1.1180339887498951,1.,-1.1180339887498951,1.,-1.1180339887498951,-1.,1.1180339887498951,-1.,0.5,0.,0.,0.5,0.7071067811865477,0.7071067811865476,0.55,1.,1.1,0.5,1.05,0.,0.7071067811865477,0.7071067811865477,1.3,0.,1.1,0.5,1.1090169943749475,1.,1.4012585384440737,0.535233134659635,0.,0.5,-0.5,0.,-0.7071067811865477,0.7071067811865476,-1.05,0.,-1.1,0.5,-0.55,1.,-0.7071067811865477,0.7071067811865477,-1.1090169943749475,1.,-1.1,0.5,-1.3,0.,-1.4012585384440737,0.5352331346596344,-0.5,0.,0.,-0.5,-0.7071067811865475,-0.7071067811865477,-0.55,-1.,-1.1,-0.5,-1.05,0.,-0.7071067811865479,-0.7071067811865476,-1.3,0.,-1.1,-0.5,-1.1090169943749475,-1.,-1.4012585384440734,-0.5352331346596354,0.,-0.5,0.5,0.,0.7071067811865475,-0.7071067811865477,1.05,0.,1.1,-0.5,0.55,-1.,0.7071067811865477,-0.7071067811865476,1.1090169943749475,-1.,1.1,-0.5,1.3,0.,1.4012585384440737,-0.535233134659635]
-        self.assertEqual(100,m3.getNodalConnectivity().getNumberOfTuples());
-        self.assertEqual(13,m3.getNodalConnectivityIndex().getNumberOfTuples());
+        expected3=[6,16,15,18,44,45,46,8,18,2,1,16,47,48,49,50,8,17,1,2,40,51,52,53,54,8,40,5,4,17,55,56,57,58,6,18,15,20,59,60,61,8,20,7,6,18,62,63,64,65,8,41,6,7,21,66,67,68,69,8,21,8,9,41,70,71,72,73,6,20,15,22,74,75,76,8,22,11,7,20,77,78,79,80,8,21,7,11,42,81,82,83,84,8,42,10,8,21,85,86,87,88,6,22,15,16,89,90,91,8,16,1,13,22,92,93,94,95,8,43,13,1,17,96,97,98,99,8,17,4,14,43,100,101,102,103]
+        expected4=[0,7,16,25,34,41,50,59,68,75,84,93,102,109,118,127,136]
+        expected5=[0.,0.,1.1, 0.,1.1,1.,0.,1.,1.7,0.,1.7,1.,-1.1,1.,-1.1,0.,-1.7,0.,-1.7,1.,-1.7,-1.,-1.1,-1.,0.,-1.,1.1,-1.,1.7,-1.,0.,0.,1.,0.,1.5,0.,0.,1.,0.,1.5,-1.,0.,-1.5,0.,0.,-1.,0.,-1.5,0.5,0.,1.25,0.,0.7071067811865476,0.7071067811865476,1.0606601717798214,1.0606601717798214,0.,0.5,0.,1.25,-0.7071067811865476,0.7071067811865476,-1.0606601717798214,1.0606601717798214,-0.5,0.,-1.25,0.,-0.7071067811865476,-0.7071067811865476,-1.0606601717798214,-1.0606601717798214,0.,-0.5,0.,-1.25,0.7071067811865476,-0.7071067811865476,1.0606601717798214,-1.0606601717798214,1.1180339887498951,1.,-1.1180339887498951,1.,-1.1180339887498951,-1.,1.1180339887498951,-1.,0.5,0.,0.,0.5,0.7071067811865477,0.7071067811865476,0.55,1.,1.1,0.5,1.05,0.,0.7071067811865477,0.7071067811865475,1.3,0.,1.1,0.5,1.1090169943749475,1.,1.4012585384440737,0.535233134659635,1.4090169943749475,1.,1.7,0.5,1.6,0.,1.4012585384440737,0.535233134659635,0.,0.5,-0.5,0.,-0.7071067811865477,0.7071067811865476,-1.05,0.,-1.1,0.5,-0.55,1.,-0.7071067811865478,0.7071067811865475,-1.1090169943749475,1.,-1.1,0.5,-1.3,0.,-1.4012585384440737,0.5352331346596344,-1.6,0.,-1.7,0.5,-1.4090169943749475,1.,-1.4012585384440737,0.5352331346596344,-0.5,0.,0.,-0.5,-0.7071067811865475,-0.7071067811865477,-0.55,-1.,-1.1,-0.5,-1.05,0.,-0.7071067811865475,-0.7071067811865477,-1.3,0.,-1.1,-0.5,-1.1090169943749475,-1.,-1.4012585384440734,-0.5352331346596354,-1.4090169943749475,-1.,-1.7,-0.5,-1.6,0.,-1.4012585384440732,-0.5352331346596354,0.,-0.5,0.5,0.,0.7071067811865475,-0.7071067811865477,1.05,0.,1.1,-0.5,0.55,-1.,0.7071067811865475,-0.7071067811865477,1.1090169943749475,-1.,1.1,-0.5,1.3,0.,1.4012585384440737,-0.535233134659635,1.6,0.,1.7,-0.5,1.4090169943749475,-1.,1.4012585384440737,-0.535233134659635]
+        self.assertEqual(136,m3.getNodalConnectivity().getNumberOfTuples());
+        self.assertEqual(17,m3.getNodalConnectivityIndex().getNumberOfTuples());
         self.assertEqual(expected3,m3.getNodalConnectivity().getValues());
         self.assertEqual(expected4,m3.getNodalConnectivityIndex().getValues());
-        for i in xrange(176):
+        for i in xrange(208):
             self.assertAlmostEqual(expected5[i],m3.getCoords().getIJ(0,i),12);
             pass
         pass
@@ -9243,6 +9244,54 @@ class MEDCouplingBasicsTest(unittest.TestCase):
         self.assertRaises(InterpKernelException,DataArrayDouble.New,vals,7,2);
         pass
 
+    def testSwigDADOp9(self):
+        l1=[(1.,2.,3),(4.,5.,6.),(7.,8.,9.),[10.,11.,12.]]
+        da1=DataArrayDouble(l1,4,3)
+        self.assertEqual(4,da1.getNumberOfTuples());
+        self.assertEqual(3,da1.getNumberOfComponents());
+        da2=DataArrayDouble(12) ; da2.iota(1.) ; da2.rearrange(3)
+        self.assertTrue(da2.isEqual(da1,1e-12))
+        self.assertRaises(InterpKernelException,DataArrayDouble.New,l1,3,4);
+        da3=DataArrayDouble(l1,4)
+        self.assertTrue(da3.isEqual(da1,1e-12))
+        self.assertRaises(InterpKernelException,DataArrayDouble.New,l1,3);
+        self.assertRaises(InterpKernelException,DataArrayDouble.New,l1,5);
+        l1=[(1.,2.,3),(4.,(5.),((6.))),(7.,8.,9.),[10.,11.,12.]]
+        da1=DataArrayDouble(l1,4,3)
+        self.assertEqual(4,da1.getNumberOfTuples());
+        self.assertEqual(3,da1.getNumberOfComponents());
+        da2=DataArrayDouble(12) ; da2.iota(1.) ; da2.rearrange(3)
+        self.assertTrue(da2.isEqual(da1,1e-12))
+        self.assertRaises(InterpKernelException,DataArrayDouble.New,l1,3,4);
+        da3=DataArrayDouble(l1,4)
+        self.assertTrue(da3.isEqual(da1,1e-12))
+        self.assertRaises(InterpKernelException,DataArrayDouble.New,l1,3);
+        self.assertRaises(InterpKernelException,DataArrayDouble.New,l1,5);
+        #
+        l1=[(1,2,3),(4,5,6),(7,8,9),[10,11,12]]
+        da1=DataArrayInt(l1,4,3)
+        self.assertEqual(4,da1.getNumberOfTuples());
+        self.assertEqual(3,da1.getNumberOfComponents());
+        da2=DataArrayInt(12) ; da2.iota(1) ; da2.rearrange(3)
+        self.assertTrue(da2.isEqual(da1))
+        self.assertRaises(InterpKernelException,DataArrayInt.New,l1,3,4);
+        da3=DataArrayInt(l1,4)
+        self.assertTrue(da3.isEqual(da1))
+        self.assertRaises(InterpKernelException,DataArrayInt.New,l1,3);
+        self.assertRaises(InterpKernelException,DataArrayInt.New,l1,5);
+        l1=[(1,[2],3),(4,[(5)],6),((([7])),8,9),[10,11,12]]
+        da1=DataArrayInt(l1,4,3)
+        self.assertEqual(4,da1.getNumberOfTuples());
+        self.assertEqual(3,da1.getNumberOfComponents());
+        da2=DataArrayInt(12) ; da2.iota(1) ; da2.rearrange(3)
+        self.assertTrue(da2.isEqual(da1))
+        self.assertRaises(InterpKernelException,DataArrayInt.New,l1,3,4);
+        da3=DataArrayInt(l1,4)
+        self.assertTrue(da3.isEqual(da1))
+        self.assertRaises(InterpKernelException,DataArrayInt.New,l1,3);
+        self.assertRaises(InterpKernelException,DataArrayInt.New,l1,5);
+        pass
+
     def testRenumberNodesInConn1(self):
         mesh2DCoords=[-0.3,-0.3,0., 0.2,-0.3,0., 0.7,-0.3,0., -0.3,0.2,0., 0.2,0.2,0., 0.7,0.2,0., -0.3,0.7,0., 0.2,0.7,0., 0.7,0.7,0. ]
         mesh2DConn=[1,4,2, 4,5,2, 0,3,4,1, 6,7,4,3, 7,8,5,4]
@@ -10230,6 +10279,124 @@ class MEDCouplingBasicsTest(unittest.TestCase):
         self.assertEqual(d.getValues(),[1,2,0,1,2,0,1,2,0,1])
         pass
 
+    def testIntersect2DMeshesTmp5(self):
+        coords=DataArrayDouble.New([41,0,42,0,0,42,0,41,41.5,0,29.698484809834998,29.698484809834994,0,41.5,28.991378028648452,28.991378028648445,-42,0,-41,0,-29.698484809834994,29.698484809834998,-41.5,0,-28.991378028648445,28.991378028648452,0,-42,0,-41,-29.698484809835001,-29.698484809834994,0,-41.5,-28.991378028648455,-28.991378028648445,29.698484809834987,-29.698484809835001,28.991378028648441,-28.991378028648455,43,0,0,43,42.5,0,30.405591591021544,30.40559159102154,0,42.5,-43,0,-30.40559159102154,30.405591591021544,-42.5,0,0,-43,-30.405591591021551,-30.40559159102154,0,-42.5,30.405591591021537,-30.405591591021551,44,0,0,44,43.5,0,31.112698372208094,31.112698372208087,0,43.5,-44,0,-31.112698372208087,31.112698372208094,-43.5,0,0,-44,-31.112698372208097,-31.112698372208087,0,-43.5,31.112698372208083,-31.112698372208097,45,0,0,45,44.5,0,31.81980515339464,31.819805153394636,0,44.5,-45,0,-31.819805153394636,31.81980515339464,-44.5,0,0,-45,-31.819805153394647,-31.819805153394636,0,-44.5,31.819805153394629,-31.819805153394647,47,0,0,47,46,0,33.234018715767739,33.234018715767732,0,46,-47,0,-33.234018715767732,33.234018715767739,-46,0,0,-47,-33.234018715767739,-33.234018715767732,0,-46,33.234018715767725,-33.234018715767739,49,0,0,49,48,0,34.648232278140831,34.648232278140824,0,48,-49,0,-34.648232278140824,34.648232278140831,-48,0,0,-49,-34.648232278140839,-34.648232278140824,0,-48,34.648232278140817,-34.648232278140839,51,0,0,51,50,0,36.062445840513924,36.062445840513924,0,50,-51,0,-36.062445840513924,36.062445840513924,-50,0,0,-51,-36.062445840513931,-36.062445840513924,0,-50,36.062445840513917,-36.062445840513931,53,0,0,53,52,0,37.476659402887023,37.476659402887016,0,52,-53,0,-37.476659402887016,37.476659402887023,-52,0,0,-53,-37.47665940288703,-37.476659402887016,0,-52,37.476659402887009,-37.47665940288703,55,0,0,55,54,0,38.890872965260115,38.890872965260108,0,54,-55,0,-38.890872965260108,38.890872965260115,-54,0,0,-55,-38.890872965260122,-38.890872965260108,0,-54,38.890872965260101,-38.890872965260122,59,0,0,59,57,0,41.719300090006307,41.7193000900063,0,57,-59,0,-41.7193000900063,41.719300090006307,-57,0,0,-59,-41.719300090006314,-41.7193000900063,0,-57,41.719300090006293,-41.719300090006314,63,0,0,63,61,0,44.547727214752499,44.547727214752491,0,61,-63,0,-44.547727214752491,44.547727214752499,-61,0,0,-63,-44.547727214752506,-44.547727214752491,0,-61,44.547727214752484,-44.547727214752506,67,0,0,67,65,0,47.37615433949869,47.376154339498683,0,65,-67,0,-47.376154339498683,47.37615433949869,-65,0,0,-67,-47.376154339498697,-47.376154339498683,0,-65,47.376154339498676,-47.376154339498697,71,0,0,71,69,0,50.204581464244875,50.204581464244868,0,69,-71,0,-50.204581464244868,50.204581464244875,-69,0,0,-71,-50.204581464244889,-50.204581464244868,0,-69,50.20458146424486,-50.204581464244889,75,0,0,75,73,0,53.033008588991066,53.033008588991059,0,73,-75,0,-53.033008588991059,53.033008588991066,-73,0,0,-75,-53.033008588991073,-53.033008588991059,0,-73,53.033008588991052,-53.033008588991073,80,0,0,80,77.5,0,56.568542494923804,56.568542494923797,0,77.5,-80,0,-56.568542494923797,56.568542494923804,-77.5,0,0,-80,-56.568542494923818,-56.568542494923797,0,-77.5,56.56854249492379,-56.568542494923818],188,2)
+        conn=DataArrayInt.New([8,0,1,2,3,4,5,6,7,8,3,2,8,9,6,10,11,12,8,9,8,13,14,11,15,16,17,8,14,13,1,0,16,18,4,19,8,1,20,21,2,22,23,24,5,8,2,21,25,8,24,26,27,10,8,8,25,28,13,27,29,30,15,8,13,28,20,1,30,31,22,18,8,20,32,33,21,34,35,36,23,8,21,33,37,25,36,38,39,26,8,25,37,40,28,39,41,42,29,8,28,40,32,20,42,43,34,31,8,32,44,45,33,46,47,48,35,8,33,45,49,37,48,50,51,38,8,37,49,52,40,51,53,54,41,8,40,52,44,32,54,55,46,43,8,44,56,57,45,58,59,60,47,8,45,57,61,49,60,62,63,50,8,49,61,64,52,63,65,66,53,8,52,64,56,44,66,67,58,55,8,56,68,69,57,70,71,72,59,8,57,69,73,61,72,74,75,62,8,61,73,76,64,75,77,78,65,8,64,76,68,56,78,79,70,67,8,68,80,81,69,82,83,84,71,8,69,81,85,73,84,86,87,74,8,73,85,88,76,87,89,90,77,8,76,88,80,68,90,91,82,79,8,80,92,93,81,94,95,96,83,8,81,93,97,85,96,98,99,86,8,85,97,100,88,99,101,102,89,8,88,100,92,80,102,103,94,91,8,92,104,105,93,106,107,108,95,8,93,105,109,97,108,110,111,98,8,97,109,112,100,111,113,114,101,8,100,112,104,92,114,115,106,103,8,104,116,117,105,118,119,120,107,8,105,117,121,109,120,122,123,110,8,109,121,124,112,123,125,126,113,8,112,124,116,104,126,127,118,115,8,116,128,129,117,130,131,132,119,8,117,129,133,121,132,134,135,122,8,121,133,136,124,135,137,138,125,8,124,136,128,116,138,139,130,127,8,128,140,141,129,142,143,144,131,8,129,141,145,133,144,146,147,134,8,133,145,148,136,147,149,150,137,8,136,148,140,128,150,151,142,139,8,140,152,153,141,154,155,156,143,8,141,153,157,145,156,158,159,146,8,145,157,160,148,159,161,162,149,8,148,160,152,140,162,163,154,151,8,152,164,165,153,166,167,168,155,8,153,165,169,157,168,170,171,158,8,157,169,172,160,171,173,174,161,8,160,172,164,152,174,175,166,163,8,164,176,177,165,178,179,180,167,8,165,177,181,169,180,182,183,170,8,169,181,184,172,183,185,186,173,8,172,184,176,164,186,187,178,175],540)
+        connI=DataArrayInt.New([0,9,18,27,36,45,54,63,72,81,90,99,108,117,126,135,144,153,162,171,180,189,198,207,216,225,234,243,252,261,270,279,288,297,306,315,324,333,342,351,360,369,378,387,396,405,414,423,432,441,450,459,468,477,486,495,504,513,522,531,540],61)
+        #
+        m1=MEDCouplingUMesh.New("Fix",2);
+        m1.setCoords(coords);
+        m1.setConnectivity(conn,connI,True);
+        #
+        coords=DataArrayDouble([46.5,-2.5,53.5,-2.5,53.5,2.5,46.5,2.5,50,-2.5,53.5,0,50,2.5,46.5,0,60.5,-2.5,60.5,2.5,57,-2.5,60.5,0,57,2.5,53.5,7.5,46.5,7.5,53.5,5,50,7.5,46.5,5,60.5,7.5,60.5,5,57,7.5,-2,47,2,47,2,53,-2,53,0,47,2,50,0,53,-2,50,6,47,6,53,4,47,6,50,4,53,2,59,-2,59,2,56,0,59,-2,56,6,59,6,56,4,59],42,2)
+        # connectivity
+        conn=DataArrayInt([8,0,1,2,3,4,5,6,7,8,1,8,9,2,10,11,12,5,8,3,2,13,14,6,15,16,17,8,2,9,18,13,12,19,20,15,8,21,22,23,24,25,26,27,28,8,22,29,30,23,31,32,33,26,8,24,23,34,35,27,36,37,38,8,23,30,39,34,33,40,41,36],72);
+        conn.setName("");
+        connI=DataArrayInt([0,9,18,27,36,45,54,63,72],9)
+        m2=MEDCouplingUMesh.New("Mobile",2);
+        m2.setCoords(coords);
+        m2.setConnectivity(conn,connI,True);
+        #
+        m3,d1,d2=MEDCouplingUMesh.Intersect2DMeshes(m1,m2,1e-10);
+        self.assertEqual(105,m3.getNumberOfCells());
+        self.assertEqual(105,d1.getNumberOfTuples());
+        self.assertEqual(105,d2.getNumberOfTuples());
+        self.assertEqual(704,m3.getNumberOfNodes());
+        #
+        areaExpected=[-65.18804756198824,-65.18804756198824,-65.18804756198824,-65.18804756198824,-66.75884388878285,-66.75884388878285,-66.7588438887833,-66.75884388878308,-68.32964021557768,-68.32964021557768,-68.32964021557814,-68.32964021557791,-69.9004365423732,-69.9004365423732,-69.90043654237297,-69.90043654237297,-1.194568659706448,-1.0869994447159463,-142.2316939607081,-144.51326206513068,-144.5132620651309,-1.1945686597064424,-143.3186934054243,-5.002264310862817,-10.0261332846393,-3.9727823117092953,-7.290862524642649,-124.504404940456,-3.9727823117093237,-146.82366506060032,-150.79644737231024,-5.002264310862776,-145.79418306144626,-5.00208651738126,-10.054764051268958,-4.001067863263231,-8.027932154428669,-129.99378209314813,-4.001067863263216,-153.07856481622616,-157.0796326794898,-5.0020865173811915,-152.07754616210832,-5.001928880064381,-10.050590216368969,-4.00098721602491,-8.025810856794209,-136.28350081741684,-4.000987216024939,-159.36183077064402,-163.36281798667005,-5.0019288800643285,-158.36088910660442,-1.2991516319851801,-3.702636830195414,-3.7815130030068254,-6.265364371195623,-0.02516260900254963,-0.6553944641345026,-3.975752765070567,-7.368528340442765,-142.57249927881398,-0.02516260900254963,-3.9757527650706095,-165.64508791977525,-169.64600329384803,-1.299151631985167,-3.7026368301953885,-164.6442148316677,-10.00321285677458,-20.08414323176165,-8.001644468035863,-16.042954878437143,-304.0096070742277,-8.00164446803587,-350.1399180412005,-358.1415625092368,-10.003212856774468,-348.13834965246224,-3.794150313030109,-8.65049239704272,-0.02260276689354157,-0.5885167811200915,-370.2185414798688,-0.022602766893559393,-383.2517009710623,-383.2743037379555,-3.7941503130300576,-379.48015342492505,-408.40704496667513,-408.4070449666742,-408.4070449666742,-408.4070449666742,-433.53978619538975,-433.5397861953902,-433.5397861953911,-433.53978619539066,-458.67252742410983,-458.6725274241094,-458.67252742410983,-458.6725274241089,-608.6835766330232,-608.6835766330232,-608.6835766330232,-608.6835766330241]
+        expected1=[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,16,16,17,18,19,19,20,20,20,20,20,21,21,22,23,23,24,24,24,24,24,25,25,26,27,27,28,28,28,28,28,29,29,30,31,31,32,32,32,32,32,32,32,32,32,33,33,33,34,35,35,35,36,36,36,36,36,37,37,38,39,39,40,40,40,40,40,41,41,42,43,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59]
+        expected2=[-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,0,2,-1,-1,-1,0,-1,0,2,4,5,-1,4,-1,-1,0,-1,0,2,4,5,-1,4,-1,-1,0,-1,0,2,4,5,-1,4,-1,-1,0,-1,0,1,2,3,4,5,6,7,-1,4,6,-1,-1,0,1,-1,1,3,6,7,-1,6,-1,-1,1,-1,1,3,6,7,-1,6,-1,-1,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1]
+        f3=m3.getMeasureField(ON_CELLS).getArray().getValues();
+        for i in xrange(105):
+            self.assertAlmostEqual(areaExpected[i],f3[i],10)
+            pass
+        self.assertEqual(expected1,d1.getValues())
+        self.assertEqual(expected2,d2.getValues())
+        pass
+
+    def testDAIBuildUnique1(self):
+        d=DataArrayInt([1,2,2,3,3,3,3,4,5,5,7,7,7,19])
+        e=d.buildUnique()
+        self.assertTrue(e.isEqual(DataArrayInt([1,2,3,4,5,7,19])))
+        pass
+
+    def testDAIPartitionByDifferentValues1(self):
+        d=DataArrayInt([1,0,1,2,0,2,2,-3,2])
+        expected=[[-3,[7]],[0,[1,4]],[1,[0,2]],[2,[3,5,6,8]]]
+        for i,elt in enumerate(zip(*d.partitionByDifferentValues())):
+            self.assertEqual(expected[i][0],elt[1])
+            self.assertEqual(expected[i][1],elt[0].getValues())
+            pass
+        pass
+
+    def testFieldGaussMultiDiscPerType1(self):
+        coords=DataArrayDouble([0.,0.,0.,1.,1.,1.,1.,0.,0.,0.5,0.5,1.,1.,0.5,0.5,0.],8,2)
+        mQ8=MEDCouplingUMesh("",2) ; mQ8.setCoords(coords)
+        mQ8.allocateCells(1)
+        mQ8.insertNextCell(NORM_QUAD8,range(8))
+        mQ8.finishInsertingCells()
+        mQ4=MEDCouplingUMesh("",2) ; mQ4.setCoords(coords)
+        mQ4.allocateCells(1)
+        mQ4.insertNextCell(NORM_QUAD4,range(4))
+        mQ4.finishInsertingCells()
+        mT3=MEDCouplingUMesh("",2) ; mT3.setCoords(coords)
+        mT3.allocateCells(1)
+        mT3.insertNextCell(NORM_TRI3,range(3))
+        mT3.finishInsertingCells()
+        
+        tr=[[0.,0.],[2.,0.], [0.,2.],[2.,2.],[4.,2.],[6.,2.],[8.,2.],[10.,2.],[12.,2.],[0.,4.],[2.,4.],[4.,4.],[6.,4.],[8.,4.],[10.,4.],[12.,4.],[14.,4.],[16.,4.],[18.,4.],[20.,4.],[22.,4.]]
+        ms=2*[mQ4]+7*[mQ8]+11*[mT3]
+        ms[:]=(elt.deepCpy() for elt in ms)
+        for m,t in zip(ms,tr):
+            d=m.getCoords() ; d+= t
+            pass
+        m=MEDCouplingUMesh.MergeUMeshes(ms)
+        f=MEDCouplingFieldDouble.New(ON_GAUSS_PT,NO_TIME)
+        f.setMesh(m)
+        # throw because cell 0,1 are QUAD4 and cell 3 is QUAD8
+        self.assertRaises(InterpKernelException,f.setGaussLocalizationOnCells,[0,1,3],[0.,0.,1.,0.,1.,1.,0.,1.],[0.3,0.3,0.7,0.7],[0.8,0.2])
+        f.setGaussLocalizationOnCells([0,1],[0.,0.,1.,0.,1.,1.,0.,1.],[0.3,0.3,0.7,0.7],[0.8,0.2])
+        f.setGaussLocalizationOnCells([3,2,5],[0.,0.,1.,0.,1.,1.,0.,1.,0.5,0.,1.,0.5,0.5,1.,0.,0.5],[0.3,0.3,0.7,0.7,0.9,0.9],[0.8,0.05,0.15])
+        f.setGaussLocalizationOnCells([4,6,8,7],[0.,0.,1.,0.,1.,1.,0.,1.,0.5,0.,1.,0.5,0.5,1.,0.,0.5],[0.3,0.3,0.7,0.7,0.9,0.9,-0.1,0.3],[0.7,0.05,0.15,0.1])
+        f.setGaussLocalizationOnCells([9,10,11,12,13],[0.,0.,1.,0.,1.,1.],[0.4,0.4],[1.])
+        f.setGaussLocalizationOnCells([14,15,16,17,18,19],[0.,0.,1.,0.,1.,1.],[0.4,0.4,0.14,0.16],[0.22,0.78])
+        self.assertEqual(46,f.getNumberOfTuplesExpected())
+        vals=DataArrayDouble.New(46*3,1) ; vals.iota(7.7) ; vals.rearrange(3)
+        f.setArray(vals)
+        f.checkCoherency()
+        #f.getLocalizationOfDiscr()
+        self.assertRaises(InterpKernelException,f.getGaussLocalizationIdOfOneType,NORM_QUAD8) #throw because several loc
+        self.assertEqual([1,2],f.getGaussLocalizationIdsOfOneType(NORM_QUAD8))
+        self.assertEqual([0,0,1,1,2,1,2,2,2,3,3,3,3,3,4,4,4,4,4,4],f.getDiscretization().getArrayOfDiscIds().getValues())
+        fc=f[[1,2,3,8]]
+        fc.checkCoherency()
+        self.assertTrue(DataArrayDouble([13.7,14.7,15.7,16.7,17.7,18.7,19.7,20.7,21.7,22.7,23.7,24.7,25.7,26.7,27.7,28.7,29.7,30.7,31.7,32.7,33.7,34.7,35.7,36.7,82.7,83.7,84.7,85.7,86.7,87.7,88.7,89.7,90.7,91.7,92.7,93.7],12,3).isEqual(fc.getArray(),1e-10))
+        fc.renumberCells([3,2,0,1])
+        self.assertTrue(DataArrayDouble([28.7, 29.7, 30.7, 31.7, 32.7, 33.7, 34.7, 35.7, 36.7, 82.7, 83.7, 84.7, 85.7, 86.7, 87.7, 88.7, 89.7, 90.7, 91.7, 92.7, 93.7, 19.7, 20.7, 21.7, 22.7, 23.7, 24.7, 25.7, 26.7, 27.7, 13.7, 14.7, 15.7, 16.7, 17.7, 18.7],12,3).isEqual(fc.getArray(),1e-10))
+        fc.getArray()
+        pass
+
+    def testSwigRotate(self):
+        d=DataArrayDouble([1.,2.,3.,4.,6.,5.],2,3)
+        MEDCouplingPointSet.Rotate3DAlg([0.,0.,0.],[0.,1.,0.],1.5707963267948966,d)
+        self.assertTrue(d.isEqual(DataArrayDouble([3.,2.,-1.,5.,6.,-4.],2,3),1e-12))
+        d=DataArrayDouble([1.,2.,3.,4.,6.,5.],3,2)
+        MEDCouplingPointSet.Rotate2DAlg([0.,0.],1.5707963267948966,d)
+        self.assertTrue(d.isEqual(DataArrayDouble([-2.,1.,-4.,3.,-5.,6.],3,2),1e-12))
+        pass
+
+    def testSwigCMeshProtection(self):
+        cm=MEDCouplingCMesh()
+        self.assertRaises(InterpKernelException,cm.setCoordsAt,0,DataArrayDouble([4.,4.5,6.,7.],2,2))
+        self.assertRaises(InterpKernelException,cm.setCoords,DataArrayDouble([4.,4.5,6.,7.],2,2))
+        pass
+
+    def testSwigCellsInBoundingBox1(self):
+        m3D=MEDCouplingDataForTest.build3DExtrudedUMesh_1()[0]
+        self.assertTrue(m3D.getCellsInBoundingBox([(0,3),(0,3),(0,1)],-1e-12).isEqual(DataArrayInt([0,1,2,3,4,5])))
+        self.assertRaises(InterpKernelException,m3D.getCellsInBoundingBox,[(0,3,0),(3,0,1)],-1e-12)
+        pass
+
     def setUp(self):
         pass
     pass
index 085293b0c9405d55d120950ae93e10bd174a8660..48c3ec0e32fdb91bbba71f166adf421ae4934046 100644 (file)
@@ -78,6 +78,8 @@ using namespace INTERP_KERNEL;
 %feature("docstring");
 
 %newobject ParaMEDMEM::MEDCouplingFieldDiscretization::getOffsetArr;
+%newobject ParaMEDMEM::MEDCouplingFieldDiscretization::clone;
+%newobject ParaMEDMEM::MEDCouplingFieldDiscretization::clonePart;
 %newobject ParaMEDMEM::MEDCouplingField::buildMeasureField;
 %newobject ParaMEDMEM::MEDCouplingField::getLocalizationOfDiscr;
 %newobject ParaMEDMEM::MEDCouplingField::computeTupleIdsToSelectFromCellIds;
@@ -162,6 +164,7 @@ using namespace INTERP_KERNEL;
 %newobject ParaMEDMEM::DataArrayInt::buildUnion;
 %newobject ParaMEDMEM::DataArrayInt::buildSubstraction;
 %newobject ParaMEDMEM::DataArrayInt::buildIntersection;
+%newobject ParaMEDMEM::DataArrayInt::buildUnique;
 %newobject ParaMEDMEM::DataArrayInt::deltaShiftIndex;
 %newobject ParaMEDMEM::DataArrayInt::buildExplicitArrByRanges;
 %newobject ParaMEDMEM::DataArrayInt::findRangeIdForEachTuple;
@@ -328,6 +331,7 @@ using namespace INTERP_KERNEL;
 %feature("unref") MEDCouplingMultiFields "$this->decrRef();"
 
 %rename(assign) *::operator=;
+%ignore ParaMEDMEM::MEDCouplingVersionMajMinRel;
 %ignore ParaMEDMEM::RefCountObject::decrRef;
 %ignore ParaMEDMEM::MemArray::operator=;
 %ignore ParaMEDMEM::MemArray::operator[];
@@ -439,6 +443,7 @@ namespace ParaMEDMEM
     virtual DataArrayInt *simplexize(int policy) throw(INTERP_KERNEL::Exception);
     static MEDCouplingMesh *MergeMeshes(const MEDCouplingMesh *mesh1, const MEDCouplingMesh *mesh2) throw(INTERP_KERNEL::Exception);
     static int GetDimensionOfGeometricType(INTERP_KERNEL::NormalizedCellType type) throw(INTERP_KERNEL::Exception);
+    static const char *GetReprOfGeometricType(INTERP_KERNEL::NormalizedCellType type) throw(INTERP_KERNEL::Exception);
     %extend
        {
          std::string __str__() const
@@ -844,10 +849,53 @@ namespace ParaMEDMEM
      std::set<int> ret=self->getDifferentValues();
      return convertIntArrToPyList3(ret);
    }
+
+  PyObject *partitionByDifferentValues() const throw(INTERP_KERNEL::Exception)
+  {
+    std::vector<int> ret1;
+    std::vector<DataArrayInt *> ret0=self->partitionByDifferentValues(ret1);
+    std::size_t sz=ret0.size();
+    PyObject *pyRet=PyTuple_New(2);
+    PyObject *pyRet0=PyList_New((int)sz);
+    PyObject *pyRet1=PyList_New((int)sz);
+    for(std::size_t i=0;i<sz;i++)
+      {
+        PyList_SetItem(pyRet0,i,SWIG_NewPointerObj(SWIG_as_voidptr(ret0[i]),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 ));
+        PyList_SetItem(pyRet1,i,PyInt_FromLong(ret1[i]));
+      }
+    PyTuple_SetItem(pyRet,0,pyRet0);
+    PyTuple_SetItem(pyRet,1,pyRet1);
+    return pyRet;
+  }
+}
+
+%extend ParaMEDMEM::MEDCouplingFieldDiscretization
+{
+  MEDCouplingFieldDiscretization *clonePart(PyObject *li)
+  {
+    int sz=0,sw=-1,val1=-1;
+    std::vector<int> val2;
+    const int *inp=convertObjToPossibleCpp1_Safe(li,sw,sz,val1,val2);
+    return self->clonePart(inp,inp+sz);
+  }
+}
+
+%extend ParaMEDMEM::MEDCouplingFieldDiscretizationPerCell
+{
+  PyObject *getArrayOfDiscIds() const
+  {
+    DataArrayInt *ret=const_cast<DataArrayInt *>(self->getArrayOfDiscIds());
+    if(ret)
+      ret->incrRef();
+    return SWIG_NewPointerObj(SWIG_as_voidptr(ret),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 );
+  }
 }
 
 %ignore ParaMEDMEM::DataArray::getInfoOnComponents;
 %ignore ParaMEDMEM::DataArrayInt::getDifferentValues;
+%ignore ParaMEDMEM::DataArrayInt::partitionByDifferentValues;
+%ignore ParaMEDMEM::MEDCouplingFieldDiscretizationPerCell::getArrayOfDiscIds;
+%ignore ParaMEDMEM::MEDCouplingFieldDiscretization::clonePart;
 
 %include "MEDCouplingMemArray.hxx"
 %include "NormalizedUnstructuredMesh.hxx"
@@ -1201,16 +1249,46 @@ namespace ParaMEDMEM
              for(int i=0;i<sz;i++)
                PyList_SetItem(coords,i,PyFloat_FromDouble(coo[i]));
            }
+           
+           static void Rotate2DAlg(PyObject *center, double angle, PyObject *coords) throw(INTERP_KERNEL::Exception)
+           {
+             int sz,sz2;
+             INTERP_KERNEL::AutoPtr<double> c=convertPyToNewDblArr2(center,&sz);
+             int sw,nbNodes=0;
+             double val0;  ParaMEDMEM::DataArrayDouble *val1=0; ParaMEDMEM::DataArrayDoubleTuple *val2=0;
+             std::vector<double> val3;
+             const double *coo=convertObjToPossibleCpp5_Safe2(coords,sw,val0,val1,val2,val3,
+                                                            "Rotate2DAlg",2,true,nbNodes);
+             if(sw!=2 && sw!=3)
+               throw INTERP_KERNEL::Exception("Invalid call to MEDCouplingPointSet::Rotate2DAlg : try another overload method !");
+             ParaMEDMEM::MEDCouplingPointSet::Rotate2DAlg(c,angle,nbNodes,const_cast<double *>(coo));
+           }
+           
            static void Rotate3DAlg(PyObject *center, PyObject *vect, double angle, int nbNodes, PyObject *coords) throw(INTERP_KERNEL::Exception)
            {
              int sz,sz2;
              INTERP_KERNEL::AutoPtr<double> c=convertPyToNewDblArr2(center,&sz);
              INTERP_KERNEL::AutoPtr<double> coo=convertPyToNewDblArr2(coords,&sz);
-             double *v=convertPyToNewDblArr2(vect,&sz2);
+             INTERP_KERNEL::AutoPtr<double> v=convertPyToNewDblArr2(vect,&sz2);
              ParaMEDMEM::MEDCouplingPointSet::Rotate3DAlg(c,v,angle,nbNodes,coo);
              for(int i=0;i<sz;i++)
                PyList_SetItem(coords,i,PyFloat_FromDouble(coo[i]));
            }
+           
+           static void Rotate3DAlg(PyObject *center, PyObject *vect, double angle, PyObject *coords) throw(INTERP_KERNEL::Exception)
+           {
+             int sz,sz2;
+             INTERP_KERNEL::AutoPtr<double> c=convertPyToNewDblArr2(center,&sz);
+             int sw,nbNodes=0;
+             double val0;  ParaMEDMEM::DataArrayDouble *val1=0; ParaMEDMEM::DataArrayDoubleTuple *val2=0;
+             std::vector<double> val3;
+             const double *coo=convertObjToPossibleCpp5_Safe2(coords,sw,val0,val1,val2,val3,
+                                                            "Rotate3DAlg",3,true,nbNodes);
+             if(sw!=2 && sw!=3)
+               throw INTERP_KERNEL::Exception("Invalid call to MEDCouplingPointSet::Rotate3DAlg : try another overload method !");
+             INTERP_KERNEL::AutoPtr<double> v=convertPyToNewDblArr2(vect,&sz2);
+             ParaMEDMEM::MEDCouplingPointSet::Rotate3DAlg(c,v,angle,nbNodes,const_cast<double *>(coo));
+           }
          }
     };
 
@@ -1352,6 +1430,7 @@ namespace ParaMEDMEM
     MEDCouplingFieldDouble *getWarpField() const throw(INTERP_KERNEL::Exception);
     MEDCouplingFieldDouble *getSkewField() const throw(INTERP_KERNEL::Exception);
     DataArrayInt *convexEnvelop2D() throw(INTERP_KERNEL::Exception);
+    std::string cppRepr() const throw(INTERP_KERNEL::Exception);
     static MEDCouplingUMesh *Build0DMeshFromCoords(DataArrayDouble *da) throw(INTERP_KERNEL::Exception);
     static MEDCouplingUMesh *MergeUMeshes(const MEDCouplingUMesh *mesh1, const MEDCouplingUMesh *mesh2) throw(INTERP_KERNEL::Exception);
     static MEDCouplingUMesh *MergeUMeshesOnSameCoords(const MEDCouplingUMesh *mesh1, const MEDCouplingUMesh *mesh2) throw(INTERP_KERNEL::Exception);
@@ -2720,10 +2799,8 @@ namespace ParaMEDMEM
                          if(nbOfCompo<0)
                            throw INTERP_KERNEL::Exception("DataArrayDouble::New : should be a positive number of components !");
                          MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
-                         double *tmp=new double[nbOfTuples*nbOfCompo];
-                         try { fillArrayWithPyListDbl(elt0,tmp,nbOfTuples*nbOfCompo,0.,true); }
-                         catch(INTERP_KERNEL::Exception& e) { delete [] tmp; throw e; }
-                         ret->useArray(tmp,true,CPP_DEALLOC,nbOfTuples,nbOfCompo);
+                         std::vector<double> tmp=fillArrayWithPyListDbl2(elt0,nbOfTuples,nbOfCompo);
+                         ret->alloc(nbOfTuples,nbOfCompo); std::copy(tmp.begin(),tmp.end(),ret->getPointer());
                          ret->incrRef();
                          return ret;
                        }
@@ -2733,10 +2810,9 @@ namespace ParaMEDMEM
                  else
                    {//DataArrayDouble.New([1.,3.,4.],3)
                      MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
-                     double *tmp=new double[nbOfTuples];
-                     try { fillArrayWithPyListDbl(elt0,tmp,nbOfTuples,0.,true); }
-                     catch(INTERP_KERNEL::Exception& e) { delete [] tmp; throw e; }
-                     ret->useArray(tmp,true,CPP_DEALLOC,nbOfTuples,1);
+                     int tmpp1=-1;
+                     std::vector<double> tmp=fillArrayWithPyListDbl2(elt0,nbOfTuples,tmpp1);
+                     ret->alloc(nbOfTuples,tmpp1); std::copy(tmp.begin(),tmp.end(),ret->getPointer());
                      ret->incrRef();
                      return ret;
                    }
@@ -2746,16 +2822,10 @@ namespace ParaMEDMEM
            }
          else
            {// DataArrayDouble.New([1.,3.,4.])
-             int szz=-1;
-             if(PyList_Check(elt0))
-               szz=PyList_Size(elt0);
-             else
-               szz=PyTuple_Size(elt0);
              MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
-             double *tmp=new double[szz];
-             try { fillArrayWithPyListDbl(elt0,tmp,szz,0.,true); }
-             catch(INTERP_KERNEL::Exception& e) { delete [] tmp; throw e; }
-             ret->useArray(tmp,true,CPP_DEALLOC,szz,1);
+             int tmpp1=-1,tmpp2=-1;
+             std::vector<double> tmp=fillArrayWithPyListDbl2(elt0,tmpp1,tmpp2);
+             ret->alloc(tmpp1,tmpp2); std::copy(tmp.begin(),tmp.end(),ret->getPointer());
              ret->incrRef();
              return ret;
            }
@@ -4440,10 +4510,8 @@ namespace ParaMEDMEM
                          if(nbOfCompo<0)
                            throw INTERP_KERNEL::Exception("DataArrayInt::New : should be a positive number of components !");
                          MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
-                         int *tmp=new int[nbOfTuples*nbOfCompo];
-                         try { fillArrayWithPyListInt(elt0,tmp,nbOfTuples*nbOfCompo,0,true); }
-                         catch(INTERP_KERNEL::Exception& e) { delete [] tmp; throw e; }
-                         ret->useArray(tmp,true,CPP_DEALLOC,nbOfTuples,nbOfCompo);
+                         std::vector<int> tmp=fillArrayWithPyListInt2(elt0,nbOfTuples,nbOfCompo);
+                         ret->alloc(nbOfTuples,nbOfCompo); std::copy(tmp.begin(),tmp.end(),ret->getPointer());
                          ret->incrRef();
                          return ret;
                        }
@@ -4453,10 +4521,9 @@ namespace ParaMEDMEM
                  else
                    {//DataArrayInt.New([1,3,4],3)
                      MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
-                     int *tmp=new int[nbOfTuples];
-                     try { fillArrayWithPyListInt(elt0,tmp,nbOfTuples,0,true); }
-                     catch(INTERP_KERNEL::Exception& e) { delete [] tmp; throw e; }
-                     ret->useArray(tmp,true,CPP_DEALLOC,nbOfTuples,1);
+                     int tmpp1=-1;
+                     std::vector<int> tmp=fillArrayWithPyListInt2(elt0,nbOfTuples,tmpp1);
+                     ret->alloc(nbOfTuples,tmpp1); std::copy(tmp.begin(),tmp.end(),ret->getPointer());
                      ret->incrRef();
                      return ret;
                    }
@@ -4466,16 +4533,10 @@ namespace ParaMEDMEM
            }
          else
            {// DataArrayInt.New([1,3,4])
-             int szz=-1;
-             if(PyList_Check(elt0))
-               szz=PyList_Size(elt0);
-             else
-               szz=PyTuple_Size(elt0);
              MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
-             int *tmp=new int[szz];
-             try { fillArrayWithPyListInt(elt0,tmp,szz,0,true); }
-             catch(INTERP_KERNEL::Exception& e) { delete [] tmp; throw e; }
-             ret->useArray(tmp,true,CPP_DEALLOC,szz,1);
+             int tmpp1=-1,tmpp2=-1;
+             std::vector<int> tmp=fillArrayWithPyListInt2(elt0,tmpp1,tmpp2);
+             ret->alloc(tmpp1,tmpp2); std::copy(tmp.begin(),tmp.end(),ret->getPointer());
              ret->incrRef();
              return ret;
            }
@@ -4616,7 +4677,7 @@ namespace ParaMEDMEM
      return ret;
    }
 
-   void transformWithIndArr(PyObject *li)
+   void transformWithIndArr(PyObject *li) throw(INTERP_KERNEL::Exception)
    {
      void *da=0;
      int res1=SWIG_ConvertPtr(li,&da,SWIGTYPE_p_ParaMEDMEM__DataArrayInt, 0 |  0 );
@@ -6160,6 +6221,8 @@ namespace ParaMEDMEM
     int getNbOfGaussLocalization() const throw(INTERP_KERNEL::Exception);
     int getGaussLocalizationIdOfOneCell(int cellId) const throw(INTERP_KERNEL::Exception);
     const MEDCouplingGaussLocalization& getGaussLocalization(int locId) const throw(INTERP_KERNEL::Exception);
+    int getGaussLocalizationIdOfOneType(INTERP_KERNEL::NormalizedCellType type) const throw(INTERP_KERNEL::Exception);
+    void setDiscretization(MEDCouplingFieldDiscretization *newDisc);
     %extend {
       PyObject *getMesh() const throw(INTERP_KERNEL::Exception)
       {
@@ -6177,6 +6240,12 @@ namespace ParaMEDMEM
         return convertFieldDiscretization(ret,SWIG_POINTER_OWN | 0 );
       }
 
+      PyObject *getGaussLocalizationIdsOfOneType(INTERP_KERNEL::NormalizedCellType type) const throw(INTERP_KERNEL::Exception)
+      {
+        std::set<int> ret=self->getGaussLocalizationIdsOfOneType(type);
+        return convertIntArrToPyList3(ret);
+      }
+
       PyObject *isEqualIfNotWhy(const MEDCouplingField *other, double meshPrec, double valsPrec) const throw(INTERP_KERNEL::Exception)
       {
         std::string ret1;
@@ -7057,6 +7126,19 @@ namespace ParaMEDMEM
   };
 }
 
+%inline %{
+  PyObject *MEDCouplingVersionMajMinRel()
+  {
+    int tmp0=0,tmp1=0,tmp2=0;
+    MEDCouplingVersionMajMinRel(tmp0,tmp1,tmp2);
+    PyObject *res = PyList_New(3);
+    PyList_SetItem(res,0,SWIG_From_int(tmp0));
+    PyList_SetItem(res,1,SWIG_From_int(tmp1));
+    PyList_SetItem(res,2,SWIG_From_int(tmp2));
+    return res;
+  }
+%}
+
 %pythoncode %{
 import os
 __filename=os.environ.get('PYTHONSTARTUP')
index 1e7727e3fec1599f81d597447f334ccdba8d5cf0..5c8042f5ecc6323988e8577041bb17e480ba1990 100644 (file)
@@ -122,6 +122,169 @@ class MEDCouplingBasicsTest(unittest.TestCase):
             self.assertAlmostEqual(valuesExpected[i0],values[i0],12);
             pass
         pass
+
+    def testPrepareUC(self):
+        # 1D
+        coords=DataArrayDouble([0.,0.5,0.7])
+        src=MEDCouplingUMesh("",1) ; src.setCoords(coords)
+        src.allocateCells(2) ; src.insertNextCell(NORM_SEG2,[0,1]) ; src.insertNextCell(NORM_SEG2,[1,2]) ; src.finishInsertingCells()
+        trg=MEDCouplingCMesh() ; arr=DataArrayDouble([-0.7,-0.1,0.2,0.7,2.,2.3])
+        trg.setCoordsAt(0,arr)
+        fieldSrc=MEDCouplingFieldDouble(ON_CELLS,NO_TIME) ; fieldSrc.setMesh(src) ; arrSrc=DataArrayDouble([10.,30.])
+        fieldSrc.setNature(Integral) ;  fieldSrc.setArray(arrSrc)
+        rem=MEDCouplingRemapper()
+        rem.prepare(src,trg,"P0P0")
+        trgField=rem.transferField(fieldSrc,-7.)
+        expected1=[-7.,4.,36.,-7.,-7.]
+        self.assertEqual(5,trgField.getArray().getNumberOfTuples())
+        self.assertEqual(5,len(expected1))
+        for i,val in enumerate(expected1):
+            self.assertAlmostEqual(expected1[i],trgField.getArray().getIJ(i,0),12);
+            pass
+        # 2D
+        coords=DataArrayDouble([0.,0.,0.,1.,1.,1.,1.,0.,0.5,-0.2],5,2)
+        src=MEDCouplingUMesh("",2) ; src.setCoords(coords)
+        src.allocateCells(2) ; src.insertNextCell(NORM_TRI3,[0,1,2]) ; src.insertNextCell(NORM_TRI3,[3,4,0]) ; src.finishInsertingCells()
+        trg=MEDCouplingCMesh() ; arr=DataArrayDouble([-0.7,-0.1,0.2,0.7,2.,2.3])
+        trg.setCoordsAt(0,arr) ; trg.setCoordsAt(1,arr)
+        fieldSrc=MEDCouplingFieldDouble(ON_CELLS,NO_TIME) ; fieldSrc.setMesh(src) ; arrSrc=DataArrayDouble([10.,30.])
+        fieldSrc.setNature(Integral) ;  fieldSrc.setArray(arrSrc)
+        rem=MEDCouplingRemapper()
+        rem.prepare(src,trg,"P0P0")
+        trgField=rem.transferField(fieldSrc,-7.)
+        expected2=[-7.,-7.,7.35,0.15,-7.,-7.,2.8,14.85,5.25,-7.,-7.,2.,2.5,-7.,-7.,-7.,1.2,3.,0.9,-7.,-7.,-7.,-7.,-7.,-7.]
+        self.assertEqual(25,trgField.getArray().getNumberOfTuples())
+        self.assertEqual(25,len(expected2))
+        for i,val in enumerate(expected2):
+            self.assertAlmostEqual(expected2[i],trgField.getArray().getIJ(i,0),12);
+            pass
+        # 3D
+        coords=DataArrayDouble([0.,0.,0.,0.,1.,0.,1.,1.,0.,1.,0.,0.,0.5,-0.2,0.,0.1,0.8,1.,0.5,0.,1.],7,3)
+        src=MEDCouplingUMesh("",3) ; src.setCoords(coords)
+        src.allocateCells(2) ; src.insertNextCell(NORM_TETRA4,[0,1,2,5]) ; src.insertNextCell(NORM_TETRA4,[3,4,0,6]) ; src.finishInsertingCells()
+        trg=MEDCouplingCMesh() ; arr=DataArrayDouble([-0.7,-0.1,0.2,0.7,2.,2.3]) ; arr2=DataArrayDouble([-0.7,0.2,0.6,1.2,2.])
+        trg.setCoordsAt(0,arr) ; trg.setCoordsAt(1,arr) ; trg.setCoordsAt(2,arr2)
+        src.checkCoherency2(1e-10)
+        trg.checkCoherency()
+        fieldSrc=MEDCouplingFieldDouble(ON_CELLS,NO_TIME) ; fieldSrc.setMesh(src) ; arrSrc=DataArrayDouble([10.,30.])
+        fieldSrc.setNature(Integral) ;  fieldSrc.setArray(arrSrc)
+        rem=MEDCouplingRemapper()
+        rem.prepare(src,trg,"P0P0")
+        trgField=rem.transferField(fieldSrc,-7.)
+        expected3=[-7.,-7.,2.925,0.015,-7.,-7.,0.9392,8.595,2.265,-7.,-7.,1.1008,1.1192,-7.,-7.,-7.,0.6392,1.6408,0.2808,-7.,-7.,-7.,-7.,-7.,-7.,-7.,-7.,0.81,-7.,-7.,-7.,0.1208,11.55,0.96,-7.,-7.,1.1752,0.6592,-7.,-7.,-7.,0.8512,1.7744,0.0192,-7.,-7.,-7.,-7.,-7.,-7.,-7.,-7.,-7.,-7.,-7.,-7.,-7.,1.92,-7.,-7.,-7.,0.12578571428571422,0.007314285714285673,-7.,-7.,-7.,0.3189253968253971,0.1879746031746033,-7.,-7.,-7.,-7.,-7.,-7.,-7.,-7.,-7.,-7.,-7.,-7.,-7.,-7.,-7.,-7.,-7.,-7.,-7.,-7.,-7.,-7.,-7.,-7.,-7.,-7.,-7.,-7.,-7.,-7.,-7.,-7.]
+        self.assertEqual(100,trgField.getArray().getNumberOfTuples())
+        self.assertEqual(100,len(expected3))
+        for i,val in enumerate(expected3):
+            self.assertAlmostEqual(expected3[i],trgField.getArray().getIJ(i,0),12);
+            pass
+        pass
+
+    def testPrepareCU(self):
+        # 1D
+        coords=DataArrayDouble([0.,0.5,0.7])
+        trg=MEDCouplingUMesh("",1) ; trg.setCoords(coords)
+        trg.allocateCells(2) ; trg.insertNextCell(NORM_SEG2,[0,1]) ; trg.insertNextCell(NORM_SEG2,[1,2]) ; trg.finishInsertingCells()
+        src=MEDCouplingCMesh() ; arr=DataArrayDouble([-0.7,-0.1,0.2,0.7,2.,2.3])
+        src.setCoordsAt(0,arr)
+        fieldSrc=MEDCouplingFieldDouble(ON_CELLS,NO_TIME) ; fieldSrc.setMesh(src) ; arrTrg=DataArrayDouble([10.,30.,40.,70.,80.])
+        fieldSrc.setNature(Integral) ;  fieldSrc.setArray(arrTrg)
+        rem=MEDCouplingRemapper()
+        rem.prepare(src,trg,"P0P0")
+        trgField=rem.transferField(fieldSrc,-7.)
+        expected1=[44.,16.]
+        self.assertEqual(2.,trgField.getArray().getNumberOfTuples())
+        self.assertEqual(2,len(expected1))
+        for i,val in enumerate(expected1):
+            self.assertAlmostEqual(expected1[i],trgField.getArray().getIJ(i,0),12);
+            pass
+        # 2D
+        coords=DataArrayDouble([0.,0.,0.,1.,1.,1.,1.,0.,0.5,-0.2],5,2)
+        trg=MEDCouplingUMesh("",2) ; trg.setCoords(coords)
+        trg.allocateCells(2) ; trg.insertNextCell(NORM_TRI3,[0,1,2]) ; trg.insertNextCell(NORM_TRI3,[3,4,0]) ; trg.finishInsertingCells()
+        src=MEDCouplingCMesh() ; arr=DataArrayDouble([-0.7,-0.1,0.2,0.7,2.,2.3])
+        src.setCoordsAt(0,arr) ; src.setCoordsAt(1,arr)
+        fieldSrc=MEDCouplingFieldDouble(ON_CELLS,NO_TIME) ; fieldSrc.setMesh(src) ; arrSrc=DataArrayDouble([10.,30.,40.,70.,80.,110.,130.,140.,170.,180.,210.,230.,240.,270.,280.,310.,330.,340.,370.,380.,410.,430.,440.,470.,480.])
+        fieldSrc.setNature(Integral) ;  fieldSrc.setArray(arrSrc)
+        rem=MEDCouplingRemapper()
+        rem.prepare(src,trg,"P0P0")
+        trgField=rem.transferField(fieldSrc,-7.)
+        expected2=[441.3050624589086,68.69529914529915]
+        self.assertEqual(2,trgField.getArray().getNumberOfTuples())
+        self.assertEqual(2,len(expected2))
+        for i,val in enumerate(expected2):
+            self.assertAlmostEqual(expected2[i],trgField.getArray().getIJ(i,0),12);
+            pass
+        # 3D
+        coords=DataArrayDouble([0.,0.,0.,0.,1.,0.,1.,1.,0.,1.,0.,0.,0.5,-0.2,0.,0.1,0.8,1.,0.5,0.,1.],7,3)
+        trg=MEDCouplingUMesh("",3) ; trg.setCoords(coords)
+        trg.allocateCells(2) ; trg.insertNextCell(NORM_TETRA4,[0,1,2,5]) ; trg.insertNextCell(NORM_TETRA4,[3,4,0,6]) ; trg.finishInsertingCells()
+        src=MEDCouplingCMesh() ; arr=DataArrayDouble([-0.7,-0.1,0.2,0.7,2.,2.3]) ; arr2=DataArrayDouble([-0.7,0.2,0.6,1.2,2.])
+        src.setCoordsAt(0,arr) ; src.setCoordsAt(1,arr) ; src.setCoordsAt(2,arr2)
+        trg.checkCoherency2(1e-10)
+        src.checkCoherency()
+        fieldSrc=MEDCouplingFieldDouble(ON_CELLS,NO_TIME) ; fieldSrc.setMesh(src) ; arrSrc=DataArrayDouble(100) ; arrSrc.iota(7.7)
+        fieldSrc.setNature(Integral) ;  fieldSrc.setArray(arrSrc)
+        rem=MEDCouplingRemapper()
+        rem.prepare(src,trg,"P0P0")
+        trgField=rem.transferField(fieldSrc,-7.)
+        expected3=[39.635196634558845,12.13422356758468]
+        self.assertEqual(2,trgField.getArray().getNumberOfTuples())
+        self.assertEqual(2,len(expected3))
+        for i,val in enumerate(expected3):
+            self.assertAlmostEqual(expected3[i],trgField.getArray().getIJ(i,0),12);
+            pass
+        pass
+
+    def testPrepareCC(self):
+        # 1D
+        src=MEDCouplingCMesh() ; arr=DataArrayDouble([-0.7,-0.1,0.2,0.7,2.,2.3])
+        src.setCoordsAt(0,arr)
+        trg=MEDCouplingCMesh() ; arr=DataArrayDouble([-0.9,-0.1,0.15])
+        trg.setCoordsAt(0,arr)
+        fieldSrc=MEDCouplingFieldDouble(ON_CELLS,NO_TIME) ; fieldSrc.setMesh(src) ; arrTrg=DataArrayDouble([10.,30.,40.,70.,80.])
+        fieldSrc.setNature(Integral) ;  fieldSrc.setArray(arrTrg)
+        rem=MEDCouplingRemapper()
+        rem.prepare(src,trg,"P0P0")
+        trgField=rem.transferField(fieldSrc,-7.)
+        expected1=[10.,25.]
+        self.assertEqual(2.,trgField.getArray().getNumberOfTuples())
+        self.assertEqual(2,len(expected1))
+        for i,val in enumerate(expected1):
+            self.assertAlmostEqual(expected1[i],trgField.getArray().getIJ(i,0),12);
+            pass
+        # 2D
+        src=MEDCouplingCMesh() ; arr=DataArrayDouble([-0.7,-0.1,0.2,0.7,2.,2.3])
+        src.setCoordsAt(0,arr) ; src.setCoordsAt(1,arr)
+        trg=MEDCouplingCMesh() ; arr=DataArrayDouble([-0.9,-0.1,0.15])
+        trg.setCoordsAt(0,arr) ; trg.setCoordsAt(1,arr)
+        fieldSrc=MEDCouplingFieldDouble(ON_CELLS,NO_TIME) ; fieldSrc.setMesh(src) ; arrSrc=DataArrayDouble([10.,30.,40.,70.,80.,110.,130.,140.,170.,180.,210.,230.,240.,270.,280.,310.,330.,340.,370.,380.,410.,430.,440.,470.,480.])
+        fieldSrc.setNature(Integral) ;  fieldSrc.setArray(arrSrc)
+        rem=MEDCouplingRemapper()
+        rem.prepare(src,trg,"P0P0")
+        trgField=rem.transferField(fieldSrc,-7.)
+        expected2=[10.,25.,91.66666666666666,90.27777777777777]
+        self.assertEqual(4,trgField.getArray().getNumberOfTuples())
+        self.assertEqual(4,len(expected2))
+        for i,val in enumerate(expected2):
+            self.assertAlmostEqual(expected2[i],trgField.getArray().getIJ(i,0),12);
+            pass
+        # 3D
+        src=MEDCouplingCMesh() ; arr=DataArrayDouble([-0.7,-0.1,0.2,0.7,2.,2.3])
+        src.setCoordsAt(0,arr) ; src.setCoordsAt(1,arr) ; src.setCoordsAt(2,arr)
+        trg=MEDCouplingCMesh() ; arr=DataArrayDouble([-0.9,-0.1,0.15])
+        trg.setCoordsAt(0,arr) ; trg.setCoordsAt(1,arr) ; trg.setCoordsAt(2,arr)
+        fieldSrc=MEDCouplingFieldDouble(ON_CELLS,NO_TIME) ; fieldSrc.setMesh(src) ; arrSrc=DataArrayDouble(125) ; arrSrc.iota(7.7)
+        fieldSrc.setNature(Integral) ;  fieldSrc.setArray(arrSrc) ; fieldSrc.checkCoherency()
+        rem=MEDCouplingRemapper()
+        rem.prepare(src,trg,"P0P0")
+        trgField=rem.transferField(fieldSrc,-7.)
+        expected3=[7.7, 7.249999999999999, 10.583333333333332, 9.513888888888886, 27.25, 23.40277777777777, 26.180555555555546, 22.39583333333333]
+        self.assertEqual(8,trgField.getArray().getNumberOfTuples())
+        self.assertEqual(8,len(expected3))
+        for i,val in enumerate(expected3):
+            self.assertAlmostEqual(expected3[i],trgField.getArray().getIJ(i,0),12);
+            pass
+        pass
     
     def build2DSourceMesh_1(self):
         sourceCoords=[-0.3,-0.3, 0.7,-0.3, -0.3,0.7, 0.7,0.7]
index 98aad204d1cd40ed09df80993bffe36e0a19c3ee..c168124294a071549462ba225c8aa5c52205cf94 100644 (file)
@@ -346,7 +346,133 @@ static void convertPyToNewIntArr4(PyObject *pyLi, int recurseLev, int nbOfSubPar
     throw INTERP_KERNEL::Exception("convertPyToNewIntArr4 : not a list nor a tuple recursively !");
 }
 
+static void checkFillArrayWithPyList(int size1, int size2, int& nbOfTuples, int& nbOfComp) throw(INTERP_KERNEL::Exception)
+{
+  if(nbOfTuples==-1)
+    {
+      if(nbOfComp==-1) { nbOfTuples=size1; nbOfComp=size2; }
+      else { if(nbOfComp==size2) { nbOfTuples=size1; } else
+          {
+            std::ostringstream oss; oss << "fillArrayWithPyListDbl2 : mismatch between nb of elemts : Input has " << size1 << " tuples and " << size2 << " components";
+            oss << " whereas nb of components expected is " << nbOfComp << " !";
+            throw INTERP_KERNEL::Exception(oss.str().c_str());
+          } }
+    }
+  else
+    {
+      if(nbOfComp!=-1)
+        {
+          if((nbOfTuples!=size1 || nbOfComp!=size2))
+            {
+              if(size2!=1 || size1!=nbOfComp*nbOfTuples)
+                {
+                  std::ostringstream oss; oss << "fillArrayWithPyListDbl2 : mismatch between nb of elemts : Input has " << size1 << " tuples and " << size2 << " components";
+                  oss << " whereas nb of tuples expected is " << nbOfTuples << " and number of components expected is " << nbOfComp << " !";
+                  throw INTERP_KERNEL::Exception(oss.str().c_str());
+                }
+            }
+        }
+      else
+        {
+          if(nbOfTuples==size1)
+            nbOfComp=size2;
+          else
+            {
+              std::ostringstream oss; oss << "fillArrayWithPyListDbl2 : mismatch between nb of elemts : Input has " << size1 << " tuples and " << size2 << " components";
+              oss << " whereas nb of tuples expected is " << nbOfTuples << " !";
+              throw INTERP_KERNEL::Exception(oss.str().c_str());
+            }
+        }
+    }
+}
+
+static void fillArrayWithPyListInt3(PyObject *pyLi, int& nbOfElt, std::vector<int>& ret)
+{
+  static const char MSG[]="fillArrayWithPyListInt3 : It appears that the input list or tuple is composed by elts having different sizes !";
+  if(PyInt_Check(pyLi))
+    {
+      long val=PyInt_AS_LONG(pyLi);
+      if(nbOfElt==-1)
+        nbOfElt=1;
+      else
+        if(nbOfElt!=1)
+          throw INTERP_KERNEL::Exception(MSG);
+      ret.push_back(val);
+    }
+  else if(PyList_Check(pyLi))
+    {
+      int size=PyList_Size(pyLi);
+      int tmp=0;
+      for(int i=0;i<size;i++)
+        {
+          PyObject *o=PyList_GetItem(pyLi,i);
+          int tmp1=-1;
+          fillArrayWithPyListInt3(o,tmp1,ret);
+          tmp+=tmp1;
+        }
+      if(nbOfElt==-1)
+        nbOfElt=tmp;
+      else
+        {
+          if(nbOfElt!=tmp)
+            throw INTERP_KERNEL::Exception(MSG);
+        }
+    }
+  else if(PyTuple_Check(pyLi))
+    {
+      int size=PyTuple_Size(pyLi);
+      int tmp=0;
+      for(int i=0;i<size;i++)
+        {
+          PyObject *o=PyTuple_GetItem(pyLi,i);
+          int tmp1=-1;
+          fillArrayWithPyListInt3(o,tmp1,ret);
+          tmp+=tmp1;
+        }
+      if(nbOfElt==-1)
+        nbOfElt=tmp;
+      else
+        {
+          if(nbOfElt!=tmp)
+            throw INTERP_KERNEL::Exception(MSG);
+        }
+    }
+  else
+    throw INTERP_KERNEL::Exception("fillArrayWithPyListInt3 : Unrecognized type ! Should be a composition of tuple,list,int !");
+}
+
+static std::vector<int> fillArrayWithPyListInt2(PyObject *pyLi, int& nbOfTuples, int& nbOfComp) throw(INTERP_KERNEL::Exception)
+{
+  std::vector<int> ret;
+  int size1=-1,size2=-1;
+  if(PyList_Check(pyLi))
+    {
+      size1=PyList_Size(pyLi);
+      for(int i=0;i<size1;i++)
+        {
+          PyObject *o=PyList_GetItem(pyLi,i);
+          fillArrayWithPyListInt3(o,size2,ret);
+        }
+    }
+  else if(PyTuple_Check(pyLi))
+    {
+      size1=PyTuple_Size(pyLi);
+      for(int i=0;i<size1;i++)
+        {
+          PyObject *o=PyTuple_GetItem(pyLi,i);
+          fillArrayWithPyListInt3(o,size2,ret);
+        }
+    }
+  else
+    throw INTERP_KERNEL::Exception("fillArrayWithPyListInt2 : Unrecognized type ! Should be a tuple or a list !");
+  //
+  checkFillArrayWithPyList(size1,size2,nbOfTuples,nbOfComp);
+  return ret;
+}
 
+/*
+ * will become obsolete -> fillArrayWithPyListInt2
+ */
 static void fillArrayWithPyListInt(PyObject *pyLi, int *arrToFill, int sizeOfArray, int dftVal, bool chckSize) throw(INTERP_KERNEL::Exception)
 {
   if(PyList_Check(pyLi))
@@ -492,6 +618,104 @@ static double *convertPyToNewDblArr2(PyObject *pyLi, int *size) throw(INTERP_KER
     throw INTERP_KERNEL::Exception("convertPyToNewDblArr2 : not a list");
 }
 
+static void fillArrayWithPyListDbl3(PyObject *pyLi, int& nbOfElt, std::vector<double>& ret)
+{
+  static const char MSG[]="fillArrayWithPyListDbl3 : It appears that the input list or tuple is composed by elts having different sizes !";
+  if(PyFloat_Check(pyLi))
+    {
+      if(nbOfElt==-1)
+        nbOfElt=1;
+      else
+        if(nbOfElt!=1)
+          throw INTERP_KERNEL::Exception(MSG);
+      double val=PyFloat_AS_DOUBLE(pyLi);
+      ret.push_back(val);
+    }
+  else if(PyInt_Check(pyLi))
+    {
+      long val0=PyInt_AS_LONG(pyLi);
+      double val=val0;
+      if(nbOfElt==-1)
+        nbOfElt=1;
+      else
+        if(nbOfElt!=1)
+          throw INTERP_KERNEL::Exception(MSG);
+      ret.push_back(val);
+    }
+  else if(PyList_Check(pyLi))
+    {
+      int size=PyList_Size(pyLi);
+      int tmp=0;
+      for(int i=0;i<size;i++)
+        {
+          PyObject *o=PyList_GetItem(pyLi,i);
+          int tmp1=-1;
+          fillArrayWithPyListDbl3(o,tmp1,ret);
+          tmp+=tmp1;
+        }
+      if(nbOfElt==-1)
+        nbOfElt=tmp;
+      else
+        {
+          if(nbOfElt!=tmp)
+            throw INTERP_KERNEL::Exception(MSG);
+        }
+    }
+  else if(PyTuple_Check(pyLi))
+    {
+      int size=PyTuple_Size(pyLi);
+      int tmp=0;
+      for(int i=0;i<size;i++)
+        {
+          PyObject *o=PyTuple_GetItem(pyLi,i);
+          int tmp1=-1;
+          fillArrayWithPyListDbl3(o,tmp1,ret);
+          tmp+=tmp1;
+        }
+      if(nbOfElt==-1)
+        nbOfElt=tmp;
+      else
+        {
+          if(nbOfElt!=tmp)
+            throw INTERP_KERNEL::Exception(MSG);
+        }
+    }
+  else
+    throw INTERP_KERNEL::Exception("fillArrayWithPyListDbl3 : Unrecognized type ! Should be a composition of tuple,list,int and float !");
+}
+
+static std::vector<double> fillArrayWithPyListDbl2(PyObject *pyLi, int& nbOfTuples, int& nbOfComp) throw(INTERP_KERNEL::Exception)
+{
+  std::vector<double> ret;
+  int size1=-1,size2=-1;
+  if(PyList_Check(pyLi))
+    {
+      size1=PyList_Size(pyLi);
+      for(int i=0;i<size1;i++)
+        {
+          PyObject *o=PyList_GetItem(pyLi,i);
+          fillArrayWithPyListDbl3(o,size2,ret);
+        }
+    }
+  else if(PyTuple_Check(pyLi))
+    {
+      size1=PyTuple_Size(pyLi);
+      for(int i=0;i<size1;i++)
+        {
+          PyObject *o=PyTuple_GetItem(pyLi,i);
+          fillArrayWithPyListDbl3(o,size2,ret);
+        }
+    }
+  else
+    throw INTERP_KERNEL::Exception("fillArrayWithPyListDbl2 : Unrecognized type ! Should be a tuple or a list !");
+  //
+  checkFillArrayWithPyList(size1,size2,nbOfTuples,nbOfComp);
+  return ret;
+}
+
+/*
+ * will become obsolete -> fillArrayWithPyListDbl2
+ */
 static void fillArrayWithPyListDbl(PyObject *pyLi, double *arrToFill, int sizeOfArray, double dftVal, bool chckSize) throw(INTERP_KERNEL::Exception)
 {
   if(PyList_Check(pyLi))
@@ -557,7 +781,7 @@ static void fillArrayWithPyListDbl(PyObject *pyLi, double *arrToFill, int sizeOf
       return ;
     }
   else
-    throw INTERP_KERNEL::Exception("convertPyToNewIntArr : not a list");
+    throw INTERP_KERNEL::Exception("fillArrayWithPyListDbl : not a list nor a tuple");
 }
 
 //convertFromPyObjVectorOfObj<const ParaMEDMEM::MEDCouplingUMesh *>(pyLi,SWIGTYPE_p_ParaMEDMEM__MEDCouplingUMesh,"MEDCouplingUMesh")
@@ -586,7 +810,6 @@ static void convertFromPyObjVectorOfObj(PyObject *pyLi, swig_type_info *ty, cons
       for(int i=0;i<size;i++)
         {
           PyObject *obj=PyTuple_GetItem(pyLi,i);
-          void *argp;
           int status=SWIG_ConvertPtr(obj,&argp,ty,0|0);
           if(!SWIG_IsOK(status))
             {
@@ -1162,55 +1385,17 @@ static const double *convertObjToPossibleCpp5_Safe(PyObject *value, int& sw, dou
         }
       return &val;
     }
-  if(PyTuple_Check(value))
-    {
-      int size=PyTuple_Size(value);
-      f.resize(size);
-      for(int i=0;i<size;i++)
-        {
-          PyObject *o=PyTuple_GetItem(value,i);
-          if(PyFloat_Check(o))
-            f[i]=PyFloat_AS_DOUBLE(o);
-          else if(PyInt_Check(o))
-            f[i]=(double)PyInt_AS_LONG(o);
-          else
-            {
-              std::ostringstream oss; oss << "Tuple as been detected but element #" << i << " is not double ! only tuples of doubles accepted or integer !";
-              throw INTERP_KERNEL::Exception(oss.str().c_str());
-            }
-        }
-      sw=4;
-      if(nbTuplesExpected*nbCompExpected!=(int)f.size())
-        {
-          std::ostringstream oss; oss << msg << "dimension expected to be " << nbTuplesExpected*nbCompExpected << " , and your data in input has dimension " << f.size() << " !"; 
-          throw INTERP_KERNEL::Exception(oss.str().c_str());
-        }
-      return &f[0];
-    }
-  if(PyList_Check(value))
+  if(PyTuple_Check(value) || PyList_Check(value))
     {
-      int size=PyList_Size(value);
-      f.resize(size);
-      for(int i=0;i<size;i++)
-        {
-          PyObject *o=PyList_GetItem(value,i);
-          if(PyFloat_Check(o))
-            f[i]=PyFloat_AS_DOUBLE(o);
-          else if(PyInt_Check(o))
-            f[i]=(double)PyInt_AS_LONG(o);
-          else
-            {
-              std::ostringstream oss; oss << "List as been detected but element #" << i << " is not double ! only lists of doubles accepted or integer !";
-              throw INTERP_KERNEL::Exception(oss.str().c_str());
-            }
-        }
-      sw=4;
-      if(nbTuplesExpected*nbCompExpected!=(int)f.size())
+      try
         {
-          std::ostringstream oss; oss << msg << "dimension expected to be " << nbTuplesExpected*nbCompExpected << " , and your data in input has dimension " << f.size() << " !"; 
-          throw INTERP_KERNEL::Exception(oss.str().c_str());
+          int tmp1=nbTuplesExpected,tmp2=nbCompExpected;
+          std::vector<double> ret=fillArrayWithPyListDbl2(value,tmp1,tmp2);
+          sw=4;
+          f=ret;
+          return &f[0];
         }
-      return &f[0];
+      catch(INTERP_KERNEL::Exception& e) { throw e; }
     }
   void *argp;
   int status=SWIG_ConvertPtr(value,&argp,SWIGTYPE_p_ParaMEDMEM__DataArrayDouble,0|0);
@@ -1409,3 +1594,83 @@ static const double *convertObjToPossibleCpp5_Safe2(PyObject *value, int& sw, do
     }
   throw INTERP_KERNEL::Exception("4 types accepted : integer, double, DataArrayDouble, DataArrayDoubleTuple");
 }
+
+/*!
+ * if python int -> cpp int sw=1
+ * if python list[int] -> cpp vector<int> sw=2
+ * if python tuple[int] -> cpp vector<int> sw=2
+ * if python DataArrayInt -> cpp DataArrayInt sw=3
+ * if python DataArrayIntTuple -> cpp DataArrayIntTuple sw=4
+ *
+ * switch between (int,vector<int>,DataArrayInt)
+ */
+static const int *convertObjToPossibleCpp1_Safe(PyObject *value, int& sw, int& sz, int& iTyypp, std::vector<int>& stdvecTyypp) throw(INTERP_KERNEL::Exception)
+{
+  sw=-1;
+  if(PyInt_Check(value))
+    {
+      iTyypp=(int)PyInt_AS_LONG(value);
+      sw=1; sz=1;
+      return &iTyypp;
+    }
+  if(PyTuple_Check(value))
+    {
+      int size=PyTuple_Size(value);
+      stdvecTyypp.resize(size);
+      for(int i=0;i<size;i++)
+        {
+          PyObject *o=PyTuple_GetItem(value,i);
+          if(PyInt_Check(o))
+            stdvecTyypp[i]=(int)PyInt_AS_LONG(o);
+          else
+            {
+              std::ostringstream oss; oss << "Tuple as been detected but element #" << i << " is not integer ! only tuples of integers accepted !";
+              throw INTERP_KERNEL::Exception(oss.str().c_str());
+            }
+        }
+      sw=2; sz=size;
+      return &stdvecTyypp[0];
+    }
+  if(PyList_Check(value))
+    {
+      int size=PyList_Size(value);
+      stdvecTyypp.resize(size);
+      for(int i=0;i<size;i++)
+        {
+          PyObject *o=PyList_GetItem(value,i);
+          if(PyInt_Check(o))
+            stdvecTyypp[i]=(int)PyInt_AS_LONG(o);
+          else
+            {
+              std::ostringstream oss; oss << "List as been detected but element #" << i << " is not integer ! only lists of integers accepted !";
+              throw INTERP_KERNEL::Exception(oss.str().c_str());
+            }
+        }
+      sw=2; sz=size;
+      return &stdvecTyypp[0];
+    }
+  void *argp;
+  int status=SWIG_ConvertPtr(value,&argp,SWIGTYPE_p_ParaMEDMEM__DataArrayInt,0|0);
+  if(SWIG_IsOK(status))
+    {
+      ParaMEDMEM::DataArrayInt *daIntTyypp=reinterpret_cast< ParaMEDMEM::DataArrayInt * >(argp);
+      if(daIntTyypp)
+        {
+          sw=3; sz=daIntTyypp->getNbOfElems();
+          return daIntTyypp->begin();
+        }
+      else
+        {
+          sz=0;
+          return 0;
+        }
+    }
+  status=SWIG_ConvertPtr(value,&argp,SWIGTYPE_p_ParaMEDMEM__DataArrayIntTuple,0|0);
+  if(SWIG_IsOK(status))
+    {  
+      ParaMEDMEM::DataArrayIntTuple *daIntTuple=reinterpret_cast< ParaMEDMEM::DataArrayIntTuple * >(argp);
+      sw=4; sz=daIntTuple->getNumberOfCompo();
+      return daIntTuple->getConstPointer();
+    }
+  throw INTERP_KERNEL::Exception("5 types accepted : integer, tuple of integer, list of integer, DataArrayInt, DataArrayIntTuple");
+}
index b18c3cb4299300f3a6afa904999148acb9728262..61f1429f310af06946731886c38affb4135dedb4 100644 (file)
@@ -129,7 +129,6 @@ bool MEDFileData::unPolyzeMeshes() throw(INTERP_KERNEL::Exception)
   MEDFileMeshes *ms=_meshes;
   if(!ms)
     return false;
-  bool ret=false;
   std::vector< MEDFileMesh * > meshesImpacted;
   std::vector< DataArrayInt * > renumParamsOfMeshImpacted;//same size as meshesImpacted
   std::vector< std::vector<int> > oldCodeOfMeshImpacted,newCodeOfMeshImpacted;//same size as meshesImpacted
index cf851c2e96052398aec3f3ad5d8a121577f6a97f..70d126a7d90d04787bfe4c00a6f490b768b3adec 100644 (file)
@@ -254,18 +254,32 @@ void MEDFileFieldPerMeshPerTypePerDisc::assignFieldNoProfile(int& start, int off
 }
 
 /*!
- * Leaf method of field with profile assignement.
- * @param pflName input containing name of profile if any. 0 if no profile.
- * @param multiTypePfl input containing the profile array \b including \b all \b types. This array is usefull only for GAUSS_NE.
- * @param idsInPfl input containing the ids in the profile 'multiTypePfl' concerning the current geo type.
+ * Leaf method of field with profile assignement. This method is the most general one. No optimization is done here.
+ * \param [in] pflName input containing name of profile if any. 0 if no profile (except for GAUSS_PT where a no profile can hide a profile when splitted by loc_id).
+ * \param [in] multiTypePfl is the end user profile specified in high level API
+ * \param [in] idsInPfl is the selection into the \a multiTypePfl whole profile that corresponds to the current geometric type.
+ * \param [in] locIds is the profile needed to be created for MED file format. It can be null if all cells of current geometric type are fetched in \a multiTypePfl.
+ *             \b WARNING if not null the MED file profile can be subdivided again in case of Gauss points.
+ * \param [in] mesh is the mesh coming from the MEDFileMesh instance in correspondance with the MEDFileField. The mesh inside the \a field is simply ignored.
  */
-void MEDFileFieldPerMeshPerTypePerDisc::assignFieldProfile(int& start, const char *pflName, const DataArrayInt *multiTypePfl, const DataArrayInt *idsInPfl, const MEDCouplingFieldDouble *field, const MEDCouplingMesh *mesh, MEDFileFieldGlobsReal& glob) throw(INTERP_KERNEL::Exception)
+void MEDFileFieldPerMeshPerTypePerDisc::assignFieldProfile(int& start, const DataArrayInt *multiTypePfl, const DataArrayInt *idsInPfl, DataArrayInt *locIds, int nbOfEltsInWholeMesh, const MEDCouplingFieldDouble *field, const MEDCouplingMesh *mesh, MEDFileFieldGlobsReal& glob) throw(INTERP_KERNEL::Exception)
 {
-  if(pflName)
-    _profile=pflName;
-  else
-    _profile.clear();
+  _profile.clear();
   _type=field->getTypeOfField();
+  std::string pflName(multiTypePfl->getName());
+  std::ostringstream oss; oss << pflName;
+  if(_type!=ON_NODES) { const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(getGeoType()); oss << "_" <<  cm.getRepr(); } else { oss << "_NODE"; }
+  if(locIds)
+    {
+      if(pflName.empty())
+        throw INTERP_KERNEL::Exception("MEDFileFieldPerMeshPerTypePerDisc::assignFieldProfile : existing profile with empty name !");
+      if(_type!=ON_GAUSS_PT)
+        {
+          locIds->setName(oss.str().c_str());
+          glob.appendProfile(locIds);
+          _profile=oss.str();
+        }
+    }
   const DataArrayDouble *da=field->getArray();
   _start=start;
   switch(_type)
@@ -288,7 +302,7 @@ void MEDFileFieldPerMeshPerTypePerDisc::assignFieldProfile(int& start, const cha
       {
         MEDCouplingAutoRefCountObjectPtr<DataArrayInt> arr=field->getDiscretization()->getOffsetArr(mesh);
         MEDCouplingAutoRefCountObjectPtr<DataArrayInt> arr2=arr->deltaShiftIndex();
-        MEDCouplingAutoRefCountObjectPtr<DataArrayInt> arr3=arr2->selectByTupleId(multiTypePfl->getConstPointer(),multiTypePfl->getConstPointer()+multiTypePfl->getNumberOfTuples());
+        MEDCouplingAutoRefCountObjectPtr<DataArrayInt> arr3=arr2->selectByTupleId(multiTypePfl->begin(),multiTypePfl->end());
         arr3->computeOffsets2();
         MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=idsInPfl->buildExplicitArrByRanges(arr3);
         int trueNval=tmp->getNumberOfTuples();
@@ -299,7 +313,52 @@ void MEDFileFieldPerMeshPerTypePerDisc::assignFieldProfile(int& start, const cha
       }
     case ON_GAUSS_PT:
       {
-        throw INTERP_KERNEL::Exception("MEDFileFieldPerMeshPerTypePerDisc::assignFieldProfile : not implemented yet for profiles on gauss points !");
+        const MEDCouplingFieldDiscretizationGauss *disc2=dynamic_cast<const MEDCouplingFieldDiscretizationGauss *>(field->getDiscretization());
+        if(!disc2)
+          throw INTERP_KERNEL::Exception("addNewEntryIfNecessaryGauss : invalid call to this method ! Internal Error !");
+        const DataArrayInt *da1=disc2->getArrayOfDiscIds();
+        const MEDCouplingGaussLocalization& gsLoc=field->getGaussLocalization(_loc_id);
+        MEDCouplingAutoRefCountObjectPtr<DataArrayInt> da2=da1->selectByTupleId(idsInPfl->begin(),idsInPfl->end());
+        MEDCouplingAutoRefCountObjectPtr<DataArrayInt> da3=da2->getIdsEqual(_loc_id);
+        MEDCouplingAutoRefCountObjectPtr<DataArrayInt> da4=idsInPfl->selectByTupleId(da3->begin(),da3->end());
+        //
+        MEDCouplingAutoRefCountObjectPtr<MEDCouplingMesh> mesh2=mesh->buildPart(multiTypePfl->begin(),multiTypePfl->end());
+        MEDCouplingAutoRefCountObjectPtr<DataArrayInt> arr=disc2->getOffsetArr(mesh2);
+        //
+        MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=DataArrayInt::New();
+        int trueNval=0;
+        for(const int *pt=da4->begin();pt!=da4->end();pt++)
+          trueNval+=arr->getIJ(*pt+1,0)-arr->getIJ(*pt,0);
+        tmp->alloc(trueNval,1);
+        int *tmpPtr=tmp->getPointer();
+        for(const int *pt=da4->begin();pt!=da4->end();pt++)
+          for(int j=arr->getIJ(*pt,0);j<arr->getIJ(*pt+1,0);j++)
+            *tmpPtr++=j;
+        //
+        _nval=da4->getNumberOfTuples();
+        getArray()->setContigPartOfSelectedValues(_start,da,tmp);
+        _end=_start+trueNval;
+        oss << "_loc_" << _loc_id;
+        if(locIds)
+          {
+            MEDCouplingAutoRefCountObjectPtr<DataArrayInt> da5=locIds->selectByTupleId(da3->begin(),da3->end());
+            da5->setName(oss.str().c_str());
+            glob.appendProfile(da5);
+            _profile=oss.str();
+          }
+        else
+          {
+            if(da3->getNumberOfTuples()!=nbOfEltsInWholeMesh || !da3->isIdentity())
+              {
+                da3->setName(oss.str().c_str());
+                glob.appendProfile(da3);
+                _profile=oss.str();
+              }
+          }
+        std::ostringstream oss2; oss2 << "Loc_" << getName() << "_" << INTERP_KERNEL::CellModel::GetCellModel(getGeoType()).getRepr() << "_" << _loc_id;
+        _localization=oss2.str();
+        glob.appendLoc(_localization.c_str(),getGeoType(),gsLoc.getRefCoords(),gsLoc.getGaussCoords(),gsLoc.getWeights());
+        break;
       }
     default:
       throw INTERP_KERNEL::Exception("MEDFileFieldPerMeshPerTypePerDisc::assignFieldProfile : not implemented yet for such discretization type of field !");
@@ -620,10 +679,10 @@ int MEDFileFieldPerMeshPerTypePerDisc::fillEltIdsFromCode(int offset, const std:
   _loc_id=offset;
   std::ostringstream oss;
   std::size_t nbOfType=codeOfMesh.size()/3;
-  std::size_t found=-1;
+  int found=-1;
   for(std::size_t i=0;i<nbOfType && found==-1;i++)
     if(getGeoType()==(INTERP_KERNEL::NormalizedCellType)codeOfMesh[3*i])
-      found=i;
+      found=(int)i;
   if(found==-1)
     {
       const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(getGeoType());
@@ -654,11 +713,11 @@ int MEDFileFieldPerMeshPerTypePerDisc::fillEltIdsFromCode(int offset, const std:
           oss << pfl->getNumberOfTuples() << " whereas the number of ids is set to " << _nval << " for this geometric type !";
           throw INTERP_KERNEL::Exception(oss.str().c_str());
         }
-      int offset=codeOfMesh[3*found+2];
+      int offset2=codeOfMesh[3*found+2];
       for(const int *pflId=pfl->begin();pflId!=pfl->end();pflId++)
         {
           if(*pflId<codeOfMesh[3*found+1])
-            *work++=offset+*pflId;
+            *work++=offset2+*pflId;
         }
     }
   return _nval;
@@ -807,15 +866,17 @@ MEDFileFieldPerMeshPerTypePerDisc *MEDFileFieldPerMeshPerTypePerDisc::NewObjectO
       if(((INTERP_KERNEL::NormalizedCellType)(*it)->_loc_id)==geoType && (*it)->_nval==nbMeshEntities)
         {
           if(!isPfl)
-            if((*it)->_profile.empty())
-              break;
-            else
-              if(!(*it)->_profile.empty())
-                {
-                  const DataArrayInt *pfl=glob.getProfile((*it)->_profile.c_str());
-                  if(pfl->isEqualWithoutConsideringStr(*idsOfMeshElt))
-                    break;
-                }
+            {
+              if((*it)->_profile.empty())
+                break;
+              else
+                if(!(*it)->_profile.empty())
+                  {
+                    const DataArrayInt *pfl=glob.getProfile((*it)->_profile.c_str());
+                    if(pfl->isEqualWithoutConsideringStr(*idsOfMeshElt))
+                      break;
+                  }
+            }
         }
     }
   if(it==entriesOnSameDisc.end())
@@ -865,28 +926,20 @@ void MEDFileFieldPerMeshPerType::assignFieldNoProfile(int& start, int offset, in
     _field_pm_pt_pd[*it]->assignFieldNoProfile(start,offset,nbOfCells,field,glob);
 }
 
-void MEDFileFieldPerMeshPerType::assignFieldProfile(int& start, const DataArrayInt *multiTypePfl, const DataArrayInt *idsInPfl, DataArrayInt *locIds, const MEDCouplingFieldDouble *field, const MEDCouplingMesh *mesh, MEDFileFieldGlobsReal& glob) throw(INTERP_KERNEL::Exception)
+/*!
+ * This method is the most general one. No optimization is done here.
+ * \param [in] multiTypePfl is the end user profile specified in high level API
+ * \param [in] idsInPfl is the selection into the \a multiTypePfl whole profile that corresponds to the current geometric type.
+ * \param [in] locIds is the profile needed to be created for MED file format. It can be null if all cells of current geometric type are fetched in \a multiTypePfl.
+ *             \b WARNING if not null the MED file profile can be subdivided again in case of Gauss points.
+ * \param [in] nbOfEltsInWholeMesh nb of elts of type \a this->_geo_type in \b WHOLE mesh
+ * \param [in] mesh is the mesh coming from the MEDFileMesh instance in correspondance with the MEDFileField. The mesh inside the \a field is simply ignored.
+ */
+void MEDFileFieldPerMeshPerType::assignFieldProfile(int& start, const DataArrayInt *multiTypePfl, const DataArrayInt *idsInPfl, DataArrayInt *locIds, int nbOfEltsInWholeMesh, const MEDCouplingFieldDouble *field, const MEDCouplingMesh *mesh, MEDFileFieldGlobsReal& glob) throw(INTERP_KERNEL::Exception)
 {
   std::vector<int> pos=addNewEntryIfNecessary(field,idsInPfl);
-  if(locIds)
-    {
-      //
-      std::string pflName(locIds->getName());
-      if(pflName.empty())
-        throw INTERP_KERNEL::Exception("MEDFileFieldPerMeshPerType::assignFieldProfile : existing profile with empty name !");
-      const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(_geo_type);
-      std::ostringstream oss; oss << pflName << "_" <<  cm.getRepr();
-      locIds->setName(oss.str().c_str());
-      glob.appendProfile(locIds);
-      //
-      for(std::vector<int>::const_iterator it=pos.begin();it!=pos.end();it++)
-        _field_pm_pt_pd[*it]->assignFieldProfile(start,oss.str().c_str(),multiTypePfl,idsInPfl,field,mesh,glob);
-    }
-  else
-    {
-      for(std::vector<int>::const_iterator it=pos.begin();it!=pos.end();it++)
-        _field_pm_pt_pd[*it]->assignFieldProfile(start,0,multiTypePfl,idsInPfl,field,mesh,glob);
-    }
+  for(std::vector<int>::const_iterator it=pos.begin();it!=pos.end();it++)
+    _field_pm_pt_pd[*it]->assignFieldProfile(start,multiTypePfl,idsInPfl,locIds,nbOfEltsInWholeMesh,field,mesh,glob);
 }
 
 void MEDFileFieldPerMeshPerType::assignNodeFieldNoProfile(int& start, const MEDCouplingFieldDouble *field, MEDFileFieldGlobsReal& glob) throw(INTERP_KERNEL::Exception)
@@ -898,17 +951,11 @@ void MEDFileFieldPerMeshPerType::assignNodeFieldNoProfile(int& start, const MEDC
 
 void MEDFileFieldPerMeshPerType::assignNodeFieldProfile(int& start, const DataArrayInt *pfl, const MEDCouplingFieldDouble *field, MEDFileFieldGlobsReal& glob) throw(INTERP_KERNEL::Exception)
 {
-  std::string pflName(pfl->getName());
-  if(pflName.empty())
-    throw INTERP_KERNEL::Exception("MEDFileFieldPerMeshPerType::assignNodeFieldProfile : existing profile with empty name !");
-  std::ostringstream oss; oss << pflName << "_NODE";
   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> pfl2=pfl->deepCpy();
-  pfl2->setName(oss.str().c_str());
-  glob.appendProfile(pfl2);
   //
   _field_pm_pt_pd.resize(1);
   _field_pm_pt_pd[0]=MEDFileFieldPerMeshPerTypePerDisc::New(this,ON_NODES,-3);
-  _field_pm_pt_pd[0]->assignFieldProfile(start,oss.str().c_str(),pfl,pfl2,field,0,glob);//mesh is not requested so 0 is send.
+  _field_pm_pt_pd[0]->assignFieldProfile(start,pfl,pfl2,pfl2,-1,field,0,glob);//mesh is not requested so 0 is send.
 }
 
 std::vector<int> MEDFileFieldPerMeshPerType::addNewEntryIfNecessary(const MEDCouplingFieldDouble *field, int offset, int nbOfCells) throw(INTERP_KERNEL::Exception)
@@ -1043,7 +1090,7 @@ std::vector<int> MEDFileFieldPerMeshPerType::addNewEntryIfNecessaryGauss(const M
   if(!disc2)
     throw INTERP_KERNEL::Exception("addNewEntryIfNecessaryGauss : invalid call to this method ! Internal Error !");
   const DataArrayInt *da=disc2->getArrayOfDiscIds();
-  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> da2=da->selectByTupleId(subCells->getConstPointer(),subCells->getConstPointer()+subCells->getNumberOfTuples());
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> da2=da->selectByTupleIdSafe(subCells->getConstPointer(),subCells->getConstPointer()+subCells->getNumberOfTuples());
   std::set<int> retTmp=da2->getDifferentValues();
   if(retTmp.find(-1)!=retTmp.end())
     throw INTERP_KERNEL::Exception("addNewEntryIfNecessaryGauss : some cells have no dicretization description !");
@@ -1403,24 +1450,6 @@ void MEDFileFieldPerMesh::copyTinyInfoFrom(const MEDCouplingMesh *mesh) throw(IN
   mesh->getTime(_mesh_iteration,_mesh_order);
 }
 
-void MEDFileFieldPerMesh::assignFieldProfile(int& start, const DataArrayInt *multiTypePfl, const std::vector<int>& code, const std::vector<DataArrayInt *>& idsInPflPerType, const std::vector<DataArrayInt *>& idsPerType, const MEDCouplingFieldDouble *field, const MEDCouplingMesh *mesh, MEDFileFieldGlobsReal& glob) throw(INTERP_KERNEL::Exception)
-{
-  int nbOfTypes=code.size()/3;
-  bool isProfile=false;
-  for(int i=0;i<nbOfTypes;i++)
-    if(code[3*i+2]!=-1)
-      isProfile=true;
-  if(!isProfile)
-    {
-      if(idsInPflPerType.empty())
-        assignFieldNoProfileNoRenum(start,code,field,glob);
-      else
-        assignFieldProfileGeneral(start,multiTypePfl,code,idsInPflPerType,idsPerType,field,mesh,glob);
-    }
-  else
-    assignFieldProfileGeneral(start,multiTypePfl,code,idsInPflPerType,idsPerType,field,mesh,glob);
-}
-
 void MEDFileFieldPerMesh::assignFieldNoProfileNoRenum(int& start, const std::vector<int>& code, const MEDCouplingFieldDouble *field, MEDFileFieldGlobsReal& glob) throw(INTERP_KERNEL::Exception)
 {
   int nbOfTypes=code.size()/3;
@@ -1437,8 +1466,14 @@ void MEDFileFieldPerMesh::assignFieldNoProfileNoRenum(int& start, const std::vec
 
 /*!
  * This method is the most general one. No optimization is done here.
+ * \param [in] multiTypePfl is the end user profile specified in high level API
+ * \param [in] code is the code of \a mesh[multiTypePfl] mesh. It is of size of number of different geometric types into \a mesh[multiTypePfl].
+ * \param [in] code2 is the code of the \b WHOLE mesh on the same level. So all types in \a code are in \a code2.
+ * \param [in] idsInPflPerType is the selection into the \a multiTypePfl whole profile that corresponds to the given geometric type. This vector is always 3 times smaller than \a code.
+ * \param [in] idsPerType is a vector containing the profiles needed to be created for MED file format. \b WARNING these processed MED file profiles can be subdivided again in case of Gauss points.
+ * \param [in] mesh is the mesh coming from the MEDFileMesh instance in correspondance with the MEDFileField. The mesh inside the \a field is simply ignored.
  */
-void MEDFileFieldPerMesh::assignFieldProfileGeneral(int& start, const DataArrayInt *multiTypePfl, const std::vector<int>& code, const std::vector<DataArrayInt *>& idsInPflPerType, const std::vector<DataArrayInt *>& idsPerType, const MEDCouplingFieldDouble *field, const MEDCouplingMesh *mesh, MEDFileFieldGlobsReal& glob) throw(INTERP_KERNEL::Exception)
+void MEDFileFieldPerMesh::assignFieldProfile(int& start, const DataArrayInt *multiTypePfl, const std::vector<int>& code, const std::vector<int>& code2, const std::vector<DataArrayInt *>& idsInPflPerType, const std::vector<DataArrayInt *>& idsPerType, const MEDCouplingFieldDouble *field, const MEDCouplingMesh *mesh, MEDFileFieldGlobsReal& glob) throw(INTERP_KERNEL::Exception)
 {
   int nbOfTypes=code.size()/3;
   for(int i=0;i<nbOfTypes;i++)
@@ -1448,7 +1483,14 @@ void MEDFileFieldPerMesh::assignFieldProfileGeneral(int& start, const DataArrayI
       DataArrayInt *pfl=0;
       if(code[3*i+2]!=-1)
         pfl=idsPerType[code[3*i+2]];
-      _field_pm_pt[pos]->assignFieldProfile(start,multiTypePfl,idsInPflPerType[i],pfl,field,mesh,glob);
+      int nbOfTupes2=code2.size()/3;
+      int found=0;
+      for(;found<nbOfTupes2;found++)
+        if(code[3*i]==code2[3*found])
+          break;
+      if(found==nbOfTupes2)
+        throw INTERP_KERNEL::Exception("MEDFileFieldPerMesh::assignFieldProfile : internal problem ! Should never happen ! Please report bug to anthony.geay@cea.fr !");
+      _field_pm_pt[pos]->assignFieldProfile(start,multiTypePfl,idsInPflPerType[i],pfl,code2[3*found+1],field,mesh,glob);
     }
 }
 
@@ -1831,6 +1873,9 @@ void MEDFileFieldPerMesh::changeLocsRefsNamesGen(const std::vector< std::pair<st
     (*it)->changeLocsRefsNamesGen(mapOfModif);
 }
 
+/*!
+ * \param [in] mesh is the whole mesh
+ */
 MEDCouplingFieldDouble *MEDFileFieldPerMesh::getFieldOnMeshAtLevel(TypeOfField type, const MEDFileFieldGlobsReal *glob, const MEDCouplingMesh *mesh, bool& isPfl) const throw(INTERP_KERNEL::Exception)
 {
   if(_field_pm_pt.empty())
@@ -2006,7 +2051,8 @@ int MEDFileFieldPerMesh::addNewEntryIfNecessary(INTERP_KERNEL::NormalizedCellTyp
 }
 
 /*!
- * 'dads' and 'locs' input parameters have the same number of elements.
+ * 'dads' and 'locs' input parameters have the same number of elements
+ * \param [in] mesh is \b NOT the global mesh, but the possibly reduced mesh. \a mesh parameter will be directly aggregated in the returned field
  */
 MEDCouplingFieldDouble *MEDFileFieldPerMesh::finishField(TypeOfField type, const MEDFileFieldGlobsReal *glob,
                                                          const std::vector< std::pair<int,int> >& dads, const std::vector<int>& locs,
@@ -2047,6 +2093,7 @@ MEDCouplingFieldDouble *MEDFileFieldPerMesh::finishField(TypeOfField type, const
  * 'dads', 'locs' and 'geoTypes' input parameters have the same number of elements.
  * No check of this is performed. 'da' array contains an array in old2New style to be applyied to mesh to obtain the right support.
  * The order of cells in the returned field is those imposed by the profile.
+ * \param [in] mesh is the global mesh.
  */
 MEDCouplingFieldDouble *MEDFileFieldPerMesh::finishField2(TypeOfField type, const MEDFileFieldGlobsReal *glob,
                                                           const std::vector<std::pair<int,int> >& dads, const std::vector<int>& locs,
@@ -2059,11 +2106,10 @@ MEDCouplingFieldDouble *MEDFileFieldPerMesh::finishField2(TypeOfField type, cons
       if(nbOfTuples==mesh->getNumberOfCells())
         return finishField(type,glob,dads,locs,mesh,isPfl);
     }
-  MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret=finishField(type,glob,dads,locs,mesh,isPfl);
-  isPfl=true;
   MEDCouplingAutoRefCountObjectPtr<MEDCouplingMesh> m2=mesh->buildPart(da->getConstPointer(),da->getConstPointer()+da->getNbOfElems());
   m2->setName(mesh->getName());
-  ret->setMesh(m2);
+  MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret=finishField(type,glob,dads,locs,m2,isPfl);
+  isPfl=true;
   ret->incrRef();
   return ret;
 }
@@ -3420,18 +3466,14 @@ void MEDFileField1TSWithoutSDA::setFieldNoProfileSBT(const MEDCouplingFieldDoubl
   TypeOfField type=field->getTypeOfField();
   std::vector<DataArrayInt *> dummy;
   int start=copyTinyInfoFrom(field);
+  int pos=addNewEntryIfNecessary(mesh);
   if(type!=ON_NODES)
     {
       std::vector<int> code=MEDFileField1TSWithoutSDA::CheckSBTMesh(mesh);
-      //
-      int pos=addNewEntryIfNecessary(mesh);
-      _field_per_mesh[pos]->assignFieldProfile(start,0,code,dummy,dummy,field,0,glob);//mesh is set to 0 because no external mesh is needed to be sent because no profile.
+      _field_per_mesh[pos]->assignFieldNoProfileNoRenum(start,code,field,glob);
     }
   else
-    {
-      int pos=addNewEntryIfNecessary(mesh);
-      _field_per_mesh[pos]->assignNodeFieldNoProfile(start,field,glob);
-    }
+    _field_per_mesh[pos]->assignNodeFieldNoProfile(start,field,glob);
 }
 
 /*!
@@ -3443,11 +3485,12 @@ void MEDFileField1TSWithoutSDA::setFieldProfile(const MEDCouplingFieldDouble *fi
   int start=copyTinyInfoFrom(field);
   std::vector<DataArrayInt *> idsInPflPerType;
   std::vector<DataArrayInt *> idsPerType;
-  std::vector<int> code;
+  std::vector<int> code,code2;
   MEDCouplingAutoRefCountObjectPtr<MEDCouplingMesh> m=mesh->getGenMeshAtLevel(meshDimRelToMax);
   if(type!=ON_NODES)
     {
       m->splitProfilePerType(profile,code,idsInPflPerType,idsPerType);
+      code2=m->getDistributionOfTypes();
       //
       std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > idsInPflPerType2(idsInPflPerType.size());
       for(std::size_t i=0;i<idsInPflPerType.size();i++)
@@ -3457,7 +3500,7 @@ void MEDFileField1TSWithoutSDA::setFieldProfile(const MEDCouplingFieldDouble *fi
         idsPerType2[i]=idsPerType[i];
       //
       int pos=addNewEntryIfNecessary(m);
-      _field_per_mesh[pos]->assignFieldProfile(start,profile,code,idsInPflPerType,idsPerType,field,m,glob);
+      _field_per_mesh[pos]->assignFieldProfile(start,profile,code,code2,idsInPflPerType,idsPerType,field,m,glob);
     }
   else
     {
@@ -3498,6 +3541,9 @@ MEDCouplingFieldDouble *MEDFileField1TSWithoutSDA::getFieldAtTopLevel(TypeOfFiel
   return MEDFileField1TSWithoutSDA::getFieldOnMeshAtLevel(type,meshDimRelToMax,renumPol,glob,mm);
 }
 
+/*!
+ * \param [in] mesh is the whole mesh.
+ */
 MEDCouplingFieldDouble *MEDFileField1TSWithoutSDA::getFieldOnMeshAtLevel(TypeOfField type, int renumPol, const MEDFileFieldGlobsReal *glob, const MEDCouplingMesh *mesh, const DataArrayInt *cellRenum, const DataArrayInt *nodeRenum) const throw(INTERP_KERNEL::Exception)
 {
   static const char msg1[]="MEDFileField1TSWithoutSDA::getFieldOnMeshAtLevel : request for a renumbered field following mesh numbering whereas it is a profile field !";
@@ -3597,7 +3643,7 @@ DataArrayDouble *MEDFileField1TSWithoutSDA::getUndergroundDataArrayExt(std::vect
 }
 
 MEDFileField1TSWithoutSDA::MEDFileField1TSWithoutSDA(const char *fieldName, int csit, int fieldtype, int iteration, int order,
-                                                     const std::vector<std::string>& infos):_csit(csit),_field_type(fieldtype),_iteration(iteration),_order(order)
+                                                     const std::vector<std::string>& infos):_iteration(iteration),_order(order),_csit(csit),_field_type(fieldtype)
 {
   DataArrayDouble *arr=getOrCreateAndGetArray();
   arr->setName(fieldName);
@@ -3747,7 +3793,7 @@ void MEDFileField1TS::write(const char *fileName, int mode) const throw(INTERP_K
 }
 
 MEDFileField1TS::MEDFileField1TS(const char *fileName, const char *fieldName, int iteration, int order) throw(INTERP_KERNEL::Exception)
-try:_content(MEDFileField1TSWithoutSDA::New(fieldName,-1,-1,iteration,order,std::vector<std::string>())),MEDFileFieldGlobsReal(fileName)
+try:MEDFileFieldGlobsReal(fileName),_content(MEDFileField1TSWithoutSDA::New(fieldName,-1,-1,iteration,order,std::vector<std::string>()))
 {
   MEDFileUtilities::CheckFileForRead(fileName);
   MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName,MED_ACC_RDONLY);
@@ -4218,9 +4264,8 @@ MEDFileFieldMultiTSWithoutSDA::MEDFileFieldMultiTSWithoutSDA(med_idt fid, int fi
 try:_name("")
 {
   med_field_type typcha;
-  int nbstep2=-1;
   //
-  int ncomp=MEDfieldnComponent(fid,1);
+  int ncomp=MEDfieldnComponent(fid,fieldId+1);
   INTERP_KERNEL::AutoPtr<char> comp=MEDLoaderBase::buildEmptyString(ncomp*MED_SNAME_SIZE);
   INTERP_KERNEL::AutoPtr<char> unit=MEDLoaderBase::buildEmptyString(ncomp*MED_SNAME_SIZE);
   INTERP_KERNEL::AutoPtr<char> dtunit=MEDLoaderBase::buildEmptyString(MED_LNAME_SIZE);
@@ -4539,12 +4584,12 @@ int MEDFileFieldMultiTSWithoutSDA::getPosOfTimeStep(int iteration, int order) co
       const MEDFileField1TSWithoutSDA *tmp(*it);
       if(tmp)
         {
-          int it,ord;
-          tmp->getTime(it,ord);
-          if(it==iteration && order==ord)
+          int it2,ord;
+          tmp->getTime(it2,ord);
+          if(it2==iteration && order==ord)
             return ret;
           else
-            oss << "(" << it << ","  << ord << "), ";
+            oss << "(" << it2 << ","  << ord << "), ";
         }
     }
   throw INTERP_KERNEL::Exception(oss.str().c_str());
@@ -4560,8 +4605,8 @@ int MEDFileFieldMultiTSWithoutSDA::getPosGivenTime(double time, double eps) cons
       const MEDFileField1TSWithoutSDA *tmp(*it);
       if(tmp)
         {
-          int it,ord;
-          double ti=tmp->getTime(it,ord);
+          int it2,ord;
+          double ti=tmp->getTime(it2,ord);
           if(fabs(time-ti)<eps)
             return ret;
           else
index b6afd67a1f57c5c00bf2918ae0b00e219fcfbffc..6ddb6f2093abd4981a74e02f01de0538953a28b5 100644 (file)
@@ -93,7 +93,7 @@ namespace ParaMEDMEM
     static MEDFileFieldPerMeshPerTypePerDisc *New(MEDFileFieldPerMeshPerType *fath, TypeOfField type, int locId);
     static MEDFileFieldPerMeshPerTypePerDisc *New(const MEDFileFieldPerMeshPerTypePerDisc& other);
     void assignFieldNoProfile(int& start, int offset, int nbOfCells, const MEDCouplingFieldDouble *field, MEDFileFieldGlobsReal& glob) throw(INTERP_KERNEL::Exception);
-    void assignFieldProfile(int& start, const char *pflName, const DataArrayInt *multiTypePfl, const DataArrayInt *idsInPfl, const MEDCouplingFieldDouble *field, const MEDCouplingMesh *mesh, MEDFileFieldGlobsReal& glob) throw(INTERP_KERNEL::Exception);
+    void assignFieldProfile(int& start, const DataArrayInt *multiTypePfl, const DataArrayInt *idsInPfl, DataArrayInt *locIds, int nbOfEltsInWholeMesh, const MEDCouplingFieldDouble *field, const MEDCouplingMesh *mesh, MEDFileFieldGlobsReal& glob) throw(INTERP_KERNEL::Exception);
     void assignNodeFieldNoProfile(int& start, const MEDCouplingFieldDouble *field, MEDFileFieldGlobsReal& glob) throw(INTERP_KERNEL::Exception);
     void getCoarseData(TypeOfField& type, std::pair<int,int>& dad, std::string& pfl, std::string& loc) const throw(INTERP_KERNEL::Exception);
     void writeLL(med_idt fid) const throw(INTERP_KERNEL::Exception);
@@ -165,7 +165,7 @@ namespace ParaMEDMEM
     static MEDFileFieldPerMeshPerType *New(MEDFileFieldPerMesh *fath, INTERP_KERNEL::NormalizedCellType geoType) throw(INTERP_KERNEL::Exception);
     static MEDFileFieldPerMeshPerType *NewOnRead(med_idt fid, MEDFileFieldPerMesh *fath, TypeOfField type, INTERP_KERNEL::NormalizedCellType geoType) throw(INTERP_KERNEL::Exception);
     void assignFieldNoProfile(int& start, int offset, int nbOfCells, const MEDCouplingFieldDouble *field, MEDFileFieldGlobsReal& glob) throw(INTERP_KERNEL::Exception);
-    void assignFieldProfile(int& start, const DataArrayInt *multiTypePfl, const DataArrayInt *idsInPfl, DataArrayInt *locIds, const MEDCouplingFieldDouble *field, const MEDCouplingMesh *mesh, MEDFileFieldGlobsReal& glob) throw(INTERP_KERNEL::Exception);
+    void assignFieldProfile(int& start, const DataArrayInt *multiTypePfl, const DataArrayInt *idsInPfl, DataArrayInt *locIds, int nbOfEltsInWholeMesh, const MEDCouplingFieldDouble *field, const MEDCouplingMesh *mesh, MEDFileFieldGlobsReal& glob) throw(INTERP_KERNEL::Exception);
     void assignNodeFieldNoProfile(int& start, const MEDCouplingFieldDouble *field, MEDFileFieldGlobsReal& glob) throw(INTERP_KERNEL::Exception);
     void assignNodeFieldProfile(int& start, const DataArrayInt *pfl, const MEDCouplingFieldDouble *field, MEDFileFieldGlobsReal& glob) throw(INTERP_KERNEL::Exception);
     const MEDFileFieldPerMesh *getFather() const;
@@ -219,8 +219,7 @@ namespace ParaMEDMEM
     static MEDFileFieldPerMesh *NewOnRead(med_idt fid, MEDFileField1TSWithoutSDA *fath, int meshCsit, int meshIteration, int meshOrder) throw(INTERP_KERNEL::Exception);
     void simpleRepr(int bkOffset,std::ostream& oss, int id) const;
     void copyTinyInfoFrom(const MEDCouplingMesh *mesh) throw(INTERP_KERNEL::Exception);
-    void assignFieldProfile(int& start, const DataArrayInt *multiTypePfl, const std::vector<int>& code, const std::vector<DataArrayInt *>& idsInPflPerType, const std::vector<DataArrayInt *>& idsPerType, const MEDCouplingFieldDouble *field, const MEDCouplingMesh *mesh, MEDFileFieldGlobsReal& glob) throw(INTERP_KERNEL::Exception);
-    void assignFieldProfileGeneral(int& start, const DataArrayInt *multiTypePfl, const std::vector<int>& code, const std::vector<DataArrayInt *>& idsInPflPerType, const std::vector<DataArrayInt *>& idsPerType, const MEDCouplingFieldDouble *field, const MEDCouplingMesh *mesh, MEDFileFieldGlobsReal& glob) throw(INTERP_KERNEL::Exception);
+    void assignFieldProfile(int& start, const DataArrayInt *multiTypePfl, const std::vector<int>& code, const std::vector<int>& code2, const std::vector<DataArrayInt *>& idsInPflPerType, const std::vector<DataArrayInt *>& idsPerType, const MEDCouplingFieldDouble *field, const MEDCouplingMesh *mesh, MEDFileFieldGlobsReal& glob) throw(INTERP_KERNEL::Exception);
     void assignFieldNoProfileNoRenum(int& start, const std::vector<int>& code, const MEDCouplingFieldDouble *field, MEDFileFieldGlobsReal& glob) throw(INTERP_KERNEL::Exception);
     void assignNodeFieldNoProfile(int& start, const MEDCouplingFieldDouble *field, MEDFileFieldGlobsReal& glob) throw(INTERP_KERNEL::Exception);
     void assignNodeFieldProfile(int& start, const DataArrayInt *pfl, const MEDCouplingFieldDouble *field, MEDFileFieldGlobsReal& glob) throw(INTERP_KERNEL::Exception);
index 6f77ac21770c9d32dba7126cf8ad001dfb18952c..5c5ccd8f86eb99458176ac048df611bf8194cac0 100644 (file)
@@ -217,8 +217,8 @@ std::vector<std::string> MEDFileMesh::getFamiliesOnGroups(const std::vector<std:
       if(it2==_groups.end())
         {
           std::ostringstream oss; oss << "No such group in mesh \"" << _name << "\" : " << *it; 
-          std::vector<std::string> grps=getGroupsNames(); oss << "\" !\nAvailable groups are :";
-          std::copy(grps.begin(),grps.end(),std::ostream_iterator<std::string>(oss," "));
+          std::vector<std::string> grps2=getGroupsNames(); oss << "\" !\nAvailable groups are :";
+          std::copy(grps2.begin(),grps2.end(),std::ostream_iterator<std::string>(oss," "));
           throw INTERP_KERNEL::Exception(oss.str().c_str());
         }
       fams.insert((*it2).second.begin(),(*it2).second.end());
@@ -2132,7 +2132,7 @@ bool MEDFileUMesh::unPolyze(std::vector<int>& oldCode, std::vector<int>& newCode
   std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > memorySaverIfThrow;//same than renumCellsSplited only in case of throw
   int start=0;
   int end=0;
-  for(std::vector<int>::const_reverse_iterator it=levs.rbegin();it!=levs.rend();it++)
+  for(std::vector<int>::reverse_iterator it=levs.rbegin();it!=levs.rend();it++)
     {
       MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=getMeshAtLevel(*it);
       std::vector<int> code1=m->getDistributionOfTypes();
index 2c3c77d9be8d6c7fff7abb6536ff48ba0308c4e7..cfb86ad46dde52f834c11069712e2e8890afcef9 100644 (file)
@@ -652,7 +652,6 @@ void MEDFileUMeshSplitL1::eraseFamilyField()
 void MEDFileUMeshSplitL1::setGroupsFromScratch(const std::vector<const MEDCouplingUMesh *>& ms, std::map<std::string,int>& familyIds,
                                                std::map<std::string, std::vector<std::string> >& groups) throw(INTERP_KERNEL::Exception)
 {
-  int sz=ms.size();
   std::vector< DataArrayInt * > corr;
   _m=MEDCouplingUMesh::FuseUMeshesOnSameCoords(ms,0,corr);
   std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > corrMSafe(corr.begin(),corr.end());
index 60e8773ec517cbc912193479c5e0abef9a2416c5..8fd883859bd4ed48c59c9dd5489fede99e6b75be 100644 (file)
@@ -261,11 +261,11 @@ void MEDLoader::MEDConnOfOneElemType::releaseArray()
   delete [] _global;
 }
 
-MEDLoader::MEDFieldDoublePerCellType::MEDFieldDoublePerCellType(INTERP_KERNEL::NormalizedCellType type, double *values, int ncomp, int ntuple,
-                                                                const int *cellIdPerType, const char *locName):_ntuple(ntuple),_ncomp(ncomp),_values(values),_type(type)
+MEDLoader::MEDFieldDoublePerCellType::MEDFieldDoublePerCellType(INTERP_KERNEL::NormalizedCellType type, double *values, int ncomp, int nGeoElt, int nbi,
+                                                                const int *cellIdPerType, const char *locName):_ngeo_elt(nGeoElt),_nbi(nbi),_ncomp(ncomp),_values(values),_type(type)
 {
   if(cellIdPerType)
-    _cell_id_per_type.insert(_cell_id_per_type.end(),cellIdPerType,cellIdPerType+ntuple);
+    _cell_id_per_type.insert(_cell_id_per_type.end(),cellIdPerType,cellIdPerType+nGeoElt);
   if(locName)
     _loc_name=locName;
 }
@@ -308,6 +308,7 @@ void MEDLoaderNS::fillGaussDataOnField(const char *fileName, const std::list<MED
   char locName[MED_NAME_SIZE+1];
   int nloc=MEDnLocalization(fid);
   med_geometry_type typeGeo;
+  int offset=0;
   for(std::list<MEDLoader::MEDFieldDoublePerCellType>::const_iterator iter=data.begin();iter!=data.end();iter++)
     {
       const std::string& loc=(*iter).getLocName();
@@ -329,7 +330,16 @@ void MEDLoaderNS::fillGaussDataOnField(const char *fileName, const std::list<MED
       int nbPtPerCell=(int)INTERP_KERNEL::CellModel::GetCellModel((*iter).getType()).getNumberOfNodes();
       std::vector<double> refcoo(nbPtPerCell*dim),gscoo(nbOfGaussPt*dim),w(nbOfGaussPt);
       MEDlocalizationRd(fid,(*iter).getLocName().c_str(),MED_FULL_INTERLACE,&refcoo[0],&gscoo[0],&w[0]);
-      f->setGaussLocalizationOnType((*iter).getType(),refcoo,gscoo,w);
+      if((*iter).getCellIdPerType().empty())
+        f->setGaussLocalizationOnType((*iter).getType(),refcoo,gscoo,w);
+      else
+        {
+          MEDCouplingAutoRefCountObjectPtr<DataArrayInt> pfl=DataArrayInt::New();
+          pfl->alloc((*iter).getCellIdPerType().size(),1);
+          pfl->iota(offset);
+          f->setGaussLocalizationOnCells(pfl->begin(),pfl->end(),refcoo,gscoo,w);
+        }
+      offset+=(*iter).getNbOfGeoElt();
     }
   MEDfileClose(fid);
 }
@@ -1106,27 +1116,33 @@ void MEDLoaderNS::readFieldDoubleDataInMedFile(const char *fileName, const char
             {
               if(nbPdt>0)
                 {
-                  int profilesize,nbi;
-                  int nval=MEDfieldnValueWithProfile(fid,fieldName,numdt,numo,tabEnt[typeOfOutField],tabType[typeOfOutField][j],1,MED_COMPACT_PFLMODE,pflname,&profilesize,locname,&nbi);
-                  if(nval>0)
+                  INTERP_KERNEL::AutoPtr<char> pflDummy=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
+                  INTERP_KERNEL::AutoPtr<char> locDummy=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
+                  int nbProfiles=MEDfieldnProfile(fid,fieldName,numdt,numo,tabEnt[typeOfOutField],tabType[typeOfOutField][j],pflDummy,locDummy);
+                  for(int kk=0;kk<nbProfiles;kk++)
                     {
-                      double *valr=new double[ncomp*nval*nbi];
-                      MEDfieldValueWithProfileRd(fid,fieldName,iteration,order,tabEnt[typeOfOutField],tabType[typeOfOutField][j],MED_COMPACT_PFLMODE,
-                                                 pflname,MED_FULL_INTERLACE,MED_ALL_CONSTITUENT,(unsigned char*)valr);
-                      std::string tmp(locname);
-                      if((locname[0]!='\0' && (typeOfOutField!=ON_GAUSS_PT))
-                         || (locname[0]=='\0' && typeOfOutField==ON_GAUSS_PT))
+                      int profilesize,nbi;
+                      int nval=MEDfieldnValueWithProfile(fid,fieldName,numdt,numo,tabEnt[typeOfOutField],tabType[typeOfOutField][j],kk+1,MED_COMPACT_PFLMODE,pflname,&profilesize,locname,&nbi);
+                      if(nval>0)
                         {
-                          delete [] valr;
-                          continue;
+                          double *valr=new double[ncomp*nval*nbi];
+                          MEDfieldValueWithProfileRd(fid,fieldName,iteration,order,tabEnt[typeOfOutField],tabType[typeOfOutField][j],MED_COMPACT_PFLMODE,
+                                                     pflname,MED_FULL_INTERLACE,MED_ALL_CONSTITUENT,(unsigned char*)valr);
+                          std::string tmp(locname);
+                          if((locname[0]!='\0' && (typeOfOutField!=ON_GAUSS_PT))
+                             || (locname[0]=='\0' && typeOfOutField==ON_GAUSS_PT))
+                            {
+                              delete [] valr;
+                              continue;
+                            }
+                          INTERP_KERNEL::AutoPtr<int> pfl=0;
+                          if(pflname[0]!='\0')
+                            {
+                              pfl=new int[nval];
+                              MEDprofileRd(fid,pflname,pfl);
+                            }
+                          field.push_back(MEDLoader::MEDFieldDoublePerCellType(typmai2[j],valr,ncomp,nval,nbi,pfl,locname));
                         }
-                      INTERP_KERNEL::AutoPtr<int> pfl=0;
-                      if(pflname[0]!='\0')
-                        {
-                          pfl=new int[nval];
-                          MEDprofileRd(fid,pflname,pfl);
-                        }
-                      field.push_back(MEDLoader::MEDFieldDoublePerCellType(typmai2[j],valr,ncomp,nval*nbi,pfl,locname));
                     }
                 }
             }
@@ -1884,32 +1900,26 @@ ParaMEDMEM::MEDCouplingFieldDouble *MEDLoaderNS::readFieldDoubleLev2(const char
       throw INTERP_KERNEL::Exception(oss.str().c_str());
     }
   //for profiles
-  ParaMEDMEM::MEDCouplingUMesh *newMesh=0;
+  MEDCouplingAutoRefCountObjectPtr<ParaMEDMEM::MEDCouplingUMesh> newMesh;
   std::string mName(mesh->getName());
-  for(std::list<MEDLoader::MEDFieldDoublePerCellType>::const_iterator iter=fieldPerCellType.begin();iter!=fieldPerCellType.end();iter++)
+  if(typeOfOutField==ON_NODES)
     {
-      const std::vector<int>& cellIds=(*iter).getCellIdPerType();
-      if(!cellIds.empty())
+      for(std::list<MEDLoader::MEDFieldDoublePerCellType>::const_iterator iter=fieldPerCellType.begin();iter!=fieldPerCellType.end();iter++)
         {
-          std::vector<int> ci(cellIds.size());
-          std::transform(cellIds.begin(),cellIds.end(),ci.begin(),std::bind2nd(std::plus<int>(),-1));
-          ParaMEDMEM::MEDCouplingUMesh *mesh2=0;
-          if(typeOfOutField==ON_CELLS)
+          const std::vector<int>& cellIds=(*iter).getCellIdPerType();
+          if(!cellIds.empty())
             {
-              if(newMesh)
-                mesh2=newMesh->keepSpecifiedCells((*iter).getType(),&ci[0],&ci[0]+ci.size());
-              else
-                mesh2=mesh->keepSpecifiedCells((*iter).getType(),&ci[0],&ci[0]+ci.size());
-            }
-          else if(typeOfOutField==ON_NODES)
-            {
-              DataArrayInt *da=0,*da2=0;
-              if(newMesh)
+              std::vector<int> ci(cellIds.size());
+              std::transform(cellIds.begin(),cellIds.end(),ci.begin(),std::bind2nd(std::plus<int>(),-1));
+              MEDCouplingAutoRefCountObjectPtr<ParaMEDMEM::MEDCouplingUMesh> mesh2;
+              MEDCouplingAutoRefCountObjectPtr<DataArrayInt> da,da2;
+              if((const ParaMEDMEM::MEDCouplingUMesh *)newMesh)
                 {
                   if((int)ci.size()!=newMesh->getNumberOfNodes())
                     {
                       da=newMesh->getCellIdsFullyIncludedInNodeIds(&ci[0],&ci[ci.size()]);
-                      mesh2=dynamic_cast<MEDCouplingUMesh *>(newMesh->buildPartAndReduceNodes(da->getConstPointer(),da->getConstPointer()+da->getNbOfElems(),da2));
+                      DataArrayInt *tmpp=0;
+                      mesh2=dynamic_cast<MEDCouplingUMesh *>(newMesh->buildPartAndReduceNodes(da->begin(),da->end(),tmpp)); da2=tmpp;
                     }
                 }
               else
@@ -1917,7 +1927,8 @@ ParaMEDMEM::MEDCouplingFieldDouble *MEDLoaderNS::readFieldDoubleLev2(const char
                   if((int)ci.size()!=mesh->getNumberOfNodes())
                     {
                       da=mesh->getCellIdsFullyIncludedInNodeIds(&ci[0],&ci[ci.size()]);
-                      mesh2=dynamic_cast<MEDCouplingUMesh *>(mesh->buildPartAndReduceNodes(da->getConstPointer(),da->getConstPointer()+da->getNbOfElems(),da2));
+                      DataArrayInt *tmpp=0;
+                      mesh2=dynamic_cast<MEDCouplingUMesh *>(mesh->buildPartAndReduceNodes(da->begin(),da->end(),tmpp)); da2=tmpp;
                       //
                       int nnodes=mesh2->getNumberOfNodes();
                       MEDCouplingAutoRefCountObjectPtr<DataArrayInt> da3=DataArrayInt::New();
@@ -1942,32 +1953,47 @@ ParaMEDMEM::MEDCouplingFieldDouble *MEDLoaderNS::readFieldDoubleLev2(const char
                       mesh2->renumberNodes(da2->getConstPointer(),(int)ci.size());
                     }
                 }
-              if(da)
-                da->decrRef();
-              if(da2)
-                da2->decrRef();
+              newMesh=mesh2;
+            }
+        }
+    }
+  else
+    {
+      newMesh=const_cast<ParaMEDMEM::MEDCouplingUMesh *>(static_cast<const ParaMEDMEM::MEDCouplingUMesh *>(mesh)); mesh->incrRef();
+      std::vector<INTERP_KERNEL::NormalizedCellType> types;
+      for(std::list<MEDLoader::MEDFieldDoublePerCellType>::const_iterator iter=fieldPerCellType.begin();iter!=fieldPerCellType.end();iter++)
+        if(std::find(types.begin(),types.end(),(*iter).getType())==types.end())
+          types.push_back((*iter).getType());
+      for(std::vector<INTERP_KERNEL::NormalizedCellType>::const_iterator it=types.begin();it!=types.end();it++)
+        {
+          std::vector<int> cids;
+          for(std::list<MEDLoader::MEDFieldDoublePerCellType>::const_iterator iter=fieldPerCellType.begin();iter!=fieldPerCellType.end();iter++)
+            {
+              if((*iter).getType()==*it)
+                {
+                  const std::vector<int>& cellIds=(*iter).getCellIdPerType();
+                  if(!cellIds.empty())
+                    std::transform(cellIds.begin(),cellIds.end(),std::back_insert_iterator< std::vector<int> >(cids),std::bind2nd(std::plus<int>(),-1));
+                }
             }
-          if(newMesh)
-            newMesh->decrRef();
-          newMesh=mesh2;
+          if(!cids.empty())
+            newMesh=newMesh->keepSpecifiedCells(*it,&cids[0],&cids[0]+cids.size());
         }
     }
   //
   ParaMEDMEM::MEDCouplingFieldDouble *ret=ParaMEDMEM::MEDCouplingFieldDouble::New(typeOfOutField,ONE_TIME);
   ret->setName(fieldName);
   ret->setTime(time,iteration,order);
-  if(newMesh)
+  ParaMEDMEM::DataArrayDouble *arr=buildArrayFromRawData(fieldPerCellType,infos);
+  ret->setArray(arr);
+  arr->decrRef();
+  if((const ParaMEDMEM::MEDCouplingUMesh *)newMesh)
     {
       newMesh->setName(mName.c_str());//retrieving mesh name to avoid renaming due to mesh restriction in case of profile.
       ret->setMesh(newMesh);
-      newMesh->decrRef();
     }
   else
     ret->setMesh(mesh);
-  ParaMEDMEM::DataArrayDouble *arr=buildArrayFromRawData(fieldPerCellType,infos);
-  ret->setArray(arr);
-  arr->decrRef();
-  //
   if(typeOfOutField==ON_GAUSS_PT)
     fillGaussDataOnField(fileName,fieldPerCellType,ret);
   if(cellRenum)
@@ -2376,10 +2402,9 @@ void MEDLoaderNS::appendCellProfileField(const char *fileName, const ParaMEDMEM:
       std::ostringstream oss; oss << "Pfl" << f->getName() << "_" << number++;
       MEDLoaderBase::safeStrCpy(oss.str().c_str(),MED_NAME_SIZE,profileName,MEDLoader::_TOO_LONG_STR);
       const std::vector<int>& ids=(*iter).getCellIdPerType();
-      int *profile=new int [ids.size()];
-      std::transform(ids.begin(),ids.end(),profile,std::bind2nd(std::plus<int>(),1));
+      INTERP_KERNEL::AutoPtr<int> profile=new int [ids.size()];
+      std::transform(ids.begin(),ids.end(),(int *)profile,std::bind2nd(std::plus<int>(),1));
       MEDprofileWr(fid,profileName,ids.size(),profile);
-      delete [] profile;
       MEDfieldValueWithProfileWr(fid,f->getName(),numdt,numo,dt,MED_CELL,typmai3[(int)(*iter).getType()],MED_COMPACT_PFLMODE,profileName,
                                  MED_NO_LOCALIZATION,MED_FULL_INTERLACE,MED_ALL_CONSTITUENT,(*iter).getNbOfTuple(),(const unsigned char*)pt);
       pt+=(*iter).getNbOfTuple()*nbComp;
@@ -2405,10 +2430,9 @@ void MEDLoaderNS::appendNodeElementProfileField(const char *fileName, const Para
       std::ostringstream oss; oss << "Pfl" << f->getName() << "_" << number++;
       MEDLoaderBase::safeStrCpy(oss.str().c_str(),MED_NAME_SIZE,profileName,MEDLoader::_TOO_LONG_STR);
       const std::vector<int>& ids=(*iter).getCellIdPerType();
-      int *profile=new int [ids.size()];
-      std::transform(ids.begin(),ids.end(),profile,std::bind2nd(std::plus<int>(),1));
+      INTERP_KERNEL::AutoPtr<int> profile=new int [ids.size()];
+      std::transform(ids.begin(),ids.end(),(int *)profile,std::bind2nd(std::plus<int>(),1));
       MEDprofileWr(fid,profileName,ids.size(),profile);
-      delete [] profile;
       int nbPtPerCell=(int)INTERP_KERNEL::CellModel::GetCellModel((*iter).getType()).getNumberOfNodes();
       int nbOfEntity=f->getMesh()->getNumberOfCellsWithType((*iter).getType());
       int nbOfValues=nbPtPerCell*nbOfEntity;
@@ -2510,25 +2534,75 @@ void MEDLoaderNS::appendFieldDirectly(const char *fileName, const ParaMEDMEM::ME
       }
     case ParaMEDMEM::ON_GAUSS_PT:
       {
+        INTERP_KERNEL::AutoPtr<char> profileName=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
         std::list<MEDLoader::MEDFieldDoublePerCellType> split;
         prepareCellFieldDoubleForWriting(f,0,split);
-        int idGp=0;
+        int idGp=0,offset=0,offset2=0;
+        const double *pt2=0;
+        INTERP_KERNEL::NormalizedCellType prevType=INTERP_KERNEL::NORM_ERROR;
         for(std::list<MEDLoader::MEDFieldDoublePerCellType>::const_iterator iter=split.begin();iter!=split.end();iter++)
           {
+            if((*iter).getType()!=prevType)
+              {
+                offset=offset2;
+                prevType=(*iter).getType();
+              }
             INTERP_KERNEL::AutoPtr<char> nomGauss=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
             std::ostringstream oss; oss << "GP_" << f->getName() << idGp++;
             MEDLoaderBase::safeStrCpy(oss.str().c_str(),MED_NAME_SIZE,nomGauss,MEDLoader::_TOO_LONG_STR);
-            int id=f->getGaussLocalizationIdOfOneType((*iter).getType());
+            std::ostringstream ossPfl;
+            int id=-1,nbOfEntity=-1;
+            MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> arrTmp;
+            if((*iter).getCellIdPerType().empty())
+              {
+                id=f->getGaussLocalizationIdOfOneType((*iter).getType());
+                nbOfEntity=f->getMesh()->getNumberOfCellsWithType((*iter).getType());
+              }
+            else
+              {
+                id=f->getGaussLocalizationIdOfOneCell((*iter).getCellIdPerType()[0]+offset);
+                nbOfEntity=(int)(*iter).getCellIdPerType().size();
+                ossPfl << "Pfl" << f->getName() << "_" << id;
+                MEDLoaderBase::safeStrCpy(ossPfl.str().c_str(),MED_NAME_SIZE,profileName,MEDLoader::_TOO_LONG_STR);
+                INTERP_KERNEL::AutoPtr<int> profile=new int[(*iter).getCellIdPerType().size()];
+                std::transform((*iter).getCellIdPerType().begin(),(*iter).getCellIdPerType().end(),(int *)profile,std::bind2nd(std::plus<int>(),1));
+                MEDprofileWr(fid,profileName,(*iter).getCellIdPerType().size(),profile);
+                //
+                MEDCouplingAutoRefCountObjectPtr<DataArrayInt> da3=DataArrayInt::New();
+                da3->useArray(const_cast<int *>(&((*iter).getCellIdPerType()[0])),false,CPP_DEALLOC,(int)(*iter).getCellIdPerType().size(),1);
+                MEDCouplingAutoRefCountObjectPtr<DataArrayInt> da4=da3->deepCpy();
+                da4->applyLin(1,offset);
+                //
+                const MEDCouplingFieldDiscretizationGauss *disc2=static_cast<const MEDCouplingFieldDiscretizationGauss *>(f->getDiscretization());
+                MEDCouplingAutoRefCountObjectPtr<DataArrayInt> arr=disc2->getOffsetArr(f->getMesh());
+                MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=DataArrayInt::New();
+                int trueNval=0;
+                for(const int *pt3=da4->begin();pt3!=da4->end();pt3++)
+                  trueNval+=arr->getIJ(*pt3+1,0)-arr->getIJ(*pt3,0);
+                tmp->alloc(trueNval,1);
+                int *tmpPtr=tmp->getPointer();
+                for(const int *pt3=da4->begin();pt3!=da4->end();pt3++)
+                  for(int j=arr->getIJ(*pt3,0);j<arr->getIJ(*pt3+1,0);j++)
+                    *tmpPtr++=j;
+                arrTmp=f->getArray()->selectByTupleId(tmp->begin(),tmp->end());
+                pt2=arrTmp->getConstPointer();
+              }
             const MEDCouplingGaussLocalization& gl=f->getGaussLocalization(id);
             MEDlocalizationWr(fid,nomGauss,typmai3[(int)(*iter).getType()],mesh->getMeshDimension(),&gl.getRefCoords()[0],MED_FULL_INTERLACE,
                               gl.getNumberOfGaussPt(),&gl.getGaussCoords()[0],&gl.getWeights()[0],MED_NO_INTERPOLATION, MED_NO_MESH_SUPPORT);
-            int nbOfEntity=f->getMesh()->getNumberOfCellsWithType((*iter).getType());
             int nbOfValues=gl.getNumberOfGaussPt()*nbOfEntity;
             INTERP_KERNEL::AutoPtr<char> fieldname=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
             MEDLoaderBase::safeStrCpy(f->getName(),MED_NAME_SIZE,fieldname,MEDLoader::_TOO_LONG_STR);
-            MEDfieldValueWithProfileWr(fid,fieldname,numdt,numo,dt,MED_CELL,typmai3[(int)(*iter).getType()],MED_COMPACT_PFLMODE,
-                                       MED_ALLENTITIES_PROFILE,nomGauss,MED_FULL_INTERLACE,MED_ALL_CONSTITUENT,nbOfEntity,(const unsigned char*)pt);
+            if((*iter).getCellIdPerType().empty())
+              {
+                MEDfieldValueWithProfileWr(fid,fieldname,numdt,numo,dt,MED_CELL,typmai3[(int)(*iter).getType()],MED_COMPACT_PFLMODE,
+                                           MED_ALLENTITIES_PROFILE,nomGauss,MED_FULL_INTERLACE,MED_ALL_CONSTITUENT,nbOfEntity,(const unsigned char*)pt);
+              }
+            else
+              MEDfieldValueWithProfileWr(fid,fieldname,numdt,numo,dt,MED_CELL,typmai3[(int)(*iter).getType()],MED_COMPACT_PFLMODE,
+                                         profileName,nomGauss,MED_FULL_INTERLACE,MED_ALL_CONSTITUENT,nbOfEntity,(const unsigned char*)pt2);
             pt+=nbOfValues*nbComp;
+            offset2+=(*iter).getNbOfGeoElt();
           }
         break;
       }
@@ -2577,12 +2651,56 @@ void MEDLoaderNS::prepareCellFieldDoubleForWriting(const ParaMEDMEM::MEDCoupling
     {
       curType=(INTERP_KERNEL::NormalizedCellType)conn[*pt];
       const int *pt2=std::find_if(pt+1,connI+nbOfCells,ConnReaderML(conn,(int)curType));
-      if(!cellIdsPerType)
-        split.push_back(MEDLoader::MEDFieldDoublePerCellType(curType,0,nbComp,pt2-pt,0,0));
+      int szOfChunk=std::distance(pt,pt2);
+      if(f->getTypeOfField()!=ON_GAUSS_PT)
+        {
+          if(!cellIdsPerType)
+            split.push_back(MEDLoader::MEDFieldDoublePerCellType(curType,0,nbComp,szOfChunk,1,0,0));
+          else
+            {
+              split.push_back(MEDLoader::MEDFieldDoublePerCellType(curType,0,nbComp,szOfChunk,1,wCellIdsPT,0));
+              wCellIdsPT+=szOfChunk;
+            }
+        }
       else
         {
-          split.push_back(MEDLoader::MEDFieldDoublePerCellType(curType,0,nbComp,pt2-pt,wCellIdsPT,0));
-          wCellIdsPT+=std::distance(pt,pt2);
+          const MEDCouplingFieldDiscretizationGauss *disc=static_cast<const MEDCouplingFieldDiscretizationGauss *>(f->getDiscretization());
+          const DataArrayInt *arr=disc->getArrayOfDiscIds();
+          MEDCouplingAutoRefCountObjectPtr<DataArrayInt> da,daTmp1;
+          if(!cellIdsPerType)
+            da=arr->selectByTupleId2(std::distance(connI,pt),std::distance(connI,pt2),1);
+          else
+            {
+              daTmp1=DataArrayInt::New();
+              daTmp1->useArray(const_cast<int *>(cellIdsPerType),false,CPP_DEALLOC,szOfChunk,1);
+              MEDCouplingAutoRefCountObjectPtr<DataArrayInt> daTmp2=daTmp1->deepCpy();
+              daTmp2->applyLin(1,std::distance(connI,pt));
+              da=arr->selectByTupleId(daTmp2->begin(),daTmp2->end());
+            }
+          std::vector<int> differentIds;
+          std::vector<DataArrayInt *> parts=da->partitionByDifferentValues(differentIds);
+          std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > partsAuto(parts.size());
+          int jj=0;
+          for(std::vector<DataArrayInt *>::const_iterator it=parts.begin();it!=parts.end();it++,jj++)
+            partsAuto[jj]=parts[jj];
+          jj=0;
+          for(std::vector<DataArrayInt *>::const_iterator it=parts.begin();it!=parts.end();it++,jj++)
+            {
+              if(!cellIdsPerType)
+                {
+                  if(parts[jj]->getNumberOfTuples()==szOfChunk && parts[jj]->isIdentity())
+                    split.push_back(MEDLoader::MEDFieldDoublePerCellType(curType,0,nbComp,szOfChunk,1,0,0));
+                  else
+                    split.push_back(MEDLoader::MEDFieldDoublePerCellType(curType,0,nbComp,parts[jj]->getNumberOfTuples(),1,parts[jj]->getConstPointer(),0));
+                }
+              else
+                {
+                  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=daTmp1->selectByTupleId(parts[jj]->begin(),parts[jj]->end());
+                  split.push_back(MEDLoader::MEDFieldDoublePerCellType(curType,0,nbComp,tmp->getNumberOfTuples(),1,tmp->getConstPointer(),0));
+                }
+            }
+          if(!cellIdsPerType)
+            wCellIdsPT+=szOfChunk;
         }
       pt=pt2;
     }
@@ -2637,7 +2755,7 @@ void MEDLoaderNS::writeFieldTryingToFitExistingMesh(const char *fileName, const
       throw INTERP_KERNEL::Exception(oss.str().c_str());
     }
   MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=MEDLoader::ReadUMeshFromFile(fileName,f->getMesh()->getName(),f2);
-  MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m2=MEDCouplingUMesh::MergeUMeshes(m,(MEDCouplingUMesh *)f->getMesh());
+  MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m2=MEDCouplingUMesh::MergeUMeshes(m,static_cast<const MEDCouplingUMesh *>(f->getMesh()));
   bool areNodesMerged;
   int newNbOfNodes;
   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> da=m2->mergeNodes(MEDLoader::_EPS_FOR_NODE_COMP,areNodesMerged,newNbOfNodes);
index 61536db389b7a46c385ce6f902cdf39df35e657c..7fd9f43b8ee0ac9707737c7f89621288c6a37b54 100644 (file)
@@ -66,17 +66,19 @@ class MEDLOADER_EXPORT MEDLoader
   class MEDFieldDoublePerCellType
   {
   public:
-    MEDFieldDoublePerCellType(INTERP_KERNEL::NormalizedCellType type, double *values, int ncomp, int ntuple, const int *cellIdPerType, const char *locName);
+    MEDFieldDoublePerCellType(INTERP_KERNEL::NormalizedCellType type, double *values, int ncomp, int nGeoElt, int nbi, const int *cellIdPerType, const char *locName);
     INTERP_KERNEL::NormalizedCellType getType() const { return _type; }
     int getNbComp() const { return _ncomp; }
-    int getNbOfTuple() const { return _ntuple; }
-    int getNbOfValues() const { return _ncomp*_ntuple; }
+    int getNbOfGeoElt() const { return _ngeo_elt; }
+    int getNbOfTuple() const { return _nbi*_ngeo_elt; }
+    int getNbOfValues() const { return _ncomp*_nbi*_ngeo_elt; }
     double *getArray() const { return _values; }
     const std::string& getLocName() const { return _loc_name; }
     const std::vector<int>& getCellIdPerType() const { return _cell_id_per_type; }
     void releaseArray();
   private:
-    int _ntuple;
+    int _ngeo_elt;
+    int _nbi;
     int _ncomp;
     double *_values;
     std::string _loc_name;
index 1622b29803f58e049a40edc98c33b3e873ef632e..194def721043b040abc04a537a772aa5bd24945a 100644 (file)
@@ -1432,6 +1432,156 @@ class MEDLoaderTest(unittest.TestCase):
         #
         mfd.write(fname,2)
         pass
+
+    def testGaussWriteOnPfl1(self):
+        fname="Pyfile49.med"
+        fname2="Pyfile50.med"
+        coords=DataArrayDouble([0.,0.,0.,1.,1.,1.,1.,0.,0.,0.5,0.5,1.,1.,0.5,0.5,0.],8,2)
+        mQ8=MEDCouplingUMesh("",2) ; mQ8.setCoords(coords)
+        mQ8.allocateCells(1)
+        mQ8.insertNextCell(NORM_QUAD8,range(8))
+        mQ8.finishInsertingCells()
+        mQ4=MEDCouplingUMesh("",2) ; mQ4.setCoords(coords)
+        mQ4.allocateCells(1)
+        mQ4.insertNextCell(NORM_QUAD4,range(4))
+        mQ4.finishInsertingCells()
+        mT3=MEDCouplingUMesh("",2) ; mT3.setCoords(coords)
+        mT3.allocateCells(1)
+        mT3.insertNextCell(NORM_TRI3,range(3))
+        mT3.finishInsertingCells()
+        
+        tr=[[0.,4.],[2.,4.],[4.,4.],[6.,4.],[8.,4.],[10.,4.],[12.,4.],[14.,4.],[16.,4.],[18.,4.],[20.,4.],[0.,0.],[2.,0.], [0.,2.],[2.,2.],[4.,2.],[6.,2.],[8.,2.],[10.,2.],[12.,2.]]
+        ms=11*[mT3]+2*[mQ4]+7*[mQ8]
+        ms[:]=(elt.deepCpy() for elt in ms)
+        for m,t in zip(ms,tr):
+            d=m.getCoords() ; d+= t
+            pass
+        m=MEDCouplingUMesh.MergeUMeshes(ms)
+        m.setName("mesh")
+        m2=m[:13] ; m2.setName(m.getName())
+        ### Use case 1 : Pfl on all tri3 and on all quad4. If we were on CELLS or GAUSS_NE no pfl were needed. But here 2 discs in tri3.
+        ### So here 2 pfls will be created (pfl_TRI3_loc_0 and pfl_TRI3_loc_1)
+        f=MEDCouplingFieldDouble.New(ON_GAUSS_PT,ONE_TIME)
+        f.setMesh(m2)
+        f.setTime(4.5,1,2)
+        da=DataArrayDouble(34) ; da.iota(3.)
+        f.setArray(da)
+        f.setName("fieldCellOnPflWithoutPfl")
+        f.setGaussLocalizationOnCells([0,1,2,3,4,5,6,7,8],[0.,0.,1.,0.,1.,1.],[0.3,0.3,0.7,0.7],[0.8,0.2])
+        f.setGaussLocalizationOnCells([9,10],[0.,0.,1.,0.,1.,1.],[0.3,0.3,0.7,0.7,0.8,0.8],[0.8,0.07,0.13])
+        f.setGaussLocalizationOnCells([11,12],[0.,0.,1.,0.,1.,1.,0.,1.],[0.3,0.3,0.7,0.7,0.8,0.8,0.8,0.8,0.8,0.8],[0.8,0.07,0.1,0.01,0.02])
+        f.checkCoherency()
+        #
+        mm=MEDFileUMesh()
+        mm.setMeshAtLevel(0,m)
+        mm.write(fname,2)
+        #
+        f1ts=MEDFileField1TS.New()
+        pfl=DataArrayInt(range(13)) ; pfl.setName("pfl")
+        f1ts.setFieldProfile(f,mm,0,pfl)
+        f1ts.write(fname,0)
+        #
+        self.assertEqual(f1ts.getPfls(),('pfl_NORM_TRI3_loc_0', 'pfl_NORM_TRI3_loc_1'))
+        self.assertEqual(f1ts.getPflsReallyUsed(),('pfl_NORM_TRI3_loc_0', 'pfl_NORM_TRI3_loc_1'))
+        da1=DataArrayInt([0,1,2,3,4,5,6,7,8]) ; da1.setName("pfl_NORM_TRI3_loc_0")
+        self.assertTrue(f1ts.getProfile("pfl_NORM_TRI3_loc_0").isEqual(da1))
+        da1=DataArrayInt([9,10]) ; da1.setName("pfl_NORM_TRI3_loc_1")
+        self.assertTrue(f1ts.getProfile("pfl_NORM_TRI3_loc_1").isEqual(da1))
+        self.assertEqual(f1ts.getLocs(),('Loc_fieldCellOnPflWithoutPfl_NORM_TRI3_0', 'Loc_fieldCellOnPflWithoutPfl_NORM_TRI3_1', 'Loc_fieldCellOnPflWithoutPfl_NORM_QUAD4_2'))
+        self.assertEqual(f1ts.getLocsReallyUsed(),('Loc_fieldCellOnPflWithoutPfl_NORM_TRI3_0', 'Loc_fieldCellOnPflWithoutPfl_NORM_TRI3_1', 'Loc_fieldCellOnPflWithoutPfl_NORM_QUAD4_2'))
+        #
+        dataRead=MEDFileData.New(fname)
+        mRead=dataRead.getMeshes()[0]
+        f1tsRead=dataRead.getFields()[0][0]
+        f1tsRead.getFieldOnMeshAtLevel(ON_GAUSS_PT,0,mRead)
+        f2=f1tsRead.getFieldOnMeshAtLevel(ON_GAUSS_PT,0,mRead)
+        self.assertTrue(f.isEqual(f2,1e-12,1e-12))
+        f2_bis=MEDLoader.ReadFieldGauss(fname,m.getName(),0,f.getName(),f.getTime()[1],f.getTime()[2])
+        f2_bis.checkCoherency()
+        self.assertTrue(f.isEqual(f2_bis,1e-12,1e-12))
+        #
+        MEDLoader.WriteField(fname2,f,True)
+        f2_ter=MEDLoader.ReadFieldGauss(fname2,m.getName(),0,f.getName(),f.getTime()[1],f.getTime()[2])
+        self.assertTrue(f.isEqual(f2_ter,1e-12,1e-12))
+        ## Use case 2 : Pfl on part tri3 with 2 disc and on part quad8 with 1 disc
+        f=MEDCouplingFieldDouble.New(ON_GAUSS_PT,ONE_TIME)
+        pfl=DataArrayInt([1,2,5,6,8,9,15,16,17,18]) ; pfl.setName("pfl2")
+        m2=m[pfl] ; m2.setName(m.getName())
+        f.setMesh(m2)
+        f.setTime(4.5,1,2)
+        da=DataArrayDouble(35) ; da.iota(3.)
+        f.setArray(da)
+        f.setName("fieldCellOnPflWithoutPfl2")
+        f.setGaussLocalizationOnCells([0,1,3],[0.,0.,1.,0.,1.,1.],[0.3,0.3,0.7,0.7],[0.8,0.2])
+        f.setGaussLocalizationOnCells([2,4,5],[0.,0.,1.,0.,1.,1.],[0.3,0.3,0.7,0.7,0.8,0.8],[0.8,0.07,0.13])
+        f.setGaussLocalizationOnCells([6,7,8,9],[0.,0.,1.,0.,1.,1.,0.,1.,0.5,0.,1.,0.5,0.5,1.,0.,0.5],[0.3,0.3,0.7,0.7,0.8,0.8,0.8,0.8,0.8,0.8],[0.8,0.07,0.1,0.01,0.02])
+        f.checkCoherency()
+        #
+        mm=MEDFileUMesh()
+        mm.setMeshAtLevel(0,m)
+        mm.write(fname,2)
+        f1ts=MEDFileField1TS.New()
+        f1ts.setFieldProfile(f,mm,0,pfl)
+        self.assertEqual(f1ts.getPfls(),('pfl2_NORM_TRI3_loc_0','pfl2_NORM_TRI3_loc_1','pfl2_NORM_QUAD8_loc_2'))
+        self.assertEqual(f1ts.getProfile("pfl2_NORM_TRI3_loc_0").getValues(),[1,2,6])
+        self.assertEqual(f1ts.getProfile("pfl2_NORM_TRI3_loc_1").getValues(),[5,8,9])
+        self.assertEqual(f1ts.getProfile("pfl2_NORM_QUAD8_loc_2").getValues(),[2,3,4,5])
+        f1ts.write(fname,0)
+        dataRead=MEDFileData.New(fname)
+        mRead=dataRead.getMeshes()[0]
+        f1tsRead=dataRead.getFields()[0][0]
+        f1tsRead.getFieldOnMeshAtLevel(ON_GAUSS_PT,0,mRead)
+        f3=f1tsRead.getFieldOnMeshAtLevel(ON_GAUSS_PT,0,mRead)
+        f3.renumberCells([0,1,3,2,4,5,6,7,8,9])
+        self.assertTrue(f.isEqual(f3,1e-12,1e-12))
+        f3_bis=MEDLoader.ReadFieldGauss(fname,m.getName(),0,f.getName(),f.getTime()[1],f.getTime()[2])
+        f3_bis.renumberCells([0,1,3,2,4,5,6,7,8,9])
+        self.assertTrue(f.isEqual(f3_bis,1e-12,1e-12))
+        #
+        MEDLoader.WriteField(fname2,f,True)
+        f3_ter=MEDLoader.ReadFieldGauss(fname2,m.getName(),0,f.getName(),f.getTime()[1],f.getTime()[2])
+        f3_ter.renumberCells([0,1,3,2,4,5,6,7,8,9])
+        self.assertTrue(f.isEqual(f3_ter,1e-12,1e-12))
+        ## Use case 3 : no pfl but creation of pfls due to gauss pts
+        f=MEDCouplingFieldDouble.New(ON_GAUSS_PT,ONE_TIME)
+        f.setMesh(m)
+        f.setTime(4.5,1,2)
+        da=DataArrayDouble(60) ; da.iota(3.)
+        f.setArray(da)
+        f.setName("fieldCellWithoutPfl")
+        f.setGaussLocalizationOnCells([0,1,2,3,4,5,6,7,8],[0.,0.,1.,0.,1.,1.],[0.3,0.3,0.7,0.7],[0.8,0.2])
+        f.setGaussLocalizationOnCells([9,10],[0.,0.,1.,0.,1.,1.],[0.3,0.3,0.7,0.7,0.8,0.8],[0.8,0.07,0.13])
+        f.setGaussLocalizationOnCells([11,12],[0.,0.,1.,0.,1.,1.,0.,1.],[0.3,0.3,0.7,0.7,0.8,0.8,0.8,0.8,0.8,0.8],[0.8,0.07,0.1,0.01,0.02])
+        f.setGaussLocalizationOnCells([13,14,15,17,18],[0.,0.,1.,0.,1.,1.,0.,1.,0.5,0.,1.,0.5,0.5,1.,0.,0.5],[0.3,0.3,0.7,0.7,0.8,0.8,0.8,0.8],[0.8,0.1,0.03,0.07])
+        f.setGaussLocalizationOnCells([16,19],[0.,0.,1.,0.,1.,1.,0.,1.,0.5,0.,1.,0.5,0.5,1.,0.,0.5],[0.3,0.3,0.7,0.7,0.8,0.8],[0.8,0.1,0.1])
+        f.checkCoherency()
+        mm=MEDFileUMesh()
+        mm.setMeshAtLevel(0,m) 
+        f1ts=MEDFileField1TS.New()
+        f1ts.setFieldNoProfileSBT(f)
+        self.assertEqual(f1ts.getPfls(),('Pfl_fieldCellWithoutPfl_NORM_TRI3_0','Pfl_fieldCellWithoutPfl_NORM_TRI3_1','Pfl_fieldCellWithoutPfl_NORM_QUAD8_3','Pfl_fieldCellWithoutPfl_NORM_QUAD8_4'))
+        self.assertEqual(f1ts.getProfile("Pfl_fieldCellWithoutPfl_NORM_TRI3_0").getValues(),[0,1,2,3,4,5,6,7,8])
+        self.assertEqual(f1ts.getProfile("Pfl_fieldCellWithoutPfl_NORM_TRI3_1").getValues(),[9,10])
+        self.assertEqual(f1ts.getProfile("Pfl_fieldCellWithoutPfl_NORM_QUAD8_3").getValues(),[0,1,2,4,5])
+        self.assertEqual(f1ts.getProfile("Pfl_fieldCellWithoutPfl_NORM_QUAD8_4").getValues(),[3,6])
+        mm.write(fname,2)
+        f1ts.write(fname,0)
+        #
+        dataRead=MEDFileData.New(fname)
+        mRead=dataRead.getMeshes()[0]
+        f1tsRead=dataRead.getFields()[0][0]
+        f3=f1tsRead.getFieldOnMeshAtLevel(ON_GAUSS_PT,0,mRead)
+        f3.renumberCells([0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,17,18,16,19])
+        self.assertTrue(f.isEqual(f3,1e-12,1e-12))
+        f3_bis=MEDLoader.ReadFieldGauss(fname,m.getName(),0,f.getName(),f.getTime()[1],f.getTime()[2])
+        f3_bis.renumberCells([0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,17,18,16,19])
+        self.assertTrue(f.isEqual(f3_bis,1e-12,1e-12))
+        #
+        MEDLoader.WriteField(fname2,f,True)
+        f3_ter=MEDLoader.ReadFieldGauss(fname2,m.getName(),0,f.getName(),f.getTime()[1],f.getTime()[2])
+        f3_ter.renumberCells([0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,17,18,16,19])
+        self.assertTrue(f.isEqual(f3_ter,1e-12,1e-12))
+        pass
     pass
 
 unittest.main()
index ad869500adb8db1b3f266f2a48c17cb6f3f0ed60..423cc0fb7f7473bcb30b12369f24897ac97d2500 100644 (file)
@@ -26,6 +26,7 @@ INCLUDE_DIRECTORIES(
   ${CMAKE_CURRENT_SOURCE_DIR}/../INTERP_KERNEL
   ${CMAKE_CURRENT_SOURCE_DIR}/../INTERP_KERNEL/Bases
   ${CMAKE_CURRENT_SOURCE_DIR}/../INTERP_KERNEL/GaussPoints
+  ${CMAKE_CURRENT_SOURCE_DIR}/../INTERP_KERNEL/Geometric2D
   )
 
 SET(MEDMEMCppTest_SOURCES
index 165ca2d82e844cedcaad6c8f36d56464dd5a9ee7..8579b38e5ece271dadbc24c66e2bd984cecd7213 100644 (file)
@@ -50,7 +50,7 @@ SET(COMMON_LIBS
   ${SalomeGenericObj}
   medcoupling
   interpkernel
-  ${MED3_LIBS}
+  ${MED3_LIBS_C_ONLY}
   ${HDF5_LIBS}
   ${OMNIORB_LIBS}
   ${PLATFORM_LIBS}
index 01758265ff4f02c4dc0f45426f6bb3c88f2a77bc..9422c56f072fe6556aefaa734bcdd9a13f356670 100644 (file)
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<XMI verified="false" xmi.version="1.2" timestamp="2012-09-06T10:36:47" xmlns:UML="http://schema.omg.org/spec/UML/1.3">
+<XMI verified="false" xmi.version="1.2" timestamp="2012-11-06T17:59:15" xmlns:UML="http://schema.omg.org/spec/UML/1.3">
  <XMI.header>
   <XMI.documentation>
    <XMI.exporter>umbrello uml modeller http://uml.sf.net</XMI.exporter>
            <startpoint startx="323" starty="220"/>
            <endpoint endx="323" endy="168"/>
           </linepath>
-          <floatingtext linecolor="none" usesdiagramfillcolor="1" linewidth="none" usesdiagramusefillcolor="1" x="325" showstereotype="1" y="199" text="n" font="Ubuntu,10,-1,5,50,0,0,0,0,0" pretext="" role="701" width="16" isinstance="0" posttext="" usefillcolor="1" fillcolor="none" xmi.id="fLhlJM6afAET" height="19"/>
-          <floatingtext linecolor="none" usesdiagramfillcolor="1" linewidth="none" usesdiagramusefillcolor="1" x="325" showstereotype="1" y="170" text="1" font="Ubuntu,10,-1,5,50,0,0,0,0,0" pretext="" role="702" width="16" isinstance="0" posttext="" usefillcolor="1" fillcolor="none" xmi.id="TQYswJeO30Ac" height="19"/>
-          <floatingtext linecolor="none" usesdiagramfillcolor="1" linewidth="none" usesdiagramusefillcolor="1" x="260" showstereotype="1" y="170" text="sourceid" font="Ubuntu,10,-1,5,50,0,0,0,0,0" pretext="+" role="710" width="67" isinstance="0" posttext="" usefillcolor="1" fillcolor="none" xmi.id="RkMoYLWfIJyZ" height="19"/>
+          <floatingtext linecolor="none" usesdiagramfillcolor="1" linewidth="none" usesdiagramusefillcolor="1" x="325" showstereotype="1" y="199" text="n" font="Ubuntu,10,-1,5,50,0,0,0,0,0" pretext="" role="701" width="16" isinstance="0" posttext="" usefillcolor="1" fillcolor="none" xmi.id="PUeF5c2aIZmS" height="19"/>
+          <floatingtext linecolor="none" usesdiagramfillcolor="1" linewidth="none" usesdiagramusefillcolor="1" x="325" showstereotype="1" y="170" text="1" font="Ubuntu,10,-1,5,50,0,0,0,0,0" pretext="" role="702" width="16" isinstance="0" posttext="" usefillcolor="1" fillcolor="none" xmi.id="UmnXhmcg0z5Y" height="19"/>
+          <floatingtext linecolor="none" usesdiagramfillcolor="1" linewidth="none" usesdiagramusefillcolor="1" x="260" showstereotype="1" y="170" text="sourceid" font="Ubuntu,10,-1,5,50,0,0,0,0,0" pretext="+" role="710" width="67" isinstance="0" posttext="" usefillcolor="1" fillcolor="none" xmi.id="zENRazZ7qpS9" height="19"/>
          </assocwidget>
          <assocwidget indexa="1" indexb="1" usesdiagramusefillcolor="1" widgetaid="Z3sQfH0YJ5g6" usesdiagramfillcolor="1" fillcolor="none" linecolor="none" totalcounta="2" xmi.id="ld0pX3I6kldh" widgetbid="mpuQQtzqbsfV" totalcountb="2" type="512" usefillcolor="1" linewidth="none">
           <linepath>
            <startpoint startx="318" starty="371"/>
            <endpoint endx="318" endy="287"/>
           </linepath>
-          <floatingtext linecolor="none" usesdiagramfillcolor="1" linewidth="none" usesdiagramusefillcolor="1" x="320" showstereotype="1" y="350" text="n" font="Ubuntu,10,-1,5,50,0,0,0,0,0" pretext="" role="701" width="16" isinstance="0" posttext="" usefillcolor="1" fillcolor="none" xmi.id="BQQrafI23qu0" height="19"/>
-          <floatingtext linecolor="none" usesdiagramfillcolor="1" linewidth="none" usesdiagramusefillcolor="1" x="320" showstereotype="1" y="289" text="1" font="Ubuntu,10,-1,5,50,0,0,0,0,0" pretext="" role="702" width="16" isinstance="0" posttext="" usefillcolor="1" fillcolor="none" xmi.id="AWMBUWnoA3P5" height="19"/>
-          <floatingtext linecolor="none" usesdiagramfillcolor="1" linewidth="none" usesdiagramusefillcolor="1" x="264" showstereotype="1" y="289" text="meshId" font="Ubuntu,10,-1,5,50,0,0,0,0,0" pretext="+" role="710" width="59" isinstance="0" posttext="" usefillcolor="1" fillcolor="none" xmi.id="KeHcxEAaZpMs" height="19"/>
+          <floatingtext linecolor="none" usesdiagramfillcolor="1" linewidth="none" usesdiagramusefillcolor="1" x="320" showstereotype="1" y="350" text="n" font="Ubuntu,10,-1,5,50,0,0,0,0,0" pretext="" role="701" width="16" isinstance="0" posttext="" usefillcolor="1" fillcolor="none" xmi.id="84EPeyr6icdP" height="19"/>
+          <floatingtext linecolor="none" usesdiagramfillcolor="1" linewidth="none" usesdiagramusefillcolor="1" x="320" showstereotype="1" y="289" text="1" font="Ubuntu,10,-1,5,50,0,0,0,0,0" pretext="" role="702" width="16" isinstance="0" posttext="" usefillcolor="1" fillcolor="none" xmi.id="OF6MD9u7mXqC" height="19"/>
+          <floatingtext linecolor="none" usesdiagramfillcolor="1" linewidth="none" usesdiagramusefillcolor="1" x="264" showstereotype="1" y="289" text="meshId" font="Ubuntu,10,-1,5,50,0,0,0,0,0" pretext="+" role="710" width="59" isinstance="0" posttext="" usefillcolor="1" fillcolor="none" xmi.id="wdfkS5upaY4d" height="19"/>
          </assocwidget>
          <assocwidget indexa="1" indexb="1" usesdiagramusefillcolor="1" widgetaid="Z3sQfH0YJ5g6" usesdiagramfillcolor="1" fillcolor="none" linecolor="none" totalcounta="2" xmi.id="oCVhQ0u5qFB3" widgetbid="tFFeytJRMARL" totalcountb="2" type="512" usefillcolor="1" linewidth="none">
           <linepath>
            <startpoint startx="418" starty="371"/>
            <endpoint endx="574" endy="300"/>
           </linepath>
-          <floatingtext linecolor="none" usesdiagramfillcolor="1" linewidth="none" usesdiagramusefillcolor="1" x="408" showstereotype="1" y="349" text="n" font="Ubuntu,10,-1,5,50,0,0,0,0,0" pretext="" role="701" width="16" isinstance="0" posttext="" usefillcolor="1" fillcolor="none" xmi.id="kd1mStmcP6lr" height="19"/>
-          <floatingtext linecolor="none" usesdiagramfillcolor="1" linewidth="none" usesdiagramusefillcolor="1" x="570" showstereotype="1" y="303" text="0" font="Ubuntu,10,-1,5,50,0,0,0,0,0" pretext="" role="702" width="16" isinstance="0" posttext="" usefillcolor="1" fillcolor="none" xmi.id="aZgic3nraRfw" height="19"/>
-          <floatingtext linecolor="none" usesdiagramfillcolor="1" linewidth="none" usesdiagramusefillcolor="1" x="487" showstereotype="1" y="282" text="fieldseriesId" font="Ubuntu,10,-1,5,50,0,0,0,0,0" pretext="+" role="710" width="90" isinstance="0" posttext="" usefillcolor="1" fillcolor="none" xmi.id="HZgqM0hYQ5Nz" height="19"/>
+          <floatingtext linecolor="none" usesdiagramfillcolor="1" linewidth="none" usesdiagramusefillcolor="1" x="408" showstereotype="1" y="349" text="n" font="Ubuntu,10,-1,5,50,0,0,0,0,0" pretext="" role="701" width="16" isinstance="0" posttext="" usefillcolor="1" fillcolor="none" xmi.id="wdocFP2bd6xq" height="19"/>
+          <floatingtext linecolor="none" usesdiagramfillcolor="1" linewidth="none" usesdiagramusefillcolor="1" x="570" showstereotype="1" y="303" text="0" font="Ubuntu,10,-1,5,50,0,0,0,0,0" pretext="" role="702" width="16" isinstance="0" posttext="" usefillcolor="1" fillcolor="none" xmi.id="Fpv0KlCvTC4k" height="19"/>
+          <floatingtext linecolor="none" usesdiagramfillcolor="1" linewidth="none" usesdiagramusefillcolor="1" x="487" showstereotype="1" y="282" text="fieldseriesId" font="Ubuntu,10,-1,5,50,0,0,0,0,0" pretext="+" role="710" width="90" isinstance="0" posttext="" usefillcolor="1" fillcolor="none" xmi.id="bkz9G4mP6yoi" height="19"/>
          </assocwidget>
          <assocwidget indexa="1" indexb="1" usesdiagramusefillcolor="1" widgetaid="tFFeytJRMARL" usesdiagramfillcolor="1" fillcolor="none" linecolor="none" totalcounta="2" xmi.id="ONJtNJsd01tV" widgetbid="mpuQQtzqbsfV" totalcountb="2" type="512" usefillcolor="1" linewidth="none">
           <linepath>
            <startpoint startx="574" starty="246"/>
            <endpoint endx="428" endy="246"/>
           </linepath>
-          <floatingtext linecolor="none" usesdiagramfillcolor="1" linewidth="none" usesdiagramusefillcolor="1" x="556" showstereotype="1" y="225" text="n" font="Ubuntu,10,-1,5,50,0,0,0,0,0" pretext="" role="701" width="16" isinstance="0" posttext="" usefillcolor="1" fillcolor="none" xmi.id="RKSqQnp8Rout" height="19"/>
-          <floatingtext linecolor="none" usesdiagramfillcolor="1" linewidth="none" usesdiagramusefillcolor="1" x="430" showstereotype="1" y="225" text="1" font="Ubuntu,10,-1,5,50,0,0,0,0,0" pretext="" role="702" width="16" isinstance="0" posttext="" usefillcolor="1" fillcolor="none" xmi.id="heT4kEtIlZ0L" height="19"/>
+          <floatingtext linecolor="none" usesdiagramfillcolor="1" linewidth="none" usesdiagramusefillcolor="1" x="556" showstereotype="1" y="225" text="n" font="Ubuntu,10,-1,5,50,0,0,0,0,0" pretext="" role="701" width="16" isinstance="0" posttext="" usefillcolor="1" fillcolor="none" xmi.id="Ep7Inv1iWpKl" height="19"/>
+          <floatingtext linecolor="none" usesdiagramfillcolor="1" linewidth="none" usesdiagramusefillcolor="1" x="430" showstereotype="1" y="225" text="1" font="Ubuntu,10,-1,5,50,0,0,0,0,0" pretext="" role="702" width="16" isinstance="0" posttext="" usefillcolor="1" fillcolor="none" xmi.id="FKMsQHge4ZeM" height="19"/>
          </assocwidget>
         </associations>
        </diagram>
-       <diagram showopsig="1" linecolor="#ff0000" snapx="10" showattribassocs="1" snapy="10" linewidth="0" showattsig="1" isopen="1" showpackage="1" showpubliconly="1" showstereotype="1" name="MEDOP_componentmodel" font="Ubuntu,10,-1,5,50,0,0,0,0,0" canvasheight="644" canvaswidth="1201" localid="-1" snapcsgrid="0" showgrid="0" showops="1" griddotcolor="#808080" backgroundcolor="#ffffff" usefillcolor="1" fillcolor="#ffffc0" zoom="100" xmi.id="e3MA5ySQiAqG" documentation="" showscope="1" snapgrid="0" showatts="1" type="1">
+       <diagram showopsig="1" linecolor="#ff0000" snapx="10" showattribassocs="1" snapy="10" linewidth="0" showattsig="1" isopen="1" showpackage="1" showpubliconly="1" showstereotype="1" name="MEDOP_componentmodel" font="Ubuntu,10,-1,5,50,0,0,0,0,0" canvasheight="436" canvaswidth="596" localid="-1" snapcsgrid="0" showgrid="0" showops="1" griddotcolor="#808080" backgroundcolor="#ffffff" usefillcolor="1" fillcolor="#ffffc0" zoom="100" xmi.id="e3MA5ySQiAqG" documentation="" showscope="1" snapgrid="0" showatts="1" type="1">
         <widgets>
          <classwidget linecolor="#ff0000" usesdiagramfillcolor="0" linewidth="none" showoperations="1" usesdiagramusefillcolor="0" showpubliconly="1" showpackage="1" x="330" showattsigs="601" showstereotype="1" y="184" showattributes="1" font="Ubuntu,10,-1,5,75,0,0,0,0,0" width="227" isinstance="0" usefillcolor="1" fillcolor="#ffffc0" xmi.id="kG3S8XATRqib" showscope="1" height="52" showopsigs="601"/>
          <interfacewidget linecolor="none" usesdiagramfillcolor="1" linewidth="none" showoperations="1" usesdiagramusefillcolor="1" showpubliconly="1" showpackage="1" x="342" showstereotype="1" y="87" font="Ubuntu,10,-1,5,75,1,0,0,0,0" drawascircle="0" width="184" isinstance="0" usefillcolor="1" fillcolor="none" xmi.id="BYw7PBW7PaZW" showscope="1" height="44" showopsigs="601"/>
            <endpoint endx="432" endy="131"/>
           </linepath>
          </assocwidget>
-         <assocwidget indexa="1" indexb="1" usesdiagramusefillcolor="255" widgetaid="kG3S8XATRqib" usesdiagramfillcolor="255" fillcolor="none" linecolor="none" totalcounta="3" xmi.id="fUBIKo7DA4LI" widgetbid="nSHVdoPkDYFK" totalcountb="2" type="512" usefillcolor="255" linewidth="none">
+         <assocwidget indexa="1" indexb="1" usesdiagramusefillcolor="1" widgetaid="kG3S8XATRqib" usesdiagramfillcolor="1" fillcolor="none" linecolor="none" totalcounta="3" xmi.id="fUBIKo7DA4LI" widgetbid="nSHVdoPkDYFK" totalcountb="2" type="512" usefillcolor="1" linewidth="none">
           <linepath>
            <startpoint startx="362" starty="236"/>
            <endpoint endx="362" endy="300"/>
           </linepath>
-          <floatingtext linecolor="none" usesdiagramfillcolor="1" linewidth="none" usesdiagramusefillcolor="1" x="362" showstereotype="1" y="268" text="instancie" font="Ubuntu,10,-1,5,50,0,0,0,0,0" pretext="" role="703" width="62" isinstance="0" posttext="" usefillcolor="1" fillcolor="none" xmi.id="We8Eh3gTpzBZ" height="19"/>
-          <floatingtext linecolor="none" usesdiagramfillcolor="1" linewidth="none" usesdiagramusefillcolor="1" x="364" showstereotype="1" y="238" text="1" font="Ubuntu,10,-1,5,50,0,0,0,0,0" pretext="" role="701" width="16" isinstance="0" posttext="" usefillcolor="1" fillcolor="none" xmi.id="RukaNOvu336i" height="19"/>
-          <floatingtext linecolor="none" usesdiagramfillcolor="1" linewidth="none" usesdiagramusefillcolor="1" x="364" showstereotype="1" y="279" text="1" font="Ubuntu,10,-1,5,50,0,0,0,0,0" pretext="" role="702" width="16" isinstance="0" posttext="" usefillcolor="1" fillcolor="none" xmi.id="GwYUBCNb75BU" height="19"/>
+          <floatingtext linecolor="none" usesdiagramfillcolor="1" linewidth="none" usesdiagramusefillcolor="1" x="362" showstereotype="1" y="268" text="instancie" font="Ubuntu,10,-1,5,50,0,0,0,0,0" pretext="" role="703" width="62" isinstance="0" posttext="" usefillcolor="1" fillcolor="none" xmi.id="yMxCnWyqPM7m" height="19"/>
+          <floatingtext linecolor="none" usesdiagramfillcolor="1" linewidth="none" usesdiagramusefillcolor="1" x="364" showstereotype="1" y="238" text="1" font="Ubuntu,10,-1,5,50,0,0,0,0,0" pretext="" role="701" width="16" isinstance="0" posttext="" usefillcolor="1" fillcolor="none" xmi.id="zDAFam9Z1k5N" height="19"/>
+          <floatingtext linecolor="none" usesdiagramfillcolor="1" linewidth="none" usesdiagramusefillcolor="1" x="364" showstereotype="1" y="279" text="1" font="Ubuntu,10,-1,5,50,0,0,0,0,0" pretext="" role="702" width="16" isinstance="0" posttext="" usefillcolor="1" fillcolor="none" xmi.id="HoH1ErvACtMz" height="19"/>
          </assocwidget>
          <assocwidget indexa="2" indexb="1" usesdiagramusefillcolor="0" widgetaid="kG3S8XATRqib" usesdiagramfillcolor="0" fillcolor="#000000" linecolor="none" totalcounta="3" xmi.id="DweL0xdEpAae" widgetbid="UsXTM49RP2EE" totalcountb="2" type="512" usefillcolor="0" linewidth="none">
           <linepath>
            <startpoint startx="508" starty="236"/>
            <endpoint endx="508" endy="300"/>
           </linepath>
-          <floatingtext linecolor="none" usesdiagramfillcolor="1" linewidth="none" usesdiagramusefillcolor="1" x="508" showstereotype="1" y="269" text="instancie" font="Ubuntu,10,-1,5,50,0,0,0,0,0" pretext="" role="703" width="62" isinstance="0" posttext="" usefillcolor="1" fillcolor="none" xmi.id="s8Nl0cfW6qjS" height="19"/>
-          <floatingtext linecolor="none" usesdiagramfillcolor="1" linewidth="none" usesdiagramusefillcolor="1" x="510" showstereotype="1" y="238" text="1" font="Ubuntu,10,-1,5,50,0,0,0,0,0" pretext="" role="701" width="16" isinstance="0" posttext="" usefillcolor="1" fillcolor="none" xmi.id="wJt1HUa9cvsa" height="19"/>
-          <floatingtext linecolor="none" usesdiagramfillcolor="1" linewidth="none" usesdiagramusefillcolor="1" x="510" showstereotype="1" y="279" text="1" font="Ubuntu,10,-1,5,50,0,0,0,0,0" pretext="" role="702" width="16" isinstance="0" posttext="" usefillcolor="1" fillcolor="none" xmi.id="XyVvibXetPfA" height="19"/>
+          <floatingtext linecolor="none" usesdiagramfillcolor="1" linewidth="none" usesdiagramusefillcolor="1" x="508" showstereotype="1" y="269" text="instancie" font="Ubuntu,10,-1,5,50,0,0,0,0,0" pretext="" role="703" width="62" isinstance="0" posttext="" usefillcolor="1" fillcolor="none" xmi.id="NJokfvWe6hrg" height="19"/>
+          <floatingtext linecolor="none" usesdiagramfillcolor="1" linewidth="none" usesdiagramusefillcolor="1" x="510" showstereotype="1" y="238" text="1" font="Ubuntu,10,-1,5,50,0,0,0,0,0" pretext="" role="701" width="16" isinstance="0" posttext="" usefillcolor="1" fillcolor="none" xmi.id="RyGQiJny75zJ" height="19"/>
+          <floatingtext linecolor="none" usesdiagramfillcolor="1" linewidth="none" usesdiagramusefillcolor="1" x="510" showstereotype="1" y="279" text="1" font="Ubuntu,10,-1,5,50,0,0,0,0,0" pretext="" role="702" width="16" isinstance="0" posttext="" usefillcolor="1" fillcolor="none" xmi.id="usT4lq477qrk" height="19"/>
          </assocwidget>
          <assocwidget indexa="1" indexb="1" usesdiagramusefillcolor="0" widgetaid="nSHVdoPkDYFK" usesdiagramfillcolor="0" fillcolor="#000000" linecolor="none" totalcounta="2" xmi.id="WqUPF7X6LpZS" widgetbid="tDJT9A2gh9I3" totalcountb="3" type="511" usefillcolor="0" linewidth="none">
           <linepath>
            <endpoint endx="398" endy="388"/>
           </linepath>
          </assocwidget>
-         <assocwidget indexa="1" indexb="2" usesdiagramusefillcolor="0" widgetaid="UsXTM49RP2EE" usesdiagramfillcolor="0" fillcolor="#000000" linecolor="none" totalcounta="2" xmi.id="AwSTl1vib2NJ" widgetbid="tDJT9A2gh9I3" totalcountb="3" type="511" usefillcolor="58" linewidth="none">
+         <assocwidget indexa="1" indexb="2" usesdiagramusefillcolor="0" widgetaid="UsXTM49RP2EE" usesdiagramfillcolor="0" fillcolor="#000000" linecolor="none" totalcounta="2" xmi.id="AwSTl1vib2NJ" widgetbid="tDJT9A2gh9I3" totalcountb="3" type="511" usefillcolor="1" linewidth="none">
           <linepath>
            <startpoint startx="510" starty="329"/>
            <endpoint endx="510" endy="388"/>
     <listitem open="1" type="821" id="Component View"/>
     <listitem open="1" type="827" id="Deployment View"/>
     <listitem open="1" type="801" id="Logical View">
-     <listitem open="1" type="818" id="NBqMfPwp0LlT">
+     <listitem open="0" type="818" id="NBqMfPwp0LlT">
       <listitem open="1" type="813" id="UsXTM49RP2EE"/>
       <listitem open="1" type="813" id="nSHVdoPkDYFK"/>
       <listitem open="0" type="813" id="KO9M6BTsmDX3">
      </listitem>
      <listitem open="0" type="807" id="e3MA5ySQiAqG" label="MEDOP_componentmodel"/>
      <listitem open="0" type="807" id="yesp3EjZ9T3u" label="MEDOP_datamodel"/>
-     <listitem open="1" type="818" id="rEjTH3dMz3kh">
+     <listitem open="0" type="818" id="rEjTH3dMz3kh">
       <listitem open="1" type="817" id="BYw7PBW7PaZW"/>
       <listitem open="1" type="817" id="tDJT9A2gh9I3"/>
      </listitem>
index 54da68859d47816fc53e190dd9e52a4fe8427e4d..cd0b113f974d4efe5bee0a466f5216f9716e3794 100644 (file)
 IF(SPHINX_STATUS)
   SET(srcdir ${CMAKE_CURRENT_SOURCE_DIR})
   CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/conf.py.in ${CMAKE_CURRENT_BINARY_DIR}/conf.py @ONLY)
-  #FILE(GLOB MEDOP_DOC_RST "${CMAKE_CURRENT_SOURCE_DIR}/*.rst")
-  
-  #FOREACH(SRCFNAME ${MEDOP_DOC_RST})
-  #  GET_FILENAME_COMPONENT(FNAME ${SRCFNAME} NAME)
-  #  CONFIGURE_FILE(${SRCFNAME} ${CMAKE_CURRENT_BINARY_DIR}/${FNAME} COPY_ONLY)
-  #ENDFOREACH(FNAME ${MEDOP_DOC_RST})
-  
-  #FILE(MAKE_DIRECTORY _static)
-  #CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/_static/xmed.css ${CMAKE_CURRENT_BINARY_DIR}/_static/xmed.css COPY_ONLY)
-
-  #FILE(GLOB MEDOP_DOC_PNG_RST "${CMAKE_CURRENT_SOURCE_DIR}/images/*.png")
-  #FOREACH(SRCFNAME ${MEDOP_DOC_PNG_RST})
-  #  GET_FILENAME_COMPONENT(FNAME ${SRCFNAME} NAME)
-  #  CONFIGURE_FILE(${SRCFNAME} ${CMAKE_CURRENT_BINARY_DIR}/images/${FNAME} COPY_ONLY)
-  #ENDFOREACH(FNAME ${MEDOP_DOC_RST})
 
   INSTALL(CODE "EXECUTE_PROCESS(COMMAND ${SPHINX_EXECUTABLE_TO_FIND} -c ${CMAKE_CURRENT_BINARY_DIR} -b html -d doctrees -D latex_paper_size=a4 ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR}/html)")
 
index a28b03d444443c52e2d7ede41fac35388df2688e..2482d90302f49c1d0ee73ec0ad537096c9d94ff2 100644 (file)
@@ -71,27 +71,23 @@ html:
 
 RSTFILES= \
        index.rst               \
-       xmed-specifications.rst \
-       xmed-develguide.rst     \
-       xmed-userguide.rst
+       medop-specifications.rst \
+       medop-develguide.rst     \
+       medop-userguide.rst
 
 # Files on the development of the prototype (version 2010)
 RSTFILES+=\
-       xmed-prototype-overview.rst     \
-       xmed-prototype-develguide.rst   \
-       xmed-prototype-medmem.rst
+       medop-prototype-overview.rst     \
+       medop-prototype-develguide.rst   \
+       medop-prototype-medmem.rst
 
 # Files containing definitions and references
 RSTFILES+=\
-       xmed-definitions.rst \
-       xmed-references.rst  \
-       xmed-workingnotes-2010.rst \
-       xmed-workingnotes-2011.rst \
-       xmed-workingnotes-2012.rst
-
-# Files on annexe topics
-RSTFILES+=\
-       salomedoc.rst
+       medop-definitions.rst \
+       medop-references.rst  \
+       medop-workingnotes-2010.rst \
+       medop-workingnotes-2011.rst \
+       medop-workingnotes-2012.rst
 
 EXTRA_DIST+= $(RSTFILES)
 
diff --git a/src/MEDOP/doc/sphinx/_static/medop.css b/src/MEDOP/doc/sphinx/_static/medop.css
new file mode 100644 (file)
index 0000000..150d019
--- /dev/null
@@ -0,0 +1,115 @@
+@import url("default.css");
+
+body {
+  font-family: {{ 'Liberation', sans-serif }};
+  font-size: 82%;
+  color: #000;
+  background-color: #fff;
+  margin-left: 28px;
+}
+
+ul {
+  margin: 0 0 0 0;
+}
+
+div.related {
+  background-color: #444;
+}
+
+a,
+div.sphinxsidebar h3 a,
+div.sphinxsidebar a,
+div.footer a {
+  color: #444;
+}
+
+div.sphinxsidebar h3,
+div.sphinxsidebar h4 {
+  color: #000;
+}
+
+div.sphinxsidebar ul {
+  font-size: 94%;
+  color: #000;
+}
+
+div.sphinxsidebar input {
+  border-color: #444;
+}
+
+div.document {
+  background-color: #f5f8e4;
+}
+
+div.body h1,
+div.body h2,
+div.body h3,
+div.body h4,
+div.body h5,
+div.body h6 {
+  color: #000;
+  background-color: transparent;
+  border-bottom: 1px solid #444;
+}
+
+div.footer {
+  color: #000;
+}
+
+li.toctree-l2 {
+  font-size: 100%;
+}
+
+li.toctree-l3 {
+  font-size: 100%;
+}
+
+div.sphinxsidebarwrapper ul {
+  list-style-type: disc;
+  margin-top: 1px;
+  padding-left: 6px;
+}
+
+div.sphinxsidebarwrapper h3 {
+  font-size: 100%;
+  font-weight: bold;
+}
+
+div.body h1 {
+  font-size: 200%;
+}
+div.body h2 {
+  font-size: 160%;
+}
+div.body h3, div.body h4 {
+  font-size: 125%;
+}
+
+div.body p.topic-title {
+  margin-bottom: 2px;
+  font-size: 100%;
+}
+
+div.sphinxsidebar p {
+  color: #444;
+}
+
+#introduction p > em {
+  text-align: right;
+  float: right;
+}
+
+#introduction p {
+  font-size: 90%;
+  margin-bottom: 3px;
+}
+
+#introduction #id2.docutils.footnote {
+  font-size: 70%;
+  margin-top: 25px;
+}
+
+#introduction table.docutils.footnote {
+  font-size: 70%;
+  margin-top: 5px;
+}
diff --git a/src/MEDOP/doc/sphinx/_static/xmed.css b/src/MEDOP/doc/sphinx/_static/xmed.css
deleted file mode 100644 (file)
index 150d019..0000000
+++ /dev/null
@@ -1,115 +0,0 @@
-@import url("default.css");
-
-body {
-  font-family: {{ 'Liberation', sans-serif }};
-  font-size: 82%;
-  color: #000;
-  background-color: #fff;
-  margin-left: 28px;
-}
-
-ul {
-  margin: 0 0 0 0;
-}
-
-div.related {
-  background-color: #444;
-}
-
-a,
-div.sphinxsidebar h3 a,
-div.sphinxsidebar a,
-div.footer a {
-  color: #444;
-}
-
-div.sphinxsidebar h3,
-div.sphinxsidebar h4 {
-  color: #000;
-}
-
-div.sphinxsidebar ul {
-  font-size: 94%;
-  color: #000;
-}
-
-div.sphinxsidebar input {
-  border-color: #444;
-}
-
-div.document {
-  background-color: #f5f8e4;
-}
-
-div.body h1,
-div.body h2,
-div.body h3,
-div.body h4,
-div.body h5,
-div.body h6 {
-  color: #000;
-  background-color: transparent;
-  border-bottom: 1px solid #444;
-}
-
-div.footer {
-  color: #000;
-}
-
-li.toctree-l2 {
-  font-size: 100%;
-}
-
-li.toctree-l3 {
-  font-size: 100%;
-}
-
-div.sphinxsidebarwrapper ul {
-  list-style-type: disc;
-  margin-top: 1px;
-  padding-left: 6px;
-}
-
-div.sphinxsidebarwrapper h3 {
-  font-size: 100%;
-  font-weight: bold;
-}
-
-div.body h1 {
-  font-size: 200%;
-}
-div.body h2 {
-  font-size: 160%;
-}
-div.body h3, div.body h4 {
-  font-size: 125%;
-}
-
-div.body p.topic-title {
-  margin-bottom: 2px;
-  font-size: 100%;
-}
-
-div.sphinxsidebar p {
-  color: #444;
-}
-
-#introduction p > em {
-  text-align: right;
-  float: right;
-}
-
-#introduction p {
-  font-size: 90%;
-  margin-bottom: 3px;
-}
-
-#introduction #id2.docutils.footnote {
-  font-size: 70%;
-  margin-top: 25px;
-}
-
-#introduction table.docutils.footnote {
-  font-size: 70%;
-  margin-top: 5px;
-}
index 1127d1ba285616d53a67b3d535c577edd15f7259..8259ef9166f462d786cc010ee0953f9de0c5961a 100644 (file)
@@ -127,7 +127,7 @@ html_theme_options = {
 # The stylecheet file will be searched within the static path, while
 # the layout.html file will be searched within the template path
 # (Note that this parameter can't be used together with html_theme. Exclusive)
-html_style = 'xmed.css'
+html_style = 'medop.css'
 
 # Add any paths that contain custom static files (such as style sheets) here,
 # relative to this directory. They are copied after the builtin static files,
@@ -170,7 +170,7 @@ html_copy_source = True
 #html_file_suffix = ''
 
 # Output file base name for HTML help builder.
-htmlhelp_basename = 'xmeddoc'
+htmlhelp_basename = 'medopdoc'
 
 
 # Options for LaTeX output
@@ -185,10 +185,10 @@ latex_font_size = '10pt'
 # Grouping the document tree into LaTeX files. List of tuples
 # (source start file, target name, title, author, document class [howto/manual]).
 latex_documents = [
-  ('index', 'xmed-alldoc.tex', 'Documentation du module XMED', 'G. Boulant', 'manual'),
-  ('xmed-specifications', 'xmed-specifications.tex', 'Module XMED - Specifications', 'G. Boulant', 'manual'),
-  ('xmed-develguide', 'xmed-develguide.tex', 'Module XMED - Guide de developpement', 'G. Boulant', 'manual'),
-  ('xmed-userguide', 'xmed-userguide.tex', 'Module XMED - Guide d\'utilisation', 'G. Boulant', 'manual')
+  ('index', 'medop-alldoc.tex', 'Documentation du module MED', 'G. Boulant', 'manual'),
+  ('medop-specifications', 'medop-specifications.tex', 'Module MED - Specifications', 'G. Boulant', 'manual'),
+  ('medop-develguide', 'medop-develguide.tex', 'Module MED - Guide de developpement', 'G. Boulant', 'manual'),
+  ('medop-userguide', 'medop-userguide.tex', 'Module MED - Guide d\'utilisation', 'G. Boulant', 'manual')
 ]
 
 # The name of an image file (relative to this directory) to place at the top of
index 90fdc6b46f4400eaefd47b450c16b9218fea35d4..1989de7880f03d634a705a6f78e13efbd07266fe 100644 (file)
@@ -1,12 +1,17 @@
 
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
- Documentation du module XMED
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+ Documentation du module MED
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
-Le module SALOME nommé XMED (pour eXtension MED) est l'espace de
-développement des fonctions de manipulation de champs dans SALOME. Le
-contenu de ce module est amené à intégrer le module MED pour former la
-future version en préparation pour la version SALOME 7 de 2012.
+Le module SALOME MED (pour Modèle d'Echange de Données) fournit la
+bibliothèque MEDCoupling (bibliothèque C++ dédiée à la manipulation de
+maillages et de champs conformes au modèle MED), ainsi qu'une
+interface graphique pour la réalisation des opérations de manipulation
+les plus usuelles.
+
+.. warning:: La partie interface graphique du module MED (composant
+            logiciel dénommé MEDOP) doit être considérée comme un
+            prototype pour la version SALOME6.
 
 Documentation principale
 ========================
@@ -14,9 +19,9 @@ Documentation principale
 .. toctree::
    :maxdepth: 1
 
-   xmed-specifications.rst
-   xmed-develguide.rst
-   xmed-userguide.rst
+   medop-specifications.rst
+   medop-develguide.rst
+   medop-userguide.rst
 
 Documentation du prototype 2010
 ===============================
@@ -27,9 +32,9 @@ analyses de conception (maquette 2010 sur base MEDMEM)
 .. toctree::
    :maxdepth: 1
 
-   xmed-prototype-overview.rst
-   xmed-prototype-develguide.rst
-   xmed-prototype-medmem.rst
+   medop-prototype-overview.rst
+   medop-prototype-develguide.rst
+   medop-prototype-medmem.rst
 
 Documentation annexe
 ====================
@@ -37,8 +42,7 @@ Documentation annexe
 .. toctree::
    :maxdepth: 1
 
-   xmed-references.rst
-   xmed-workingnotes-2010.rst
-   xmed-workingnotes-2011.rst
-   xmed-workingnotes-2012.rst
-   salomedoc.rst
+   medop-references.rst
+   medop-workingnotes-2010.rst
+   medop-workingnotes-2011.rst
+   medop-workingnotes-2012.rst
diff --git a/src/MEDOP/doc/sphinx/medop-definitions.rst b/src/MEDOP/doc/sphinx/medop-definitions.rst
new file mode 100644 (file)
index 0000000..cfd0bc1
--- /dev/null
@@ -0,0 +1,88 @@
+.. AVERTISSEMENT:
+.. Ce fichier contient les définitions globales à la documentation. Il
+.. peut être inclu au moyen de la directive rst "include" pour
+.. disposer des définitions dans le fichier qui fait l'inclusion.
+.. Pour éviter de polluer les textes dans lequel ce fichier est inclu,
+.. il est interdit de faire afficher du texte par ce document de
+.. définition.
+
+.. REFERENCES DOCUMENTAIRES:
+.. (les documents sont fournis dans le répertoire _static/documents)
+
+.. You can refer to this reference using the keyword: |REF_EDF_VCA_H-I2C-2009-03595-FR|_
+.. |REF_EDF_VCA_H-I2C-2009-03595-FR| replace:: H-I2C-2009-03595-FR: Manipulation de champs dans SALOME - Orientations générales
+.. _REF_EDF_VCA_H-I2C-2009-03595-FR: _static/documents/20091218_EDF_VCANO_H-I2C-2009-03595-FR.pdf
+
+.. You can refer to this reference using the keyword: |REF_CEA_VBE_MEDMEM|_
+.. |REF_CEA_VBE_MEDMEM| replace:: Guide utilisateur de MED mémoire
+.. _REF_CEA_VBE_MEDMEM: _static/documents/20070105_CEA_VBERGEAUD_GuideutilisateurMEDMEMOIRE.pdf
+
+.. You can refer to this reference using the keyword: |REF_EDF_GBO_WORKNOTE|_
+.. |REF_EDF_GBO_WORKNOTE| replace:: XMED: Notes de travail
+.. _REF_EDF_GBO_WORKNOTE: _static/documents/20110309_XMED_scan_notes.pdf
+
+.. You can refer to this reference using the keyword: |REF_EDF_ELO_REM|_
+.. |REF_EDF_ELO_REM| replace:: XMED: Remarques E. Lorentz
+.. _REF_EDF_ELO_REM: _static/documents/20110309_XMED_scan_remarques_ELORENTZ.pdf
+
+.. You can refer to this reference using the keyword: |REF_EDF_PRESMANIPCHP01|_
+.. |REF_EDF_PRESMANIPCHP01| replace:: Séminaire EDF-CEA de janvier 2010: manipulation de champs
+.. _REF_EDF_PRESMANIPCHP01: _static/documents/20100129_MAN_seminaireEDF-CEA_all.pdf
+
+.. You can refer to this reference using the keyword: |REF_EDF_PRESMANIPCHP02|_
+.. |REF_EDF_PRESMANIPCHP02| replace:: Révue EDF-CEA: maquette de manipulation de champs
+.. _REF_EDF_PRESMANIPCHP02: _static/documents/20101027_MAN_revueEDF-CEA.pdf
+
+.. You can refer to this reference using the keyword: |REF_EDF_PRESMANIPCHP03|_
+.. |REF_EDF_PRESMANIPCHP03| replace:: Séminaire EDF-CEA de mars 2011: manipulation de champs, maquette 2010
+.. _REF_EDF_PRESMANIPCHP03: _static/documents/20110310_seminaireEDF-CEA_maquetteXMED.pdf
+
+.. PRESENTATIONS:
+
+.. You can refer to this reference using the keyword: |REF_EDF_JUS2011_PDF|_
+.. |REF_EDF_JUS2011_PDF| replace:: JUS2011: outils de manipulation de champs
+.. _REF_EDF_JUS2011_PDF: _static/presentations/20111115_JUS-2011/20111115_JUS2011_manipulation_de_champs.pdf
+
+.. You can refer to this reference using the keyword: |REF_EDF_JUS2011_OGV1|_
+.. |REF_EDF_JUS2011_OGV1| replace:: JUS2011: outils de manipulation de champs - Exemple 1
+.. _REF_EDF_JUS2011_OGV1: _static/presentations/20111115_JUS-2011/20111115_JUS2011_medop_exemple_1.ogv
+.. You can refer to this reference using the keyword: |REF_EDF_JUS2011_OGV3|_
+.. |REF_EDF_JUS2011_OGV3| replace:: JUS2011: outils de manipulation de champs - Exemple 3
+.. _REF_EDF_JUS2011_OGV3: _static/presentations/20111115_JUS-2011/20111115_JUS2011_medop_exemple_3.ogv
+.. You can refer to this reference using the keyword: |REF_EDF_JUS2011_OGV4|_
+.. |REF_EDF_JUS2011_OGV4| replace:: JUS2011: outils de manipulation de champs - Exemple 4
+.. _REF_EDF_JUS2011_OGV4: _static/presentations/20111115_JUS-2011/20111115_JUS2011_medop_exemple_4.ogv
+
+
+
+.. LIENS EXTERNES:
+.. (l'accès nécessite le réseau intranet EDF et internet)
+
+.. You can refer to this reference using the keyword: |LINK_EDF_MEDDOC|_
+.. |LINK_EDF_MEDDOC| replace:: Modèle MED
+.. _LINK_EDF_MEDDOC: http://med.der.edf.fr/logiciels/med-2.3.6/doc/html/modele_de_donnees.html
+
+.. You can refer to this reference using the keyword: |LINK_EDF_MEDFICHIERDOC|_
+.. |LINK_EDF_MEDFICHIERDOC| replace:: Documentation de MED fichier
+.. _LINK_EDF_MEDFICHIERDOC: http://med.der.edf.fr/logiciels/med-2.3.6/doc
+
+.. You can refer to this reference using the keyword: |LINK_EDF_SALOME_MED__MED|_
+.. |LINK_EDF_SALOME_MED__MED| replace:: SALOME_MED::MED
+.. _LINK_EDF_SALOME_MED__MED: http://nepal.der.edf.fr/pub/SALOME_userguide/MED5/doc/salome/tui/MED/interfaceSALOME__MED_1_1MED.html
+
+.. RENVOIES:
+
+.. You can refer to this reference using the keyword: |SEE_MEDMEM_CORBA|
+.. |SEE_MEDMEM_CORBA| replace:: :ref:`L'interface CORBA SALOME_MED<xmed-medmem_corbainterface>`
+
+
+.. SNAPSHOTS:
+
+.. |XMED_SPECIFICATIONS_PDF| replace:: version pdf
+.. _XMED_SPECIFICATIONS_PDF: _static/documents/xmed-specifications.pdf
+
+.. |XMED_DEVELGUIDE_PDF| replace:: version pdf
+.. _XMED_DEVELGUIDE_PDF: _static/documents/xmed-develguide.pdf
+
+.. |XMED_USERGUIDE_PDF| replace:: version pdf
+.. _XMED_USERGUIDE_PDF: _static/documents/xmed-userguide.pdf
diff --git a/src/MEDOP/doc/sphinx/medop-develguide.rst b/src/MEDOP/doc/sphinx/medop-develguide.rst
new file mode 100644 (file)
index 0000000..20d49c6
--- /dev/null
@@ -0,0 +1,275 @@
+.. meta::
+   :keywords: maillage, champ, manipulation, med, développement
+   :author: Guillaume Boulant
+
+.. include:: medop-definitions.rst
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+Module MED: Guide de développement du composant MEDOP
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+Le composant logiciel MEDOP est un élément du module MED. Il fournit
+une interface utilisateur pour la manipulation de maillages et de
+champs, composée d'une interface texte (TUI) et d'une interface
+graphique (GUI). L'interface graphique constitue l'interface graphique
+du module MED.
+
+Ce document est la documentation technique du composant MEDOP. Il
+fournit les instructions à suivre pour installer le composant en vue
+d'un travail de développement, puis décrit les éléments de conception.
+
+.. contents:: Sommaire
+   :local:
+   :backlinks: none
+
+Mise en place de l'espace de développement
+==========================================
+
+Gestion de configuration du composant MEDOP
+-------------------------------------------
+
+Le composant logiciel MEDOP est un package du module SALOME MED,
+hébergé dans l'espace source au niveau du sous-répertoire
+`src/MEDOP`. La gestion des fichiers sources est donc intégrée dans le
+module SALOME MED.
+
+Organisation des sources du composant MEDOP
+-------------------------------------------
+
+Le répertoire source `src/MEDOP` distingue les sous-répertoires
+suivants:
+
+* cmp: package containing the SALOME components
+* tui: package containing the python user interface
+* gui: package containing the graphical user interface (the GUI part
+  of the MED module)
+* res: resources files associated to the MEDOP package (icons, config
+  files, data files, ...)
+* exe: additional executable programs that can be launched from the
+  MEDOP framework
+
+Construction du composant MEDOP
+-------------------------------
+
+Intégré à la construction du module MED. Le composant MEDOP dépend de
+MEDCoupling et MEDLoader uniquement.
+
+Exécution des tests unitaires du composant MEDOP
+------------------------------------------------
+
+Les tests unitaires peuvent être exécutés au moyen de scripts python
+lancés depuis une session shell SALOME. Dans un nouveau shell, taper::
+
+ $ ./appli/runSession
+ [NS=mars:2810]$ python appli/lib/python2.6/site-packages/salome/xmed/test_medoperation.py
+
+L'exécution imprime un rapport détaillant le résultat pour chaque
+fonction de test::
+
+ test_addition (__main__.MyTestSuite) ... ok
+ test_arithmetics (__main__.MyTestSuite) ... ok
+ test_composition (__main__.MyTestSuite) ... FAIL
+ test_litteral_equation (__main__.MyTestSuite) ... ok
+ test_modification_of_attributes (__main__.MyTestSuite) ... ok
+ test_unary_operations (__main__.MyTestSuite) ... ok
+ test_update_metadata (__main__.MyTestSuite) ... ok
+
+Les scripts de test sont:
+
+* ``test_medoperation.py``: tests des operations de champs telles
+  qu'elles sont mises en oeuvre depuis l'interface textuelle.
+* ``test_xmed.py``: tests des composants CORBA mis en oeuvre
+  (``MEDDataManager`` et ``MEDCalculator``)
+
+Architecture du module XMED
+===========================
+
+Le module MED pour la manipulation de champs est composé de:
+
+* une bibliothèque de fonctions pour le traitement de données sur des
+  maillages et des champs conformes au modèle MED (package
+  MEDCoupling, MEDLoader et REMAPPER);
+* une interface graphique pour la mise en oeuvre des cas standard de
+  manipulation de champs;
+* une ensemble d'outils pour intervenir sur des fichiers au format
+  MED.
+
+Une bibliothèque de fonctions pour le traitement de données
+-----------------------------------------------------------
+
+La figure ci-dessous montre la structure des paquets logiciels qui
+constituent la bibliothèque:
+
+.. image:: images/medlayers.png
+   :align: center
+
+Elle comprend en particulier les paquets suivants:
+
+* MEDCoupling: qui décrit les structures de données pour porter les
+  maillages et les champs
+* MEDLoader: qui fournit les fonctions de persistence sous forme de
+  fichiers au format MED (lecture et écriture).
+* REMAPPER:
+
+Il est important de noter que MEDCoupling n'a aucune dépendance
+logicielle autre que la bibliothèque C++ standard. Ceci permet
+d'envisager son implantation dans un code de calcul ou un outil de
+traitement sans tirer l'ensemble pré-requis de SALOME.
+
+Une interface graphique pour l'exécution des cas standard
+---------------------------------------------------------
+
+
+Un ensemble d'outils pour le traitement de fichiers
+---------------------------------------------------
+
+
+Description des composants
+==========================
+
+MEDDataManager - Le gestionnaire des données de session
+-------------------------------------------------------
+
+Le composant MEDDataManager s'occupe de fournir les données MED sur
+demande des interfaces clientes, en particulier pour module de
+pilotage fieldproxy.py. Ces données peuvent avoir plusieurs sources,
+en général elle proviennent d'un fichier au format med contenant des
+champs définis sur des maillages. Les données sont identifiées à la
+lecture des métadonnées de description dans le fichiers med, puis les
+valeurs des champs et les maillages support sont chargés au besoin.
+
+Le chargement des métadonnées de description se fait par la méthode::
+
+  addDatasource(const char \*filepath)
+
+
+
+Eléments d'implémentation
+=========================
+
+Ecrire un service CORBA qui retourne une sequence de FieldHandler:
+
+.. code-block:: cpp
+
+  MEDOP::FieldHandlerList * MyFunction(...) {
+    vector<MEDOP::FieldHandler*> fieldHandlerList;
+    ...
+  
+    fieldHandlerList.push_back(fieldHandler);
+  
+    // Map the resulting list to a CORBA sequence for return:
+    MEDOP::FieldHandlerList_var fieldHandlerSeq = new MEDOP::FieldHandlerList();
+    int nbFieldHandler = fieldHandlerList.size();
+    fieldHandlerSeq->length(nbFieldHandler);
+    for (int i=0; i<nbFieldHandler; i++) {
+      fieldHandlerSeq[i] = *fieldHandlerList[i];
+    } 
+    return fieldHandlerSeq._retn();
+  }
+
+Ecrire un service CORBA qui retourne une structure CORBA:
+
+.. code-block:: cpp
+
+    MEDOP::FieldHandler * fieldHandler = new ...
+    _fieldHandlerMap[fieldHandler->id] = fieldHandler;
+
+    // >>> WARNING: CORBA struct specification indicates that the
+    // assignement acts as a desctructor for the structure that is
+    // pointed to. The values of the fields are copy first in the new
+    // structure that receives the assignement and finally the initial
+    // structure is destroyed. In the present case, WE WANT to keep
+    // the initial fieldHandler in the map. We must then make a deep
+    // copy of the structure found in the map and return the copy. The
+    // CORBA struct specification indicates that a deep copy can be
+    // done using the copy constructor.  <<<
+    return new MEDOP::FieldHandler(*fieldHandler);
+
+
+
+ANNEXE A: Bug en cours
+======================
+
+TO FIX:
+
+* la composition d'opérations n'est pas possible (ex: 2*f1+f2) car
+  2*f1 est indiqué comme non compatible (il semble qu'il n'ai pas la
+  reference correcte vers le maillage).
+* le script de test test_medoperation.py plante si le module xmed n'a
+  pas été chargé avec des données chargées.
+
+ANNEXE B: Traçabilité avec le module XMED
+=========================================
+
+Le module SALOME de nom XMED est l'espace de développement initial du
+composant logiciel MEDOP, intégré aujourd'hui au module MED. Cette
+annexe est la notice technique de ce module, qui reste disponible mais
+qui n'est plus maintenu.
+
+Gestion de configuration du module XMED
+---------------------------------------
+
+Les sources du module (répertoire ``xmed``) sont archivés en dépôt de
+configuration dans une base git du projet NEPAL. Ils peuvent être
+récupérés au moyen de la commande::
+
+ $ git clone git@cli70rw.der.edf.fr:xom/xmed.git
+
+Cette commande installe un répertoire ``xmed`` contenant l'ensemble
+des sources du module XMED.
+
+Le module XMED a pour pré-requis logiciel la plateforme SALOME:
+
+* SALOME version 6.1.3 (au moins) à télécharger à l'URL
+  http://pal.der.edf.fr/pal/projets/pal/releases/V6_1_3
+* On peut également utiliser une version dérivée comme SALOME-MECA 2010.1
+* Installer la plate-forme choisie selon les instructions fournies.
+
+Le module XMED utilise également une bibliothèque interne au projet
+NEPAL, appelée XSALOME, et qui fournit une extension aux fonctions de
+SALOME pour un usage de développement (XSALOME signifie eXtension
+SALOME). Les sources de cette bibliothèque doivent être récupérés au
+moyen de la commande::
+
+ $ git clone git@cli70rw.der.edf.fr:xom/xsalome.git
+
+Cette commande installe un répertoire ``xsalome`` contenant l'ensemble
+des sources de la bibliothèque XSALOME.
+.. note:: La bibliothèque XSALOME n'est pas un module SALOME mais une
+   simple bibliothèque de fonctions qui complète ou rend plus facile
+   d'utilisation les fonctions de SALOME. Elle NE DOIT EN AUCUN CAS
+   être intégrée à d'autres projets que les projets internes NEPAL ou
+   MAILLAGE. Il s'agit en effet d'une bibliothèque de transition qui
+   héberge des développements destinés à être reversés dans la
+   plate-forme SALOME. Le contenu et les interfaces de XSALOME ne peut
+   donc être garanti sur le long terme.
+
+Installation et lancement de l'application
+------------------------------------------
+
+L'installation suppose qu'une version 6.1.3 de SALOME (ou plus) est
+disponible et que le shell de travail est étendu avec l'environnement
+de SALOME. En général, par des commandes de la forme::
+
+ $ . /where/is/salome/prerequis.sh
+ $ . /where/is/salome/envSalome.sh
+
+La compilation des modules xsalome et xmed suit le standard SALOME. La
+bibliothèque xsalome est un prérequis à la compilation de xmed. Pour
+cela, la variable d'environnement XSALOME_DIR doit être spécifiée pour
+la configuration de la procédure de reconstruction de xmed::
+
+ $ export XSALOME_DIR=<xsalome_installdir>
+
+Aprés l'installation de xmed, il est possible de générer
+automatiquement une application SALOME prête à l'emploi pour la
+manipulation de champs::
+
+ $ <xmed_installdir>/bin/salome/xmed/appligen/appligen.sh
+
+Cette commande génére un répertoire ``appli`` à l'emplacement où elle
+est exécutée. Il reste à lancer l'application SALOME au moyen de la
+commande::
+ $ ./appli/runAppli -k
diff --git a/src/MEDOP/doc/sphinx/medop-prototype-develguide.rst b/src/MEDOP/doc/sphinx/medop-prototype-develguide.rst
new file mode 100644 (file)
index 0000000..de2387b
--- /dev/null
@@ -0,0 +1,731 @@
+.. meta::
+   :keywords: maillage, champ, manipulation, XMED
+   :author: Guillaume Boulant
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+Démonstrateur XMED, documentation technique
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+Cette note fait la synthèse des développements effectués pour le
+maquettage des fonctions de manipulation de champs dans SALOME. Elle
+présente les principes retenus en matière de conception, c'est-à-dire
+concernant les mécanismes techniques sous-jacents, et en matière
+d'ergonomie, c'est-à-dire concernant les modalités d'utilisation dans
+l'environnement SALOME.
+
+Ces principes sont illustrés par des développements implantés dans le
+module XMED, développé pour les besoins de l'analyse, et dans le
+module MED distribué avec la plateforme SALOME.
+
+.. note:: la lecture de ce chapitre demande une connaissance de la
+   structure de classes du module MED, en particulier la distinction
+   entre les classes ``MEDMEM::*`` et les servants CORBA associés
+   (classe ``SALOME_MED::*``).
+
+.. contents:: Sommaire
+   :local:
+   :backlinks: none
+
+Principes directeurs
+====================
+
+Objectif et motivation
+----------------------
+
+L'objectif de maquettage est de trouver une architecture technique qui
+permet d'exécuter le cas d'utilisation suivant:
+
+* Chargement d'un fichier med dans SALOME (a priori dans le module MED)
+* Sélection graphique des champs de l'étude à mettre à disposition
+  dans la console utilisateur ("calculette" en mode texte qui
+  concraitement correspond à l'interface python de SALOME).
+* Dans la calculette, exécution d'opérations algébriques (+,-,*,/)
+  entre champs avec possibilité d'utiliser des scalaires dans des
+  opérations de type transformation linéaire (y=ax+b ou y et x sont
+  des champs et a et b des scalaires). Opérations pow, sqrt.
+* Possibilité de visualiser les champs produits avec VISU pour
+  contrôle des résultats.
+* Possibilité d'exporter des champs produits dans un fichier med.
+
+Eléments de contexte
+--------------------
+
+Les opérations de manipulation de champs sont en grande partie
+implémentées dans la bibliothèque MEDMEM. Pour illustration, le
+fragment de code ci-dessous montre comment une addition de champ peut
+être opérée en python:
+
+.. code-block:: python
+
+    from libMEDMEM_Swig import MedDataManager
+    from xmed.helper import readMed, writeMed
+
+    # Load the medmem data structure from a med file
+    med = readMed("/tmp/input.med")
+    # Then create a med data manager to deal with the fields data
+    dm  = MedDataManager(med)
+    # Get the timestamps (dt,it)=(-1,-1) of the fields "testfield1" and "testfield2"
+    f1 = dm.getFieldDouble("testfield1",-1,-1)
+    f2 = dm.getFieldDouble("testfield2",-1,-1)
+
+    # Create a new field as the sum of f1 and f2
+    r  = f1 + f2
+    # And add this new field to the med data structure
+    med.addField(r)
+
+    # Finally, write the whole data in an output med file
+    writeMed(med,"/tmp/output.med")
+
+Ceci montre que les champs peuvent être manipulés avec une interface
+relativement ergonomique (une addition de deux champs f1 et f2 s'écrit
+f1+f2) tant que l'on manoeuvre des objets MEDMEM purs (classes C++ du
+package MEDMEM et wrapping python du package MEDMEM_SWIG).
+
+Par ailleurs, le fonctionnement actuel des modules SALOME qui
+manoeuvrent des données MED est d'instancier les structures de données
+MEDMEM au niveau de la partie serveur, c'est-à-dire au niveau des
+servants CORBA hébergés dans le processus ``SALOME_Container``, et de
+donner accés à ces données depuis l'étude SALOME au travers de
+pointeurs CORBA. Ce choix d'architecture présente l'avantage de
+centraliser au niveau serveur la gestion du cycle de vie des données
+informatiques et de pouvoir distribuer des "poignées" pour manipuler
+ces données depuis chaque point de l'application qui sait accéder au
+bus CORBA, l'interface graphique en particulier.
+
+
+Hypothèse de travail
+--------------------
+
+Compte-tenu de l'objectif de maquettage et des éléments de contexte
+existant, on cherche une solution dans le cadre des hypothèses
+de travail suivantes:
+
+* La manipulation des champs se fait dans l'environement graphique de
+  SALOME.
+* Dans cet environnement, on souhaite pouvoir sélectionner
+  graphiquement les champs à considérer, puis manipuler ces champs
+  dans l'interface texte au moyen de variables python avec une syntaxe
+  aussi simple que celle définie dans le wrapping python de MEDMEM,
+  c'est-à-dire que pour faire l'addition de 2 champs f1 et f2, on veut
+  pouvoir écrire f1+f2.
+* Les données MED sont physiquement dans la partie serveur de SALOME
+  et accessibles via des pointeurs CORBA (interface spécifiée dans
+  MED.idl). On exclu la recopie de données au niveau du client
+  graphique.
+
+Dans le cadre de ces hypothèses, la difficulté technique réside dans
+la mise au point d'une interface de communication entre des variables
+manipulées par l'utilisateur dans l'interface graphique (c'est-à-dire
+dans le processus ``SALOME_SessionServer``) et des objets MEDMEM
+instanciés dans le containeur des servants CORBA (c'est-à-dire dans le
+processus ``SALOME_Container``).
+
+
+Eléments de conception
+======================
+
+
+Implantation technique
+----------------------
+
+Le diagramme ci-dessous représente l'organisation des principaux
+paquets logiciels du module MED:
+
+.. image:: images/medmem-layers.png
+   :align: center
+
+Les cadres bleus représentent le lieu d'implantation des
+développements effectués dans le module MED pour les besoins du
+maquettage. On notera en particulier les interventions aux niveaux
+suivants:
+
+* interfaces idl: ajout de l'interface MEDOP.idl
+* package MEDMEM_I: ajout du servant SALOME_MED::MEDOP qui implémente
+  l'interface MEDOP.idl
+
+Architecture technique
+----------------------
+
+Les schéma ci-dessous représente les objets informatiques qui sont à
+l'oeuvre pour la réalisation des opérations sur les champs:
+
+.. image:: /images/xmed-architecture.png
+   :align: center
+   :alt: Objets mis en oeuvre dans l'interface de manipulation de champs
+
+On distingue les objets suivants:
+
+* Une instance de ``MEDMEM::MED``, correspondant à la structure de donnée
+  MED chargée en mémoire.
+* Des instances de ``MEDMEM::FIELD`` qui représentent les champs med
+  chargés en mémoire.
+* Une instances de ``SALOME_MED::MED`` et des instances de
+  ``SALOME_MED::FIELD`` qui sont les servants CORBA respectivement de la
+  structure med et des champs qui lui sont associés et chargés en
+  mémoire.
+* Une instance de ``SALOME_MED::MEDOP`` qui est le servant CORBA qui
+  centralise la mise en oeuvre des opérations de champs sur le serveur
+  ``SALOME_Container``. Le servant MEDOP détient en attribut une référence
+  sur la structure ``MEDMEM::MED``, ce qui lui permet d'accéder
+  directement aux champs ``MEDMEM::FIELD`` à partir de leur nom et du pas
+  de temps.
+* Des instances de ``FieldProxy`` qui correspondent aux variables
+  manipulées au niveau de l'interface graphique et qui représentent
+  les champs. Une instance de FieldProxy possède détient les
+  références des servants ``SALOME_MED::MEDOP`` et
+  ``SALOME_MED::FIELD`` sous la forme de pointeurs CORBA de noms
+  ``medop_ptr`` et ``field_ptr`` respectivement.
+* Il existe également une instance de ``MedProxy`` non représentée
+  dans ce diagramme. Cette instance correspond à une variable qui
+  permet de manipuler la structure med.
+
+.. note:: Les éléments apportés par la maquette sont les classes
+   ``SALOME_MED::MEDOP``, ``MedProxy`` et ``FieldProxy``. Les autres
+   éléments ont pu être modifiés légèrement pour les besoins de
+   l'intégration ou pour la correction de quelques bugs.
+
+Le cycle de vie de ces objets est le suivant.
+
+Pour ce qui concerne les instances de la structure ``MEDMEM::MED`` et
+des champs ``MEDMEM::FIELD``, la création est faite au moment du
+chargement du fichier med dans SALOME au moyen du module MED. A cette
+occasion, les servants CORBA associés ``SALOME_MED::MED`` et
+``SALOME_MED::FIELD`` sont créés et des références vers ces servants
+sont publiés dans l'étude. Ils peuvent donc être sélectionnés par
+l'utilisateur dans l'interface graphique. L'ensemble de ces données
+préexiste à la manipulation de champs.
+
+Les objets ``SALOME_MED::MEDOP`` sont instanciés au sein du servant
+``SALOME_MED::MED`` auquel ils sont associées. Le servant
+``SALOME_MED::MED`` possède une référence sur la structure
+``MEDMEM::MED`` et il la transmet à l'instance du servant
+``SALOME_MED::MEDOP`` qu'il construit. L'opérateur MEDOP est donc
+autonome par la suite pour manipuler les données MED, et les champs en
+particulier. Le code python ci-dessous montre comment un opérateur med
+``SALOME_MED::MEDOP`` peut être créé puis utilisé pour réaliser
+l'addition de deux champs:
+
+.. code-block:: python
+
+   import salome
+   salome.salome_init()
+   import SALOME_MED
+   
+   medComp = salome.lcc.FindOrLoadComponent("FactoryServer", "MED")
+   medObj  = medComp.readStructFile("myfile.med",salome.myStudyName)
+   medOp   = medObj.createMedOperator()
+   
+   f1 = medObj.getField("testfield1",-1,-1)
+   f2 = medObj.getField("testfield2",-1,-1)
+   
+   somme = medOp.add(f1,f2)
+
+Il est à noter qu'une instance de ``SALOME_MED::MEDOP`` est associé à
+une instance unique de ``SALOME_MED::MED`` (et donc indirectement de
+``MEDMED::MED``) pour toute la durée de son cycle de vie. Par contre,
+un servant ``SALOME_MED::MED`` peut être associé à plusieurs servants
+``SALOME_MED::MEDOP`` différents. Un servant ``SALOME_MED::MEDOP`` a
+une référence directe sur la structure ``MEDMEM::MED`` et peut la
+manoeuvrer pour demander des champs, faire des opérations avec ces
+champs, ajouter le champs résultat à la structure et enfin retourner
+un servant ``SALOME_MED::FIELD`` qui encapsule le champ résultat.
+
+Enfin, quelques éléments concernant la classe ``FieldProxy``. Une
+instance de ``FieldProxy`` est un objet python qui peut être
+manoeuvrée dans l'interpréteur SALOME et qui référence un champ MED
+localisé sur le serveur ``SALOME_Container`` (par le mécanisme décrit
+ci-dessus). C'est à ce niveau qu'on règle les détails d'ergonomie
+d'usage (cf. paragraphe ci-après). La création d'un objet
+``FieldProxy`` déclenche la création d'un opérateur med (instance de
+``SALOME_MED::MEDOP``) qui lui est associé et dont il conserve la
+référence CORBA en attribut (noté ``medop_ptr`` sur le diagramme). Cet
+opérateur ``medop_ptr`` peut être requêter pour exécuter toutes les
+opérations possibles sur ce champ, comme illustrer sur l'exemple
+ci-dessus.
+
+
+Rôle des objets proxy
+---------------------
+
+Dans le modèle d'architecture présenté ci-dessus, on introduit deux
+types d'objets proxy:
+
+* Les objets de classe ``FieldProxy`` qui représentent des poignées de
+  manipulation des champs ``MEDMEM::FIELD`` physiquement instanciés
+  dans le container SALOME.
+* Les objets de classe ``MedProxy`` qui représentent des poignées de
+  manipulation des structures ``MEDMEM::MED`` physiquement instanciées
+  dans le container SALOME.
+
+Elles sont instanciées dans l'interpréteur python SALOME pour
+manipulation dans l'interface textuelle à partir de la donnée du
+pointeur vers le servant ``SALOME_MED::MED`` et de l'identifiant du
+champ (le nom du champ et le pas de temps défini par le numéro d'ordre
+et le numéro d'iteration:
+
+.. code-block:: python
+
+   import salome
+   salome.salome_init()
+   import SALOME_MED
+
+   medComp = salome.lcc.FindOrLoadComponent("FactoryServer", "MED")   
+   medObj  = medComp.readStructFile("myfile.med",salome.myStudyName)
+
+   from xmed import fieldproxy
+   from xmed import medproxy
+
+   f1 = fieldproxy.getFieldFromMed(medObj, "testfield1", -1, -1)
+   f2 = fieldproxy.getFieldFromMed(medObj, "testfield2", -1, -1)
+
+   field_somme  = f1 + f2
+   field_offset = f1 + 5.3
+
+Dans cet exemple, les variables ``f1``, ``f2``, ``field_somme`` et
+``field_offset`` sont des objets de classe ``FieldProxy``. Ils
+correspondent aux variables physiquement manipulées par
+l'utilisateur pour désigner les champs dans les opérations.
+
+Ces classes proxy sont conçues pour être le lieu d'implémentation de
+l'interprétation des commandes utilisateur et donc de l'ergonomie
+de manipulation des champs au niveau l'interface textuelle. Ce point
+est développé :ref:`plus bas <develguide_execFieldOperation>`.
+
+Programmation de l'interface textuelle
+--------------------------------------
+
+Dans le cadre de la maquette, l'interface de manipulation des champs
+est l'interface textuelle python intégrée à SALOME. Dans la pratique,
+l'utilisateur manipule des variables python qui correspondent à des
+objets de classe ``FieldProxy`` équipées des fonctions requises et de
+l'ergonomie nécessaire à la mise en oeuvre des opérations (voir
+ci-dessus).
+
+Or, l'hypothèse de travail est que les données MED sont chargées dans
+SALOME et publiées dans l'étude pour point d'accés depuis l'interface
+graphique. L'utilisateur choisi un champs directement dans l'arbre
+d'étude (ou dans une interface graphique dédiée) puis demande qu'il
+soit mis à disposition dans l'interface python sous un nom de variable
+à choisir. Les captures d'écran ci-dessous montre la séquence
+graphique en images:
+
+.. |IMG_SELECT| image:: images/medop-gui-selectfield_scale.png
+.. |IMG_ALIAS| image:: images/medop-gui-aliasfield_scale.png
+
++---------------+---------------+ 
+| |IMG_SELECT|  | |IMG_ALIAS|   |
++---------------+---------------+ 
+
+L'image de gauche montre la sélection du pas de temps, l'image de
+droite la boîte de dialogue qui permet la saisie de l'alias avec
+lequel le champs sera manipulé dans l'interface textuelle. La
+validation de cette fenêtre doit mettre automatiquement le champ à
+disposition dans l'interface python SALOME et sous le nom de variable
+spécifié par l'alias saisi.
+
+Pour cela, il y a un couplage technique à programmer entre l'interface
+graphique et l'interface textuelle python, avec en particulier la
+transmission des pointeurs vers les servants CORBA mis en jeu dans la
+sélection.
+
+Ce couplage est implanté au niveau de la classe MEDGUI.cxx du module
+MED (où de la classe XMEDGUI.cxx du module XMED pour la maquette) qui
+implémente l'interface graphique du module. Pour rappel, l'interface
+graphique d'un module SALOME se présente sous la forme d'une classe
+centrale de nom ``<MODULE_NAME>GUI`` et qui spécialise la classe
+``SalomeApp_Module``. Cette classe possède une méthode ``getApp()``
+par laquelle on peut récupérer une instance de la console python
+embarquée (this->getApp()->pythonConsole()).
+
+Le code suivant illustre l'envoie d'une commande python par ce
+mécanisme. Dans cet example, on cherche à reconstituer dans le
+contexte de la console python un pointer vers un objet med instancié
+dans le contexte C++ de l'application graphique. Pour cela, on
+communique la référence de l'objet sous la forme sérialisé (IOR pour
+un objet CORBA):
+
+.. code-block:: cpp
+
+   #include <PyConsole_Console.h>
+   #include <QString>
+   #include <QStringList>
+   #include <SalomeApp_Application.h>
+
+   // We suppose here that we have a CORBA object reference (object of
+   // type *_ptr or *_var), for example a SALOME_MED::MED object.
+   SALOME_MED::MED_ptr medObj = ... // anything to get this object  
+
+   // Get the IOR of this object
+   QString medIOR = SalomeApp_Application::orb()->object_to_string(medObj);
+
+   PyConsole_Console * pyConsole = getApp()->pythonConsole();
+
+   QStringList commands;
+   commands+="import salome";
+   commands+=QString("med=salome.orb.string_to_object(\"%1\")").arg(medIOR);
+      
+   QStringListIterator it(commands);
+   while (it.hasNext()) {
+       pyConsole->exec(it.next());
+   }
+
+Le code réel de la maquette est basé sur ce principe et transmet à la
+console python des lignes de commandes qui permettent de reconstruire:
+
+* un pointeur CORBA vers le servant ``SALOME_MED::MED`` associé au
+  champ sélectionné;
+* une instance de ``FieldProxy`` qui correspond au champ sélectionné
+  et avec pour nom de variable la valeur de l'alias saisi dans
+  l'interface graphique.
+
+Au niveau du code C++ de la classe ``XMEDGUI.cxx``, cela se traduit
+par la fabrication de la liste de commandes suivante pour envoie à la
+console python par le mécanisme illustré plus haut:
+
+.. code-block:: cpp
+
+   QStringList commands;
+   commands+="from xmed.fieldproxy import getFieldFromMed";
+   commands+="from xmed.medproxy import getMedProxy";
+   commands+=QString("if not dir().__contains__('med'): med = getMedProxy(\"%1\")").arg(medIOR);
+   commands+=QString("%1=getFieldFromMed(med,\"%3\",%4,%5)").arg(*alias).arg(fieldName).arg(orderIndex).arg(iterationIndex);
+
+Les variables ``medIOR``, ``fieldName``, ``orderIndex`` et
+``iterationIndex`` sont construites à partir du champ sélectionné par
+des techniques de programmation standard dans SALOME qu'on peut
+examiner en détail dans la classe ``XMEDGUI`` (voir méthode
+``XMEDGUI::LoadIntoPythonConsole()``). La variable ``alias`` est la
+chaîne saisie par l'utilisateur dans la fenêtre de dialogue.
+
+Le point important à noter ici est que les données à transmettre
+doivent être fournies sous forme de chaînes de caractères ou de types
+simples. C'est pourquoi la référence au servant CORBA
+``SALOME_MED::MED`` est transmise ici sous la forme de son IOR,
+c'est-à-dire une chaîne de caractères qui permet l'identification de
+l'objet au niveau du bus CORBA.
+
+Au niveau de la console python cela correspond à l'exécution des
+commandes suivantes:
+
+.. code-block:: python
+
+   from xmed.fieldproxy import getFieldFromMed
+   from xmed.medproxy import getMedProxy
+   
+   med = getMedProxy("IOR:010000001700000049444c3a53414c4f4d455f4d45442f4d45443a312e300000010000000000000064000000010102000e0000003133302e39382e37372e313733009e0a0e000000feadc4ca4c00003169000000001100000200000000000000080000000100000000545441010000001c00000001000000010001000100000001000105090101000100000009010100")
+   
+   f1=getFieldFromMed(med,"testfield1",-1,-1)
+
+Ce jeu d'instructions reconstitue un pointeur vers le servant CORBA
+``SALOME_MED::MED`` à partir de son identifiant IOR (voir la fonction
+``getMedProxy(...)``, puis crée une instance de ``FieldProxy``
+associée à ce servant (en fait associée au servant
+``SALOME_MED::MEDOP`` créé sur demande par le servant
+``SALOME_MED::MED``, voir la fonction ``getFieldFromMed(...)``).
+
+.. _develguide_execFieldOperation:
+
+Exécution des opérations sur le champs
+--------------------------------------
+
+Les variables définies dans l'interface textuelle pour désigner les
+champs à manipuler sont des objets de classe ``FieldProxy``.
+
+Cette classe a une propriété remarquable, elle est construite sur un
+design pattern de type "Proxy" qui pointe vers un servant
+``SALOME_MED::FIELD``. Cela signifie que l'on ne peut pas accéder
+directement au servant vers lequel il pointe, mais que l'on passe
+systématiquement par une procédure de l'objet proxy qui fait "boîte
+aux lettres":
+
+.. code-block:: python
+
+   class FieldProxy:
+
+     def __getattr__( self, name ):
+        """
+        This method realizes the proxy pattern toward the servant
+        SALOME_MED::FIELD.
+        """
+        return getattr( self.__field_ptr, name )
+
+Ce pattern permet l'implémentation de pré-traitement et/ou de
+post-traitement suivant le type d'accés que l'on cherche à faire.
+
+Il permet aussi et surtout de fournir un objet python qui présente
+l'interface de ``SALOME_MED::FIELD`` dotée d'extentions adhoc pour les
+operations de champs. Ici, python est ton ami, car il s'agit pour cela
+d'équiper la classe ``FieldProxy`` des automatismes prévus nativement
+par python pour les operations entre objets. En particulier, la
+re-définition des fonctions internes ``__add__`` (opérateur addition),
+``__sub__`` (opérateur soustraction), ``__mul__`` (opérateur
+multiplication) et ``__div__`` (opérateur division) au sein de la
+classe ``FieldProxy``, permet de prendre la main sur le comportement
+des opérations algébriques et de définir une ergonomie sur mesure. Par
+exemple, la méthode ``__add__`` peut gérer les variantes "f1+f2"
+(ajout de deux variables de type FieldProxy) et "f1+5.3" (ajout d'un
+réel à une variable de type FieldProxy):
+
+.. code-block:: python
+
+   class FieldProxy:
+
+     def __add__(self, operande):
+        """
+        This can process the addition of two fields or the addition of
+        a scalar to a field. It depends weither the operande is a
+        FieldProxy or a simple scalar numerical value.
+        """
+        if isinstance(operande, FieldProxy):
+            # The operande is an other field
+            otherField_ptr = operande.__field_ptr
+            rfield_ptr = self.__medOp_ptr.add(self.__field_ptr, otherField_ptr)
+        else:
+            # The operande is a scalar numerical value that must be
+            # considered as an offset in a linear transformation
+            factor = 1
+            offset = operande
+            rfield_ptr = self.__medOp_ptr.lin(self.__field_ptr, factor, offset)
+        return FieldProxy(self.__med_ptr, rfield_ptr)
+
+Il est à noter que dans les deux cas de figure (opérande=champ ou
+opérande=scalaire), la fonction délègue la réalisation concrète de
+l'opération au servant ``SALOME_MED::MEDOP`` (identifié ici par
+l'attribut ``self.__medOp_ptr`` et que l'on appelera l'*opérateur
+MEDOP* dans la suite pour simplifier), mais n'appelle pas le même
+service de calcul (l'addition entre champs dans le premier cas,
+l'application d'une transformation linéaire de type y=factor*x+offset
+dans le deuxième cas).
+
+Pour couvrir le cas des opérations algébriques, l'opérateur MEDOP
+présentre l'interface suivante (cf. fichier ``MEDOP.idl`` qui définie
+l'interface du servant ``SALOME_MED_MEDOP``):
+
+.. code-block:: cpp
+
+    /*! Addition of the fields f1 and f2 ( f1+f2) */
+    FIELD add(in FIELD f1, in FIELD f2) raises (SALOME::SALOME_Exception);
+    /*! Substraction of the fields f1 and f2 (f1-f2) */
+    FIELD sub(in FIELD f1, in FIELD f2) raises (SALOME::SALOME_Exception);
+    /*! Multiplication of the fields f1 by f2 (f1*f2) */
+    FIELD mul(in FIELD f1, in FIELD f2) raises (SALOME::SALOME_Exception);
+    /*! Division of the fields f1 by f2 (f1/f2) */
+    FIELD div(in FIELD f1, in FIELD f2) raises (SALOME::SALOME_Exception);
+    /*! Power of the field f (f^power) */
+    FIELD pow(in FIELD f, in long power) raises (SALOME::SALOME_Exception);
+    /*! Linear transformation of the field f (factor*f+offset) */
+    FIELD lin(in FIELD f, in double factor, in double offset) raises (SALOME::SALOME_Exception);
+    /*! Dublication of the field f */
+    FIELD dup(in FIELD f) raises (SALOME::SALOME_Exception);
+
+Cette interface est implémentée dans la classe C++ ``MEDOP_i`` du
+module MED (voir fichier ``MEDMEM_MedOp_i.hxx`` du package
+``MEDMEM_I``). C'est au sein des instances de cette classe que sont
+réalisées les opérations et que sont produites physiquement les
+données. Typiquement, les opérations présentées ici produisent un
+champ ``MEDMEM::FIELD`` sur la base duquel elle fabrique un servant
+``SALOME_MED::FIELD`` pour finalement retourner un pointeur CORBA sur
+ce servant.
+
+Ce mécanisme global peut être étendu sans limitation à tout les types
+d'opération qui sont envisagés dans les spécifications de manipulation
+des champs dans SALOME.
+
+
+Contrôle visuel des champs
+--------------------------
+
+Les illustrations ci-dessous montrent qu'une fonction de visalisation
+est implémentée dans la maquette pour permettre le contrôle visuel
+d'un champ au moyen d'une représentation 3D (une carte spatiale du
+module du champ dans l'exemple implémenté par défaut):
+
+.. |IMG_VISU| image:: images/medop-gui-visufield_scale.png
+.. |IMG_RESULT| image:: images/medop-gui-result_scale.png
+
++---------------+---------------+ 
+| |IMG_VISU|    | |IMG_RESULT|  |
++---------------+---------------+ 
+
+Cette fonction répond au besoin de contrôle interactif des résultats
+produits par les opérations de manipulation de champs.
+
+Il s'agit là d'un usage classique de SALOME, dans lequel on demande au
+module VISU de faire une représentation 3D d'un champ spécifié par la
+donnée du servant ``SALOME_MED::FIELD`` qui lui est associé
+(représenté par la variable ``field_ptr`` dans l'exemple ci-dessous):
+
+.. code-block:: python
+   
+   import salome
+   import VISU
+
+   visuComp = salome.lcc.FindOrLoadComponent("FactoryServer", "VISU")
+   visuComp.SetCurrentStudy(salome.myStudy)
+
+   # Then we can import the specified field in the VISU module. This
+   # creates an study entry in the VISU folder.
+   result = visuComp.ImportMedField(field_ptr)
+
+   meshName   = field_ptr.getSupport().getMesh().getName()
+   fieldName  = field_ptr.getName()
+   iterNumber = field_ptr.getIterationNumber()
+   scalarmap = visuComp.ScalarMapOnField(result,
+                                         meshName,
+                                         visuEntityType,
+                                         fieldName,
+                                         iterNumber)
+
+Dans ce jeu d'instructions donné pour exemple (non fonctionnel, en
+particulier à cause de la non définition de la variable
+``visuEntityType``, voir remarque plus bas), le composant VISU
+désigné ici par la variable ``visuComp`` va chercher les données du
+champ en interrogeant le servant ``SALOME_MED::FIELD`` transmis en
+argument de la fonction ``ImportMedField``, puis produit une
+représentation de type "scalarmap".
+
+.. note:: Compte-tenu des propriétés de la classe FieldProxy décrites
+   plus haut conférées par le pattern "Proxy", on peut transmettre ici
+   aussi bien le servant CORBA que l'instance du proxy (la fonction
+   ``ImportMedField`` n'y verra que du feu).
+
+Le code complet et fonctionnel de la fonction d'affichage est dans le
+corps du module python ``fieldproxy.py`` sous la forme d'une fonction
+de nom ``visuField``. Il convient de noter que cette fonction doit
+établir une correspondance entre le type des entités tel que défini
+dans MED et dans VISU:
+
+.. code-block:: python
+
+    medEntityType = field_ptr.getSupport().getEntity()
+    if (medEntityType == SALOME_MED.MED_CELL):
+        visuEntityType = VISU.CELL
+    elif (medEntityType == SALOME_MED.MED_NODE):
+        visuEntityType = VISU.NODE
+
+
+Export des résultats de calcul
+------------------------------
+
+Tous les champs produits à l'occasion des opérations entre objets
+``FieldProxy`` sont automatiquement ajoutés à la structure med à
+laquelle is sont associés. Une convention d'attribution des noms est
+implémentée de sorte que par défaut aucune précision n'est demandée à
+l'utilisateur.
+
+La structure med peut être manipulée au moyen de la variable ``med``
+créée dans l'interface textuelle comme une instance de la classe
+``MedProxy``. La classe ``MedProxy`` fournit un objet qui présente
+l'interface du servant ``SALOME_MED::MED`` étendue de quelques
+fonctions utilitaires pour la gestion et le contrôle des données.
+
+En particulier, la sauvegarde de la structure dans un fichier est
+automatisée par la méthode ``save(medfilename)``:
+
+.. code-block:: python
+
+   med = medproxy.MedProxy(medObj)
+   med.save("/tmp/output.med")
+
+Cette méthode s'occupe de définir un driver d'écriture et de procéder
+à l'enregistrement des données de la structure med (les maillages, les
+champs présents au départ et tous les champs produits depuis la
+lecture initiale).
+
+Limitations
+===========
+
+L'implémentation de la maquette limite l'usage des opérations aux cas
+de figure suivants:
+
+* Seules les operations entre champs qui partagent le même support med
+  sont possibles. Ceci est une contrainte imposé par la conception
+  actuelle de MEDMEM.
+* Le résultat d'une opérations est calculé sur toutes les composantes
+  et tout le domaine de définition des champs en opérande. Cette
+  deuxième contrainte est juste parce que les usages plus fin,
+  notemment avec la notion de domaine de définition, n'a pas encore
+  été exéminée à ce jour.
+* Le nom d'un champ produit par une opération ne correspond pas au nom
+  de la variable python par laquelle on le réceptionne et on le
+  manipule. Le nom est attribué par une convention (ceci n'est pas
+  vraiment une limitation mais une caractéristique à connaître).
+
+On note également les restriction techniques suivantes:
+
+* Les données MEDMEM sont supposées être chargées par le composant MED
+  puis référencées dans l'étude SALOME (comme c'est fait aujourd'hui
+  par le module MED).
+* Dans certain cas, python n'est pas ton ami. Pour que les opérateur
+  de la classe ``FieldProxy`` soient pris en considération dans les
+  opérations sur les champs, il est indispensable que le premier
+  opérande d'une opération unitaire soit un champ (objet de classe
+  ``FieldProxy``). Par exemple: "field_offset = field + 5.3"
+  fonctionne alors que "field_offset = 5.3 + field" ne fonctionne pas
+  car python tente de traiter la situation au moyen de la fonction
+  ``__add__`` de la classe ``float`` (qui n'est pas modifiable).
+
+
+Notice informatique
+===================
+
+Gestion de configuration
+------------------------
+
+Les développements décrits dans ce chapitre sont répartis entre les
+modules MED et XMED (développé pour l'occasion). Cette séparation est
+faite par soucis de clarté et d'efficacité de développement, mais les
+éléménts du module XMED ont vocation à intégrer le module MED dans la
+mesure où les propositions techniques sont retenues pour le
+développement à venir.
+
+Le code source du module XMED peut être récupérés par la commande
+suivante::
+
+ $ svn co svn://nepal.der.edf.fr/FIELD/XMED_SRC/trunk XMED_SRC
+
+Le pré-requis est la plate-forme SALOME version 5.1.4 (ou plus)
+équipée au minimum des modules KERNEL, GUI, MED (branche BR_medop) et
+VISU. Pour récupérer la branche BR_medop du module MED, taper la
+commande::
+
+ $ cvs -d :pserver:anonymous@cvs.opencascade.com:2401/home/server/cvs/MED co -r BR_medop MED_SRC
+
+La configuration de référence est:
+
+* XMED: révision svn 41
+* MED: tag cvs BR_medop_20101025
+
+Moyens de tests
+---------------
+
+Plusieurs types de tests unitaires sont définis (reste à les
+automatiser proprement):
+
+* Test des servants et utilitaires de manipulation python:
+
+  - Dans XMED, package xmed/tests, utiliser le script
+    ``test_medoperation.py`` dans un interpréteur python lancé dans
+    une session shell SALOME. Ce script prépare des variables de test
+    et fournit des fonctions de test unitaire (à exécuter ou pour s'en
+    inspirer). Après avoir lancé SALOME via une application virtuelle,
+    on peut taper::
+      $ <APPLI_ROOT>/runSession
+      [NS=venus:2810] $ python -i test_medoperation.py
+      >>> 
+   
+  - Ceci permet de tester en particulier l'interface ``MedOp`` et son
+    utilisation dans le module python ``fieldproxy.py``.
+
+* Test des classes MEDMEM:
+
+  - Test de MEDMEM::MedDataManager dans ``MEDMEM_MedDataManager_test.cxx``
+
+Un fichier de test basique (mais néanmoins suffisant) de nom
+``tesfield.med`` est fourni avec les sources dans le répertoire
+``<XMED_SRC>/resources/datafiles`` et dans l'installation au niveau du
+répertoire ``<INSTALLDIR>/share/salome/resources/xmed/datadir``. Il
+contient deux champs ``testfield1`` et ``testfield2`` définis sur un
+pas de temps unique (dt,it=-1,-1). Ces champs définissent des valeurs
+par éléments (MED_CELL).
diff --git a/src/MEDOP/doc/sphinx/medop-prototype-medmem.rst b/src/MEDOP/doc/sphinx/medop-prototype-medmem.rst
new file mode 100644 (file)
index 0000000..2302f7b
--- /dev/null
@@ -0,0 +1,513 @@
+.. meta::
+   :keywords: maillage, champ, MED, MEDMEM
+   :author: Guillaume Boulant
+
+.. include:: medop-definitions.rst
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+Note de travail concernant l'utilisation de MEDMEM
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+Le module MED de SALOME comporte plusieurs composants d'intérêt pour
+la manipulation de champs:
+
+* la bibliothèque MEDMEM qui fournit une interface de programmation
+  pour manoeuvrer une structure MED
+* le module CORBA SALOME_MED qui matérialise le composant SALOME
+  (serveur corba) du module MED
+* l'interopérabilité avec le module VISU qui permet la visualisation
+  des champs manipulés dans MED
+
+Les sections ci-après donnent quelques éclairages techniques sur ces
+différents aspects. Les sources de démonstration peuvent être
+récupérés depuis le dépôt svn::
+
+ $ svn export svn://nepal.der.edf.fr/OM/manifield/trunk manifield
+ $ svn export svn://nepal.der.edf.fr/FIELD/demofield/trunk demofield
+
+.. contents:: Sommaire
+   :local:
+   :backlinks: none
+
+Présentation synthétique de MED
+===============================
+
+MED désigne un modèle conceptuel pour décrire des données de type
+éléments finis (éléments finis, volumes finis et éléments
+discrets). Dans l'usage courant, il permet la description et l'échange
+des données de calcul de type maillages et champs. La documentation
+complète peut être trouvée à l'URL suivantes:
+
+* |LINK_EDF_MEDDOC|_ (version 2.3).
+
+On distingue deux implémentations informatiques de ce modèle:
+
+* MED fichier: qui permet la lecture et l'écriture de données depuis
+  un fichier au format med. Les opérations de lecture/écriture sont
+  atomiques (pas de chargement de la structure de données globale).
+* MED mémoire (noté MEDMEM): qui permet le chargement en mémoire d'une
+  image de la structure de données MED contenue dans un fichier au
+  format med. Les opérations peuvent être atomiques ou
+  globales.
+
+On notera simplement ici que MEDMEM utilise MED fichier pour les
+opérations de lecture/écriture et que MED fichier est indépendant de
+MED mémoire. La documentation complète de MED fichier peut être
+trouvée à l'URL suivante:
+
+* |LINK_EDF_MEDFICHIERDOC|_
+
+La bibliothèque MEDMEM
+======================
+
+Le modèle de classes MEDMEM est structuré autour des notions de MESH
+(les maillages), de SUPPORT (le profil des entités) et de FIELD (les
+champs). Ces notions reprennent en partie des concepts du modèle
+MED. Le diagramme ci-dessous présente les classes principales:
+
+.. image:: images/med-uml-main_60pc.png
+   :align: center
+
+Le conteneur de plus haut niveau dans MEDMEM est la classe MED. La
+figure ci-dessous indique qu'une instance MED peut être associée à
+plusieurs maillage et plusieurs champs. Par contre un champ donné ne
+peut être associé qu'à un seul maillage (par l'intermédiaire du
+support). Plusieurs champs peuvent être associés au même maillage. La
+forme la plus courante est d'ailleurs une instance composé d'un
+maillage unique sur lequel sont définis plusieurs champs.
+
+On peut avoir également des configurations plus complexes, comme par
+exemple un maillage unique, plusieurs champs définis sur ce maillage
+mais avec des supports différents, par exemple parce que les valeurs
+sont définies sur des entités de maillage différentes (les éléments
+pour un champ, les noeuds pour un autre, ...)::
+
+  field1->support1->mesh
+  field2->support2->mesh
+  field3->support3->mesh
+
+On observe:
+
+* 2 champs U et V doivent avoir le même support (au sens informatique
+  du terme) pour pouvoir être en argument d'une opération (sinon
+  exception). Il faudrait accepter qu'il soit informatiquement
+  différent et vérifier la conformité conceptuelle.
+* Cette contrainte peut se comprendre car physiquement les données
+  sont stockées dans un vecteur qui couvre toutes les mailles. Le
+  support est le seul masque de lecture pour établir la correspondance
+  avec les positions dans le maillage et il est donc important qu'une
+  cohérence soit assurée.
+
+Les objets champs (FIELD) et maillage (MESH)
+--------------------------------------------
+
+Un objet MED permet d'accéder aux différentes informations concernant
+les objets MESH, SUPPORT et FIELD, mais il ne permet pas d'accéder aux
+données physiques associées à ces objets (les valeurs des composantes
+pour les champs, les mailles et leur connectivité pour les
+maillages). L'accès aux données physiques est du ressort des objets
+spécifiques MESH, SUPPORT et FIELD.
+
+Un objet MED peut être créé intégralement en mémoire. L'usage plus
+fréquent est de l'initialiser à partir de la donnée d'un fichier
+med. Pour cela, l'objet MED doit être associé à un driver
+d'entrée/sortie branché sur le fichier (``testfilename`` dans
+l'exemple):
+
+.. code-block:: cpp
+   
+   MED *myMed = new MED;
+   MED_MED_RDONLY_DRIVER *driverIn = new MED_MED_RDONLY_DRIVER(testfilename, myMed);
+   driverIn->open();
+   driverIn->readFileStruct();
+   driverIn->close();
+
+A l'occasion de la fonction readFileStruct, la structure interne de
+l'objet MED est enrichie des informations concernant les objets MESH,
+SUPPORT et FIELD contenu dans le fichier. En particulier un
+dictionnaire des champs (variable map interne) est initialisé est
+contient l'ensemble des objets ``FIELD_`` préchargés (i.e. avec les
+méta-données uniquement). Chaque objet ``FIELD_`` ainsi préchargé est
+autonome pour être chargé sur demande. On peut alors requêter l'objet
+MED pour obtenir un champ particulier (spécifié par son nom
+``fieldname`` dans l'exemple):
+
+.. code-block:: cpp
+
+   FIELD<double> *field = (FIELD<double> *)myMed->getField(fieldname, dt, it);
+
+Puis le champ qui lui est associé doit être physiquement chargé pour
+permettre la mise à jour du support:
+
+.. code-block:: cpp
+   
+   MESH * mesh = myMed->getMesh(field);
+   mesh->read();
+   myMed->updateSupport();
+
+Pour enfin charger les valeurs des composantes du champ:
+
+.. code-block:: cpp
+   
+   field->read();
+
+La numérotation des éléments de maillage
+----------------------------------------
+
+Les éléments qui composent un maillage sont caractérisés par:
+
+* Le type d'entité de l'élément, à choisir dans la liste
+  ``MED_EN::medEntityMesh``, qui contient en particulier ``MED_NODE``,
+  ``MED_FACE``, ``MED_CELL``.
+* Le type de géométrie de l'élément, à choisir dans la liste
+  ``MED_EN::medGeometryElement``, qui contient en particulier
+  ``MED_NONE``, ``MED_TRIA3``, ..., ``MED_ALL_ELEMENTS``.
+
+Les éléments sont numérotés par un indice relatif à la catégorie
+géométrique à laquelle ils appartiennent. Ainsi, si le modèle est
+composé de Na arrêtes et Nf faces de type géométrique MED_QUAD4, alors
+ces faces sont numérotées de 1 à Nf dans le modèle MED (et de manière
+persistente dans le fichier med). De même, les arrêtes sont numérotées
+de 1 à Na. Une numérotion globale implicite existe sur les éléments,
+elle consiste à parcourir l'ensemble des types géométriques dans
+l'ordre de définition du modèle de données. Ainsi, si le modèle
+contient uniquement les Na arrêtes et les Nf faces, alors l'indice
+global de la première face est Na+1.
+
+.. note:: Des exemples de code sont disponibles dans le package ``demofield``, fichier ``python/pybasicfields/MEDMEM_tester.py``.
+
+
+Binding python de MEDMEM
+------------------------
+
+Les classes du package ``MEDMEM`` (package du module ``MED`` qui
+implémentent les structures de données C++ de MED mémoire) produisent
+la bibliothèque ``libmedmem.so``. Cette ensemble de classes est en
+partie mis à disposition de l'interface python grace à une couche de
+liaison (binding Python-C++) générée par le logiciel SWIG à partir
+d'un fichier de description d'interface ``libMEDMEM_Swig.i`` (dans le
+package source ``MEDMEM_SWIG``).
+
+Ce fichier d'interface doit être mis à jour dés lors qu'une évolution
+des interfaces publiques des classes C++ MEDMEM est faite ou qu'une
+nouvelle classe est créée (du moins si l'on souhaite profiter de ces
+évolutions dans l'interface python).
+
+Cette mise à jour nécessite de prendre soin au transfert des
+structures de données entre les espaces python et C++. En particulier,
+l'utilisation des template de classe pour décrire les champs typés en
+C++ appelle une précaution de codage particulière de l'interface
+SWIG.
+
+Pour exemple, le fragment de code ci-dessous, extrait du fichier
+``libMEDMEM_Swig.i``, montre comment déclarer la nouvelle classe
+``MedDataManager`` dans l'interface:
+
+.. code-block:: cpp
+   
+   #include "MEDMEM_MedDataManager.hxx"
+
+   class MedDataManager
+   {
+     public:
+      ~MedDataManager();
+      void printFieldDouble(FIELD<double,FullInterlace> * field);
+   
+      %extend {
+        MedDataManager(char * fileName)
+        {
+         return new MedDataManager(string(fileName));
+        }
+        MedDataManager(MED * med)
+        {
+          return new MedDataManager(med);
+        }
+    
+        %newobject getFieldDouble(const char * fieldName, const int dt, const int it);
+        FIELD<double, FullInterlace> * getFieldDouble(const char * fieldName, const int dt, const int it)
+        {
+         return (FIELD<double, FullInterlace> *) self->getFieldDouble(string(fieldName), dt, it);
+        }
+      }
+  
+   };
+
+
+Utilisation de MEDMEM pour la manipulation de champs
+----------------------------------------------------
+
+Des opérations de manipulation de champs sont disponibles dans la
+bibliothèque MEDMEM standard est peuvent être utilisées dans
+l'interface python. Les quelques lignes suivantes illustrent l'usage
+qu'on peut en faire pour exécuter l'addition de deux champs sur tout
+leur espace de définition et pour un pas de temps donné:
+
+.. code-block:: python
+
+    from libMEDMEM_Swig import MedDataManager
+    from xmed.helper import readMed, writeMed
+
+    # Load the medmem data structure from a med file
+    med = readMed("/tmp/input.med")
+    # Then create a med data manager to deal with the fields data
+    dm  = MedDataManager(med)
+    # Get the timestamps (dt,it)=(-1,-1) of the fields "testfield1" and "testfield2"
+    f1 = dm.getFieldDouble("testfield1",-1,-1)
+    f2 = dm.getFieldDouble("testfield2",-1,-1)
+
+    # Create a new field as the sum of f1 and f2
+    r  = f1 + f2
+    # And add this new field to the med data structure
+    med.addField(r)
+
+    # Finally, write the whole data in an output med file
+    writeMed(med,"/tmp/output.med")
+
+.. note:: Cet exemple de code requiert les évolutions de MEDMEM
+   opérées dans la branche BR_medop (pour disposer de la classe
+   MedDataManager en particulier) et le package python ``xmed`` qui
+   fournit quelques fonctions utilitaires pour manoeuvrer les données
+   med (ce package est dans le module XMED et sera probablement à
+   terme intégré au module MED).
+
+Des limitations existent aujourd'hui pour ce type de manipulations:
+
+* les champs doivent partager le même support MED, c'est-à-dire être
+  décrit sur le même maillage et sur les mêmes entités de ce
+  maillage.
+* ...
+
+
+Remarque sur l'implémentation C++
+---------------------------------
+
+A noter l'usage de plusieurs formes d'arguments pour les fonctions:
+
+* passage des arguments par valeur ``myfunction(A a);``
+* passage des arguments par référence ``myfunction(A& a);``
+* passage des arguments par pointeur ``myfunction(A* a);``
+
+Le passage des arguments par référence est une facilité d'écriture
+pour éviter de passer un pointeur tout en évitant la récopie des
+données de la variable.
+
+.. _xmed-medmem_corbainterface:
+
+L'interface CORBA SALOME_MED
+============================
+
+Implémentation du composant MED et des servants SALOME_MED::\*
+--------------------------------------------------------------
+
+Le composant MED est un servant CORBA qui permet la manipulation de
+données MEDMEM dans l'environnement SALOME. Le composant peut fournir
+des pointeurs vers des instances de l'interface SALOME_MED (objets
+SALOMEMED::MED, SALOME_MED_FIELD, ...). Ces instances sont des
+servants CORBA qui résident dans le container et qui encapsulent les
+données MEDMEM.
+
+Le schéma ci-dessous représente les éléments informatiques qui
+composent l'architecture CORBA du module MED:
+
+.. image:: images/medmem-corba-layers.png
+   :align: center
+
+Les structures MEDMEM (données physiques) et SALOME_MED (wrapping
+CORBA) fonctionnent différement en ce qui concerne le chargement des
+données:
+
+* Dans MEDMEM, les données sont chargées à la demande (fonctions read
+  des objets) et aucune gestion n'est assurée. En particulier l'appel
+  à read alors que la donnée est déjà chargée conduit à une levée
+  d'exception. C'est à l'utilisateur de MEDMEM de prendre en charge ce
+  type de gestion.
+* Dans SALOME_MED, les données sont chargées à la création de
+  l'instance SALOME_MED::MED. Les maillages ainsi que les champs et
+  leurs données sont chargés à ce moment là et gérés dans une table de
+  type HashMap au niveau de la structure SALOME_MED::MED. Cette
+  structure remplie dés lors des fonction de gestion. L'appel à
+  SALOME_MED::MED.getField(...) ne charge pas les données mais renvoie
+  un pointeur SALOME_MED::FIELD_ptr sur les données chargées à
+  l'initialisation (ATTENTION, cette fonction est bugguée dans la
+  branche principale -> Fix dans la branche BR_medop).
+
+Une gestion intermédiaire peut être envisagée: le chargement à la
+demande géré dans une ou plusieurs tables de champs (une pour chaque
+type de valeur numérique). Une implémentation de ce type de gestion
+est illustré dans la classe ``MedDataManager`` du package MEDMEM qui prend
+en charge ce comportement pour les structures de données MED (en
+particulier les champs).
+
+Utilisation du composant MED
+----------------------------
+Le module SALOME MED fournit un module CORBA appelé SALOME_MED. Les
+interfaces de ce module CORBA sont spécifiées par les fichiers idl
+suivants:
+
+* le fichier
+  [http://nepal.der.edf.fr/pub/SALOME_userguide/MED5/doc/salome/tui/MED/MED_8idl.html
+  ``MED.idl``] qui décrit les interfaces des objets manipulés par le
+  module SALOME_MED. On trouve en particulier les objets MESH, SUPPORT
+  et FIELD.
+* le fichier
+  [http://nepal.der.edf.fr/pub/SALOME_userguide/MED5/doc/salome/tui/MED/MED__Gen_8idl.html
+  ``MED_Gen.idl``] qui décrit les interfaces du composant SALOME
+  (c'est-à-dire le composant chargé par la commande
+  ``FindOrLoadComponent("FactoryServer", "MED")`` du
+  lyfeCycleCorba). On trouve:
+
+  - l'interface ``MED_Gen_Driver`` qui hérite de SALOMEDS::Driver
+    pour l'implémentation des services généraux des composants SALOME
+    (persistance hdf, dump)
+  - l'interface ``MED_Gen`` qui hérite des interfaces
+    ``Engines::Component`` et ``MED_Gen_Driver`` pour
+    l'implémentation des services spécifiques du composant MED.
+
+L'implémentation de ces interfaces est faites au niveau de différents
+packages des sources du module MED:
+
+* Le package ``MEDMEM_I`` qui fournit l'implémentation C++ des
+  interfaces décrites par le fichier ``MED.idl``;
+* Le package ``MED`` qui fournit l'implémentation C++ des interfaces
+  décrites par le fichier ``MED_Gen.idl``, et qui correspond à la
+  partie composant classique d'un module SALOME.
+* Le package ``MedCorba_Swig`` qui fournit une interface swig
+  générée à partir de l'implémentation C++ de ``MEDMEM_I`` et
+  ``MED``
+
+L'utilisation peut être illustrée au moyen d'exemples python (i.e. qui
+utilise l'interface swig fournie par MedCorba_Swig). Après l'import
+d'amorce systématique:
+
+.. code-block:: python
+   
+   import salome
+   salome.salome_init()
+   
+   import SALOME_MED
+   from libSALOME_Swig import *
+
+On peut charger le composant SALOME MED:
+
+.. code-block:: python
+   
+   medComp=salome.lcc.FindOrLoadComponent("FactoryServer", "MED")
+
+grâce auquel les services de chargement de la structure MED peuvent
+être invoqués. Par exemple, les commandes suivantes chargent toute la
+structure MED dans l'étude salome passée en argument:
+
+.. code-block:: python
+   
+   filePathName = "myfile.med"
+   medComp.readStructFileWithFieldType(filePathName,salome.myStudyName)
+
+Ce deuxième exemple charge la structure MED mais ne place pas le résultat dans l'étude:
+
+.. code-block:: python
+   
+   filePathName = "myfile.med"
+   medObj = medComp.readStructFile(filePathName,salome.myStudyName)
+
+On récupère à la place un objet de classe |LINK_EDF_SALOME_MED__MED|_
+qui permet une utilisation assez semblable (mais différente on le
+verra plus bas) à MEDMEM:
+
+.. code-block:: python
+
+   fieldIdx     = 1 # WRN maybe there is no field of idx=1
+   iterationIdx = 0
+   fieldName = medObj.getFieldNames()[fieldIdx]
+   dtitfield = medObj.getFieldIteration(fieldName,iterationIdx)        
+   it = dtitfield[0]
+   dt = dtitfield[1]
+   fieldObj = medObj.getField(fieldName,it,dt)
+   nbOfFields = medObj.getNumberOfFields()
+   fieldNames = medObj.getFieldNames()
+    
+   mesh = fieldObj.getSupport().getMesh()
+
+.. note::
+   Observations en vrac:
+
+   * Un FIELD_i possède un champ de type ``MEDMEM::FIELD_`` qui représente
+     le champ informatique réel (objet MEDMEM).
+   * FIELD_i::fieldMap variable static de type map qui semble gérer
+     les différentes instances de FIELD_i (~pattern factory). Cette
+     map peut être requétée au moyen d'un indice de type long  appelé
+     corbaIndex.
+   * Quand on crée un FIELD_i par le constructeur d'argument
+     ``MEDMEM::FIELD_``, le ``MEDMEM::FIELD_`` est ajouté dans la map avec
+     incrément du corbaIndex
+   * La fonction FIELD_i::read(i) redirige vers la fonction read(i) du
+     ``MEDMEM::FIELD_`` associé
+   * A CONFIRMER: Il semble que les fonctions de chargement
+     ``readStructFile*()`` charge toutes les données du fichier med,
+     alors qu'en MEDMEM seules les meta-données sont chargées.
+   * A CONFIRMER: il semble que le chargement d'une structure MED
+     CORBA peut se faire sans passer par le composant (cf. l'interface
+     de MED)
+
+Interface avec le module VISU
+=============================
+
+Des interactions sont possibles entre MED et VISU à partir du moment
+où les données med sont gérées dans l'étude, c'est-à-dire sous la
+forme d'objets SALOME_MED (voir ci-dessus) publiés dans l'étude. Les
+deux conditions sont aujourd'hui nécessaires (objet corba + publié
+dans l'étude) mais il semble que ce ne soit lié qu'à un choix
+d'interface VISU (la fonction ``ImportMed`` en particulier) qui peut
+a priori être modifié. A CONFIRMER.
+
+L'exemple de code ci-dessous (en python, mais il peut être transposé à
+une implémentation C++) montre par exemple comment envoyer au module
+VISU  une requête de visualisation d'un champs hébergé par le module
+MED (en fait, les données sont gérées au travers d'un objet corba
+SALOME_MED "délocalisé" et qui a été référencé dans l'étude dans la
+catégorie du composant MED). Les importations standard (salome,
+SALOME_MED, ...) sont supposées avoir été faites au préalable (voir
+les exemples précédents):
+
+.. code-block:: python
+   
+   # Load the med structure using MED
+   medComp=salome.lcc.FindOrLoadComponent("FactoryServer", "MED")
+   filePathName = "myfile.med"
+   medComp.readStructFileWithFieldType(filePathName,salome.myStudyName)
+    
+   # Get the VISU component
+   import VISU
+   visuComp = salome.lcc.FindOrLoadComponent("FactoryServer", "VISU")
+   visuComp.SetCurrentStudy(salome.myStudy)
+    
+   # Get the sobject associated to the med object named "Med"
+   aSObject = salome.myStudy.FindObject("Med")
+   isPresent, medSObj = aSObject.FindSubObject(1)
+    
+   # Finally, import the med sobject in VISU 
+   result = visuComp.ImportMed(medSObj)
+
+Il est possible de d'aller plus loin et par exemple de déclencher
+l'affichage d'une scalarmap d'un champ spécifique pour une itération
+particulière (voir la fonction
+``TEST_SALOMEMED_requestToVisu_scalarmap`` du fichier
+``SALOMEMED_tester.py`` fourni dans les sources d'exemple).
+
+Liens complémentaires:
+
+* http://nepal.der.edf.fr/pub/SALOME_userguide/VISU_V5_1_3/doc/salome/gui/VISU La documentation utilisateur en ligne du module VISU
+
+
+Notes en vrac
+=============
+
+Questions:
+
+* Comment obtenir le nom du fichier med à partir d'une structure med? 
+* Peut-on imaginer un moyen de fournir l'objet MEDMEM::MED à partir de
+  la donnée de l'objet CORBA SALOME_MED::MED?
+
+Remarques:
+
+* A part, les opérations arithmétiques (+,-,*,/), aucune opération
+  n'est définie.
diff --git a/src/MEDOP/doc/sphinx/medop-prototype-overview.rst b/src/MEDOP/doc/sphinx/medop-prototype-overview.rst
new file mode 100644 (file)
index 0000000..c571c6e
--- /dev/null
@@ -0,0 +1,95 @@
+.. meta::
+   :keywords: maillage, champ, manipulation, XMED
+   :author: Guillaume Boulant
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+Démonstrateur XMED, vue d'ensemble
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+Le module XMED est un espace d'expérimentation pour le développement
+des opérations de manipulation de champs. Il complète des
+développements intégrés directement dans le module MED et gérés dans
+la branche CVS BR_medop.
+
+Une maquette est au point pour illustrer les propositions en matière
+d'ergonomie d'utilisation et en matière d'architecture technique. La
+maquette permet de réaliser des cas d'utilisation de la forme:
+
+* Chargement d'un fichier med dans le module MED (ou publication par
+  un code de calcul).
+* Sélection graphique des champs de l'étude à mettre à disposition
+  dans la console utilisateur ("calculette" en mode texte qui
+  concraitement correspond à l'interface python de SALOME).
+* Dans la calculette, exécution d'opérations algébriques (+,-,*,/)
+  entre champs avec possibilité d'utiliser des scalaires dans des
+  opérations de type transformation linéaire (y=ax+b ou y et x sont
+  des champs et a et b des scalaires). Egalement quelques fonctions
+  mathématiques standard applicables sur des champs (pow, sqrt).
+* Possibilité de visualiser les champs produits avec VISU
+* Possibilité d'exporter des champs produits dans un fichier med
+
+La figure ci-dessous montre le résultat d'une séquence d'utilisation
+dans laquelle les champs "testfield1" et "testfield2" ont été
+sélectionnés dans l'arbre d'étude pour être utilisés dans la console
+textuelle sous les noms de variables f1 et f2. L'image montre le
+contrôle visuel du résultat de l'opération f1+f2-(f1-f2)^2 tapée en
+ligne de commande:
+
+.. image:: images/medop-gui-result.png
+   :align: center
+
+La séquence ci-après montre le cas d'utilisation complet en
+images:
+
+1. Sélection d'un champs sur un pas de temps dans l'arbre d'étude
+2. Saisie d'un nom de variable (alias) pour manipuler ce champ. Par
+   défaut, le nom du champ est proposé (``testfield1`` ici). Dans
+   l'exemple, l'utilisateur remplace par l'alias ``f1``.
+3. Contrôle visuel du champ ``testfield1`` manipulé par sa variable
+   ``f1`` au moyen de la commande ``f1.visu()``
+4. Chargement du champ ``testfield2`` sous le nom ``f2``, exécution de
+   l'opération ``f1+f2-(f1-f2)^2`` et contrôle visuel du résultat,
+   récupéré ici dans une variable de nom ``result``.
+
+.. |IMG_SELECT| image:: images/medop-gui-selectfield_scale.png
+.. |IMG_ALIAS| image:: images/medop-gui-aliasfield_scale.png
+.. |IMG_VISU| image:: images/medop-gui-visufield_scale.png
+.. |IMG_RESULT| image:: images/medop-gui-result_scale.png
+
++---------------+---------------+ 
+| |IMG_SELECT|  | |IMG_ALIAS|   |
++---------------+---------------+ 
+| |IMG_VISU|    | |IMG_RESULT|  |
++---------------+---------------+ 
+
+La solution technique est construite sur les principes suivants:
+
+* Les données MEDMEM sont physiquement chargées par le composant MED,
+  c'est-à-dire dans le processus ``Container`` de SALOME, et sont
+  référencées dans l'étude SALOME.
+* Les opérations sont physiquement des opérations entre objets MEDMEM
+  purs qui ont lieu dans le composant MED.
+* Les opérations sont pilotées par des objets proxy python instanciés
+  dans la console TUI puis manipulés par l'utilisateur. Ces objets
+  proxy savent accéder aux objets MEDMEM au travers de leur interface
+  CORBA.
+
+Ainsi, l'architecture technique est construite pour pouvoir travailler
+sur des données MEDMEM pur en partant de pointeurs CORBA manoeuvrés
+depuis des objets python dans l'interface textuelle de
+SALOME. L'effort principal a donc porté sur la mise au point de
+l'interface technique qui permet de lier des variables représentant
+les champs au niveau du GUI (techniquement, la calculette est
+l'interpréteur python embarqué dans le GUI, étendu de quelques
+fonctions pour la manipulation de champs), alors que les données
+MEDMEM sont physiquement disponibles uniquement au niveau des
+composants CORBA (et les opérations implémentées dans MEDMEM
+uniquement).
+
+Pour le moment, la maquette est limitée à des operations entre champs
+qui partagent le même support med (contrainte de MEDMEM) et le
+résultat est calculé sur toutes les composantes et tout le domaine de
+définition du champs (cette deuxième contrainte est juste parce que
+les extentions n'ont pas encore été examinées). Enfin, le support de
+gestion des données est supposé être l'étude SALOME et la structure
+MED qui y est publiée.
diff --git a/src/MEDOP/doc/sphinx/medop-references.rst b/src/MEDOP/doc/sphinx/medop-references.rst
new file mode 100644 (file)
index 0000000..9be8cdc
--- /dev/null
@@ -0,0 +1,28 @@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+ANNEXE: Références documentaires
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+.. include:: medop-definitions.rst
+
+Documents de référence:
+
+* |REF_EDF_VCA_H-I2C-2009-03595-FR|_ - Valérie Cano - décembre 2009
+* |REF_CEA_VBE_MEDMEM|_ - Vincent Bergeaud - janvier 2007
+* |LINK_EDF_MEDDOC|_ - documentation en ligne (EDF)
+
+Présentations:
+
+* |REF_EDF_PRESMANIPCHP01|_ - Valérie Cano, Guillaume Boulant - janvier 2010
+* |REF_EDF_PRESMANIPCHP02|_ - Guillaume Boulant - octobre 2010
+* |REF_EDF_PRESMANIPCHP03|_ - Guillaume Boulant - mars 2011
+* Présentation à la Journée des Utilisateurs de SALOME de 2011 (JUS2011):
+
+  - |REF_EDF_JUS2011_PDF|_ - Anthony Geay (CEA), Guillaume Boulant - novembre 2011
+  - |REF_EDF_JUS2011_OGV1|_
+  - |REF_EDF_JUS2011_OGV3|_
+  - |REF_EDF_JUS2011_OGV4|_
+
+Notes de travail:
+
+* |REF_EDF_GBO_WORKNOTE|_ - Guillaume Boulant - novembre 2010
+* |REF_EDF_ELO_REM|_ - Eric Lorentz - novembre 2010
diff --git a/src/MEDOP/doc/sphinx/medop-specifications.rst b/src/MEDOP/doc/sphinx/medop-specifications.rst
new file mode 100644 (file)
index 0000000..09ca88c
--- /dev/null
@@ -0,0 +1,916 @@
+.. meta::
+   :keywords: maillage, champ, manipulation, med
+   :author: Guillaume Boulant
+
+.. include:: medop-definitions.rst
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+Module MED: Spécifications fonctionnelles et techniques
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+Ce texte présente les spécifications informatiques pour le
+développement d'un module de manipulation de champs qui répond à
+l'expression de besoins formulée dans le cahier des charges
+|REF_EDF_VCA_H-I2C-2009-03595-FR|_.
+
+.. contents:: Sommaire
+   :local:
+   :backlinks: none
+
+Description des cas d'application de référence
+==============================================
+
+Plusieurs cas d'applications métier sont identifiés pour piloter le
+développement du module de manipulation de champs:
+
+* **Analyser et post-traiter le résultat d'un calcul**. C'est l'usage
+  principal qui consiste typiquement à créer des champs comme le
+  résultat d'*opérations mathématiques* dont les opérandes sont des
+  champs et des scalaires. On compte également dans cette catégorie
+  les *opérations de restriction* qui permettent d'extraire puis
+  utiliser une partie d'un champs, c'est-à-dire de créer un champ
+  comme la restriction d'un autre champ à une partie de son domaine de
+  définition (certaines composantes, certains pas de temps, limitation
+  à un groupe de mailles).
+* **Comparer des champs issus d'un calcul paramétrique**. Il s'agit
+  d'une variante du cas précédent qui consiste à mesurer et visualiser
+  les variations entre des champs issues de sources de données
+  différentes (différents fichiers med).
+* **Préparer les conditions aux limites d'une calcul**. Il s'agit de
+  pouvoir initialiser un champ sur un maillage ou un groupe de
+  mailles, c'est-à-dire créer un champ de toute pièce sur un
+  support spatial donné, par exemple par la donnée d'une fonction
+  mathématique qui donne les valeurs des composantes en fonction des
+  coordonnées spatiales.
+* **Gérer des données de calcul**. Il s'agit typiquement de pouvoir
+  rassembler au sein d'un même fichier med des champs et des maillages
+  issues de différentes sources de données, et/ou créés au travers des
+  cas d'application présentés ci-dessus.
+
+Modèle conceptuel des données
+=============================
+
+On rappelle ici les concepts utilisés dans le module et les modalités
+d'utilisation de ces concepts. Le point de vue est celui de
+l'utilisateur du module de manipulation de champs. Il s'agit
+essentiellement pour le moment d'éclaircir l'ergonomie d'usage sur le
+plan conceptuel, avant d'aborder la déclinaison en spécifications
+techniques pour lesquelles les particularités du modèle MED devront
+être intégrées à la réflexion.
+
+Concept de champ
+----------------
+
+Le concept central est celui de *champ*, c'est-à-dire une grandeur
+physique exprimée sur un domaine spatial D. La grandeur peut être de
+type scalaire (une température), de type vectorielle (une vitesse) ou
+de type tensorielle (les contraintes). En un point de l'espace, elle
+se définie donc par la donnée d'une ou plusieurs valeurs numériques
+appelées les *composantes* (1 pour un champ scalaire, 3 pour un champ
+vectoriel 3D, 6 pour un champ tensoriel symétrique 3D).
+
+.. note:: Une pratique courante au niveau des codes est de stocker
+   plusieurs grandeurs physiques différentes dans un même champs med
+   (au sens informatique du terme). Par exemple, le champ
+   électromagnétique à 6 composantes, plus le champ de température
+   scalaire peuvent techniquement être stockés dans un même champs med
+   à 7 composantes. C'est pourquoi, le module de manipulation de
+   champs doit fournir des fonctions de restrictions qui permettent
+   d'extraire certaines composantes pour former la grandeur physique à
+   étudier. Dans la suite du document, on part du principe que l'on
+   peut se ramener dans tous les cas au cas d'un champ homogène tel
+   que défini plus haut.
+
+Dans le cadre d'un modèle numérique discret, les valeurs du champ sont
+exprimées pour un nombre fini de positions, qui correspondent à des
+lieux particuliers du maillage. Suivant la nature des modèles de
+calcul, les valeurs peuvent être données par cellule, par face, par
+noeud, aux points de gauss, ...
+
+Ainsi, un champ discret est un objet dont les valeurs peuvent être
+lues selon les dimensions suivantes:
+
+* *La position p dans l'espace*, caractérisée par le type de l'élément
+  de maillage support et son numéro identifiant
+* *La composante c*, caractérisée par son indice (jusqu'à 6
+  composantes dans les modèles physiques envisagés)
+
+L'évolution d'un champ dans le temps peut être exprimée sous la forme
+d'une série temporelle, c'est-à-dire une séquence de champs donnés
+pour des instants discrets. Aussi, si l'on manipule un champ qui varie
+dans le temps, l'accès aux valeurs introduit une dimension
+supplémentaire:
+
+* *Le temps t*, caractérisé par un numéro de pas de temps
+  (correspondant en général à une étape du calcul qui a produit le champ).
+
+.. note:: Il s'agit là d'une représentation conceptuelle standard dont
+   le |LINK_EDF_MEDDOC|_ fait une expression détaillée. En
+   particulier, la position p est déterminée par la donnée du type
+   d'élément support (valeurs aux noeuds, aux mailles, aux noeuds par
+   éléments, aux points de gauss) et de l'indice de cet élément. En
+   général, le type d'éléments support est résolu à l'initialisation
+   et l'indice peut suffire au repérage dans les algorithmes. Le temps
+   t est déterminé par un numéro d'itération, qui peut éventuellement
+   être complété par un numéro d'ordre. Le cas des points de gauss
+   ajoute un cran de complexité dans la mesure où il faut repérer
+   l'entité géométrique (maille, face, arrête) puis le point de gauss
+   de cette entité. A noter que dans le modèle MED, le concept de
+   série temporelle de champ n'est pas explicitement définie et
+   l'accès à des valeurs à différents instants t1 et t2 nécessite le
+   chargement des champs ``F1=F(t1)`` et ``F2=F(t2)``.
+
+Par convention, on utilisera par la suite les notations:
+
+* **U(t,p,c)** pour désigner la valeur de la composante c d'un champ U
+  à la position p et prise à l'instant t; 
+* **U(t,p,:)** pour signifier que l'on manipule l'ensemble de toutes
+  les composantes;
+* **U(t,:,c)** pour signifier que l'on manipule le domaine de
+  définition spatial complet. 
+
+Dans une grande majorité des cas d'usage on travaille à temps t fixé
+et sur un domaine spatiale prédéfini. Aussi on utilisera également la
+notation à deux arguments ``U(:,:)`` ou tout simplement ``U`` (dès
+lors qu'il n'y a pas ambiguïté) pour désigner un champ complet et Uc
+pour désigner la composante c du champ avec c=1..6.
+
+Concept d'opération
+-------------------
+Le deuxième concept à préciser est la notion d'*opération*. Une
+opération dans le présent contexte est l'application d'un opérateur
+sur un ou plusieurs champs pour produire une grandeur de type champ ou
+de type valeur numérique.
+
+Par exemple, la formule ``W=OP(U,V)`` indique que le champ W est formé
+à partir des champs U et V en arguments d'une fonction OP. Dans le cas
+d'une opération algébrique comme l'addition (cf. :ref:`Spécification
+des opérations<xmed-specifications>`, le résultat attendu par défaut
+est que pour chaque instant t, chaque position p et chaque composante
+c, on a ``W(t,p,c)=U(t,p,c)+V(t,p,c)`` (que l'on peut noter également
+``W(:,:,:)=U(:,:,:)+V(:,:,:)`` compte-tenu de la convention présentée
+plus haut). Ce n'est cependant pas une règle et l'utilisateur peut
+très bien manoeuvrer les champs en détaillant et mixant les
+composantes (par exemple ``W(:,:,3)=5+U(:,:,1)*V(:,:,2)``), ou encore
+ne travailler que sur un domaine spatial et/ou temporel particulier
+(cf. |REF_EDF_VCA_H-I2C-2009-03595-FR|_ §5.4.1).
+
+On formalise donc le concept d'opération par les propriétés suivantes:
+
+* L'opérateur peut produire un champ (par exemple la somme de deux
+  champs W=sum(U,V)=U+V), une valeur numérique (par exemple la moyenne
+  spatiale d'un champ m=smoy(U)) ou une valeur logique (par exemple le
+  test d'égalité de deux champs b=isequal(U,V));
+* L'opérateur peut être paramétré par la donnée de valeurs numériques
+  (par exemple, le changement d'unité peut être défini comme une
+  multiplication par un scalaire V=multiply(U,1000)=1000*U);
+* L'opérateur est caractérisé par un domaine d'application qui
+  spécifie la portée de l'opération. Ce domaine comporte plusieurs
+  dimensions:
+  - Un domaine temporel T qui spécifie les pas de temps sur lesquels
+    l'opération est appliquée;
+  - Un domaine spatial D qui spécifie la limite de portée de
+    l'opérateur et donc le domaine de définition du champ produit (qui
+    correspond dans ce cas à une restriction du domaine de définition
+    des champs en argument);
+  - Un domaine de composantes C qui spécifie les composantes sur
+    lesquelles l'opération est appliquée;
+
+.. note::
+   Sur le plan informatique, l'opérateur aura également un paramètre
+   appelé *option* qui pourra indiquer par exemple dans une
+   opération unaire V=F(U) si le résultat V est une nouvelle instance
+   de champ ou la valeur modifiée du champ de départ U. Il pourra
+   également être amené à manoeuvrer des paramètres de type chaîne de
+   caractères, par exemple pour les opérations de changement de nom
+   des champs.
+
+De manière générale, on utilisera la notation
+**(W|y)=OP[D,C,T](P,U,V,...)** pour désigner une opération OP:
+
+* **(V|y)**: V ou y désignent respectivement un résultat de type
+  champ ou de type valeur numérique ou logique;
+* **[T,D,C]**: le domaine d'application de l'opérateur avec T le
+  domaine temporel, D le domaine spatial et C le domaine des
+  composantes;
+* **P,U,V,...**: les paramètres numériques P (liste de valeurs
+  numériques) et les champs U,V,... en arguments de l'opérateur;
+
+On note également les particularités suivantes pour certaines
+opérations:
+
+* Le domaine de définition du champ produit par une opération peut
+  être différent du domaine de définition des champs en argument. Par
+  exemple, dans le cas d'une opération de projection de champ, le
+  domaine spatial résultat peut être modifié par rapport au domaine de
+  définition initial, soit par la modification de la zone géométrique,
+  soit par modification des entités de maillage support.
+* En dehors des opérations de type dérivée et intégrale, les valeurs
+  résultats sont déterminées de manière locale en chaque point du
+  domaine d'application. Par exemple, l'addition W=U+V consiste à
+  produire un champ W dont les valeurs en chaque point p sont la somme
+  des valeurs des composantes de U et V en ce point p: ``W=U+V <=>
+  W(:,p,:)=U(:,p,:)+V(:,p,:)`` pour tout point p du domaine
+  d'application D.
+
+Concept de domaine d'application
+--------------------------------
+
+Un domaine d'application est associé à une opération (et non pas à un
+champ). Il a pour objectif de restreindre la portée de l'opération en
+terme spatial, temporel, jeu des composantes.
+
+Pour ce qui concerne le domaine spatial D, plusieurs modalités de
+définition sont envisagées:
+
+* la donnée d'un maillage ou d'un groupe d'éléments du maillage;
+* un système de filtres qui peut combiner:
+
+  - une zone géométrique définie indépendamment du maillage (boîte
+    limite par exemple),
+  - des critères conditionnant le calcul (par exemple U(t,p,c)=1 si
+    V(t,p,c)<seuil).
+
+.. warning:: Version 2010: D pourra correspondre au maillage complet
+   et dans la mesure du possible à un groupe d'éléments du maillage
+
+Ce domaine d'application peut être différent du domaine de définition
+des champs mais il doit être compatible (recouvrement spatial partiel
+au moins et même support d'entité de maillage). Ainsi, sans précision
+particulière, une opération s'applique à l'ensemble du domaine de
+définition des champs en argument (qui dans la pratique MED est
+spécifié par le support et correspond en général au maillage
+complet).
+
+Limites d'utilisation
+---------------------
+
+Plusieurs situations doivent être examinées pour poser les limites
+d'utilisation:
+
+* Les champs en argument n'ont pas tous le même domaine de définition,
+  par exemple parcequ'il ne sont pas définis sur les mêmes zones
+  géométriques ou parcequ'ils ne sont pas donnés sur le même type
+  d'entité de maillage. On peut imaginer dans ce cas produire le
+  résultat sur les zones de recouvrement uniquement.
+* Le domaine de définition des champs et le domaine d'application de
+  l'opérateur ne sont pas compatibles, par exemple parcequ'on demande
+  une restriction sur une zone géométrique qui ne fait pas partie de
+  la zone de définition du champ d'entrée. A priori, ce type
+  d'opération est déclaré en échec.
+* Les champs en argument ne sont pas définis sur les mêmes pas de
+  temps. Si l'opération est tolérée (techniquement MEDCoupling permet
+  de le faire), le pas de temps résultat est indéfini.
+
+.. warning:: **A faire**: spécifier les modalités de prise en compte de
+   ces différentes situations (au moins sur le plan conceptuel).
+
+Au delà de ces limites conceptuelles, il faut avoir en tête les
+limites techniques liées à l'usage de MED mémoire (paquet
+MEDCoupling). Par exemple, MEDCoupling impose que les champs opérandes
+soient définis sur le même maillage support (on parle ici de l'objet
+informatique correspondant au maillage). Deux champs construits sur le
+même maillage (du point de vue conceptuel) mais issus de deux fichiers
+med différents sont considérés comme des champs définis sur des
+maillages support différents, c'est-à-dire que les objects
+informatiques correspondant aux maillages sont différents (chargés de
+deux fichiers différents). En l'état, il est donc impossible par
+exemple de faire la comparaison de champs résultats d'une étude
+paramétriques. MEDCoupling fournit une solution qu'il faudra mettre en
+oeuvre de manière ergonomique au niveau du module MED. Il est possible
+de changer le maillage support M1 d'un champs par un maillage M2 à
+partir du moment où les maillages M1 et M2 sont identiques
+géométriquement à une erreur près qu'il est possible de spécifier.
+
+.. note:: 
+   D'autres situations limites peuvent être évoquées sous l'angle
+   informatique. Ce sont des situations qui a priori n'ont pas de
+   raison d'exister sur le plan conceptuel mais qui peuvent très bien
+   survenir au niveau du module informatique compte-tenu des
+   particularités du modèle MED. Par exemple:
+   
+   * Le nombre et la nature des composantes ne sont pas identiques
+     pour tous les champs d'entrée. Par exemple, U défini ses
+     composantes comme U(:,:,1)=Ux, U(:,:,2)=Uy, U(:,:,3)=Uz et V les
+     défini comme U(:,:,1)=Uz, U(:,:,2)=Ux, U(:,:,3)=Uy. Cette
+     situation peut être gérée techniquement par exemple au moyen
+     d'une carte de correspondance qui accompagnerai chacun des champs
+     pour exprimer le sens physique de chaque composants (histoire de
+     ne pas ajouter des choux et des carottes).
+
+Spécifications générales
+========================
+
+Le diagramme ci-dessous représente un découpage fonctionnel qui rend
+compte de l'expression des besoins:
+
+.. image:: images/xmed-functions.png
+   :align: center
+
+On peut identifier les fonctionnalités suivantes:
+
+* **Opérations**: fonctions de manipulation de champs proprement
+  dites;
+* **Persistance**: fonctions d'enregistrement persistant et de
+  chargement des données (au format med fichier)
+* **Visualisation**: fonctions de contrôle visuel des champs
+  manipulés
+* **Export des données**: fonction de transposition des données de
+  champs dans un format textuel directement exploitable et de manière
+  autoportante dans une autre application, par exemple en python au
+  moyen des structures de données Numpy.
+
+Ces fonctions s'articulent autour d'un conteneur qui héberge les
+champs manipulés et les supports de ces champs (représenté par le
+cylindre central).
+
+Un scénario d'utilisation type est:
+
+* Préparation des champs à manipuler, par deux moyens complémentaires:
+
+  - Utilisation des fonctions de persistance: chargement depuis un
+    fichier med d'un ensemble de champs qui partagent le même espace
+    de définition;
+  - Utilisation des opérations de champs: chargement d'un maillage
+    depuis un fichier med, puis création ab initio de champs au moyen
+    des opérations de champs;
+
+* Manipulation des champs par application des opérations à
+  disposition, puis contrôle visuel des résultats produits au moyen
+  des fonctions de visualisation mises à disposition par SALOME;
+* Restitution des résultats produits, par deux moyens complémentaires:
+
+  - Restitution des champs produits et/ou modifiés sous une forme
+    persistante (fichier med);
+  - Restitution d'une partie seulement des résultats sous forme de
+    tableaux de valeurs sauvegardés dans un fichier texte ou exporté
+    sous forme de tableau numpy
+
+.. _xmed-specifications:
+
+Spécification des opérations
+============================
+
+Le cahier des charges définit trois catégories d'opérations
+mathématiques:
+
+* **Les opérations arithmétiques**, dans lesquelles le résultat à la
+  position p et à l'instant t ne dépend que des données à la position
+  p et à l'instant t;
+* **Les opérations d'interpolations**, dans lesquelles le résultat
+  est exprimé sur des entités de maillages différentes ou est projeté
+  sur une zone géométrique différente du domaine de définition
+  initial;
+* **Les opérations globales**, dans lesquelles le résultat peut
+  demander l'agrégation des valeurs sur plusieurs position p ou
+  plusieurs pas de temps t (calcul d'extremum, d'intégrale);
+
+Auxquelles, on peut ajouter à des fins de gestion des données:
+
+* **Les opérations de génération**, qui permettent de créer un champ
+  sur un maillage vierge ou d'étendre le domaine spatial de définition
+  d'un champ;
+* **Les opérations d'ordre sémantique**, qui permettent de modifier
+  les méta-données associées aux champs (nom, unité, ...)
+* **Les opérations de diagnostic**, qui permettent d'effectuer une
+  analyse particulière d'un champ et/ou des éléments de maillage
+  associés et de fournir un compte-rendu, sous la forme d'une
+  structure de données ou d'un texte formaté affichable dans
+  l'interface utilisateur.
+
+La suite de la section décrit les spécifications prévues pour chaque
+type d'opération unitaire. Un dernier paragraphe concerne les
+modalités de combinaison des opérations et spécifie la définition d'un
+domaine d'application sur une opération, qui permet de restreindre la
+portée de l'opération en terme spatial, temporelle ou nature des
+composantes impliquées.
+
+Les opérations arithmétiques
+----------------------------
+
+Les opérations arithmétiques regroupent:
+
+* les **opérations algébriques** (+, -, x, /);
+* les **opérations vectorielles** (produit scalaire, produit
+  vectoriel, produit tensoriel);
+* l'**application d'une fonction mathématique** à variable scalaire
+  (exponentielle, logarithme, fonctions trigonométriques, valeur
+  absolue, partie entière) ou à variable de type champ (les fonctions
+  de norme par exemple).
+
+Pour les besoins des spécifications informatiques, il est plus commode
+de classer ces opérations en deux catégories:
+
+* les **opérations unaires**, qui prennent un opérande unique en
+  argument. C'est le cas de la plupart des fonctions mathématiques
+  envisagées;
+* les **opérations binaires**, qui prennent deux opérandes en
+  argument. C'est le cas des opérations algébriques et des opérations
+  vectorielles.
+A partir de cette classification, il convient de distinguer trois
+formes d'usage selon la nature des opérandes:
+
+* les opérandes sont exclusivement des scalaires (typiquement des
+  valeurs de composantes des champs et des paramètres numériques). Par
+  exemple::
+    W(:,:4) = 1+2xU(:,:,2)+V(:,:,3)
+
+* les opérandes sont exclusivement des champs. Par exemple::
+
+    W = U + V       (addition)
+    W = U ^ V       (produit vectoriel)
+
+* les opérandes sont des champs et des paramètres numériques. Par exemple::
+
+    W = 3xU - 2xV
+    W = U + 2
+
+Le premier cas de figure (opérandes scalaires) est trivial car les
+règles mathématiques conventionnelles s'appliquent et sont
+implémentées dans tous les langages (Python et C++ en
+particulier). Les cas 2 et 3 par contre doivent être précisés car (i)
+les règles de comportement ne peuvent pas être simplement déduites des
+règles mathématiques (quel est le résultat de ``W = U + 2`` ?) et
+(ii) certaines écritures ne peuvent avoir aucun sens (par exemple
+``W = 2 / U``). Il convient donc de  préciser les conventions et
+les limites sur ces deux cas de figure.
+
+Dans le cas des opérations unaires où l'opérande est un champ, on doit
+distinguer deux cas d'usage:
+
+* l'application d'une fonction mathématique à valeur de type champ. Ce
+  cas est trivial également et on applique la règle d'usage de la
+  fonction. C'est typiquement le cas des fonctions de calcul de
+  norme.
+* l'application d'une fonction mathématique à valeur scalaire. Dans ce
+  cas, on convient d'appliquer la fonction de manière unitaire sur
+  chacune des composantes c du champ: ``W(:,:,c) = OP( U(:,:,c)
+  )``
+
+Dans le cas des opérations binaires, on recense les combinaisons
+d'opérandes suivantes (les lettres capitales représentent des champs,
+et les lettres minuscules une valeur scalaire qui peut être un
+paramètre numérique ou la composante d'un champ):
+
+* U+V ajoute les composantes en regard: W(:,:,c)=U(:,:,c)+V(:,:,c)
+* U-V soustrait les composantes en regard: W(:,:,c)=U(:,:,c)-V(:,:,c)
+* U*V multiplie les composantes en regard: W(:,:,c)=U(:,:,c)*V(:,:,c)
+* U/V divise les composantes en regard: W(:,:,c)=U(:,:,c)/V(:,:,c)
+* U+x ajoute x à toute les composantes: W(:,:,c)=U(:,:,c)+x
+* U*x multiplie toutes les composantes par x: W(:,:,c)=U(:,:,c)*x
+* U.V produit scalaire des champs U et V: W(:,:c)=U(:,:,c)*V(:,:,c)
+* U^V produit vectoriel des champs U et V: W(:,:1)=U(:,:,2)*V(:,:,3)-U(:,:,3)*V(:,:,2), ...
+
+.. note::
+   Pour ce qui concerne les opérations vectorielles, un convention
+   implicite est appliquée par laquelle on suppose que les composantes
+   sont rangées dans l'ordre des dimensions spatiales U1=Ux, U2=Uy,
+   U3=Uz. Sur le plan informatique au niveau du modèle MEDMEM, ceci
+   n'est pas garanti et aucun élément du modèle ne permet de
+   contraindre l'application de cette convention. Il convient donc de
+   prévoir des fonctions techniques qui permettront de mettre en
+   correspondance les indices de composantes et les dimensions
+   spatiales (par exemple par la données d'une carte de correspondance
+   applicable à un ensemble de champs).
+
+.. warning::
+   A développer:
+   
+   * Analyse dimensionnelle du champ résultats pour adapter
+     l'unité. Par exemple, si on fait UxV où U et V sont exprimés en
+     [m] alors le résultat est en [m2].
+
+Les opérations d'interpolation
+------------------------------
+.. warning:: Non prévues au programme 2010.
+
+Les opérations mathématiques globales
+-------------------------------------
+.. warning:: Non prévues au programme 2010.
+
+Les opérations de génération
+----------------------------
+.. warning:: EN TRAVAUX
+
+Les opérations de génération sont des fonctions qui permettent de
+créer un champ sur un domaine du maillage où il n'est pas défini
+initialement. Deux cas de figure peuvent se présenter:
+
+* Le champ n'existe pas et il doit être créé sur un domaine à définir;
+* Le champ existe mais les valeurs ne sont pas définies sur l'ensemble
+  du maillage.
+
+On peut envisager plusieurs modalités de mise en oeuvre:
+
+* le prolongement par une valeur constante (ou plus généralement par
+  une fonction de l'espace?);
+* les valeurs du champs sont données par une fonction f(p,t) qui prend
+  la position p et le pas de temps t en argument;
+* on peut prédéfinir le champ position **r** qui porte les
+  coordonnées spatiales de l'élément de maillage support, puis faire
+  une opération arithmétique standard.
+
+Les opérations d'ordre sémantique
+---------------------------------
+.. warning:: EN TRAVAUX
+
+Concerne:
+
+* le changement de nom du champ
+* le changement d'unité du champ (il s'agit ici de conserver la
+  cohérence entre la valeur numérique et l'attribut "unité" d'un
+  champ.
+
+Les opérations de diagnostic
+----------------------------
+.. warning:: EN TRAVAUX. A faire en fonction des besoins des cas d'application
+
+On peut identifier plusieurs types d'opérations:
+
+* les opérations à diagnostic booléen, par exemple
+  b=isequal(U,V)=[U=V] (où [.] signifie évaluation de la condition
+  entre crochers)
+* les opérations à diagnostic textuel, par exemple afficher les
+  méta-données associées à un champs (unité, nom, maillage support,
+  type d'entité, pas de temps, ...)
+* les opérations à diagnostic structuré, qui donneraient une structure
+  de données exploitable au niveau d'un code logiciel.
+
+Combinaison des opérations
+--------------------------
+.. warning:: EN TRAVAUX. Indiquer les règles de combinaison (associativité, commutativité, ...)
+
+Définition d'un domaine d'application
+-------------------------------------
+Pour rappel, un domaine d'application peut être associé à une
+opération pour restreindre la portée de l'opération en terme spatial,
+temporelle ou nature des composantes impliquées.
+
+.. warning:: Todo: spécifier comment on le définit et les modalités d'applications.
+
+Spécification de l'ergonomie
+============================
+
+L'ergonomie générale d'utilisation du module de manipulation de champs
+est inspirée des logiciels comme octave ou scilab. Elle associe une
+interface graphique, pour sélectionner et préparer les données, avec
+une interface texte (la console python) pour le travail effectif sur
+les données:
+
+* L'**interface graphique** a pour fonction essentielle de sélectionner et
+  préparer les champs à manipuler dans l'interface texte, puis
+  fournit des fonctions pour la gestion générale des données
+  (chargement, sauvegarde, contrôle visuel, export).
+* L'**interface texte** offre un jeu de commandes pour manipuler les
+  champs (afficher les données, effectuer des opérations), piloter les
+  fonctions d'affichage (contrôle visuel au moyen des modules VISU
+  et/ou PARAVIS) et communiquer avec l'interface graphique (ajouter
+  des nouveaux champs dans l'espace de gestion, mettre à jour les
+  méta-données d'un champ).
+
+Sur le plan de l'ergonomie, cela se traduit par un processus de
+travail dans lequel on peut distinguer différentes phases:
+
+* Une phase de préparation des champs à manoeuvrer sous la forme de
+  variables nommées et simples à manipuler dans l'interface
+  textuelle. Lors de cette phase, l'utilisateur spécifie de manière
+  graphique tout ce qui peut être définis à l'avance et pour toute la
+  durée du processus de travail. Par exemple, en spécifiant le nom des
+  fichiers med source des données et les noms des champs à utiliser
+  dans ces fichiers, le pas de temps de travail, le jeu des
+  composantes à considérer, le domaine d'application des opérations;
+* Une phase de manipulation des champs proprement dite, qui a lieu
+  principalement dans l'interface textuelle, et qui peut s'accompagner
+  de contrôle visuel des résultats et/ou d'export à destination
+  d'outils complémentaires indépendants (gnuplot, python, ...);
+* Une phase de restitution des champs produits pour assurer la
+  persistance des données de travail. Tout les champs créés par les
+  manipulations au niveau de l'interface textuelle ne sont pas à
+  sauvegarder, et on on propose donc à l'utilisateur les moyens de
+  choisir les champs à conserver. Cette phase peut amener
+  l'utilisateur à préciser les informations manquantes, comme les noms
+  de fichiers, les noms de champs produits, les unités, ...
+
+Dans ce cadre, l'utilisation type des fonctions de manipulation de
+champs est un processus de la forme suivante:
+
+1. Chargement d'un fichier med dans SALOME et exploration du contenu,
+   composé de maillages, sur lesquels sont définis des champs, pouvant
+   contenir un ou plusieurs pas de temps.
+2. Sélection (graphique) des champs à manipuler, avec la possibilité
+   de préciser des restrictions d'utilisation (pas de temps,
+   composantes, groupe de maille).
+3. Création de nouveaux champs par l'exécution d'opérations
+   algébriques (+,-,*,/) entre champs, l'application de fonctions
+   mathématiques standard (pow, sqrt, abs), ou encore l'initialisation
+   "from scratch" à partir d'un maillage support.
+4. Contrôle visuel rapide des champs produits (avec les modules VISU
+   et/ou PARAVIS de SALOME, pilotés automatiquement depuis l'interface
+   utilisateur)
+5. Enregistrement d'une partie des champs produits dans un fichier med
+
+
+Les espaces de données utilisateur
+----------------------------------
+
+Sur le plan conceptuel, on est amené à définir deux espaces de données
+utilisateur:
+
+* **l'espace des données source** (*dataspace*), dans lequel
+  l'utilisateur définit les sources de données med (*datasource*),
+  c'est-à-dire les fichiers med dans lesquels sont lus les champs
+  et maillages. Cet espace est en lecture seule et permet
+  l'exploration des sources de données (aperçu des maillages et des
+  champs).
+* **l'espace des données de travail** (*workspace*), dans lequel
+  l'utilisateur dépose les champs et maillages à utiliser, puis range
+  les champs produits au travers des fonctions de manipulation de
+  champs.
+
+La figure ci-dessous en donne une représentation imagée avec le
+support de l'interface graphique du module (interface non définitive
+affichée ici pour illustration des spécifications):
+
+.. image:: images/xmed-gui-withframe.png
+   :align: center
+
+.. note:: Techniquement, les données sources sont rangées dans l'étude
+   SALOME et peuvent être explorées au moyen de l'object browser. Les
+   données de travail sont rangées dans un arbre complémentaire et
+   manipulable dans la console python.
+
+Le principe général est que **les données sources ne sont jamais
+modifiées**. Le dataspace est un espace de chargement qui permet
+d'explorer puis de sélectionner les données à manipuler. L'utilisateur
+travaille à partir de maillages et de champs chargés préalablement
+dans cet espace, mais ne peut en aucun cas les modifier
+directement. Pour cela, il doit d'abord les sélectionner pour
+utilisation dans l'espace de travail. Ce choix garantie l'intégrité
+des sources de données et permet de rejouer la séquence de travail à
+partir de zéro en cas de besoin (on efface le tableau noir et on
+recommence). Par ailleurs, il permet d'assister graphiquement la
+définition du champs à manipuler effectivement, en particulier pour
+affecter un nom de variable de manipulation.
+
+Les captures d'écrans suivantes montrent le principe d'utilisation sur
+le cas de la sélection d'un pas de temps à utiliser dans l'espace de
+travail. Les données à manoeuvrer (maillage et/ou champs) sont
+sélectionnées pour utilisation dans l'espace de travail, où elles
+peuvent être modifiées et/ou utilisées dans les opérations de
+champs. Ici, le champ est désigné par la varibale ``f4`` dans
+l'interface textuelle:
+
+* Sur cette première capture, on sélectionne le pas de temps n°4 du
+  champs ``Pulse`` définit sur le maillage ``Grid_80x80`` de la source
+  de données ``timeseries.med`` (concrètement le fichier
+  ``timeseries.med``) pour faire apparaître ensuite le menu contextuel
+  et choisir l'option "Use in workspace":
+
+.. image:: images/xmed-gui-datasource-contextmenu_70pc.png
+   :align: center
+
+* Cette capture montre une fenêtre de dialogue qui invite
+  l'utilisateur à spécifier un alias pour la variable python qui
+  va permettre la manipulation du champ dans l'interface textuelle de
+  l'espace de travail (par défaut, le nom complet du champ est
+  proposé). Ici, l'utilisateur spécifie ``f4``: 
+
+.. image:: images/xmed-gui-datasource-useinworkspace_70pc.png
+   :align: center
+
+* La validation de la fenêtre provoque l'ajout du champs dans l'espace
+  de travail (le champ est désormais disponible à la manipulation) et
+  définit une variable python de nom ``f4`` qui permet la manipulation
+  du champ:
+
+.. image:: images/xmed-gui-datasource-useinworkspace-result_70pc.png
+   :align: center
+
+Modalités d'utilisation
+-----------------------
+
+.. warning:: cette section est à nettoyer car elle contient des
+   informations redondantes avec d'autres sections précédentes ou pire
+   qui contredisent des sections précédentes.
+
+Dans le cadre défini ci-dessus, une session d'utilisation type est:
+
+* Sélectionner les sources de données puis définir le domaine
+  d'application (espace, temps, composantes), avec éventuellement
+  l'assistance d'une interface graphique;
+* Charger les champs en conséquence dans l'espace de travail. Cette
+  opération propose de définir une variable python pour manipulation
+  dans l'interface textuelle.
+* Effectuer les opérations dans l'espace de travail, c'est-à-dire en
+  ligne de commandes python (ce qui demandera sans doute un travail
+  conséquent de simplification et d'assistance en ligne). Par exemple,
+  si ``fa`` et ``fb`` désignent deux champs définis dans l'espace de
+  travail, alors on peut en faire la somme par la commande::
+  
+  >>> r=fa+fb
+
+* Effectuer les contrôles visuel et les diagnostics en ligne de
+  commandes python (cf. :ref:`Spécification des fonctions de
+  visualisation<specification_visualisation>`)::
+
+  >>> view(r)
+
+* Enregistrer les champs produits dans l'espace de travail sous forme
+  de fichier med.
+
+Sur cette base, on peut envisager une grande variété de cas d'utilisation:
+
+* La structure MED (champs, maillage et groupes de mailles) est
+  chargée dans le dataspace (l'étude SALOME techniquement) et peut
+  être explorée au niveau de l'arbre d'étude. L'arbre peut faire
+  apparaître:
+  - les maillages et les groupes (qui peuvent être utilisés
+    éventuellement pour restreindre le domaine d'application)
+  - les champs dont on peut explorer les composantes et les itérations
+
+* On sélectionne plusieurs champs, éventuellement en sélectionnant les
+  pas de temps, les composantes et les domaines d'application spatiaux
+* Menu contextuel --> Modifier un champ, Créer un champ, Prolonger un
+  champ, ....
+* On choisi pour la suite "Créer un champ", une fenêtre de dialogue
+  s'affiche avec les saisies préremplies avec les données
+  sélectionnées. Il est possible de rajouter des éléments ou préciser
+  le domaine d'application
+* Une partie de la boîte de dialogue est réservée à la saisie de la
+  ligne de commande python qui permet la création du nouveau champ. Le
+  nom dans l'étude pour le nouveau champ, ainsi que son nom python,
+  sont spécifié par l'utilisateur ({{H|un peu à la mode du module
+  system}}).
+* L'opération est exécutée dans l'espace utilisateur (l'interface
+  python), de sorte que les variables soient projetées dans cet espace
+  et manipulables après l'opération au besoin. Par ailleurs,
+  l'utilisateur peut visualiser les ligne de commandes nécessaires à
+  taper pour exécuter sa requête.
+
+.. _specification_visualisation:
+
+Spécification des fonctions de visualisation
+============================================
+
+Dans le cadre du module MED, on appelle *fonction de visualisation*
+une fonction qui permet d'avoir un aperçu graphique d'un champ, par
+exemple au moyen d'une carte de champ construite sur une de ses
+composante. Il s'agit là de vue de contrôle pour avoir une idée rapide
+de la forme du champs. Pour créer des représentations spécifiques, on
+préférera passer par les fonctions d'export vers le module PARAVIS.
+
+Les modules VISU et PARAVIS offre des interface de programmation C++
+et python qui permettent le pilotage depuis un module tiers comme le
+module MED. On peut donc envisager une fonction de visualisation
+intégrée au module de manipulation de champs, c'est-à-dire que l'on
+déclenche sans sortir du module MED, et qui exploite les fonctions de
+visualisation des modules VISU et/ou PARAVIS.
+
+Les captures d'écran ci-dessous illustrent la mise en oeuvre de la
+fonction de visualisation:
+
+* Sélection d'un champ pour faire apparaitre le menu contextuel et
+  choisir l'option "Visualize":
+
+.. image:: images/xmed-gui-datasource-visualize_70pc.png
+   :align: center   
+
+* Cette option déclenche l'affichage d'une carte de champ sur le cadre
+  d'affichage des viewers SALOME:
+
+.. image:: images/xmed-gui-datasource-visualize-result_70pc.png
+   :align: center
+
+Cette fonction est également disponible en ligne de commandes de
+l'interface textuelle. Par exemple si ``f4`` désigne un champ de
+l'espace de travail (importé des données source ou construit par les
+opérations de champs), alors, on obtient une carte de champ par la
+commande::
+
+ >>> view(f4)
+
+On peut remarquer d'ailleurs sur la capture d'écran de droite
+ci-dessus que la demande de visualisation déclenche l'exécution de la
+commande ``view`` dans la console de travail sur un champ identifié
+par son numéro (3 dans l'exemple).
+
+.. note:: Tous les champs, qu'ils soient des champs chargés d'une
+   source de données ou construits par des opérations de champs sont
+   identifiés par un numéro unique et invariant tout au long de la
+   session de travail.
+
+Spécification des fonctions de persistance
+==========================================
+
+On adopte le principe de fonctionnement suivant:
+
+* Le module n’assure pas la persistence au sens SALOME du terme,
+  c’est-à-dire qu’il ne permet pas la sauvegarde du travail dans une
+  étude au format hdf, ni le dump sous la forme de script python
+  SALOME. Le besoin n'est pas avéré et on peut même dire que ça n'a
+  pas de sens compte-tenu de l'usage envisagé pour le module MED.
+* Par contre, le module fournit des fonctions de sauvegarde du travail
+  sous forme de fichiers med, l’export vers les modules VISU et
+  PARAVIZ, ou même la sauvegarde de l’historique de l’interface de
+  commandes.
+
+Ainsi donc, l'utilisateur aura une fonction (probablement graphique)
+pour définir la sélection des champs de l'espace de travail à
+sauvegarder.
+
+Spécification des fonctions d'export
+====================================
+
+.. warning:: EN TRAVAUX.
+
+Plusieurs export peuvent être proposés:
+
+* Export des champs vers le module PARAVIZ, dans l'objectif par
+  exemple d'en faire une analyse visuelle plus poussée qu'avec les
+  cartes de champs disponibles par défaut dans le module MED
+* Export des données sous forme de tableau numpy, par exemple pour
+  permettre un travail algorithmique sur les valeurs des champs.
+
+Spécifications techniques
+=========================
+
+Il s'agit d'exprimer ici les contraintes techniques applicables à la
+conception et au développement du nouveau module MED.
+
+Implantation technique du module
+--------------------------------
+
+Il est convenu que le module MED existant dans la plate-forme SALOME
+incarne le module de manipulation de champ. Dans la pratique, il
+s'agit d'identifier clairement les parties à conserver, d'une part,
+puis les parties à re-écrire, d'autre part. On peut partir sur les
+hypothèses techniques suivantes:
+
+* Le noyau du module en charge des opérations de manipulation de
+  champs proprement dites est construit sur la base des paquets
+  logiciels MEDCoupling (lui-même basé sur le INTERP_KERNEL) et
+  MEDLoader.
+* L'interface graphique du module MED est complétement re-écrite et
+  remplacée par une interface adaptée spécialement à la manipulation
+  des champs et la gestion des données associées
+* Le contrôle visuel pourra être déclenché dans les visualisateurs
+  SALOME (servis par les modules VISU et/ou PARAVIZ);
+* Le module n'assure pas la persistence au sens SALOME du terme,
+  c'est-à-dire qu'il ne permet pas la sauvegarde du travail dans une
+  étude au format hdf, ni le dump sous la forme de script python
+  SALOME.
+* Par contre, il fournit des fonctions de sauvegarde du travail sous
+  forme de fichiers med, l'export vers les modules VISU et PARAVIZ, ou
+  même la sauvegarde de l'historique de l'interface de commandes.
+
+L'implantation technique des développements est représentée sur la
+figure ci-dessous:
+
+.. image:: images/xmed-implantation.png
+   :align: center
+
+Le schéma représente les packages logiciels qui composent le module
+MED (cf. |REF_CEA_VBE_MEDMEM|_):
+
+* La partie MEDMEM, représentées en blanc. Cette partie est conservée
+  pour compatibilité ascendante au niveau des applications métier qui
+  ont fait le choix historique de s'appuyer sur MEDMEM. Cette partie
+  du module MED aura tendance à disparaitre dans le futur au bénéfice
+  de MEDCoupling et MEDLoader.
+* La partie MEDCoupling, représentée en orange et qui founrnit le
+  modèle MED mémoire de référence (composé de maillage et de champs)
+  et l'interface de programmation pour manipuler le modèle. Le paquet
+  MEDLoader est une extention dédiée à la persistence au format med
+  fichier (lecture et écriture de champs et de maillage dans des
+  fichiers med).
+* La partie à développer pour la manipulation de champ, représentée en
+  bleu.
+
+.. note:: MEDCoupling peut être vu comme une structure de donnée
+   particulièrement adaptée à la manipulation des gros volumes de
+   données, en particulier par l'exploitation des possibilités de
+   parallélisation et la réduction de la tailles des structures de
+   données. En contrepartie, elle peut présenter un périmètre
+   fonctionnel moins large que MEDMEM. Pour cette raison, MEDMEM avait
+   été choisi comme socle de développement du prototype en 2010:
+
+   * MEDCoupling ne permet pas de gérer des maillages composés de
+     plusieurs type de mailles et il est exclus de le faire évoluer
+     dans ce sens (c'est un choix fait pour les objectifs de
+     performances évoqués plus haut);
+   * MEDCoupling ne permet pas de gérer les supports qui expriment les
+     champs aux noeuds par élément ni aux points de gauss. Cette
+     seconde limitation a disparu en 2011.
+
+   Aujourd'hui, on fait clairement le choix de MEDCoupling pour sa
+   qualité et sa robustesse, dans l'objectif d'une meilleure
+   maintenance à long terme. Par ailleurs, les différences
+   fonctionnelles avec MEDMEM, si elles existaient encore en 2012 pour
+   les besoins de la manipulation de champs, pourront être résorbées
+   dans un futur proche.
+
+
diff --git a/src/MEDOP/doc/sphinx/medop-userguide.rst b/src/MEDOP/doc/sphinx/medop-userguide.rst
new file mode 100644 (file)
index 0000000..bf00e8b
--- /dev/null
@@ -0,0 +1,748 @@
+.. meta::
+   :keywords: maillage, champ, manipulation, guide utilisateur
+   :author: Guillaume Boulant
+
+.. include:: medop-definitions.rst
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+Module MED: Guide d'utilisation de l'interface graphique
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+Ce document est un guide rapide pour l'utilisation de l'interface
+graphique du module MED. Il montre comment utiliser le module sur la
+base de quelques exemples de référence, inspirés des cas d'utilisation
+identifiés lors de l'analyse des besoins en matière de manipulation de
+champs.
+
+.. warning:: Le document est autonome, mais il est vivement conseillé
+   de parcourir au préalable (ou en parallèle) :doc:`le document de
+   spécifications<medop-specifications>`, au moins pour fixer les
+   concepts et la terminologie.
+
+.. contents:: Sommaire
+   :local:
+   :backlinks: none
+
+Présentation générale du module MED
+===================================
+
+L'ergonomie générale d'utilisation du module de manipulation de champs
+est inspirée des logiciels comme octave ou scilab. Elle associe une
+interface graphique, pour sélectionner et préparer les données, avec
+une interface texte (la console python) pour le travail effectif sur
+les données.
+
+Pour cela, le module propose deux espaces utilisateurs qui sont
+symbolisés par les rectangles rouges et vert sur la capture d'écran
+ci-dessous:
+
+* **l'espace des données** (*dataspace*), dans lequel l'utilisateur
+  définit les sources de données med (*datasource*), c'est-à-dire les
+  fichiers med dans lesquels sont lus les champs et maillages. Cet
+  espace permet l'exploration des maillages et des champs fournis par
+  les différentes sources de données.
+* **l'espace de travail** (*workspace*), dans lequel l'utilisateur
+  peut déposer des champs sélectionnées dans l'espace source, pour
+  ensuite les travailler par exemple pour produire des nouveaux champs
+  au moyen des fonctions de manipulation fournies par l'interface
+  textuelle (console python TUI).
+
+.. image:: images/xmed-gui-withframe.png
+   :align: center
+
+L'utilisation type des fonctions de manipulation de champs suit un
+processus de la forme suivante:
+
+1. Chargement d'un fichier med dans l'espace de données (dataspace) et
+   exploration du contenu, composé de maillages et de champs définis
+   sur ces maillages et pouvant contenir un ou plusieurs pas de temps.
+2. Sélection (graphique) des champs à manipuler dans l'espace de
+   travail (workspace), avec la possibilité de préciser des
+   restrictions d'utilisation (pas de temps, composantes, groupe de
+   maille).
+3. Création de nouveaux champs par l'exécution d'opérations
+   algébriques (+,-,*,/) entre champs, l'application de fonctions
+   mathématiques standard (pow, sqrt, abs), ou encore l'initialisation
+   "from scratch" sur un maillage support.
+4. Contrôle visuel rapide des champs produits (avec les modules VISU
+   et/ou PARAVIS de SALOME, pilotés automatiquement depuis l'interface
+   utilisateur)
+5. Enregistrement d'une partie des champs produits dans un fichier med
+
+
+Tour rapide des fonctions du module MED
+=======================================
+
+Cette section présente des exemples d'utilisation du module XMED sous
+la forme de "storyboard", et illustre au passage les fonctions mises à
+disposition par le module.
+
+.. warning:: Cette section est en travaux. Tant que cet avis n'aura
+   pas disparu, veuillez en considérer le plan et le contenu encore
+   incomplets, temporaires et sujets à caution.
+
+Exemple 1: Explorer des sources de données
+------------------------------------------
+
+.. note:: Cet exemple présente les fonctions:
+
+   * ajouter une source de données
+   * fonctions "Extends field series", "Visualize"
+
+.. |ICO_DATASOURCE_ADD| image:: images/ico_datasource_add.png
+                        :height: 16px
+
+.. |ICO_XMED| image:: images/ico_xmed.png
+              :height: 16px
+
+.. |ICO_DATASOURCE_EXPAND| image:: images/ico_datasource_expandfield.png
+                           :height: 16px
+
+.. |ICO_DATASOURCE_VIEW| image:: images/ico_datasource_view.png
+                         :height: 16px
+
+Au démarrage, le module de manipulation de champs, identifié par
+l'icône |ICO_XMED|, présente une interface vierge:
+
+.. image:: images/xmed-gui-start.png
+   :align: center
+   :width: 800px
+
+La première étape consiste à ajouter une ou plusieurs source de
+données med dans le "dataspace". Pour cela, on clique sur l'icône "Add
+datasource" |ICO_DATASOURCE_ADD| qui propose de sélectionner un
+fichier med:
+
+.. image:: images/xmed-gui-datasource-selectfile.png
+   :align: center
+   :width: 800px
+
+L'opération ajoute une nouvelle entrée (datasource) dans l'espace de
+données (dataspace). Le contenu peut être exploré en parcourant
+l'arborescence. La figure ci-dessous (image de gauche) montre le
+résultat du chargement du fichier ``timeseries.med`` contenant un
+maillage de nom ``Grid_80x80`` sur lequel est défini un champ au noeud
+de nom ``Pulse``. Par défaut, la composition du champs (en terme de
+pas de temps et de composantes) n'est pas affichée pour éviter
+l'encombrement visuel de l'arbre. On doit faire la demande explicite
+au moyen de la commande "Expand field timeseries"
+|ICO_DATASOURCE_EXPAND| disponible dans le menu contextuel associé aux
+champs. Le résultat est affiché sur l'image centrale. La liste des
+itérations du champ ``Pulse`` peut être consultée.
+
+.. |IMG_DATASOURCE_EXPLORE| image:: images/xmed-gui-datasource-explore-zoom.png
+                            :height: 340px
+.. |IMG_DATASOURCE_MENUCON| image:: images/xmed-gui-datasource-menucontextuel-zoom.png
+                            :height: 340px
+.. |IMG_DATASOURCE_EXPANDF| image:: images/xmed-gui-datasource-expand-zoom.png
+                            :height: 340px
+
++--------------------------+--------------------------+--------------------------+
+| |IMG_DATASOURCE_EXPLORE| | |IMG_DATASOURCE_MENUCON| | |IMG_DATASOURCE_EXPANDF| |
++--------------------------+--------------------------+--------------------------+
+
+.. note:: En toute rigueur, le concept de *champ* dans le modèle MED
+   désigne une itération donnée. Un ensemble d'itérations est désigné
+   par le terme *série temporelle de champs*. Par abus de langage, et
+   s'il n'y a pas ambiguité, on utilisera le nom du champ pour
+   désigner à la fois le champs proprement dit ou la série temporelle
+   à laquelle il appartient.
+
+Enfin, il est possible au niveau du dataspace de visualiser la forme
+générale du champ au moyen d'une carte scalaire affichée dans le
+viewer de SALOME. Pour cela, on sélectionne le pas de temps à
+visualiser et on utilise la commande "Visualize" |ICO_DATASOURCE_VIEW|
+disponible dans le menu contextuel associé:
+
+.. image:: images/xmed-gui-datasource-visualize-zoom.png
+   :align: center
+   :width: 800px
+
+.. note:: Cette représentation graphique a pour objectif le contrôle
+   visuel rapide. Aussi, les fonctions du module VISU sont employées
+   par défaut, mais il est possible de faire l'affichage des cartes
+   scalaires au moyen du module PARAVIS (choix de préférence non
+   implémenté pour le moment, mais techniquement réalisable).
+
+Exemple 2: Rassembler des champs issus de différentes sources
+-------------------------------------------------------------
+
+.. note:: Cet exemple présente les fonctions:
+
+   * fonction "Use in workspace"
+   * fonction "Save"
+
+.. |ICO_DATASOURCE_USE| image:: images/ico_datasource_use.png
+                        :height: 16px
+.. |ICO_WORKSPACE_SAVE| image:: images/ico_workspace_save.png
+                        :height: 16px
+
+L'objectif est de récupérer des données issues de différents fichiers
+med, puis de les rassembler dans un même fichier en sortie.
+
+On commence par ajouter les sources de données med dans l'espace de
+données (dataspace). Dans l'exemple ci-dessous, l'espace de données
+contient deux sources de nom ``parametric_01.med`` et
+``smallmesh_varfiled.med``. La première source contient le maillage
+``Grid_80x80_01`` sur lequel est défini le champ ``StiffExp_01``. La
+deuxième source contient le maillage ``My2DMesh`` sur lequel sont
+définis deux champs de noms respectifs ``testfield1`` et
+``testfield2``:
+
+.. image:: images/xmed-userguide-example2-datasource.png
+   :align: center
+   :width: 800px
+
+Pour l'exemple, on souhaite rassembler les champs ``StiffExp_01`` et
+``testfield2`` dans un fichier de nom ``result.med``. La procédure
+consiste à importer les deux champs dans l'espace de travail
+(workspace), puis à sauvegarder l'espace de travail. Pour cela, on
+sélectionne les champs et on utilise la commande "Use in workspace"
+|ICO_DATASOURCE_USE| disponible dans le menu contextuel. Les deux
+champs sélectionnés apparaissent dans l'arborescence de l'espace de
+travail:
+
+.. image:: images/xmed-userguide-example2-workspace.png
+   :align: center
+   :width: 800px
+
+La sauvegarde de l'espace de travail est faite au moyen de la commande
+"Save workspace" |ICO_WORKSPACE_SAVE| disponible dans la barre
+d'outils du module. Une fenêtre de dialogue invite l'utilisateur à
+spécifier le nom du fichier de sauvegarde:
+
+.. image:: images/xmed-userguide-example2-workspace-save.png
+   :align: center
+   :width: 800px
+
+Ce fichier ``result.med`` peut ensuite être rechargé dans le module
+XMED (ou les modules VISU ou PARAVIS) pour vérifier la présence des
+champs sauvegardés.
+
+.. BUG: plantage à l'utilsation dans XMED d'un fichier rechargé
+.. (invalid mesh on field)
+
+.. _xmed.userguide.exemple3:
+
+Exemple 3: Appliquer une opération mathématique sur des champs
+--------------------------------------------------------------
+
+.. note:: Cet exemple présente les fonctions:
+
+   * exécution d'opérations mathématiques dans la console TUI
+   * fonction "put" pour référencer un champ de travail dans la liste
+     des champs persistant.
+   * fonction "Visualize" depuis le TUI.
+
+L'usage le plus courant du module de manipulation de champs est
+d'exécuter des opérations mathématiques dont les opérandes sont des
+champs ou des composantes de ces champs.
+
+On se place dans une situation où les sources de données sont définies
+dans le "dataspace" (dans l'exemple ci-après, une série temporelle de
+nom ``Pulse``, contenant 10 pas de temps, définis sur un maillage de
+nom ``Grid_80x80``, le tout issu du datasource ``timeseries.med``).
+
+Comme vu précedemment, pour manoeuvrer un champ dans l'espace de
+travail, on sélectionne ce champ, puis on exécute la commande "Use in
+workspace" |ICO_DATASOURCE_USE| du menu contextuel. Dans le cas
+présent, un seul champ est sélectionné (contre deux dans l'exemple
+précédent) et la commande ouvre alors une fenêtre de dialogue qui
+permet de préciser les données sur lesquelles on souhaite
+effectivement travailler et comment on veut les manoeuvrer:
+
+.. image:: images/xmed-gui-datasource-useinworkspace-alias.png
+   :align: center
+   :width: 800px
+
+.. note:: En l'état actuel du développement, l'interface propose
+   uniquement de définir le nom de la variable sous laquelle doit être
+   manoeuvré le champ dans la console de travail (TUI). Dans une
+   version ultérieure, il est prévue de pouvoir préciser la ou les
+   composante du champs à utiliser et un groupe de maille pour définir
+   une restriction géométrique. Inversement, il sera également
+   possible de choisir une série temporelle complète pour faire des
+   opérations globales sur l'ensemble des pas de temps.
+
+Aprés validation, le champ est placé dans l'arborescence du
+"workspace" et une variable de nom ``<alias>`` est créée
+automatiquement dans la console de travail pour désigner le
+champ. Dans cet exemple, ``<alias>`` vaut ``f3``, positionné ainsi par
+l'utilisateur pour rappeler que la variable correspond au pas de temps
+n°3:
+
+.. image:: images/xmed-gui-workspace.png
+   :align: center
+   :width: 800px
+
+La manipulation peut commencer. Dans l'exemple ci-dessous, on crée le
+champ ``r`` comme le résultat d'une transformation afine du champ
+``f3`` (multiplication du champ par le facteur 2.7 auquel on ajoute
+l'offset 5.2)::
+
+ >>> r=2.7*f3+5.2
+
+On peut poursuivre la manipulation du champs avec une variété
+d'opérations qui sont détaillées dans les spécifications du module
+(cf. :ref:`Spécification des opérations<xmed-specifications>`):
+
+ >>> r=f3/1000     # les valeurs de r sont celles du champ f3 réduites d'un facteur 1000
+ >>> r=1/f3        # les valeurs de r sont les inverses des valeurs de f3
+ >>> r=f3*f3       # les valeurs de r sont celles du champ f3 élevées au carré
+ >>> r=pow(f3,2)   # même résultat
+ >>> r=abs(f3)     # valeur absolue du champ f3
+ >>> ...
+
+Les opérations peuvent utiliser plusieurs opérandes de type champs. Si
+``f4`` désigne le pas de temps n°4 du champ ``Pulse``, alors on peut
+calculer toute combinaison algébrique des deux champs::
+
+ >>> r=f3+f4
+ >>> r=f3-f4
+ >>> r=f3/f4
+ >>> r=f3*f4
+
+Avec au besoin l'utilisation de variables scalaires::
+
+ >>> r=4*f3-f4/1000
+ >>> ...
+
+Dans ces exemples, la variable ``r`` désigne un champ de travail qui
+contient le résultat de l'opération. Par défaut, ce champ de travail
+n'est pas référencé dans l'arborescence du workspace. Si on souhaite
+tout de même le référencer, par exemple pour qu'il soit pris en compte
+dans la sauvegarde, alors on tape la commande::
+
+ >>> put(r)
+
+La fonction ``put`` a pour but de marquer le champ en argument comme
+persistent, puis de le ranger dans l'arborescence du "workspace" afin
+qu'il soit visible et sélectionnable. En effet, parmi tous les champs
+qui pourront être créés dans la console pendant la session de travail,
+tous n'ont pas besoin d'être sauvegardés. Certains sont même des
+variables temporaires qui servent à la construction des champs
+résultats finaux. C'est pourquoi, seuls les champs rangés dans
+l'arborescence du workspace sont enregistrés lors de la demande de
+sauvegarde du workspace.
+
+Les variables définies dans la console ont d'autres utilités. Tout
+d'abord, elles permettent d'imprimer les informations concernant le
+champ manoeuvré. Pour cela, on tape simplement le nom de la variable
+puis retour::
+
+ >>> f3
+ field name (id)        = Pulse (3)
+ mesh name (id)         = Grid_80x80 (0)
+ discretization         = ON_NODES
+ (iter, order)          = (3,-1)
+ data source            = file:///home/gboulant/development/projets/salome/MEDOP/XMED/xmed/resources/datafiles/timeseries.med
+
+Elle peut également être utilisée comme argument des commandes de
+gestion disponibles dans l'interface textuelle (dont la liste
+détaillée est décrite à la section :ref:`Documentation de l'interface
+textuelle<xmed.userguide.tui>`). Par exemple, la fonction ``view``
+permet d'afficher la carte scalaire du champ dans le viewer::
+
+ >>> view(f3)
+
+Donne:
+
+.. image:: images/xmed-gui-workspace-view.png
+   :align: center
+   :width: 800px
+
+.. note:: On remarquera ici qu'il est facile de comparer deux pas de
+   temps d'un champ, par exemple en calculant la différence ``f3-f4``,
+   puis en affichant un aperçu de la carte scalaire résultat au moyen
+   de la fonction ``view``::
+
+    >>> view(f3-f4)
+
+On peut enfin tout simplement afficher les données du champs par la
+commande ``print``::
+
+ >>> print f3
+ Data content :
+ Tuple #0 : -0.6 
+ Tuple #1 : -0.1 
+ Tuple #2 : 0.4 
+ Tuple #3 : -0.1 
+ Tuple #4 : 0.4 
+ ...
+ Tuple #6556 : 3.5 
+ Tuple #6557 : 3.3 
+ Tuple #6558 : 1.5 
+ Tuple #6559 : 0.3 
+ Tuple #6560 : 0.2
+
+Il est important de noter que les opérations entre champs ne peuvent
+être faites qu'entre champs définis sur le même maillage. Il s'agit là
+d'une spécification du modèle MED qui interdit d'envisager les
+opérations entre champs définis sur des maillages géométriquement
+différents. Techniquement, cela se traduit par l'obligation pour les
+objets informatique *champs* de partager le même objet informatique
+*maillage*.
+
+Dans l'hypothèse où on souhaite utiliser des champs définis sur des
+maillages différents, par exemple pour manoeuvrer les valeurs des
+champs à l'interface de deux maillages partageant une zone géométrique
+2D, il faut d'abord ramener tous les champs sur le même maillage de
+surface par une opération de projection.
+
+.. note:: Même si ceci est techniquement possible avec la bibliothèque
+   MEDCoupling, cet type d'opération de projection n'est pas encore
+   disponible dans le module de manipulation de champs (prévu en
+   2012).
+
+Un autre besoin plus classique est l'utilisation de champs définis sur
+des maillages géométriquement identiques, mais techniquement
+différents, par exemple lorsqu'ils sont chargés de fichiers med
+différents. Pour traiter ce cas de figure, la bibliothèque MEDCoupling
+prévoit une fonction de "Changement du maillage support", dont
+l'utilisation au niveau du module de manipulation de champs est
+illustrée dans :ref:`l'exemple 4<xmed.userguide.exemple4>` ci-après.
+
+.. _xmed.userguide.exemple4:
+
+Exemple 4: Comparer des champs issues de différentes sources
+------------------------------------------------------------
+
+.. note:: Cet exemple présente les fonctions:
+
+   * Changement du maillage support "change underlying mesh"
+
+On se place ici dans le cas de figure où des champs ont été produits
+sur le même maillage, au sens géométrique, mais enregistrés dans des
+fichiers med différents. C'est le cas par exemple d'une étude
+paramétrique où plusieurs calculs sont effectués avec des variantes
+sur certains paramètres du modèle simulé, chaque calcul produisant un
+fichier med.
+
+Soit ``parametric_01.med`` et ``parametric_02.med`` deux fichiers med
+contenant les champs que l'on souhaite comparer, par exemple en
+calculant la différence des valeurs et en visualisant le résultat.
+
+Aprés le chargement des sources de données dans le module XMED,
+l'utilisateur se trouve en présence de deux maillages, au sens
+technique du terme cette fois-ci, c'est-à-dire que les champs sont
+associées à des objets informatiques maillage différents, bien que
+géométriquement identiques.
+
+Or, les fonctions de manipulation de champs ne permettent pas les
+opérations sur des champs dont les maillages supports sont différents
+(voir la remarque à la fin de :ref:`l'exemple
+3<xmed.userguide.exemple3>`).
+
+Pour résoudre ce cas de figure, le module de manipulation de champs
+met à disposition la fonction "Change underlying mesh" qui permet de
+remplacer le maillage support d'un champ par un autre à partir du
+moment où les deux maillages sont géométriquement identiques,
+c'est-à-dire que les noeuds ont les mêmes coordonnées spatiales.
+
+.. |ICO_DATASOURCE_CHG| image:: images/ico_datasource_changeUnderlyingMesh.png
+                        :height: 16px
+
+Dans l'exemple proposé, l'utilisateur sélectionne le premier pas de
+temps du champ ``StiffExp_01`` du "datasource" ``parametric_01.med``,
+puis l'importe dans l'espace de travail au moyen de la commande "Use
+in workspace" |ICO_DATASOURCE_USE|. Il sélectionne ensuite le premier
+pas de temps du champs ``StiffExp_02`` du "datasource"
+``parametric_02.med``, mais l'importe dans l'espace de travail au
+moyen de la commande "Change underlying mesh" |ICO_DATASOURCE_CHG|. La
+fenêtre de dialogue ci-dessous s'affiche et invite l'utilisateur à
+choisir le nouveau maillage support par sélection dans l'arborescence
+du "dataspace":
+
+.. image:: images/xmed-gui-datasource-changeUnderlyingMesh.png
+   :align: center
+
+Dans cet exemple, on sélectionne le maillage ``Grid_80x80_01`` support
+du champ ``StiffExp_01``, avec lequel on souhaite faire la
+comparaison. Après validation, l'arborescence du workspace contient le
+champ ``StiffExp_02`` défini sur le maillage ``Grid_80x80_01``:
+
+.. image:: images/xmed-gui-datasource-changeUnderlyingMesh_wsview.png
+   :align: center
+
+.. note:: La fonction "Change underlying mesh" ne modifie pas le champ
+  sélectionné dans le "dataspace" (principe de base de fonctionnement
+  du dataspace), mais crée une copie du champ dans l'espace de travail
+  pour ensuite remplacer le maillage support. D'où le nom par défaut
+  pour le champ ``dup(<nom du champ sélectionné>)`` (dup pour
+  "duplicate").
+
+Il reste à associer une variable à ce champ pour le manipuler dans la
+console. Ceci peut être fait au moyen de la commande "Use in console",
+disponible dans le menu contextuel du workspace.
+
+En définitif, si ``f1`` désigne le champ issu du datasource
+``parametric_01.med`` et ``f2`` le champ issu du datasource
+``parametric_02.med`` par la procédure décrite ci-dessus, alors la
+comparaison des deux grandeurs peut être faite comme pour le cas de
+:ref:`l'exemple 3<xmed.userguide.exemple3>`::
+
+ >>> r=f1-f2
+ >>> view(r)
+
+.. note:: En remarque générale sur cet exemple, il convient de noter
+   les points suivants:
+
+   * l'égalité géométrique de deux maillages est établie à une marge
+     d'erreur prés qu'il est possible de définir techniquement, mais
+     qui n'est pas ajustable au niveau de l'interface du module de
+     manipulation de champs. Elle est fixée à une valeur standard qui
+     permet de traiter la plupart des cas utilisateur. On verra à
+     l'usage s'il est nécessaire de remonter ce paramètre au niveau de
+     l'interface.
+   * L'utilisateur doit faire la démande explicite de changer le
+     maillage support d'un champ, en prévision de la comparaison de
+     champs issus de datasource différentes. Il s'agit là d'un choix
+     fonctionnel délibéré pour que l'utilisateur garde trace des
+     modifications faites sur les données (pas de modification
+     automatiques à l'insu de l'utilisateur, même sous prétexte
+     d'amélioration de l'ergonomie).
+
+
+Exemple 5: Créer un champ sur un domaine spatial
+------------------------------------------------
+
+.. note:: Cet exemple présente les fonctions:
+
+   * initialisation par une fonction de la position spatiale
+   * initialisation sur un groupe de maille
+
+Le domaine géométrique de définition du champs à créer est spécifié
+ici par la donnée d'un groupe de mailles. Ce cas d'usage est
+typiquement prévu pour produire les conditions de chargement initial
+d'une structure, par exemple en définissant un champ sur une surface
+de la géométrie, identifiée par un nom de groupe de mailles.
+
+.. warning:: DEVELOPPEMENT EN COURS
+
+Exemple 6: Extraire une partie d'un champ
+-----------------------------------------
+
+.. note:: Cet exemple présente les fonctions:
+
+   * extraire une composante (ou un sous-ensemble des composantes)
+   * extraire un domaine géométrique (valeurs sur un groupe de maille)
+   * extraire un ou plusieurs pas de temps.
+
+.. warning:: DEVELOPPEMENT EN COURS
+
+   On doit illustrer ici les fonctions de restriction, qui
+   permettraient de récupérer certaines composantes uniquement. Le
+   principe est qu'on crée un nouveau champ qui est une restriction du
+   champ argument à une liste de composantes à spécifier (utiliser la
+   fonction __call__ des fieldproxy).
+
+Pour l'extraction des pas de temps, on peut se ramener au cas de
+l'exemple 2 avec une seule source de donnée.
+
+Exemple 7: Créer un champ à partir d'une image to[mp]ographique
+---------------------------------------------------------------
+
+.. note:: Cet exemple présente les fonctions:
+
+   * Création d'un champ sans datasource (ni maillage, ni champs), à
+     partir d'un fichier image
+
+En tomographie ou en topographie, les appareils de mesure produisent
+des images qui représentent une grandeur physique en niveaux de gris
+sur un plan de coupe donné. L'image ci-dessous représente par exemple
+une vue interne du corps humain faite par IRM:
+
+.. image:: images/xmed-irm.png
+   :align: center
+   :width: 600px
+
+Cette image est un ensemble de pixels organisés sur une grille
+cartesienne. Elle peut donc être modélisée sous la forme d'un champ
+scalaire dont les valeurs sont définies aux cellules d'un maillage
+réglés de même taille que l'image (en nombre de pixels):
+
+.. image:: images/xmed-irm-field.png
+   :align: center
+   :width: 600px
+
+Le module de manipulation de champ fournit un utilitaire appelé
+``image2med.py`` qui permet d'appliquer ce principe à la conversion
+d'un fichier image en fichier med contenant la représentation de
+l'image sous forme d'un champ scalaire (seul le niveau de gris est
+conservé)::
+
+  $ <xmed_root_dir>/bin/salome/xmed/image2med.py -i myimage.png -m myfield.med
+
+.. |ICO_IMAGESOURCE| image:: images/ico_imagesource.png
+                        :height: 16px
+
+Cette opération de conversion peut être faite automatiquement dans
+l'interface graphique du module au moyen de la commande "Add Image
+Source" |ICO_IMAGESOURCE| disponible dans la barre d'outils. Cette
+commande ouvre la fenêtre suivante pour inviter l'utilisateur à
+choisir un fichier image:
+
+.. image:: images/medop_image2med_dialog.png
+   :align: center
+
+Le nom du fichier med résultat est proposé par défaut (changement de
+l'extention en ``*.med``) mais il peut être modifié. Enfin, on peut
+demander le chargement automatique du fichier med produit pour ajout
+dans l'espace de donnée. Les champs peuvent alors être manipulés comme
+dans les cas d'utilisation standard.
+
+Par exemple, l'image ci-dessous affiche le résultat de la différence
+entre deux images, ajoutée à l'image de référence: si i1 et i2
+désignent les champs créés à partir des deux images, on représente ``r
+= i1 + 5*(i2-i1)`` où le facteur 5 est arbitraire et sert à amplifier
+la zone d'intérêt (en haut de l'oeil gauche):
+
+.. image:: images/xmed-irm-diff.png
+   :align: center
+   :width: 600px
+
+L'exemple ci-dessous est le résultat du chargement d'une image
+tomographique issue du projet MAP (Charles Toulemonde,
+EDF/R&D/MMC). L'image tomographique:
+
+.. image:: images/champ_altitude_MAP.png
+   :align: center
+   :width: 600px
+
+Le résultat du chargement:
+
+.. image:: images/medop_image2med_tomographie.png
+   :align: center
+   :width: 800px
+
+Exemple 8: Continuer l'analyse dans PARAVIS
+-------------------------------------------
+
+.. note:: Cet exemple présente les fonctions:
+
+   * Export de champs vers le module PARAVIS.
+
+Les possibilités de représentation graphique des champs fournies par
+le module MED ont pour seul objectif le contrôle visuel rapide. Par
+défaut, le viewer de VISU est employé.
+
+Pour une analyse plus détaillées des champs, il est nécessaire de
+poursuivre le travail dans PARAVIS. Le module de manipulation de
+champs offre une fonction qui simplifie ce passage, en faisant le
+chargement automatique dans PARAVIS et en proposant une visualisation
+par défaut (carte de champs scalaire).
+
+Pour cela, il faut sélectionner dans l'espace de travail les champs à
+exporter, puis déclencher la fonction d'export depuis le menu
+contextuel associé:
+
+.. image:: images/medop_exportparavis.png
+   :align: center
+
+Les champs sélectionnés sont regroupés dans une entrée MED du
+navigateur PARAVIS, et le premier champ est affiché sous forme de
+carte de champ:
+
+.. image:: images/medop_exportparavis_result.png
+   :align: center
+   :width: 800px
+
+.. note:: La fonction d'export est une fonction de confort. La même
+   opération peut être faite manuellement en procédant d'abord à
+   l'enregistrement des champs sous forme de fichier MED, puis en
+   chargeant le fichier généré dans le module PARAVIS pour
+   visualisation.
+
+.. _xmed.userguide.tui:
+
+Utilisation de l'interface textuelle du moduel MED (TUI)
+========================================================
+
+Toutes les opérations menées au moyen de l'interface graphique peuvent
+être réalisées (avec plus ou moins de facilité) avec l'interface
+textuelle. Le module de manipulation de champs peut même être utilisé
+exclusivement en mode texte. Pour cela, on lance la commande::
+
+ $ <path/to/appli>/medop.sh
+
+Cette commande ouvre une console de commandes ``medop>``. Un fichier
+med peut être chargé et travaillé, par exemple pour créer des champs à
+partir des données du fichier.
+
+Que l'on soit en mode texte pur ou en mode graphique, un séquence de
+travail type dans la console peut ressembler au jeu d'instructions
+suivantes::
+
+ >>> load("/path/to/mydata.med")
+ >>> la
+ id=0    name    = testfield1
+ id=1    name    = testfield2
+ >>> f1=get(0)
+ >>> f2=get(1)
+ >>>   ls
+ f1      (id=0, name=testfield1)
+ f2      (id=1, name=testfield2)
+ >>> r=f1+f2
+ >>> ls
+ f1      (id=0, name=testfield1)
+ f2      (id=1, name=testfield2)
+ r       (id=2, name=testfield1+testfield2)
+ >>> r.update(name="toto")
+ >>> ls
+ f1      (id=0, name=testfield1)
+ f2      (id=1, name=testfield2)
+ r       (id=2, name=toto)
+ >>> put(r)
+ >>> save("result.med")
+
+Les commandes principales sont:
+
+* ``load``: charge un fichier med dans la base de données (utile
+  uniquement en mode texte pur)::
+
+  >>> load("/path/to/datafile.med")
+
+* ``la``: affiche la liste de tous les champs chargés en base de données ("list all")
+* ``get``: définit un champ dans l'espace de travail à partir de son
+  identifiant (utile plutôt en mode texte pur car l'interface
+  graphique permet de faire cette opération par sélection d'un champ
+  dans le dataspace)::
+
+  >>> f=get(fieldId)
+
+* ``ls``: affiche la liste des champs présent dans l'espace de travail ("list")
+* ``put``: met un champ en référence dans l'*espace de gestion*::
+
+  >>> put(f)
+
+* ``save``: sauvegarde tous les champs référencés dans l'espace de
+  gestion dans un fichier med::
+
+  >>> save("/path/to/resultfile.med")
+
+.. note:: On peut faire à ce stade plusieurs remarques:
+
+   * la commande ``load`` charge uniquement les méta-informations
+     décrivant les maillage et les champs (noms, type de
+     discrétisation, liste des pas de temps). Les maillages et les
+     valeurs physiques des champs sont chargées ultérieurement (et
+     automatiquement) dés lors qu'elles sont requises par une
+     opération. Dans tous les cas, les données med (méta-informations
+     et valeurs) sont physiquement stockées au niveau de l'espace
+     *base de données*.
+   * la commande ``get`` définit en réalité un *manipulateur de champ*
+     dans l'espace de travail, c'est-à-dire une variable qui fait la
+     liaison avec le champ physique hébergé dans la base de
+     données. Les données physiques ne circulent jamais entre les
+     espaces, mais restent centralisées au niveau de la base de
+     données.
+
+Les commandes TUI suivantes nécessitent de travailler dans
+l'environnement graphique:
+
+* ``visu``: afficher une carte de champ pour contrôle visuel rapide
+  (pas de paramettrage possible)
+
+  >>> view(f)
+
+
diff --git a/src/MEDOP/doc/sphinx/medop-workingnotes-2010.rst b/src/MEDOP/doc/sphinx/medop-workingnotes-2010.rst
new file mode 100644 (file)
index 0000000..724c9a8
--- /dev/null
@@ -0,0 +1,461 @@
+.. meta::
+   :keywords: maillage, champ, manipulation
+   :author: Guillaume Boulant
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+ANNEXE: Note de travail concernant le chantier XMED 2010
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+.. contents:: Sommaire
+   :local:
+   :backlinks: none
+
+Principes directeurs du développement
+=====================================
+
+En matière de développement:
+
+* On ne cherche pas d'emblée à s'inscrire dans la fabrication d'un
+  module SALOME diffusable dans la version d'exploitation 2010 (SALOME
+  6). La raison est double: (i) on souhaite au moins pour 2010 ne pas
+  devoir tenir compte des contraintes de temps SALOME et (ii) le
+  produit envisagé fin 2010 est une maquette qui cherche à éprouver
+  l'ergonomie générale d'utilisation et en aucun cas on ne peut
+  garantir la réalisation d'un module SALOME compatible avec les
+  exigences de mise en exploitation.
+* On ne cherche pas d'emblée à capturer tous les cas d'application,
+  mais à concevoir un développement qui acceptera les extensions de
+  périmètres dans des conditions raisonnables. Aussi, les
+  fonctionnalités développées seront celles qui sont nécessaires à la
+  réalisation des cas d'application de référence;
+
+En matière d'ergonomie:
+
+* L'interface utilisateur de référence (appelé espace de travail dans
+  le volet de spécifications fonctionnelles) est l'interpréteur
+  python. Les fonctionnalités doivent être pensées pour un usage
+  adapté à une interface textuelle (TUI) de ce type.
+* La création d'une interface graphique (GUI) peut être envisagée en
+  complément et comme un moyen de manipuler graphiquement les
+  fonctionnalités développées pour l'interface textuelle et pour aider
+  la préparation des variables dans l'interface python.
+* Le modèle d'un processus de manipulation de champs est:
+
+  - Préparation du jeu de variables U, V, ... représentant les champs
+    à manipuler. C'est à ce stade que l'on résoud la question de
+    sélection des données (dans un champ publié dans l'arbre d'étude,
+    par un module de calcul ou par chargement d'un fichier med)
+  - Utilisation des variables avec une sémantique la plus proche
+    possible du modèle conceptuel et des spécifications
+    fonctionnelles;
+  - Création des variables qui représentent les résultats des
+    fonctions de manipulation;
+  - Persistence (fichier med), visualisation (SALOME) ou export (vers
+    une structure qui peut être directement utilisable en numpy)
+
+Sur le plan technique:
+
+* On souhaite spécifier clairement le conteneur SALOME des fonctions
+  de manipulation de champs. Pour discussion:
+
+  - Il apparaît que les modules SALOME MED et VISU contiennent déjà
+    des fonctions qui peuvent faire partie des fonctions de
+    manipulations de champs (en particulier pour l'exploration des
+    structures MED, leur visualisation et la sélection des données à
+    manipuler).
+  - Dans la mesure où le module MED n'est pas utilisé à ce jour (en
+    tout cas pas sous sa forme de module SALOME) et compte-tenu du
+    caractère obsolescent du module VISU (amené à être remplacé sur le
+    plan fonctionnel  par le module PARAVIS), on pourrait examiner la
+    création d'un module dédié à la manipulation des maillages et des
+    champs par l'agrégation technique au sein d'un même module des
+    fonctions des modules MED et VISU.
+
+Au moins dans un premier temps, on se donne les limites suivantes:
+
+* Une opération ne peut pas combiner des pas de temps différents. Dans
+  l'hypothèse où cette limite venait à être levée, on doit spécifier
+  le pas de temps de la donnée résultat;
+* Le domaine d'application d'une opération pourra être défini
+  exclusivement par la donnée d'un maillage ou un groupe d'éléments du
+  maillage;
+* On ne traite pas le cas des champs qui prennent leurs valeurs aux
+  points de gauss ou aux noeuds par élément. Une particularité de ces
+  types de support est que le repérage de la position implique deux
+  indices (par exemple l'indice de la maille, puis l'indice du point
+  de gauss).
+
+Eléments de conception
+======================
+
+Plan général
+------------
+
+On peut par exemple imaginer une maquette du genre:
+
+* En C++ dans MEDGUI, charger un fichier med et donner une vue de la
+  structure des maillages et des champs dans l'arbre d'étude.
+* Sélectionner un élément (par exemple un pas de temps d'un champ) et
+  le menu contextuel permet d'exporter ce champ dans la console python
+  pour manipulation. Pour cela, s'inspirer de la fonction
+  ``XCADGUI::OnLoadScript()`` du XCADGUI pour manoeuvrer un objet
+  PythonConsole.
+* L'élément est marqué comme ayant été exporté, on peut imaginer une
+  récupération ultérieure.
+* Exporter un deuxième champ cohérent avec le premier (même pas de
+  temps et défini sur le même maillage avec le même support, on
+  s'arrange pour).
+* Dans la console python, faire les opérations sur les champs
+* Publication du champ résultat dans l'arbre d'étude pour sauvegarde
+  ultérieure. C'est a priori le gros morceau qui consiste à faire un
+  objet CORBA MED à partir d'un objet MED standard, en plus défini
+  dans la console python (sous forme d'objet python).
+
+Quand ce premier cas d'utilisation est au point, on peut envisager de
+le compléter par les opérations suivantes
+
+* exporter le résultat med dans un fichier
+* visualiser les champs produits
+
+Plan de développement:
+
+* Faire une maquette en MEDMEM pur d'abord, car quelque soit le choix
+  d'architecture, l'opération physique se déroulera en définitif au
+  niveau de MEDMEM pur.
+* Prévoir une implémentation des opérations sous forme de fonctions
+  informatiques, même les opérations algébriques (+,-,*,/). Pour ces
+  dernières et dans certaines conditions (quand on manipule
+  directement les strutures MEDMEM et non pas les objets CORBA),
+  l'utilisation des formes A+B, A-B, ... peuvent être rendues
+  possibles. Dans ce cas, voir la possibilité de combiner plusieurs
+  opérations algébriques sur une seule ligne: A+B-C*0.3.
+* On peut charger la structure MED sous forme d'objet CORBA publiable
+  dans l'étude, de sorte d'avoir accés aux méta-données et pouvoir par
+  exemple sélectionner les champs d'intérêt. De cet objet CORBA, on ne
+  récupère que les informations nécessaires au chargement d'un champs:
+  le nom du champs, le nom de son maillage associé, les identifiants
+  du pas de temps, au besoin une structure Field non chargée (par
+  exemple pour récupérer plus facilement le maillage).
+* Un mécanisme (à développer à partir du PyConsole par exemple)
+  pourrait alors permettre le chargement des champs sélectionnés dans
+  la console python et sous un nom facile à manoeuvrer. Prendre
+  inspiration sur XCADGUI::LoadIntoPythonConsole().
+* A priori, les données sont physiquement chargée dans le GUI. Au
+  besoin, il semble possible (cf. MED_i::init) de fabriquer une objet
+  CORBA field à partir d'un field standard (à tester).
+
+Une autre idée est de récupérer le pointeur CORBA MED dans la console
+python et de tirer les données à partir de là. Ajouter une couche de
+wrapping python pur pour gérer les cas de simplification (surcharge
+des opérations arithmétiques par exemple).
+
+Besoins complémentaires:
+
+* L'interpréteur doit contenir des éléments d'aide (par exemple un
+  help qui liste les opérations possibles sur les champs chargés)
+* prévoir quelques fonctions de visu et de persistence. Cela commence
+  probablement par des fonctions de publication dans l'étude des
+  champs créés par les opérations de manipulation. Les champs sont
+  physiquement ajouté automatiquement à la structure med par le MedOp
+  mais il n'est pas obligatoirement publié => fournir un moyen de
+  publication.
+
+Limitations actuelles (liées à la conception de MEDMEM):
+
+* les champs doivent être gérés par la même structure MED car ils
+  doivent partager le même support.
+* les opérations possibles dans MEDMEM sont entre champs pris sur un
+  pas de temps (Q: les pas de temps peuvent-ils être différents).
+
+
+Développements
+--------------
+
+Développement de classes proxy:
+
+* FieldProxy, FieldTimeSeriesProxy
+* Attention pour les éries temporelles, le SUPPORT med peut être
+  différent en chaque pas de temps (par exemple en cas d'extension
+  spatiale du champ au cours du temps).
+
+MEDMEM_MedDataManager:
+
+* FIX: test de l'implémentation C++ au travers de la fonction test() du
+  MedOperator ==> OK. Quand on fait la même opération depuis python
+  via l'interface SWIG ==> au deuxième appel de getFieldDouble, le
+  destructeur du champ semble être appelé. Pb de gestion des pointeurs?
+
+
+Evolutions à prévoir
+====================
+
+Concernant MEDMEM:
+
+* FIX: SALOME_MED::MED::getField devrait pouvoir être appelée
+  plusieurs fois de suite puisqu'on recycle la référence si elle est
+  déjà chargée.
+* IMP: MEDMEM::MED faire une gestion des chargements des champs (par
+  exemple avec un getField qui renvoie le champ s'il est déjà chargé
+  ou le charge et le renvoie sinon).
+* IMP: Récupérer le nom du fichier med à partir de l'objet MED, en
+  passant a priori par le driver associé. Plusieurs driver peuvent
+  être associés à une structure MED car les données peuvent être
+  chargées en plusieurs fois et de plusieurs fichiers. Il faut donc
+  étendre la structure MED pour avoir accés à la liste des driver puis
+  de cette liste déduire les noms des fichiers.
+* IMP: Opérations combinant des champs sur des support différents ne
+  peuvent pas être faites par l'API (une exception est levée en cas de
+  supports incompatibles), mais on peut imaginer le faire en
+  manoeuvrant les tableaux de données directement.
+* INF: faire le point sur les fonctions utilitaires autour de MEDMEM
+  et de son interface SWIG (ex: dumpMEDMEM.py, med_opfield_test.py).
+* IMP: dans MEDMEM::MED et SALOME_MED::MED, pouvoir enlever un champ
+  préalablement ajouté: une fonction removeField en complément de
+  addField.
+
+Concernant l'interface SALOME_MED:
+
+* IMP: Fonctions algébriques, qui seront implémentées au niveau de la
+  structure MED et requêtées au niveau des classes proxy en spécifiant
+  les identifiants des champs impliqués et les paramétres requis (pas
+  de temps en particulier).
+
+Concernant le module MED:
+
+* IMP: pourvoir exporter la structure med dans un fichier med (la
+  structure ayant pu être enrichie par la publication de champs créés
+  par les operations de champs.
+
+
+Historique des travaux
+======================
+
+20100726 : mise au point du schéma de conception
+------------------------------------------------
+
+Choix entre MEDMEM et MEDCoupling: on reste sur MEDMEM pour plusieurs
+raisons:
+
+* MED Coupling ne peut pas gérer des mailles de dimensions différentes
+  dans un même modèle (choix faits dans un soucis de performance dans
+  l'accès à une structure de donnée compact). On peut contourner le
+  problème en définissant deux champs pour traiter chacun des type de
+  mailles.
+* Un champ repose sur un maillage complet (pas de notion de profil,
+  mais cela peut être émulé en créant deux maillages)
+* Le concept de point de gauss n'existe pas (pas implémenté)
+
+TODO:
+
+* Idéalement, il conviendrait de faire un état des lieux du module
+  MED, en particulier des éléments MEDMEM (le coeur), les interfaces
+  CORBA associées (MED.idl implémenté dans le package source
+  MEDMEM_I), l'engine (composant SALOME d'interface MED_Gen.idl et
+  implémenté dans le package source MED) et le GUI (MedGUI.cxx
+  implémenté dans le package source MEDGUI).
+
+* Ergonomie TUI et modèle CORBA associé:
+
+  1. Charger un objet medmem (puis les objets métier mesh et field)
+     sur un domaine d'application donné.
+  2. En faire des variables disponibles dans l'interface TUI et que
+     l'on peut manipuler dans des opérations algébriques.
+  3. Pouvoir au besoin en faire des objets CORBA pour l'interface avec
+     les autres modules SALOME.
+
+* Compléter le diagramme de la structure informatique de MED (en
+  particulier l'implémentation des interface IDL).
+* Préparer un module de travail XMED (organisation d'une bibliothèque)
+
+Tests à réaliser:
+
+* Est-il possible de faire des opérations algébriques à partir des
+  objets SALOMEMED (objects CORBA MED)?
+* Création d'un objet MED_i à partir d'une objet MED pur préalablement
+  chargé en mémoire.
+
+A retenir:
+
+* Des opérations de champs sont possibles sur des champs à des pas de
+  temps fixés. Si l'opération doit être menée sur plusieurs pas de
+  temps, alors itérer sur chaque pas de temps. L'idée ici est
+  d'introduire le concept de série temporelle de champs en temps
+  qu'objet manipulable.
+* Pour deux champs différents de la même structure MED, la données des
+  identifiants dt et it ne correspond pas forcément au même instant
+  absolu (en tout cas rien ne le garanti, même si c'est tout de même
+  une pratique courante).
+
+20101005 : première maquette de démonstration de l'ergonomie en MEDMEM pur
+--------------------------------------------------------------------------
+
+XMED: svn révision 16
+Travailler avec le fichier de donnée testfield.med joint.
+
+
+20101007 : Vers une maquette CORBA
+----------------------------------
+
+Le contexte d'utilisation des opérations de champs est l'environnement
+SALOME. Le support de gestion des données est donc l'étude SALOME. Au
+plus bas niveau, les champs sont des objets MEDMEM instanciés dans une
+session SALOME (soit par un code de calcul intégré, soit par
+chargement des données à partir d'un fichier med). Ces objets sont en
+général référencés dans l'étude SALOME sous la forme d'objets CORBA de
+classe SALOMEMED::FIELD. Plus exactement, l'étude SALOME gère des
+SObject (Study Object) dont un attribut est une référence vers un
+objet CORBA de classe SALOMEMED::FIELD qui lui-même encapsule un objet
+MEDMEM::Field.
+
+On peut donc envisager une solution dans laquelle on donne à
+l'utilisateur des poignées de manipulation des objets
+SALOMEMED::FIELD, par exemple au moyen d'un modèle informatique de
+type proxy. Cela signifie que l'utilisateur ne manipule pas
+directement des objets MEDMEM mais des objets python qui font
+l'interface (à concevoir et implémenter, a priori avec un design
+pattern de type proxy).
+
+L'utilisation directe des objets MEDMEM aurait pu être une solution
+extremement pratique dans la mesure où ces objets en l'état peuvent
+être combinés dans des opérations de champs (c'est déjà
+implémenté). Par contre, ce procédé souffre de limitations importantes
+dans la gestion et la circulation des données pour les différents cas
+d'utilisation envisagés (visualisation, export, transfert à un autre
+module SALOME).
+
+L'avantage de la solution proposée est multiple:
+
+* Elle permet de travailler sur une structure MED cohérente pour
+  intégrer les résultats des opérations de calculs et combiner des
+  champs cohérents entre eux. Tout passe par des classes proxy qui
+  pourront s'assurer de la cohérence des opérations demandées et
+  exécuter automatiquement les fonctions de pré-traitement ou
+  post-traitement requises pour ces opérations. On peut imaginer par
+  exemple que les requêtes d'opération soient envoyées par les classes
+  proxy à la structure MED à laquelle les champs sont associés pour
+  piloter l'opération en MEDMEM pur.
+* Elle permet d'automatiser un certain nombre d'opérations
+  implicites. Par exemple si deux champs ne sont pas définis dans la
+  même unité, un changement d'unité peut être effectué automatiquement
+  par la classe proxy avant de commander l'opération au niveau
+  MEDMEM.
+* Elle permet de laisser les données sur le container SALOME et de
+  réaliser des opérations sans rappatrier les données en local (qui
+  peuvent être en trés grand nombre).
+* Elle permet d'étendre facilement l'ergonomie de manipulation des
+  champs, par exemple en définissant la notion de *série temporelle de
+  champs*, ou encore les concepts de *domaine de définition* évoqués
+  dans les spécifications fonctionnelles.
+* Elle rend immédiat la circulation des données entre modules SALOME,
+  puisque les champs restent accessble par des objets CORBA, en
+  particulier pour la visualisation ou l'export des champs produits
+  par les opérations.
+
+Elle a cependant des inconvénients et/ou limitations:
+
+* Elle nécessite l'implémentation d'une classe proxy pour encapsuler tous
+  les appels aux objets SALOME_MED (et donc MEDMEM). Cette interface
+  se limite a priori aux opérations de champs (les opérations
+  algébriques dans un premier temps).
+* Les champs à manipuler dans une opération donnée doivent être gérés
+  par la même structure MED.
+
+Il est à noter également que les interfaces de programmation de
+SALOMEMED (interface CORBA pour MEDMEM) devront être étendues pour
+permettre des requêtes de manipulations de champs (fonctions addition,
+soustraction, multiplication, ...). Pas de contrainte ici sur
+l'ergonomie puisque la manipulation par l'utilisateur se fera au
+niveau des classes proxy uniquement.
+
+
+Hypothèses:
+
+* On tente ici une maquette qui exploite dans la mesure du possible le
+  fonctionnement actuel du module MED, en particulier la gestion des
+  données dans l'étude.
+* Dans une deuxième version, on pourra examiner sérieusement la
+  révision de la gestion des données dans le module, quitte à la
+  spécifier et maquetter dans XMED pour intégration ultérieure dans
+  MED. Exemple:
+
+  - Pouvoir gérer plusieurs structures med dans l'étude.
+
+* Enfin, on exploite MEDMEM en l'état. Pour les besoins de la gestion
+  des données (gestion des chargements des champs en particulier,
+  références croisées pour retrouver le med à partir du champ par
+  exemple, ...), il pourra être nécessaire de faire évoluer MEDMEM. Il
+  faut pouvoir par ailleurs gérer indifféremment une structure med (et
+  les champs qui y sont associés) qu'elle soit créée en mémoire from
+  scratch ou chargée d'un fichier (donc attention avec les opérations
+  de lecture read(), sur les maillages comme sur les champs). La
+  structure med permet d'obtenir les méta données (meta-field par
+  exemple) mais ne permet pas de savoir si les données sont
+  physiquement chargées ou pas.
+
+
+Révisions:
+
+* XMED svn revision 21 + tarball MED_SRC-20101014-15h26m.tgz.
+  Première version qui permet d'importer un champ dans la console
+  python sous la forme d'un FieldProxy. Ne permet pas encore de faire
+  des opérations. Introduction dans le module MED de l'interface MEDOP
+  pour prendre en charge les opérations sur les champs.
+
+
+20101019 : Maquette de démonstration pour l'addition
+----------------------------------------------------
+
+Cette maquette implémente une solution technique de bout en bout (de
+l'interface python aux objets MEDMEM, en passant par le fieldproxy
+puis les servants CORBA pour les operations, ...) mais sur le
+périmètre de l'addition de champs sur tout leur domaine de définition
+et pour un pas de temps donné.
+
+Limitations:
+
+* gére l'addition de champs de type double uniquement (parceque le
+  reste n'est pas implémenté)
+
+Révisions:
+
+* XMED: svn révision 25
+* MED: cvs tag BR_medop_20101019
+
+
+20101020: Fonctions complémentaires
+-----------------------------------
+
+Cette version test la faisabilité des fonctions complémentaires pour
+accompagner la manipulation de champs. Cela comprend en particulier:
+
+* **la sauvegarde des champs produits** dans un fichier med (un champ ou
+  toute la structure med). Pour cela, on définit un med proxy comme
+  l'extention du SALOME_MED::MED (prévir plutôt d'implémenter ce type
+  de fonction au niveau C++ pour permettre un usage au niveau du GUI
+  C++?).
+* **la visualisation d'un champ** au moyen du module VISU.
+* **des fonctions d'aide interactives** pour assister l'utilisateur
+  dans la console de manipulation des champs.
+
+
+Questions:
+
+* peut-on sauvegarder un champ unique?
+* peut-on faire en sorte que ce soit l'affectation à une variable qui
+  provoque l'ajout du champ à la structure med (ou plus exactement qui
+  supprime tous les champs intermédiaires).
+
+
+Révision:
+
+* XMED: svn revision 31
+* MED: cvs tag BR_medop_20101025
+
+
+20110606: commit avant transfert dans git
+-----------------------------------------
+
+* XMED: svn revision 53
+
+Les parties de MED utiles à MEDOP seront reversées dans XMED
+dans une première étape, puis le tout dans MED 6 au final. 
diff --git a/src/MEDOP/doc/sphinx/medop-workingnotes-2011.rst b/src/MEDOP/doc/sphinx/medop-workingnotes-2011.rst
new file mode 100644 (file)
index 0000000..2c38e64
--- /dev/null
@@ -0,0 +1,473 @@
+.. meta::
+   :keywords: maillage, champ, manipulation
+   :author: Guillaume Boulant
+
+.. include:: medop-definitions.rst
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+ANNEXE: Note de travail concernant le chantier XMED 2011
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+.. contents:: Sommaire
+   :local:
+   :backlinks: none
+
+Cas d'utilisation métier
+========================
+
+On illustre par un exemple (Christophe Vallet, R&D/MMC, 1/7/2011)::
+
+ J'ai souvent des fichiers med de résultats de calcul, et j'aimerais y
+ ajouter de nouveaux champs issus de champs existants. J'aimerais
+ aussi pouvoir créer de nouveaux meds plus petits par extraction de
+ certaines composantes de champs, certains groupes ou certains pas de
+ temps.
+
+On peut exprimer le besoin sous la forme des cas d'utilisation
+suivants (use cases):
+
+* **UC1: combiner dans un même fichier med des champs issus de
+  plusieurs sources de données**. On peut par exemple charger un
+  premier fichier, puis ajouter à cette base des champs issus d'autre
+  fichiers ou générés par manipulation de champs, ou encore générés
+  par un module de calcul qui produirait directement du MEDCoupling.
+* **UC2: créer un champ contenant certaines composantes d'un autre
+  champ**. On pense ici aux fonctions de restriction, qui permettraient
+  de récupérer certaines composantes uniquement.
+* **UC3: créer un champ contenant certains pas de temps d'un autre
+  champ**. C'est un cas particulier des fonctions de restriction
+  évoquées ci-dessus.
+* **UC4: créer un champ comme la limitation d'un autre champ à un
+  groupe de mailles**. C'est un cas particulier des fonctions de
+  restriction évoquées ci-dessus. Notion de domaine spatial. A
+  priori la notion de groupe est définie dans MEDLoader.
+
+On peut ajouter également les UC identifiés pour la maquette 2010:
+
+* **UC5: comparer des champs issus de source de données différentes**,
+  par exemple des champs chargés de deux fichiers med différents et
+  qui s'appuient sur le même maillage (au moins conceptuellement).  Le
+  problème technique ici est de pouvoir changer le maillage d'un
+  champ, pour ramener tous les champs sur le même maillage (au sens
+  informatique). Ceci est une contrainte de MEDCoupling, les
+  opérations sur des champs A et B imposent que A et B soient définis
+  sur le même maillage, i.e. le même objet informatique.
+* **UC6: créer un champ de toute pièce sur un maillage**, ou un groupe
+  de mailles. Ce cas d'usage est typiquement prévu pour produire les
+  conditions de chargement initial d'une structure. Il s'agit ici
+  d'initialiser un champ à partir de zéro sur une surface prédéfinie
+  de la géométrie (par exemple spécifiée par un nom de groupe de
+  mailles).
+
+Pour UC5: les sources de données sont référencées dans l'object
+browser. On importe explicitement les données dans l'espace de
+travail. On peut détecter que les maillages sont identiques et on
+propose à l'utilisateur de transférer le champ sur le maillage déjà
+présent. Sinon, les champs devront être référencés sur des maillages
+distincts dans l'arbre de l'espace de travail.
+
+Analyses préliminaires pour le chantier 2011
+============================================
+
+On fait le choix pour le chantier 2011 de travailler à partir de la
+bibliothèque MEDCoupling (et non plus MEDMEM comme c'était le cas dans
+le démonstrateur 2011).
+
+Analyse de MEDCoupling et MEDLoader
+-----------------------------------
+
+MEDCoupling est l'implémentation du modèle de données MED (avec
+recherche de minimisation des dépendances logicielles) et MEDLoader
+fournit une ensemble de fonctions pour le chargement des structures
+MEDCoupling depuis un fichier ou inversement leur sauvegarde sous
+forme de fichiers.
+
+Dans l'implémentation MEDCoupling, un champ est l'ensemble des valeurs
+d'une grandeur physique sur un maillage pour un pas de temps donné. Un
+champ est caractérisé par:
+
+* un support spatial, le maillage
+* un type de discrétisation spatial, défini par l'emplacement des
+  valeurs sur le maillage (sur les noeuds, sur les cellules, aux
+  points de gauss, ...) et le mode d'interpolation spatial (P0, P1,
+  etc)
+* un pas de temps, défini par deux entiers (iteration, order) et un
+  réel (timestamps)
+
+Dans cette implémentation, il existe une association 1..n entre un
+maillage et un champ (alors que dans MEDMEM, la structure
+intermédiaire SUPPORT est implémentée).
+
+MEDCouplingCorba fournit un ensemble de servants CORBA pour manoeuvrer
+des structures MEDCoupling au travers du bus CORBA. L'interface à ce
+jour est délibérément réduite. Des classes dites "Cliente" sont
+fournies pour piloter les servants CORBA depuis un contexte
+client. Par exemple ``MEDCouplingFieldDoubleClient`` fournit une
+fonction de création d'une structure MEDCoupling à partir d'un
+pointeur vers un servant CORBA. La structure est créée localement
+(dans le contexte client) avec duplication des données issue de la
+structure encapsulée par le servant CORBA (récupération par la
+fonction de sérialisation).
+
+Aucune interface CORBA n'est défini pour MEDLoader.
+
+Questions:
+
+* Voir comment sont créés les servants, et surtout comment ils sont
+  récupérés (via le lcc?)
+* Comment peut-on définir un champ sur un groupe de mailles (et non
+  pas sur le maillage complet)? Comment peut-on extraire le champs
+  circoncit à une groupe de mailles pour des opérations.
+
+  - R: méthode changeUnderlyingMesh
+
+* Comment manipuler deux champs chargées de fichiers différents mais
+  construit sur le même maillage (conceptuellement). On peut forcer la
+  réassociation d'un champ sur un autre maillage?
+* Manipuler des champs de pas de temps différents? Différentes
+  composantes d'un ou plusieurs champs?
+* Comment importer un MedCoupling dans PARAVIS? (dans VISU?)?
+
+* mapper sur une image
+
+Improvments:
+
+* MEDLoader::Write should raise an exception if the filepath is not writable
+* MEDDataManager: développer une classe chapeau sur MEDCoupling et
+  MEDLoader pour  aider au chargement et la gestion de données MED
+  (orienté manipulation de champs). Cette classe serait associée des
+  structures légères FieldHandler et MeshHandler et des listes
+  correspondantes pour la navigation dans les méta-données.
+* Sur base du MEDDataManager, prévoir des ports med pour yacs par
+  lesquels pourrait transiter des handler.
+
+Nouveaux concepts à prendre en compte
+-------------------------------------
+
+Au démarrage du chantier 2011, on observe que les concepts suivants
+sont introduits dans le module MED: 
+
+* Le conteneur MED n'existe plus, utiliser MEDFILEBROWSER pour charger
+  les fichiers med et obtenir les informations générales sur le
+  contenu.
+* MEDFILEBROWSER: remplace le concept de driver et fournit les
+  fonctions précédemment fournies par la classe MED pour obtenir les
+  informations de structure.
+* Concept d'Extractor pour une lecture sélective des données de champs
+  (suivant un critère d'extraction)
+* Il n'est plus nécessaire d'appeler les méthodes read explicitement
+  sur les objets (MESH et FIELD) pour charger les données. Par
+  ailleurs, on peut définir deux fois le même champs (double
+  chargement a priori) sans lever d'exception).
+
+
+Analyse de conception pour le chantier 2011
+===========================================
+
+Composants SALOME (interfaces IDL)
+----------------------------------
+
+* MEDDataManager: défini une structure FIELD pour identifier un champ
+  dans les requêtes. Il s'occupe également de la récupération physique
+  des données, quelqu'en soit la source (fichier avec MEDLoader, autre
+  module SALOME comme PARAVIS avec une méthode à définir)
+* MEDCalculator: s'occupe des requêtes de calcul dont les arguments sont
+  les structures FIELD du MEDDataManager. Reprendre l'interface de
+  MEDOP.
+
+Use case à réaliser depuis un client python:
+
+* UC01: ajouter un fichier d'entrée et accéder aux informations
+  concernant les champs. Ex: récupérer une structure champs par la
+  donnée des paramètres primaires (nom identifiant, dt, it, nom du
+  maillage).
+* UC02: créer des champs et les ajouter au MEDDataManager
+* UC03: mener des opérations basique sur les champs en console python
+
+Interface Utilisateur
+---------------------
+
+L'interface utilisateur est composée des parties suivantes:
+
+* une partie GUI (appelée par la suite MEDGUI) qui s'occupe de piloter
+  le chargement des données dans l'espace de travail, au moyen d'une
+  interface graphique;
+* une partie TUI (appelée par la suite MEDTUI) qui s'occupe de piloter
+  la création de champs, au moyen de commandes exécutées dans la
+  console python.
+
+Le principe est que les champs sont préalablement chargés au niveau du
+composant SALOME au moyen de l'interface graphique (MEDGUI), puis
+manoeuvrés depuis l'application SALOME au moyen de variables proxy
+définies dans la console python (MEDTUI). Au chargement, les champs
+sont indéxés par le MEDDataManager, puis les index sont rendus
+accessibles au niveau du GUI au moyen d'une représentation
+arborescente de la structure MED. Les feuilles de l'arbre
+correspondent à des champs qui peuvent être sélectionnés et dont
+l'index peut être obtenu de la sélection.
+
+L'espace de travail est organisé autour du concept de
+"workspace". L'étude SALOME liste les datasource (les fichiers source
+des données med, mais peut-être aussi les référence vers des objets
+MED déjà existants ou chargé dans PARAVIZ). Une vue complémentaire
+permet de voir la structure fine d'une source de données.
+
+Concernant MEDGUI:
+
+* la représentation des données (les champs et les maillages associés)
+  doit permettre de récupérer par l'interface graphique les
+  identifiants des champs à manipuler (a priori les structures FIELD
+  définies par le composant MEDDataManager). Cela conduit à la mise en
+  place des composants suivants:
+
+  - MedDataModel hérité de TreeData. Il est peuplé avec les
+    méta-données décrivant la structure MED explorée.
+  - MedGuiManager qui permet l'implantation du doc widget de
+    présentation
+
+TODO:
+
+* specifier le concept de workspace (qui a une entrée dans l'étude?)
+  en bijection avec un datamanager
+* identifier des interlocuteur/utilisateur pour l'aspect ergonomie d'usage
+
+Concernant MEDTUI:
+
+* Il fournit les classes FieldProxy
+
+Questions:
+
+* Comment traiter le cas du travail sur des composantes ciblées, plus
+  généralement, comment introduire le concept de domaine
+  d'application?
+* Prévoir des fonctions génériques (initialisation d'un champ sur un
+  maillage avec une fonction analytique de la position, sauvegarder
+  les champs créés dans un fichier med)
+
+
+Tâches de développement
+=======================
+
+T20110622.1: Gestion des données internes
+-----------------------------------------
+
+**Status: terminé.**
+Suite: fonction de sauvegarde au niveau graphique également
+
+On vise les cas d'utiliation suivants:
+
+* UC1: intégrer dans le datamodel du gui un champ créé dans la console
+  python (et donc présent dans le datamanager du composant). Définir
+  l'utilité?
+* UC2: renommer un champ et plus généralement changer ses méta-données
+  (avec assurance de synchronisation entre toutes les données).
+* UC3: sauvegarder une sélection de champs. La sélection peut se faire
+  dans l'arbre du datamodel gui.
+
+WARN: robustesse de fieldproxy
+
+
+
+T20110622.2: UC Initialisation/Création de champs
+-------------------------------------------------
+
+**Status: à faire**
+
+Les cas implémentés à ce jour sont la création de champs à partir de
+champs existants et chargés d'un fichier med. On souhaite ici réaliser
+des cas 'utilisation autour de la création de champs "from scratch",
+s'appuyant tout de même sur un maillage chargé.
+
+UC01: Sélection d'un groupe de maille dans SMESH pour initialiser un
+champ (par exemple les conditions limites d'un problème de calcul).
+
+UC02: créer un champ avec des restrictions qui définissent le domaine
+d'application des opération de champs.
+
+UC03: créer un champ à partir d'une image (codes rgb utilisé comme les
+composantes du champs vectoriel ou niveaux de gris pour un champ
+scalaire. Attention, pour ça, il faudra a priori fiare une projection
+du maillage cartesien de l'image sur le maillage (quelconque) sur
+lequel on souhaite définir le champ.
+
+UC04: créer un champ à partir d'un tableau numpy
+
+De manière générale, ce type de création sera assisté par le
+MEDGUI. Au niveau MEDTUI, les fonctions pourraient être fastidieuses
+pour l'utilisateur.
+
+Par exemple, prévoir un menu contextuel qui propose les opérations
+possibles en fonction de la sélection (en plus de la fonction d'import
+dans la console python).
+
+TODO:
+
+* développer les fonctions d'initialisation, par exemple au moyen
+  d'applyFunc et du mécanisme de callable?
+
+T20110622.3: documentation contextuel
+-------------------------------------
+
+**Status: à faire**
+
+* Remettre toutes les commandes dans le même fichier (fusionner cmdtools
+  et fieldtools)
+* Faire un modèle générique de command (classe de base
+* Batir la doc des commandes sur cette base (lister toutes les
+  instances de type Command par exemple)
+
+T20110622.4: remontée des exception du composant MEDCalculator
+--------------------------------------------------------------
+
+**Status: en cours, compléter la couverture**
+
+Pour des messages contextuel sur les erreurs de calcul (ex: division
+par 0)
+
+* Poursuivre le travail fait sur getMedEventListener
+* Protéger tous les appels au composants effectués depuis la console
+  python (prendre example sur la commande save)
+
+T20110624.1: gestion des données GUI
+------------------------------------
+
+**Status: à faire**
+
+
+
+Le workspace a une entrée dans l'obrowser. Sur cette entrée on peut:
+
+* supprimer: supprime tout les champs associés
+* sauvegarder. Dans ce cas, on rappelle l'ensemble des champs pour
+  cocher ceux qu'on veut sauvegarder.
+
+Le gui data model est réservé aux opérations sur les champs et à
+piloter leur import dans la console python.
+
+TODO:
+
+* Spécifier les concepts de workspace, database, et datasource, espace
+  de gestion, ... et les associations. Simplifier avec l'appuie de use
+  cases.
+* Mécanisme de mise à jour du TreeView de XSALOME (aujourd'hui, seul
+  l'ajout addChild est implémenté
+* Clic droit sur objets de l'arbre: dans la notification TreeView ->
+  WorkspaceController, faire remonter l'évènement clic droit ainsi que la
+  liste des éléments sélectionné pour faire générer le menu contextuel
+  au niveau du WorkspaceController qui peut déterminer le contexte métier
+  (le TreeView ne le connaît pas).
+* Définir des DataObject pour les maillages, les séries temporelles et
+  les champs
+
+
+Spécification des espaces de données:
+
+* MEDDataManager dépend de l'étude (pour permettre la publication
+  d'information dans une étude SALOME).
+* créer "sourcid = MEDDataManager::addDataSource(filename)", suivie de
+  requetes getFields(sourceid), getMeshes(sourceid)
+* les espaces de données: dataspace, workspace. Un seul workspace par
+  étude, mais autand de datasources que l'on souhaite dans le
+  dataspace. Les datasources sont rangés dans l'étude (le dataspace)
+  et sont non modifiables après chargement (référence des sources de
+  données).
+
+
+T20110628.1: extention à d'autres objets SALOME
+-----------------------------------------------
+
+**Status: suspendu**
+
+On doit reposer la question de l'existance de l'arbre indépendant
+(DockWidget), d'une part, et l'extention aux autres objets (GEOM et
+SMESH en particulier) du principe de sélection graphique pour
+utilisation dans la console python, d'autre part.
+
+
+T20110628.2: visualisation d'un champ avec PARAVIS
+--------------------------------------------------
+
+**Status: terminé (pour une première version)**
+Suite: de nombreux défauts subsistent
+
+Questions/remarques:
+
+* Pb au démarrage du module: VisTrails fails to start
+* Peux-t-on piloter la vue 3D sans charger le module? (voir
+  myparavis.py)
+* Comment donner un nom au MEDReader1 dans l'arbre Pipeline?
+* Comment utiliser directement les objets MEDCouplingField?
+
+
+T20110706.1: documentation du module
+------------------------------------
+
+**Status: en cours (10%)**
+
+Documenter les commandes TUI puis l'utilisation générale de
+l'interafce graphique. Mentionner l'existance de la commande medop.sh
+pour travailler exclusivement en mode texte (utile pour les tests
+rapides).
+
+Documenter les modalités d'exécution des tests.
+
+T20110708.1: helper python pour MEDCoupling
+-------------------------------------------
+
+**Status: en attente (pas urgent)**
+
+Faire un helper python dans le package xmed qui permet de faire du
+medcoupling facilement (essentiellement pour simplifier le chargement,
+puis la sélection des données). Cela demanderait de faire un
+MedDataManager comme une class C++ pure (non CORBA). Cette classe
+travaillerait par exemple uniquement avec des id et des liste d'id, et
+fournirait des fonctions d'affichage (comme le ``ls`` et le ``la``)
+pour obtenir des meta-information.
+
+Le servant MedDataManager pourrait être une surcouche de cette classe
+c++ pure.
+
+T20110708.2: analyses et tests
+------------------------------
+
+TODO:
+
+* créer un fichier de test avec plusieurs pas de temps
+* créer un fichier de test avec des groupes de mailles
+
+
+T20110728.1: refactoring MEDDataManager
+---------------------------------------
+
+Refactoring pour une meilleur association entre FieldHandler et MeshHandler:
+
+* dans la mesure du possible utiliser les id plutôt que les handler en
+  arguments des fonctions d'appel des objets
+* A chaque champ (FieldHandler), on doit associer un meshid (et de
+  manière optionnelle un fieldseriesId, si le champ peut être associé
+  à une serie temporelle. A priori faisable uniquement au chargement
+  du datasource).
+* Pour cela, revoir les fonctions internes newFieldHandler et addField
+  ou prévoir de les compléter à chaque fois qu'elles sont appelée avec
+  les informations concernant le meshid.
+* addField est utilisée par le MEDCalculator
+* Attention au raffraichissement des données handler au niveau du
+  Workspace. Peut-être le mieux est que les fieldproxy contiennent
+  uniquement le fieldid, et qu'ils interroge le datamanager à chaque
+  fois qu'ils ont besoin d'une donnée. Voir aussi les notifications
+  via le MEDEventListener?  **Le plus simple est de faire la mise à
+  jour lors de l'appel à la méthode __repr__ du fieldproxy, i.e. quand
+  on essaye d'afficher les données**. Parceque sinon il n'y a pas de
+  problème puisque que le calculateur travaille à partir des id.
+
+
+Petites améliorations du DataspaceController:
+
+* Au OnUseInWorkspace, stocker (dans la mesure du possible) le nom de
+  l'alias python dans un attribut du sobject.
+* Dans DlgChangeUnderLyingMesh, expliquer que le champs sera dupliquer
+  est posé dans le WS. On peut donc proposer en option de lui associer
+  un alias pour manipulation dans la console
+
diff --git a/src/MEDOP/doc/sphinx/medop-workingnotes-2012.rst b/src/MEDOP/doc/sphinx/medop-workingnotes-2012.rst
new file mode 100644 (file)
index 0000000..b6ecb6d
--- /dev/null
@@ -0,0 +1,84 @@
+.. meta::
+   :keywords: maillage, champ, manipulation
+   :author: Guillaume Boulant
+
+.. include:: medop-definitions.rst
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+ANNEXE: Note de travail concernant le chantier XMED 2012
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+.. contents:: Sommaire
+   :local:
+   :backlinks: none
+
+
+Analyse preliminaire pour le chantier 2012
+==========================================
+
+La figure imposée pour le chantier 2012 est l'intégration du nouveau
+module de manipulation de champs dans SALOME 6.6 (objectif CEA), en
+préparation de la mise en exploitation dans SALOME 7 (objectif EDF).
+
+L'état actuel est:
+
+* Un module SALOME de nom MED intégrant les bibliothèques MEDCoupling,
+  MEDLoader, REMAPPER, mais aussi plusieurs packages logiciels
+  aujourd'hui obsolètes ou amener à disparaître pour l'échéance
+  SALOME7
+* Un module SALOME de nom XMED qui fournit les fonctions graphiques
+  pour la manipulation de champs.
+* Ce module XMED utilise le module VISU pour les vue de contrôle.
+
+La cible est:
+
+* Un module unique (nom à définir, par exemple MEDOP) débarrassé des
+  packages logiciels obsolètes et intégrant les fonctions graphiques
+  (GUI et TUI).
+* L'utilisation du module PARAVIS (au lieu de VISU) pour les vues de
+  contrôle.
+* L'intégration de MEDCoupling avec YACS (port MED dans YACS par
+  exemple).
+
+A examiner:
+
+* voir les attendus concernant les ports MED dans YACS
+* interface PARAVIS: utilisation du viewer (et de l'API python) sans chargement du GUI
+
+Tâches de développement
+=======================
+
+20120904: Migrer XMED dans MED
+------------------------------
+
+Plan de travail:
+
+* Migration des composants + test
+
+
+
+20120904: Nettoyage de XSALOME
+------------------------------
+
+:status: en cours
+
+* Supprimer les vieilleries de XSALOME:
+
+  - StdHelper -> Basic_Utils (KERNEL)
+
+20120829: mise en place du chantier 2012
+----------------------------------------
+
+:status: terminé
+
+L'objectif de cette première étape est de reverser le prototype 2011
+(module XMED indépendant) dans la branche V6_main du module MED. On
+peut procéder de la manière suivante:
+
+* update de XMED (et XSALOME utilisé par XMED) pour fonctionnement sur
+  V6_main
+* Eliminer la dépendance à XSALOME
+* Supprimer la gestion des multiversion SALOME5/6 au niveau de l'engine
+
+.. warning:: TODO: refaire le point sur les tâches initiées en 2011 
+
diff --git a/src/MEDOP/doc/sphinx/salomedoc.rst b/src/MEDOP/doc/sphinx/salomedoc.rst
deleted file mode 100644 (file)
index fc2f1fd..0000000
+++ /dev/null
@@ -1,231 +0,0 @@
-.. meta::
-   :keywords: SALOME, development
-   :author: Guillaume Boulant
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-Annexe : Règles de développement SALOME
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-Cette annexe est un recueil de techniques de développement spécifiques
-à l'environnement SALOME et utilisées pour la mise au point du module
-XMED. Elles sont a priori utilisables pour d'autres contexte de
-développement dans SALOME.
-
-.. TODO: récupérer les fonctions génériques de VisuGUI_Tools.cxx
-.. TODO: récupérer les fonctions génériques de SMESGGUI_utils.cxx
-
-.. contents:: Sommaire
-   :local:
-   :backlinks: none
-
-Récupérer la sélection dans l'arbre d'étude
-===========================================
-
-Dans une classe dérivée de ``SalomeApp_Module``, on peut utiliser un
-code de la forme suivante:
-
-.. code-block:: cpp
- #include <SALOME_ListIO.hxx>
- #include <LightApp_SelectionMgr.h>
- #include <SALOME_ListIteratorOfListIO.hxx>
- #include <SALOME_InteractiveObject.hxx>
- // ...
-
- // Get the selected object in the study (SObject)
- LightApp_SelectionMgr* aSelectionMgr = this->getApp()->selectionMgr();
- SALOME_ListIO aListIO;
- aSelectionMgr->selectedObjects(aListIO);
-
- // Analyse the selection. There can be more than one item.
- SALOME_ListIteratorOfListIO It (aListIO);
- for (; It.More(); It.Next()) {
-   Handle(SALOME_InteractiveObject) anIO = It.Value();
-   SALOMEDS::SObject_var aSObject = aStudy->FindObjectID(anIO->getEntry());
-
-   // Check if the selected object is relevant for the operation
-   // ...
-
-   // Process the SObject if it's relevant
-   // ...
-   
- }
-
-On peut noter qu'une variable ``aStudy`` est requise. Elle représente
-l'étude SALOME sur laquelle s'oppère la sélection. L'étude active
-(impliquée dans la sélection) peut être obtenue au moyen du
-gestionnaire d'étude (voir :ref:`ci-dessous <salomedoc_getActiveStudy>`).
-
-Réglage du curseur graphique
-============================
-
-Dans le cas où le traitement est long, il peut être intéressant
-d'encadrer l'opération par un vérouillage du curseur de sélection:
-
-.. code-block:: cpp
-
- QApplication::setOverrideCursor(Qt::WaitCursor);
-
- // Do the job
- // ...
-
- QApplication::restoreOverrideCursor();
-
-
-Les variables pour la gestion de l'étude
-========================================
-
-Les variables CORBA
--------------------
-
-Les variables CORBA comme le serveur de noms (naming service) et le
-gestionnaire de cycle de vie des objets (LifeCycleCRORBA) sont
-fréquement utilisés. Dans le contexte d'une application (classe de
-type ``SalomeApp_Module``), il est possible de récupérer simplement
-des instances de ces variables par les commandes suivantes:
-
-.. code-block:: cpp
-
-   #include <SalomeApp_Application.h>
-   #include <SALOME_NamingService.hxx>
-
-   CORBA::ORB_var               orb           = SalomeApp_Application::orb();
-   SALOMEDSClient_StudyManager* studyMgr      = SalomeApp_Application::studyMgr();
-   SALOME_NamingService*        namingService = SalomeApp_Application::namingService();
-   SALOME_LifeCycleCORBA*       lcc           = SalomeApp_Application::lcc();
-
-Pour un usage en dehors de l'application graphique (par exemple au
-niveau du container), l'orb peut être obtenu par les mécanismes
-standard d'omniORB:
-
-.. code-block:: cpp
-
-   CORBA::ORB_var orb = CORBA::ORB_init(0,0);
-
-L'orb est par exemple utile à récupérer pour la sérialisation des
-objets CORBA et la manipulation des références sous forme de chaîne de
-caractères:
-
-.. code-block:: cpp
-
-   // We suppose here that we have a CORBA object reference (object of
-   // type *_ptr or *_var), for example a SALOME_MED::MED object.
-   SALOME_MED::MED_ptr medObj = ... // anything to get this object  
-   QString medIOR = orb->object_to_string(medObj);
-
-   SALOME_MED::MED_ptr anOtherRefToMedObj = orb->string_to_object(medIOR)
-
-.. note: this serialization can be used to communicate between a GUI
-   and a component in a container, or between the C++ context and the
-   python context.
-
-.. _salomedoc_getActiveStudy:
-
-Récupérer l'étude active
-------------------------
-
-Le concept d'étude active est un concept GUI. Il désigne l'étude en
-cours d'usage au niveau de l'interface graphique. 
-
-.. note: Pour rappel, l'étude est un objet CORBA de type
-   ``SALOMEDS::Study`` qui héberge physiquement les ``SObject``
-   pointant vers les données. L'arbre d'étude ("Object browser") est
-   une représentation graphique de cet objet.
-
-L'étude active peut être obtenue au moyen du gestionnaire
-d'étude. Dans le corps d'une classe de type ``SalomeApp_Module``, ceci
-peut se faire par un code de la forme suivante:
-
-.. code-block:: cpp
-
-  #include "SALOMEconfig.h"
-  #include CORBA_SERVER_HEADER(SALOMEDS)
-  #include <SalomeApp_Application.h>
-  #include <SALOME_NamingService.hxx>
-
-  // ...
-
-  // Get the study id of the active study
-  SalomeApp_Study* appStudy = dynamic_cast<SalomeApp_Study*> (this->getApp()->activeStudy());
-  _PTR(Study) aCStudy = appStudy->studyDS();
-  int aStudyID = aCStudy->StudyId();
-
-  // Then get the study manager
-  SALOME_NamingService *aNamingService = SalomeApp_Application::namingService();
-  CORBA::Object_var anObject = aNamingService->Resolve("/myStudyManager");
-  SALOMEDS::StudyManager_var aStudyManager = SALOMEDS::StudyManager::_narrow(anObject);
-
-  // Finally, request the study manager for the study (SALOMEDS::Study)
-  SALOMEDS::Study_var aStudy = aStudyManager->GetStudyByID(aStudyID);
-
-
-Communiquer avec la console python
-==================================
-
-La console python désigne l'interpréteur embarqué dans l'interface
-graphique de SALOME (GUI). Elle est également désignée comme
-l'interface textuelle de SALOME (TUI) car elle permet de piloter
-SALOME au moyen de commandes en syntaxe python.
-
-Le paragraphe montre comment communiquer avec cette interface texte
-depuis le contexte C++ de l'interface graphique, en particulier pour
-déclencher l'exécution de commandes.
-
-Le code se situe donc au sein d'une classe de type
-``SalomeApp_Module`` (de laquelle hérite la partie graphique d'un
-module SALOME, de nom ``<MODULE_NAME>GUI``). Cette classe possède une
-méthode ``getApp()`` par laquelle on peut récupérer une instance de la
-console python embarquée (this->getApp()->pythonConsole()).
-
-Le code suivant illustre l'envoie d'une commande python par ce
-mécanisme. Dans cette exemple, on défini une variable ``id`` dans la
-console python comme l'identifiant de l'étude active:
-
-.. code-block:: cpp
-
-   #include <PyConsole_Console.h>
-   #include <QString>
-   #include <QStringList>
-
-   PyConsole_Console * pyConsole = getApp()->pythonConsole();
-
-   QStringList commands;
-   commands+="import salome";
-   commands+="id=salome.myStudyId";
-      
-   QStringListIterator it(commands);
-   while (it.hasNext()) {
-       pyConsole->exec(it.next());
-   }
-
-Dans ce deuxième exemple, on cherche à reconstituer dans le contexte
-de la console python un pointer vers un objet med instancié dans le
-contexte C++ de l'application graphique. Pour cela, on communique la
-référence de l'objet sous la forme sérialisé (IOR pour un objet
-CORBA):
-
-.. code-block:: cpp
-
-   #include <PyConsole_Console.h>
-   #include <QString>
-   #include <QStringList>
-   #include <SalomeApp_Application.h>
-
-   // We suppose here that we have a CORBA object reference (object of
-   // type *_ptr or *_var), for example a SALOME_MED::MED object.
-   SALOME_MED::MED_ptr medObj = ... // anything to get this object  
-
-   // Get the IOR of this object
-   QString medIOR = SalomeApp_Application::orb()->object_to_string(medObj);
-
-   PyConsole_Console * pyConsole = getApp()->pythonConsole();
-
-   QStringList commands;
-   commands+="import salome";
-   commands+=QString("med=salome.orb.string_to_object(\"%1\")").arg(medIOR);
-      
-   QStringListIterator it(commands);
-   while (it.hasNext()) {
-       pyConsole->exec(it.next());
-   }
diff --git a/src/MEDOP/doc/sphinx/xmed-definitions.rst b/src/MEDOP/doc/sphinx/xmed-definitions.rst
deleted file mode 100644 (file)
index cfd0bc1..0000000
+++ /dev/null
@@ -1,88 +0,0 @@
-.. AVERTISSEMENT:
-.. Ce fichier contient les définitions globales à la documentation. Il
-.. peut être inclu au moyen de la directive rst "include" pour
-.. disposer des définitions dans le fichier qui fait l'inclusion.
-.. Pour éviter de polluer les textes dans lequel ce fichier est inclu,
-.. il est interdit de faire afficher du texte par ce document de
-.. définition.
-
-.. REFERENCES DOCUMENTAIRES:
-.. (les documents sont fournis dans le répertoire _static/documents)
-
-.. You can refer to this reference using the keyword: |REF_EDF_VCA_H-I2C-2009-03595-FR|_
-.. |REF_EDF_VCA_H-I2C-2009-03595-FR| replace:: H-I2C-2009-03595-FR: Manipulation de champs dans SALOME - Orientations générales
-.. _REF_EDF_VCA_H-I2C-2009-03595-FR: _static/documents/20091218_EDF_VCANO_H-I2C-2009-03595-FR.pdf
-
-.. You can refer to this reference using the keyword: |REF_CEA_VBE_MEDMEM|_
-.. |REF_CEA_VBE_MEDMEM| replace:: Guide utilisateur de MED mémoire
-.. _REF_CEA_VBE_MEDMEM: _static/documents/20070105_CEA_VBERGEAUD_GuideutilisateurMEDMEMOIRE.pdf
-
-.. You can refer to this reference using the keyword: |REF_EDF_GBO_WORKNOTE|_
-.. |REF_EDF_GBO_WORKNOTE| replace:: XMED: Notes de travail
-.. _REF_EDF_GBO_WORKNOTE: _static/documents/20110309_XMED_scan_notes.pdf
-
-.. You can refer to this reference using the keyword: |REF_EDF_ELO_REM|_
-.. |REF_EDF_ELO_REM| replace:: XMED: Remarques E. Lorentz
-.. _REF_EDF_ELO_REM: _static/documents/20110309_XMED_scan_remarques_ELORENTZ.pdf
-
-.. You can refer to this reference using the keyword: |REF_EDF_PRESMANIPCHP01|_
-.. |REF_EDF_PRESMANIPCHP01| replace:: Séminaire EDF-CEA de janvier 2010: manipulation de champs
-.. _REF_EDF_PRESMANIPCHP01: _static/documents/20100129_MAN_seminaireEDF-CEA_all.pdf
-
-.. You can refer to this reference using the keyword: |REF_EDF_PRESMANIPCHP02|_
-.. |REF_EDF_PRESMANIPCHP02| replace:: Révue EDF-CEA: maquette de manipulation de champs
-.. _REF_EDF_PRESMANIPCHP02: _static/documents/20101027_MAN_revueEDF-CEA.pdf
-
-.. You can refer to this reference using the keyword: |REF_EDF_PRESMANIPCHP03|_
-.. |REF_EDF_PRESMANIPCHP03| replace:: Séminaire EDF-CEA de mars 2011: manipulation de champs, maquette 2010
-.. _REF_EDF_PRESMANIPCHP03: _static/documents/20110310_seminaireEDF-CEA_maquetteXMED.pdf
-
-.. PRESENTATIONS:
-
-.. You can refer to this reference using the keyword: |REF_EDF_JUS2011_PDF|_
-.. |REF_EDF_JUS2011_PDF| replace:: JUS2011: outils de manipulation de champs
-.. _REF_EDF_JUS2011_PDF: _static/presentations/20111115_JUS-2011/20111115_JUS2011_manipulation_de_champs.pdf
-
-.. You can refer to this reference using the keyword: |REF_EDF_JUS2011_OGV1|_
-.. |REF_EDF_JUS2011_OGV1| replace:: JUS2011: outils de manipulation de champs - Exemple 1
-.. _REF_EDF_JUS2011_OGV1: _static/presentations/20111115_JUS-2011/20111115_JUS2011_medop_exemple_1.ogv
-.. You can refer to this reference using the keyword: |REF_EDF_JUS2011_OGV3|_
-.. |REF_EDF_JUS2011_OGV3| replace:: JUS2011: outils de manipulation de champs - Exemple 3
-.. _REF_EDF_JUS2011_OGV3: _static/presentations/20111115_JUS-2011/20111115_JUS2011_medop_exemple_3.ogv
-.. You can refer to this reference using the keyword: |REF_EDF_JUS2011_OGV4|_
-.. |REF_EDF_JUS2011_OGV4| replace:: JUS2011: outils de manipulation de champs - Exemple 4
-.. _REF_EDF_JUS2011_OGV4: _static/presentations/20111115_JUS-2011/20111115_JUS2011_medop_exemple_4.ogv
-
-
-
-.. LIENS EXTERNES:
-.. (l'accès nécessite le réseau intranet EDF et internet)
-
-.. You can refer to this reference using the keyword: |LINK_EDF_MEDDOC|_
-.. |LINK_EDF_MEDDOC| replace:: Modèle MED
-.. _LINK_EDF_MEDDOC: http://med.der.edf.fr/logiciels/med-2.3.6/doc/html/modele_de_donnees.html
-
-.. You can refer to this reference using the keyword: |LINK_EDF_MEDFICHIERDOC|_
-.. |LINK_EDF_MEDFICHIERDOC| replace:: Documentation de MED fichier
-.. _LINK_EDF_MEDFICHIERDOC: http://med.der.edf.fr/logiciels/med-2.3.6/doc
-
-.. You can refer to this reference using the keyword: |LINK_EDF_SALOME_MED__MED|_
-.. |LINK_EDF_SALOME_MED__MED| replace:: SALOME_MED::MED
-.. _LINK_EDF_SALOME_MED__MED: http://nepal.der.edf.fr/pub/SALOME_userguide/MED5/doc/salome/tui/MED/interfaceSALOME__MED_1_1MED.html
-
-.. RENVOIES:
-
-.. You can refer to this reference using the keyword: |SEE_MEDMEM_CORBA|
-.. |SEE_MEDMEM_CORBA| replace:: :ref:`L'interface CORBA SALOME_MED<xmed-medmem_corbainterface>`
-
-
-.. SNAPSHOTS:
-
-.. |XMED_SPECIFICATIONS_PDF| replace:: version pdf
-.. _XMED_SPECIFICATIONS_PDF: _static/documents/xmed-specifications.pdf
-
-.. |XMED_DEVELGUIDE_PDF| replace:: version pdf
-.. _XMED_DEVELGUIDE_PDF: _static/documents/xmed-develguide.pdf
-
-.. |XMED_USERGUIDE_PDF| replace:: version pdf
-.. _XMED_USERGUIDE_PDF: _static/documents/xmed-userguide.pdf
diff --git a/src/MEDOP/doc/sphinx/xmed-develguide.rst b/src/MEDOP/doc/sphinx/xmed-develguide.rst
deleted file mode 100644 (file)
index be5d72b..0000000
+++ /dev/null
@@ -1,239 +0,0 @@
-.. meta::
-   :keywords: maillage, champ, manipulation, med, développement
-   :author: Guillaume Boulant
-
-.. include:: xmed-definitions.rst
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-Module XMED: Guide de développement
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-(|XMED_DEVELGUIDE_PDF|_)
-
-Ce document est la documentation technique du module XMED. Il fournit
-les instructions à suivre pour installer le module en vue d'un travail
-de développement, puis décrit les éléments de conception qui
-structurent le module.
-
-.. contents:: Sommaire
-   :local:
-   :backlinks: none
-
-.. warning:: Ce document est en travaux. Tant que cet avis n'aura pas
-   disparu, veuillez en considérer le plan et le contenu encore
-   incomplets, temporaires et sujets à caution.
-
-Mise en place d'un espace de développement
-==========================================
-
-Gestion de configuration du module XMED
----------------------------------------
-
-Les sources du module (répertoire ``xmed``) sont archivés en dépôt de
-configuration dans une base git du projet NEPAL. Ils peuvent être
-récupérés au moyen de la commande::
-
- $ git clone git@cli70rw.der.edf.fr:xom/xmed.git
-
-Cette commande installe un répertoire ``xmed`` contenant l'ensemble
-des sources du module XMED.
-
-Le module XMED a pour pré-requis logiciel la plateforme SALOME:
-
-* SALOME version 6.1.3 (au moins) à télécharger à l'URL
-  http://pal.der.edf.fr/pal/projets/pal/releases/V6_1_3
-* On peut également utiliser une version dérivée comme SALOME-MECA 2010.1
-* Installer la plate-forme choisie selon les instructions fournies.
-
-Le module XMED utilise également une bibliothèque interne au projet
-NEPAL, appelée XSALOME, et qui fournit une extension aux fonctions de
-SALOME pour un usage de développement (XSALOME signifie eXtension
-SALOME). Les sources de cette bibliothèque doivent être récupérés au
-moyen de la commande::
-
- $ git clone git@cli70rw.der.edf.fr:xom/xsalome.git
-
-Cette commande installe un répertoire ``xsalome`` contenant l'ensemble
-des sources de la bibliothèque XSALOME.
-.. note:: La bibliothèque XSALOME n'est pas un module SALOME mais une
-   simple bibliothèque de fonctions qui complète ou rend plus facile
-   d'utilisation les fonctions de SALOME. Elle NE DOIT EN AUCUN CAS
-   être intégrée à d'autres projets que les projets internes NEPAL ou
-   MAILLAGE. Il s'agit en effet d'une bibliothèque de transition qui
-   héberge des développements destinés à être reversés dans la
-   plate-forme SALOME. Le contenu et les interfaces de XSALOME ne peut
-   donc être garanti sur le long terme.
-
-Installation et lancement de l'application
-------------------------------------------
-
-L'installation suppose qu'une version 6.1.3 de SALOME (ou plus) est
-disponible et que le shell de travail est étendu avec l'environnement
-de SALOME. En général, par des commandes de la forme::
-
- $ . /where/is/salome/prerequis.sh
- $ . /where/is/salome/envSalome.sh
-
-La compilation des modules xsalome et xmed suit le standard SALOME. La
-bibliothèque xsalome est un prérequis à la compilation de xmed. Pour
-cela, la variable d'environnement XSALOME_DIR doit être spécifiée pour
-la configuration de la procédure de reconstruction de xmed::
-
- $ export XSALOME_DIR=<xsalome_installdir>
-
-Aprés l'installation de xmed, il est possible de générer
-automatiquement une application SALOME prête à l'emploi pour la
-manipulation de champs::
-
- $ <xmed_installdir>/bin/salome/xmed/appligen/appligen.sh
-
-Cette commande génére un répertoire ``appli`` à l'emplacement où elle
-est exécutée. Il reste à lancer l'application SALOME au moyen de la
-commande::
- $ ./appli/runAppli -k
-
-Exécution des tests unitaires
------------------------------
-
-Les tests unitaires peuvent être exécutés au moyen de scripts python
-lancés depuis une session shell SALOME. Dans un nouveau shell, taper::
-
- $ ./appli/runSession
- [NS=mars:2810]$ python appli/lib/python2.6/site-packages/salome/xmed/test_medoperation.py
-
-L'exécution imprime un rapport détaillant le résultat pour chaque
-fonction de test::
-
- test_addition (__main__.MyTestSuite) ... ok
- test_arithmetics (__main__.MyTestSuite) ... ok
- test_composition (__main__.MyTestSuite) ... FAIL
- test_litteral_equation (__main__.MyTestSuite) ... ok
- test_modification_of_attributes (__main__.MyTestSuite) ... ok
- test_unary_operations (__main__.MyTestSuite) ... ok
- test_update_metadata (__main__.MyTestSuite) ... ok
-
-Les scripts de test sont:
-
-* ``test_medoperation.py``: tests des operations de champs telles
-  qu'elles sont mises en oeuvre depuis l'interface textuelle.
-* ``test_xmed.py``: tests des composants CORBA mis en oeuvre
-  (``MEDDataManager`` et ``MEDCalculator``)
-
-Architecture du module XMED
-===========================
-
-Le module MED pour la manipulation de champs est composé de:
-
-* une bibliothèque de fonctions pour le traitement de données sur des
-  maillages et des champs conformes au modèle MED (package
-  MEDCoupling, MEDLoader et REMAPPER);
-* une interface graphique pour la mise en oeuvre des cas standard de
-  manipulation de champs;
-* une ensemble d'outils pour intervenir sur des fichiers au format
-  MED.
-
-Une bibliothèque de fonctions pour le traitement de données
------------------------------------------------------------
-
-La figure ci-dessous montre la structure des paquets logiciels qui
-constituent la bibliothèque:
-
-.. image:: images/medlayers.png
-   :align: center
-
-Elle comprend en particulier les paquets suivants:
-
-* MEDCoupling: qui décrit les structures de données pour porter les
-  maillages et les champs
-* MEDLoader: qui fournit les fonctions de persistence sous forme de
-  fichiers au format MED (lecture et écriture).
-* REMAPPER:
-
-Il est important de noter que MEDCoupling n'a aucune dépendance
-logicielle autre que la bibliothèque C++ standard. Ceci permet
-d'envisager son implantation dans un code de calcul ou un outil de
-traitement sans tirer l'ensemble pré-requis de SALOME.
-
-Une interface graphique pour l'exécution des cas standard
----------------------------------------------------------
-
-
-Un ensemble d'outils pour le traitement de fichiers
----------------------------------------------------
-
-
-Description des composants
-==========================
-
-MEDDataManager - Le gestionnaire des données de session
--------------------------------------------------------
-
-Le composant MEDDataManager s'occupe de fournir les données MED sur
-demande des interfaces clientes, en particulier pour module de
-pilotage fieldproxy.py. Ces données peuvent avoir plusieurs sources,
-en général elle proviennent d'un fichier au format med contenant des
-champs définis sur des maillages. Les données sont identifiées à la
-lecture des métadonnées de description dans le fichiers med, puis les
-valeurs des champs et les maillages support sont chargés au besoin.
-
-Le chargement des métadonnées de description se fait par la méthode::
-
-  addDatasource(const char \*filepath)
-
-
-
-Eléments d'implémentation
-=========================
-
-Ecrire un service CORBA qui retourne une sequence de FieldHandler:
-
-.. code-block:: cpp
-
-  MEDOP::FieldHandlerList * MyFunction(...) {
-    vector<MEDOP::FieldHandler*> fieldHandlerList;
-    ...
-  
-    fieldHandlerList.push_back(fieldHandler);
-  
-    // Map the resulting list to a CORBA sequence for return:
-    MEDOP::FieldHandlerList_var fieldHandlerSeq = new MEDOP::FieldHandlerList();
-    int nbFieldHandler = fieldHandlerList.size();
-    fieldHandlerSeq->length(nbFieldHandler);
-    for (int i=0; i<nbFieldHandler; i++) {
-      fieldHandlerSeq[i] = *fieldHandlerList[i];
-    } 
-    return fieldHandlerSeq._retn();
-  }
-
-Ecrire un service CORBA qui retourne une structure CORBA:
-
-.. code-block:: cpp
-
-    MEDOP::FieldHandler * fieldHandler = new ...
-    _fieldHandlerMap[fieldHandler->id] = fieldHandler;
-
-    // >>> WARNING: CORBA struct specification indicates that the
-    // assignement acts as a desctructor for the structure that is
-    // pointed to. The values of the fields are copy first in the new
-    // structure that receives the assignement and finally the initial
-    // structure is destroyed. In the present case, WE WANT to keep
-    // the initial fieldHandler in the map. We must then make a deep
-    // copy of the structure found in the map and return the copy. The
-    // CORBA struct specification indicates that a deep copy can be
-    // done using the copy constructor.  <<<
-    return new MEDOP::FieldHandler(*fieldHandler);
-
-
-
-ANNEXE: Bug en cours
-====================
-
-TO FIX:
-
-* la composition d'opérations n'est pas possible (ex: 2*f1+f2) car
-  2*f1 est indiqué comme non compatible (il semble qu'il n'ai pas la
-  reference correcte vers le maillage).
-* le script de test test_medoperation.py plante si le module xmed n'a
-  pas été chargé avec des données chargées.
diff --git a/src/MEDOP/doc/sphinx/xmed-prototype-develguide.rst b/src/MEDOP/doc/sphinx/xmed-prototype-develguide.rst
deleted file mode 100644 (file)
index de2387b..0000000
+++ /dev/null
@@ -1,731 +0,0 @@
-.. meta::
-   :keywords: maillage, champ, manipulation, XMED
-   :author: Guillaume Boulant
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-Démonstrateur XMED, documentation technique
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-Cette note fait la synthèse des développements effectués pour le
-maquettage des fonctions de manipulation de champs dans SALOME. Elle
-présente les principes retenus en matière de conception, c'est-à-dire
-concernant les mécanismes techniques sous-jacents, et en matière
-d'ergonomie, c'est-à-dire concernant les modalités d'utilisation dans
-l'environnement SALOME.
-
-Ces principes sont illustrés par des développements implantés dans le
-module XMED, développé pour les besoins de l'analyse, et dans le
-module MED distribué avec la plateforme SALOME.
-
-.. note:: la lecture de ce chapitre demande une connaissance de la
-   structure de classes du module MED, en particulier la distinction
-   entre les classes ``MEDMEM::*`` et les servants CORBA associés
-   (classe ``SALOME_MED::*``).
-
-.. contents:: Sommaire
-   :local:
-   :backlinks: none
-
-Principes directeurs
-====================
-
-Objectif et motivation
-----------------------
-
-L'objectif de maquettage est de trouver une architecture technique qui
-permet d'exécuter le cas d'utilisation suivant:
-
-* Chargement d'un fichier med dans SALOME (a priori dans le module MED)
-* Sélection graphique des champs de l'étude à mettre à disposition
-  dans la console utilisateur ("calculette" en mode texte qui
-  concraitement correspond à l'interface python de SALOME).
-* Dans la calculette, exécution d'opérations algébriques (+,-,*,/)
-  entre champs avec possibilité d'utiliser des scalaires dans des
-  opérations de type transformation linéaire (y=ax+b ou y et x sont
-  des champs et a et b des scalaires). Opérations pow, sqrt.
-* Possibilité de visualiser les champs produits avec VISU pour
-  contrôle des résultats.
-* Possibilité d'exporter des champs produits dans un fichier med.
-
-Eléments de contexte
---------------------
-
-Les opérations de manipulation de champs sont en grande partie
-implémentées dans la bibliothèque MEDMEM. Pour illustration, le
-fragment de code ci-dessous montre comment une addition de champ peut
-être opérée en python:
-
-.. code-block:: python
-
-    from libMEDMEM_Swig import MedDataManager
-    from xmed.helper import readMed, writeMed
-
-    # Load the medmem data structure from a med file
-    med = readMed("/tmp/input.med")
-    # Then create a med data manager to deal with the fields data
-    dm  = MedDataManager(med)
-    # Get the timestamps (dt,it)=(-1,-1) of the fields "testfield1" and "testfield2"
-    f1 = dm.getFieldDouble("testfield1",-1,-1)
-    f2 = dm.getFieldDouble("testfield2",-1,-1)
-
-    # Create a new field as the sum of f1 and f2
-    r  = f1 + f2
-    # And add this new field to the med data structure
-    med.addField(r)
-
-    # Finally, write the whole data in an output med file
-    writeMed(med,"/tmp/output.med")
-
-Ceci montre que les champs peuvent être manipulés avec une interface
-relativement ergonomique (une addition de deux champs f1 et f2 s'écrit
-f1+f2) tant que l'on manoeuvre des objets MEDMEM purs (classes C++ du
-package MEDMEM et wrapping python du package MEDMEM_SWIG).
-
-Par ailleurs, le fonctionnement actuel des modules SALOME qui
-manoeuvrent des données MED est d'instancier les structures de données
-MEDMEM au niveau de la partie serveur, c'est-à-dire au niveau des
-servants CORBA hébergés dans le processus ``SALOME_Container``, et de
-donner accés à ces données depuis l'étude SALOME au travers de
-pointeurs CORBA. Ce choix d'architecture présente l'avantage de
-centraliser au niveau serveur la gestion du cycle de vie des données
-informatiques et de pouvoir distribuer des "poignées" pour manipuler
-ces données depuis chaque point de l'application qui sait accéder au
-bus CORBA, l'interface graphique en particulier.
-
-
-Hypothèse de travail
---------------------
-
-Compte-tenu de l'objectif de maquettage et des éléments de contexte
-existant, on cherche une solution dans le cadre des hypothèses
-de travail suivantes:
-
-* La manipulation des champs se fait dans l'environement graphique de
-  SALOME.
-* Dans cet environnement, on souhaite pouvoir sélectionner
-  graphiquement les champs à considérer, puis manipuler ces champs
-  dans l'interface texte au moyen de variables python avec une syntaxe
-  aussi simple que celle définie dans le wrapping python de MEDMEM,
-  c'est-à-dire que pour faire l'addition de 2 champs f1 et f2, on veut
-  pouvoir écrire f1+f2.
-* Les données MED sont physiquement dans la partie serveur de SALOME
-  et accessibles via des pointeurs CORBA (interface spécifiée dans
-  MED.idl). On exclu la recopie de données au niveau du client
-  graphique.
-
-Dans le cadre de ces hypothèses, la difficulté technique réside dans
-la mise au point d'une interface de communication entre des variables
-manipulées par l'utilisateur dans l'interface graphique (c'est-à-dire
-dans le processus ``SALOME_SessionServer``) et des objets MEDMEM
-instanciés dans le containeur des servants CORBA (c'est-à-dire dans le
-processus ``SALOME_Container``).
-
-
-Eléments de conception
-======================
-
-
-Implantation technique
-----------------------
-
-Le diagramme ci-dessous représente l'organisation des principaux
-paquets logiciels du module MED:
-
-.. image:: images/medmem-layers.png
-   :align: center
-
-Les cadres bleus représentent le lieu d'implantation des
-développements effectués dans le module MED pour les besoins du
-maquettage. On notera en particulier les interventions aux niveaux
-suivants:
-
-* interfaces idl: ajout de l'interface MEDOP.idl
-* package MEDMEM_I: ajout du servant SALOME_MED::MEDOP qui implémente
-  l'interface MEDOP.idl
-
-Architecture technique
-----------------------
-
-Les schéma ci-dessous représente les objets informatiques qui sont à
-l'oeuvre pour la réalisation des opérations sur les champs:
-
-.. image:: /images/xmed-architecture.png
-   :align: center
-   :alt: Objets mis en oeuvre dans l'interface de manipulation de champs
-
-On distingue les objets suivants:
-
-* Une instance de ``MEDMEM::MED``, correspondant à la structure de donnée
-  MED chargée en mémoire.
-* Des instances de ``MEDMEM::FIELD`` qui représentent les champs med
-  chargés en mémoire.
-* Une instances de ``SALOME_MED::MED`` et des instances de
-  ``SALOME_MED::FIELD`` qui sont les servants CORBA respectivement de la
-  structure med et des champs qui lui sont associés et chargés en
-  mémoire.
-* Une instance de ``SALOME_MED::MEDOP`` qui est le servant CORBA qui
-  centralise la mise en oeuvre des opérations de champs sur le serveur
-  ``SALOME_Container``. Le servant MEDOP détient en attribut une référence
-  sur la structure ``MEDMEM::MED``, ce qui lui permet d'accéder
-  directement aux champs ``MEDMEM::FIELD`` à partir de leur nom et du pas
-  de temps.
-* Des instances de ``FieldProxy`` qui correspondent aux variables
-  manipulées au niveau de l'interface graphique et qui représentent
-  les champs. Une instance de FieldProxy possède détient les
-  références des servants ``SALOME_MED::MEDOP`` et
-  ``SALOME_MED::FIELD`` sous la forme de pointeurs CORBA de noms
-  ``medop_ptr`` et ``field_ptr`` respectivement.
-* Il existe également une instance de ``MedProxy`` non représentée
-  dans ce diagramme. Cette instance correspond à une variable qui
-  permet de manipuler la structure med.
-
-.. note:: Les éléments apportés par la maquette sont les classes
-   ``SALOME_MED::MEDOP``, ``MedProxy`` et ``FieldProxy``. Les autres
-   éléments ont pu être modifiés légèrement pour les besoins de
-   l'intégration ou pour la correction de quelques bugs.
-
-Le cycle de vie de ces objets est le suivant.
-
-Pour ce qui concerne les instances de la structure ``MEDMEM::MED`` et
-des champs ``MEDMEM::FIELD``, la création est faite au moment du
-chargement du fichier med dans SALOME au moyen du module MED. A cette
-occasion, les servants CORBA associés ``SALOME_MED::MED`` et
-``SALOME_MED::FIELD`` sont créés et des références vers ces servants
-sont publiés dans l'étude. Ils peuvent donc être sélectionnés par
-l'utilisateur dans l'interface graphique. L'ensemble de ces données
-préexiste à la manipulation de champs.
-
-Les objets ``SALOME_MED::MEDOP`` sont instanciés au sein du servant
-``SALOME_MED::MED`` auquel ils sont associées. Le servant
-``SALOME_MED::MED`` possède une référence sur la structure
-``MEDMEM::MED`` et il la transmet à l'instance du servant
-``SALOME_MED::MEDOP`` qu'il construit. L'opérateur MEDOP est donc
-autonome par la suite pour manipuler les données MED, et les champs en
-particulier. Le code python ci-dessous montre comment un opérateur med
-``SALOME_MED::MEDOP`` peut être créé puis utilisé pour réaliser
-l'addition de deux champs:
-
-.. code-block:: python
-
-   import salome
-   salome.salome_init()
-   import SALOME_MED
-   
-   medComp = salome.lcc.FindOrLoadComponent("FactoryServer", "MED")
-   medObj  = medComp.readStructFile("myfile.med",salome.myStudyName)
-   medOp   = medObj.createMedOperator()
-   
-   f1 = medObj.getField("testfield1",-1,-1)
-   f2 = medObj.getField("testfield2",-1,-1)
-   
-   somme = medOp.add(f1,f2)
-
-Il est à noter qu'une instance de ``SALOME_MED::MEDOP`` est associé à
-une instance unique de ``SALOME_MED::MED`` (et donc indirectement de
-``MEDMED::MED``) pour toute la durée de son cycle de vie. Par contre,
-un servant ``SALOME_MED::MED`` peut être associé à plusieurs servants
-``SALOME_MED::MEDOP`` différents. Un servant ``SALOME_MED::MEDOP`` a
-une référence directe sur la structure ``MEDMEM::MED`` et peut la
-manoeuvrer pour demander des champs, faire des opérations avec ces
-champs, ajouter le champs résultat à la structure et enfin retourner
-un servant ``SALOME_MED::FIELD`` qui encapsule le champ résultat.
-
-Enfin, quelques éléments concernant la classe ``FieldProxy``. Une
-instance de ``FieldProxy`` est un objet python qui peut être
-manoeuvrée dans l'interpréteur SALOME et qui référence un champ MED
-localisé sur le serveur ``SALOME_Container`` (par le mécanisme décrit
-ci-dessus). C'est à ce niveau qu'on règle les détails d'ergonomie
-d'usage (cf. paragraphe ci-après). La création d'un objet
-``FieldProxy`` déclenche la création d'un opérateur med (instance de
-``SALOME_MED::MEDOP``) qui lui est associé et dont il conserve la
-référence CORBA en attribut (noté ``medop_ptr`` sur le diagramme). Cet
-opérateur ``medop_ptr`` peut être requêter pour exécuter toutes les
-opérations possibles sur ce champ, comme illustrer sur l'exemple
-ci-dessus.
-
-
-Rôle des objets proxy
----------------------
-
-Dans le modèle d'architecture présenté ci-dessus, on introduit deux
-types d'objets proxy:
-
-* Les objets de classe ``FieldProxy`` qui représentent des poignées de
-  manipulation des champs ``MEDMEM::FIELD`` physiquement instanciés
-  dans le container SALOME.
-* Les objets de classe ``MedProxy`` qui représentent des poignées de
-  manipulation des structures ``MEDMEM::MED`` physiquement instanciées
-  dans le container SALOME.
-
-Elles sont instanciées dans l'interpréteur python SALOME pour
-manipulation dans l'interface textuelle à partir de la donnée du
-pointeur vers le servant ``SALOME_MED::MED`` et de l'identifiant du
-champ (le nom du champ et le pas de temps défini par le numéro d'ordre
-et le numéro d'iteration:
-
-.. code-block:: python
-
-   import salome
-   salome.salome_init()
-   import SALOME_MED
-
-   medComp = salome.lcc.FindOrLoadComponent("FactoryServer", "MED")   
-   medObj  = medComp.readStructFile("myfile.med",salome.myStudyName)
-
-   from xmed import fieldproxy
-   from xmed import medproxy
-
-   f1 = fieldproxy.getFieldFromMed(medObj, "testfield1", -1, -1)
-   f2 = fieldproxy.getFieldFromMed(medObj, "testfield2", -1, -1)
-
-   field_somme  = f1 + f2
-   field_offset = f1 + 5.3
-
-Dans cet exemple, les variables ``f1``, ``f2``, ``field_somme`` et
-``field_offset`` sont des objets de classe ``FieldProxy``. Ils
-correspondent aux variables physiquement manipulées par
-l'utilisateur pour désigner les champs dans les opérations.
-
-Ces classes proxy sont conçues pour être le lieu d'implémentation de
-l'interprétation des commandes utilisateur et donc de l'ergonomie
-de manipulation des champs au niveau l'interface textuelle. Ce point
-est développé :ref:`plus bas <develguide_execFieldOperation>`.
-
-Programmation de l'interface textuelle
---------------------------------------
-
-Dans le cadre de la maquette, l'interface de manipulation des champs
-est l'interface textuelle python intégrée à SALOME. Dans la pratique,
-l'utilisateur manipule des variables python qui correspondent à des
-objets de classe ``FieldProxy`` équipées des fonctions requises et de
-l'ergonomie nécessaire à la mise en oeuvre des opérations (voir
-ci-dessus).
-
-Or, l'hypothèse de travail est que les données MED sont chargées dans
-SALOME et publiées dans l'étude pour point d'accés depuis l'interface
-graphique. L'utilisateur choisi un champs directement dans l'arbre
-d'étude (ou dans une interface graphique dédiée) puis demande qu'il
-soit mis à disposition dans l'interface python sous un nom de variable
-à choisir. Les captures d'écran ci-dessous montre la séquence
-graphique en images:
-
-.. |IMG_SELECT| image:: images/medop-gui-selectfield_scale.png
-.. |IMG_ALIAS| image:: images/medop-gui-aliasfield_scale.png
-
-+---------------+---------------+ 
-| |IMG_SELECT|  | |IMG_ALIAS|   |
-+---------------+---------------+ 
-
-L'image de gauche montre la sélection du pas de temps, l'image de
-droite la boîte de dialogue qui permet la saisie de l'alias avec
-lequel le champs sera manipulé dans l'interface textuelle. La
-validation de cette fenêtre doit mettre automatiquement le champ à
-disposition dans l'interface python SALOME et sous le nom de variable
-spécifié par l'alias saisi.
-
-Pour cela, il y a un couplage technique à programmer entre l'interface
-graphique et l'interface textuelle python, avec en particulier la
-transmission des pointeurs vers les servants CORBA mis en jeu dans la
-sélection.
-
-Ce couplage est implanté au niveau de la classe MEDGUI.cxx du module
-MED (où de la classe XMEDGUI.cxx du module XMED pour la maquette) qui
-implémente l'interface graphique du module. Pour rappel, l'interface
-graphique d'un module SALOME se présente sous la forme d'une classe
-centrale de nom ``<MODULE_NAME>GUI`` et qui spécialise la classe
-``SalomeApp_Module``. Cette classe possède une méthode ``getApp()``
-par laquelle on peut récupérer une instance de la console python
-embarquée (this->getApp()->pythonConsole()).
-
-Le code suivant illustre l'envoie d'une commande python par ce
-mécanisme. Dans cet example, on cherche à reconstituer dans le
-contexte de la console python un pointer vers un objet med instancié
-dans le contexte C++ de l'application graphique. Pour cela, on
-communique la référence de l'objet sous la forme sérialisé (IOR pour
-un objet CORBA):
-
-.. code-block:: cpp
-
-   #include <PyConsole_Console.h>
-   #include <QString>
-   #include <QStringList>
-   #include <SalomeApp_Application.h>
-
-   // We suppose here that we have a CORBA object reference (object of
-   // type *_ptr or *_var), for example a SALOME_MED::MED object.
-   SALOME_MED::MED_ptr medObj = ... // anything to get this object  
-
-   // Get the IOR of this object
-   QString medIOR = SalomeApp_Application::orb()->object_to_string(medObj);
-
-   PyConsole_Console * pyConsole = getApp()->pythonConsole();
-
-   QStringList commands;
-   commands+="import salome";
-   commands+=QString("med=salome.orb.string_to_object(\"%1\")").arg(medIOR);
-      
-   QStringListIterator it(commands);
-   while (it.hasNext()) {
-       pyConsole->exec(it.next());
-   }
-
-Le code réel de la maquette est basé sur ce principe et transmet à la
-console python des lignes de commandes qui permettent de reconstruire:
-
-* un pointeur CORBA vers le servant ``SALOME_MED::MED`` associé au
-  champ sélectionné;
-* une instance de ``FieldProxy`` qui correspond au champ sélectionné
-  et avec pour nom de variable la valeur de l'alias saisi dans
-  l'interface graphique.
-
-Au niveau du code C++ de la classe ``XMEDGUI.cxx``, cela se traduit
-par la fabrication de la liste de commandes suivante pour envoie à la
-console python par le mécanisme illustré plus haut:
-
-.. code-block:: cpp
-
-   QStringList commands;
-   commands+="from xmed.fieldproxy import getFieldFromMed";
-   commands+="from xmed.medproxy import getMedProxy";
-   commands+=QString("if not dir().__contains__('med'): med = getMedProxy(\"%1\")").arg(medIOR);
-   commands+=QString("%1=getFieldFromMed(med,\"%3\",%4,%5)").arg(*alias).arg(fieldName).arg(orderIndex).arg(iterationIndex);
-
-Les variables ``medIOR``, ``fieldName``, ``orderIndex`` et
-``iterationIndex`` sont construites à partir du champ sélectionné par
-des techniques de programmation standard dans SALOME qu'on peut
-examiner en détail dans la classe ``XMEDGUI`` (voir méthode
-``XMEDGUI::LoadIntoPythonConsole()``). La variable ``alias`` est la
-chaîne saisie par l'utilisateur dans la fenêtre de dialogue.
-
-Le point important à noter ici est que les données à transmettre
-doivent être fournies sous forme de chaînes de caractères ou de types
-simples. C'est pourquoi la référence au servant CORBA
-``SALOME_MED::MED`` est transmise ici sous la forme de son IOR,
-c'est-à-dire une chaîne de caractères qui permet l'identification de
-l'objet au niveau du bus CORBA.
-
-Au niveau de la console python cela correspond à l'exécution des
-commandes suivantes:
-
-.. code-block:: python
-
-   from xmed.fieldproxy import getFieldFromMed
-   from xmed.medproxy import getMedProxy
-   
-   med = getMedProxy("IOR:010000001700000049444c3a53414c4f4d455f4d45442f4d45443a312e300000010000000000000064000000010102000e0000003133302e39382e37372e313733009e0a0e000000feadc4ca4c00003169000000001100000200000000000000080000000100000000545441010000001c00000001000000010001000100000001000105090101000100000009010100")
-   
-   f1=getFieldFromMed(med,"testfield1",-1,-1)
-
-Ce jeu d'instructions reconstitue un pointeur vers le servant CORBA
-``SALOME_MED::MED`` à partir de son identifiant IOR (voir la fonction
-``getMedProxy(...)``, puis crée une instance de ``FieldProxy``
-associée à ce servant (en fait associée au servant
-``SALOME_MED::MEDOP`` créé sur demande par le servant
-``SALOME_MED::MED``, voir la fonction ``getFieldFromMed(...)``).
-
-.. _develguide_execFieldOperation:
-
-Exécution des opérations sur le champs
---------------------------------------
-
-Les variables définies dans l'interface textuelle pour désigner les
-champs à manipuler sont des objets de classe ``FieldProxy``.
-
-Cette classe a une propriété remarquable, elle est construite sur un
-design pattern de type "Proxy" qui pointe vers un servant
-``SALOME_MED::FIELD``. Cela signifie que l'on ne peut pas accéder
-directement au servant vers lequel il pointe, mais que l'on passe
-systématiquement par une procédure de l'objet proxy qui fait "boîte
-aux lettres":
-
-.. code-block:: python
-
-   class FieldProxy:
-
-     def __getattr__( self, name ):
-        """
-        This method realizes the proxy pattern toward the servant
-        SALOME_MED::FIELD.
-        """
-        return getattr( self.__field_ptr, name )
-
-Ce pattern permet l'implémentation de pré-traitement et/ou de
-post-traitement suivant le type d'accés que l'on cherche à faire.
-
-Il permet aussi et surtout de fournir un objet python qui présente
-l'interface de ``SALOME_MED::FIELD`` dotée d'extentions adhoc pour les
-operations de champs. Ici, python est ton ami, car il s'agit pour cela
-d'équiper la classe ``FieldProxy`` des automatismes prévus nativement
-par python pour les operations entre objets. En particulier, la
-re-définition des fonctions internes ``__add__`` (opérateur addition),
-``__sub__`` (opérateur soustraction), ``__mul__`` (opérateur
-multiplication) et ``__div__`` (opérateur division) au sein de la
-classe ``FieldProxy``, permet de prendre la main sur le comportement
-des opérations algébriques et de définir une ergonomie sur mesure. Par
-exemple, la méthode ``__add__`` peut gérer les variantes "f1+f2"
-(ajout de deux variables de type FieldProxy) et "f1+5.3" (ajout d'un
-réel à une variable de type FieldProxy):
-
-.. code-block:: python
-
-   class FieldProxy:
-
-     def __add__(self, operande):
-        """
-        This can process the addition of two fields or the addition of
-        a scalar to a field. It depends weither the operande is a
-        FieldProxy or a simple scalar numerical value.
-        """
-        if isinstance(operande, FieldProxy):
-            # The operande is an other field
-            otherField_ptr = operande.__field_ptr
-            rfield_ptr = self.__medOp_ptr.add(self.__field_ptr, otherField_ptr)
-        else:
-            # The operande is a scalar numerical value that must be
-            # considered as an offset in a linear transformation
-            factor = 1
-            offset = operande
-            rfield_ptr = self.__medOp_ptr.lin(self.__field_ptr, factor, offset)
-        return FieldProxy(self.__med_ptr, rfield_ptr)
-
-Il est à noter que dans les deux cas de figure (opérande=champ ou
-opérande=scalaire), la fonction délègue la réalisation concrète de
-l'opération au servant ``SALOME_MED::MEDOP`` (identifié ici par
-l'attribut ``self.__medOp_ptr`` et que l'on appelera l'*opérateur
-MEDOP* dans la suite pour simplifier), mais n'appelle pas le même
-service de calcul (l'addition entre champs dans le premier cas,
-l'application d'une transformation linéaire de type y=factor*x+offset
-dans le deuxième cas).
-
-Pour couvrir le cas des opérations algébriques, l'opérateur MEDOP
-présentre l'interface suivante (cf. fichier ``MEDOP.idl`` qui définie
-l'interface du servant ``SALOME_MED_MEDOP``):
-
-.. code-block:: cpp
-
-    /*! Addition of the fields f1 and f2 ( f1+f2) */
-    FIELD add(in FIELD f1, in FIELD f2) raises (SALOME::SALOME_Exception);
-    /*! Substraction of the fields f1 and f2 (f1-f2) */
-    FIELD sub(in FIELD f1, in FIELD f2) raises (SALOME::SALOME_Exception);
-    /*! Multiplication of the fields f1 by f2 (f1*f2) */
-    FIELD mul(in FIELD f1, in FIELD f2) raises (SALOME::SALOME_Exception);
-    /*! Division of the fields f1 by f2 (f1/f2) */
-    FIELD div(in FIELD f1, in FIELD f2) raises (SALOME::SALOME_Exception);
-    /*! Power of the field f (f^power) */
-    FIELD pow(in FIELD f, in long power) raises (SALOME::SALOME_Exception);
-    /*! Linear transformation of the field f (factor*f+offset) */
-    FIELD lin(in FIELD f, in double factor, in double offset) raises (SALOME::SALOME_Exception);
-    /*! Dublication of the field f */
-    FIELD dup(in FIELD f) raises (SALOME::SALOME_Exception);
-
-Cette interface est implémentée dans la classe C++ ``MEDOP_i`` du
-module MED (voir fichier ``MEDMEM_MedOp_i.hxx`` du package
-``MEDMEM_I``). C'est au sein des instances de cette classe que sont
-réalisées les opérations et que sont produites physiquement les
-données. Typiquement, les opérations présentées ici produisent un
-champ ``MEDMEM::FIELD`` sur la base duquel elle fabrique un servant
-``SALOME_MED::FIELD`` pour finalement retourner un pointeur CORBA sur
-ce servant.
-
-Ce mécanisme global peut être étendu sans limitation à tout les types
-d'opération qui sont envisagés dans les spécifications de manipulation
-des champs dans SALOME.
-
-
-Contrôle visuel des champs
---------------------------
-
-Les illustrations ci-dessous montrent qu'une fonction de visalisation
-est implémentée dans la maquette pour permettre le contrôle visuel
-d'un champ au moyen d'une représentation 3D (une carte spatiale du
-module du champ dans l'exemple implémenté par défaut):
-
-.. |IMG_VISU| image:: images/medop-gui-visufield_scale.png
-.. |IMG_RESULT| image:: images/medop-gui-result_scale.png
-
-+---------------+---------------+ 
-| |IMG_VISU|    | |IMG_RESULT|  |
-+---------------+---------------+ 
-
-Cette fonction répond au besoin de contrôle interactif des résultats
-produits par les opérations de manipulation de champs.
-
-Il s'agit là d'un usage classique de SALOME, dans lequel on demande au
-module VISU de faire une représentation 3D d'un champ spécifié par la
-donnée du servant ``SALOME_MED::FIELD`` qui lui est associé
-(représenté par la variable ``field_ptr`` dans l'exemple ci-dessous):
-
-.. code-block:: python
-   
-   import salome
-   import VISU
-
-   visuComp = salome.lcc.FindOrLoadComponent("FactoryServer", "VISU")
-   visuComp.SetCurrentStudy(salome.myStudy)
-
-   # Then we can import the specified field in the VISU module. This
-   # creates an study entry in the VISU folder.
-   result = visuComp.ImportMedField(field_ptr)
-
-   meshName   = field_ptr.getSupport().getMesh().getName()
-   fieldName  = field_ptr.getName()
-   iterNumber = field_ptr.getIterationNumber()
-   scalarmap = visuComp.ScalarMapOnField(result,
-                                         meshName,
-                                         visuEntityType,
-                                         fieldName,
-                                         iterNumber)
-
-Dans ce jeu d'instructions donné pour exemple (non fonctionnel, en
-particulier à cause de la non définition de la variable
-``visuEntityType``, voir remarque plus bas), le composant VISU
-désigné ici par la variable ``visuComp`` va chercher les données du
-champ en interrogeant le servant ``SALOME_MED::FIELD`` transmis en
-argument de la fonction ``ImportMedField``, puis produit une
-représentation de type "scalarmap".
-
-.. note:: Compte-tenu des propriétés de la classe FieldProxy décrites
-   plus haut conférées par le pattern "Proxy", on peut transmettre ici
-   aussi bien le servant CORBA que l'instance du proxy (la fonction
-   ``ImportMedField`` n'y verra que du feu).
-
-Le code complet et fonctionnel de la fonction d'affichage est dans le
-corps du module python ``fieldproxy.py`` sous la forme d'une fonction
-de nom ``visuField``. Il convient de noter que cette fonction doit
-établir une correspondance entre le type des entités tel que défini
-dans MED et dans VISU:
-
-.. code-block:: python
-
-    medEntityType = field_ptr.getSupport().getEntity()
-    if (medEntityType == SALOME_MED.MED_CELL):
-        visuEntityType = VISU.CELL
-    elif (medEntityType == SALOME_MED.MED_NODE):
-        visuEntityType = VISU.NODE
-
-
-Export des résultats de calcul
-------------------------------
-
-Tous les champs produits à l'occasion des opérations entre objets
-``FieldProxy`` sont automatiquement ajoutés à la structure med à
-laquelle is sont associés. Une convention d'attribution des noms est
-implémentée de sorte que par défaut aucune précision n'est demandée à
-l'utilisateur.
-
-La structure med peut être manipulée au moyen de la variable ``med``
-créée dans l'interface textuelle comme une instance de la classe
-``MedProxy``. La classe ``MedProxy`` fournit un objet qui présente
-l'interface du servant ``SALOME_MED::MED`` étendue de quelques
-fonctions utilitaires pour la gestion et le contrôle des données.
-
-En particulier, la sauvegarde de la structure dans un fichier est
-automatisée par la méthode ``save(medfilename)``:
-
-.. code-block:: python
-
-   med = medproxy.MedProxy(medObj)
-   med.save("/tmp/output.med")
-
-Cette méthode s'occupe de définir un driver d'écriture et de procéder
-à l'enregistrement des données de la structure med (les maillages, les
-champs présents au départ et tous les champs produits depuis la
-lecture initiale).
-
-Limitations
-===========
-
-L'implémentation de la maquette limite l'usage des opérations aux cas
-de figure suivants:
-
-* Seules les operations entre champs qui partagent le même support med
-  sont possibles. Ceci est une contrainte imposé par la conception
-  actuelle de MEDMEM.
-* Le résultat d'une opérations est calculé sur toutes les composantes
-  et tout le domaine de définition des champs en opérande. Cette
-  deuxième contrainte est juste parce que les usages plus fin,
-  notemment avec la notion de domaine de définition, n'a pas encore
-  été exéminée à ce jour.
-* Le nom d'un champ produit par une opération ne correspond pas au nom
-  de la variable python par laquelle on le réceptionne et on le
-  manipule. Le nom est attribué par une convention (ceci n'est pas
-  vraiment une limitation mais une caractéristique à connaître).
-
-On note également les restriction techniques suivantes:
-
-* Les données MEDMEM sont supposées être chargées par le composant MED
-  puis référencées dans l'étude SALOME (comme c'est fait aujourd'hui
-  par le module MED).
-* Dans certain cas, python n'est pas ton ami. Pour que les opérateur
-  de la classe ``FieldProxy`` soient pris en considération dans les
-  opérations sur les champs, il est indispensable que le premier
-  opérande d'une opération unitaire soit un champ (objet de classe
-  ``FieldProxy``). Par exemple: "field_offset = field + 5.3"
-  fonctionne alors que "field_offset = 5.3 + field" ne fonctionne pas
-  car python tente de traiter la situation au moyen de la fonction
-  ``__add__`` de la classe ``float`` (qui n'est pas modifiable).
-
-
-Notice informatique
-===================
-
-Gestion de configuration
-------------------------
-
-Les développements décrits dans ce chapitre sont répartis entre les
-modules MED et XMED (développé pour l'occasion). Cette séparation est
-faite par soucis de clarté et d'efficacité de développement, mais les
-éléménts du module XMED ont vocation à intégrer le module MED dans la
-mesure où les propositions techniques sont retenues pour le
-développement à venir.
-
-Le code source du module XMED peut être récupérés par la commande
-suivante::
-
- $ svn co svn://nepal.der.edf.fr/FIELD/XMED_SRC/trunk XMED_SRC
-
-Le pré-requis est la plate-forme SALOME version 5.1.4 (ou plus)
-équipée au minimum des modules KERNEL, GUI, MED (branche BR_medop) et
-VISU. Pour récupérer la branche BR_medop du module MED, taper la
-commande::
-
- $ cvs -d :pserver:anonymous@cvs.opencascade.com:2401/home/server/cvs/MED co -r BR_medop MED_SRC
-
-La configuration de référence est:
-
-* XMED: révision svn 41
-* MED: tag cvs BR_medop_20101025
-
-Moyens de tests
----------------
-
-Plusieurs types de tests unitaires sont définis (reste à les
-automatiser proprement):
-
-* Test des servants et utilitaires de manipulation python:
-
-  - Dans XMED, package xmed/tests, utiliser le script
-    ``test_medoperation.py`` dans un interpréteur python lancé dans
-    une session shell SALOME. Ce script prépare des variables de test
-    et fournit des fonctions de test unitaire (à exécuter ou pour s'en
-    inspirer). Après avoir lancé SALOME via une application virtuelle,
-    on peut taper::
-      $ <APPLI_ROOT>/runSession
-      [NS=venus:2810] $ python -i test_medoperation.py
-      >>> 
-   
-  - Ceci permet de tester en particulier l'interface ``MedOp`` et son
-    utilisation dans le module python ``fieldproxy.py``.
-
-* Test des classes MEDMEM:
-
-  - Test de MEDMEM::MedDataManager dans ``MEDMEM_MedDataManager_test.cxx``
-
-Un fichier de test basique (mais néanmoins suffisant) de nom
-``tesfield.med`` est fourni avec les sources dans le répertoire
-``<XMED_SRC>/resources/datafiles`` et dans l'installation au niveau du
-répertoire ``<INSTALLDIR>/share/salome/resources/xmed/datadir``. Il
-contient deux champs ``testfield1`` et ``testfield2`` définis sur un
-pas de temps unique (dt,it=-1,-1). Ces champs définissent des valeurs
-par éléments (MED_CELL).
diff --git a/src/MEDOP/doc/sphinx/xmed-prototype-medmem.rst b/src/MEDOP/doc/sphinx/xmed-prototype-medmem.rst
deleted file mode 100644 (file)
index da331c0..0000000
+++ /dev/null
@@ -1,513 +0,0 @@
-.. meta::
-   :keywords: maillage, champ, MED, MEDMEM
-   :author: Guillaume Boulant
-
-.. include:: xmed-definitions.rst
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-Note de travail concernant l'utilisation de MEDMEM
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-Le module MED de SALOME comporte plusieurs composants d'intérêt pour
-la manipulation de champs:
-
-* la bibliothèque MEDMEM qui fournit une interface de programmation
-  pour manoeuvrer une structure MED
-* le module CORBA SALOME_MED qui matérialise le composant SALOME
-  (serveur corba) du module MED
-* l'interopérabilité avec le module VISU qui permet la visualisation
-  des champs manipulés dans MED
-
-Les sections ci-après donnent quelques éclairages techniques sur ces
-différents aspects. Les sources de démonstration peuvent être
-récupérés depuis le dépôt svn::
-
- $ svn export svn://nepal.der.edf.fr/OM/manifield/trunk manifield
- $ svn export svn://nepal.der.edf.fr/FIELD/demofield/trunk demofield
-
-.. contents:: Sommaire
-   :local:
-   :backlinks: none
-
-Présentation synthétique de MED
-===============================
-
-MED désigne un modèle conceptuel pour décrire des données de type
-éléments finis (éléments finis, volumes finis et éléments
-discrets). Dans l'usage courant, il permet la description et l'échange
-des données de calcul de type maillages et champs. La documentation
-complète peut être trouvée à l'URL suivantes:
-
-* |LINK_EDF_MEDDOC|_ (version 2.3).
-
-On distingue deux implémentations informatiques de ce modèle:
-
-* MED fichier: qui permet la lecture et l'écriture de données depuis
-  un fichier au format med. Les opérations de lecture/écriture sont
-  atomiques (pas de chargement de la structure de données globale).
-* MED mémoire (noté MEDMEM): qui permet le chargement en mémoire d'une
-  image de la structure de données MED contenue dans un fichier au
-  format med. Les opérations peuvent être atomiques ou
-  globales.
-
-On notera simplement ici que MEDMEM utilise MED fichier pour les
-opérations de lecture/écriture et que MED fichier est indépendant de
-MED mémoire. La documentation complète de MED fichier peut être
-trouvée à l'URL suivante:
-
-* |LINK_EDF_MEDFICHIERDOC|_
-
-La bibliothèque MEDMEM
-======================
-
-Le modèle de classes MEDMEM est structuré autour des notions de MESH
-(les maillages), de SUPPORT (le profil des entités) et de FIELD (les
-champs). Ces notions reprennent en partie des concepts du modèle
-MED. Le diagramme ci-dessous présente les classes principales:
-
-.. image:: images/med-uml-main_60pc.png
-   :align: center
-
-Le conteneur de plus haut niveau dans MEDMEM est la classe MED. La
-figure ci-dessous indique qu'une instance MED peut être associée à
-plusieurs maillage et plusieurs champs. Par contre un champ donné ne
-peut être associé qu'à un seul maillage (par l'intermédiaire du
-support). Plusieurs champs peuvent être associés au même maillage. La
-forme la plus courante est d'ailleurs une instance composé d'un
-maillage unique sur lequel sont définis plusieurs champs.
-
-On peut avoir également des configurations plus complexes, comme par
-exemple un maillage unique, plusieurs champs définis sur ce maillage
-mais avec des supports différents, par exemple parce que les valeurs
-sont définies sur des entités de maillage différentes (les éléments
-pour un champ, les noeuds pour un autre, ...)::
-
-  field1->support1->mesh
-  field2->support2->mesh
-  field3->support3->mesh
-
-On observe:
-
-* 2 champs U et V doivent avoir le même support (au sens informatique
-  du terme) pour pouvoir être en argument d'une opération (sinon
-  exception). Il faudrait accepter qu'il soit informatiquement
-  différent et vérifier la conformité conceptuelle.
-* Cette contrainte peut se comprendre car physiquement les données
-  sont stockées dans un vecteur qui couvre toutes les mailles. Le
-  support est le seul masque de lecture pour établir la correspondance
-  avec les positions dans le maillage et il est donc important qu'une
-  cohérence soit assurée.
-
-Les objets champs (FIELD) et maillage (MESH)
---------------------------------------------
-
-Un objet MED permet d'accéder aux différentes informations concernant
-les objets MESH, SUPPORT et FIELD, mais il ne permet pas d'accéder aux
-données physiques associées à ces objets (les valeurs des composantes
-pour les champs, les mailles et leur connectivité pour les
-maillages). L'accès aux données physiques est du ressort des objets
-spécifiques MESH, SUPPORT et FIELD.
-
-Un objet MED peut être créé intégralement en mémoire. L'usage plus
-fréquent est de l'initialiser à partir de la donnée d'un fichier
-med. Pour cela, l'objet MED doit être associé à un driver
-d'entrée/sortie branché sur le fichier (``testfilename`` dans
-l'exemple):
-
-.. code-block:: cpp
-   
-   MED *myMed = new MED;
-   MED_MED_RDONLY_DRIVER *driverIn = new MED_MED_RDONLY_DRIVER(testfilename, myMed);
-   driverIn->open();
-   driverIn->readFileStruct();
-   driverIn->close();
-
-A l'occasion de la fonction readFileStruct, la structure interne de
-l'objet MED est enrichie des informations concernant les objets MESH,
-SUPPORT et FIELD contenu dans le fichier. En particulier un
-dictionnaire des champs (variable map interne) est initialisé est
-contient l'ensemble des objets ``FIELD_`` préchargés (i.e. avec les
-méta-données uniquement). Chaque objet ``FIELD_`` ainsi préchargé est
-autonome pour être chargé sur demande. On peut alors requêter l'objet
-MED pour obtenir un champ particulier (spécifié par son nom
-``fieldname`` dans l'exemple):
-
-.. code-block:: cpp
-
-   FIELD<double> *field = (FIELD<double> *)myMed->getField(fieldname, dt, it);
-
-Puis le champ qui lui est associé doit être physiquement chargé pour
-permettre la mise à jour du support:
-
-.. code-block:: cpp
-   
-   MESH * mesh = myMed->getMesh(field);
-   mesh->read();
-   myMed->updateSupport();
-
-Pour enfin charger les valeurs des composantes du champ:
-
-.. code-block:: cpp
-   
-   field->read();
-
-La numérotation des éléments de maillage
-----------------------------------------
-
-Les éléments qui composent un maillage sont caractérisés par:
-
-* Le type d'entité de l'élément, à choisir dans la liste
-  ``MED_EN::medEntityMesh``, qui contient en particulier ``MED_NODE``,
-  ``MED_FACE``, ``MED_CELL``.
-* Le type de géométrie de l'élément, à choisir dans la liste
-  ``MED_EN::medGeometryElement``, qui contient en particulier
-  ``MED_NONE``, ``MED_TRIA3``, ..., ``MED_ALL_ELEMENTS``.
-
-Les éléments sont numérotés par un indice relatif à la catégorie
-géométrique à laquelle ils appartiennent. Ainsi, si le modèle est
-composé de Na arrêtes et Nf faces de type géométrique MED_QUAD4, alors
-ces faces sont numérotées de 1 à Nf dans le modèle MED (et de manière
-persistente dans le fichier med). De même, les arrêtes sont numérotées
-de 1 à Na. Une numérotion globale implicite existe sur les éléments,
-elle consiste à parcourir l'ensemble des types géométriques dans
-l'ordre de définition du modèle de données. Ainsi, si le modèle
-contient uniquement les Na arrêtes et les Nf faces, alors l'indice
-global de la première face est Na+1.
-
-.. note:: Des exemples de code sont disponibles dans le package ``demofield``, fichier ``python/pybasicfields/MEDMEM_tester.py``.
-
-
-Binding python de MEDMEM
-------------------------
-
-Les classes du package ``MEDMEM`` (package du module ``MED`` qui
-implémentent les structures de données C++ de MED mémoire) produisent
-la bibliothèque ``libmedmem.so``. Cette ensemble de classes est en
-partie mis à disposition de l'interface python grace à une couche de
-liaison (binding Python-C++) générée par le logiciel SWIG à partir
-d'un fichier de description d'interface ``libMEDMEM_Swig.i`` (dans le
-package source ``MEDMEM_SWIG``).
-
-Ce fichier d'interface doit être mis à jour dés lors qu'une évolution
-des interfaces publiques des classes C++ MEDMEM est faite ou qu'une
-nouvelle classe est créée (du moins si l'on souhaite profiter de ces
-évolutions dans l'interface python).
-
-Cette mise à jour nécessite de prendre soin au transfert des
-structures de données entre les espaces python et C++. En particulier,
-l'utilisation des template de classe pour décrire les champs typés en
-C++ appelle une précaution de codage particulière de l'interface
-SWIG.
-
-Pour exemple, le fragment de code ci-dessous, extrait du fichier
-``libMEDMEM_Swig.i``, montre comment déclarer la nouvelle classe
-``MedDataManager`` dans l'interface:
-
-.. code-block:: cpp
-   
-   #include "MEDMEM_MedDataManager.hxx"
-
-   class MedDataManager
-   {
-     public:
-      ~MedDataManager();
-      void printFieldDouble(FIELD<double,FullInterlace> * field);
-   
-      %extend {
-        MedDataManager(char * fileName)
-        {
-         return new MedDataManager(string(fileName));
-        }
-        MedDataManager(MED * med)
-        {
-          return new MedDataManager(med);
-        }
-    
-        %newobject getFieldDouble(const char * fieldName, const int dt, const int it);
-        FIELD<double, FullInterlace> * getFieldDouble(const char * fieldName, const int dt, const int it)
-        {
-         return (FIELD<double, FullInterlace> *) self->getFieldDouble(string(fieldName), dt, it);
-        }
-      }
-  
-   };
-
-
-Utilisation de MEDMEM pour la manipulation de champs
-----------------------------------------------------
-
-Des opérations de manipulation de champs sont disponibles dans la
-bibliothèque MEDMEM standard est peuvent être utilisées dans
-l'interface python. Les quelques lignes suivantes illustrent l'usage
-qu'on peut en faire pour exécuter l'addition de deux champs sur tout
-leur espace de définition et pour un pas de temps donné:
-
-.. code-block:: python
-
-    from libMEDMEM_Swig import MedDataManager
-    from xmed.helper import readMed, writeMed
-
-    # Load the medmem data structure from a med file
-    med = readMed("/tmp/input.med")
-    # Then create a med data manager to deal with the fields data
-    dm  = MedDataManager(med)
-    # Get the timestamps (dt,it)=(-1,-1) of the fields "testfield1" and "testfield2"
-    f1 = dm.getFieldDouble("testfield1",-1,-1)
-    f2 = dm.getFieldDouble("testfield2",-1,-1)
-
-    # Create a new field as the sum of f1 and f2
-    r  = f1 + f2
-    # And add this new field to the med data structure
-    med.addField(r)
-
-    # Finally, write the whole data in an output med file
-    writeMed(med,"/tmp/output.med")
-
-.. note:: Cet exemple de code requiert les évolutions de MEDMEM
-   opérées dans la branche BR_medop (pour disposer de la classe
-   MedDataManager en particulier) et le package python ``xmed`` qui
-   fournit quelques fonctions utilitaires pour manoeuvrer les données
-   med (ce package est dans le module XMED et sera probablement à
-   terme intégré au module MED).
-
-Des limitations existent aujourd'hui pour ce type de manipulations:
-
-* les champs doivent partager le même support MED, c'est-à-dire être
-  décrit sur le même maillage et sur les mêmes entités de ce
-  maillage.
-* ...
-
-
-Remarque sur l'implémentation C++
----------------------------------
-
-A noter l'usage de plusieurs formes d'arguments pour les fonctions:
-
-* passage des arguments par valeur ``myfunction(A a);``
-* passage des arguments par référence ``myfunction(A& a);``
-* passage des arguments par pointeur ``myfunction(A* a);``
-
-Le passage des arguments par référence est une facilité d'écriture
-pour éviter de passer un pointeur tout en évitant la récopie des
-données de la variable.
-
-.. _xmed-medmem_corbainterface:
-
-L'interface CORBA SALOME_MED
-============================
-
-Implémentation du composant MED et des servants SALOME_MED::\*
---------------------------------------------------------------
-
-Le composant MED est un servant CORBA qui permet la manipulation de
-données MEDMEM dans l'environnement SALOME. Le composant peut fournir
-des pointeurs vers des instances de l'interface SALOME_MED (objets
-SALOMEMED::MED, SALOME_MED_FIELD, ...). Ces instances sont des
-servants CORBA qui résident dans le container et qui encapsulent les
-données MEDMEM.
-
-Le schéma ci-dessous représente les éléments informatiques qui
-composent l'architecture CORBA du module MED:
-
-.. image:: images/medmem-corba-layers.png
-   :align: center
-
-Les structures MEDMEM (données physiques) et SALOME_MED (wrapping
-CORBA) fonctionnent différement en ce qui concerne le chargement des
-données:
-
-* Dans MEDMEM, les données sont chargées à la demande (fonctions read
-  des objets) et aucune gestion n'est assurée. En particulier l'appel
-  à read alors que la donnée est déjà chargée conduit à une levée
-  d'exception. C'est à l'utilisateur de MEDMEM de prendre en charge ce
-  type de gestion.
-* Dans SALOME_MED, les données sont chargées à la création de
-  l'instance SALOME_MED::MED. Les maillages ainsi que les champs et
-  leurs données sont chargés à ce moment là et gérés dans une table de
-  type HashMap au niveau de la structure SALOME_MED::MED. Cette
-  structure remplie dés lors des fonction de gestion. L'appel à
-  SALOME_MED::MED.getField(...) ne charge pas les données mais renvoie
-  un pointeur SALOME_MED::FIELD_ptr sur les données chargées à
-  l'initialisation (ATTENTION, cette fonction est bugguée dans la
-  branche principale -> Fix dans la branche BR_medop).
-
-Une gestion intermédiaire peut être envisagée: le chargement à la
-demande géré dans une ou plusieurs tables de champs (une pour chaque
-type de valeur numérique). Une implémentation de ce type de gestion
-est illustré dans la classe ``MedDataManager`` du package MEDMEM qui prend
-en charge ce comportement pour les structures de données MED (en
-particulier les champs).
-
-Utilisation du composant MED
-----------------------------
-Le module SALOME MED fournit un module CORBA appelé SALOME_MED. Les
-interfaces de ce module CORBA sont spécifiées par les fichiers idl
-suivants:
-
-* le fichier
-  [http://nepal.der.edf.fr/pub/SALOME_userguide/MED5/doc/salome/tui/MED/MED_8idl.html
-  ``MED.idl``] qui décrit les interfaces des objets manipulés par le
-  module SALOME_MED. On trouve en particulier les objets MESH, SUPPORT
-  et FIELD.
-* le fichier
-  [http://nepal.der.edf.fr/pub/SALOME_userguide/MED5/doc/salome/tui/MED/MED__Gen_8idl.html
-  ``MED_Gen.idl``] qui décrit les interfaces du composant SALOME
-  (c'est-à-dire le composant chargé par la commande
-  ``FindOrLoadComponent("FactoryServer", "MED")`` du
-  lyfeCycleCorba). On trouve:
-
-  - l'interface ``MED_Gen_Driver`` qui hérite de SALOMEDS::Driver
-    pour l'implémentation des services généraux des composants SALOME
-    (persistance hdf, dump)
-  - l'interface ``MED_Gen`` qui hérite des interfaces
-    ``Engines::Component`` et ``MED_Gen_Driver`` pour
-    l'implémentation des services spécifiques du composant MED.
-
-L'implémentation de ces interfaces est faites au niveau de différents
-packages des sources du module MED:
-
-* Le package ``MEDMEM_I`` qui fournit l'implémentation C++ des
-  interfaces décrites par le fichier ``MED.idl``;
-* Le package ``MED`` qui fournit l'implémentation C++ des interfaces
-  décrites par le fichier ``MED_Gen.idl``, et qui correspond à la
-  partie composant classique d'un module SALOME.
-* Le package ``MedCorba_Swig`` qui fournit une interface swig
-  générée à partir de l'implémentation C++ de ``MEDMEM_I`` et
-  ``MED``
-
-L'utilisation peut être illustrée au moyen d'exemples python (i.e. qui
-utilise l'interface swig fournie par MedCorba_Swig). Après l'import
-d'amorce systématique:
-
-.. code-block:: python
-   
-   import salome
-   salome.salome_init()
-   
-   import SALOME_MED
-   from libSALOME_Swig import *
-
-On peut charger le composant SALOME MED:
-
-.. code-block:: python
-   
-   medComp=salome.lcc.FindOrLoadComponent("FactoryServer", "MED")
-
-grâce auquel les services de chargement de la structure MED peuvent
-être invoqués. Par exemple, les commandes suivantes chargent toute la
-structure MED dans l'étude salome passée en argument:
-
-.. code-block:: python
-   
-   filePathName = "myfile.med"
-   medComp.readStructFileWithFieldType(filePathName,salome.myStudyName)
-
-Ce deuxième exemple charge la structure MED mais ne place pas le résultat dans l'étude:
-
-.. code-block:: python
-   
-   filePathName = "myfile.med"
-   medObj = medComp.readStructFile(filePathName,salome.myStudyName)
-
-On récupère à la place un objet de classe |LINK_EDF_SALOME_MED__MED|_
-qui permet une utilisation assez semblable (mais différente on le
-verra plus bas) à MEDMEM:
-
-.. code-block:: python
-
-   fieldIdx     = 1 # WRN maybe there is no field of idx=1
-   iterationIdx = 0
-   fieldName = medObj.getFieldNames()[fieldIdx]
-   dtitfield = medObj.getFieldIteration(fieldName,iterationIdx)        
-   it = dtitfield[0]
-   dt = dtitfield[1]
-   fieldObj = medObj.getField(fieldName,it,dt)
-   nbOfFields = medObj.getNumberOfFields()
-   fieldNames = medObj.getFieldNames()
-    
-   mesh = fieldObj.getSupport().getMesh()
-
-.. note::
-   Observations en vrac:
-
-   * Un FIELD_i possède un champ de type ``MEDMEM::FIELD_`` qui représente
-     le champ informatique réel (objet MEDMEM).
-   * FIELD_i::fieldMap variable static de type map qui semble gérer
-     les différentes instances de FIELD_i (~pattern factory). Cette
-     map peut être requétée au moyen d'un indice de type long  appelé
-     corbaIndex.
-   * Quand on crée un FIELD_i par le constructeur d'argument
-     ``MEDMEM::FIELD_``, le ``MEDMEM::FIELD_`` est ajouté dans la map avec
-     incrément du corbaIndex
-   * La fonction FIELD_i::read(i) redirige vers la fonction read(i) du
-     ``MEDMEM::FIELD_`` associé
-   * A CONFIRMER: Il semble que les fonctions de chargement
-     ``readStructFile*()`` charge toutes les données du fichier med,
-     alors qu'en MEDMEM seules les meta-données sont chargées.
-   * A CONFIRMER: il semble que le chargement d'une structure MED
-     CORBA peut se faire sans passer par le composant (cf. l'interface
-     de MED)
-
-Interface avec le module VISU
-=============================
-
-Des interactions sont possibles entre MED et VISU à partir du moment
-où les données med sont gérées dans l'étude, c'est-à-dire sous la
-forme d'objets SALOME_MED (voir ci-dessus) publiés dans l'étude. Les
-deux conditions sont aujourd'hui nécessaires (objet corba + publié
-dans l'étude) mais il semble que ce ne soit lié qu'à un choix
-d'interface VISU (la fonction ``ImportMed`` en particulier) qui peut
-a priori être modifié. A CONFIRMER.
-
-L'exemple de code ci-dessous (en python, mais il peut être transposé à
-une implémentation C++) montre par exemple comment envoyer au module
-VISU  une requête de visualisation d'un champs hébergé par le module
-MED (en fait, les données sont gérées au travers d'un objet corba
-SALOME_MED "délocalisé" et qui a été référencé dans l'étude dans la
-catégorie du composant MED). Les importations standard (salome,
-SALOME_MED, ...) sont supposées avoir été faites au préalable (voir
-les exemples précédents):
-
-.. code-block:: python
-   
-   # Load the med structure using MED
-   medComp=salome.lcc.FindOrLoadComponent("FactoryServer", "MED")
-   filePathName = "myfile.med"
-   medComp.readStructFileWithFieldType(filePathName,salome.myStudyName)
-    
-   # Get the VISU component
-   import VISU
-   visuComp = salome.lcc.FindOrLoadComponent("FactoryServer", "VISU")
-   visuComp.SetCurrentStudy(salome.myStudy)
-    
-   # Get the sobject associated to the med object named "Med"
-   aSObject = salome.myStudy.FindObject("Med")
-   isPresent, medSObj = aSObject.FindSubObject(1)
-    
-   # Finally, import the med sobject in VISU 
-   result = visuComp.ImportMed(medSObj)
-
-Il est possible de d'aller plus loin et par exemple de déclencher
-l'affichage d'une scalarmap d'un champ spécifique pour une itération
-particulière (voir la fonction
-``TEST_SALOMEMED_requestToVisu_scalarmap`` du fichier
-``SALOMEMED_tester.py`` fourni dans les sources d'exemple).
-
-Liens complémentaires:
-
-* http://nepal.der.edf.fr/pub/SALOME_userguide/VISU_V5_1_3/doc/salome/gui/VISU La documentation utilisateur en ligne du module VISU
-
-
-Notes en vrac
-=============
-
-Questions:
-
-* Comment obtenir le nom du fichier med à partir d'une structure med? 
-* Peut-on imaginer un moyen de fournir l'objet MEDMEM::MED à partir de
-  la donnée de l'objet CORBA SALOME_MED::MED?
-
-Remarques:
-
-* A part, les opérations arithmétiques (+,-,*,/), aucune opération
-  n'est définie.
diff --git a/src/MEDOP/doc/sphinx/xmed-prototype-overview.rst b/src/MEDOP/doc/sphinx/xmed-prototype-overview.rst
deleted file mode 100644 (file)
index c571c6e..0000000
+++ /dev/null
@@ -1,95 +0,0 @@
-.. meta::
-   :keywords: maillage, champ, manipulation, XMED
-   :author: Guillaume Boulant
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-Démonstrateur XMED, vue d'ensemble
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-Le module XMED est un espace d'expérimentation pour le développement
-des opérations de manipulation de champs. Il complète des
-développements intégrés directement dans le module MED et gérés dans
-la branche CVS BR_medop.
-
-Une maquette est au point pour illustrer les propositions en matière
-d'ergonomie d'utilisation et en matière d'architecture technique. La
-maquette permet de réaliser des cas d'utilisation de la forme:
-
-* Chargement d'un fichier med dans le module MED (ou publication par
-  un code de calcul).
-* Sélection graphique des champs de l'étude à mettre à disposition
-  dans la console utilisateur ("calculette" en mode texte qui
-  concraitement correspond à l'interface python de SALOME).
-* Dans la calculette, exécution d'opérations algébriques (+,-,*,/)
-  entre champs avec possibilité d'utiliser des scalaires dans des
-  opérations de type transformation linéaire (y=ax+b ou y et x sont
-  des champs et a et b des scalaires). Egalement quelques fonctions
-  mathématiques standard applicables sur des champs (pow, sqrt).
-* Possibilité de visualiser les champs produits avec VISU
-* Possibilité d'exporter des champs produits dans un fichier med
-
-La figure ci-dessous montre le résultat d'une séquence d'utilisation
-dans laquelle les champs "testfield1" et "testfield2" ont été
-sélectionnés dans l'arbre d'étude pour être utilisés dans la console
-textuelle sous les noms de variables f1 et f2. L'image montre le
-contrôle visuel du résultat de l'opération f1+f2-(f1-f2)^2 tapée en
-ligne de commande:
-
-.. image:: images/medop-gui-result.png
-   :align: center
-
-La séquence ci-après montre le cas d'utilisation complet en
-images:
-
-1. Sélection d'un champs sur un pas de temps dans l'arbre d'étude
-2. Saisie d'un nom de variable (alias) pour manipuler ce champ. Par
-   défaut, le nom du champ est proposé (``testfield1`` ici). Dans
-   l'exemple, l'utilisateur remplace par l'alias ``f1``.
-3. Contrôle visuel du champ ``testfield1`` manipulé par sa variable
-   ``f1`` au moyen de la commande ``f1.visu()``
-4. Chargement du champ ``testfield2`` sous le nom ``f2``, exécution de
-   l'opération ``f1+f2-(f1-f2)^2`` et contrôle visuel du résultat,
-   récupéré ici dans une variable de nom ``result``.
-
-.. |IMG_SELECT| image:: images/medop-gui-selectfield_scale.png
-.. |IMG_ALIAS| image:: images/medop-gui-aliasfield_scale.png
-.. |IMG_VISU| image:: images/medop-gui-visufield_scale.png
-.. |IMG_RESULT| image:: images/medop-gui-result_scale.png
-
-+---------------+---------------+ 
-| |IMG_SELECT|  | |IMG_ALIAS|   |
-+---------------+---------------+ 
-| |IMG_VISU|    | |IMG_RESULT|  |
-+---------------+---------------+ 
-
-La solution technique est construite sur les principes suivants:
-
-* Les données MEDMEM sont physiquement chargées par le composant MED,
-  c'est-à-dire dans le processus ``Container`` de SALOME, et sont
-  référencées dans l'étude SALOME.
-* Les opérations sont physiquement des opérations entre objets MEDMEM
-  purs qui ont lieu dans le composant MED.
-* Les opérations sont pilotées par des objets proxy python instanciés
-  dans la console TUI puis manipulés par l'utilisateur. Ces objets
-  proxy savent accéder aux objets MEDMEM au travers de leur interface
-  CORBA.
-
-Ainsi, l'architecture technique est construite pour pouvoir travailler
-sur des données MEDMEM pur en partant de pointeurs CORBA manoeuvrés
-depuis des objets python dans l'interface textuelle de
-SALOME. L'effort principal a donc porté sur la mise au point de
-l'interface technique qui permet de lier des variables représentant
-les champs au niveau du GUI (techniquement, la calculette est
-l'interpréteur python embarqué dans le GUI, étendu de quelques
-fonctions pour la manipulation de champs), alors que les données
-MEDMEM sont physiquement disponibles uniquement au niveau des
-composants CORBA (et les opérations implémentées dans MEDMEM
-uniquement).
-
-Pour le moment, la maquette est limitée à des operations entre champs
-qui partagent le même support med (contrainte de MEDMEM) et le
-résultat est calculé sur toutes les composantes et tout le domaine de
-définition du champs (cette deuxième contrainte est juste parce que
-les extentions n'ont pas encore été examinées). Enfin, le support de
-gestion des données est supposé être l'étude SALOME et la structure
-MED qui y est publiée.
diff --git a/src/MEDOP/doc/sphinx/xmed-references.rst b/src/MEDOP/doc/sphinx/xmed-references.rst
deleted file mode 100644 (file)
index 30d66ec..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-ANNEXE: Références documentaires
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-.. include:: xmed-definitions.rst
-
-Documents de référence:
-
-* |REF_EDF_VCA_H-I2C-2009-03595-FR|_ - Valérie Cano - décembre 2009
-* |REF_CEA_VBE_MEDMEM|_ - Vincent Bergeaud - janvier 2007
-* |LINK_EDF_MEDDOC|_ - documentation en ligne (EDF)
-
-Présentations:
-
-* |REF_EDF_PRESMANIPCHP01|_ - Valérie Cano, Guillaume Boulant - janvier 2010
-* |REF_EDF_PRESMANIPCHP02|_ - Guillaume Boulant - octobre 2010
-* |REF_EDF_PRESMANIPCHP03|_ - Guillaume Boulant - mars 2011
-* Présentation à la Journée des Utilisateurs de SALOME de 2011 (JUS2011):
-
-  - |REF_EDF_JUS2011_PDF|_ - Anthony Geay (CEA), Guillaume Boulant - novembre 2011
-  - |REF_EDF_JUS2011_OGV1|_
-  - |REF_EDF_JUS2011_OGV3|_
-  - |REF_EDF_JUS2011_OGV4|_
-
-Notes de travail:
-
-* |REF_EDF_GBO_WORKNOTE|_ - Guillaume Boulant - novembre 2010
-* |REF_EDF_ELO_REM|_ - Eric Lorentz - novembre 2010
diff --git a/src/MEDOP/doc/sphinx/xmed-specifications.rst b/src/MEDOP/doc/sphinx/xmed-specifications.rst
deleted file mode 100644 (file)
index 1f8cdab..0000000
+++ /dev/null
@@ -1,918 +0,0 @@
-.. meta::
-   :keywords: maillage, champ, manipulation, med
-   :author: Guillaume Boulant
-
-.. include:: xmed-definitions.rst
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-Module XMED: Spécifications fonctionnelles et techniques
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-(|XMED_SPECIFICATIONS_PDF|_)
-
-Ce texte présente les spécifications informatiques pour le
-développement d'un module de manipulation de champs qui répond à
-l'expression de besoins formulée dans le cahier des charges
-|REF_EDF_VCA_H-I2C-2009-03595-FR|_.
-
-.. contents:: Sommaire
-   :local:
-   :backlinks: none
-
-Description des cas d'application de référence
-==============================================
-
-Plusieurs cas d'applications métier sont identifiés pour piloter le
-développement du module de manipulation de champs:
-
-* **Analyser et post-traiter le résultat d'un calcul**. C'est l'usage
-  principal qui consiste typiquement à créer des champs comme le
-  résultat d'*opérations mathématiques* dont les opérandes sont des
-  champs et des scalaires. On compte également dans cette catégorie
-  les *opérations de restriction* qui permettent d'extraire puis
-  utiliser une partie d'un champs, c'est-à-dire de créer un champ
-  comme la restriction d'un autre champ à une partie de son domaine de
-  définition (certaines composantes, certains pas de temps, limitation
-  à un groupe de mailles).
-* **Comparer des champs issus d'un calcul paramétrique**. Il s'agit
-  d'une variante du cas précédent qui consiste à mesurer et visualiser
-  les variations entre des champs issues de sources de données
-  différentes (différents fichiers med).
-* **Préparer les conditions aux limites d'une calcul**. Il s'agit de
-  pouvoir initialiser un champ sur un maillage ou un groupe de
-  mailles, c'est-à-dire créer un champ de toute pièce sur un
-  support spatial donné, par exemple par la donnée d'une fonction
-  mathématique qui donne les valeurs des composantes en fonction des
-  coordonnées spatiales.
-* **Gérer des données de calcul**. Il s'agit typiquement de pouvoir
-  rassembler au sein d'un même fichier med des champs et des maillages
-  issues de différentes sources de données, et/ou créés au travers des
-  cas d'application présentés ci-dessus.
-
-Modèle conceptuel des données
-=============================
-
-On rappelle ici les concepts utilisés dans le module et les modalités
-d'utilisation de ces concepts. Le point de vue est celui de
-l'utilisateur du module de manipulation de champs. Il s'agit
-essentiellement pour le moment d'éclaircir l'ergonomie d'usage sur le
-plan conceptuel, avant d'aborder la déclinaison en spécifications
-techniques pour lesquelles les particularités du modèle MED devront
-être intégrées à la réflexion.
-
-Concept de champ
-----------------
-
-Le concept central est celui de *champ*, c'est-à-dire une grandeur
-physique exprimée sur un domaine spatial D. La grandeur peut être de
-type scalaire (une température), de type vectorielle (une vitesse) ou
-de type tensorielle (les contraintes). En un point de l'espace, elle
-se définie donc par la donnée d'une ou plusieurs valeurs numériques
-appelées les *composantes* (1 pour un champ scalaire, 3 pour un champ
-vectoriel 3D, 6 pour un champ tensoriel symétrique 3D).
-
-.. note:: Une pratique courante au niveau des codes est de stocker
-   plusieurs grandeurs physiques différentes dans un même champs med
-   (au sens informatique du terme). Par exemple, le champ
-   électromagnétique à 6 composantes, plus le champ de température
-   scalaire peuvent techniquement être stockés dans un même champs med
-   à 7 composantes. C'est pourquoi, le module de manipulation de
-   champs doit fournir des fonctions de restrictions qui permettent
-   d'extraire certaines composantes pour former la grandeur physique à
-   étudier. Dans la suite du document, on part du principe que l'on
-   peut se ramener dans tous les cas au cas d'un champ homogène tel
-   que défini plus haut.
-
-Dans le cadre d'un modèle numérique discret, les valeurs du champ sont
-exprimées pour un nombre fini de positions, qui correspondent à des
-lieux particuliers du maillage. Suivant la nature des modèles de
-calcul, les valeurs peuvent être données par cellule, par face, par
-noeud, aux points de gauss, ...
-
-Ainsi, un champ discret est un objet dont les valeurs peuvent être
-lues selon les dimensions suivantes:
-
-* *La position p dans l'espace*, caractérisée par le type de l'élément
-  de maillage support et son numéro identifiant
-* *La composante c*, caractérisée par son indice (jusqu'à 6
-  composantes dans les modèles physiques envisagés)
-
-L'évolution d'un champ dans le temps peut être exprimée sous la forme
-d'une série temporelle, c'est-à-dire une séquence de champs donnés
-pour des instants discrets. Aussi, si l'on manipule un champ qui varie
-dans le temps, l'accès aux valeurs introduit une dimension
-supplémentaire:
-
-* *Le temps t*, caractérisé par un numéro de pas de temps
-  (correspondant en général à une étape du calcul qui a produit le champ).
-
-.. note:: Il s'agit là d'une représentation conceptuelle standard dont
-   le |LINK_EDF_MEDDOC|_ fait une expression détaillée. En
-   particulier, la position p est déterminée par la donnée du type
-   d'élément support (valeurs aux noeuds, aux mailles, aux noeuds par
-   éléments, aux points de gauss) et de l'indice de cet élément. En
-   général, le type d'éléments support est résolu à l'initialisation
-   et l'indice peut suffire au repérage dans les algorithmes. Le temps
-   t est déterminé par un numéro d'itération, qui peut éventuellement
-   être complété par un numéro d'ordre. Le cas des points de gauss
-   ajoute un cran de complexité dans la mesure où il faut repérer
-   l'entité géométrique (maille, face, arrête) puis le point de gauss
-   de cette entité. A noter que dans le modèle MED, le concept de
-   série temporelle de champ n'est pas explicitement définie et
-   l'accès à des valeurs à différents instants t1 et t2 nécessite le
-   chargement des champs ``F1=F(t1)`` et ``F2=F(t2)``.
-
-Par convention, on utilisera par la suite les notations:
-
-* **U(t,p,c)** pour désigner la valeur de la composante c d'un champ U
-  à la position p et prise à l'instant t; 
-* **U(t,p,:)** pour signifier que l'on manipule l'ensemble de toutes
-  les composantes;
-* **U(t,:,c)** pour signifier que l'on manipule le domaine de
-  définition spatial complet. 
-
-Dans une grande majorité des cas d'usage on travaille à temps t fixé
-et sur un domaine spatiale prédéfini. Aussi on utilisera également la
-notation à deux arguments ``U(:,:)`` ou tout simplement ``U`` (dès
-lors qu'il n'y a pas ambiguïté) pour désigner un champ complet et Uc
-pour désigner la composante c du champ avec c=1..6.
-
-Concept d'opération
--------------------
-Le deuxième concept à préciser est la notion d'*opération*. Une
-opération dans le présent contexte est l'application d'un opérateur
-sur un ou plusieurs champs pour produire une grandeur de type champ ou
-de type valeur numérique.
-
-Par exemple, la formule ``W=OP(U,V)`` indique que le champ W est formé
-à partir des champs U et V en arguments d'une fonction OP. Dans le cas
-d'une opération algébrique comme l'addition (cf. :ref:`Spécification
-des opérations<xmed-specifications>`, le résultat attendu par défaut
-est que pour chaque instant t, chaque position p et chaque composante
-c, on a ``W(t,p,c)=U(t,p,c)+V(t,p,c)`` (que l'on peut noter également
-``W(:,:,:)=U(:,:,:)+V(:,:,:)`` compte-tenu de la convention présentée
-plus haut). Ce n'est cependant pas une règle et l'utilisateur peut
-très bien manoeuvrer les champs en détaillant et mixant les
-composantes (par exemple ``W(:,:,3)=5+U(:,:,1)*V(:,:,2)``), ou encore
-ne travailler que sur un domaine spatial et/ou temporel particulier
-(cf. |REF_EDF_VCA_H-I2C-2009-03595-FR|_ §5.4.1).
-
-On formalise donc le concept d'opération par les propriétés suivantes:
-
-* L'opérateur peut produire un champ (par exemple la somme de deux
-  champs W=sum(U,V)=U+V), une valeur numérique (par exemple la moyenne
-  spatiale d'un champ m=smoy(U)) ou une valeur logique (par exemple le
-  test d'égalité de deux champs b=isequal(U,V));
-* L'opérateur peut être paramétré par la donnée de valeurs numériques
-  (par exemple, le changement d'unité peut être défini comme une
-  multiplication par un scalaire V=multiply(U,1000)=1000*U);
-* L'opérateur est caractérisé par un domaine d'application qui
-  spécifie la portée de l'opération. Ce domaine comporte plusieurs
-  dimensions:
-  - Un domaine temporel T qui spécifie les pas de temps sur lesquels
-    l'opération est appliquée;
-  - Un domaine spatial D qui spécifie la limite de portée de
-    l'opérateur et donc le domaine de définition du champ produit (qui
-    correspond dans ce cas à une restriction du domaine de définition
-    des champs en argument);
-  - Un domaine de composantes C qui spécifie les composantes sur
-    lesquelles l'opération est appliquée;
-
-.. note::
-   Sur le plan informatique, l'opérateur aura également un paramètre
-   appelé *option* qui pourra indiquer par exemple dans une
-   opération unaire V=F(U) si le résultat V est une nouvelle instance
-   de champ ou la valeur modifiée du champ de départ U. Il pourra
-   également être amené à manoeuvrer des paramètres de type chaîne de
-   caractères, par exemple pour les opérations de changement de nom
-   des champs.
-
-De manière générale, on utilisera la notation
-**(W|y)=OP[D,C,T](P,U,V,...)** pour désigner une opération OP:
-
-* **(V|y)**: V ou y désignent respectivement un résultat de type
-  champ ou de type valeur numérique ou logique;
-* **[T,D,C]**: le domaine d'application de l'opérateur avec T le
-  domaine temporel, D le domaine spatial et C le domaine des
-  composantes;
-* **P,U,V,...**: les paramètres numériques P (liste de valeurs
-  numériques) et les champs U,V,... en arguments de l'opérateur;
-
-On note également les particularités suivantes pour certaines
-opérations:
-
-* Le domaine de définition du champ produit par une opération peut
-  être différent du domaine de définition des champs en argument. Par
-  exemple, dans le cas d'une opération de projection de champ, le
-  domaine spatial résultat peut être modifié par rapport au domaine de
-  définition initial, soit par la modification de la zone géométrique,
-  soit par modification des entités de maillage support.
-* En dehors des opérations de type dérivée et intégrale, les valeurs
-  résultats sont déterminées de manière locale en chaque point du
-  domaine d'application. Par exemple, l'addition W=U+V consiste à
-  produire un champ W dont les valeurs en chaque point p sont la somme
-  des valeurs des composantes de U et V en ce point p: ``W=U+V <=>
-  W(:,p,:)=U(:,p,:)+V(:,p,:)`` pour tout point p du domaine
-  d'application D.
-
-Concept de domaine d'application
---------------------------------
-
-Un domaine d'application est associé à une opération (et non pas à un
-champ). Il a pour objectif de restreindre la portée de l'opération en
-terme spatial, temporel, jeu des composantes.
-
-Pour ce qui concerne le domaine spatial D, plusieurs modalités de
-définition sont envisagées:
-
-* la donnée d'un maillage ou d'un groupe d'éléments du maillage;
-* un système de filtres qui peut combiner:
-
-  - une zone géométrique définie indépendamment du maillage (boîte
-    limite par exemple),
-  - des critères conditionnant le calcul (par exemple U(t,p,c)=1 si
-    V(t,p,c)<seuil).
-
-.. warning:: Version 2010: D pourra correspondre au maillage complet
-   et dans la mesure du possible à un groupe d'éléments du maillage
-
-Ce domaine d'application peut être différent du domaine de définition
-des champs mais il doit être compatible (recouvrement spatial partiel
-au moins et même support d'entité de maillage). Ainsi, sans précision
-particulière, une opération s'applique à l'ensemble du domaine de
-définition des champs en argument (qui dans la pratique MED est
-spécifié par le support et correspond en général au maillage
-complet).
-
-Limites d'utilisation
----------------------
-
-Plusieurs situations doivent être examinées pour poser les limites
-d'utilisation:
-
-* Les champs en argument n'ont pas tous le même domaine de définition,
-  par exemple parcequ'il ne sont pas définis sur les mêmes zones
-  géométriques ou parcequ'ils ne sont pas donnés sur le même type
-  d'entité de maillage. On peut imaginer dans ce cas produire le
-  résultat sur les zones de recouvrement uniquement.
-* Le domaine de définition des champs et le domaine d'application de
-  l'opérateur ne sont pas compatibles, par exemple parcequ'on demande
-  une restriction sur une zone géométrique qui ne fait pas partie de
-  la zone de définition du champ d'entrée. A priori, ce type
-  d'opération est déclaré en échec.
-* Les champs en argument ne sont pas définis sur les mêmes pas de
-  temps. Si l'opération est tolérée (techniquement MEDCoupling permet
-  de le faire), le pas de temps résultat est indéfini.
-
-.. warning:: **A faire**: spécifier les modalités de prise en compte de
-   ces différentes situations (au moins sur le plan conceptuel).
-
-Au delà de ces limites conceptuelles, il faut avoir en tête les
-limites techniques liées à l'usage de MED mémoire (paquet
-MEDCoupling). Par exemple, MEDCoupling impose que les champs opérandes
-soient définis sur le même maillage support (on parle ici de l'objet
-informatique correspondant au maillage). Deux champs construits sur le
-même maillage (du point de vue conceptuel) mais issus de deux fichiers
-med différents sont considérés comme des champs définis sur des
-maillages support différents, c'est-à-dire que les objects
-informatiques correspondant aux maillages sont différents (chargés de
-deux fichiers différents). En l'état, il est donc impossible par
-exemple de faire la comparaison de champs résultats d'une étude
-paramétriques. MEDCoupling fournit une solution qu'il faudra mettre en
-oeuvre de manière ergonomique au niveau du module MED. Il est possible
-de changer le maillage support M1 d'un champs par un maillage M2 à
-partir du moment où les maillages M1 et M2 sont identiques
-géométriquement à une erreur près qu'il est possible de spécifier.
-
-.. note:: 
-   D'autres situations limites peuvent être évoquées sous l'angle
-   informatique. Ce sont des situations qui a priori n'ont pas de
-   raison d'exister sur le plan conceptuel mais qui peuvent très bien
-   survenir au niveau du module informatique compte-tenu des
-   particularités du modèle MED. Par exemple:
-   
-   * Le nombre et la nature des composantes ne sont pas identiques
-     pour tous les champs d'entrée. Par exemple, U défini ses
-     composantes comme U(:,:,1)=Ux, U(:,:,2)=Uy, U(:,:,3)=Uz et V les
-     défini comme U(:,:,1)=Uz, U(:,:,2)=Ux, U(:,:,3)=Uy. Cette
-     situation peut être gérée techniquement par exemple au moyen
-     d'une carte de correspondance qui accompagnerai chacun des champs
-     pour exprimer le sens physique de chaque composants (histoire de
-     ne pas ajouter des choux et des carottes).
-
-Spécifications générales
-========================
-
-Le diagramme ci-dessous représente un découpage fonctionnel qui rend
-compte de l'expression des besoins:
-
-.. image:: images/xmed-functions.png
-   :align: center
-
-On peut identifier les fonctionnalités suivantes:
-
-* **Opérations**: fonctions de manipulation de champs proprement
-  dites;
-* **Persistance**: fonctions d'enregistrement persistant et de
-  chargement des données (au format med fichier)
-* **Visualisation**: fonctions de contrôle visuel des champs
-  manipulés
-* **Export des données**: fonction de transposition des données de
-  champs dans un format textuel directement exploitable et de manière
-  autoportante dans une autre application, par exemple en python au
-  moyen des structures de données Numpy.
-
-Ces fonctions s'articulent autour d'un conteneur qui héberge les
-champs manipulés et les supports de ces champs (représenté par le
-cylindre central).
-
-Un scénario d'utilisation type est:
-
-* Préparation des champs à manipuler, par deux moyens complémentaires:
-
-  - Utilisation des fonctions de persistance: chargement depuis un
-    fichier med d'un ensemble de champs qui partagent le même espace
-    de définition;
-  - Utilisation des opérations de champs: chargement d'un maillage
-    depuis un fichier med, puis création ab initio de champs au moyen
-    des opérations de champs;
-
-* Manipulation des champs par application des opérations à
-  disposition, puis contrôle visuel des résultats produits au moyen
-  des fonctions de visualisation mises à disposition par SALOME;
-* Restitution des résultats produits, par deux moyens complémentaires:
-
-  - Restitution des champs produits et/ou modifiés sous une forme
-    persistante (fichier med);
-  - Restitution d'une partie seulement des résultats sous forme de
-    tableaux de valeurs sauvegardés dans un fichier texte ou exporté
-    sous forme de tableau numpy
-
-.. _xmed-specifications:
-
-Spécification des opérations
-============================
-
-Le cahier des charges définit trois catégories d'opérations
-mathématiques:
-
-* **Les opérations arithmétiques**, dans lesquelles le résultat à la
-  position p et à l'instant t ne dépend que des données à la position
-  p et à l'instant t;
-* **Les opérations d'interpolations**, dans lesquelles le résultat
-  est exprimé sur des entités de maillages différentes ou est projeté
-  sur une zone géométrique différente du domaine de définition
-  initial;
-* **Les opérations globales**, dans lesquelles le résultat peut
-  demander l'agrégation des valeurs sur plusieurs position p ou
-  plusieurs pas de temps t (calcul d'extremum, d'intégrale);
-
-Auxquelles, on peut ajouter à des fins de gestion des données:
-
-* **Les opérations de génération**, qui permettent de créer un champ
-  sur un maillage vierge ou d'étendre le domaine spatial de définition
-  d'un champ;
-* **Les opérations d'ordre sémantique**, qui permettent de modifier
-  les méta-données associées aux champs (nom, unité, ...)
-* **Les opérations de diagnostic**, qui permettent d'effectuer une
-  analyse particulière d'un champ et/ou des éléments de maillage
-  associés et de fournir un compte-rendu, sous la forme d'une
-  structure de données ou d'un texte formaté affichable dans
-  l'interface utilisateur.
-
-La suite de la section décrit les spécifications prévues pour chaque
-type d'opération unitaire. Un dernier paragraphe concerne les
-modalités de combinaison des opérations et spécifie la définition d'un
-domaine d'application sur une opération, qui permet de restreindre la
-portée de l'opération en terme spatial, temporelle ou nature des
-composantes impliquées.
-
-Les opérations arithmétiques
-----------------------------
-
-Les opérations arithmétiques regroupent:
-
-* les **opérations algébriques** (+, -, x, /);
-* les **opérations vectorielles** (produit scalaire, produit
-  vectoriel, produit tensoriel);
-* l'**application d'une fonction mathématique** à variable scalaire
-  (exponentielle, logarithme, fonctions trigonométriques, valeur
-  absolue, partie entière) ou à variable de type champ (les fonctions
-  de norme par exemple).
-
-Pour les besoins des spécifications informatiques, il est plus commode
-de classer ces opérations en deux catégories:
-
-* les **opérations unaires**, qui prennent un opérande unique en
-  argument. C'est le cas de la plupart des fonctions mathématiques
-  envisagées;
-* les **opérations binaires**, qui prennent deux opérandes en
-  argument. C'est le cas des opérations algébriques et des opérations
-  vectorielles.
-A partir de cette classification, il convient de distinguer trois
-formes d'usage selon la nature des opérandes:
-
-* les opérandes sont exclusivement des scalaires (typiquement des
-  valeurs de composantes des champs et des paramètres numériques). Par
-  exemple::
-    W(:,:4) = 1+2xU(:,:,2)+V(:,:,3)
-
-* les opérandes sont exclusivement des champs. Par exemple::
-
-    W = U + V       (addition)
-    W = U ^ V       (produit vectoriel)
-
-* les opérandes sont des champs et des paramètres numériques. Par exemple::
-
-    W = 3xU - 2xV
-    W = U + 2
-
-Le premier cas de figure (opérandes scalaires) est trivial car les
-règles mathématiques conventionnelles s'appliquent et sont
-implémentées dans tous les langages (Python et C++ en
-particulier). Les cas 2 et 3 par contre doivent être précisés car (i)
-les règles de comportement ne peuvent pas être simplement déduites des
-règles mathématiques (quel est le résultat de ``W = U + 2`` ?) et
-(ii) certaines écritures ne peuvent avoir aucun sens (par exemple
-``W = 2 / U``). Il convient donc de  préciser les conventions et
-les limites sur ces deux cas de figure.
-
-Dans le cas des opérations unaires où l'opérande est un champ, on doit
-distinguer deux cas d'usage:
-
-* l'application d'une fonction mathématique à valeur de type champ. Ce
-  cas est trivial également et on applique la règle d'usage de la
-  fonction. C'est typiquement le cas des fonctions de calcul de
-  norme.
-* l'application d'une fonction mathématique à valeur scalaire. Dans ce
-  cas, on convient d'appliquer la fonction de manière unitaire sur
-  chacune des composantes c du champ: ``W(:,:,c) = OP( U(:,:,c)
-  )``
-
-Dans le cas des opérations binaires, on recense les combinaisons
-d'opérandes suivantes (les lettres capitales représentent des champs,
-et les lettres minuscules une valeur scalaire qui peut être un
-paramètre numérique ou la composante d'un champ):
-
-* U+V ajoute les composantes en regard: W(:,:,c)=U(:,:,c)+V(:,:,c)
-* U-V soustrait les composantes en regard: W(:,:,c)=U(:,:,c)-V(:,:,c)
-* U*V multiplie les composantes en regard: W(:,:,c)=U(:,:,c)*V(:,:,c)
-* U/V divise les composantes en regard: W(:,:,c)=U(:,:,c)/V(:,:,c)
-* U+x ajoute x à toute les composantes: W(:,:,c)=U(:,:,c)+x
-* U*x multiplie toutes les composantes par x: W(:,:,c)=U(:,:,c)*x
-* U.V produit scalaire des champs U et V: W(:,:c)=U(:,:,c)*V(:,:,c)
-* U^V produit vectoriel des champs U et V: W(:,:1)=U(:,:,2)*V(:,:,3)-U(:,:,3)*V(:,:,2), ...
-
-.. note::
-   Pour ce qui concerne les opérations vectorielles, un convention
-   implicite est appliquée par laquelle on suppose que les composantes
-   sont rangées dans l'ordre des dimensions spatiales U1=Ux, U2=Uy,
-   U3=Uz. Sur le plan informatique au niveau du modèle MEDMEM, ceci
-   n'est pas garanti et aucun élément du modèle ne permet de
-   contraindre l'application de cette convention. Il convient donc de
-   prévoir des fonctions techniques qui permettront de mettre en
-   correspondance les indices de composantes et les dimensions
-   spatiales (par exemple par la données d'une carte de correspondance
-   applicable à un ensemble de champs).
-
-.. warning::
-   A développer:
-   
-   * Analyse dimensionnelle du champ résultats pour adapter
-     l'unité. Par exemple, si on fait UxV où U et V sont exprimés en
-     [m] alors le résultat est en [m2].
-
-Les opérations d'interpolation
-------------------------------
-.. warning:: Non prévues au programme 2010.
-
-Les opérations mathématiques globales
--------------------------------------
-.. warning:: Non prévues au programme 2010.
-
-Les opérations de génération
-----------------------------
-.. warning:: EN TRAVAUX
-
-Les opérations de génération sont des fonctions qui permettent de
-créer un champ sur un domaine du maillage où il n'est pas défini
-initialement. Deux cas de figure peuvent se présenter:
-
-* Le champ n'existe pas et il doit être créé sur un domaine à définir;
-* Le champ existe mais les valeurs ne sont pas définies sur l'ensemble
-  du maillage.
-
-On peut envisager plusieurs modalités de mise en oeuvre:
-
-* le prolongement par une valeur constante (ou plus généralement par
-  une fonction de l'espace?);
-* les valeurs du champs sont données par une fonction f(p,t) qui prend
-  la position p et le pas de temps t en argument;
-* on peut prédéfinir le champ position **r** qui porte les
-  coordonnées spatiales de l'élément de maillage support, puis faire
-  une opération arithmétique standard.
-
-Les opérations d'ordre sémantique
----------------------------------
-.. warning:: EN TRAVAUX
-
-Concerne:
-
-* le changement de nom du champ
-* le changement d'unité du champ (il s'agit ici de conserver la
-  cohérence entre la valeur numérique et l'attribut "unité" d'un
-  champ.
-
-Les opérations de diagnostic
-----------------------------
-.. warning:: EN TRAVAUX. A faire en fonction des besoins des cas d'application
-
-On peut identifier plusieurs types d'opérations:
-
-* les opérations à diagnostic booléen, par exemple
-  b=isequal(U,V)=[U=V] (où [.] signifie évaluation de la condition
-  entre crochers)
-* les opérations à diagnostic textuel, par exemple afficher les
-  méta-données associées à un champs (unité, nom, maillage support,
-  type d'entité, pas de temps, ...)
-* les opérations à diagnostic structuré, qui donneraient une structure
-  de données exploitable au niveau d'un code logiciel.
-
-Combinaison des opérations
---------------------------
-.. warning:: EN TRAVAUX. Indiquer les règles de combinaison (associativité, commutativité, ...)
-
-Définition d'un domaine d'application
--------------------------------------
-Pour rappel, un domaine d'application peut être associé à une
-opération pour restreindre la portée de l'opération en terme spatial,
-temporelle ou nature des composantes impliquées.
-
-.. warning:: Todo: spécifier comment on le définit et les modalités d'applications.
-
-Spécification de l'ergonomie
-============================
-
-L'ergonomie générale d'utilisation du module de manipulation de champs
-est inspirée des logiciels comme octave ou scilab. Elle associe une
-interface graphique, pour sélectionner et préparer les données, avec
-une interface texte (la console python) pour le travail effectif sur
-les données:
-
-* L'**interface graphique** a pour fonction essentielle de sélectionner et
-  préparer les champs à manipuler dans l'interface texte, puis
-  fournit des fonctions pour la gestion générale des données
-  (chargement, sauvegarde, contrôle visuel, export).
-* L'**interface texte** offre un jeu de commandes pour manipuler les
-  champs (afficher les données, effectuer des opérations), piloter les
-  fonctions d'affichage (contrôle visuel au moyen des modules VISU
-  et/ou PARAVIS) et communiquer avec l'interface graphique (ajouter
-  des nouveaux champs dans l'espace de gestion, mettre à jour les
-  méta-données d'un champ).
-
-Sur le plan de l'ergonomie, cela se traduit par un processus de
-travail dans lequel on peut distinguer différentes phases:
-
-* Une phase de préparation des champs à manoeuvrer sous la forme de
-  variables nommées et simples à manipuler dans l'interface
-  textuelle. Lors de cette phase, l'utilisateur spécifie de manière
-  graphique tout ce qui peut être définis à l'avance et pour toute la
-  durée du processus de travail. Par exemple, en spécifiant le nom des
-  fichiers med source des données et les noms des champs à utiliser
-  dans ces fichiers, le pas de temps de travail, le jeu des
-  composantes à considérer, le domaine d'application des opérations;
-* Une phase de manipulation des champs proprement dite, qui a lieu
-  principalement dans l'interface textuelle, et qui peut s'accompagner
-  de contrôle visuel des résultats et/ou d'export à destination
-  d'outils complémentaires indépendants (gnuplot, python, ...);
-* Une phase de restitution des champs produits pour assurer la
-  persistance des données de travail. Tout les champs créés par les
-  manipulations au niveau de l'interface textuelle ne sont pas à
-  sauvegarder, et on on propose donc à l'utilisateur les moyens de
-  choisir les champs à conserver. Cette phase peut amener
-  l'utilisateur à préciser les informations manquantes, comme les noms
-  de fichiers, les noms de champs produits, les unités, ...
-
-Dans ce cadre, l'utilisation type des fonctions de manipulation de
-champs est un processus de la forme suivante:
-
-1. Chargement d'un fichier med dans SALOME et exploration du contenu,
-   composé de maillages, sur lesquels sont définis des champs, pouvant
-   contenir un ou plusieurs pas de temps.
-2. Sélection (graphique) des champs à manipuler, avec la possibilité
-   de préciser des restrictions d'utilisation (pas de temps,
-   composantes, groupe de maille).
-3. Création de nouveaux champs par l'exécution d'opérations
-   algébriques (+,-,*,/) entre champs, l'application de fonctions
-   mathématiques standard (pow, sqrt, abs), ou encore l'initialisation
-   "from scratch" à partir d'un maillage support.
-4. Contrôle visuel rapide des champs produits (avec les modules VISU
-   et/ou PARAVIS de SALOME, pilotés automatiquement depuis l'interface
-   utilisateur)
-5. Enregistrement d'une partie des champs produits dans un fichier med
-
-
-Les espaces de données utilisateur
-----------------------------------
-
-Sur le plan conceptuel, on est amené à définir deux espaces de données
-utilisateur:
-
-* **l'espace des données source** (*dataspace*), dans lequel
-  l'utilisateur définit les sources de données med (*datasource*),
-  c'est-à-dire les fichiers med dans lesquels sont lus les champs
-  et maillages. Cet espace est en lecture seule et permet
-  l'exploration des sources de données (aperçu des maillages et des
-  champs).
-* **l'espace des données de travail** (*workspace*), dans lequel
-  l'utilisateur dépose les champs et maillages à utiliser, puis range
-  les champs produits au travers des fonctions de manipulation de
-  champs.
-
-La figure ci-dessous en donne une représentation imagée avec le
-support de l'interface graphique du module (interface non définitive
-affichée ici pour illustration des spécifications):
-
-.. image:: images/xmed-gui-withframe.png
-   :align: center
-
-.. note:: Techniquement, les données sources sont rangées dans l'étude
-   SALOME et peuvent être explorées au moyen de l'object browser. Les
-   données de travail sont rangées dans un arbre complémentaire et
-   manipulable dans la console python.
-
-Le principe général est que **les données sources ne sont jamais
-modifiées**. Le dataspace est un espace de chargement qui permet
-d'explorer puis de sélectionner les données à manipuler. L'utilisateur
-travaille à partir de maillages et de champs chargés préalablement
-dans cet espace, mais ne peut en aucun cas les modifier
-directement. Pour cela, il doit d'abord les sélectionner pour
-utilisation dans l'espace de travail. Ce choix garantie l'intégrité
-des sources de données et permet de rejouer la séquence de travail à
-partir de zéro en cas de besoin (on efface le tableau noir et on
-recommence). Par ailleurs, il permet d'assister graphiquement la
-définition du champs à manipuler effectivement, en particulier pour
-affecter un nom de variable de manipulation.
-
-Les captures d'écrans suivantes montrent le principe d'utilisation sur
-le cas de la sélection d'un pas de temps à utiliser dans l'espace de
-travail. Les données à manoeuvrer (maillage et/ou champs) sont
-sélectionnées pour utilisation dans l'espace de travail, où elles
-peuvent être modifiées et/ou utilisées dans les opérations de
-champs. Ici, le champ est désigné par la varibale ``f4`` dans
-l'interface textuelle:
-
-* Sur cette première capture, on sélectionne le pas de temps n°4 du
-  champs ``Pulse`` définit sur le maillage ``Grid_80x80`` de la source
-  de données ``timeseries.med`` (concrètement le fichier
-  ``timeseries.med``) pour faire apparaître ensuite le menu contextuel
-  et choisir l'option "Use in workspace":
-
-.. image:: images/xmed-gui-datasource-contextmenu_70pc.png
-   :align: center
-
-* Cette capture montre une fenêtre de dialogue qui invite
-  l'utilisateur à spécifier un alias pour la variable python qui
-  va permettre la manipulation du champ dans l'interface textuelle de
-  l'espace de travail (par défaut, le nom complet du champ est
-  proposé). Ici, l'utilisateur spécifie ``f4``: 
-
-.. image:: images/xmed-gui-datasource-useinworkspace_70pc.png
-   :align: center
-
-* La validation de la fenêtre provoque l'ajout du champs dans l'espace
-  de travail (le champ est désormais disponible à la manipulation) et
-  définit une variable python de nom ``f4`` qui permet la manipulation
-  du champ:
-
-.. image:: images/xmed-gui-datasource-useinworkspace-result_70pc.png
-   :align: center
-
-Modalités d'utilisation
------------------------
-
-.. warning:: cette section est à nettoyer car elle contient des
-   informations redondantes avec d'autres sections précédentes ou pire
-   qui contredisent des sections précédentes.
-
-Dans le cadre défini ci-dessus, une session d'utilisation type est:
-
-* Sélectionner les sources de données puis définir le domaine
-  d'application (espace, temps, composantes), avec éventuellement
-  l'assistance d'une interface graphique;
-* Charger les champs en conséquence dans l'espace de travail. Cette
-  opération propose de définir une variable python pour manipulation
-  dans l'interface textuelle.
-* Effectuer les opérations dans l'espace de travail, c'est-à-dire en
-  ligne de commandes python (ce qui demandera sans doute un travail
-  conséquent de simplification et d'assistance en ligne). Par exemple,
-  si ``fa`` et ``fb`` désignent deux champs définis dans l'espace de
-  travail, alors on peut en faire la somme par la commande::
-  
-  >>> r=fa+fb
-
-* Effectuer les contrôles visuel et les diagnostics en ligne de
-  commandes python (cf. :ref:`Spécification des fonctions de
-  visualisation<specification_visualisation>`)::
-
-  >>> view(r)
-
-* Enregistrer les champs produits dans l'espace de travail sous forme
-  de fichier med.
-
-Sur cette base, on peut envisager une grande variété de cas d'utilisation:
-
-* La structure MED (champs, maillage et groupes de mailles) est
-  chargée dans le dataspace (l'étude SALOME techniquement) et peut
-  être explorée au niveau de l'arbre d'étude. L'arbre peut faire
-  apparaître:
-  - les maillages et les groupes (qui peuvent être utilisés
-    éventuellement pour restreindre le domaine d'application)
-  - les champs dont on peut explorer les composantes et les itérations
-
-* On sélectionne plusieurs champs, éventuellement en sélectionnant les
-  pas de temps, les composantes et les domaines d'application spatiaux
-* Menu contextuel --> Modifier un champ, Créer un champ, Prolonger un
-  champ, ....
-* On choisi pour la suite "Créer un champ", une fenêtre de dialogue
-  s'affiche avec les saisies préremplies avec les données
-  sélectionnées. Il est possible de rajouter des éléments ou préciser
-  le domaine d'application
-* Une partie de la boîte de dialogue est réservée à la saisie de la
-  ligne de commande python qui permet la création du nouveau champ. Le
-  nom dans l'étude pour le nouveau champ, ainsi que son nom python,
-  sont spécifié par l'utilisateur ({{H|un peu à la mode du module
-  system}}).
-* L'opération est exécutée dans l'espace utilisateur (l'interface
-  python), de sorte que les variables soient projetées dans cet espace
-  et manipulables après l'opération au besoin. Par ailleurs,
-  l'utilisateur peut visualiser les ligne de commandes nécessaires à
-  taper pour exécuter sa requête.
-
-.. _specification_visualisation:
-
-Spécification des fonctions de visualisation
-============================================
-
-Dans le cadre du module MED, on appelle *fonction de visualisation*
-une fonction qui permet d'avoir un aperçu graphique d'un champ, par
-exemple au moyen d'une carte de champ construite sur une de ses
-composante. Il s'agit là de vue de contrôle pour avoir une idée rapide
-de la forme du champs. Pour créer des représentations spécifiques, on
-préférera passer par les fonctions d'export vers le module PARAVIS.
-
-Les modules VISU et PARAVIS offre des interface de programmation C++
-et python qui permettent le pilotage depuis un module tiers comme le
-module MED. On peut donc envisager une fonction de visualisation
-intégrée au module de manipulation de champs, c'est-à-dire que l'on
-déclenche sans sortir du module MED, et qui exploite les fonctions de
-visualisation des modules VISU et/ou PARAVIS.
-
-Les captures d'écran ci-dessous illustrent la mise en oeuvre de la
-fonction de visualisation:
-
-* Sélection d'un champ pour faire apparaitre le menu contextuel et
-  choisir l'option "Visualize":
-
-.. image:: images/xmed-gui-datasource-visualize_70pc.png
-   :align: center   
-
-* Cette option déclenche l'affichage d'une carte de champ sur le cadre
-  d'affichage des viewers SALOME:
-
-.. image:: images/xmed-gui-datasource-visualize-result_70pc.png
-   :align: center
-
-Cette fonction est également disponible en ligne de commandes de
-l'interface textuelle. Par exemple si ``f4`` désigne un champ de
-l'espace de travail (importé des données source ou construit par les
-opérations de champs), alors, on obtient une carte de champ par la
-commande::
-
- >>> view(f4)
-
-On peut remarquer d'ailleurs sur la capture d'écran de droite
-ci-dessus que la demande de visualisation déclenche l'exécution de la
-commande ``view`` dans la console de travail sur un champ identifié
-par son numéro (3 dans l'exemple).
-
-.. note:: Tous les champs, qu'ils soient des champs chargés d'une
-   source de données ou construits par des opérations de champs sont
-   identifiés par un numéro unique et invariant tout au long de la
-   session de travail.
-
-Spécification des fonctions de persistance
-==========================================
-
-On adopte le principe de fonctionnement suivant:
-
-* Le module n’assure pas la persistence au sens SALOME du terme,
-  c’est-à-dire qu’il ne permet pas la sauvegarde du travail dans une
-  étude au format hdf, ni le dump sous la forme de script python
-  SALOME. Le besoin n'est pas avéré et on peut même dire que ça n'a
-  pas de sens compte-tenu de l'usage envisagé pour le module MED.
-* Par contre, le module fournit des fonctions de sauvegarde du travail
-  sous forme de fichiers med, l’export vers les modules VISU et
-  PARAVIZ, ou même la sauvegarde de l’historique de l’interface de
-  commandes.
-
-Ainsi donc, l'utilisateur aura une fonction (probablement graphique)
-pour définir la sélection des champs de l'espace de travail à
-sauvegarder.
-
-Spécification des fonctions d'export
-====================================
-
-.. warning:: EN TRAVAUX.
-
-Plusieurs export peuvent être proposés:
-
-* Export des champs vers le module PARAVIZ, dans l'objectif par
-  exemple d'en faire une analyse visuelle plus poussée qu'avec les
-  cartes de champs disponibles par défaut dans le module MED
-* Export des données sous forme de tableau numpy, par exemple pour
-  permettre un travail algorithmique sur les valeurs des champs.
-
-Spécifications techniques
-=========================
-
-Il s'agit d'exprimer ici les contraintes techniques applicables à la
-conception et au développement du nouveau module MED.
-
-Implantation technique du module
---------------------------------
-
-Il est convenu que le module MED existant dans la plate-forme SALOME
-incarne le module de manipulation de champ. Dans la pratique, il
-s'agit d'identifier clairement les parties à conserver, d'une part,
-puis les parties à re-écrire, d'autre part. On peut partir sur les
-hypothèses techniques suivantes:
-
-* Le noyau du module en charge des opérations de manipulation de
-  champs proprement dites est construit sur la base des paquets
-  logiciels MEDCoupling (lui-même basé sur le INTERP_KERNEL) et
-  MEDLoader.
-* L'interface graphique du module MED est complétement re-écrite et
-  remplacée par une interface adaptée spécialement à la manipulation
-  des champs et la gestion des données associées
-* Le contrôle visuel pourra être déclenché dans les visualisateurs
-  SALOME (servis par les modules VISU et/ou PARAVIZ);
-* Le module n'assure pas la persistence au sens SALOME du terme,
-  c'est-à-dire qu'il ne permet pas la sauvegarde du travail dans une
-  étude au format hdf, ni le dump sous la forme de script python
-  SALOME.
-* Par contre, il fournit des fonctions de sauvegarde du travail sous
-  forme de fichiers med, l'export vers les modules VISU et PARAVIZ, ou
-  même la sauvegarde de l'historique de l'interface de commandes.
-
-L'implantation technique des développements est représentée sur la
-figure ci-dessous:
-
-.. image:: images/xmed-implantation.png
-   :align: center
-
-Le schéma représente les packages logiciels qui composent le module
-MED (cf. |REF_CEA_VBE_MEDMEM|_):
-
-* La partie MEDMEM, représentées en blanc. Cette partie est conservée
-  pour compatibilité ascendante au niveau des applications métier qui
-  ont fait le choix historique de s'appuyer sur MEDMEM. Cette partie
-  du module MED aura tendance à disparaitre dans le futur au bénéfice
-  de MEDCoupling et MEDLoader.
-* La partie MEDCoupling, représentée en orange et qui founrnit le
-  modèle MED mémoire de référence (composé de maillage et de champs)
-  et l'interface de programmation pour manipuler le modèle. Le paquet
-  MEDLoader est une extention dédiée à la persistence au format med
-  fichier (lecture et écriture de champs et de maillage dans des
-  fichiers med).
-* La partie à développer pour la manipulation de champ, représentée en
-  bleu.
-
-.. note:: MEDCoupling peut être vu comme une structure de donnée
-   particulièrement adaptée à la manipulation des gros volumes de
-   données, en particulier par l'exploitation des possibilités de
-   parallélisation et la réduction de la tailles des structures de
-   données. En contrepartie, elle peut présenter un périmètre
-   fonctionnel moins large que MEDMEM. Pour cette raison, MEDMEM avait
-   été choisi comme socle de développement du prototype en 2010:
-
-   * MEDCoupling ne permet pas de gérer des maillages composés de
-     plusieurs type de mailles et il est exclus de le faire évoluer
-     dans ce sens (c'est un choix fait pour les objectifs de
-     performances évoqués plus haut);
-   * MEDCoupling ne permet pas de gérer les supports qui expriment les
-     champs aux noeuds par élément ni aux points de gauss. Cette
-     seconde limitation a disparu en 2011.
-
-   Aujourd'hui, on fait clairement le choix de MEDCoupling pour sa
-   qualité et sa robustesse, dans l'objectif d'une meilleure
-   maintenance à long terme. Par ailleurs, les différences
-   fonctionnelles avec MEDMEM, si elles existaient encore en 2012 pour
-   les besoins de la manipulation de champs, pourront être résorbées
-   dans un futur proche.
-
-
diff --git a/src/MEDOP/doc/sphinx/xmed-userguide.rst b/src/MEDOP/doc/sphinx/xmed-userguide.rst
deleted file mode 100644 (file)
index f352660..0000000
+++ /dev/null
@@ -1,749 +0,0 @@
-.. meta::
-   :keywords: maillage, champ, manipulation, guide utilisateur
-   :author: Guillaume Boulant
-
-.. include:: xmed-definitions.rst
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-Module XMED: Guide d'utilisation
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-(|XMED_USERGUIDE_PDF|_)
-
-Ce document est un guide rapide pour l'utilisation du module MED. Il
-montre comment utiliser le module sur la base de quelques exemples de
-référence, inspirés des cas d'utilisation identifiés lors de l'analyse
-des besoins en matière de manipulation de champs.
-
-.. warning:: Le document est autonome, mais il est vivement conseillé
-   de parcourir au préalable (ou en parallèle) :doc:`le document de
-   spécifications<xmed-specifications>`, au moins pour fixer les
-   concepts et la terminologie.
-
-.. contents:: Sommaire
-   :local:
-   :backlinks: none
-
-Présentation générale du module XMED
-====================================
-
-L'ergonomie générale d'utilisation du module de manipulation de champs
-est inspirée des logiciels comme octave ou scilab. Elle associe une
-interface graphique, pour sélectionner et préparer les données, avec
-une interface texte (la console python) pour le travail effectif sur
-les données.
-
-Pour cela, le module propose deux espaces utilisateurs qui sont
-symbolisés par les rectangles rouges et vert sur la capture d'écran
-ci-dessous:
-
-* **l'espace des données** (*dataspace*), dans lequel l'utilisateur
-  définit les sources de données med (*datasource*), c'est-à-dire les
-  fichiers med dans lesquels sont lus les champs et maillages. Cet
-  espace permet l'exploration des maillages et des champs fournis par
-  les différentes sources de données.
-* **l'espace de travail** (*workspace*), dans lequel l'utilisateur
-  peut déposer des champs sélectionnées dans l'espace source, pour
-  ensuite les travailler par exemple pour produire des nouveaux champs
-  au moyen des fonctions de manipulation fournies par l'interface
-  textuelle (console python TUI).
-
-.. image:: images/xmed-gui-withframe.png
-   :align: center
-
-L'utilisation type des fonctions de manipulation de champs suit un
-processus de la forme suivante:
-
-1. Chargement d'un fichier med dans l'espace de données (dataspace) et
-   exploration du contenu, composé de maillages et de champs définis
-   sur ces maillages et pouvant contenir un ou plusieurs pas de temps.
-2. Sélection (graphique) des champs à manipuler dans l'espace de
-   travail (workspace), avec la possibilité de préciser des
-   restrictions d'utilisation (pas de temps, composantes, groupe de
-   maille).
-3. Création de nouveaux champs par l'exécution d'opérations
-   algébriques (+,-,*,/) entre champs, l'application de fonctions
-   mathématiques standard (pow, sqrt, abs), ou encore l'initialisation
-   "from scratch" sur un maillage support.
-4. Contrôle visuel rapide des champs produits (avec les modules VISU
-   et/ou PARAVIS de SALOME, pilotés automatiquement depuis l'interface
-   utilisateur)
-5. Enregistrement d'une partie des champs produits dans un fichier med
-
-
-Tour rapide des fonctions du module XMED
-========================================
-
-Cette section présente des exemples d'utilisation du module XMED sous
-la forme de "storyboard", et illustre au passage les fonctions mises à
-disposition par le module.
-
-.. warning:: Cette section est en travaux. Tant que cet avis n'aura
-   pas disparu, veuillez en considérer le plan et le contenu encore
-   incomplets, temporaires et sujets à caution.
-
-Exemple 1: Explorer des sources de données
-------------------------------------------
-
-.. note:: Cet exemple présente les fonctions:
-
-   * ajouter une source de données
-   * fonctions "Extends field series", "Visualize"
-
-.. |ICO_DATASOURCE_ADD| image:: images/ico_datasource_add.png
-                        :height: 16px
-
-.. |ICO_XMED| image:: images/ico_xmed.png
-              :height: 16px
-
-.. |ICO_DATASOURCE_EXPAND| image:: images/ico_datasource_expandfield.png
-                           :height: 16px
-
-.. |ICO_DATASOURCE_VIEW| image:: images/ico_datasource_view.png
-                         :height: 16px
-
-Au démarrage, le module de manipulation de champs, identifié par
-l'icône |ICO_XMED|, présente une interface vierge:
-
-.. image:: images/xmed-gui-start.png
-   :align: center
-   :width: 800px
-
-La première étape consiste à ajouter une ou plusieurs source de
-données med dans le "dataspace". Pour cela, on clique sur l'icône "Add
-datasource" |ICO_DATASOURCE_ADD| qui propose de sélectionner un
-fichier med:
-
-.. image:: images/xmed-gui-datasource-selectfile.png
-   :align: center
-   :width: 800px
-
-L'opération ajoute une nouvelle entrée (datasource) dans l'espace de
-données (dataspace). Le contenu peut être exploré en parcourant
-l'arborescence. La figure ci-dessous (image de gauche) montre le
-résultat du chargement du fichier ``timeseries.med`` contenant un
-maillage de nom ``Grid_80x80`` sur lequel est défini un champ au noeud
-de nom ``Pulse``. Par défaut, la composition du champs (en terme de
-pas de temps et de composantes) n'est pas affichée pour éviter
-l'encombrement visuel de l'arbre. On doit faire la demande explicite
-au moyen de la commande "Expand field timeseries"
-|ICO_DATASOURCE_EXPAND| disponible dans le menu contextuel associé aux
-champs. Le résultat est affiché sur l'image centrale. La liste des
-itérations du champ ``Pulse`` peut être consultée.
-
-.. |IMG_DATASOURCE_EXPLORE| image:: images/xmed-gui-datasource-explore-zoom.png
-                            :height: 340px
-.. |IMG_DATASOURCE_MENUCON| image:: images/xmed-gui-datasource-menucontextuel-zoom.png
-                            :height: 340px
-.. |IMG_DATASOURCE_EXPANDF| image:: images/xmed-gui-datasource-expand-zoom.png
-                            :height: 340px
-
-+--------------------------+--------------------------+--------------------------+
-| |IMG_DATASOURCE_EXPLORE| | |IMG_DATASOURCE_MENUCON| | |IMG_DATASOURCE_EXPANDF| |
-+--------------------------+--------------------------+--------------------------+
-
-.. note:: En toute rigueur, le concept de *champ* dans le modèle MED
-   désigne une itération donnée. Un ensemble d'itérations est désigné
-   par le terme *série temporelle de champs*. Par abus de langage, et
-   s'il n'y a pas ambiguité, on utilisera le nom du champ pour
-   désigner à la fois le champs proprement dit ou la série temporelle
-   à laquelle il appartient.
-
-Enfin, il est possible au niveau du dataspace de visualiser la forme
-générale du champ au moyen d'une carte scalaire affichée dans le
-viewer de SALOME. Pour cela, on sélectionne le pas de temps à
-visualiser et on utilise la commande "Visualize" |ICO_DATASOURCE_VIEW|
-disponible dans le menu contextuel associé:
-
-.. image:: images/xmed-gui-datasource-visualize-zoom.png
-   :align: center
-   :width: 800px
-
-.. note:: Cette représentation graphique a pour objectif le contrôle
-   visuel rapide. Aussi, les fonctions du module VISU sont employées
-   par défaut, mais il est possible de faire l'affichage des cartes
-   scalaires au moyen du module PARAVIS (choix de préférence non
-   implémenté pour le moment, mais techniquement réalisable).
-
-Exemple 2: Rassembler des champs issus de différentes sources
--------------------------------------------------------------
-
-.. note:: Cet exemple présente les fonctions:
-
-   * fonction "Use in workspace"
-   * fonction "Save"
-
-.. |ICO_DATASOURCE_USE| image:: images/ico_datasource_use.png
-                        :height: 16px
-.. |ICO_WORKSPACE_SAVE| image:: images/ico_workspace_save.png
-                        :height: 16px
-
-L'objectif est de récupérer des données issues de différents fichiers
-med, puis de les rassembler dans un même fichier en sortie.
-
-On commence par ajouter les sources de données med dans l'espace de
-données (dataspace). Dans l'exemple ci-dessous, l'espace de données
-contient deux sources de nom ``parametric_01.med`` et
-``smallmesh_varfiled.med``. La première source contient le maillage
-``Grid_80x80_01`` sur lequel est défini le champ ``StiffExp_01``. La
-deuxième source contient le maillage ``My2DMesh`` sur lequel sont
-définis deux champs de noms respectifs ``testfield1`` et
-``testfield2``:
-
-.. image:: images/xmed-userguide-example2-datasource.png
-   :align: center
-   :width: 800px
-
-Pour l'exemple, on souhaite rassembler les champs ``StiffExp_01`` et
-``testfield2`` dans un fichier de nom ``result.med``. La procédure
-consiste à importer les deux champs dans l'espace de travail
-(workspace), puis à sauvegarder l'espace de travail. Pour cela, on
-sélectionne les champs et on utilise la commande "Use in workspace"
-|ICO_DATASOURCE_USE| disponible dans le menu contextuel. Les deux
-champs sélectionnés apparaissent dans l'arborescence de l'espace de
-travail:
-
-.. image:: images/xmed-userguide-example2-workspace.png
-   :align: center
-   :width: 800px
-
-La sauvegarde de l'espace de travail est faite au moyen de la commande
-"Save workspace" |ICO_WORKSPACE_SAVE| disponible dans la barre
-d'outils du module. Une fenêtre de dialogue invite l'utilisateur à
-spécifier le nom du fichier de sauvegarde:
-
-.. image:: images/xmed-userguide-example2-workspace-save.png
-   :align: center
-   :width: 800px
-
-Ce fichier ``result.med`` peut ensuite être rechargé dans le module
-XMED (ou les modules VISU ou PARAVIS) pour vérifier la présence des
-champs sauvegardés.
-
-.. BUG: plantage à l'utilsation dans XMED d'un fichier rechargé
-.. (invalid mesh on field)
-
-.. _xmed.userguide.exemple3:
-
-Exemple 3: Appliquer une opération mathématique sur des champs
---------------------------------------------------------------
-
-.. note:: Cet exemple présente les fonctions:
-
-   * exécution d'opérations mathématiques dans la console TUI
-   * fonction "put" pour référencer un champ de travail dans la liste
-     des champs persistant.
-   * fonction "Visualize" depuis le TUI.
-
-L'usage le plus courant du module de manipulation de champs est
-d'exécuter des opérations mathématiques dont les opérandes sont des
-champs ou des composantes de ces champs.
-
-On se place dans une situation où les sources de données sont définies
-dans le "dataspace" (dans l'exemple ci-après, une série temporelle de
-nom ``Pulse``, contenant 10 pas de temps, définis sur un maillage de
-nom ``Grid_80x80``, le tout issu du datasource ``timeseries.med``).
-
-Comme vu précedemment, pour manoeuvrer un champ dans l'espace de
-travail, on sélectionne ce champ, puis on exécute la commande "Use in
-workspace" |ICO_DATASOURCE_USE| du menu contextuel. Dans le cas
-présent, un seul champ est sélectionné (contre deux dans l'exemple
-précédent) et la commande ouvre alors une fenêtre de dialogue qui
-permet de préciser les données sur lesquelles on souhaite
-effectivement travailler et comment on veut les manoeuvrer:
-
-.. image:: images/xmed-gui-datasource-useinworkspace-alias.png
-   :align: center
-   :width: 800px
-
-.. note:: En l'état actuel du développement, l'interface propose
-   uniquement de définir le nom de la variable sous laquelle doit être
-   manoeuvré le champ dans la console de travail (TUI). Dans une
-   version ultérieure, il est prévue de pouvoir préciser la ou les
-   composante du champs à utiliser et un groupe de maille pour définir
-   une restriction géométrique. Inversement, il sera également
-   possible de choisir une série temporelle complète pour faire des
-   opérations globales sur l'ensemble des pas de temps.
-
-Aprés validation, le champ est placé dans l'arborescence du
-"workspace" et une variable de nom ``<alias>`` est créée
-automatiquement dans la console de travail pour désigner le
-champ. Dans cet exemple, ``<alias>`` vaut ``f3``, positionné ainsi par
-l'utilisateur pour rappeler que la variable correspond au pas de temps
-n°3:
-
-.. image:: images/xmed-gui-workspace.png
-   :align: center
-   :width: 800px
-
-La manipulation peut commencer. Dans l'exemple ci-dessous, on crée le
-champ ``r`` comme le résultat d'une transformation afine du champ
-``f3`` (multiplication du champ par le facteur 2.7 auquel on ajoute
-l'offset 5.2)::
-
- >>> r=2.7*f3+5.2
-
-On peut poursuivre la manipulation du champs avec une variété
-d'opérations qui sont détaillées dans les spécifications du module
-(cf. :ref:`Spécification des opérations<xmed-specifications>`):
-
- >>> r=f3/1000     # les valeurs de r sont celles du champ f3 réduites d'un facteur 1000
- >>> r=1/f3        # les valeurs de r sont les inverses des valeurs de f3
- >>> r=f3*f3       # les valeurs de r sont celles du champ f3 élevées au carré
- >>> r=pow(f3,2)   # même résultat
- >>> r=abs(f3)     # valeur absolue du champ f3
- >>> ...
-
-Les opérations peuvent utiliser plusieurs opérandes de type champs. Si
-``f4`` désigne le pas de temps n°4 du champ ``Pulse``, alors on peut
-calculer toute combinaison algébrique des deux champs::
-
- >>> r=f3+f4
- >>> r=f3-f4
- >>> r=f3/f4
- >>> r=f3*f4
-
-Avec au besoin l'utilisation de variables scalaires::
-
- >>> r=4*f3-f4/1000
- >>> ...
-
-Dans ces exemples, la variable ``r`` désigne un champ de travail qui
-contient le résultat de l'opération. Par défaut, ce champ de travail
-n'est pas référencé dans l'arborescence du workspace. Si on souhaite
-tout de même le référencer, par exemple pour qu'il soit pris en compte
-dans la sauvegarde, alors on tape la commande::
-
- >>> put(r)
-
-La fonction ``put`` a pour but de marquer le champ en argument comme
-persistent, puis de le ranger dans l'arborescence du "workspace" afin
-qu'il soit visible et sélectionnable. En effet, parmi tous les champs
-qui pourront être créés dans la console pendant la session de travail,
-tous n'ont pas besoin d'être sauvegardés. Certains sont même des
-variables temporaires qui servent à la construction des champs
-résultats finaux. C'est pourquoi, seuls les champs rangés dans
-l'arborescence du workspace sont enregistrés lors de la demande de
-sauvegarde du workspace.
-
-Les variables définies dans la console ont d'autres utilités. Tout
-d'abord, elles permettent d'imprimer les informations concernant le
-champ manoeuvré. Pour cela, on tape simplement le nom de la variable
-puis retour::
-
- >>> f3
- field name (id)        = Pulse (3)
- mesh name (id)         = Grid_80x80 (0)
- discretization         = ON_NODES
- (iter, order)          = (3,-1)
- data source            = file:///home/gboulant/development/projets/salome/MEDOP/XMED/xmed/resources/datafiles/timeseries.med
-
-Elle peut également être utilisée comme argument des commandes de
-gestion disponibles dans l'interface textuelle (dont la liste
-détaillée est décrite à la section :ref:`Documentation de l'interface
-textuelle<xmed.userguide.tui>`). Par exemple, la fonction ``view``
-permet d'afficher la carte scalaire du champ dans le viewer::
-
- >>> view(f3)
-
-Donne:
-
-.. image:: images/xmed-gui-workspace-view.png
-   :align: center
-   :width: 800px
-
-.. note:: On remarquera ici qu'il est facile de comparer deux pas de
-   temps d'un champ, par exemple en calculant la différence ``f3-f4``,
-   puis en affichant un aperçu de la carte scalaire résultat au moyen
-   de la fonction ``view``::
-
-    >>> view(f3-f4)
-
-On peut enfin tout simplement afficher les données du champs par la
-commande ``print``::
-
- >>> print f3
- Data content :
- Tuple #0 : -0.6 
- Tuple #1 : -0.1 
- Tuple #2 : 0.4 
- Tuple #3 : -0.1 
- Tuple #4 : 0.4 
- ...
- Tuple #6556 : 3.5 
- Tuple #6557 : 3.3 
- Tuple #6558 : 1.5 
- Tuple #6559 : 0.3 
- Tuple #6560 : 0.2
-
-Il est important de noter que les opérations entre champs ne peuvent
-être faites qu'entre champs définis sur le même maillage. Il s'agit là
-d'une spécification du modèle MED qui interdit d'envisager les
-opérations entre champs définis sur des maillages géométriquement
-différents. Techniquement, cela se traduit par l'obligation pour les
-objets informatique *champs* de partager le même objet informatique
-*maillage*.
-
-Dans l'hypothèse où on souhaite utiliser des champs définis sur des
-maillages différents, par exemple pour manoeuvrer les valeurs des
-champs à l'interface de deux maillages partageant une zone géométrique
-2D, il faut d'abord ramener tous les champs sur le même maillage de
-surface par une opération de projection.
-
-.. note:: Même si ceci est techniquement possible avec la bibliothèque
-   MEDCoupling, cet type d'opération de projection n'est pas encore
-   disponible dans le module de manipulation de champs (prévu en
-   2012).
-
-Un autre besoin plus classique est l'utilisation de champs définis sur
-des maillages géométriquement identiques, mais techniquement
-différents, par exemple lorsqu'ils sont chargés de fichiers med
-différents. Pour traiter ce cas de figure, la bibliothèque MEDCoupling
-prévoit une fonction de "Changement du maillage support", dont
-l'utilisation au niveau du module de manipulation de champs est
-illustrée dans :ref:`l'exemple 4<xmed.userguide.exemple4>` ci-après.
-
-.. _xmed.userguide.exemple4:
-
-Exemple 4: Comparer des champs issues de différentes sources
-------------------------------------------------------------
-
-.. note:: Cet exemple présente les fonctions:
-
-   * Changement du maillage support "change underlying mesh"
-
-On se place ici dans le cas de figure où des champs ont été produits
-sur le même maillage, au sens géométrique, mais enregistrés dans des
-fichiers med différents. C'est le cas par exemple d'une étude
-paramétrique où plusieurs calculs sont effectués avec des variantes
-sur certains paramètres du modèle simulé, chaque calcul produisant un
-fichier med.
-
-Soit ``parametric_01.med`` et ``parametric_02.med`` deux fichiers med
-contenant les champs que l'on souhaite comparer, par exemple en
-calculant la différence des valeurs et en visualisant le résultat.
-
-Aprés le chargement des sources de données dans le module XMED,
-l'utilisateur se trouve en présence de deux maillages, au sens
-technique du terme cette fois-ci, c'est-à-dire que les champs sont
-associées à des objets informatiques maillage différents, bien que
-géométriquement identiques.
-
-Or, les fonctions de manipulation de champs ne permettent pas les
-opérations sur des champs dont les maillages supports sont différents
-(voir la remarque à la fin de :ref:`l'exemple
-3<xmed.userguide.exemple3>`).
-
-Pour résoudre ce cas de figure, le module de manipulation de champs
-met à disposition la fonction "Change underlying mesh" qui permet de
-remplacer le maillage support d'un champ par un autre à partir du
-moment où les deux maillages sont géométriquement identiques,
-c'est-à-dire que les noeuds ont les mêmes coordonnées spatiales.
-
-.. |ICO_DATASOURCE_CHG| image:: images/ico_datasource_changeUnderlyingMesh.png
-                        :height: 16px
-
-Dans l'exemple proposé, l'utilisateur sélectionne le premier pas de
-temps du champ ``StiffExp_01`` du "datasource" ``parametric_01.med``,
-puis l'importe dans l'espace de travail au moyen de la commande "Use
-in workspace" |ICO_DATASOURCE_USE|. Il sélectionne ensuite le premier
-pas de temps du champs ``StiffExp_02`` du "datasource"
-``parametric_02.med``, mais l'importe dans l'espace de travail au
-moyen de la commande "Change underlying mesh" |ICO_DATASOURCE_CHG|. La
-fenêtre de dialogue ci-dessous s'affiche et invite l'utilisateur à
-choisir le nouveau maillage support par sélection dans l'arborescence
-du "dataspace":
-
-.. image:: images/xmed-gui-datasource-changeUnderlyingMesh.png
-   :align: center
-
-Dans cet exemple, on sélectionne le maillage ``Grid_80x80_01`` support
-du champ ``StiffExp_01``, avec lequel on souhaite faire la
-comparaison. Après validation, l'arborescence du workspace contient le
-champ ``StiffExp_02`` défini sur le maillage ``Grid_80x80_01``:
-
-.. image:: images/xmed-gui-datasource-changeUnderlyingMesh_wsview.png
-   :align: center
-
-.. note:: La fonction "Change underlying mesh" ne modifie pas le champ
-  sélectionné dans le "dataspace" (principe de base de fonctionnement
-  du dataspace), mais crée une copie du champ dans l'espace de travail
-  pour ensuite remplacer le maillage support. D'où le nom par défaut
-  pour le champ ``dup(<nom du champ sélectionné>)`` (dup pour
-  "duplicate").
-
-Il reste à associer une variable à ce champ pour le manipuler dans la
-console. Ceci peut être fait au moyen de la commande "Use in console",
-disponible dans le menu contextuel du workspace.
-
-En définitif, si ``f1`` désigne le champ issu du datasource
-``parametric_01.med`` et ``f2`` le champ issu du datasource
-``parametric_02.med`` par la procédure décrite ci-dessus, alors la
-comparaison des deux grandeurs peut être faite comme pour le cas de
-:ref:`l'exemple 3<xmed.userguide.exemple3>`::
-
- >>> r=f1-f2
- >>> view(r)
-
-.. note:: En remarque générale sur cet exemple, il convient de noter
-   les points suivants:
-
-   * l'égalité géométrique de deux maillages est établie à une marge
-     d'erreur prés qu'il est possible de définir techniquement, mais
-     qui n'est pas ajustable au niveau de l'interface du module de
-     manipulation de champs. Elle est fixée à une valeur standard qui
-     permet de traiter la plupart des cas utilisateur. On verra à
-     l'usage s'il est nécessaire de remonter ce paramètre au niveau de
-     l'interface.
-   * L'utilisateur doit faire la démande explicite de changer le
-     maillage support d'un champ, en prévision de la comparaison de
-     champs issus de datasource différentes. Il s'agit là d'un choix
-     fonctionnel délibéré pour que l'utilisateur garde trace des
-     modifications faites sur les données (pas de modification
-     automatiques à l'insu de l'utilisateur, même sous prétexte
-     d'amélioration de l'ergonomie).
-
-
-Exemple 5: Créer un champ sur un domaine spatial
-------------------------------------------------
-
-.. note:: Cet exemple présente les fonctions:
-
-   * initialisation par une fonction de la position spatiale
-   * initialisation sur un groupe de maille
-
-Le domaine géométrique de définition du champs à créer est spécifié
-ici par la donnée d'un groupe de mailles. Ce cas d'usage est
-typiquement prévu pour produire les conditions de chargement initial
-d'une structure, par exemple en définissant un champ sur une surface
-de la géométrie, identifiée par un nom de groupe de mailles.
-
-.. warning:: DEVELOPPEMENT EN COURS
-
-Exemple 6: Extraire une partie d'un champ
------------------------------------------
-
-.. note:: Cet exemple présente les fonctions:
-
-   * extraire une composante (ou un sous-ensemble des composantes)
-   * extraire un domaine géométrique (valeurs sur un groupe de maille)
-   * extraire un ou plusieurs pas de temps.
-
-.. warning:: DEVELOPPEMENT EN COURS
-
-   On doit illustrer ici les fonctions de restriction, qui
-   permettraient de récupérer certaines composantes uniquement. Le
-   principe est qu'on crée un nouveau champ qui est une restriction du
-   champ argument à une liste de composantes à spécifier (utiliser la
-   fonction __call__ des fieldproxy).
-
-Pour l'extraction des pas de temps, on peut se ramener au cas de
-l'exemple 2 avec une seule source de donnée.
-
-Exemple 7: Créer un champ à partir d'une image to[mp]ographique
----------------------------------------------------------------
-
-.. note:: Cet exemple présente les fonctions:
-
-   * Création d'un champ sans datasource (ni maillage, ni champs), à
-     partir d'un fichier image
-
-En tomographie ou en topographie, les appareils de mesure produisent
-des images qui représentent une grandeur physique en niveaux de gris
-sur un plan de coupe donné. L'image ci-dessous représente par exemple
-une vue interne du corps humain faite par IRM:
-
-.. image:: images/xmed-irm.png
-   :align: center
-   :width: 600px
-
-Cette image est un ensemble de pixels organisés sur une grille
-cartesienne. Elle peut donc être modélisée sous la forme d'un champ
-scalaire dont les valeurs sont définies aux cellules d'un maillage
-réglés de même taille que l'image (en nombre de pixels):
-
-.. image:: images/xmed-irm-field.png
-   :align: center
-   :width: 600px
-
-Le module de manipulation de champ fournit un utilitaire appelé
-``image2med.py`` qui permet d'appliquer ce principe à la conversion
-d'un fichier image en fichier med contenant la représentation de
-l'image sous forme d'un champ scalaire (seul le niveau de gris est
-conservé)::
-
-  $ <xmed_root_dir>/bin/salome/xmed/image2med.py -i myimage.png -m myfield.med
-
-.. |ICO_IMAGESOURCE| image:: images/ico_imagesource.png
-                        :height: 16px
-
-Cette opération de conversion peut être faite automatiquement dans
-l'interface graphique du module au moyen de la commande "Add Image
-Source" |ICO_IMAGESOURCE| disponible dans la barre d'outils. Cette
-commande ouvre la fenêtre suivante pour inviter l'utilisateur à
-choisir un fichier image:
-
-.. image:: images/medop_image2med_dialog.png
-   :align: center
-
-Le nom du fichier med résultat est proposé par défaut (changement de
-l'extention en ``*.med``) mais il peut être modifié. Enfin, on peut
-demander le chargement automatique du fichier med produit pour ajout
-dans l'espace de donnée. Les champs peuvent alors être manipulés comme
-dans les cas d'utilisation standard.
-
-Par exemple, l'image ci-dessous affiche le résultat de la différence
-entre deux images, ajoutée à l'image de référence: si i1 et i2
-désignent les champs créés à partir des deux images, on représente ``r
-= i1 + 5*(i2-i1)`` où le facteur 5 est arbitraire et sert à amplifier
-la zone d'intérêt (en haut de l'oeil gauche):
-
-.. image:: images/xmed-irm-diff.png
-   :align: center
-   :width: 600px
-
-L'exemple ci-dessous est le résultat du chargement d'une image
-tomographique issue du projet MAP (Charles Toulemonde,
-EDF/R&D/MMC). L'image tomographique:
-
-.. image:: images/champ_altitude_MAP.png
-   :align: center
-   :width: 600px
-
-Le résultat du chargement:
-
-.. image:: images/medop_image2med_tomographie.png
-   :align: center
-   :width: 800px
-
-Exemple 8: Continuer l'analyse dans PARAVIS
--------------------------------------------
-
-.. note:: Cet exemple présente les fonctions:
-
-   * Export de champs vers le module PARAVIS.
-
-Les possibilités de représentation graphique des champs fournies par
-le module MED ont pour seul objectif le contrôle visuel rapide. Par
-défaut, le viewer de VISU est employé.
-
-Pour une analyse plus détaillées des champs, il est nécessaire de
-poursuivre le travail dans PARAVIS. Le module de manipulation de
-champs offre une fonction qui simplifie ce passage, en faisant le
-chargement automatique dans PARAVIS et en proposant une visualisation
-par défaut (carte de champs scalaire).
-
-Pour cela, il faut sélectionner dans l'espace de travail les champs à
-exporter, puis déclencher la fonction d'export depuis le menu
-contextuel associé:
-
-.. image:: images/medop_exportparavis.png
-   :align: center
-
-Les champs sélectionnés sont regroupés dans une entrée MED du
-navigateur PARAVIS, et le premier champ est affiché sous forme de
-carte de champ:
-
-.. image:: images/medop_exportparavis_result.png
-   :align: center
-   :width: 800px
-
-.. note:: La fonction d'export est une fonction de confort. La même
-   opération peut être faite manuellement en procédant d'abord à
-   l'enregistrement des champs sous forme de fichier MED, puis en
-   chargeant le fichier généré dans le module PARAVIS pour
-   visualisation.
-
-.. _xmed.userguide.tui:
-
-Utilisation de l'interface textuelle du moduel XMED (TUI)
-=========================================================
-
-Toutes les opérations menées au moyen de l'interface graphique peuvent
-être réalisées (avec plus ou moins de facilité) avec l'interface
-textuelle. Le module de manipulation de champs peut même être utilisé
-exclusivement en mode texte. Pour cela, on lance la commande::
-
- $ <path/to/appli>/medop.sh
-
-Cette commande ouvre une console de commandes ``medop>``. Un fichier
-med peut être chargé et travaillé, par exemple pour créer des champs à
-partir des données du fichier.
-
-Que l'on soit en mode texte pur ou en mode graphique, un séquence de
-travail type dans la console peut ressembler au jeu d'instructions
-suivantes::
-
- >>> load("/path/to/mydata.med")
- >>> la
- id=0    name    = testfield1
- id=1    name    = testfield2
- >>> f1=get(0)
- >>> f2=get(1)
- >>>   ls
- f1      (id=0, name=testfield1)
- f2      (id=1, name=testfield2)
- >>> r=f1+f2
- >>> ls
- f1      (id=0, name=testfield1)
- f2      (id=1, name=testfield2)
- r       (id=2, name=testfield1+testfield2)
- >>> r.update(name="toto")
- >>> ls
- f1      (id=0, name=testfield1)
- f2      (id=1, name=testfield2)
- r       (id=2, name=toto)
- >>> put(r)
- >>> save("result.med")
-
-Les commandes principales sont:
-
-* ``load``: charge un fichier med dans la base de données (utile
-  uniquement en mode texte pur)::
-
-  >>> load("/path/to/datafile.med")
-
-* ``la``: affiche la liste de tous les champs chargés en base de données ("list all")
-* ``get``: définit un champ dans l'espace de travail à partir de son
-  identifiant (utile plutôt en mode texte pur car l'interface
-  graphique permet de faire cette opération par sélection d'un champ
-  dans le dataspace)::
-
-  >>> f=get(fieldId)
-
-* ``ls``: affiche la liste des champs présent dans l'espace de travail ("list")
-* ``put``: met un champ en référence dans l'*espace de gestion*::
-
-  >>> put(f)
-
-* ``save``: sauvegarde tous les champs référencés dans l'espace de
-  gestion dans un fichier med::
-
-  >>> save("/path/to/resultfile.med")
-
-.. note:: On peut faire à ce stade plusieurs remarques:
-
-   * la commande ``load`` charge uniquement les méta-informations
-     décrivant les maillage et les champs (noms, type de
-     discrétisation, liste des pas de temps). Les maillages et les
-     valeurs physiques des champs sont chargées ultérieurement (et
-     automatiquement) dés lors qu'elles sont requises par une
-     opération. Dans tous les cas, les données med (méta-informations
-     et valeurs) sont physiquement stockées au niveau de l'espace
-     *base de données*.
-   * la commande ``get`` définit en réalité un *manipulateur de champ*
-     dans l'espace de travail, c'est-à-dire une variable qui fait la
-     liaison avec le champ physique hébergé dans la base de
-     données. Les données physiques ne circulent jamais entre les
-     espaces, mais restent centralisées au niveau de la base de
-     données.
-
-Les commandes TUI suivantes nécessitent de travailler dans
-l'environnement graphique:
-
-* ``visu``: afficher une carte de champ pour contrôle visuel rapide
-  (pas de paramettrage possible)
-
-  >>> view(f)
-
-
diff --git a/src/MEDOP/doc/sphinx/xmed-workingnotes-2010.rst b/src/MEDOP/doc/sphinx/xmed-workingnotes-2010.rst
deleted file mode 100644 (file)
index 724c9a8..0000000
+++ /dev/null
@@ -1,461 +0,0 @@
-.. meta::
-   :keywords: maillage, champ, manipulation
-   :author: Guillaume Boulant
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-ANNEXE: Note de travail concernant le chantier XMED 2010
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-.. contents:: Sommaire
-   :local:
-   :backlinks: none
-
-Principes directeurs du développement
-=====================================
-
-En matière de développement:
-
-* On ne cherche pas d'emblée à s'inscrire dans la fabrication d'un
-  module SALOME diffusable dans la version d'exploitation 2010 (SALOME
-  6). La raison est double: (i) on souhaite au moins pour 2010 ne pas
-  devoir tenir compte des contraintes de temps SALOME et (ii) le
-  produit envisagé fin 2010 est une maquette qui cherche à éprouver
-  l'ergonomie générale d'utilisation et en aucun cas on ne peut
-  garantir la réalisation d'un module SALOME compatible avec les
-  exigences de mise en exploitation.
-* On ne cherche pas d'emblée à capturer tous les cas d'application,
-  mais à concevoir un développement qui acceptera les extensions de
-  périmètres dans des conditions raisonnables. Aussi, les
-  fonctionnalités développées seront celles qui sont nécessaires à la
-  réalisation des cas d'application de référence;
-
-En matière d'ergonomie:
-
-* L'interface utilisateur de référence (appelé espace de travail dans
-  le volet de spécifications fonctionnelles) est l'interpréteur
-  python. Les fonctionnalités doivent être pensées pour un usage
-  adapté à une interface textuelle (TUI) de ce type.
-* La création d'une interface graphique (GUI) peut être envisagée en
-  complément et comme un moyen de manipuler graphiquement les
-  fonctionnalités développées pour l'interface textuelle et pour aider
-  la préparation des variables dans l'interface python.
-* Le modèle d'un processus de manipulation de champs est:
-
-  - Préparation du jeu de variables U, V, ... représentant les champs
-    à manipuler. C'est à ce stade que l'on résoud la question de
-    sélection des données (dans un champ publié dans l'arbre d'étude,
-    par un module de calcul ou par chargement d'un fichier med)
-  - Utilisation des variables avec une sémantique la plus proche
-    possible du modèle conceptuel et des spécifications
-    fonctionnelles;
-  - Création des variables qui représentent les résultats des
-    fonctions de manipulation;
-  - Persistence (fichier med), visualisation (SALOME) ou export (vers
-    une structure qui peut être directement utilisable en numpy)
-
-Sur le plan technique:
-
-* On souhaite spécifier clairement le conteneur SALOME des fonctions
-  de manipulation de champs. Pour discussion:
-
-  - Il apparaît que les modules SALOME MED et VISU contiennent déjà
-    des fonctions qui peuvent faire partie des fonctions de
-    manipulations de champs (en particulier pour l'exploration des
-    structures MED, leur visualisation et la sélection des données à
-    manipuler).
-  - Dans la mesure où le module MED n'est pas utilisé à ce jour (en
-    tout cas pas sous sa forme de module SALOME) et compte-tenu du
-    caractère obsolescent du module VISU (amené à être remplacé sur le
-    plan fonctionnel  par le module PARAVIS), on pourrait examiner la
-    création d'un module dédié à la manipulation des maillages et des
-    champs par l'agrégation technique au sein d'un même module des
-    fonctions des modules MED et VISU.
-
-Au moins dans un premier temps, on se donne les limites suivantes:
-
-* Une opération ne peut pas combiner des pas de temps différents. Dans
-  l'hypothèse où cette limite venait à être levée, on doit spécifier
-  le pas de temps de la donnée résultat;
-* Le domaine d'application d'une opération pourra être défini
-  exclusivement par la donnée d'un maillage ou un groupe d'éléments du
-  maillage;
-* On ne traite pas le cas des champs qui prennent leurs valeurs aux
-  points de gauss ou aux noeuds par élément. Une particularité de ces
-  types de support est que le repérage de la position implique deux
-  indices (par exemple l'indice de la maille, puis l'indice du point
-  de gauss).
-
-Eléments de conception
-======================
-
-Plan général
-------------
-
-On peut par exemple imaginer une maquette du genre:
-
-* En C++ dans MEDGUI, charger un fichier med et donner une vue de la
-  structure des maillages et des champs dans l'arbre d'étude.
-* Sélectionner un élément (par exemple un pas de temps d'un champ) et
-  le menu contextuel permet d'exporter ce champ dans la console python
-  pour manipulation. Pour cela, s'inspirer de la fonction
-  ``XCADGUI::OnLoadScript()`` du XCADGUI pour manoeuvrer un objet
-  PythonConsole.
-* L'élément est marqué comme ayant été exporté, on peut imaginer une
-  récupération ultérieure.
-* Exporter un deuxième champ cohérent avec le premier (même pas de
-  temps et défini sur le même maillage avec le même support, on
-  s'arrange pour).
-* Dans la console python, faire les opérations sur les champs
-* Publication du champ résultat dans l'arbre d'étude pour sauvegarde
-  ultérieure. C'est a priori le gros morceau qui consiste à faire un
-  objet CORBA MED à partir d'un objet MED standard, en plus défini
-  dans la console python (sous forme d'objet python).
-
-Quand ce premier cas d'utilisation est au point, on peut envisager de
-le compléter par les opérations suivantes
-
-* exporter le résultat med dans un fichier
-* visualiser les champs produits
-
-Plan de développement:
-
-* Faire une maquette en MEDMEM pur d'abord, car quelque soit le choix
-  d'architecture, l'opération physique se déroulera en définitif au
-  niveau de MEDMEM pur.
-* Prévoir une implémentation des opérations sous forme de fonctions
-  informatiques, même les opérations algébriques (+,-,*,/). Pour ces
-  dernières et dans certaines conditions (quand on manipule
-  directement les strutures MEDMEM et non pas les objets CORBA),
-  l'utilisation des formes A+B, A-B, ... peuvent être rendues
-  possibles. Dans ce cas, voir la possibilité de combiner plusieurs
-  opérations algébriques sur une seule ligne: A+B-C*0.3.
-* On peut charger la structure MED sous forme d'objet CORBA publiable
-  dans l'étude, de sorte d'avoir accés aux méta-données et pouvoir par
-  exemple sélectionner les champs d'intérêt. De cet objet CORBA, on ne
-  récupère que les informations nécessaires au chargement d'un champs:
-  le nom du champs, le nom de son maillage associé, les identifiants
-  du pas de temps, au besoin une structure Field non chargée (par
-  exemple pour récupérer plus facilement le maillage).
-* Un mécanisme (à développer à partir du PyConsole par exemple)
-  pourrait alors permettre le chargement des champs sélectionnés dans
-  la console python et sous un nom facile à manoeuvrer. Prendre
-  inspiration sur XCADGUI::LoadIntoPythonConsole().
-* A priori, les données sont physiquement chargée dans le GUI. Au
-  besoin, il semble possible (cf. MED_i::init) de fabriquer une objet
-  CORBA field à partir d'un field standard (à tester).
-
-Une autre idée est de récupérer le pointeur CORBA MED dans la console
-python et de tirer les données à partir de là. Ajouter une couche de
-wrapping python pur pour gérer les cas de simplification (surcharge
-des opérations arithmétiques par exemple).
-
-Besoins complémentaires:
-
-* L'interpréteur doit contenir des éléments d'aide (par exemple un
-  help qui liste les opérations possibles sur les champs chargés)
-* prévoir quelques fonctions de visu et de persistence. Cela commence
-  probablement par des fonctions de publication dans l'étude des
-  champs créés par les opérations de manipulation. Les champs sont
-  physiquement ajouté automatiquement à la structure med par le MedOp
-  mais il n'est pas obligatoirement publié => fournir un moyen de
-  publication.
-
-Limitations actuelles (liées à la conception de MEDMEM):
-
-* les champs doivent être gérés par la même structure MED car ils
-  doivent partager le même support.
-* les opérations possibles dans MEDMEM sont entre champs pris sur un
-  pas de temps (Q: les pas de temps peuvent-ils être différents).
-
-
-Développements
---------------
-
-Développement de classes proxy:
-
-* FieldProxy, FieldTimeSeriesProxy
-* Attention pour les éries temporelles, le SUPPORT med peut être
-  différent en chaque pas de temps (par exemple en cas d'extension
-  spatiale du champ au cours du temps).
-
-MEDMEM_MedDataManager:
-
-* FIX: test de l'implémentation C++ au travers de la fonction test() du
-  MedOperator ==> OK. Quand on fait la même opération depuis python
-  via l'interface SWIG ==> au deuxième appel de getFieldDouble, le
-  destructeur du champ semble être appelé. Pb de gestion des pointeurs?
-
-
-Evolutions à prévoir
-====================
-
-Concernant MEDMEM:
-
-* FIX: SALOME_MED::MED::getField devrait pouvoir être appelée
-  plusieurs fois de suite puisqu'on recycle la référence si elle est
-  déjà chargée.
-* IMP: MEDMEM::MED faire une gestion des chargements des champs (par
-  exemple avec un getField qui renvoie le champ s'il est déjà chargé
-  ou le charge et le renvoie sinon).
-* IMP: Récupérer le nom du fichier med à partir de l'objet MED, en
-  passant a priori par le driver associé. Plusieurs driver peuvent
-  être associés à une structure MED car les données peuvent être
-  chargées en plusieurs fois et de plusieurs fichiers. Il faut donc
-  étendre la structure MED pour avoir accés à la liste des driver puis
-  de cette liste déduire les noms des fichiers.
-* IMP: Opérations combinant des champs sur des support différents ne
-  peuvent pas être faites par l'API (une exception est levée en cas de
-  supports incompatibles), mais on peut imaginer le faire en
-  manoeuvrant les tableaux de données directement.
-* INF: faire le point sur les fonctions utilitaires autour de MEDMEM
-  et de son interface SWIG (ex: dumpMEDMEM.py, med_opfield_test.py).
-* IMP: dans MEDMEM::MED et SALOME_MED::MED, pouvoir enlever un champ
-  préalablement ajouté: une fonction removeField en complément de
-  addField.
-
-Concernant l'interface SALOME_MED:
-
-* IMP: Fonctions algébriques, qui seront implémentées au niveau de la
-  structure MED et requêtées au niveau des classes proxy en spécifiant
-  les identifiants des champs impliqués et les paramétres requis (pas
-  de temps en particulier).
-
-Concernant le module MED:
-
-* IMP: pourvoir exporter la structure med dans un fichier med (la
-  structure ayant pu être enrichie par la publication de champs créés
-  par les operations de champs.
-
-
-Historique des travaux
-======================
-
-20100726 : mise au point du schéma de conception
-------------------------------------------------
-
-Choix entre MEDMEM et MEDCoupling: on reste sur MEDMEM pour plusieurs
-raisons:
-
-* MED Coupling ne peut pas gérer des mailles de dimensions différentes
-  dans un même modèle (choix faits dans un soucis de performance dans
-  l'accès à une structure de donnée compact). On peut contourner le
-  problème en définissant deux champs pour traiter chacun des type de
-  mailles.
-* Un champ repose sur un maillage complet (pas de notion de profil,
-  mais cela peut être émulé en créant deux maillages)
-* Le concept de point de gauss n'existe pas (pas implémenté)
-
-TODO:
-
-* Idéalement, il conviendrait de faire un état des lieux du module
-  MED, en particulier des éléments MEDMEM (le coeur), les interfaces
-  CORBA associées (MED.idl implémenté dans le package source
-  MEDMEM_I), l'engine (composant SALOME d'interface MED_Gen.idl et
-  implémenté dans le package source MED) et le GUI (MedGUI.cxx
-  implémenté dans le package source MEDGUI).
-
-* Ergonomie TUI et modèle CORBA associé:
-
-  1. Charger un objet medmem (puis les objets métier mesh et field)
-     sur un domaine d'application donné.
-  2. En faire des variables disponibles dans l'interface TUI et que
-     l'on peut manipuler dans des opérations algébriques.
-  3. Pouvoir au besoin en faire des objets CORBA pour l'interface avec
-     les autres modules SALOME.
-
-* Compléter le diagramme de la structure informatique de MED (en
-  particulier l'implémentation des interface IDL).
-* Préparer un module de travail XMED (organisation d'une bibliothèque)
-
-Tests à réaliser:
-
-* Est-il possible de faire des opérations algébriques à partir des
-  objets SALOMEMED (objects CORBA MED)?
-* Création d'un objet MED_i à partir d'une objet MED pur préalablement
-  chargé en mémoire.
-
-A retenir:
-
-* Des opérations de champs sont possibles sur des champs à des pas de
-  temps fixés. Si l'opération doit être menée sur plusieurs pas de
-  temps, alors itérer sur chaque pas de temps. L'idée ici est
-  d'introduire le concept de série temporelle de champs en temps
-  qu'objet manipulable.
-* Pour deux champs différents de la même structure MED, la données des
-  identifiants dt et it ne correspond pas forcément au même instant
-  absolu (en tout cas rien ne le garanti, même si c'est tout de même
-  une pratique courante).
-
-20101005 : première maquette de démonstration de l'ergonomie en MEDMEM pur
---------------------------------------------------------------------------
-
-XMED: svn révision 16
-Travailler avec le fichier de donnée testfield.med joint.
-
-
-20101007 : Vers une maquette CORBA
-----------------------------------
-
-Le contexte d'utilisation des opérations de champs est l'environnement
-SALOME. Le support de gestion des données est donc l'étude SALOME. Au
-plus bas niveau, les champs sont des objets MEDMEM instanciés dans une
-session SALOME (soit par un code de calcul intégré, soit par
-chargement des données à partir d'un fichier med). Ces objets sont en
-général référencés dans l'étude SALOME sous la forme d'objets CORBA de
-classe SALOMEMED::FIELD. Plus exactement, l'étude SALOME gère des
-SObject (Study Object) dont un attribut est une référence vers un
-objet CORBA de classe SALOMEMED::FIELD qui lui-même encapsule un objet
-MEDMEM::Field.
-
-On peut donc envisager une solution dans laquelle on donne à
-l'utilisateur des poignées de manipulation des objets
-SALOMEMED::FIELD, par exemple au moyen d'un modèle informatique de
-type proxy. Cela signifie que l'utilisateur ne manipule pas
-directement des objets MEDMEM mais des objets python qui font
-l'interface (à concevoir et implémenter, a priori avec un design
-pattern de type proxy).
-
-L'utilisation directe des objets MEDMEM aurait pu être une solution
-extremement pratique dans la mesure où ces objets en l'état peuvent
-être combinés dans des opérations de champs (c'est déjà
-implémenté). Par contre, ce procédé souffre de limitations importantes
-dans la gestion et la circulation des données pour les différents cas
-d'utilisation envisagés (visualisation, export, transfert à un autre
-module SALOME).
-
-L'avantage de la solution proposée est multiple:
-
-* Elle permet de travailler sur une structure MED cohérente pour
-  intégrer les résultats des opérations de calculs et combiner des
-  champs cohérents entre eux. Tout passe par des classes proxy qui
-  pourront s'assurer de la cohérence des opérations demandées et
-  exécuter automatiquement les fonctions de pré-traitement ou
-  post-traitement requises pour ces opérations. On peut imaginer par
-  exemple que les requêtes d'opération soient envoyées par les classes
-  proxy à la structure MED à laquelle les champs sont associés pour
-  piloter l'opération en MEDMEM pur.
-* Elle permet d'automatiser un certain nombre d'opérations
-  implicites. Par exemple si deux champs ne sont pas définis dans la
-  même unité, un changement d'unité peut être effectué automatiquement
-  par la classe proxy avant de commander l'opération au niveau
-  MEDMEM.
-* Elle permet de laisser les données sur le container SALOME et de
-  réaliser des opérations sans rappatrier les données en local (qui
-  peuvent être en trés grand nombre).
-* Elle permet d'étendre facilement l'ergonomie de manipulation des
-  champs, par exemple en définissant la notion de *série temporelle de
-  champs*, ou encore les concepts de *domaine de définition* évoqués
-  dans les spécifications fonctionnelles.
-* Elle rend immédiat la circulation des données entre modules SALOME,
-  puisque les champs restent accessble par des objets CORBA, en
-  particulier pour la visualisation ou l'export des champs produits
-  par les opérations.
-
-Elle a cependant des inconvénients et/ou limitations:
-
-* Elle nécessite l'implémentation d'une classe proxy pour encapsuler tous
-  les appels aux objets SALOME_MED (et donc MEDMEM). Cette interface
-  se limite a priori aux opérations de champs (les opérations
-  algébriques dans un premier temps).
-* Les champs à manipuler dans une opération donnée doivent être gérés
-  par la même structure MED.
-
-Il est à noter également que les interfaces de programmation de
-SALOMEMED (interface CORBA pour MEDMEM) devront être étendues pour
-permettre des requêtes de manipulations de champs (fonctions addition,
-soustraction, multiplication, ...). Pas de contrainte ici sur
-l'ergonomie puisque la manipulation par l'utilisateur se fera au
-niveau des classes proxy uniquement.
-
-
-Hypothèses:
-
-* On tente ici une maquette qui exploite dans la mesure du possible le
-  fonctionnement actuel du module MED, en particulier la gestion des
-  données dans l'étude.
-* Dans une deuxième version, on pourra examiner sérieusement la
-  révision de la gestion des données dans le module, quitte à la
-  spécifier et maquetter dans XMED pour intégration ultérieure dans
-  MED. Exemple:
-
-  - Pouvoir gérer plusieurs structures med dans l'étude.
-
-* Enfin, on exploite MEDMEM en l'état. Pour les besoins de la gestion
-  des données (gestion des chargements des champs en particulier,
-  références croisées pour retrouver le med à partir du champ par
-  exemple, ...), il pourra être nécessaire de faire évoluer MEDMEM. Il
-  faut pouvoir par ailleurs gérer indifféremment une structure med (et
-  les champs qui y sont associés) qu'elle soit créée en mémoire from
-  scratch ou chargée d'un fichier (donc attention avec les opérations
-  de lecture read(), sur les maillages comme sur les champs). La
-  structure med permet d'obtenir les méta données (meta-field par
-  exemple) mais ne permet pas de savoir si les données sont
-  physiquement chargées ou pas.
-
-
-Révisions:
-
-* XMED svn revision 21 + tarball MED_SRC-20101014-15h26m.tgz.
-  Première version qui permet d'importer un champ dans la console
-  python sous la forme d'un FieldProxy. Ne permet pas encore de faire
-  des opérations. Introduction dans le module MED de l'interface MEDOP
-  pour prendre en charge les opérations sur les champs.
-
-
-20101019 : Maquette de démonstration pour l'addition
-----------------------------------------------------
-
-Cette maquette implémente une solution technique de bout en bout (de
-l'interface python aux objets MEDMEM, en passant par le fieldproxy
-puis les servants CORBA pour les operations, ...) mais sur le
-périmètre de l'addition de champs sur tout leur domaine de définition
-et pour un pas de temps donné.
-
-Limitations:
-
-* gére l'addition de champs de type double uniquement (parceque le
-  reste n'est pas implémenté)
-
-Révisions:
-
-* XMED: svn révision 25
-* MED: cvs tag BR_medop_20101019
-
-
-20101020: Fonctions complémentaires
------------------------------------
-
-Cette version test la faisabilité des fonctions complémentaires pour
-accompagner la manipulation de champs. Cela comprend en particulier:
-
-* **la sauvegarde des champs produits** dans un fichier med (un champ ou
-  toute la structure med). Pour cela, on définit un med proxy comme
-  l'extention du SALOME_MED::MED (prévir plutôt d'implémenter ce type
-  de fonction au niveau C++ pour permettre un usage au niveau du GUI
-  C++?).
-* **la visualisation d'un champ** au moyen du module VISU.
-* **des fonctions d'aide interactives** pour assister l'utilisateur
-  dans la console de manipulation des champs.
-
-
-Questions:
-
-* peut-on sauvegarder un champ unique?
-* peut-on faire en sorte que ce soit l'affectation à une variable qui
-  provoque l'ajout du champ à la structure med (ou plus exactement qui
-  supprime tous les champs intermédiaires).
-
-
-Révision:
-
-* XMED: svn revision 31
-* MED: cvs tag BR_medop_20101025
-
-
-20110606: commit avant transfert dans git
------------------------------------------
-
-* XMED: svn revision 53
-
-Les parties de MED utiles à MEDOP seront reversées dans XMED
-dans une première étape, puis le tout dans MED 6 au final. 
diff --git a/src/MEDOP/doc/sphinx/xmed-workingnotes-2011.rst b/src/MEDOP/doc/sphinx/xmed-workingnotes-2011.rst
deleted file mode 100644 (file)
index 8ba8b80..0000000
+++ /dev/null
@@ -1,473 +0,0 @@
-.. meta::
-   :keywords: maillage, champ, manipulation
-   :author: Guillaume Boulant
-
-.. include:: xmed-definitions.rst
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-ANNEXE: Note de travail concernant le chantier XMED 2011
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-.. contents:: Sommaire
-   :local:
-   :backlinks: none
-
-Cas d'utilisation métier
-========================
-
-On illustre par un exemple (Christophe Vallet, R&D/MMC, 1/7/2011)::
-
- J'ai souvent des fichiers med de résultats de calcul, et j'aimerais y
- ajouter de nouveaux champs issus de champs existants. J'aimerais
- aussi pouvoir créer de nouveaux meds plus petits par extraction de
- certaines composantes de champs, certains groupes ou certains pas de
- temps.
-
-On peut exprimer le besoin sous la forme des cas d'utilisation
-suivants (use cases):
-
-* **UC1: combiner dans un même fichier med des champs issus de
-  plusieurs sources de données**. On peut par exemple charger un
-  premier fichier, puis ajouter à cette base des champs issus d'autre
-  fichiers ou générés par manipulation de champs, ou encore générés
-  par un module de calcul qui produirait directement du MEDCoupling.
-* **UC2: créer un champ contenant certaines composantes d'un autre
-  champ**. On pense ici aux fonctions de restriction, qui permettraient
-  de récupérer certaines composantes uniquement.
-* **UC3: créer un champ contenant certains pas de temps d'un autre
-  champ**. C'est un cas particulier des fonctions de restriction
-  évoquées ci-dessus.
-* **UC4: créer un champ comme la limitation d'un autre champ à un
-  groupe de mailles**. C'est un cas particulier des fonctions de
-  restriction évoquées ci-dessus. Notion de domaine spatial. A
-  priori la notion de groupe est définie dans MEDLoader.
-
-On peut ajouter également les UC identifiés pour la maquette 2010:
-
-* **UC5: comparer des champs issus de source de données différentes**,
-  par exemple des champs chargés de deux fichiers med différents et
-  qui s'appuient sur le même maillage (au moins conceptuellement).  Le
-  problème technique ici est de pouvoir changer le maillage d'un
-  champ, pour ramener tous les champs sur le même maillage (au sens
-  informatique). Ceci est une contrainte de MEDCoupling, les
-  opérations sur des champs A et B imposent que A et B soient définis
-  sur le même maillage, i.e. le même objet informatique.
-* **UC6: créer un champ de toute pièce sur un maillage**, ou un groupe
-  de mailles. Ce cas d'usage est typiquement prévu pour produire les
-  conditions de chargement initial d'une structure. Il s'agit ici
-  d'initialiser un champ à partir de zéro sur une surface prédéfinie
-  de la géométrie (par exemple spécifiée par un nom de groupe de
-  mailles).
-
-Pour UC5: les sources de données sont référencées dans l'object
-browser. On importe explicitement les données dans l'espace de
-travail. On peut détecter que les maillages sont identiques et on
-propose à l'utilisateur de transférer le champ sur le maillage déjà
-présent. Sinon, les champs devront être référencés sur des maillages
-distincts dans l'arbre de l'espace de travail.
-
-Analyses préliminaires pour le chantier 2011
-============================================
-
-On fait le choix pour le chantier 2011 de travailler à partir de la
-bibliothèque MEDCoupling (et non plus MEDMEM comme c'était le cas dans
-le démonstrateur 2011).
-
-Analyse de MEDCoupling et MEDLoader
------------------------------------
-
-MEDCoupling est l'implémentation du modèle de données MED (avec
-recherche de minimisation des dépendances logicielles) et MEDLoader
-fournit une ensemble de fonctions pour le chargement des structures
-MEDCoupling depuis un fichier ou inversement leur sauvegarde sous
-forme de fichiers.
-
-Dans l'implémentation MEDCoupling, un champ est l'ensemble des valeurs
-d'une grandeur physique sur un maillage pour un pas de temps donné. Un
-champ est caractérisé par:
-
-* un support spatial, le maillage
-* un type de discrétisation spatial, défini par l'emplacement des
-  valeurs sur le maillage (sur les noeuds, sur les cellules, aux
-  points de gauss, ...) et le mode d'interpolation spatial (P0, P1,
-  etc)
-* un pas de temps, défini par deux entiers (iteration, order) et un
-  réel (timestamps)
-
-Dans cette implémentation, il existe une association 1..n entre un
-maillage et un champ (alors que dans MEDMEM, la structure
-intermédiaire SUPPORT est implémentée).
-
-MEDCouplingCorba fournit un ensemble de servants CORBA pour manoeuvrer
-des structures MEDCoupling au travers du bus CORBA. L'interface à ce
-jour est délibérément réduite. Des classes dites "Cliente" sont
-fournies pour piloter les servants CORBA depuis un contexte
-client. Par exemple ``MEDCouplingFieldDoubleClient`` fournit une
-fonction de création d'une structure MEDCoupling à partir d'un
-pointeur vers un servant CORBA. La structure est créée localement
-(dans le contexte client) avec duplication des données issue de la
-structure encapsulée par le servant CORBA (récupération par la
-fonction de sérialisation).
-
-Aucune interface CORBA n'est défini pour MEDLoader.
-
-Questions:
-
-* Voir comment sont créés les servants, et surtout comment ils sont
-  récupérés (via le lcc?)
-* Comment peut-on définir un champ sur un groupe de mailles (et non
-  pas sur le maillage complet)? Comment peut-on extraire le champs
-  circoncit à une groupe de mailles pour des opérations.
-
-  - R: méthode changeUnderlyingMesh
-
-* Comment manipuler deux champs chargées de fichiers différents mais
-  construit sur le même maillage (conceptuellement). On peut forcer la
-  réassociation d'un champ sur un autre maillage?
-* Manipuler des champs de pas de temps différents? Différentes
-  composantes d'un ou plusieurs champs?
-* Comment importer un MedCoupling dans PARAVIS? (dans VISU?)?
-
-* mapper sur une image
-
-Improvments:
-
-* MEDLoader::Write should raise an exception if the filepath is not writable
-* MEDDataManager: développer une classe chapeau sur MEDCoupling et
-  MEDLoader pour  aider au chargement et la gestion de données MED
-  (orienté manipulation de champs). Cette classe serait associée des
-  structures légères FieldHandler et MeshHandler et des listes
-  correspondantes pour la navigation dans les méta-données.
-* Sur base du MEDDataManager, prévoir des ports med pour yacs par
-  lesquels pourrait transiter des handler.
-
-Nouveaux concepts à prendre en compte
--------------------------------------
-
-Au démarrage du chantier 2011, on observe que les concepts suivants
-sont introduits dans le module MED: 
-
-* Le conteneur MED n'existe plus, utiliser MEDFILEBROWSER pour charger
-  les fichiers med et obtenir les informations générales sur le
-  contenu.
-* MEDFILEBROWSER: remplace le concept de driver et fournit les
-  fonctions précédemment fournies par la classe MED pour obtenir les
-  informations de structure.
-* Concept d'Extractor pour une lecture sélective des données de champs
-  (suivant un critère d'extraction)
-* Il n'est plus nécessaire d'appeler les méthodes read explicitement
-  sur les objets (MESH et FIELD) pour charger les données. Par
-  ailleurs, on peut définir deux fois le même champs (double
-  chargement a priori) sans lever d'exception).
-
-
-Analyse de conception pour le chantier 2011
-===========================================
-
-Composants SALOME (interfaces IDL)
-----------------------------------
-
-* MEDDataManager: défini une structure FIELD pour identifier un champ
-  dans les requêtes. Il s'occupe également de la récupération physique
-  des données, quelqu'en soit la source (fichier avec MEDLoader, autre
-  module SALOME comme PARAVIS avec une méthode à définir)
-* MEDCalculator: s'occupe des requêtes de calcul dont les arguments sont
-  les structures FIELD du MEDDataManager. Reprendre l'interface de
-  MEDOP.
-
-Use case à réaliser depuis un client python:
-
-* UC01: ajouter un fichier d'entrée et accéder aux informations
-  concernant les champs. Ex: récupérer une structure champs par la
-  donnée des paramètres primaires (nom identifiant, dt, it, nom du
-  maillage).
-* UC02: créer des champs et les ajouter au MEDDataManager
-* UC03: mener des opérations basique sur les champs en console python
-
-Interface Utilisateur
----------------------
-
-L'interface utilisateur est composée des parties suivantes:
-
-* une partie GUI (appelée par la suite MEDGUI) qui s'occupe de piloter
-  le chargement des données dans l'espace de travail, au moyen d'une
-  interface graphique;
-* une partie TUI (appelée par la suite MEDTUI) qui s'occupe de piloter
-  la création de champs, au moyen de commandes exécutées dans la
-  console python.
-
-Le principe est que les champs sont préalablement chargés au niveau du
-composant SALOME au moyen de l'interface graphique (MEDGUI), puis
-manoeuvrés depuis l'application SALOME au moyen de variables proxy
-définies dans la console python (MEDTUI). Au chargement, les champs
-sont indéxés par le MEDDataManager, puis les index sont rendus
-accessibles au niveau du GUI au moyen d'une représentation
-arborescente de la structure MED. Les feuilles de l'arbre
-correspondent à des champs qui peuvent être sélectionnés et dont
-l'index peut être obtenu de la sélection.
-
-L'espace de travail est organisé autour du concept de
-"workspace". L'étude SALOME liste les datasource (les fichiers source
-des données med, mais peut-être aussi les référence vers des objets
-MED déjà existants ou chargé dans PARAVIZ). Une vue complémentaire
-permet de voir la structure fine d'une source de données.
-
-Concernant MEDGUI:
-
-* la représentation des données (les champs et les maillages associés)
-  doit permettre de récupérer par l'interface graphique les
-  identifiants des champs à manipuler (a priori les structures FIELD
-  définies par le composant MEDDataManager). Cela conduit à la mise en
-  place des composants suivants:
-
-  - MedDataModel hérité de TreeData. Il est peuplé avec les
-    méta-données décrivant la structure MED explorée.
-  - MedGuiManager qui permet l'implantation du doc widget de
-    présentation
-
-TODO:
-
-* specifier le concept de workspace (qui a une entrée dans l'étude?)
-  en bijection avec un datamanager
-* identifier des interlocuteur/utilisateur pour l'aspect ergonomie d'usage
-
-Concernant MEDTUI:
-
-* Il fournit les classes FieldProxy
-
-Questions:
-
-* Comment traiter le cas du travail sur des composantes ciblées, plus
-  généralement, comment introduire le concept de domaine
-  d'application?
-* Prévoir des fonctions génériques (initialisation d'un champ sur un
-  maillage avec une fonction analytique de la position, sauvegarder
-  les champs créés dans un fichier med)
-
-
-Tâches de développement
-=======================
-
-T20110622.1: Gestion des données internes
------------------------------------------
-
-**Status: terminé.**
-Suite: fonction de sauvegarde au niveau graphique également
-
-On vise les cas d'utiliation suivants:
-
-* UC1: intégrer dans le datamodel du gui un champ créé dans la console
-  python (et donc présent dans le datamanager du composant). Définir
-  l'utilité?
-* UC2: renommer un champ et plus généralement changer ses méta-données
-  (avec assurance de synchronisation entre toutes les données).
-* UC3: sauvegarder une sélection de champs. La sélection peut se faire
-  dans l'arbre du datamodel gui.
-
-WARN: robustesse de fieldproxy
-
-
-
-T20110622.2: UC Initialisation/Création de champs
--------------------------------------------------
-
-**Status: à faire**
-
-Les cas implémentés à ce jour sont la création de champs à partir de
-champs existants et chargés d'un fichier med. On souhaite ici réaliser
-des cas 'utilisation autour de la création de champs "from scratch",
-s'appuyant tout de même sur un maillage chargé.
-
-UC01: Sélection d'un groupe de maille dans SMESH pour initialiser un
-champ (par exemple les conditions limites d'un problème de calcul).
-
-UC02: créer un champ avec des restrictions qui définissent le domaine
-d'application des opération de champs.
-
-UC03: créer un champ à partir d'une image (codes rgb utilisé comme les
-composantes du champs vectoriel ou niveaux de gris pour un champ
-scalaire. Attention, pour ça, il faudra a priori fiare une projection
-du maillage cartesien de l'image sur le maillage (quelconque) sur
-lequel on souhaite définir le champ.
-
-UC04: créer un champ à partir d'un tableau numpy
-
-De manière générale, ce type de création sera assisté par le
-MEDGUI. Au niveau MEDTUI, les fonctions pourraient être fastidieuses
-pour l'utilisateur.
-
-Par exemple, prévoir un menu contextuel qui propose les opérations
-possibles en fonction de la sélection (en plus de la fonction d'import
-dans la console python).
-
-TODO:
-
-* développer les fonctions d'initialisation, par exemple au moyen
-  d'applyFunc et du mécanisme de callable?
-
-T20110622.3: documentation contextuel
--------------------------------------
-
-**Status: à faire**
-
-* Remettre toutes les commandes dans le même fichier (fusionner cmdtools
-  et fieldtools)
-* Faire un modèle générique de command (classe de base
-* Batir la doc des commandes sur cette base (lister toutes les
-  instances de type Command par exemple)
-
-T20110622.4: remontée des exception du composant MEDCalculator
---------------------------------------------------------------
-
-**Status: en cours, compléter la couverture**
-
-Pour des messages contextuel sur les erreurs de calcul (ex: division
-par 0)
-
-* Poursuivre le travail fait sur getMedEventListener
-* Protéger tous les appels au composants effectués depuis la console
-  python (prendre example sur la commande save)
-
-T20110624.1: gestion des données GUI
-------------------------------------
-
-**Status: à faire**
-
-
-
-Le workspace a une entrée dans l'obrowser. Sur cette entrée on peut:
-
-* supprimer: supprime tout les champs associés
-* sauvegarder. Dans ce cas, on rappelle l'ensemble des champs pour
-  cocher ceux qu'on veut sauvegarder.
-
-Le gui data model est réservé aux opérations sur les champs et à
-piloter leur import dans la console python.
-
-TODO:
-
-* Spécifier les concepts de workspace, database, et datasource, espace
-  de gestion, ... et les associations. Simplifier avec l'appuie de use
-  cases.
-* Mécanisme de mise à jour du TreeView de XSALOME (aujourd'hui, seul
-  l'ajout addChild est implémenté
-* Clic droit sur objets de l'arbre: dans la notification TreeView ->
-  WorkspaceController, faire remonter l'évènement clic droit ainsi que la
-  liste des éléments sélectionné pour faire générer le menu contextuel
-  au niveau du WorkspaceController qui peut déterminer le contexte métier
-  (le TreeView ne le connaît pas).
-* Définir des DataObject pour les maillages, les séries temporelles et
-  les champs
-
-
-Spécification des espaces de données:
-
-* MEDDataManager dépend de l'étude (pour permettre la publication
-  d'information dans une étude SALOME).
-* créer "sourcid = MEDDataManager::addDataSource(filename)", suivie de
-  requetes getFields(sourceid), getMeshes(sourceid)
-* les espaces de données: dataspace, workspace. Un seul workspace par
-  étude, mais autand de datasources que l'on souhaite dans le
-  dataspace. Les datasources sont rangés dans l'étude (le dataspace)
-  et sont non modifiables après chargement (référence des sources de
-  données).
-
-
-T20110628.1: extention à d'autres objets SALOME
------------------------------------------------
-
-**Status: suspendu**
-
-On doit reposer la question de l'existance de l'arbre indépendant
-(DockWidget), d'une part, et l'extention aux autres objets (GEOM et
-SMESH en particulier) du principe de sélection graphique pour
-utilisation dans la console python, d'autre part.
-
-
-T20110628.2: visualisation d'un champ avec PARAVIS
---------------------------------------------------
-
-**Status: terminé (pour une première version)**
-Suite: de nombreux défauts subsistent
-
-Questions/remarques:
-
-* Pb au démarrage du module: VisTrails fails to start
-* Peux-t-on piloter la vue 3D sans charger le module? (voir
-  myparavis.py)
-* Comment donner un nom au MEDReader1 dans l'arbre Pipeline?
-* Comment utiliser directement les objets MEDCouplingField?
-
-
-T20110706.1: documentation du module
-------------------------------------
-
-**Status: en cours (10%)**
-
-Documenter les commandes TUI puis l'utilisation générale de
-l'interafce graphique. Mentionner l'existance de la commande medop.sh
-pour travailler exclusivement en mode texte (utile pour les tests
-rapides).
-
-Documenter les modalités d'exécution des tests.
-
-T20110708.1: helper python pour MEDCoupling
--------------------------------------------
-
-**Status: en attente (pas urgent)**
-
-Faire un helper python dans le package xmed qui permet de faire du
-medcoupling facilement (essentiellement pour simplifier le chargement,
-puis la sélection des données). Cela demanderait de faire un
-MedDataManager comme une class C++ pure (non CORBA). Cette classe
-travaillerait par exemple uniquement avec des id et des liste d'id, et
-fournirait des fonctions d'affichage (comme le ``ls`` et le ``la``)
-pour obtenir des meta-information.
-
-Le servant MedDataManager pourrait être une surcouche de cette classe
-c++ pure.
-
-T20110708.2: analyses et tests
-------------------------------
-
-TODO:
-
-* créer un fichier de test avec plusieurs pas de temps
-* créer un fichier de test avec des groupes de mailles
-
-
-T20110728.1: refactoring MEDDataManager
----------------------------------------
-
-Refactoring pour une meilleur association entre FieldHandler et MeshHandler:
-
-* dans la mesure du possible utiliser les id plutôt que les handler en
-  arguments des fonctions d'appel des objets
-* A chaque champ (FieldHandler), on doit associer un meshid (et de
-  manière optionnelle un fieldseriesId, si le champ peut être associé
-  à une serie temporelle. A priori faisable uniquement au chargement
-  du datasource).
-* Pour cela, revoir les fonctions internes newFieldHandler et addField
-  ou prévoir de les compléter à chaque fois qu'elles sont appelée avec
-  les informations concernant le meshid.
-* addField est utilisée par le MEDCalculator
-* Attention au raffraichissement des données handler au niveau du
-  Workspace. Peut-être le mieux est que les fieldproxy contiennent
-  uniquement le fieldid, et qu'ils interroge le datamanager à chaque
-  fois qu'ils ont besoin d'une donnée. Voir aussi les notifications
-  via le MEDEventListener?  **Le plus simple est de faire la mise à
-  jour lors de l'appel à la méthode __repr__ du fieldproxy, i.e. quand
-  on essaye d'afficher les données**. Parceque sinon il n'y a pas de
-  problème puisque que le calculateur travaille à partir des id.
-
-
-Petites améliorations du DataspaceController:
-
-* Au OnUseInWorkspace, stocker (dans la mesure du possible) le nom de
-  l'alias python dans un attribut du sobject.
-* Dans DlgChangeUnderLyingMesh, expliquer que le champs sera dupliquer
-  est posé dans le WS. On peut donc proposer en option de lui associer
-  un alias pour manipulation dans la console
-
diff --git a/src/MEDOP/doc/sphinx/xmed-workingnotes-2012.rst b/src/MEDOP/doc/sphinx/xmed-workingnotes-2012.rst
deleted file mode 100644 (file)
index 011190e..0000000
+++ /dev/null
@@ -1,84 +0,0 @@
-.. meta::
-   :keywords: maillage, champ, manipulation
-   :author: Guillaume Boulant
-
-.. include:: xmed-definitions.rst
-
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-ANNEXE: Note de travail concernant le chantier XMED 2012
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-.. contents:: Sommaire
-   :local:
-   :backlinks: none
-
-
-Analyse preliminaire pour le chantier 2012
-==========================================
-
-La figure imposée pour le chantier 2012 est l'intégration du nouveau
-module de manipulation de champs dans SALOME 6.6 (objectif CEA), en
-préparation de la mise en exploitation dans SALOME 7 (objectif EDF).
-
-L'état actuel est:
-
-* Un module SALOME de nom MED intégrant les bibliothèques MEDCoupling,
-  MEDLoader, REMAPPER, mais aussi plusieurs packages logiciels
-  aujourd'hui obsolètes ou amener à disparaître pour l'échéance
-  SALOME7
-* Un module SALOME de nom XMED qui fournit les fonctions graphiques
-  pour la manipulation de champs.
-* Ce module XMED utilise le module VISU pour les vue de contrôle.
-
-La cible est:
-
-* Un module unique (nom à définir, par exemple MEDOP) débarrassé des
-  packages logiciels obsolètes et intégrant les fonctions graphiques
-  (GUI et TUI).
-* L'utilisation du module PARAVIS (au lieu de VISU) pour les vues de
-  contrôle.
-* L'intégration de MEDCoupling avec YACS (port MED dans YACS par
-  exemple).
-
-A examiner:
-
-* voir les attendus concernant les ports MED dans YACS
-* interface PARAVIS: utilisation du viewer (et de l'API python) sans chargement du GUI
-
-Tâches de développement
-=======================
-
-20120904: Migrer XMED dans MED
-------------------------------
-
-Plan de travail:
-
-* Migration des composants + test
-
-
-
-20120904: Nettoyage de XSALOME
-------------------------------
-
-:status: en cours
-
-* Supprimer les vieilleries de XSALOME:
-
-  - StdHelper -> Basic_Utils (KERNEL)
-
-20120829: mise en place du chantier 2012
-----------------------------------------
-
-:status: terminé
-
-L'objectif de cette première étape est de reverser le prototype 2011
-(module XMED indépendant) dans la branche V6_main du module MED. On
-peut procéder de la manière suivante:
-
-* update de XMED (et XSALOME utilisé par XMED) pour fonctionnement sur
-  V6_main
-* Eliminer la dépendance à XSALOME
-* Supprimer la gestion des multiversion SALOME5/6 au niveau de l'engine
-
-.. warning:: TODO: refaire le point sur les tâches initiées en 2011 
-