diff --git a/applications/test/ensightFile/Make/files b/applications/test/ensightFile/Make/files
new file mode 100644
index 0000000000000000000000000000000000000000..856556c31697747e52200d5a0c9702ca2fb4a2d1
--- /dev/null
+++ b/applications/test/ensightFile/Make/files
@@ -0,0 +1,3 @@
+Test-ensightFile.C
+
+EXE = $(FOAM_USER_APPBIN)/Test-ensightFile
diff --git a/applications/test/ensightFile/Make/options b/applications/test/ensightFile/Make/options
new file mode 100644
index 0000000000000000000000000000000000000000..a4f7656262c1b023744c2cad1b819aefa108ef52
--- /dev/null
+++ b/applications/test/ensightFile/Make/options
@@ -0,0 +1,10 @@
+EXE_INC = \
+    -I$(LIB_SRC)/conversion/lnInclude \
+    -I$(LIB_SRC)/fileFormats/lnInclude \
+    -I$(LIB_SRC)/meshTools/lnInclude
+
+EXE_LIBS = \
+    -lconversion \
+    -lfileFormats \
+    -lmeshTools
+
diff --git a/applications/test/ensightFile/Test-ensightFile.C b/applications/test/ensightFile/Test-ensightFile.C
new file mode 100644
index 0000000000000000000000000000000000000000..6921176bc233ba6eef1f0e62dc5f45492a5c66d0
--- /dev/null
+++ b/applications/test/ensightFile/Test-ensightFile.C
@@ -0,0 +1,77 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2016 OpenCFD Ltd.
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM 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 3 of the License, or
+    (at your option) any later version.
+
+    OpenFOAM 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 OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
+
+Application
+    Test-ensightFile
+
+Description
+    check cleanup of ensight file and variable names
+
+\*---------------------------------------------------------------------------*/
+
+#include "argList.H"
+#include "ensightFileName.H"
+#include "ensightVarName.H"
+#include "IOstreams.H"
+
+using namespace Foam;
+
+void printCleaning(const fileName& pathName)
+{
+    Info<< "input = " << pathName << nl;
+    Info<< "file  = " << ensight::FileName(pathName) << nl;
+    Info<< "var   = " << ensight::VarName(pathName)  << nl;
+    Info<< nl;
+}
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+// Main program:
+
+int main(int argc, char *argv[])
+{
+    argList::noBanner();
+    argList::noParallel();
+    argList::validArgs.insert("fileName .. fileNameN");
+
+    argList args(argc, argv, false, true);
+
+    if (args.size() <= 1 && args.options().empty())
+    {
+        args.printUsage();
+    }
+
+    fileName pathName;
+
+    for (label argI=1; argI < args.size(); ++argI)
+    {
+        pathName = args[argI];
+        printCleaning(pathName);
+    }
+
+    Info<< "\nEnd\n" << endl;
+    return 0;
+}
+
+
+// ************************************************************************* //
diff --git a/applications/utilities/postProcessing/dataConversion/foamToEnsightParts/checkHasMovingMesh.H b/applications/utilities/postProcessing/dataConversion/foamToEnsightParts/checkHasMovingMesh.H
index 454cb3ebb6b61c454ae34c7254ecaf05487b3d62..d59f258d356a6103aa7200349290946a0d0a519e 100644
--- a/applications/utilities/postProcessing/dataConversion/foamToEnsightParts/checkHasMovingMesh.H
+++ b/applications/utilities/postProcessing/dataConversion/foamToEnsightParts/checkHasMovingMesh.H
@@ -1,4 +1,5 @@
 // check for "points" in all of the result directories
+// - could restrict to the selected times
 
 bool hasMovingMesh = false;
 if (timeDirs.size() > 1)
diff --git a/applications/utilities/postProcessing/dataConversion/foamToEnsightParts/ensightOutputCase.H b/applications/utilities/postProcessing/dataConversion/foamToEnsightParts/ensightOutputCase.H
index 0d221590790e6ef2dab658669ab9bd0ed819ba1e..83bae0f842363da1d144539f21bbd1ec73a473e1 100644
--- a/applications/utilities/postProcessing/dataConversion/foamToEnsightParts/ensightOutputCase.H
+++ b/applications/utilities/postProcessing/dataConversion/foamToEnsightParts/ensightOutputCase.H
@@ -8,7 +8,7 @@ if (timeDirs[0].value() < 0)
 }
 
 // the case file is always ASCII
-Info << "write case: " << caseFileName.c_str() << endl;
+Info<< "write case: " << caseFileName.c_str() << endl;
 
 OFstream caseFile(ensightDir/caseFileName, IOstream::ASCII);
 caseFile.setf(ios_base::left);
@@ -20,7 +20,9 @@ caseFile
     << "FORMAT" << nl
     << setw(16) << "type:" << "ensight gold" << nl << nl;
 
-if (hasMovingMesh)
+// time-set for geometries
+// TODO: split off into separate time-set, but need to verify ensight spec
+if (geometryTimesUsed.size())
 {
     caseFile
         << "GEOMETRY" << nl
@@ -43,7 +45,7 @@ forAllConstIter(HashTable<HashTable<word>>, cloudFields, cloudIter)
     caseFile
         << setw(16) << "measured: 2"
         << fileName(dataMask/cloud::prefix/cloudName/"positions").c_str()
-            << nl;
+        << nl;
 }
 caseFile
     << nl << "VARIABLE" << nl;
