diff --git a/Common/Options.cpp b/Common/Options.cpp
index 60eb3ad9970e2124a8d29dabbe0397aec168b34d..3ec6cd728638487e78b33997d12a1fcc8c854304 100644
--- a/Common/Options.cpp
+++ b/Common/Options.cpp
@@ -8032,7 +8032,7 @@ double opt_view_tensor_type(OPT_ARGS_NUM)
   GET_VIEW(0.);
   if(action & GMSH_SET) {
     opt->tensorType = (int)val;
-    if(opt->tensorType > 4)
+    if(opt->tensorType > 5 || opt->tensorType < 1)
       opt->tensorType = 1;
     if(view) view->setChanged(true);
   }
diff --git a/Fltk/optionWindow.cpp b/Fltk/optionWindow.cpp
index 13ca769988e800ed09a1cbff50fa58a59d45d043..95fe7e88d9da2f6b1cf6a757321bdd393be9a934 100644
--- a/Fltk/optionWindow.cpp
+++ b/Fltk/optionWindow.cpp
@@ -3156,6 +3156,7 @@ optionWindow::optionWindow(int deltaFontSize)
         {"Maximum eigen value", 0, 0, 0},
         {"Minimum eigen value", 0, 0, 0},
         {"Eigen vectors", 0, 0, 0},
+        {"Ellipse", 0, 0, 0},
         {0}
       };
       view.choice[4] = new Fl_Choice
