From 14c5b1c4751446ab038c1cc104dd1c05dbd8d642 Mon Sep 17 00:00:00 2001
From: Eric Bechet <eric.bechet@ulg.ac.be>
Date: Wed, 7 Nov 2012 15:20:11 +0000
Subject: [PATCH] - used BasisFactory in some elements instead of
 PolynomialBases - getfunctionspaces now returns a nodalBasis instead of
 polynomialBasis - reversed order for saving elements in GModelIO_MSH - makes
 things simpler for subelements - taking msh file version into account while
 exporting data files (PView ...)

---
 Geo/GModelIO_MSH.cpp       | 24 +++++++++----------
 Geo/MElement.cpp           |  2 +-
 Geo/MPoint.h               |  5 ++--
 Geo/MPrism.cpp             | 19 ++++++++-------
 Geo/MPrism.h               |  2 +-
 Geo/MQuadrangle.cpp        | 47 +++++++++++++++++++------------------
 Geo/MQuadrangle.h          |  2 +-
 Geo/MSubElement.cpp        | 16 ++++++-------
 Geo/MSubElement.h          |  8 +++----
 Geo/MTriangle.cpp          | 48 +++++++++++++++++++-------------------
 Geo/MTriangle.h            |  2 +-
 Post/PViewData.h           |  2 +-
 Post/PViewDataGModel.h     |  2 +-
 Post/PViewDataGModelIO.cpp |  4 ++--
 Post/PViewDataIO.cpp       |  2 +-
 Post/PViewDataList.h       |  2 +-
 Post/PViewDataListIO.cpp   |  9 ++++---
 Post/PViewIO.cpp           |  4 ++--
 18 files changed, 103 insertions(+), 97 deletions(-)