@@ -87,9 +89,8 @@ forAllConstIter(HashTable<word>, volumeFields, fieldIter)
     }
 }
 
-// TODO: allow similar/different time-steps for each cloud
-
 
+// TODO: allow similar/different time-steps for each cloud
 label cloudNo = 0;
 forAllConstIter(HashTable<HashTable<word>>, cloudFields, cloudIter)
 {
@@ -135,7 +136,7 @@ forAllConstIter(HashTable<HashTable<word>>, cloudFields, cloudIter)
 // add time values
 caseFile << nl << "TIME" << nl;
 
-// time set 1 - geometry and volume fields
+// time set 1 - volume fields
 if (fieldTimesUsed.size())
 {
     caseFile
@@ -161,9 +162,50 @@ if (fieldTimesUsed.size())
     count = 0;
     forAll(fieldTimesUsed, i)
     {
+        const label& index = fieldTimesUsed[i];
+        caseFile
+            << " " << setw(12) << timeIndices[index] + timeCorrection;
+
+        if (++count % 6 == 0)
+        {
+            caseFile << nl;
+        }
+    }
+    caseFile << nl << nl;
+}
+
+
+// time set 2 - geometry
+// THIS NEEDS MORE CHECKING
+#if 0
+if (geometryTimesUsed.size())
+{
+    caseFile
+        << "time set:        " << 2 << nl
+        << "number of steps: " << geometryTimesUsed.size() << nl
+        << "filename numbers:" << nl;
+
+    label count = 0;
+    forAll(geometryTimesUsed, i)
+    {
+        caseFile
+            << " " << setw(12) << geometryTimesUsed[i];
+
+        if (++count % 6 == 0)
+        {
+            caseFile << nl;
+        }
+    }
+
+    caseFile
+        << nl << "time values:" << nl;
+
+    count = 0;
+    forAll(geometryTimesUsed, i)
+    {
+        const label& index = geometryTimesUsed[i];
         caseFile
-            << " " << setw(12)
-                << timeIndices[fieldTimesUsed[i]] + timeCorrection;
+            << " " << setw(12) << timeIndices[index] + timeCorrection;
 
         if (++count % 6 == 0)
         {
@@ -172,7 +214,9 @@ if (fieldTimesUsed.size())
     }
     caseFile << nl << nl;
 }
+#endif
 
+// time set - clouds
 // TODO: allow similar/different time-steps for each cloud
 cloudNo = 0;
 forAllConstIter(HashTable<DynamicList<label>>, cloudTimesUsed, cloudIter)
@@ -205,9 +249,9 @@ forAllConstIter(HashTable<DynamicList<label>>, cloudTimesUsed, cloudIter)
         count = 0;
         forAll(timesUsed, i)
         {
+            const label& index = timesUsed[i];
             caseFile
-                << " " << setw(12)
-                    << timeIndices[timesUsed[i]] + timeCorrection;
+                << " " << setw(12) << timeIndices[index] + timeCorrection;
 
             if (++count % 6 == 0)
             {
diff --git a/applications/utilities/postProcessing/dataConversion/foamToEnsightParts/ensightOutputFunctions.C b/applications/utilities/postProcessing/dataConversion/foamToEnsightParts/ensightOutputFunctions.C
index 309b49a82ddaee8e1b7860fa9483b4a3c9b1007d..2c92bee9cc43b47aa3c0c017ed378fa37d996d2e 100644
--- a/applications/utilities/postProcessing/dataConversion/foamToEnsightParts/ensightOutputFunctions.C
+++ b/applications/utilities/postProcessing/dataConversion/foamToEnsightParts/ensightOutputFunctions.C
@@ -3,7 +3,7 @@
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
     \\  /    A nd           | Copyright (C) 2011-2016 OpenFOAM Foundation
-     \\/     M anipulation  |
+     \\/     M anipulation  | Copyright (C) 2016 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -47,6 +47,8 @@ void Foam::ensightCaseEntry
     const label timeSet
 )
 {
+    const ensight::VarName varName(fieldName);
+
     caseFile.setf(ios_base::left);
 
     fileName dirName(dataMask);
@@ -68,9 +70,9 @@ void Foam::ensightCaseEntry
             << ensightType.c_str()
             << " per measured node: " << ts << " "
             << setw(15)
-            << ("c" + Foam::name(cloudNo) + fieldName).c_str()
+            << ("c" + Foam::name(cloudNo) + varName).c_str()
             << " "
-            << (dirName/fieldName).c_str()
+            << (dirName/varName).c_str()
             << nl;
     }
     else
@@ -78,9 +80,9 @@ void Foam::ensightCaseEntry
         caseFile
             << ensightType.c_str()
             << " per element: "
-            << setw(15) << fieldName
+            << setw(15) << varName
             << " "
-            << (dirName/fieldName).c_str()
+            << (dirName/varName).c_str()
             << nl;
     }
 }
@@ -97,16 +99,16 @@ void Foam::ensightParticlePositions
 {
     Cloud<passiveParticle> parcels(mesh, cloudName, false);
 
-    fileName cloudDir = subDir/cloud::prefix/cloudName;
-    fileName postFileName = cloudDir/"positions";
+    const fileName postFileName =
+        subDir/cloud::prefix/cloudName/"positions";
 
     // the ITER/lagrangian subdirectory must exist
-    mkDir(dataDir/cloudDir);
-    ensightFile os(dataDir/postFileName, format);
+    mkDir(dataDir/postFileName.path());
+    ensightFile os(dataDir, postFileName, format);
 
     // tag binary format (just like geometry files)
     os.writeBinaryHeader();
-    os.write(postFileName);
+    os.write(postFileName); // description
     os.newline();
     os.write("particle coordinates");
     os.newline();
@@ -161,14 +163,19 @@ void Foam::ensightLagrangianField
 {
     Info<< " " << fieldObject.name() << flush;
 
-    fileName cloudDir = subDir/cloud::prefix/cloudName;
-    fileName postFileName = cloudDir/fieldObject.name();
+    const fileName postFileName =
+        subDir/cloud::prefix/cloudName
+        /ensight::VarName(fieldObject.name());
 
-    string title =
-        postFileName + " with " + pTraits<Type>::typeName + " values";
+    // the ITER/lagrangian subdirectory was already created
+    // when writing positions
 
-    ensightFile os(dataDir/postFileName, format);
-    os.write(title);
+    ensightFile os(dataDir, postFileName, format);
+    os.write
+    (
+        // description
+        string(postFileName + " with " + pTraits<Type>::typeName + " values")
+    );
     os.newline();
 
     IOField<Type> field(fieldObject);
@@ -219,10 +226,10 @@ void Foam::ensightVolField
 {
     Info<< " " << fieldObject.name() << flush;
 
-    fileName postFileName = subDir/fieldObject.name();
+    const fileName postFileName = subDir/ensight::VarName(fieldObject.name());
 
-    ensightFile os(dataDir/postFileName, format);
-    os.write(postFileName);
+    ensightFile os(dataDir, postFileName, format);
+    os.write(postFileName); // description
     os.newline();
 
     // ie, volField<Type>
diff --git a/applications/utilities/postProcessing/dataConversion/foamToEnsightParts/foamToEnsightParts.C b/applications/utilities/postProcessing/dataConversion/foamToEnsightParts/foamToEnsightParts.C
index 6aecc40fc2e4e237a80e8ec69a0c751ae42731cd..0a3cdf6509d7f43b17363d8d69212cfc7cfa6fbf 100644
--- a/applications/utilities/postProcessing/dataConversion/foamToEnsightParts/foamToEnsightParts.C
+++ b/applications/utilities/postProcessing/dataConversion/foamToEnsightParts/foamToEnsightParts.C
@@ -3,7 +3,7 @@
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
     \\  /    A nd           | Copyright (C) 2011-2016 OpenFOAM Foundation
-     \\/     M anipulation  |
+     \\/     M anipulation  | Copyright (C) 2016 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -166,9 +166,9 @@ int main(int argc, char *argv[])
         ensightDir = args.rootPath()/args.globalCaseName()/ensightDir;
     }
 
-    fileName dataDir = ensightDir/"data";
-    fileName caseFileName = "Ensight.case";
-    fileName dataMask = fileName("data")/ensightFile::mask();
+    const fileName caseFileName = "Ensight.case";
+    const fileName dataDir  = ensightDir/"data";
+    const fileName dataMask = dataDir.name()/ensightFile::mask();
 
     // Ensight and Ensight/data directories must exist
     // do not remove old data - we might wish to convert new results
@@ -178,6 +178,8 @@ int main(int argc, char *argv[])
         Info<<"Warning: re-using existing directory" << nl
             << "    " << ensightDir << endl;
     }
+
+    // as per mkdir -p "Ensight/data"
     mkDir(ensightDir);
     mkDir(dataDir);
 
@@ -216,6 +218,9 @@ int main(int argc, char *argv[])
     // map times used
     Map<scalar>  timeIndices;
 
+    // TODO: Track the time indices used by the geometry
+    DynamicList<label> geometryTimesUsed;
+
     // Track the time indices used by the volume fields
     DynamicList<label> fieldTimesUsed;
 
@@ -235,11 +240,12 @@ int main(int argc, char *argv[])
 
         #include "getTimeIndex.H"
 
-        // remember the time index
+        // remember the time index for the volume fields
         fieldTimesUsed.append(timeIndex);
 
         // the data/ITER subdirectory must exist
-        fileName subDir = ensightFile::subDir(timeIndex);
+        // Note that data/ITER is indeed a valid ensight::FileName
+        const fileName subDir = ensightFile::subDir(timeIndex);
         mkDir(dataDir/subDir);
 
         // place a timestamp in the directory for future reference
@@ -261,15 +267,19 @@ int main(int argc, char *argv[])
 
             if (!optNoMesh)
             {
-                fileName geomDir;
                 if (hasMovingMesh)
                 {
-                    geomDir = dataDir/subDir;
+                    // remember the time index for the geometry
+                    geometryTimesUsed.append(timeIndex);
                 }
 
-                ensightGeoFile geoFile(ensightDir/geomDir/geometryName, format);
+                ensightGeoFile geoFile
+                (
+                    (hasMovingMesh ? dataDir/subDir : ensightDir),
+                    geometryName,
+                    format
+                );
                 partsList.writeGeometry(geoFile);
-                Info<< nl;
             }
         }
 
diff --git a/src/conversion/ensight/file/ensightFile.C b/src/conversion/ensight/file/ensightFile.C
index 09269edd329f3a59ce04ad2a8ea15259f52b9f26..5481ca57153702ca14af742b6adbcf9c8f0ef08b 100644
--- a/src/conversion/ensight/file/ensightFile.C
+++ b/src/conversion/ensight/file/ensightFile.C
@@ -3,7 +3,7 @@
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
     \\  /    A nd           | Copyright (C) 2011-2015 OpenFOAM Foundation
-     \\/     M anipulation  |
+     \\/     M anipulation  | Copyright (C) 2016 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -24,6 +24,9 @@ License
 \*---------------------------------------------------------------------------*/
 
 #include "ensightFile.H"
+#include "error.H"
+
+#include <cstring>
 #include <sstream>
 
 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
@@ -33,8 +36,7 @@ bool Foam::ensightFile::allowUndef_ = false;
 Foam::scalar Foam::ensightFile::undefValue_ = Foam::floatScalarVGREAT;
 
 // default is width 8
-Foam::string Foam::ensightFile::mask_ = "********";
-
+Foam::string Foam::ensightFile::mask_   = "********";
 Foam::string Foam::ensightFile::dirFmt_ = "%08d";
 
 
@@ -79,15 +81,9 @@ Foam::label Foam::ensightFile::subDirWidth()
 }
 
 
-// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
+// * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
 
-Foam::ensightFile::ensightFile
-(
-    const fileName& pathname,
-    IOstream::streamFormat format
-)
-:
-    OFstream(pathname, format)
+void Foam::ensightFile::initialize()
 {
     // ascii formatting specs
     setf
@@ -99,6 +95,33 @@ Foam::ensightFile::ensightFile
 }
 
 
+// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
+
+Foam::ensightFile::ensightFile
+(
+    const fileName& pathname,
+    IOstream::streamFormat format
+)
+:
+    OFstream(ensight::FileName(pathname), format)
+{
+    initialize();
+}
+
+
+Foam::ensightFile::ensightFile
+(
+    const fileName& path,
+    const fileName& name,
+    IOstream::streamFormat format
+)
+:
+    OFstream(path/ensight::FileName(name), format)
+{
+    initialize();
+}
+
+
 // * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
 
 Foam::ensightFile::~ensightFile()
@@ -144,30 +167,9 @@ Foam::Ostream& Foam::ensightFile::write
 
 
 Foam::Ostream& Foam::ensightFile::write(const char* value)
-{
-    return write(string(value));
-}
-
-
-Foam::Ostream& Foam::ensightFile::write(const string& value)
 {
     char buf[80];
-
-    for (string::size_type i = 0; i < 80; ++i)
-    {
-        buf[i] = 0;
-    }
-
-    string::size_type n = value.size();
-    if (n >= 80)
-    {
-        n = 79;
-    }
-
-    for (string::size_type i = 0; i < n; ++i)
-    {
-        buf[i] = value[i];
-    }
+    strncpy(buf, value, 80); // max 80 chars or padded with nul if smaller
 
     if (format() == IOstream::BINARY)
     {
@@ -179,10 +181,18 @@ Foam::Ostream& Foam::ensightFile::write(const string& value)
     }
     else
     {
+        buf[79] = 0;  // max 79 in ASCII, ensure it is indeed nul-terminated
         stdStream() << buf;
     }
 
     return *this;
+
+}
+
+
+Foam::Ostream& Foam::ensightFile::write(const string& value)
+{
+    return write(value.c_str());
 }
 
 
