diff --git a/MathEval/Makefile b/MathEval/Makefile
index 58e2c969484fcabcf440cb073b8c606310ba0ad1..30d4ac96afb60a30d8608bfcb998a671798b6e49 100644
--- a/MathEval/Makefile
+++ b/MathEval/Makefile
@@ -1,4 +1,4 @@
-# $Id: Makefile,v 1.5 2005-06-20 16:35:30 geuzaine Exp $
+# $Id: Makefile,v 1.6 2005-06-27 19:34:34 geuzaine Exp $
 #
 # Copyright (C) 1997-2005 C. Geuzaine, J.-F. Remacle
 #
@@ -67,10 +67,11 @@ matheval.o: matheval.cpp common.h ../DataStr/Malloc.h matheval.h node.h \
 # 1 "/Users/geuzaine/.gmsh/MathEval//"
 node.o: node.cpp common.h ../DataStr/Malloc.h node.h symbol_table.h
 # 1 "/Users/geuzaine/.gmsh/MathEval//"
-scanner.o: scanner.cpp common.h ../DataStr/Malloc.h node.h symbol_table.h \
-  parser.h
+scanner.yy.o: scanner.yy.cpp common.h ../DataStr/Malloc.h node.h \
+  symbol_table.h parser.tab.hpp
 # 1 "/Users/geuzaine/.gmsh/MathEval//"
-parser.o: parser.cpp common.h ../DataStr/Malloc.h node.h symbol_table.h
+parser.tab.o: parser.tab.cpp common.h ../DataStr/Malloc.h node.h \
+  symbol_table.h
 # 1 "/Users/geuzaine/.gmsh/MathEval//"
 symbol_table.o: symbol_table.cpp common.h ../DataStr/Malloc.h \
   symbol_table.h xmath.h
diff --git a/Plugin/HarmonicToTime.cpp b/Plugin/HarmonicToTime.cpp
index 65dbaa2905d713161260e4616bc2ae990f03c8ec..2c4beda168a63995d3a12690af02a52039d1997c 100644
--- a/Plugin/HarmonicToTime.cpp
+++ b/Plugin/HarmonicToTime.cpp
@@ -1,4 +1,4 @@
-// $Id: HarmonicToTime.cpp,v 1.6 2005-01-08 20:15:19 geuzaine Exp $
+// $Id: HarmonicToTime.cpp,v 1.7 2005-06-27 19:34:34 geuzaine Exp $
 //
 // Copyright (C) 1997-2005 C. Geuzaine, J.-F. Remacle
 //