diff --git a/Graphics/drawContext.h b/Graphics/drawContext.h
index a1fe610eb48cb17a152de4bc3bb53c26a8b7b044..9170a4789c683a63dfb27c5e52b5062725789848 100644
--- a/Graphics/drawContext.h
+++ b/Graphics/drawContext.h
@@ -201,6 +201,7 @@ class drawContext {
   void drawStringRight(const std::string &s);
   void drawString(const std::string &s, double style);
   void drawSphere(double R, double x, double y, double z, int n1, int n2, int light);
+  void drawEllipse(double x, double y, double z, float v0[3], float v1[3], float v2[3], int light);
   void drawSphere(double size, double x, double y, double z, int light);
   void drawCylinder(double width, double *x, double *y, double *z, int light);
   void drawTaperedCylinder(double width, double val1, double val2, 
diff --git a/Graphics/drawGlyph.cpp b/Graphics/drawGlyph.cpp
index 119bb7c7e8937f5017d24c36f2a96206f7158b7d..b2f7ac2c40b218319d357b1e40b7e18d28f7c097 100644
--- a/Graphics/drawGlyph.cpp
+++ b/Graphics/drawGlyph.cpp
@@ -128,6 +128,22 @@ void drawContext::drawSphere(double R, double x, double y, double z,
   glDisable(GL_LIGHTING);
 }
 
+void drawContext::drawEllipse(double x, double y, double z, float v0[3], float v1[3], float v2[3], int light)
+{
+  if(light) glEnable(GL_LIGHTING);
+  glPushMatrix();
+  GLfloat m[16] = {
+    v0[0], v0[1], v0[2], .0d,
+    v1[0], v1[1], v1[2], .0d,
+    v2[0], v2[1], v2[2], .0d,
+    x, y, z, 1.d
+  };
+  glMultMatrixf(m);
+  glCallList(_displayLists + 0);
+  glPopMatrix();
+  glDisable(GL_LIGHTING);
+}
+
 void drawContext::drawSphere(double size, double x, double y, double z, int light)
 {
   double ss = size * pixel_equiv_x / s[0]; // size is in pixels
diff --git a/Graphics/drawPost.cpp b/Graphics/drawPost.cpp
index b2196e549a9998313b0e283e9926b68b675b6cc4..68f4533e9455b8bf1f4e7a369ec65e779dabcf6d 100644
--- a/Graphics/drawPost.cpp
+++ b/Graphics/drawPost.cpp
@@ -87,6 +87,31 @@ static void drawArrays(drawContext *ctx, PView *p, VertexArray *va, GLint type,
   glDisable(GL_LIGHTING);
 }
 
+static void drawEllipseArray(drawContext *ctx, PView *p, VertexArray *va)
+{
+  if(!va || va->getNumVerticesPerElement() != 4) return;
+
+  PViewOptions *opt = p->getOptions();
+  
+  for(int i = 0; i < va->getNumVertices(); i += 4) {
+    float *s = va->getVertexArray(3 * i);
+    float vv[3][3];
+    double lmax = opt->tmpMax;
+    double scale = (opt->arrowSizeMax - opt->arrowSizeMin) *ctx->pixel_equiv_x / ctx->s[0]/2;
+    double lmin = opt->arrowSizeMin * ctx->pixel_equiv_x / ctx->s[0]/2;
+    for (int j = 0; j < 3; j++) {
+      float *v = va->getVertexArray(3 * (i + j + 1));
+      double l = sqrt (v[0]*v[0] + v[1]*v[1] + v[2]*v[2]);
+      double l2 = std::min(1., l/lmax);
+      for (int k = 0; k < 3; k++) {
+        vv[j][k] = v[k]/l*(scale*l2 + lmin);
+      }
+    }
+    glColor4ubv((GLubyte *)va->getColorArray(4 * i));
+    ctx->drawEllipse(s[0], s[1], s[2], vv[0], vv[1], vv[2], opt->light);
+  }
+}
+
 static void drawVectorArray(drawContext *ctx, PView *p, VertexArray *va)
 {
   if(!va || va->getNumVerticesPerElement() != 2) return;
@@ -374,6 +399,7 @@ class drawPView {
 
     // draw the "pseudo" vertex arrays for vectors
     drawVectorArray(_ctx, p, p->va_vectors);
+    drawEllipseArray(_ctx, p, p->va_ellipses);
 
     // to avoid looping over elements (and to enable drawing glyphs
     // for remote views) we should also store these glyphs in "pseudo"
diff --git a/Post/PView.cpp b/Post/PView.cpp
index 22cc1d460d7b496e95b51fd4bcbefdae3dd8119a..a757940c09ad763f41ea772310b25811baad333a 100644
--- a/Post/PView.cpp
+++ b/Post/PView.cpp
@@ -29,7 +29,7 @@ void PView::_init(int num)
   _changed = true;
   _aliasOf = 0;
   _eye = SPoint3(0., 0., 0.);
-  va_points = va_lines = va_triangles = va_vectors = 0;
+  va_points = va_lines = va_triangles = va_vectors = va_ellipses = 0;
   normals = 0;
   list.push_back(this);
   for(unsigned int i = 0; i < list.size(); i++) list[i]->setIndex(i);
@@ -179,6 +179,7 @@ void PView::deleteVertexArrays()
   if(va_lines) delete va_lines; va_lines = 0;
   if(va_triangles) delete va_triangles; va_triangles = 0;
   if(va_vectors) delete va_vectors; va_vectors = 0;
+  if(va_ellipses) delete va_ellipses; va_ellipses = 0;
 }
 
 void PView::setOptions(PViewOptions *val)
diff --git a/Post/PView.h b/Post/PView.h
index a3bc1710f82fda67e5a1f7711c18dacac8327f72..3091b2778544348d90f418d3e22a4e034fdd14a8 100644
--- a/Post/PView.h
+++ b/Post/PView.h
@@ -114,7 +114,7 @@ class PView{
   bool write(std::string fileName, int format, bool append=false);
 
   // vertex arrays to draw the elements efficiently
-  VertexArray *va_points, *va_lines, *va_triangles, *va_vectors;
+  VertexArray *va_points, *va_lines, *va_triangles, *va_vectors, *va_ellipses;
 
   // fill the vertex arrays, given the current option and data
   void fillVertexArrays();
diff --git a/Post/PViewOptions.h b/Post/PViewOptions.h
index 795b3002512f406df24807a6944957f3d32000bc..ee03adbaf365723b51d63cf26cced8d2b4b1736d 100644
--- a/Post/PViewOptions.h
+++ b/Post/PViewOptions.h
@@ -37,7 +37,8 @@ class PViewOptions {
     VonMises = 1,
     MaxEigenValue = 2,
     MinEigenValue = 3,
-    EigenVectors = 4
+    EigenVectors = 4,
+    Ellipse = 5
   };
   enum GlyphLocation {
     COG = 1,
diff --git a/Post/PViewVertexArrays.cpp b/Post/PViewVertexArrays.cpp
index 139cc9736d4f45b1c597b3dee0d0079b5788edc5..02bde3526c3236d9f04380ca66ff4c6d8c3c1c26 100644
--- a/Post/PViewVertexArrays.cpp
+++ b/Post/PViewVertexArrays.cpp
@@ -970,7 +970,7 @@ static void addTensorElement(PView *p, int iEnt, int iEle, int numNodes, int typ
     }
     addScalarElement(p, type, xyz, val, pre, numNodes);
   } else if (opt->tensorType == PViewOptions::MaxEigenValue) {
-    for(int i = 0; i < numNodes; i++) {
+    for (int i = 0; i < numNodes; i++) {
       for (int j = 0; j < 3; j++) {
         tensor(j,0) = val [i][0+j*3];
         tensor(j,1) = val [i][1+j*3];
@@ -998,6 +998,29 @@ static void addTensorElement(PView *p, int iEnt, int iEle, int numNodes, int typ
     addVectorElement(p, iEnt, iEle, numNodes, type, xyz, vval[0], pre);
     addVectorElement(p, iEnt, iEle, numNodes, type, xyz, vval[1], pre);
     addVectorElement(p, iEnt, iEle, numNodes, type, xyz, vval[2], pre);
+  } else if (opt->tensorType == PViewOptions::Ellipse) {
+    double vval[3][4]= {0,0,0, 0,0,0, 0,0,0, 0,0,0};
+    for(int i = 0; i < numNodes; i++) {
+      for (int j = 0; j < 3; j++) {
+        tensor(j,0) = val [i][0+j*3];
+        tensor(j,1) = val [i][1+j*3];
+        tensor(j,2) = val [i][2+j*3];
+      }
+      tensor.eig(S, imS, V, rightV, false);
+      for (int j = 0; j < 3; j++) {
+        vval[0][j+1] += V(j,0)*S(j)/numNodes;
+        vval[1][j+1] += V(j,1)*S(j)/numNodes;
+        vval[2][j+1] += V(j,2)*S(j)/numNodes;
+      }
+      vval[0][0] += xyz[i][0]/numNodes;
+      vval[1][0] += xyz[i][1]/numNodes;
+      vval[2][0] += xyz[i][2]/numNodes;
+    }
+    double lmax = std::max(S(0), std::max(S(1), S(2)));
+    //unsigned int color = opt->getColor(lmax, opt->externalMin, opt->externalMax, false, (opt->intervalsType == PViewOptions::Discrete) ?  opt->nbIso : -1);
+    unsigned int color = opt->getColor(lmax, opt->tmpMin, opt->tmpMax, false, (opt->intervalsType == PViewOptions::Discrete) ?  opt->nbIso : -1);
+    unsigned int col[4] = {color, color, color, color};
+    p->va_ellipses->add( vval[0], vval[1], vval[2], 0, col, 0, false);
   }
 }
 
@@ -1153,6 +1176,14 @@ class initPView {
     heuristic = _estimateIfClipped(p, heuristic);
     return heuristic + 1000;
   }
+  int _estimateNumEllipses(PView *p)
+  {
+    PViewData *data = p->getData(true);
+    PViewOptions *opt = p->getOptions();
+    int heuristic = data->getNumTensors(opt->timeStep);
+    heuristic = _estimateIfClipped(p, heuristic);
+    return heuristic + 1000;
+  }
  public:
   void operator () (PView *p)
   {
@@ -1195,6 +1226,7 @@ class initPView {
     p->va_lines = new VertexArray(2, _estimateNumLines(p));
     p->va_triangles = new VertexArray(3, _estimateNumTriangles(p));
     p->va_vectors = new VertexArray(2, _estimateNumVectors(p));
+    p->va_ellipses = new VertexArray(4, _estimateNumEllipses(p));
 
     if(p->normals) delete p->normals;
     p->normals = new smooth_normals(opt->angleSmoothNormals);
@@ -1206,12 +1238,13 @@ class initPView {
     p->va_lines->finalize();
     p->va_triangles->finalize();
     p->va_vectors->finalize();
+    p->va_ellipses->finalize();
 
     Msg::Info("%d vertices in vertex arrays (%g Mb)", p->va_points->getNumVertices() + 
               p->va_lines->getNumVertices() + p->va_triangles->getNumVertices() + 
-              p->va_vectors->getNumVertices(), p->va_points->getMemoryInMb() +
+              p->va_vectors->getNumVertices() + p->va_ellipses->getNumVertices(), p->va_points->getMemoryInMb() +
               p->va_lines->getMemoryInMb() + p->va_triangles->getMemoryInMb() + 
-              p->va_vectors->getMemoryInMb());
+              p->va_vectors->getMemoryInMb() + p->va_ellipses->getMemoryInMb());
 
     p->setChanged(false);
   }
@@ -1278,6 +1311,11 @@ void PView::fillVertexArray(ConnectionManager *remote, int length,
     p->va_vectors = new VertexArray(2, 100);
     p->va_vectors->fromChar(length, bytes, swap);
     break;
+  case 5:
+    if(p->va_ellipses) delete p->va_ellipses;
+    p->va_ellipses = new VertexArray(4, 100);
+    p->va_ellipses->fromChar(length, bytes, swap);
+    break;
   default: 
     Msg::Error("Cannot fill vertex array of type %d", type);
     return;