diff --git a/Geo/GModelIO_MSH.cpp b/Geo/GModelIO_MSH.cpp
index 4d2aa4c0b4..b3ca1d9d1d 100644
--- a/Geo/GModelIO_MSH.cpp
+++ b/Geo/GModelIO_MSH.cpp
@@ -468,18 +468,6 @@ int GModel::writeMSH(const std::string &name, double version, bool binary,
 
   _elementIndexCache.clear();
 
-  for(viter it = firstVertex(); it != lastVertex(); ++it)
-    writeElementsMSH(fp, this, *it, (*it)->points, saveAll, saveSinglePartition,
-                     binary);
-  for(eiter it = firstEdge(); it != lastEdge(); ++it)
-    writeElementsMSH(fp, this, *it, (*it)->lines, saveAll, saveSinglePartition,
-                     binary);
-  for(fiter it = firstFace(); it != lastFace(); ++it)
-    writeElementsMSH(fp, this, *it, (*it)->triangles, saveAll, saveSinglePartition,
-                     binary);
-  for(fiter it = firstFace(); it != lastFace(); ++it)
-    writeElementsMSH(fp, this, *it, (*it)->quadrangles, saveAll, saveSinglePartition,
-                     binary);
   for(riter it = firstRegion(); it != lastRegion(); ++it)
     writeElementsMSH(fp, this, *it, (*it)->tetrahedra, saveAll, saveSinglePartition,
                      binary);
@@ -492,6 +480,18 @@ int GModel::writeMSH(const std::string &name, double version, bool binary,
   for(riter it = firstRegion(); it != lastRegion(); ++it)
     writeElementsMSH(fp, this, *it, (*it)->pyramids, saveAll, saveSinglePartition,
                      binary);
+  for(fiter it = firstFace(); it != lastFace(); ++it)
+    writeElementsMSH(fp, this, *it, (*it)->triangles, saveAll, saveSinglePartition,
+                     binary);
+  for(fiter it = firstFace(); it != lastFace(); ++it)
+    writeElementsMSH(fp, this, *it, (*it)->quadrangles, saveAll, saveSinglePartition,
+                     binary);
+  for(eiter it = firstEdge(); it != lastEdge(); ++it)
+    writeElementsMSH(fp, this, *it, (*it)->lines, saveAll, saveSinglePartition,
+                     binary);
+  for(viter it = firstVertex(); it != lastVertex(); ++it)
+    writeElementsMSH(fp, this, *it, (*it)->points, saveAll, saveSinglePartition,
+                     binary);
 
   if(binary) fprintf(fp, "\n");
 
diff --git a/Geo/MElement.cpp b/Geo/MElement.cpp
index ee60c2eed8..1d76cb7a6b 100644
--- a/Geo/MElement.cpp
+++ b/Geo/MElement.cpp
@@ -1330,7 +1330,7 @@ MElement *MElement::copy(std::map<int, MVertex*> &vertexMap,
 
 // Gives the parent type corresponding to 
 // any element type.
-// Ex. : MSN_TRI_3 -> TYPE_TRI
+// Ex. : MSH_TRI_3 -> TYPE_TRI
 int MElement::ParentTypeFromTag(int tag)
 {
   switch(tag) {
diff --git a/Geo/MPoint.h b/Geo/MPoint.h
index 17eb4e6562..101cbd6b08 100644
--- a/Geo/MPoint.h
+++ b/Geo/MPoint.h
@@ -7,6 +7,7 @@
 #define _MPOINT_H_
 
 #include "MElement.h"
+#include "BasisFactory.h"
 
 /*
  * MPoint
@@ -58,9 +59,9 @@ class MPoint : public MElement {
   {
     s[0][0] = s[0][1] = s[0][2] = 0.;
   }
-  virtual const polynomialBasis* getFunctionSpace(int o) const
+  virtual const nodalBasis* getFunctionSpace(int o) const
   {
-    return polynomialBases::find(MSH_PNT);
+    return BasisFactory::create(MSH_PNT);
   }
   virtual const JacobianBasis* getJacobianFuncSpace(int o) const
   {
diff --git a/Geo/MPrism.cpp b/Geo/MPrism.cpp
index e12b6d1518..e3907a44f4 100644
--- a/Geo/MPrism.cpp
+++ b/Geo/MPrism.cpp
@@ -5,6 +5,7 @@
 
 #include "MPrism.h"
 #include "Numeric.h"
+#include "BasisFactory.h"
 
 int MPrism::getVolumeSign()
 { 
@@ -30,25 +31,25 @@ void MPrism::getIntegrationPoints(int pOrder, int *npts, IntPt **pts)
   *pts = getGQPriPts(pOrder);
 }
 
-const polynomialBasis* MPrism::getFunctionSpace(int o) const
+const nodalBasis* MPrism::getFunctionSpace(int o) const
 {
   int order = (o == -1) ? getPolynomialOrder() : o;
 
   int nv = getNumVolumeVertices();
-  
+
   if ((nv == 0) && (o == -1)) {
     switch (order) {
-    case 0: return polynomialBases::find(MSH_PRI_1);
-    case 1: return polynomialBases::find(MSH_PRI_6);
-    case 2: return polynomialBases::find(MSH_PRI_18);
+    case 0: return BasisFactory::create(MSH_PRI_1);
+    case 1: return BasisFactory::create(MSH_PRI_6);
+    case 2: return BasisFactory::create(MSH_PRI_18);
     default: Msg::Error("Order %d prism function space not implemented", order);
     }
   }
-  else { 
+  else {
     switch (order) {
-    case 0: return polynomialBases::find(MSH_PRI_1);
-    case 1: return polynomialBases::find(MSH_PRI_6);
-    case 2: return polynomialBases::find(MSH_PRI_18);
+    case 0: return BasisFactory::create(MSH_PRI_1);
+    case 1: return BasisFactory::create(MSH_PRI_6);
+    case 2: return BasisFactory::create(MSH_PRI_18);
     default: Msg::Error("Order %d prism function space not implemented", order);
     }
   }
diff --git a/Geo/MPrism.h b/Geo/MPrism.h
index d6e14731ca..0026378137 100644
--- a/Geo/MPrism.h
+++ b/Geo/MPrism.h
@@ -127,7 +127,7 @@ class MPrism : public MElement {
     tmp = _v[0]; _v[0] = _v[1]; _v[1] = tmp;
     tmp = _v[3]; _v[3] = _v[4]; _v[4] = tmp;
   }
-  virtual const polynomialBasis* getFunctionSpace(int o=-1) const;
+  virtual const nodalBasis* getFunctionSpace(int o=-1) const;
   virtual const JacobianBasis* getJacobianFuncSpace(int o=-1) const;
   virtual int getVolumeSign();
   virtual void getNode(int num, double &u, double &v, double &w)
diff --git a/Geo/MQuadrangle.cpp b/Geo/MQuadrangle.cpp
index 92f18a4664..06e7c5a9f6 100644
--- a/Geo/MQuadrangle.cpp
+++ b/Geo/MQuadrangle.cpp
@@ -9,6 +9,7 @@
 #include "Context.h"
 #include "qualityMeasures.h"
 #include "Numeric.h"
+#include "BasisFactory.h"
 
 #if defined(HAVE_MESH)
 #include "qualityMeasures.h"
@@ -16,7 +17,7 @@
 
 #define SQU(a)      ((a)*(a))
 
-const polynomialBasis* MQuadrangle::getFunctionSpace(int o) const
+const nodalBasis* MQuadrangle::getFunctionSpace(int o) const
 {
   int order = (o == -1) ? getPolynomialOrder() : o;
 
@@ -24,31 +25,31 @@ const polynomialBasis* MQuadrangle::getFunctionSpace(int o) const
 
   if ((nf == 0) && (o == -1)) {
     switch (order) {
-      case 0: return polynomialBases::find(MSH_QUA_1);
-      case 1: return polynomialBases::find(MSH_QUA_4);
-      case 2: return polynomialBases::find(MSH_QUA_8);
-      case 3: return polynomialBases::find(MSH_QUA_12);
-      case 4: return polynomialBases::find(MSH_QUA_16I);
-      case 5: return polynomialBases::find(MSH_QUA_20);
-      case 6: return polynomialBases::find(MSH_QUA_24);
-      case 7: return polynomialBases::find(MSH_QUA_28);
-      case 8: return polynomialBases::find(MSH_QUA_32);
-      case 9: return polynomialBases::find(MSH_QUA_36I);
-      case 10: return polynomialBases::find(MSH_QUA_40);
+      case 0: return BasisFactory::create(MSH_QUA_1);
+      case 1: return BasisFactory::create(MSH_QUA_4);
+      case 2: return BasisFactory::create(MSH_QUA_8);
+      case 3: return BasisFactory::create(MSH_QUA_12);
+      case 4: return BasisFactory::create(MSH_QUA_16I);
+      case 5: return BasisFactory::create(MSH_QUA_20);
+      case 6: return BasisFactory::create(MSH_QUA_24);
+      case 7: return BasisFactory::create(MSH_QUA_28);
+      case 8: return BasisFactory::create(MSH_QUA_32);
+      case 9: return BasisFactory::create(MSH_QUA_36I);
+      case 10: return BasisFactory::create(MSH_QUA_40);
     }
   }
   switch (order) {
-    case 0: return polynomialBases::find(MSH_QUA_1);
-    case 1: return polynomialBases::find(MSH_QUA_4);
-    case 2: return polynomialBases::find(MSH_QUA_9);
-    case 3: return polynomialBases::find(MSH_QUA_16);
-    case 4: return polynomialBases::find(MSH_QUA_25);
-    case 5: return polynomialBases::find(MSH_QUA_36);
-    case 6: return polynomialBases::find(MSH_QUA_49);
-    case 7: return polynomialBases::find(MSH_QUA_64);
-    case 8: return polynomialBases::find(MSH_QUA_81);
-    case 9: return polynomialBases::find(MSH_QUA_100);
-    case 10: return polynomialBases::find(MSH_QUA_121);
+    case 0: return BasisFactory::create(MSH_QUA_1);
+    case 1: return BasisFactory::create(MSH_QUA_4);
+    case 2: return BasisFactory::create(MSH_QUA_9);
+    case 3: return BasisFactory::create(MSH_QUA_16);
+    case 4: return BasisFactory::create(MSH_QUA_25);
+    case 5: return BasisFactory::create(MSH_QUA_36);
+    case 6: return BasisFactory::create(MSH_QUA_49);
+    case 7: return BasisFactory::create(MSH_QUA_64);
+    case 8: return BasisFactory::create(MSH_QUA_81);
+    case 9: return BasisFactory::create(MSH_QUA_100);
+    case 10: return BasisFactory::create(MSH_QUA_121);
     default: Msg::Error("Order %d quadrangle function space not implemented", order);
   }
   return 0;
diff --git a/Geo/MQuadrangle.h b/Geo/MQuadrangle.h
index 0f8df873e5..3c1d9a7939 100644
--- a/Geo/MQuadrangle.h
+++ b/Geo/MQuadrangle.h
@@ -115,7 +115,7 @@ class MQuadrangle : public MElement {
   virtual const char *getStringForBDF() const { return "CQUAD4"; }
   virtual const char *getStringForDIFF() const { return "ElmB4n2D"; }
   virtual const char *getStringForINP() const { return "C2D4"; }
-  virtual const polynomialBasis* getFunctionSpace(int o=-1) const;
+  virtual const nodalBasis* getFunctionSpace(int o=-1) const;
   virtual const JacobianBasis* getJacobianFuncSpace(int o=-1) const;
   virtual void getNode(int num, double &u, double &v, double &w)
   {
diff --git a/Geo/MSubElement.cpp b/Geo/MSubElement.cpp
index 60c4e82e15..3d8b99cad7 100644
--- a/Geo/MSubElement.cpp
+++ b/Geo/MSubElement.cpp
@@ -16,9 +16,9 @@ MSubTetrahedron::~MSubTetrahedron()
     delete _orig;
 }
 
-const polynomialBasis* MSubTetrahedron::getFunctionSpace(int order) const
+const nodalBasis* MSubTetrahedron::getFunctionSpace(int order) const
 {
-  if(_orig) return (polynomialBasis*)_orig->getFunctionSpace(order);
+  if(_orig) return _orig->getFunctionSpace(order);
   return 0;
 }
 
@@ -114,9 +114,9 @@ MSubTriangle::~MSubTriangle()
     delete _orig;
 }
 
-const polynomialBasis* MSubTriangle::getFunctionSpace(int order) const
+const nodalBasis* MSubTriangle::getFunctionSpace(int order) const
 {
-  if(_orig) return (polynomialBasis*)_orig->getFunctionSpace(order);
+  if(_orig) return _orig->getFunctionSpace(order);
   return 0;
 }
 
@@ -209,9 +209,9 @@ MSubLine::~MSubLine()
     delete _orig;
 }
 
-const polynomialBasis* MSubLine::getFunctionSpace(int order) const
+const nodalBasis* MSubLine::getFunctionSpace(int order) const
 {
-  if(_orig) return (polynomialBasis*)_orig->getFunctionSpace(order);
+  if(_orig) return _orig->getFunctionSpace(order);
   return 0;
 }
 
@@ -299,9 +299,9 @@ MSubPoint::~MSubPoint()
     delete _orig;
 }
 
-const polynomialBasis* MSubPoint::getFunctionSpace(int order) const
+const nodalBasis* MSubPoint::getFunctionSpace(int order) const
 {
-  if(_orig) return (polynomialBasis*)_orig->getFunctionSpace(order);
+  if(_orig) return _orig->getFunctionSpace(order);
   return 0;
 }
 
diff --git a/Geo/MSubElement.h b/Geo/MSubElement.h
index 6d66e652b0..c2cd0ec5a1 100644
--- a/Geo/MSubElement.h
+++ b/Geo/MSubElement.h
@@ -36,7 +36,7 @@ class MSubTetrahedron : public MTetrahedron
 
   ~MSubTetrahedron();
   virtual int getTypeForMSH() const { return MSH_TET_SUB; }
-  virtual const polynomialBasis* getFunctionSpace(int order=-1) const;
+  virtual const nodalBasis* getFunctionSpace(int order=-1) const;
   virtual const JacobianBasis* getJacobianFuncSpace(int order=-1) const;
   virtual void getShapeFunctions(double u, double v, double w, double s[], int o);
   virtual void getGradShapeFunctions(double u, double v, double w, double s[][3], int o);
@@ -73,7 +73,7 @@ class MSubTriangle : public MTriangle
     : MTriangle(tri), _owner(owner), _orig(orig), _intpt(0) {}
   ~MSubTriangle();
   virtual int getTypeForMSH() const { return MSH_TRI_SUB; }
-  virtual const polynomialBasis* getFunctionSpace(int order=-1) const;
+  virtual const nodalBasis* getFunctionSpace(int order=-1) const;
   virtual const JacobianBasis* getJacobianFuncSpace(int order=-1) const;
   virtual void getShapeFunctions(double u, double v, double w, double s[], int o);
   virtual void getGradShapeFunctions(double u, double v, double w, double s[][3], int o);
@@ -111,7 +111,7 @@ class MSubLine : public MLine
 
   ~MSubLine();
   virtual int getTypeForMSH() const { return MSH_LIN_SUB; }
-  virtual const polynomialBasis* getFunctionSpace(int order=-1) const;
+  virtual const nodalBasis* getFunctionSpace(int order=-1) const;
   virtual const JacobianBasis* getJacobianFuncSpace(int order=-1) const;
   virtual void getShapeFunctions(double u, double v, double w, double s[], int o);
   virtual void getGradShapeFunctions(double u, double v, double w, double s[][3], int o);
@@ -148,7 +148,7 @@ class MSubPoint : public MPoint
 
   ~MSubPoint();
   virtual int getTypeForMSH() const { return MSH_PNT_SUB; }
-  virtual const polynomialBasis* getFunctionSpace(int order=-1) const;
+  virtual const nodalBasis* getFunctionSpace(int order=-1) const;
   virtual const JacobianBasis* getJacobianFuncSpace(int order=-1) const;
   virtual void getShapeFunctions(double u, double v, double w, double s[], int o);
   virtual void getGradShapeFunctions(double u, double v, double w, double s[][3], int o);
diff --git a/Geo/MTriangle.cpp b/Geo/MTriangle.cpp
index dd73931ffb..518675aaf4 100644
--- a/Geo/MTriangle.cpp
+++ b/Geo/MTriangle.cpp
@@ -7,7 +7,7 @@
 #include "MTriangle.h"
 #include "Numeric.h"
 #include "Context.h"
-#include "GmshDefines.h"
+#include "BasisFactory.h"
 
 #if defined(HAVE_MESH)
 #include "qualityMeasures.h"
@@ -128,7 +128,7 @@ double MTriangle::gammaShapeMeasure()
    uvw[2] = 0.;
 }
 
-const polynomialBasis* MTriangle::getFunctionSpace(int o) const
+const nodalBasis* MTriangle::getFunctionSpace(int o) const
 {
   int order = (o == -1) ? getPolynomialOrder() : o;
 
@@ -136,33 +136,33 @@ const polynomialBasis* MTriangle::getFunctionSpace(int o) const
 
   if ((nf == 0) && (o == -1)) {
     switch (order) {
-    case 0: return polynomialBases::find(MSH_TRI_1);
-    case 1: return polynomialBases::find(MSH_TRI_3);
-    case 2: return polynomialBases::find(MSH_TRI_6);
-    case 3: return polynomialBases::find(MSH_TRI_9);
-    case 4: return polynomialBases::find(MSH_TRI_12);
-    case 5: return polynomialBases::find(MSH_TRI_15I);
-    case 6: return polynomialBases::find(MSH_TRI_18);
-    case 7: return polynomialBases::find(MSH_TRI_21I);
-    case 8: return polynomialBases::find(MSH_TRI_24);
-    case 9: return polynomialBases::find(MSH_TRI_27);
-    case 10: return polynomialBases::find(MSH_TRI_30);
+    case 0: return BasisFactory::create(MSH_TRI_1);
+    case 1: return BasisFactory::create(MSH_TRI_3);
+    case 2: return BasisFactory::create(MSH_TRI_6);
+    case 3: return BasisFactory::create(MSH_TRI_9);
+    case 4: return BasisFactory::create(MSH_TRI_12);
+    case 5: return BasisFactory::create(MSH_TRI_15I);
+    case 6: return BasisFactory::create(MSH_TRI_18);
+    case 7: return BasisFactory::create(MSH_TRI_21I);
+    case 8: return BasisFactory::create(MSH_TRI_24);
+    case 9: return BasisFactory::create(MSH_TRI_27);
+    case 10: return BasisFactory::create(MSH_TRI_30);
     default: Msg::Error("Order %d triangle incomplete function space not implemented", order);
     }
   }
   else {
     switch (order) {
-    case 0: return polynomialBases::find(MSH_TRI_1);
-    case 1: return polynomialBases::find(MSH_TRI_3);
-    case 2: return polynomialBases::find(MSH_TRI_6);
-    case 3: return polynomialBases::find(MSH_TRI_10);
-    case 4: return polynomialBases::find(MSH_TRI_15);
-    case 5: return polynomialBases::find(MSH_TRI_21);
-    case 6: return polynomialBases::find(MSH_TRI_28);
-    case 7: return polynomialBases::find(MSH_TRI_36);
-    case 8: return polynomialBases::find(MSH_TRI_45);
-    case 9: return polynomialBases::find(MSH_TRI_55);
-    case 10: return polynomialBases::find(MSH_TRI_66);
+    case 0: return BasisFactory::create(MSH_TRI_1);
+    case 1: return BasisFactory::create(MSH_TRI_3);
+    case 2: return BasisFactory::create(MSH_TRI_6);
+    case 3: return BasisFactory::create(MSH_TRI_10);
+    case 4: return BasisFactory::create(MSH_TRI_15);
+    case 5: return BasisFactory::create(MSH_TRI_21);
+    case 6: return BasisFactory::create(MSH_TRI_28);
+    case 7: return BasisFactory::create(MSH_TRI_36);
+    case 8: return BasisFactory::create(MSH_TRI_45);
+    case 9: return BasisFactory::create(MSH_TRI_55);
+    case 10: return BasisFactory::create(MSH_TRI_66);
     default: Msg::Error("Order %d triangle function space not implemented", order);
     }
   }
diff --git a/Geo/MTriangle.h b/Geo/MTriangle.h
index cc01e6ca43..6a2168e4ef 100644
--- a/Geo/MTriangle.h
+++ b/Geo/MTriangle.h
@@ -124,7 +124,7 @@ class MTriangle : public MElement {
   {
     MVertex *tmp = _v[1]; _v[1] = _v[2]; _v[2] = tmp;
   }
-  virtual const polynomialBasis* getFunctionSpace(int o=-1) const;
+  virtual const nodalBasis* getFunctionSpace(int o=-1) const;
   virtual const JacobianBasis* getJacobianFuncSpace(int o=-1) const;
   virtual void getNode(int num, double &u, double &v, double &w)
   {
diff --git a/Post/PViewData.h b/Post/PViewData.h
index 660243623a..140beabaf2 100644
--- a/Post/PViewData.h
+++ b/Post/PViewData.h
@@ -255,7 +255,7 @@ class PViewData {
   virtual bool writeTXT(const std::string &fileName);
   virtual bool writePOS(const std::string &fileName, bool binary=false,
                         bool parsed=true, bool append=false);
-  virtual bool writeMSH(const std::string &fileName, bool binary=false,
+  virtual bool writeMSH(const std::string &fileName, double version=2.2, bool binary=false,
                         bool savemesh=true, bool multipleView=false);
   virtual bool writeMED(const std::string &fileName);
   virtual bool toVector(std::vector<std::vector<double> > &vec);
diff --git a/Post/PViewDataGModel.h b/Post/PViewDataGModel.h
index 8b63c3a2a7..c3e2f2c7f4 100644
--- a/Post/PViewDataGModel.h
+++ b/Post/PViewDataGModel.h
@@ -241,7 +241,7 @@ class PViewDataGModel : public PViewData {
                int fileIndex, FILE *fp, bool binary, bool swap, int step,
                double time, int partition, int numComp, int numNodes,
                const std::string &interpolationScheme);
-  virtual bool writeMSH(const std::string &fileName, bool binary=false, bool savemesh=true,
+  virtual bool writeMSH(const std::string &fileName, double version=2.2, bool binary=false, bool savemesh=true,
                         bool multipleView=false);
   bool readMED(const std::string &fileName, int fileIndex);
   bool writeMED(const std::string &fileName);
diff --git a/Post/PViewDataGModelIO.cpp b/Post/PViewDataGModelIO.cpp
index 473bae2f61..2976d81144 100644
--- a/Post/PViewDataGModelIO.cpp
+++ b/Post/PViewDataGModelIO.cpp
@@ -133,7 +133,7 @@ bool PViewDataGModel::readMSH(const std::string &viewName, const std::string &fi
   return true;
 }
 
-bool PViewDataGModel::writeMSH(const std::string &fileName, bool binary, bool savemesh,
+bool PViewDataGModel::writeMSH(const std::string &fileName, double version, bool binary, bool savemesh,
                                bool multipleView)
 {
   if(_steps.empty()) return true;
@@ -148,7 +148,7 @@ bool PViewDataGModel::writeMSH(const std::string &fileName, bool binary, bool sa
   bool writeNodesAndElements = savemesh;
   FILE *fp;
   if(writeNodesAndElements){
-    if(!model->writeMSH(fileName, 2.0, binary,false,false,1.0,0,0,multipleView)) return false;
+    if(!model->writeMSH(fileName, version, binary,false,false,1.0,0,0,multipleView)) return false;
     // append data
     fp = fopen(fileName.c_str(), binary ? "ab" : "a");
     if(!fp){
diff --git a/Post/PViewDataIO.cpp b/Post/PViewDataIO.cpp
index 82c4e4fe3e..12a21425dc 100644
--- a/Post/PViewDataIO.cpp
+++ b/Post/PViewDataIO.cpp
@@ -176,7 +176,7 @@ bool PViewData::writePOS(const std::string &fileName, bool binary, bool parsed,
   return true;
 }
 
-bool PViewData::writeMSH(const std::string &fileName, bool binary, bool savemesh,
+bool PViewData::writeMSH(const std::string &fileName, double version, bool binary, bool savemesh,
                          bool multipleView)
 {
   Msg::Error("MSH export not implemented for this view type");
diff --git a/Post/PViewDataList.h b/Post/PViewDataList.h
index 706c77dfce..322593d3bf 100644
--- a/Post/PViewDataList.h
+++ b/Post/PViewDataList.h
@@ -125,7 +125,7 @@ class PViewDataList : public PViewData {
   bool readPOS(FILE *fp, double version, bool binary);
   bool writePOS(const std::string &fileName, bool binary=false, bool parsed=true,
                 bool append=false);
-  virtual bool writeMSH(const std::string &fileName, bool binary=false, bool savemesh=true,
+  virtual bool writeMSH(const std::string &fileName, double version=2.2, bool binary=false, bool savemesh=true,
                         bool multipleView=false);
 };
 
diff --git a/Post/PViewDataListIO.cpp b/Post/PViewDataListIO.cpp
index 6c8e35800d..a3f3021cb5 100644
--- a/Post/PViewDataListIO.cpp
+++ b/Post/PViewDataListIO.cpp
@@ -525,12 +525,12 @@ static void createElements(std::vector<double> &list, int nbelm, int nbnod,
   }
 }
 
-bool PViewDataList::writeMSH(const std::string &fileName, bool binary, bool savemesh,
+bool PViewDataList::writeMSH(const std::string &fileName, double version, bool binary, bool savemesh,
                              bool multipleView)
 {
   if(_adaptive){
     Msg::Warning("Writing adapted dataset (will only export current time step)");
-    return _adaptive->getData()->writeMSH(fileName, binary);
+    return _adaptive->getData()->writeMSH(fileName, version, binary);
   }
 
   FILE *fp = fopen(fileName.c_str(), "w");
@@ -579,8 +579,11 @@ bool PViewDataList::writeMSH(const std::string &fileName, bool binary, bool save
 
   fprintf(fp, "$Elements\n");
   fprintf(fp, "%d\n", (int)elements.size());
-  for(unsigned int i = 0; i < elements.size(); i++)
+  for(unsigned int i = 0; i < elements.size(); i++){
+    if(version > 2.2)
+      Msg::Warning("PViewDataList: Unable to writeMSH in version '%d'. Version 2.2 selected.", version);
     elements[i]->writeMSH2(fp, 2.2, false, i + 1);
+  }
   fprintf(fp, "$EndElements\n");
 
   if(haveInterpolationMatrices()){
diff --git a/Post/PViewIO.cpp b/Post/PViewIO.cpp
index 63eb8e4d7e..484726b40e 100644
--- a/Post/PViewIO.cpp
+++ b/Post/PViewIO.cpp
@@ -309,7 +309,7 @@ bool PView::write(const std::string &fileName, int format, bool append)
   case 2: ret = _data->writePOS(fileName, false, true, append); break; // parsed
   case 3: ret = _data->writeSTL(fileName); break;
   case 4: ret = _data->writeTXT(fileName); break;
-  case 5: ret = _data->writeMSH(fileName, CTX::instance()->mesh.binary); break;
+  case 5: ret = _data->writeMSH(fileName, CTX::instance()->mesh.mshFileVersion, CTX::instance()->mesh.binary); break;
   case 6: ret = _data->writeMED(fileName); break;
   case 10:
     {
@@ -319,7 +319,7 @@ bool PView::write(const std::string &fileName, int format, bool append)
       else if(ext == ".stl")
         ret = _data->writeSTL(fileName);
       else if(ext == ".msh")
-        ret = _data->writeMSH(fileName, CTX::instance()->mesh.binary);
+        ret = _data->writeMSH(fileName, CTX::instance()->mesh.mshFileVersion, CTX::instance()->mesh.binary);
       else if(ext == ".med")
         ret = _data->writeMED(fileName);
       else
-- 
GitLab