@@ -116,12 +116,10 @@ static void h2t(int nb1, List_T *list1, int *nb2, List_T *list2,
 
 Post_View *GMSH_HarmonicToTimePlugin::execute(Post_View * v)
 {
-  int rIndex, iIndex, nSteps, iView;
-
-  rIndex = (int)HarmonicToTimeOptions_Number[0].def;
-  iIndex = (int)HarmonicToTimeOptions_Number[1].def;
-  nSteps = (int)HarmonicToTimeOptions_Number[2].def;
-  iView = (int)HarmonicToTimeOptions_Number[3].def;
+  int rIndex = (int)HarmonicToTimeOptions_Number[0].def;
+  int iIndex = (int)HarmonicToTimeOptions_Number[1].def;
+  int nSteps = (int)HarmonicToTimeOptions_Number[2].def;
+  int iView = (int)HarmonicToTimeOptions_Number[3].def;
 
   if(iView < 0)
     iView = v ? v->Index : 0;
@@ -131,16 +129,16 @@ Post_View *GMSH_HarmonicToTimePlugin::execute(Post_View * v)
     return v;
   }
 
-  if(nSteps <= 0){
-    Msg(GERROR, "nSteps should be > 0");
-    return v;
-  }
-
   Post_View *v1 = *(Post_View **)List_Pointer(CTX.post.list, iView);
   if(rIndex < 0 || rIndex >= v1->NbTimeStep ||
      iIndex < 0 || iIndex >= v1->NbTimeStep){
     Msg(GERROR, "Wrong real or imaginary part index");
-    return v;
+    return v1;
+  }
+
+  if(nSteps <= 0){
+    Msg(GERROR, "nSteps should be > 0");
+    return v1;
   }
 
   Post_View *v2 = BeginView(1);
diff --git a/Plugin/HarmonicToTime.h b/Plugin/HarmonicToTime.h
index 8009f55a0d6ff2255bd3dbbd3ab73f7010cbe2f2..f3e8912a5769a3ad81037d004c13f75511512846 100644
--- a/Plugin/HarmonicToTime.h
+++ b/Plugin/HarmonicToTime.h
@@ -1,5 +1,5 @@
-#ifndef _HARMONIC_2_TIME_H_
-#define _HARMONIC_2_TIME_H_
+#ifndef _HARMONIC_TO_TIME_H_
+#define _HARMONIC_TO_TIME_H_
 
 // Copyright (C) 1997-2005 C. Geuzaine, J.-F. Remacle
 //
diff --git a/Plugin/Makefile b/Plugin/Makefile
index 8abda091e8cbd79d0655fa8648fa80f211a63ac7..12b3bdfb9269130b2f9f963c2c7aad812852222b 100644
--- a/Plugin/Makefile
+++ b/Plugin/Makefile
@@ -1,4 +1,4 @@
-# $Id: Makefile,v 1.82 2005-06-03 17:32:30 geuzaine Exp $
+# $Id: Makefile,v 1.83 2005-06-27 19:34:34 geuzaine Exp $
 #
 # Copyright (C) 1997-2005 C. Geuzaine, J.-F. Remacle
 #
@@ -46,7 +46,7 @@ SRC = Plugin.cpp\
         Integrate.cpp Gradient.cpp Curl.cpp Divergence.cpp\
         Annotate.cpp Remove.cpp\
         Probe.cpp\
-        HarmonicToTime.cpp
+        HarmonicToTime.cpp ModulusPhase.cpp
 
 OBJ = ${SRC:.cpp=.o}
 
@@ -78,17 +78,17 @@ Plugin.o: Plugin.cpp Plugin.h ../Common/Options.h ../Common/Message.h \
   ../Common/GmshMatrix.h ../Common/AdaptiveViews.h ../Common/GmshMatrix.h \
   PluginManager.h CutMap.h Levelset.h CutGrid.h StreamLines.h CutPlane.h \
   CutParametric.h CutSphere.h Skin.h ../DataStr/Tree.h ../DataStr/avl.h \
-  Extract.h HarmonicToTime.h Integrate.h Gradient.h Curl.h Divergence.h \
-  Annotate.h Remove.h DecomposeInSimplex.h Smooth.h Transform.h \
-  Triangulate.h SphericalRaise.h DisplacementRaise.h StructuralSolver.h \
-  ../Geo/Geo.h ../Mesh/Mesh.h ../Mesh/Vertex.h ../Mesh/Element.h \
-  ../Mesh/Vertex.h ../Mesh/Simplex.h ../Mesh/Vertex.h ../Mesh/Element.h \
-  ../Mesh/Face.h ../Mesh/Vertex.h ../Mesh/Element.h ../Mesh/Edge.h \
-  ../Mesh/Vertex.h ../Mesh/Simplex.h ../Geo/ExtrudeParams.h \
-  ../Mesh/Metric.h ../Mesh/Vertex.h ../Mesh/Simplex.h ../Mesh/Mesh.h \
-  ../Mesh/Matrix.h ../Common/GmshUI.h Eigenvectors.h Eigenvalues.h \
-  Lambda2.h ../Numeric/Numeric.h Evaluate.h OctreePost.h Octree.h \
-  OctreeInternals.h Probe.h ../Common/Context.h
+  Extract.h HarmonicToTime.h ModulusPhase.h Integrate.h Gradient.h Curl.h \
+  Divergence.h Annotate.h Remove.h DecomposeInSimplex.h Smooth.h \
+  Transform.h Triangulate.h SphericalRaise.h DisplacementRaise.h \
+  StructuralSolver.h ../Geo/Geo.h ../Mesh/Mesh.h ../Mesh/Vertex.h \
+  ../Mesh/Element.h ../Mesh/Vertex.h ../Mesh/Simplex.h ../Mesh/Vertex.h \
+  ../Mesh/Element.h ../Mesh/Face.h ../Mesh/Vertex.h ../Mesh/Element.h \
+  ../Mesh/Edge.h ../Mesh/Vertex.h ../Mesh/Simplex.h \
+  ../Geo/ExtrudeParams.h ../Mesh/Metric.h ../Mesh/Vertex.h \
+  ../Mesh/Simplex.h ../Mesh/Mesh.h ../Mesh/Matrix.h ../Common/GmshUI.h \
+  Eigenvectors.h Eigenvalues.h Lambda2.h ../Numeric/Numeric.h Evaluate.h \
+  OctreePost.h Octree.h OctreeInternals.h Probe.h ../Common/Context.h
 # 1 "/Users/geuzaine/.gmsh/Plugin//"
 Levelset.o: Levelset.cpp Levelset.h Plugin.h ../Common/Options.h \
   ../Common/Message.h ../Common/Views.h ../Common/ColorTable.h \
@@ -340,3 +340,9 @@ HarmonicToTime.o: HarmonicToTime.cpp Plugin.h ../Common/Options.h \
   ../DataStr/List.h ../Common/VertexArray.h ../Common/SmoothNormals.h \
   ../Common/GmshMatrix.h ../Common/AdaptiveViews.h ../Common/GmshMatrix.h \
   HarmonicToTime.h ../Common/Context.h ../Numeric/Numeric.h
+# 1 "/Users/geuzaine/.gmsh/Plugin//"
+ModulusPhase.o: ModulusPhase.cpp Plugin.h ../Common/Options.h \
+  ../Common/Message.h ../Common/Views.h ../Common/ColorTable.h \
+  ../DataStr/List.h ../Common/VertexArray.h ../Common/SmoothNormals.h \
+  ../Common/GmshMatrix.h ../Common/AdaptiveViews.h ../Common/GmshMatrix.h \
+  ModulusPhase.h ../Common/Context.h ../Numeric/Numeric.h
diff --git a/Plugin/ModulusPhase.cpp b/Plugin/ModulusPhase.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..4448919c375d0de397986f628fcec71cbb5befd2
--- /dev/null
+++ b/Plugin/ModulusPhase.cpp
@@ -0,0 +1,161 @@
+// $Id: ModulusPhase.cpp,v 1.1 2005-06-27 19:34:34 geuzaine Exp $
+//
+// Copyright (C) 1997-2005 C. Geuzaine, J.-F. Remacle
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+// 
+// Please report all bugs and problems to <gmsh@geuz.org>.
+
+#include "Plugin.h"
+#include "ModulusPhase.h"
+#include "List.h"
+#include "Views.h"
+#include "Context.h"
+#include "Numeric.h"
+
+extern Context_T CTX;
+
+StringXNumber ModulusPhaseOptions_Number[] = {
+  {GMSH_FULLRC, "RealPart", NULL, 0.},
+  {GMSH_FULLRC, "ImaginaryPart", NULL, 1.},
+  {GMSH_FULLRC, "iView", NULL, -1.}
+};
+
+extern "C"
+{
+  GMSH_Plugin *GMSH_RegisterModulusPhasePlugin()
+  {
+    return new GMSH_ModulusPhasePlugin();
+  }
+}
+
+
+GMSH_ModulusPhasePlugin::GMSH_ModulusPhasePlugin()
+{
+  ;
+}
+
+void GMSH_ModulusPhasePlugin::getName(char *name) const
+{
+  strcpy(name, "Modulus Phase");
+}
+
+void GMSH_ModulusPhasePlugin::getInfos(char *author, char *copyright,
+                                        char *help_text) const
+{
+  strcpy(author, "C. Geuzaine (geuz@geuz.org)");
+  strcpy(copyright, "DGR (www.multiphysics.com)");
+  strcpy(help_text,
+         "Plugin(ModulusPhase) interprets the time steps\n"
+	 "`realPart' and `imaginaryPart' in the view `iView'\n"
+	 "as the real and imaginary parts of a complex field\n"
+	 "and replaces them with their corresponding\n"
+	 "modulus and phase. If `iView' < 0, the plugin is\n"
+	 "run on the current view.\n"
+	 "\n"
+	 "Plugin(ModulusPhase) is executed in-place.\n");
+}
+
+int GMSH_ModulusPhasePlugin::getNbOptions() const
+{
+  return sizeof(ModulusPhaseOptions_Number) / sizeof(StringXNumber);
+}
+
+StringXNumber *GMSH_ModulusPhasePlugin::getOption(int iopt)
+{
+  return &ModulusPhaseOptions_Number[iopt];
+}
+
+void GMSH_ModulusPhasePlugin::catchErrorMessage(char *errorMessage) const
+{
+  strcpy(errorMessage, "ModulusPhase failed...");
+}
+
+
+static void mp(int nb1, List_T *list1, int nbNod, int nbComp)
+{
+  if(!nb1) return;
+
+  int rIndex = (int)ModulusPhaseOptions_Number[0].def;
+  int iIndex = (int)ModulusPhaseOptions_Number[1].def;
+
+  int nb = List_Nbr(list1) / nb1;
+  for(int i = 0; i < List_Nbr(list1); i += nb) {
+    double *valr = (double *)List_Pointer_Fast(list1, i + 3 * nbNod +
+					       nbNod * nbComp * rIndex);
+    double *vali = (double *)List_Pointer_Fast(list1, i + 3 * nbNod +
+					       nbNod * nbComp * iIndex);
+    for(int j = 0; j < nbNod; j++) {
+      for(int k = 0; k < nbComp; k++) {
+	double vr = valr[nbComp * j + k];
+	double vi = vali[nbComp * j + k];
+	double modulus = sqrt(vr*vr+vi*vi);
+	double phase = atan2(vi, vr);
+	valr[nbComp * j + k] = modulus;
+	vali[nbComp * j + k] = phase;
+      }
+    }
+  }
+}
+
+Post_View *GMSH_ModulusPhasePlugin::execute(Post_View * v)
+{
+  int rIndex = (int)ModulusPhaseOptions_Number[0].def;
+  int iIndex = (int)ModulusPhaseOptions_Number[1].def;
+  int iView = (int)ModulusPhaseOptions_Number[2].def;
+
+  if(iView < 0)
+    iView = v ? v->Index : 0;
+
+  if(!List_Pointer_Test(CTX.post.list, iView)) {
+    Msg(GERROR, "View[%d] does not exist", iView);
+    return v;
+  }
+
+  Post_View *v1 = *(Post_View **)List_Pointer(CTX.post.list, iView);
+  if(rIndex < 0 || rIndex >= v1->NbTimeStep ||
+     iIndex < 0 || iIndex >= v1->NbTimeStep){
+    Msg(GERROR, "Wrong real or imaginary part index");
+    return v1;
+  }
+
+  mp(v1->NbSP, v1->SP, 1, 1); mp(v1->NbVP, v1->VP, 1, 3); mp(v1->NbTP, v1->TP, 1, 9);
+  mp(v1->NbSL, v1->SL, 2, 1); mp(v1->NbVL, v1->VL, 2, 3); mp(v1->NbTL, v1->TL, 2, 9);
+  mp(v1->NbST, v1->ST, 3, 1); mp(v1->NbVT, v1->VT, 3, 3); mp(v1->NbTT, v1->TT, 3, 9);
+  mp(v1->NbSQ, v1->SQ, 4, 1); mp(v1->NbVQ, v1->VQ, 4, 3); mp(v1->NbTQ, v1->TQ, 4, 9);
+  mp(v1->NbSS, v1->SS, 4, 1); mp(v1->NbVS, v1->VS, 4, 3); mp(v1->NbTS, v1->TS, 4, 9);
+  mp(v1->NbSH, v1->SH, 8, 1); mp(v1->NbVH, v1->VH, 8, 3); mp(v1->NbTH, v1->TH, 8, 9);
+  mp(v1->NbSI, v1->SI, 6, 1); mp(v1->NbVI, v1->VI, 6, 3); mp(v1->NbTI, v1->TI, 6, 9);
+  mp(v1->NbSY, v1->SY, 5, 1); mp(v1->NbVY, v1->VY, 5, 3); mp(v1->NbTY, v1->TY, 5, 9);
+
+  // recompute min/max, etc.:
+  for(int i = 0; i < v1->NbTimeStep; i++){
+    v1->TimeStepMin[i] = VAL_INF;
+    v1->TimeStepMax[i] = -VAL_INF;
+  }
+  v1->Min = VAL_INF;
+  v1->Max = -VAL_INF;
+  for(int i = 0; i < 3; i++) {
+    v1->BBox[2 * i] = VAL_INF;
+    v1->BBox[2 * i + 1] = -VAL_INF;
+  }
+  char name[1024], filename[1024];
+  sprintf(name, "%s_ModulusPhase", v1->Name);
+  sprintf(filename, "%s_ModulusPhase.pos", v1->Name);
+  EndView(v1, 0, filename, name);
+
+  return v1;
+}
diff --git a/Plugin/ModulusPhase.h b/Plugin/ModulusPhase.h
new file mode 100644
index 0000000000000000000000000000000000000000..8ebc82256baa4db3fdd6efdf576b4798f400ebde
--- /dev/null
+++ b/Plugin/ModulusPhase.h
@@ -0,0 +1,42 @@
+#ifndef _MODULUS_PHASE_H_
+#define _MODULUS_PHASE_H_
+
+// Copyright (C) 1997-2005 C. Geuzaine, J.-F. Remacle
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+// 
+// Please report all bugs and problems to <gmsh@geuz.org>.
+
+#include "Plugin.h"
+
+extern "C"
+{
+  GMSH_Plugin *GMSH_RegisterModulusPhasePlugin();
+}
+
+class GMSH_ModulusPhasePlugin : public GMSH_Post_Plugin
+{
+public:
+  GMSH_ModulusPhasePlugin();
+  void getName(char *name) const;
+  void getInfos(char *author, char *copyright, char *help_text) const;
+  void catchErrorMessage(char *errorMessage) const;
+  int getNbOptions() const;
+  StringXNumber* getOption(int iopt);  
+  Post_View *execute(Post_View *);
+};
+
+#endif
diff --git a/Plugin/Plugin.cpp b/Plugin/Plugin.cpp
index 26d6bf736a39f11b163476a8a10dcce2478aa0c4..c5a312a00d0ede25fffa9402562995f73a963550 100644
--- a/Plugin/Plugin.cpp
+++ b/Plugin/Plugin.cpp
@@ -1,4 +1,4 @@
-// $Id: Plugin.cpp,v 1.76 2005-04-19 16:03:16 remacle Exp $
+// $Id: Plugin.cpp,v 1.77 2005-06-27 19:34:34 geuzaine Exp $
 //
 // Copyright (C) 1997-2005 C. Geuzaine, J.-F. Remacle
 //
@@ -41,6 +41,7 @@
 #include "Skin.h"
 #include "Extract.h"
 #include "HarmonicToTime.h"
+#include "ModulusPhase.h"
 #include "Integrate.h"
 #include "Gradient.h"
 #include "Curl.h"
@@ -199,6 +200,8 @@ void GMSH_PluginManager::registerDefaultPlugins()
 		      ("DisplacementRaise", GMSH_RegisterDisplacementRaisePlugin()));
     allPlugins.insert(std::pair < char *, GMSH_Plugin * >
 		      ("HarmonicToTime", GMSH_RegisterHarmonicToTimePlugin()));
