diff --git a/applications/utilities/preProcessing/snappyHexMeshConfig/Make/files b/applications/utilities/preProcessing/snappyHexMeshConfig/Make/files
new file mode 100644
index 0000000000..e364d57038
--- /dev/null
+++ b/applications/utilities/preProcessing/snappyHexMeshConfig/Make/files
@@ -0,0 +1,11 @@
+meshingSurface.C
+meshingSurfaceList.C
+caseFileConfiguration.C
+blockMeshConfigurationBase.C
+blockMeshCartesianConfiguration.C
+blockMeshCylindricalConfiguration.C
+snappyHexMeshConfiguration.C
+surfaceFeaturesConfiguration.C
+snappyHexMeshConfig.C
+
+EXE = $(FOAM_APPBIN)/snappyHexMeshConfig
diff --git a/applications/utilities/preProcessing/snappyHexMeshConfig/Make/options b/applications/utilities/preProcessing/snappyHexMeshConfig/Make/options
new file mode 100644
index 0000000000..02673494be
--- /dev/null
+++ b/applications/utilities/preProcessing/snappyHexMeshConfig/Make/options
@@ -0,0 +1,13 @@
+EXE_INC = \
+ -I$(LIB_SRC)/sampling/lnInclude \
+ -I$(LIB_SRC)/meshTools/lnInclude \
+ -I$(LIB_SRC)/mesh/blockMesh/lnInclude \
+ -I$(LIB_SRC)/fileFormats/lnInclude \
+ -I$(LIB_SRC)/triSurface/lnInclude
+
+EXE_LIBS = \
+ -lsampling \
+ -ltriSurface \
+ -lfileFormats \
+ -lmeshTools \
+ -lblockMesh
diff --git a/applications/utilities/preProcessing/snappyHexMeshConfig/Tuple3.H b/applications/utilities/preProcessing/snappyHexMeshConfig/Tuple3.H
new file mode 100644
index 0000000000..be601d70f2
--- /dev/null
+++ b/applications/utilities/preProcessing/snappyHexMeshConfig/Tuple3.H
@@ -0,0 +1,263 @@
+/*---------------------------------------------------------------------------*\
+ ========= |
+ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
+ \\ / O peration | Website: https://openfoam.org
+ \\ / A nd | Copyright (C) 2023 OpenFOAM Foundation
+ \\/ 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 .
+
+Class
+ Foam::Tuple3
+
+Description
+ A 3-tuple for storing three objects of different types.
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef Tuple3_H
+#define Tuple3_H
+
+#include "Istream.H"
+#include "Hash.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+// Forward declaration of friend functions and operators
+
+template
+class Tuple3;
+
+template
+inline Istream& operator>>(Istream&, Tuple3&);
+
+template
+inline Ostream& operator<<(Ostream&, const Tuple3&);
+
+
+/*---------------------------------------------------------------------------*\
+ Class Tuple3 Declaration
+\*---------------------------------------------------------------------------*/
+
+template
+class Tuple3
+{
+ // Private Data
+
+ Type1 f_;
+ Type2 s_;
+ Type3 t_;
+
+
+public:
+
+ //- Hashing function class
+ template
+ <
+ class HashT1=Hash,
+ class HashT2=Hash,
+ class HashT3=Hash
+ >
+ class Hash
+ {
+ public:
+ Hash()
+ {}
+
+ inline unsigned operator()
+ (
+ const Tuple3&,
+ unsigned seed = 0
+ ) const;
+ };
+
+
+ // Static Data Members
+
+ static const char* const typeName;
+
+
+ // Constructors
+
+ //- Null constructor for lists
+ inline Tuple3()
+ {}
+
+ //- Construct from components
+ inline Tuple3(const Type1& f, const Type2& s, const Type3& t)
+ :
+ f_(f),
+ s_(s),
+ t_(t)
+ {}
+
+ //- Construct from Istream
+ inline Tuple3(Istream& is)
+ {
+ is >> *this;
+ }
+
+
+ // Member Functions
+
+ //- Return first
+ inline const Type1& first() const
+ {
+ return f_;
+ }
+
+ //- Return first
+ inline Type1& first()
+ {
+ return f_;
+ }
+
+ //- Return second
+ inline const Type2& second() const
+ {
+ return s_;
+ }
+
+ //- Return second
+ inline Type2& second()
+ {
+ return s_;
+ }
+
+ //- Return third
+ inline const Type3& third() const
+ {
+ return t_;
+ }
+
+ //- Return third
+ inline Type3& third()
+ {
+ return t_;
+ }
+
+ // IOstream Operators
+
+ //- Read Tuple3 from Istream, discarding contents of existing Tuple3.
+ friend Istream& operator>>
+ (
+ Istream& is,
+ Tuple3& t3
+ );
+
+ // Write Tuple3 to Ostream.
+ friend Ostream& operator<<
+ (
+ Ostream& os,
+ const Tuple3& t3
+ );
+};
+
+
+template
+template
+inline unsigned
+Tuple3::Hash::operator()
+(
+ const Tuple3& t,
+ unsigned seed
+) const
+{
+ // Hash incrementally
+ unsigned val = seed;
+ val = HashT1()(t.first(), val);
+ val = HashT2()(t.second(), val);
+ val = HashT3()(t.third(), val);
+ return val;
+}
+
+
+//- Return reverse of a tuple3
+template
+inline Tuple3 reverse
+(
+ const Tuple3& t
+)
+{
+ return Tuple3(t.third(), t.second(), t.first());
+}
+
+
+template
+inline bool operator==
+(
+ const Tuple3& a,
+ const Tuple3& b
+)
+{
+ return
+ (
+ a.first() == b.first()
+ && a.second() == b.second()
+ && a.third() == b.third()
+ );
+}
+
+
+template
+inline bool operator!=
+(
+ const Tuple3& a,
+ const Tuple3& b
+)
+{
+ return !(a == b);
+}
+
+
+template
+inline Istream& operator>>(Istream& is, Tuple3& t3)
+{
+ is.readBegin("Tuple3");
+ is >> t3.f_ >> t3.s_ >> t3.t_;
+ is.readEnd("Tuple3");
+
+ // Check state of Istream
+ is.check("operator>>(Istream&, Tuple3&)");
+
+ return is;
+}
+
+
+template
+inline Ostream& operator<<(Ostream& os, const Tuple3& t2)
+{
+ os << token::BEGIN_LIST
+ << t2.f_ << token::SPACE << t2.s_ << token::SPACE << t2.t_
+ << token::END_LIST;
+
+ return os;
+}
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/applications/utilities/preProcessing/snappyHexMeshConfig/blockMeshCartesianConfiguration.C b/applications/utilities/preProcessing/snappyHexMeshConfig/blockMeshCartesianConfiguration.C
new file mode 100644
index 0000000000..cc72e277da
--- /dev/null
+++ b/applications/utilities/preProcessing/snappyHexMeshConfig/blockMeshCartesianConfiguration.C
@@ -0,0 +1,300 @@
+/*---------------------------------------------------------------------------*\
+ ========= |
+ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
+ \\ / O peration | Website: https://openfoam.org
+ \\ / A nd | Copyright (C) 2023 OpenFOAM Foundation
+ \\/ 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 .
+
+\*---------------------------------------------------------------------------*/
+
+#include "blockMeshCartesianConfiguration.H"
+#include "dictionary.H"
+#include "polyPatch.H"
+#include "wallPolyPatch.H"
+#include "blockMeshFunctions.H"
+
+// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
+
+const Foam::List Foam::blockMeshCartesianConfiguration::patches =
+ {"xMin", "xMax", "yMin", "yMax", "zMin", "zMax"};
+
+
+// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
+
+void Foam::blockMeshCartesianConfiguration::calcBlockMeshDict()
+{
+ Info<< "Surface bounding box is " << bb_ << endl;
+
+ // Round the bounding box
+ const scalar roundFactor = roundingScale(bb_.minDim());
+ roundBoundingBox(bb_, roundFactor);
+
+ // Set nCells with the lowest number of cells within the range 10-20
+ if (nCells_ == Vector