diff --git a/src/conversion/ensight/file/ensightFile.H b/src/conversion/ensight/file/ensightFile.H
index c9ed78157547a9cea1d13e17f5986397210fda7d..ea4a29da00908bdc115fdc9e08fc708e25757f5b 100644
--- a/src/conversion/ensight/file/ensightFile.H
+++ b/src/conversion/ensight/file/ensightFile.H
@@ -3,7 +3,7 @@
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
     \\  /    A nd           | Copyright (C) 2011-2015 OpenFOAM Foundation
-     \\/     M anipulation  |
+     \\/     M anipulation  | Copyright (C) 2016 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -36,13 +36,16 @@ Description
 #include "OFstream.H"
 #include "IOstream.H"
 
+#include "ensightFileName.H"
+#include "ensightVarName.H"
+
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
 namespace Foam
 {
 
 /*---------------------------------------------------------------------------*\
-                        Class ensightFile Declaration
+                         Class ensightFile Declaration
 \*---------------------------------------------------------------------------*/
 
 class ensightFile
@@ -66,24 +69,41 @@ class ensightFile
 
     // Private Member Functions
 
+        //- Initialize by setting the ASCII output formatting
+        void initialize();
+
         //- Disallow default bitwise assignment
-        void operator=(const ensightFile&);
+        void operator=(const ensightFile&) = delete;
 
         //- Disallow default copy constructor
-        ensightFile(const ensightFile&);
-
+        ensightFile(const ensightFile&) = delete;
 
 public:
 
+    // Forward declarations
+    class FileName;
+    class VarName;
+
+
     // Constructors
 
-        //- Construct from pathname
+        //- Construct from pathname.
+        //  The entire pathname is checked for valid ensight naming.
         ensightFile
         (
             const fileName& pathname,
             IOstream::streamFormat format=IOstream::BINARY
         );
 
+        //- Construct from path and name.
+        //  Only the name portion is checked for valid ensight naming.
+        ensightFile
+        (
+            const fileName& path,
+            const fileName& name,
+            IOstream::streamFormat format=IOstream::BINARY
+        );
+
 
     //- Destructor
     ~ensightFile();
@@ -135,10 +155,10 @@ public:
         //- Write undef value
         Ostream& writeUndef();
 
-        //- Write C-string as "%80s" or as binary
+        //- Write C-string as "%79s" or as binary (max 80 chars)
         Ostream& write(const char* value);
 
-        //- Write string as "%80s" or as binary
+        //- Write string as "%79s" or as binary (max 80 chars)
         Ostream& write(const string& value);
 
         //- Write integer as "%10d" or as binary
diff --git a/src/conversion/ensight/file/ensightGeoFile.C b/src/conversion/ensight/file/ensightGeoFile.C
index 77f2d9397895110ca23e8055681ed5721db4c09d..749a5d1542679c31e6106492f562c2ac1a16c479 100644
--- a/src/conversion/ensight/file/ensightGeoFile.C
+++ b/src/conversion/ensight/file/ensightGeoFile.C
@@ -3,7 +3,7 @@
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
     \\  /    A nd           | Copyright (C) 2011 OpenFOAM Foundation
-     \\/     M anipulation  |
+     \\/     M anipulation  | Copyright (C) 2016 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -25,6 +25,18 @@ License
 
 #include "ensightGeoFile.H"
 
+// * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
+
+void Foam::ensightGeoFile::initialize()
+{
+    writeBinaryHeader();
+    write("Ensight Geometry File");  newline(); // description line 1
+    write("=====================");  newline(); // description line 2
+    write("node id assign");         newline();
+    write("element id assign");      newline();
+}
+
+
 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
 
 Foam::ensightGeoFile::ensightGeoFile
@@ -35,13 +47,23 @@ Foam::ensightGeoFile::ensightGeoFile
 :
     ensightFile(pathname, format)
 {
-    writeBinaryHeader();
-    write("Ensight Geometry File");  newline();
-    write("=====================");  newline();
-    write("node id assign");         newline();
-    write("element id assign");      newline();
+    initialize();
 }
 
+
+Foam::ensightGeoFile::ensightGeoFile
+(
+    const fileName& path,
+    const fileName& name,
+    IOstream::streamFormat format
+)
+:
+    ensightFile(path, name, format)
+{
+    initialize();
+}
+
+
 // * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
 
 Foam::ensightGeoFile::~ensightGeoFile()
@@ -52,8 +74,7 @@ Foam::ensightGeoFile::~ensightGeoFile()
 
 Foam::Ostream& Foam::ensightGeoFile::writeKeyword(const string& key)
 {
-    write(key);
-    newline();
+    write(key); newline();
 
     return *this;
 }
diff --git a/src/conversion/ensight/file/ensightGeoFile.H b/src/conversion/ensight/file/ensightGeoFile.H
index c4fc94180cb8ccb072a2357ffb69a8f8c743ccfc..0fb9896bf0b40835abeb0576bd0204d89073e796 100644
--- a/src/conversion/ensight/file/ensightGeoFile.H
+++ b/src/conversion/ensight/file/ensightGeoFile.H
@@ -3,7 +3,7 @@
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
     \\  /    A nd           | Copyright (C) 2011-2015 OpenFOAM Foundation
-     \\/     M anipulation  |
+     \\/     M anipulation  | Copyright (C) 2016 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -49,24 +49,37 @@ class ensightGeoFile
 {
     // Private Member Functions
 
+        //- Initialize by outputting header information
+        void initialize();
+
         //- Disallow default bitwise assignment
-        void operator=(const ensightGeoFile&);
+        void operator=(const ensightGeoFile&) = delete;
 
         //- Disallow default copy constructor
-        ensightGeoFile(const ensightGeoFile&);
+        ensightGeoFile(const ensightGeoFile&) = delete;
 
 
 public:
 
     // Constructors
 
-        //- Construct from pathname
+        //- Construct from pathname.
+        //  The entire pathname is checked for valid ensight naming.
         ensightGeoFile
         (
             const fileName& pathname,
             IOstream::streamFormat format=IOstream::BINARY
         );
 
+        //- Construct from path and name.
+        //  Only the name portion is checked for valid ensight naming.
+        ensightGeoFile
+        (
+            const fileName& path,
+            const fileName& name,
+            IOstream::streamFormat format=IOstream::BINARY
+        );
+
 
     //- Destructor
     ~ensightGeoFile();
diff --git a/src/conversion/ensight/name/ensightFileName.H b/src/conversion/ensight/name/ensightFileName.H
new file mode 100644
index 0000000000000000000000000000000000000000..550a86f68c4d7745bcea4611358f24c47ebcaeb7
--- /dev/null
+++ b/src/conversion/ensight/name/ensightFileName.H
@@ -0,0 +1,106 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2016 OpenCFD Ltd.
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM 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 3 of the License, or
+    (at your option) any later version.
+
+    OpenFOAM 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 OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
+
+Class
+    Foam::ensight::FileName
+
+Description
+    Specification of a valid Ensight file-name.
+
+    Spaces must be quoted,
+    no '*' wildcards, not '%' (structured block continuation).
+
+    Overall line length within case file is limited to 1024, but this is not
+    yet addresssed.
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef ensightFileName_H
+#define ensightFileName_H
+
+#include "fileName.H"
+#include "word.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+namespace ensight
+{
+
+/*---------------------------------------------------------------------------*\
+                      Class ensight::FileName Declaration
+\*---------------------------------------------------------------------------*/
+
+class FileName
+:
+    public fileName
+{
+    // Private Member Functions
+
+        //- Strip invalid characters
+        inline void stripInvalid();
+
+public:
+
+    // Constructors
+
+        //- Construct as copy
+        inline explicit FileName(const FileName&);
+
+        //- Construct as copy of character array
+        inline explicit FileName(const char*);
+
+        //- Construct as copy of std::string
+        inline explicit FileName(const std::string&);
+
+
+    // Member functions
+
+        //- Is this character valid for an ensight file-name
+        inline static bool valid(char);
+
+    // Member operators
+
+        // Assignment
+
+            void operator=(const fileName&) = delete;
+            void operator=(const word&) = delete;
+            void operator=(const string&) = delete;
+            void operator=(const std::string&) = delete;
+            void operator=(const char*) = delete;
+
+};
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace ensight
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#include "ensightFileNameI.H"
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/conversion/ensight/name/ensightFileNameI.H b/src/conversion/ensight/name/ensightFileNameI.H
new file mode 100644
index 0000000000000000000000000000000000000000..495ca6df006423dec2500d5631f46955f197f4c2
--- /dev/null
+++ b/src/conversion/ensight/name/ensightFileNameI.H
@@ -0,0 +1,83 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2016 OpenCFD Ltd.
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM 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 3 of the License, or
+    (at your option) any later version.
+
+    OpenFOAM 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 OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
+
+\*---------------------------------------------------------------------------*/
+
+#include "error.H"
+#include <cctype>
+
+// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
+
+inline Foam::ensight::FileName::FileName(const FileName& fn)
+:
+    fileName(fn, false)
+{}
+
+
+inline Foam::ensight::FileName::FileName(const char* s)
+:
+    fileName(s, false)
+{
+    stripInvalid();
+}
+
+
+inline Foam::ensight::FileName::FileName(const std::string& s)
+:
+    fileName(s, false)
+{
+    stripInvalid();
+}
+
+
+
+// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
+
+inline void Foam::ensight::FileName::stripInvalid()
+{
+    string::stripInvalid<FileName>(*this);
+
+    removeRepeated('/');
+    removeTrailing('/');
+
+    if (empty())
+    {
+        FatalErrorInFunction
+            << "ensight::FileName empty after stripping" << nl
+            << exit(FatalError);
+    }
+}
+
+
+inline bool Foam::ensight::FileName::valid(char c)
+{
+    return
+    (
+        fileName::valid(c)  // includes space, quotes
+     && c != '*'   // wild-card
+     && c != '%'   // structured block continuation
+    );
+}
+
+
+// ************************************************************************* //
diff --git a/src/conversion/ensight/name/ensightVarName.H b/src/conversion/ensight/name/ensightVarName.H
new file mode 100644
index 0000000000000000000000000000000000000000..fe2c57aefbf50812b36e107c790c3e28a14db959
--- /dev/null
+++ b/src/conversion/ensight/name/ensightVarName.H
@@ -0,0 +1,111 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2016 OpenCFD Ltd.
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM 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 3 of the License, or
+    (at your option) any later version.
+
+    OpenFOAM 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 OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
+
+Class
+    Foam::ensight::VarName
+
+Description
+    Specification of a valid Ensight variable-name.
+
+    \code
+        space !#%()*+,-./;@[]^
+    \endcode
+    If spaces exist, they must be quoted
+
+    Variable names cannot start with a digit.
+    The maximum part name length (in GUI: 49 chars) - not addresssed.
+    The maximum variable length (in GUI: 49 chars) - not addresssed.
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef ensightVarName_H
+#define ensightVarName_H
+
+#include "word.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+namespace ensight
+{
+
+/*---------------------------------------------------------------------------*\
+                      Class ensight::VarName Declaration
+\*---------------------------------------------------------------------------*/
+
+class VarName
+:
+    public word
+{
+    // Private Member Functions
+
+        //- Strip invalid characters
+        inline void stripInvalid();
+
+
+public:
+
+
+    // Constructors
+
+        //- Construct as copy
+        inline explicit VarName(const VarName&);
+
+        //- Construct as copy of character array
+        inline explicit VarName(const char*);
+
+        //- Construct as copy of std::string
+        inline explicit VarName(const std::string&);
+
+
+    // Member functions
+
+        //- Is this character valid for an ensight var-name
+        inline static bool valid(char);
+
+
+    // Member operators
+
+        // Assignment
+
+            void operator=(const word&) = delete;
+            void operator=(const string&) = delete;
+            void operator=(const std::string&) = delete;
+            void operator=(const char*) = delete;
+
+};
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace ensight
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#include "ensightVarNameI.H"
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/conversion/ensight/name/ensightVarNameI.H b/src/conversion/ensight/name/ensightVarNameI.H
new file mode 100644
index 0000000000000000000000000000000000000000..17bec6125a78c5c64bf97be18b3e77e5f5b22a5c
--- /dev/null
+++ b/src/conversion/ensight/name/ensightVarNameI.H
@@ -0,0 +1,100 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2016 OpenCFD Ltd.
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM 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 3 of the License, or
+    (at your option) any later version.
+
+    OpenFOAM 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 OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
+
+\*---------------------------------------------------------------------------*/
+
+#include "error.H"
+#include <cctype>
+
+
+// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
+
+inline Foam::ensight::VarName::VarName(const VarName& vn)
+:
+    word(vn, false)
+{}
+
+
+inline Foam::ensight::VarName::VarName(const char* s)
+:
+    word(s, false)
+{
+    stripInvalid();
+}
+
+
+inline Foam::ensight::VarName::VarName(const std::string& s)
+:
+    word(s, false)
+{
+    stripInvalid();
+}
+
+
+
+// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
+
+inline void Foam::ensight::VarName::stripInvalid()
+{
+    string::stripInvalid<VarName>(*this);
+
+    if (empty())
+    {
+        FatalErrorInFunction
+            << "ensight::VarName empty after stripping" << nl
+            << exit(FatalError);
+    }
+
+    // prefix with '_' to avoid starting with leading digits
+    std::string::iterator iter = begin();
+    if (isdigit(*iter))
+    {
+        insert(iter, '_');
+    }
+}
+
+
+inline bool Foam::ensight::VarName::valid(char c)
+{
+    return
+    (
+        word::valid(c) // includes space, quotes, /\;{}
+     && c != '!'
+     && c != '#'
+     && c != '%'
+     && c != '('
+     && c != ')'
+     && c != '*'
+     && c != '+'
+     && c != ','
+     && c != '-'
+     && c != '.'
+     && c != '@'
+     && c != '['
+     && c != ']'
+     && c != '^'
+    );
+}
+
+
+// ************************************************************************* //
diff --git a/src/conversion/ensight/part/ensightParts.C b/src/conversion/ensight/part/ensightParts.C
index dce9cabfed270c0e39e5951665295093455e1332..a7675bf4839c3fb428f3ec8b4532e06ac021a919 100644
--- a/src/conversion/ensight/part/ensightParts.C
+++ b/src/conversion/ensight/part/ensightParts.C
@@ -183,13 +183,14 @@ void Foam::ensightParts::renumber
 void Foam::ensightParts::writeGeometry(ensightGeoFile& os) const
 {
     // with some feedback
-    Info<< "write geometry part:" << nl << flush;
+    Info<< "write geometry part (" << flush;
 
     forAll(partsList_, partI)
     {
         Info<< " " << partI << flush;
         partsList_[partI].writeGeometry(os);
     }
+    Info<< " )" << endl;
 }
 
 
diff --git a/src/sampling/sampledSurface/writers/ensight/ensightSurfaceWriter.C b/src/sampling/sampledSurface/writers/ensight/ensightSurfaceWriter.C
index 89eadae4fe22fd517dedd8e0406f21df3dbf746d..e8c5589d7d4834cacc23d8399a0f49fe66d49c91 100644
--- a/src/sampling/sampledSurface/writers/ensight/ensightSurfaceWriter.C
+++ b/src/sampling/sampledSurface/writers/ensight/ensightSurfaceWriter.C
@@ -77,6 +77,8 @@ Foam::fileName Foam::ensightSurfaceWriter::write
     const bool verbose
 ) const
 {
+    const ensight::FileName surfName(surfaceName);
+
     if (!isDir(outputDir))
     {
         mkDir(outputDir);
@@ -85,10 +87,11 @@ Foam::fileName Foam::ensightSurfaceWriter::write
     // const scalar timeValue = Foam::name(this->mesh().time().timeValue());
     const scalar timeValue = 0.0;
 
-    OFstream osCase(outputDir/surfaceName + ".case");
+    OFstream osCase(outputDir/surfName + ".case");
     ensightGeoFile osGeom
     (
-        outputDir/surfaceName + ".0000.mesh",
+        outputDir,
+        surfName + ".0000.mesh",
         writeFormat_
     );
 
diff --git a/src/sampling/sampledSurface/writers/ensight/ensightSurfaceWriterTemplates.C b/src/sampling/sampledSurface/writers/ensight/ensightSurfaceWriterTemplates.C
index 1d14ab01966abd70849a6ffd7a2b743122ee9b65..b564b5c8e596cda596d07fd293257ca120760d32 100644
--- a/src/sampling/sampledSurface/writers/ensight/ensightSurfaceWriterTemplates.C
+++ b/src/sampling/sampledSurface/writers/ensight/ensightSurfaceWriterTemplates.C
@@ -3,7 +3,7 @@
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
     \\  /    A nd           | Copyright (C) 2011-2014 OpenFOAM Foundation
-     \\/     M anipulation  | Copyright (C) 2015 OpenCFD Ltd.
+     \\/     M anipulation  | Copyright (C) 2015-2016 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -47,23 +47,43 @@ Foam::fileName Foam::ensightSurfaceWriter::writeUncollated
     const bool verbose
 ) const
 {
-    if (!isDir(outputDir/fieldName))
+    const ensight::FileName surfName(surfaceName);
+    const ensight::VarName  varName(fieldName);
+
+    // use variable name as sub-directory for results
+    // eg, something like this:
+    // - VAR1/SURF1.case
+    // - VAR1/SURF1.0000.mesh
+    // - VAR1/SURF1.0001.VAR1
+    // - VAR1/SURF2.case
+    // - VAR1/SURF2.0000.mesh
+    // - VAR1/SURF2.0001.VAR1
+    // and
+    // - VAR2/SURF1.case
+    // - VAR2/SURF1.0000.mesh
+    // - VAR2/SURF1.0001.VAR2
+
+    const fileName baseDir = outputDir/varName;
+
+    if (!isDir(baseDir))
     {
-        mkDir(outputDir/fieldName);
+        mkDir(baseDir);
     }
 
     // const scalar timeValue = Foam::name(this->mesh().time().timeValue());
     const scalar timeValue = 0.0;
 
-    OFstream osCase(outputDir/fieldName/surfaceName + ".case");
+    OFstream osCase(baseDir/surfName + ".case");
     ensightGeoFile osGeom
     (
-        outputDir/fieldName/surfaceName + ".0000.mesh",
+        baseDir,
+        surfName + ".0000.mesh",
         writeFormat_
     );
     ensightFile osField
     (
-        outputDir/fieldName/surfaceName + ".0000." + fieldName,
+        baseDir,
+        surfName + ".0000." + varName,
         writeFormat_
     );
 
@@ -82,8 +102,8 @@ Foam::fileName Foam::ensightSurfaceWriter::writeUncollated
         << "VARIABLE" << nl
         << ensightPTraits<Type>::typeName << " per "
         << word(isNodeValues ? "node:" : "element:") << setw(10) << 1
-        << "       " << fieldName
-        << "       " << surfaceName.c_str() << ".****." << fieldName << nl
+        << "       " << varName
+        << "       " << surfName.c_str() << ".****." << varName << nl
         << nl
         << "TIME" << nl
         << "time set:                      1" << nl
@@ -118,8 +138,22 @@ Foam::fileName Foam::ensightSurfaceWriter::writeCollated
     const bool verbose
 ) const
 {
-
-    const fileName baseDir = outputDir.path()/surfaceName;
+    const ensight::FileName surfName(surfaceName);
+    const ensight::VarName  varName(fieldName);
+
+    // use surface name as sub-directory for results
+    // eg, something like this:
+    // - SURF1/SURF1.case
+    // - SURF1/SURF1.0000.mesh
+    // - SURF1/SURF1.0001.VAR1
+    // - SURF1/SURF1.0001.VAR2
+    // and
+    // - SURF2/SURF2.case
+    // - SURF2/SURF2.0000.mesh
+    // - SURF2/SURF2.0001.VAR1
+    // - SURF2/SURF2.0001.VAR2
+
+    const fileName baseDir = outputDir.path()/surfName;
     const fileName timeDir = outputDir.name();
 
     if (!isDir(baseDir))
@@ -127,7 +161,8 @@ Foam::fileName Foam::ensightSurfaceWriter::writeCollated
         mkDir(baseDir);
     }
 
-    const fileName meshFile(baseDir/surfaceName + ".0000.mesh");
+    // surfName already validated
+    const fileName meshFile(baseDir/surfName + ".0000.mesh");
     const scalar timeValue = readScalar(IStringStream(timeDir)());
     label timeIndex = 0;
 
@@ -171,6 +206,8 @@ Foam::fileName Foam::ensightSurfaceWriter::writeCollated
                 {
                     dictionary fieldDict;
                     fieldDict.set("type", ensightPTraits<Type>::typeName);
+                    fieldDict.set("name", varName); // ensight variable name
+
                     fieldsDict.set(fieldName, fieldDict);
 
                     stateChanged = true;
@@ -180,6 +217,7 @@ Foam::fileName Foam::ensightSurfaceWriter::writeCollated
             {
                 dictionary fieldDict;
                 fieldDict.set("type", ensightPTraits<Type>::typeName);
+                fieldDict.set("name", varName); // ensight variable name
 
                 dictionary fieldsDict;
                 fieldsDict.set(fieldName, fieldDict);
@@ -201,7 +239,7 @@ Foam::fileName Foam::ensightSurfaceWriter::writeCollated
             os << dict;
 
 
-            OFstream osCase(baseDir/surfaceName + ".case");
+            OFstream osCase(baseDir/surfName + ".case");
 
             if (verbose)
             {
@@ -216,18 +254,24 @@ Foam::fileName Foam::ensightSurfaceWriter::writeCollated
                 << "model:        1     " << meshFile.name() << nl
                 << nl
                 << "VARIABLE" << nl;
+
             const dictionary& fieldsDict = dict.subDict("fields");
             forAllConstIter(dictionary, fieldsDict, iter)
             {
-                const word& fieldName = iter().keyword();
-                const word fieldType(iter().dict().lookup("type"));
+                const dictionary& subDict = iter().dict();
+                const word fieldType(subDict.lookup("type"));
+                const word varName = subDict.lookupOrDefault
+                (
+                    "name",
+                    iter().keyword() // fieldName as fallback
+                );
 
                 osCase
                     << fieldType << " per "
                     << word(isNodeValues ? "node:" : "element:")
                     << setw(10) << 1
-                    << setw(15) << fieldName
-                    << "       " << surfaceName.c_str() << ".****." << fieldName
+                    << setw(15) << varName
+                    << "       " << surfName.c_str() << ".****." << varName
                     << nl;
             }
             osCase << nl;
@@ -261,7 +305,8 @@ Foam::fileName Foam::ensightSurfaceWriter::writeCollated
         {
             Info<< "Writing mesh file to " << meshFile.name() << endl;
         }
-        ensightGeoFile osGeom(meshFile, writeFormat_);
+        // use two-argument form for path-name to avoid validating the base-dir
+        ensightGeoFile osGeom(meshFile.path(), meshFile.name(), writeFormat_);
         osGeom << ensPart;
     }
 
@@ -278,7 +323,8 @@ Foam::fileName Foam::ensightSurfaceWriter::writeCollated
     // Write field
     ensightFile osField
     (
-        baseDir/surfaceName + "." + timeString + "." + fieldName,
+        baseDir,
+        surfName + "." + timeString + "." + varName,
         writeFormat_
     );
     if (verbose)
@@ -288,7 +334,7 @@ Foam::fileName Foam::ensightSurfaceWriter::writeCollated
     osField.writeKeyword(ensightPTraits<Type>::typeName);
     ensPart.writeField(osField, values, isNodeValues);
 
-    return baseDir/surfaceName + ".case";
+    return baseDir/surfName + ".case";
 }