+    allPlugins.insert(std::pair < char *, GMSH_Plugin * >
+		      ("ModulusPhase", GMSH_RegisterModulusPhasePlugin()));
     allPlugins.insert(std::pair < char *, GMSH_Plugin * >
 		      ("Integrate", GMSH_RegisterIntegratePlugin()));
     allPlugins.insert(std::pair < char *, GMSH_Plugin * >
diff --git a/doc/texinfo/opt_plugin.texi b/doc/texinfo/opt_plugin.texi
index 7ec278d1afd11f62bbffb1845eb40979bcb039e6..592b9b9d58754947fe0c2e05c67fdf0a670bd59d 100644
--- a/doc/texinfo/opt_plugin.texi
+++ b/doc/texinfo/opt_plugin.texi
@@ -513,6 +513,26 @@ Default value: @code{2}
 Default value: @code{-1}
 @end table
 
+@item Plugin(ModulusPhase)
+Plugin(ModulusPhase) interprets the time steps
+`realPart' and `imaginaryPart' in the view `iView'
+as the real and imaginary parts of a complex field
+and replaces them with their corresponding
+modulus and phase. If `iView' < 0, the plugin is
+run on the current view.
+
+Plugin(ModulusPhase) is executed in-place.
+
+Numeric options:
+@table @code
+@item RealPart
+Default value: @code{0}
+@item ImaginaryPart
+Default value: @code{1}
+@item iView
+Default value: @code{-1}
+@end table
+
 @item Plugin(Probe)
 Plugin(Probe) gets the value of the view `iView' at
 the point (`X',`Y',`Z'). If `iView' < 0, the plugin is