snappyHexMeshConfig: utility to preconfigure input files for snappyHexMesh,

including blockMeshDict, surfaceFeaturesDict and snappyHexMeshDict, based on the
case surface geometry.

Description
    Preconfigures blockMeshDict, surfaceFeaturesDict and snappyHexMeshDict
    files based on the case surface geometry files.

    Starting from a standard OpenFOAM case, this utility locates surface
    geometry files, e.g. OBJ, STL format, in the constant/geometry directory.
    It writes out the configuration files for mesh generation with
    snappyHexMesh based on assumptions which can be overridden by options on
    the command line.

    The utility processes the surface geometry files, attempting to anticipate
    their intended purpose, trying in particular to recognise whether the
    domain represents an external or internal flow. If there is a surface
    which is closed, and is either single or surrounds all other surfaces,
    then it is assumed that it forms the external boundary of an internal
    flow. This assumption is overridden if the bounds of the background mesh
    are specified using the '-bounds' option and they are more than 50% larger
    than the surface bounds.

    Surfaces which form boundaries of the domain may contain named regions
    that are intended to become patches in the final mesh. Any surface region
    whose name begins with 'inlet' or 'outlet' will become a patch of the same
    name in the final mesh. On an external surface (for an internal flow),
    regions can be identified as inlets and outlets using the '-inletRegions'
    and '-outletRegions' options, respectively. When either option specifies a
    single region, the resulting patch name will be specifically 'inlet' or
    'outlet', respectively. Surfaces which are contained within the domain,
    which do not surround or intersect other surfaces, are assumed by default
    to be wall patches. Any closed surface which surrounds another (but not an
    external surface) is used to form a cellZone within the mesh. Any surface
    can be specifically identified as a cellZone with the '-cellZones' option,
    with the additional '-baffles' and '-rotatingZones' options available to
    assign a surface to a more specific use.

    The background mesh for snappyHexMesh is a single block generated by
    blockMesh, configured using a blockMeshDict file. The block bounds are
    automatically calculated, but can be overridden by the '-bounds'
    option. The number of cells is calculated to produce a fairly small
    prototype mesh. The cell density can be overridden by the '-nCells' option
    or can be scaled up by an integer factor using the '-refineBackground'
    option. When the background mesh is required to form patches in the final
    mesh, e.g. for an external flow, the user can specify the names and types
    of the patches corresponding to the six block faces using options such as
    '-xMinPatch', '-xMaxPatch', etc. The name and type of the default patch,
    formed from block faces which are not configured, can also be specified
    with the '-defaultPatch' option. The utility provides placeholder entries
    for all block faces unless the '-clearBoundary' option is used. A special
    '-cylindricalBackground' option generates a cylindrical background mesh,
    oriented along the z-axis along x = y = 0.

    The snappyHexMesh configuration is generated automatically, applying a set
    of defaults to the main configuration parameters. By default, explicit
    feature capturing is configured, for which a surfaceFeaturesDict file is
    written for the user to generate the features files with the
    surfaceFeatures utility. Implicit feature capturing can alternatively be
    selected with the '-implicitFeatures' option. Refinement levels can be
    controlled with a range of options including: '-refinementLevel' for the
    baseline refinement level; '-refinementSurfaces' for levels on specific
    surfaces; '-refinementRegions' for levels inside specific surfaces;
    '-refinementBoxes' for quick, box-shaped refinement regions specified by
    min and max bounds; '-refinementDists' for distance-based refinement; and
    '-nCellsBetweenLevels' to control the transition between refinement
    levels. A '-layers' option specifies additional layers of cells at wall
    boundaries. The insidePoint parameter is set to '(0 0 0)' by default but
    can be overridden using the '-insidePoint' option.
This commit is contained in:
Chris Greenshields
2023-07-07 12:32:14 +01:00
parent e7f75df23f
commit c2552978a3
21 changed files with 4498 additions and 0 deletions

View File

@ -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

View File

@ -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

View File

@ -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 <http://www.gnu.org/licenses/>.
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 Type1, class Type2, class Type3>
class Tuple3;
template<class Type1, class Type2, class Type3>
inline Istream& operator>>(Istream&, Tuple3<Type1, Type2, Type3>&);
template<class Type1, class Type2, class Type3>
inline Ostream& operator<<(Ostream&, const Tuple3<Type1, Type2, Type3>&);
/*---------------------------------------------------------------------------*\
Class Tuple3 Declaration
\*---------------------------------------------------------------------------*/
template<class Type1, class Type2, class Type3>
class Tuple3
{
// Private Data
Type1 f_;
Type2 s_;
Type3 t_;
public:
//- Hashing function class
template
<
class HashT1=Hash<Type1>,
class HashT2=Hash<Type2>,
class HashT3=Hash<Type3>
>
class Hash
{
public:
Hash()
{}
inline unsigned operator()
(
const Tuple3<Type1, Type2, Type3>&,
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>> <Type1, Type2, Type3>
(
Istream& is,
Tuple3<Type1, Type2, Type3>& t3
);
// Write Tuple3 to Ostream.
friend Ostream& operator<< <Type1, Type2, Type3>
(
Ostream& os,
const Tuple3<Type1, Type2, Type3>& t3
);
};
template<class Type1, class Type2, class Type3>
template<class HashT1, class HashT2, class HashT3>
inline unsigned
Tuple3<Type1, Type2, Type3>::Hash<HashT1, HashT2, HashT3>::operator()
(
const Tuple3<Type1, Type2, Type3>& 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<class Type1, class Type2, class Type3>
inline Tuple3<Type3, Type2, Type1> reverse
(
const Tuple3<Type1, Type2, Type3>& t
)
{
return Tuple3<Type3, Type2, Type1>(t.third(), t.second(), t.first());
}
template<class Type1, class Type2, class Type3>
inline bool operator==
(
const Tuple3<Type1, Type2, Type3>& a,
const Tuple3<Type1, Type2, Type3>& b
)
{
return
(
a.first() == b.first()
&& a.second() == b.second()
&& a.third() == b.third()
);
}
template<class Type1, class Type2, class Type3>
inline bool operator!=
(
const Tuple3<Type1, Type2, Type3>& a,
const Tuple3<Type1, Type2, Type3>& b
)
{
return !(a == b);
}
template<class Type1, class Type2, class Type3>
inline Istream& operator>>(Istream& is, Tuple3<Type1, Type2, Type3>& t3)
{
is.readBegin("Tuple3");
is >> t3.f_ >> t3.s_ >> t3.t_;
is.readEnd("Tuple3");
// Check state of Istream
is.check("operator>>(Istream&, Tuple3<Type1, Type2, Type3>&)");
return is;
}
template<class Type1, class Type2, class Type3>
inline Ostream& operator<<(Ostream& os, const Tuple3<Type1, Type2, Type3>& t2)
{
os << token::BEGIN_LIST
<< t2.f_ << token::SPACE << t2.s_ << token::SPACE << t2.t_
<< token::END_LIST;
return os;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -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 <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "blockMeshCartesianConfiguration.H"
#include "dictionary.H"
#include "polyPatch.H"
#include "wallPolyPatch.H"
#include "blockMeshFunctions.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
const Foam::List<Foam::word> 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<label>::zero)
{
nCells_ = Vector<label>(bb_.span()/roundFactor);
if (!isEven(nCells_) && cmptMin(nCells_) > 20)
{
roundBoundingBox(bb_, 2*roundFactor);
nCells_ = Vector<label>(bb_.span()/roundFactor);
}
if (cmptMin(nCells_) < 10)
{
nCells_ *= 2;
}
else if (cmptMin(nCells_) > 20)
{
nCells_ /= 2;
}
}
Info<< "Bounding box is now " << bb_ << endl;
// Scale nCells_ by refine factor
nCells_ *= refineFactor_;
Info<< "Using background mesh nCells " << nCells_ << endl;
}
void Foam::blockMeshCartesianConfiguration::writeBackgroundMesh()
{
dictionary dict("backgroundMesh");
dict.add("xMin", bb_.min().x(), true);
dict.add("xMax", bb_.max().x(), true);
dict.add("yMin", bb_.min().y(), true);
dict.add("yMax", bb_.max().y(), true);
dict.add("zMin", bb_.min().z(), true);
dict.add("zMax", bb_.max().z(), true);
dict.add("xCells", nCells_.x(), true);
dict.add("yCells", nCells_.y(), true);
dict.add("zCells", nCells_.z(), true);
os_ << dict.name().c_str()
<< dict << nl
<< "convertToMeters 1;" << nl
<< endl;
}
void Foam::blockMeshCartesianConfiguration::writeDefaultPatch()
{
Pair<word> defaultPatch;
word opt = "defaultPatch";
if (patchOpts_.found(opt))
{
defaultPatch = readPatchOption(opt);
}
else
{
defaultPatch = {"background", "internal"};
}
beginDict(os_, "defaultPatch");
os_ << indent << "name " << defaultPatch.first() << ";" << nl
<< indent << "type " << defaultPatch.second() << ";" << endl;
endDict(os_);
Info<< "\nAdding defaultPatch '" << defaultPatch.first()
<< "' of type '" << defaultPatch.second() << "'" << endl;
}
void Foam::blockMeshCartesianConfiguration::writePatch
(
const word& name,
const word& type,
const string& face
)
{
os_ << indent << name
<< " { type " << type
<< "; faces ( " << face.c_str()
<< " ); }" << endl;
Info<< "Adding patch '" << name
<< "' of type '" << type << "'" << endl;
}
void Foam::blockMeshCartesianConfiguration::writeBoundary()
{
// Enable boundary section if a patch option or clearBoundary is selected
bool enableBoundary = clearBoundary_;
forAll(patches, i)
{
if (enableBoundary)
{
break;
}
enableBoundary = patchOpts_.found(patches[i] + "Patch");
}
if (!enableBoundary)
{
os_ << "// delete \"-disabled\" to enable boundary settings" << endl;
Info<< "\nNote: The boundary list in blockMeshDict is disabled" << nl
<< "To enable, open the file and edit line number "
<< os_.lineNumber() << nl << endl;
}
beginList
(
os_,
enableBoundary ? "boundary" : "boundary-disabled"
);
const List<word> faces
{
"(0 3 7 4)",
"(1 5 6 2)",
"(0 4 5 1)",
"(3 2 6 7)",
"(0 1 2 3)",
"(4 7 6 5)"
};
forAll(patches, i)
{
const bool optFound(patchOpts_.found(patches[i] + "Patch"));
// Do not write patch entry if clearBoundary option is selected
// and the respective patch option is not selected
if (clearBoundary_ && !optFound)
{
continue;
}
Pair<word> patch(patches[i], "patch");
if (optFound)
{
patch = readPatchOption(patch.first() + "Patch");
}
writePatch(patch.first(), patch.second(), faces[i]);
}
endList(os_);
}
void Foam::blockMeshCartesianConfiguration::writeVertices()
{
beginList(os_, "vertices");
writeVertex("xMin", "yMin", "zMin");
writeVertex("xMax", "yMin", "zMin");
writeVertex("xMax", "yMax", "zMin");
writeVertex("xMin", "yMax", "zMin");
writeVertex("xMin", "yMin", "zMax");
writeVertex("xMax", "yMin", "zMax");
writeVertex("xMax", "yMax", "zMax");
writeVertex("xMin", "yMax", "zMax");
endList(os_);
}
void Foam::blockMeshCartesianConfiguration::writeBlocks()
{
beginList(os_, "blocks");
os_ << indent << "hex (0 1 2 3 4 5 6 7)" << nl
<< indent << "(" << incrIndent << nl
<< indent << "$!backgroundMesh/xCells" << nl
<< indent << "$!backgroundMesh/yCells" << nl
<< indent << "$!backgroundMesh/zCells" << decrIndent << nl
<< indent << ")" << nl
<< indent << "simpleGrading (1 1 1)" << endl;
endList(os_);
}
void Foam::blockMeshCartesianConfiguration::writeEdges()
{
beginList(os_, "edges");
endList(os_);
}
void Foam::blockMeshCartesianConfiguration::writeMergePatchPairs()
{
beginList(os_, "mergePatchPairs");
endList(os_, false);
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::blockMeshCartesianConfiguration::blockMeshCartesianConfiguration
(
const fileName& name,
const fileName& dir,
const Time& time,
const meshingSurfaceList& surfaces,
const Vector<label>& nCells,
const label refineFactor,
const HashTable<Pair<word>>& patchOpts,
const bool clearBoundary
)
:
blockMeshConfigurationBase(name, dir, time, surfaces, patchOpts),
nCells_(nCells),
refineFactor_(refineFactor),
clearBoundary_(clearBoundary)
{
calcBlockMeshDict();
}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::blockMeshCartesianConfiguration::~blockMeshCartesianConfiguration()
{}
// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
void Foam::blockMeshCartesianConfiguration::write()
{
dict_.writeHeader(os_, word("dictionary"));
writeBackgroundMesh();
writeDefaultPatch();
writeBoundary();
writeVertices();
writeBlocks();
writeEdges();
writeMergePatchPairs();
dict_.writeEndDivider(os_);
}
// ************************************************************************* //

View File

@ -0,0 +1,157 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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 <http://www.gnu.org/licenses/>.
Class
Foam::blockMeshCartesianConfiguration
Description
From a set of input surface geometry files and a set of configuration
parameters, writes out a blockMeshDict configuration file. The mesh
consists of a single block, aligned with Cartesian axes.
SourceFiles
blockMeshCartesianConfiguration.C
\*---------------------------------------------------------------------------*/
#ifndef blockMeshCartesianConfiguration_H
#define blockMeshCartesianConfiguration_H
#include "blockMeshConfigurationBase.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class blockMeshCartesianConfiguration Declaration
\*---------------------------------------------------------------------------*/
class blockMeshCartesianConfiguration
:
public blockMeshConfigurationBase
{
// Private Data
//- Number of cells in background mesh block
Vector<label> nCells_;
//- Refinement factor used to scale nCells
const label refineFactor_;
//- Clear the default patch entries for the background mesh
const bool clearBoundary_;
// Private Member Functions
//- Calculate the parameters for the blockMeshDict file
void calcBlockMeshDict();
//- Write backgroundMesh sub-dictionary
void writeBackgroundMesh();
//- Write the defaultPatch entry
void writeDefaultPatch();
//- Write a patch in the boundary sub-dictionary
void writePatch
(
const word& name,
const word& type,
const string& face
);
//- Write the boundary sub-dictionary
void writeBoundary();
//- Write vertices list
void writeVertices();
//- Write blocks sub-dictionary
void writeBlocks();
//- Write edges list
void writeEdges();
//- Write mergePatchPairs
void writeMergePatchPairs();
public:
// Static Data Members
//- Default patch names for the background mesh
static const List<word> patches;
// Constructors
//- Construct from components
blockMeshCartesianConfiguration
(
const fileName& name,
const fileName& dir,
const Time& time,
const meshingSurfaceList& surfaces,
const Vector<label>& nCells,
const label refineFactor,
const HashTable<Pair<word>>& patchOpts,
const bool clearBoundary
);
//- Disallow default bitwise copy construction
blockMeshCartesianConfiguration
(
const blockMeshCartesianConfiguration&
) = delete;
//- Destructor
~blockMeshCartesianConfiguration();
// Member Functions
//- Write the blockMeshDict
void write();
// Member Operators
//- Disallow default bitwise assignment
void operator=(const blockMeshCartesianConfiguration&) = delete;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,114 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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 <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "blockMeshConfigurationBase.H"
#include "polyPatch.H"
#include "wallPolyPatch.H"
#include "blockMeshFunctions.H"
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
void Foam::blockMeshConfigurationBase::roundBoundingBox
(
boundBox& bb,
const scalar s
)
{
Info<< "Rounding bounding box to multiples of " << s << endl;
bb.min() = roundDown(bb.min(), s);
bb.max() = roundUp(bb.max(), s);
}
Foam::Pair<Foam::word> Foam::blockMeshConfigurationBase::readPatchOption
(
const word& option
) const
{
const Pair<word> patchOpt(patchOpts_.find(option)());
if
(
!(
polyPatch::constraintType(patchOpt.second())
|| patchOpt.second() == wallPolyPatch::typeName
|| patchOpt.second() == polyPatch::typeName
)
)
{
FatalErrorInFunction<< "Argument to '-"
<< option << " should be of the form "
<< "'(<name> <type>)'" << nl
<< "where <type> must be a generic \"patch\", \"wall\" "
<< "or a constraint condition:" << nl << nl
<< polyPatch::constraintTypes()
<< exit(FatalError);
}
return patchOpt;
}
void Foam::blockMeshConfigurationBase::writeVertex
(
const word& x,
const word& y,
const word& z
)
{
const word bgm("$!backgroundMesh/");
os_ << indent << "("
<< bgm << x << " "
<< bgm << y << " "
<< bgm << z << ")"
<< endl;
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::blockMeshConfigurationBase::blockMeshConfigurationBase
(
const fileName& name,
const fileName& dir,
const Time& time,
const meshingSurfaceList& surfaces,
const HashTable<Pair<word>>& patchOpts
)
:
caseFileConfiguration(name, dir, time),
bb_(surfaces.bb()),
patchOpts_(patchOpts)
{}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::blockMeshConfigurationBase::~blockMeshConfigurationBase()
{}
// ************************************************************************* //

View File

@ -0,0 +1,120 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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 <http://www.gnu.org/licenses/>.
Class
Foam::blockMeshConfigurationBase
Description
Functions to configure and write a blockMeshDict configuration file.
SourceFiles
blockMeshConfigurationBase.C
\*---------------------------------------------------------------------------*/
#ifndef blockMeshConfigurationBase_H
#define blockMeshConfigurationBase_H
#include "caseFileConfiguration.H"
#include "meshingSurfaceList.H"
#include "boundBox.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class blockMeshConfigurationBase Declaration
\*---------------------------------------------------------------------------*/
class blockMeshConfigurationBase
:
public caseFileConfiguration
{
protected:
// Protected Data
//- Bounding box for the background mesh block
boundBox bb_;
//- Optional settings for patch names and types in the background mesh
HashTable<Pair<word>> patchOpts_;
// Protected Member Functions
//- Round a bounding box by the rounding scale
void roundBoundingBox(boundBox& bb, const scalar s);
//- Parse the patch commandline options
Pair<word> readPatchOption(const word& option) const;
//- Write a vertex entry in the vertices list
void writeVertex
(
const word& x,
const word& y,
const word& z
);
public:
// Constructors
//- Construct from components
blockMeshConfigurationBase
(
const fileName& name,
const fileName& dir,
const Time& time,
const meshingSurfaceList& surfaces,
const HashTable<Pair<word>>& patchOpts
);
//- Disallow default bitwise copy construction
blockMeshConfigurationBase(const blockMeshConfigurationBase&) = delete;
//- Destructor
~blockMeshConfigurationBase();
// Member Operators
//- Disallow default bitwise assignment
void operator=(const blockMeshConfigurationBase&) = delete;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,446 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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 <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "blockMeshCylindricalConfiguration.H"
#include "dictionary.H"
#include "polyPatch.H"
#include "wallPolyPatch.H"
#include "unitConversion.H"
#include "blockMeshFunctions.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
const Foam::List<Foam::word> Foam::blockMeshCylindricalConfiguration::patches =
{"zMin", "zMax"};
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
void Foam::blockMeshCylindricalConfiguration::bbInflate
(
boundBox& bb,
const vector& s
)
{
bb.min() = cmptMultiply(s, bb.min());
bb.max() = cmptMultiply(s, bb.max());
}
void Foam::blockMeshCylindricalConfiguration::calcBlockMeshDict()
{
// Set nCells as a vector: (boxCells radialCells zCells)
label boxCells = nCells_.x();
label radialCells = nCells_.y();
if (nCells_ == Vector<label>::zero)
{
boxCells = 5;
radialCells = 15;
nCells_ = Vector<label>
(
boxCells,
radialCells,
2.0*radialCells*bb_.span().z()/bb_.span().x()
);
}
// Size the bounding box
const scalar roundFactor = roundingScale(0.01*bb_.minDim());
const scalar expansion = 1.0/(Foam::cos(degToRad(45.0/nCells_.x())));
const vector scaling(expansion, expansion, 1);
// Inflate the bounding box in radial direction
bbInflate(bb_, scaling);
bbInflate(rzbb_, scaling);
// Round the bounding box
roundBoundingBox(bb_, roundFactor);
roundBoundingBox(rzbb_, roundFactor);
radBox_ = ceil(0.3*rzbb_.max().x()/roundFactor)*roundFactor;
nCells_ *= refineFactor_;
}
void Foam::blockMeshCylindricalConfiguration::writeBackgroundMesh()
{
const scalar radOut = bb_.max().x();
const scalar radIn = rzbb_.max().x();
const scalar boxToRadOut = radOut - radBox_;
const scalar boxToRadIn = radIn - radBox_;
const label inCells = ceil(boxToRadIn*nCells_.y()/boxToRadOut);
const label outCells = nCells_.y() - inCells;
beginDict(os_, "backgroundMesh");
os_ << indent << "radOut " << radOut << ";" << endl;
os_ << indent << "radIn " << radIn << ";" << endl;
os_ << indent << "radBox " << radBox_ << ";" << nl << endl;
os_ << indent << "zMin " << bb_.min().z() << ";" << endl;
os_ << indent << "zMax " << bb_.max().z() << ";" << nl << endl;
os_ << indent << "boxCells " << nCells_.x() << ";" << endl;
os_ << indent << "inCells " << inCells << ";" << endl;
os_ << indent << "outCells " << outCells << ";" << endl;
os_ << indent << "zCells " << nCells_.z() << ";" << nl << endl;
os_ << indent << "outGrading 2.0;" << nl << endl;
os_ << indent << "radOutN #neg $radOut;" << endl;
os_ << indent << "radInN #neg $radIn;" << endl;
os_ << indent << "radBoxN #neg $radBox;" << endl;
endDict(os_);
os_ << "convertToMeters 1;" << nl << endl;
}
void Foam::blockMeshCylindricalConfiguration::writeDefaultPatch()
{
Pair<word> defaultPatch;
word opt = "defaultPatch";
if (patchOpts_.found(opt))
{
defaultPatch = readPatchOption(opt);
}
else
{
defaultPatch = {"sides", "patch"};
}
beginDict(os_, "defaultPatch");
os_ << indent << "name " << defaultPatch.first() << ";" << nl
<< indent << "type " << defaultPatch.second() << ";" << endl;
endDict(os_);
Info<< "\nAdding defaultPatch '" << defaultPatch.first()
<< "' of type '" << defaultPatch.second() << "'" << endl;
}
void Foam::blockMeshCylindricalConfiguration::writePatch
(
const word& name,
const word& type,
const string& face
)
{
os_ << indent << name
<< " { type " << type
<< "; faces ( " << face.c_str()
<< " ); }" << endl;
Info<< "Adding patch '" << name
<< "' of type '" << type << "'" << endl;
}
void Foam::blockMeshCylindricalConfiguration::writeBoundary()
{
// Enable boundary section if a patch option or clearBoundary is selected
bool enableBoundary = clearBoundary_;
forAll(patches, i)
{
if (enableBoundary)
{
break;
}
enableBoundary = patchOpts_.found(patches[i] + "Patch");
}
if (!enableBoundary)
{
os_ << "// delete \"-disabled\" to enable boundary settings" << endl;
Info<< "\nNote: The boundary list in blockMeshDict is disabled" << nl
<< "To enable, open the file and edit line number "
<< os_.lineNumber() << nl << endl;
}
beginList
(
os_,
enableBoundary ? "boundary" : "boundary-disabled"
);
forAll(patches, i)
{
const bool optFound(patchOpts_.found(patches[i] + "Patch"));
// Do not write patch entry if clearBoundary option is selected
// and the respective patch option is not selected
if (clearBoundary_ && !optFound)
{
continue;
}
Pair<word> patch(patches[i], "patch");
if (optFound)
{
patch = readPatchOption(patch.first() + "Patch");
}
beginDict(os_, patch.first());
os_ << indent << "type " << patch.second() << ";" << endl;
beginList(os_, "faces");
switch (i)
{
case 0:
{
os_ << indent << "(0 1 2 3)" << nl
<< indent << "(0 4 5 1)" << nl
<< indent << "(1 5 6 2)" << nl
<< indent << "(2 6 7 3)" << nl
<< indent << "(3 7 4 0)" << nl
<< indent << "(4 8 9 5)" << nl
<< indent << "(5 9 10 6)" << nl
<< indent << "(6 10 11 7)" << nl
<< indent << "(7 11 8 4)" << endl;
break;
}
case 1:
{
os_ << indent << "(12 13 14 15)" << nl
<< indent << "(12 16 17 13)" << nl
<< indent << "(13 17 18 14)" << nl
<< indent << "(14 18 19 15)" << nl
<< indent << "(15 19 16 12)" << nl
<< indent << "(16 20 21 17)" << nl
<< indent << "(17 21 22 18)" << nl
<< indent << "(18 22 23 19)" << nl
<< indent << "(19 23 20 16)" << endl;
break;
}
}
endList(os_, false);
endDict(os_, i != 1);
}
endList(os_);
}
void Foam::blockMeshCylindricalConfiguration::writeGeometry()
{
beginDict(os_, "geometry");
List<word> geometries {"rotatingZone", "outer"};
List<word> dims {"radIn", "radOut"};
const scalar zMin = roundDown(bb_.min().z(), 10);
const scalar zMax = roundUp(bb_.max().z(), 10);
forAll(geometries, i)
{
beginDict(os_, geometries[i]);
os_ << indent << "type searchableCylinder;" << nl
<< indent << "point1 (0 0 " << zMin << ");" << nl
<< indent << "point2 (0 0 " << zMax << ");" << nl
<< indent << "radius $!backgroundMesh/" << dims[i] << ";" << endl;
endDict(os_);
}
endDict(os_);
}
void Foam::blockMeshCylindricalConfiguration::writeProjectedVertex
(
const word& x,
const word& y,
const word& z,
const word& surface
)
{
os_ << indent << "project" << endl;
writeVertex(x, y, z);
os_ << indent << "(" << surface << ")" << nl << endl;
}
void Foam::blockMeshCylindricalConfiguration::writeVertices()
{
beginList(os_, "vertices");
forAll(patches, i)
{
const word& dir = patches[i];
writeVertex("radBoxN", "radBoxN", dir);
writeVertex("radBox", "radBoxN", dir);
writeVertex("radBox", "radBox", dir);
writeVertex("radBoxN", "radBox", dir);
os_ << endl;
writeProjectedVertex("radInN", "radInN", dir, "rotatingZone");
writeProjectedVertex("radIn", "radInN", dir, "rotatingZone");
writeProjectedVertex("radIn", "radIn", dir, "rotatingZone");
writeProjectedVertex("radInN", "radIn", dir, "rotatingZone");
writeProjectedVertex("radOutN", "radOutN", dir, "outer");
writeProjectedVertex("radOut", "radOutN", dir, "outer");
writeProjectedVertex("radOut", "radOut", dir, "outer");
writeProjectedVertex("radOutN", "radOut", dir, "outer");
}
endList(os_);
}
void Foam::blockMeshCylindricalConfiguration::writeBlocks()
{
os_ << "boxMesh" << endl;
writeVertex("boxCells", "boxCells", "zCells");
os_ << "simpleGrading (1 1 1);" << nl << endl;
os_ << "inMesh" << endl;
writeVertex("boxCells", "inCells", "zCells");
os_ << "simpleGrading (1 1 1);" << nl << endl;
os_ << "outMesh" << endl;
writeVertex("boxCells", "outCells", "zCells");
os_ << "simpleGrading (1 $!backgroundMesh/outGrading 1);" << nl << endl;
beginList(os_, "blocks");
os_ << indent << "hex (0 1 2 3 12 13 14 15) $boxMesh" << nl << nl
<< indent << "hex (1 0 4 5 13 12 16 17) $inMesh" << nl
<< indent << "hex (0 3 7 4 12 15 19 16) $inMesh" << nl
<< indent << "hex (2 1 5 6 14 13 17 18) $inMesh" << nl
<< indent << "hex (3 2 6 7 15 14 18 19) $inMesh" << nl << nl
<< indent << "hex (5 4 8 9 17 16 20 21) $outMesh" << nl
<< indent << "hex (4 7 11 8 16 19 23 20) $outMesh" << nl
<< indent << "hex (6 5 9 10 18 17 21 22) $outMesh" << nl
<< indent << "hex (7 6 10 11 19 18 22 23) $outMesh" << endl;
endList(os_);
}
void Foam::blockMeshCylindricalConfiguration::writeEdges()
{
beginList(os_, "edges");
os_ << indent << "project 4 5 (rotatingZone)" << nl
<< indent << "project 5 6 (rotatingZone)" << nl
<< indent << "project 6 7 (rotatingZone)" << nl
<< indent << "project 7 4 (rotatingZone)" << nl
<< indent << "project 16 17 (rotatingZone)" << nl
<< indent << "project 17 18 (rotatingZone)" << nl
<< indent << "project 18 19 (rotatingZone)" << nl
<< indent << "project 19 16 (rotatingZone)" << nl << nl
<< indent << "project 8 9 (outer)" << nl
<< indent << "project 9 10 (outer)" << nl
<< indent << "project 10 11 (outer)" << nl
<< indent << "project 11 8 (outer)" << nl
<< indent << "project 20 21 (outer)" << nl
<< indent << "project 21 22 (outer)" << nl
<< indent << "project 22 23 (outer)" << nl
<< indent << "project 23 20 (outer)" << endl;
endList(os_);
}
void Foam::blockMeshCylindricalConfiguration::writeMergePatchPairs()
{
os_ << "mergePatchPairs" << nl
<< "(" << nl
<< ");" << endl;
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::blockMeshCylindricalConfiguration::blockMeshCylindricalConfiguration
(
const fileName& name,
const fileName& dir,
const Time& time,
const meshingSurfaceList& surfaces,
const Vector<label>& nCells,
const label refineFactor,
const HashTable<Pair<word>>& patchOpts,
const bool clearBoundary
)
:
blockMeshConfigurationBase(name, dir, time, surfaces, patchOpts),
rzbb_(surfaces.rzbb()),
nCells_(nCells),
refineFactor_(refineFactor),
clearBoundary_(clearBoundary)
{
if (rzbb_.volume() == 0)
{
FatalErrorInFunction
<< "Attempting to create a cylindrical background mesh"
<< nl << "but the rotatingZone surface has zero volume."
<< exit(FatalError);
}
calcBlockMeshDict();
}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::blockMeshCylindricalConfiguration::~blockMeshCylindricalConfiguration()
{}
// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
void Foam::blockMeshCylindricalConfiguration::write()
{
dict_.writeHeader(os_, word("dictionary"));
writeBackgroundMesh();
writeDefaultPatch();
writeBoundary();
writeGeometry();
writeVertices();
writeBlocks();
writeEdges();
writeMergePatchPairs();
dict_.writeEndDivider(os_);
}
// ************************************************************************* //

View File

@ -0,0 +1,180 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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 <http://www.gnu.org/licenses/>.
Class
Foam::blockMeshCylindricalConfiguration
Description
From a set of input surface geometry files and a set of configuration
parameters, writes out a blockMeshDict configuration file. The mesh
consists of a single block, aligned with cylindrical coordinates about
the z-axis.
SourceFiles
blockMeshCylindricalConfiguration.C
\*---------------------------------------------------------------------------*/
#ifndef blockMeshCylindricalConfiguration_H
#define blockMeshCylindricalConfiguration_H
#include "blockMeshConfigurationBase.H"
#include "meshingSurfaceList.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class blockMeshCylindricalConfiguration Declaration
\*---------------------------------------------------------------------------*/
class blockMeshCylindricalConfiguration
:
public blockMeshConfigurationBase
{
// Private Data
//- Bounding box for the rotatingZone surfaces
boundBox rzbb_;
//- Half width of the core box
scalar radBox_;
//- Number of cells in background mesh = (boxCells radialCells zCells)
Vector<label> nCells_;
//- Refinement factor used to scale nCells
label refineFactor_;
//- Clear the default patch entries for the background mesh
bool clearBoundary_;
// Private Member Functions
//- Inflate a bounding box by a scaling vector
void bbInflate(boundBox& bb, const vector& s);
//- Calculate the parameters for the blockMeshDict file
void calcBlockMeshDict();
//- Write backgroundMesh sub-dictionary
void writeBackgroundMesh();
//- Write the defaultPatch entry
void writeDefaultPatch();
//- Write a patch in the boundary sub-dictionary
void writePatch
(
const word& name,
const word& type,
const string& face
);
//- Write the boundary sub-dictionary
void writeBoundary();
//- Write the geometry sub-dictionary
void writeGeometry();
//- Write a projected vertex entry in the vertices list
void writeProjectedVertex
(
const word& x,
const word& y,
const word& z,
const word& surface
);
//- Write vertices list
void writeVertices();
//- Write blocks sub-dictionary
void writeBlocks();
//- Write edges list
void writeEdges();
//- Write mergePatchPairs
void writeMergePatchPairs();
public:
// Static Data Members
//- Default patch names for the background mesh
static const List<word> patches;
// Constructors
//- Construct from components
blockMeshCylindricalConfiguration
(
const fileName& name,
const fileName& dir,
const Time& time,
const meshingSurfaceList& surfaces,
const Vector<label>& nCells,
const label refineFactor,
const HashTable<Pair<word>>& patchOpts,
const bool clearBoundary
);
//- Disallow default bitwise copy construction
blockMeshCylindricalConfiguration
(
const blockMeshCylindricalConfiguration&
) = delete;
//- Destructor
~blockMeshCylindricalConfiguration();
// Member Functions
// Write the blockMeshDict
void write();
// Member Operators
//- Disallow default bitwise assignment
void operator=(const blockMeshCylindricalConfiguration&) = delete;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,110 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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 <http://www.gnu.org/licenses/>.
InNamespace
Foam
Description
Functions for calculating the bounds and number of cells of a background
mesh configured within a blockMeshDict file
\*---------------------------------------------------------------------------*/
#ifndef blockMeshFunctions_H
#define blockMeshFunctions_H
#include "vector.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
inline bool isEven(const label l)
{
return (l % 2 == 0) ? true : false;
}
inline bool isEven(const Vector<label>& vl)
{
return isEven(vl.x()) && isEven(vl.y()) && isEven(vl.z());
}
inline int order(const scalar s)
{
return std::round(Foam::log10(mag(s)));
}
inline scalar roundingScale(const scalar s)
{
return (s == 0) ? 0 : Foam::pow(10.0, order(s) - 1);
}
inline scalar roundDown(const scalar x, const scalar s)
{
return floor(x/s)*s;
}
inline scalar roundUp(const scalar x, const scalar s)
{
return ceil(x/s)*s;
}
inline vector roundDown(const vector& v, const scalar s)
{
return vector
(
roundDown(v.x(), s),
roundDown(v.y(), s),
roundDown(v.z(), s)
);
}
inline vector roundUp(const vector& v, const scalar s)
{
return vector
(
roundUp(v.x(), s),
roundUp(v.y(), s),
roundUp(v.z(), s)
);
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,99 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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 <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "caseFileConfiguration.H"
#include "Time.H"
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
void Foam::caseFileConfiguration::beginDict(OFstream& os)
{
os << indent << "{" << incrIndent << endl;
}
void Foam::caseFileConfiguration::beginDict(OFstream& os,const word& name)
{
os << indent << name << endl;
beginDict(os);
}
void Foam::caseFileConfiguration::endDict(OFstream& os, bool newline)
{
os << decrIndent << indent << "}" << endl;
if (newline)
{
os << endl;
}
}
void Foam::caseFileConfiguration::beginList(OFstream& os)
{
os << indent << "(" << incrIndent << endl;
}
void Foam::caseFileConfiguration::beginList(OFstream& os, const word& name)
{
os << indent << name << endl;
beginList(os);
}
void Foam::caseFileConfiguration::endList(OFstream& os, bool newline)
{
os << decrIndent << indent << ");" << endl;
if (newline)
{
os << endl;
}
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::caseFileConfiguration::caseFileConfiguration
(
const fileName& name,
const fileName& dir,
const Time& time
)
:
dict_(IOobject(name, dir, time)),
os_(dict_.objectPath(true))
{}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::caseFileConfiguration::~caseFileConfiguration()
{}
// ************************************************************************* //

View File

@ -0,0 +1,120 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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 <http://www.gnu.org/licenses/>.
Class
Foam::caseFileConfiguration
Description
Base class for writing case files.
SourceFiles
caseFileConfiguration.C
\*---------------------------------------------------------------------------*/
#ifndef caseFileConfiguration_H
#define caseFileConfiguration_H
#include "IOobject.H"
#include "OFstream.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class caseFileConfiguration Declaration
\*---------------------------------------------------------------------------*/
class caseFileConfiguration
{
protected:
// Protected Data
//- IOobject to write file headers
IOobject dict_;
//- Output file stream to write file content
OFstream os_;
// Protected Functions
//- Output stream to begin a new dictionary without name
void beginDict(OFstream& os);
//- Output stream to begin a new dictionary with name
void beginDict(OFstream& os, const word& name);
//- Output stream to end a dictionary
void endDict(OFstream& os, bool newline=true);
//- Output stream to begin a new list without name
void beginList(OFstream& os);
//- Output stream to begin a new list with name
void beginList(OFstream& os, const word& name);
//- Output stream to end a list
void endList(OFstream& os, bool newline=true);
public:
// Constructors
//- Construct from components
caseFileConfiguration
(
const fileName& name,
const fileName& dir,
const Time& time
);
//- Disallow default bitwise copy construction
caseFileConfiguration(const caseFileConfiguration&) = delete;
//- Destructor
~caseFileConfiguration();
// Member Operators
//- Disallow default bitwise assignment
void operator=(const caseFileConfiguration&) = delete;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,140 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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 <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "meshingSurface.H"
#include "triSurface.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
template<>
const char* NamedEnum<meshingSurface::surfaceType, 5>::names[] =
{"wall", "external", "cellZone", "rotatingZone", "baffle"};
}
const Foam::NamedEnum<Foam::meshingSurface::surfaceType, 5>
Foam::meshingSurface::surfaceTypeNames;
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
Foam::label Foam::meshingSurface::nSurfaceParts(const triSurfaceMesh& surf)
{
labelList faceZone;
return surf.markZones(boolList(surf.nEdges(), false), faceZone);
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::meshingSurface::meshingSurface()
:
path_(),
file_(),
name_(),
type_(surfaceType::wall),
boundBox_(),
closed_(),
inletRegions_(),
outletRegions_()
{}
Foam::meshingSurface::meshingSurface(const fileName& file, const Time& time)
:
path_(file.path()),
file_(file.name()),
name_(word(file_.lessExt())),
type_(surfaceType::wall),
boundBox_(),
closed_(),
nParts_(),
regions_(),
inletRegions_(),
outletRegions_()
{
triSurfaceMesh surf
(
IOobject
(
file_,
path_,
time
),
triSurface(path_/file_)
);
boundBox_ = Foam::boundBox(surf.points(), false);
closed_ = surf.hasVolumeType();
nParts_ = nSurfaceParts(surf);
forAll(surf.patches(), i)
{
regions_.append(surf.patches()[i].name());
}
// Add any region with name beginning "inlet" to inletRegions_
forAll(regions_, r)
{
if (!strncmp(regions_[r].c_str(), "inlet", 5))
{
inletRegions_.append(regions_[r]);
}
}
// Add any region with name beginning "outlet" to outletRegions_
forAll(regions_, r)
{
if (!strncmp(regions_[r].c_str(), "outlet", 6))
{
outletRegions_.append(regions_[r]);
}
}
}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::meshingSurface::~meshingSurface()
{}
// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
bool Foam::meshingSurface::isSurfaceExt(const Foam::fileName& file)
{
const word ext(file.ext());
if (ext == "stl" || ext == "stlb" || ext == "obj" || ext == "vtk")
{
return true;
}
return false;
}
// ************************************************************************* //

View File

@ -0,0 +1,235 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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 <http://www.gnu.org/licenses/>.
Class
Foam::meshingSurface
Description
Attributes of a surface geometry file (e.g. OBJ, STL) that are used in
the configuration of mesh input files, (e.g. blockMeshDict,
snappyHexMeshDict).
SourceFiles
meshingSurface.C
\*---------------------------------------------------------------------------*/
#ifndef meshingSurface_H
#define meshingSurface_H
#include "Time.H"
#include "boundBox.H"
#include "NamedEnum.H"
#include "triSurfaceMesh.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class meshingSurface Declaration
\*---------------------------------------------------------------------------*/
class meshingSurface
{
public:
// Static Data Members
//- Type of surface
enum class surfaceType
{
wall, // Solid wall boundary
external, // External domain boundary
cellZone, // Surface defining a cellZone
rotatingZone, // Surface defining a rotatingZone
baffle // Zero-thickness wall
};
private:
// Private Data
//- Path to surface file
fileName path_;
//- Surface file name
fileName file_;
//- Surfaces names, without file extensions
word name_;
//- Type of surface: wall, external, cellZone, rotatingZone, baffle
surfaceType type_;
//- Bounding boxes of the surface
boundBox boundBox_;
//- Is the surface closed?
bool closed_;
//- Number of disconnected parts
label nParts_;
//- List of regions
List<word> regions_;
//- List of inlet regions
List<word> inletRegions_;
//- List of outlet regions
List<word> outletRegions_;
// Private Member Functions
//- Returns the number of disconnected regions in a surface
label nSurfaceParts(const triSurfaceMesh& surf);
public:
// Static Data Members
//- Enumeration names for surfaceTypes
static const NamedEnum<surfaceType, 5> surfaceTypeNames;
// Constructors
//- Construct null
meshingSurface();
//- Construct from components
meshingSurface(const fileName& file, const Time& time);
//- Disallow default bitwise copy construction
meshingSurface(const meshingSurface&) = delete;
//- Destructor
~meshingSurface();
// Member Functions
//- Path to the surface file
const fileName& path() const
{
return path_;
}
//- Surface file name
const fileName& file() const
{
return file_;
}
//- Surface name, without file extension
const word& name() const
{
return name_;
}
//- Surface type
const surfaceType& type() const
{
return type_;
}
//- Return non-const access to the surface type
surfaceType& type()
{
return type_;
}
//- Surface bounding box
const boundBox& bb() const
{
return boundBox_;
}
//- Is the surface closed?
bool closed() const
{
return closed_;
}
//- Return the number of disconnected surfaces
label nParts() const
{
return nParts_;
}
//- Surface geometry regions
const List<word>& regions() const
{
return regions_;
}
//- Inlet regions
const List<word>& inletRegions() const
{
return inletRegions_;
}
//- Inlet regions
List<word>& inletRegions()
{
return inletRegions_;
}
//- Outlet regions
const List<word>& outletRegions() const
{
return outletRegions_;
}
//- Outlet regions
List<word>& outletRegions()
{
return outletRegions_;
}
// Check the file extension of surface geometry files
static bool isSurfaceExt(const fileName& file);
// Member Operators
//- Disallow default bitwise assignment
void operator=(const meshingSurface&) = delete;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,426 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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 <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "meshingSurfaceList.H"
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
void Foam::meshingSurfaceList::mergeBoundingBoxes
(
boundBox& bb1,
const boundBox& bb2
)
{
if (bb1.volume() == 0)
{
bb1 = bb2;
return;
}
point& min1 = bb1.min();
point& max1 = bb1.max();
const point& min2 = bb2.min();
const point& max2 = bb2.max();
forAll(min1, i)
{
min1[i] = Foam::min(min1[i], min2[i]);
max1[i] = Foam::max(max1[i], max2[i]);
}
}
void Foam::meshingSurfaceList::swapExternalIndexZero(const label index)
{
if (index == 0)
{
return;
}
autoPtr<meshingSurface> s0Ptr(set(0, nullptr));
autoPtr<meshingSurface> sIndexPtr(set(index, nullptr));
set(index, s0Ptr.ptr());
set(0, sIndexPtr.ptr());
}
bool Foam::meshingSurfaceList::regionsValid
(
const wordList& specifiedRegions,
const wordList& regions,
const word& opt
)
{
if (specifiedRegions.empty())
{
return false;
}
forAll(specifiedRegions, s)
{
bool match(false);
forAll(regions, r)
{
match = (specifiedRegions[s] == regions[r]) || match;
if (match)
{
break;
}
}
if (!match)
{
FatalErrorInFunction
<< "Region '"<< specifiedRegions[s]
<< "' specified with the '" << opt
<< "' option" << nl
<< "does not match any regions in the external surface"
<< exit(FatalError);
}
}
return true;
}
void Foam::meshingSurfaceList::setSurfaceTypes
(
const List<word>& surfaces,
const surfaceType& type
)
{
forAll(surfaces, i)
{
const word surface = fileName(surfaces[i]).lessExt();
const word surfaceType = meshingSurface::surfaceTypeNames[type];
bool match = false;
// Check if the surface name matches a surface name
forAll(*this, surfi)
{
if (surface == operator[](surfi).name())
{
// For cellZone and rotatingZone, ensure surface is closed
if
(
!operator[](surfi).closed()
&& (
type == surfaceType::rotatingZone
|| type == surfaceType::cellZone
)
)
{
FatalErrorInFunction
<< "Argument to '-" << surfaceType
<< "' contains the " << surfaceType << " '"
<< surface << "'" << nl
<< "which is not a closed surface."
<< exit(FatalError);
}
operator[](surfi).type() = type;
match = true;
break;
}
}
if (!match)
{
FatalErrorInFunction
<< "Argument to '-" << surfaceType
<< "' contains the " << surfaceType << " '"
<< surface << "'" << nl
<< "which does not correspond to any surfaces."
<< exit(FatalError);
}
}
}
void Foam::meshingSurfaceList::setRotatingZoneBounds()
{
forAll(*this, surfi)
{
if (operator[](surfi).type() == surfaceType::rotatingZone)
{
mergeBoundingBoxes(rzbb_, operator[](surfi).bb());
}
}
}
void Foam::meshingSurfaceList::identifyCellZones()
{
forAll(*this, i)
{
if
(
operator[](i).type() == surfaceType::external
|| operator[](i).type() == surfaceType::rotatingZone
|| operator[](i).nParts() != 1
|| !operator[](i).closed()
)
{
continue;
}
forAll(*this, j)
{
if (i == j)
{
continue;
}
if (operator[](i).bb().contains(operator[](j).bb()))
{
operator[](i).type() = surfaceType::cellZone;
continue;
}
}
}
}
void Foam::meshingSurfaceList::reportWordList(const wordList& wl)
{
forAll(wl, i)
{
Info<< wl[i];
if (i != wl.size() - 1)
{
Info<< ", ";
}
}
Info<< endl;
}
void Foam::meshingSurfaceList::reportSurfaces()
{
Info<< "Case contains the following surface geometry files:"
<< endl;
forAll(*this, i)
{
Info<< "+ " << operator[](i).name() << nl
<< " + File: " << operator[](i).file() << nl
<< " + Bounding box: " << operator[](i).bb() << nl
<< " + " << (operator[](i).closed() ? "Closed" : "Open")
<< " surface" << endl;
switch (operator[](i).type())
{
case surfaceType::external:
{
Info << " + External boundary surface" << endl;
if (!operator[](i).inletRegions().empty())
{
Info<< " + Inlet regions: ";
reportWordList(operator[](i).inletRegions());
}
if (!operator[](i).outletRegions().empty())
{
Info << " + Outlet regions: ";
reportWordList(operator[](i).outletRegions());
}
break;
}
case surfaceType::wall:
{
Info << " + Wall boundary surface" << endl;
break;
}
case surfaceType::cellZone:
{
Info << " + Cell zone surface" << endl;
break;
}
case surfaceType::rotatingZone:
{
Info << " + Rotating zone surface" << endl;
break;
}
case surfaceType::baffle:
{
Info << " + Baffle wall surface" << endl;
break;
}
}
}
Info<< endl;
}
void Foam::meshingSurfaceList::setBounds(const boundBox& bb)
{
if (bb.contains(bb_))
{
Info<< "Specifed bounding box contains the overall bounding box"
<< endl;
}
else
{
WarningInFunction
<< "Specified bounding box does not contain the overall "
<< "bounding box"
<< endl;
}
if (bb.mag() > 1.5*bb_.mag())
{
Info<< "Specified bounding box is > (1.5 * overall "
<< "bounding box)" << nl
<< "**Assuming this is an external flow**"
<< endl;
operator[](0).type() = surfaceType::wall;
}
Info<< endl;
bb_ = bb;
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::meshingSurfaceList::meshingSurfaceList
(
const Time& time,
const fileNameList& surfaces,
const wordList& cellZones,
const wordList& rotatingZones,
const wordList& baffles,
const boundBox& bb,
const wordList& specifiedInletRegions,
const wordList& specifiedOutletRegions
)
:
PtrList<meshingSurface>(),
bb_(),
rzbb_()
{
// Load all the surfaces and construct the bounding box
forAll(surfaces, i)
{
append(new meshingSurface(surfaces[i], time));
mergeBoundingBoxes(bb_, last().bb());
}
label externalID = 0;
forAll(surfaces, i)
{
// Test for external surface inflates the bounding box by a small factor
// to account for imprecise surface geometry files
boundBox bbInflate = operator[](i).bb();
bbInflate.inflate(1e-4);
if
(
operator[](i).closed()
&& operator[](i).nParts() == 1
&& bbInflate.contains(bb_)
)
{
externalID = i;
operator[](i).type() = surfaceType::external;
// Override any inlet and outlet regions on external boundary
// specified by the '-inletRegions' and '-outletRegions' options
const wordList& regions = operator[](i).regions();
wordList& inletRegions = operator[](i).inletRegions();
if (regionsValid(specifiedInletRegions, regions, "-inletRegions"))
{
inletRegions = specifiedInletRegions;
}
wordList& outletRegions = operator[](i).outletRegions();
if (regionsValid(specifiedOutletRegions, regions, "-outletRegions"))
{
outletRegions = specifiedOutletRegions;
}
// If inletRegions and outletRegions are both empty, set "template"
// names
if (inletRegions.empty() && outletRegions.empty())
{
inletRegions.append("<inletRegion>");
outletRegions.append("<outletRegion>");
}
}
}
swapExternalIndexZero(externalID);
if (!rotatingZones.empty())
{
setSurfaceTypes(rotatingZones, surfaceType::rotatingZone);
}
if (!baffles.empty())
{
setSurfaceTypes(baffles, surfaceType::baffle);
}
setRotatingZoneBounds();
if (cellZones.empty())
{
identifyCellZones();
}
else
{
setSurfaceTypes(cellZones, surfaceType::cellZone);
}
reportSurfaces();
if (bb.volume() != 0)
{
setBounds(bb);
}
}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::meshingSurfaceList::~meshingSurfaceList()
{}
// ************************************************************************* //

View File

@ -0,0 +1,167 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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 <http://www.gnu.org/licenses/>.
Class
Foam::meshingSurfaceList
Description
List of meshingSurfaces which stores the overall bounding box of all the
meshingSurfaces.
SourceFiles
meshingSurfaceList.C
\*---------------------------------------------------------------------------*/
#ifndef meshingSurfaceList_H
#define meshingSurfaceList_H
#include "meshingSurface.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class meshingSurfaceList Declaration
\*---------------------------------------------------------------------------*/
class meshingSurfaceList
:
public PtrList<meshingSurface>
{
// Private Typedefs
//- The surface type
typedef meshingSurface::surfaceType surfaceType;
// Private Data
//- Bounding box for all the surfaces
boundBox bb_;
//- Bounding box for the rotatingZone surfaces
boundBox rzbb_;
// Private Member Functions
//- Merge the second bounding box into the first
void mergeBoundingBoxes
(
boundBox& bb1,
const boundBox& bb2
);
//- Swap surfaces list to make external surface index 0
void swapExternalIndexZero(const label index);
//- Return true if specified regions > 0 and match surface regions
bool regionsValid
(
const wordList& specifiedRegions,
const wordList& regions,
const word& opt
);
//- Set the specified surface types
void setSurfaceTypes
(
const List<word>& surfaces,
const surfaceType& type
);
//- Identify cell zones by analysing the surfaces
void identifyCellZones();
//- Write a word list as comma separated entries
void reportWordList(const wordList& wl);
//- Write a report on the surfaces to stdout
void reportSurfaces();
//- Set bounds specified in boundBox
void setBounds(const boundBox& bb);
//- Set bounds of rotatingZone surfaces
void setRotatingZoneBounds();
public:
// Constructors
//- Construct from components
meshingSurfaceList
(
const Time& time,
const fileNameList& surfaces,
const wordList& cellZones,
const wordList& rotatingZones,
const wordList& baffles,
const boundBox& bb,
const wordList& inletRegions,
const wordList& outletRegions
);
//- Disallow default bitwise copy construction
meshingSurfaceList(const meshingSurfaceList&) = delete;
//- Destructor
~meshingSurfaceList();
// Member Functions
// Bounding box
const boundBox& bb() const
{
return bb_;
}
// Bounding box of rotating zone surfaces
const boundBox& rzbb() const
{
return rzbb_;
}
// Member Operators
//- Disallow default bitwise assignment
void operator=(const meshingSurfaceList&) = delete;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,620 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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 <http://www.gnu.org/licenses/>.
Application
snappyHexMeshConfig
Description
Preconfigures blockMeshDict, surfaceFeaturesDict and snappyHexMeshDict
files based on the case surface geometry files.
Starting from a standard OpenFOAM case, this utility locates surface
geometry files, e.g. OBJ, STL format, in the constant/geometry directory.
It writes out the configuration files for mesh generation with
snappyHexMesh based on assumptions which can be overridden by options on
the command line.
The utility processes the surface geometry files, attempting to anticipate
their intended purpose, trying in particular to recognise whether the
domain represents an external or internal flow. If there is a surface
which is closed, and is either single or surrounds all other surfaces,
then it is assumed that it forms the external boundary of an internal
flow. This assumption is overridden if the bounds of the background mesh
are specified using the '-bounds' option and they are more than 50% larger
than the surface bounds.
Surfaces which form boundaries of the domain may contain named regions
that are intended to become patches in the final mesh. Any surface region
whose name begins with 'inlet' or 'outlet' will become a patch of the same
name in the final mesh. On an external surface (for an internal flow),
regions can be identified as inlets and outlets using the '-inletRegions'
and '-outletRegions' options, respectively. When either option specifies a
single region, the resulting patch name will be specifically 'inlet' or
'outlet', respectively. Surfaces which are contained within the domain,
which do not surround or intersect other surfaces, are assumed by default
to be wall patches. Any closed surface which surrounds another (but not an
external surface) is used to form a cellZone within the mesh. Any surface
can be specifically identified as a cellZone with the '-cellZones' option,
with the additional '-baffles' and '-rotatingZones' options available to
assign a surface to a more specific use.
The background mesh for snappyHexMesh is a single block generated by
blockMesh, configured using a blockMeshDict file. The block bounds are
automatically calculated, but can be overridden by the '-bounds'
option. The number of cells is calculated to produce a fairly small
prototype mesh. The cell density can be overridden by the '-nCells' option
or can be scaled up by an integer factor using the '-refineBackground'
option. When the background mesh is required to form patches in the final
mesh, e.g. for an external flow, the user can specify the names and types
of the patches corresponding to the six block faces using options such as
'-xMinPatch', '-xMaxPatch', etc. The name and type of the default patch,
formed from block faces which are not configured, can also be specified
with the '-defaultPatch' option. The utility provides placeholder entries
for all block faces unless the '-clearBoundary' option is used. A special
'-cylindricalBackground' option generates a cylindrical background mesh,
oriented along the z-axis along x = y = 0.
The snappyHexMesh configuration is generated automatically, applying a set
of defaults to the main configuration parameters. By default, explicit
feature capturing is configured, for which a surfaceFeaturesDict file is
written for the user to generate the features files with the
surfaceFeatures utility. Implicit feature capturing can alternatively be
selected with the '-implicitFeatures' option. Refinement levels can be
controlled with a range of options including: '-refinementLevel' for the
baseline refinement level; '-refinementSurfaces' for levels on specific
surfaces; '-refinementRegions' for levels inside specific surfaces;
'-refinementBoxes' for quick, box-shaped refinement regions specified by
min and max bounds; '-refinementDists' for distance-based refinement; and
'-nCellsBetweenLevels' to control the transition between refinement
levels. A '-layers' option specifies additional layers of cells at wall
boundaries. The insidePoint parameter is set to '(0 0 0)' by default but
can be overridden using the '-insidePoint' option.
Usage
\b snappyHexMeshConfig [OPTIONS]
Options:
- \par -surface \<file\>
Single surface geometry file for meshing
- \par -nCells \<cells\>
Number of cells in each direction, e.g. '(10 20 30)'
- \par -bounds \<box\>
Bounding box of the mesh, e.g. '((-10 -5 0) (10 5 10))'
- \par -cylindricalBackground
Generate a cylindrical background mesh aligned with the z-axis
- \par -refineBackground \<int\>
Integer multiplier for the number of cells (>= 1)
- \par -refinementLevel \<int\>
Refinement level used by snappyHexMesh, default 2
- \par -surfaceLevels \<entry\>
Refinement level at specified surfaces, e.g. '((pipe 2) (baffles 1))'
- \par -refinementRegions \<entry\>
Refinement regions specfied by '( (<surface> <level>) (...) )'
- \par -refinementBoxes \<entry\>
Refinement boxes specfied by '( (<min> <max> <level>) (...) )'
- \par -refinementDists \<entry\>
Refinement distance specified by '( (<surface> <dist> <level>) (...) )'
- \par -defaultPatch \<entry\>
Name and type of default patch, '(<name> <type>)'
- \par -xMinPatch (-xMaxPatch, -yMinPatch, etc...) \<entry\>
Name and type of the xMin (xMax, yMin, etc...) patch, '(<name> <type>)'
- \par -clearBoundary,
Do not set default patch entries, i.e. xMin, xMax, yMin, etc...
- \par -implicitFeatures,
Use implicit feature capturing
- \par -layers \<int\>
Specify <int> surface layers at wall boundaries, default 0
- \par -cellZones \<list\>
Surfaces that form cellZones, e.g. '(porousZone heatSource)'
- \par -rotatingZones \<list\>
Surfaces that form rotatingZones, e.g. '(rotatingZone)'
- \par -baffles \<list\>
Surfaces that form baffles, e.g. '(helical)'
- \par -insidePoint \<point\>
Point location inside the region of geometry to be meshed
- \par -nCellsBetweenLevels \<int\>
Number of cells at successive refinement levels, default 3
- \par -inletRegions \<list\>
Inlet regions on an external surface, e.g. '(inletA inletB)'
- \par -outletRegions \<list\>
Outlet regions on an external surface, e.g. '(outletA outletB)'
\*---------------------------------------------------------------------------*/
#include "argList.H"
#include "Time.H"
#include "meshingSurface.H"
#include "blockMeshCartesianConfiguration.H"
#include "blockMeshCylindricalConfiguration.H"
#include "snappyHexMeshConfiguration.H"
#include "surfaceFeaturesConfiguration.H"
#include "boundBox.H"
#include "searchableSurface.H"
#include "Tuple3.H"
using namespace Foam;
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
void readPatchOption
(
const argList& args,
HashTable<Pair<word>>& opts,
const word& name
)
{
if (args.optionFound(name))
{
opts.insert(name, args.optionRead<Pair<word>>(name));
}
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
int main(int argc, char *argv[])
{
argList::usageMin = 30;
argList::usageMax = 105;
argList::addNote
(
"Writes blockMeshDict, surfaceFeaturesDict and snappyHexMeshDict "
"files from surface geometry files.\n"
"For more information, see 'Description' in snappyHexMeshConfig.C "
"or run\n\n foamInfo snappyHexMeshConfig"
);
#include "removeCaseOptions.H"
argList::addOption
(
"surface",
"file",
"single surface geometry file for meshing"
);
argList::addOption
(
"nCells",
"cells",
"number of cells in each direction, e.g. '(10 20 30)'"
);
argList::addOption
(
"bounds",
"box",
"bounding box of the mesh, e.g. '((-10 -5 0) (10 5 10))'"
);
argList::addBoolOption
(
"cylindricalBackground",
"generate a cylindrical background mesh aligned with the z-axis"
);
argList::addOption
(
"refineBackground",
"int",
"integer multiplier for the number of cells (>= 1)"
);
argList::addOption
(
"refinementLevel",
"int",
"refinement level used by snappyHexMesh, default 2"
);
argList::addOption
(
"surfaceLevels",
"entry",
"refinement level at specified surfaces, e.g. '((pipe 2) (baffles 1))'"
);
argList::addOption
(
"refinementRegions",
"entry",
"refinement regions specfied by '( (<surface> <level>) (...) )'"
);
argList::addOption
(
"refinementBoxes",
"entry",
"refinement boxes specfied by '( (<min> <max> <level>) (...) )'"
);
argList::addOption
(
"refinementDists",
"entry",
"refinement distance specified by "
"'( (<surface> <dist> <level>) (...) )'"
);
argList::addOption
(
"defaultPatch",
"entry",
"name and type of default patch, '(<name> <type>)'"
);
List<word> patches(blockMeshCartesianConfiguration::patches);
forAll(patches, i)
{
argList::addOption
(
patches[i] + "Patch",
"entry",
"patch in the "
+ patches[i]
+ " direction, format '(<name> <type>)'"
);
}
argList::addBoolOption
(
"clearBoundary",
"do not set default patch entries, i.e. xMin, xMax, etc"
);
argList::addBoolOption
(
"implicitFeatures",
"use implicit feature capturing"
);
argList::addOption
(
"layers",
"int",
"specify <int> surface layers at wall boundaries, default 0"
);
argList::addOption
(
"cellZones",
"list",
"surfaces that form cellZones, e.g. '(porousZone heatSource)'"
);
argList::addOption
(
"rotatingZones",
"list",
"surfaces that form rotatingZones, e.g. '(rotatingZone)'"
);
argList::addOption
(
"baffles",
"list",
"surfaces that form baffles, e.g. '(helical)'"
);
argList::addOption
(
"insidePoint",
"point",
"point location inside the region of geometry to be meshed"
);
argList::addOption
(
"nCellsBetweenLevels",
"int",
"number of cells at successive refinement levels, default 3"
);
argList::addOption
(
"inletRegions",
"list",
"inlet regions on an external surface, e.g. '(inletA inletB)'"
);
argList::addOption
(
"outletRegions",
"list",
"outlet regions on an external surface, e.g. '(outletA outletB)'"
);
#include "setRootCase.H"
#include "createTime.H"
fileNameList surfaceNames;
if (args.optionFound("surface"))
{
surfaceNames.append(args.optionRead<fileName>("surface"));
}
else
{
const fileName surfDir
(
runTime.constant()/searchableSurface::geometryDir(runTime)
);
// Reads files, removing "gz" extensions
fileNameList files(readDir(surfDir));
// Check valid extensions and add the path to the names
forAll(files, i)
{
if (!meshingSurface::isSurfaceExt(files[i]))
{
continue;
}
surfaceNames.append(surfDir/files[i]);
}
// Need to exit if no surface geometry files found
if (surfaceNames.empty())
{
FatalErrorInFunction
<< "No surface geometry files found in "
<< surfDir << nl
<< "or provided using the '-surface' option"
<< exit(FatalError);
}
}
wordList cellZoneNames;
if (args.optionFound("cellZones"))
{
cellZoneNames.append(args.optionReadList<word>("cellZones"));
}
wordList rotatingZoneNames;
if (args.optionFound("rotatingZones"))
{
rotatingZoneNames.append(args.optionReadList<word>("rotatingZones"));
}
wordList baffleNames;
if (args.optionFound("baffles"))
{
baffleNames.append(args.optionReadList<word>("baffles"));
}
boundBox bb;
if (args.optionFound("bounds"))
{
List<vector> bounds(args.optionReadList<vector>("bounds"));
if (bounds.size() != 2)
{
FatalErrorInFunction
<< "Argument to '-bounds'"
<< " should be of the form '(<min> <max>)'" << nl
<< "with the <min> and <max> bounds of a bounding box"
<< "\n\nFound instead the argument: "
<< bounds
<< exit(FatalError);
}
bb = boundBox(bounds[0], bounds[1]);
Info<< "Bounding box specified by '-bounds' option: "
<< bb << endl;
}
wordList inletRegions;
if (args.optionFound("inletRegions"))
{
inletRegions.append(args.optionReadList<word>("inletRegions"));
}
wordList outletRegions;
if (args.optionFound("outletRegions"))
{
outletRegions.append(args.optionReadList<word>("outletRegions"));
}
meshingSurfaceList surfaces
(
runTime,
surfaceNames,
cellZoneNames,
rotatingZoneNames,
baffleNames,
bb,
inletRegions,
outletRegions
);
const Vector<label> nCells
(
args.optionLookupOrDefault("nCells", Vector<label>::zero)
);
const label refineFactor
(
args.optionLookupOrDefault("refineBackground", 1)
);
HashTable<Pair<word>> patchOpts(7);
patches.append("defaultPatch");
forAll(patches, i)
{
readPatchOption(args, patchOpts, patches[i] + "Patch");
}
const bool clearBoundary(args.optionFound("clearBoundary"));
if (args.optionFound("cylindricalBackground"))
{
blockMeshCylindricalConfiguration blockMeshConfig
(
"blockMeshDict",
runTime.system(),
runTime,
surfaces,
nCells,
refineFactor,
patchOpts,
clearBoundary
);
blockMeshConfig.write();
}
else
{
blockMeshCartesianConfiguration blockMeshConfig
(
"blockMeshDict",
runTime.system(),
runTime,
surfaces,
nCells,
refineFactor,
patchOpts,
clearBoundary
);
blockMeshConfig.write();
}
// snappyHexMeshDict options
const label refinementLevel
(
args.optionLookupOrDefault<label>("refinementLevel", 2)
);
List<Tuple2<word, label>> surfaceLevels;
if (args.optionFound("surfaceLevels"))
{
surfaceLevels.append
(
args.optionReadList<Tuple2<word, label>>("surfaceLevels")
);
}
List<Tuple2<word, label>> refinementRegions;
if (args.optionFound("refinementRegions"))
{
refinementRegions.append
(
args.optionReadList<Tuple2<word, label>>("refinementRegions")
);
}
List<Tuple3<vector, vector, label>> refinementBoxes;
if (args.optionFound("refinementBoxes"))
{
refinementBoxes.append
(
args.optionReadList<Tuple3<vector, vector, label>>
(
"refinementBoxes"
)
);
}
List<Tuple3<word, scalar, label>> refinementDists;
if (args.optionFound("refinementDists"))
{
refinementDists.append
(
args.optionReadList<Tuple3<word, scalar, label>>("refinementDists")
);
}
const bool implicitFeatures(args.optionFound("implicitFeatures"));
const label layers(args.optionLookupOrDefault<label>("layers", 0));
const point insidePoint
(
args.optionLookupOrDefault<point>("insidePoint", point::zero)
);
const label nCellsBetweenLevels
(
args.optionLookupOrDefault<label>("nCellsBetweenLevels", 3)
);
surfaceFeaturesConfiguration surfaceFeaturesConfig
(
"surfaceFeaturesDict",
runTime.system(),
runTime,
surfaces
);
surfaceFeaturesConfig.write();
snappyHexMeshConfiguration snappyConfig
(
"snappyHexMeshDict",
runTime.system(),
runTime,
surfaces,
refinementLevel,
surfaceLevels,
refinementRegions,
refinementBoxes,
refinementDists,
implicitFeatures,
layers,
insidePoint,
nCellsBetweenLevels
);
snappyConfig.write();
Info<< "\nEnd\n" << endl;
return 0;
}
// ************************************************************************* //

View File

@ -0,0 +1,548 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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 <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "snappyHexMeshConfiguration.H"
#include "Tuple3.H"
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
void Foam::snappyHexMeshConfiguration::writeSnappySwitches()
{
dictionary dict("switches");
dict.add("castellatedMesh", "on", true);
dict.add("snap", "on", true);
dict.add
(
"addLayers",
layers_ == 0 ? "off" : "on",
true
);
dict.write(os_, false);
os_ << endl;
}
void Foam::snappyHexMeshConfiguration::writeGeometrySurface(const label surfID)
{
beginDict(os_, surfaces_[surfID].name());
os_ << indent << "type triSurfaceMesh;" << nl
<< indent << "file " << surfaces_[surfID].file() << ";" << endl;
const wordList& inletRegions = surfaces_[surfID].inletRegions();
const wordList& outletRegions = surfaces_[surfID].outletRegions();
if (!inletRegions.empty() || !outletRegions.empty())
{
beginDict(os_, "regions");
forAll(inletRegions, i)
{
const word& region = inletRegions[i];
const word patch =
(
region == "<inletRegion>" || inletRegions.size() == 1
? "inlet"
: region
);
os_ << indent << region << " { name " << patch << "; }" << endl;
}
forAll(outletRegions, i)
{
const word& region = outletRegions[i];
const word patch =
(
region == "<outletRegion>" || outletRegions.size() == 1
? "outlet"
: region
);
os_ << indent << region << " { name " << patch << "; }" << endl;
}
endDict(os_, false);
}
endDict(os_, false);
}
void Foam::snappyHexMeshConfiguration::writeSearchableBox(const label i)
{
beginDict(os_, "box" + std::to_string(i));
os_ << indent << "type searchableBox;" << nl
<< indent << "min " << refinementBoxes_[i].first() << ";" << nl
<< indent << "max " << refinementBoxes_[i].second() << ";" << endl;
endDict(os_);
}
void Foam::snappyHexMeshConfiguration::writeSnappyGeometry()
{
beginDict(os_, "geometry");
forAll(surfaces_, i)
{
if (i != 0)
{
os_ << endl;
}
writeGeometrySurface(i);
}
forAll(refinementBoxes_, i)
{
os_ << endl;
writeSearchableBox(i);
}
endDict(os_);
}
void Foam::snappyHexMeshConfiguration::writeFeatures()
{
beginList(os_, "features");
if (!implicitFeatures_)
{
forAll(surfaces_, i)
{
fileName eMeshFile(surfaces_[i].name() + ".eMesh");
os_ << indent << "{ file " << eMeshFile
<< "; level 1; }" << endl;
}
}
endList(os_);
}
void Foam::snappyHexMeshConfiguration::writeRefinementSurfacesLevel
(
const label rl
)
{
os_ << indent << "level (" << rl << " " << rl << ");" << endl;
}
void Foam::snappyHexMeshConfiguration::writeRefinementSurfacesLevel()
{
writeRefinementSurfacesLevel(refinementLevel_);
}
void Foam::snappyHexMeshConfiguration::writeRefinementSurfacesLevel
(
const word& name
)
{
label rl(refinementLevel_);
forAll(surfaceLevels_, i)
{
if (surfaceLevels_[i].first() == name)
{
rl = surfaceLevels_[i].second();
break;
}
}
writeRefinementSurfacesLevel(rl);
}
void Foam::snappyHexMeshConfiguration::writePatchInfo
(
const word& type,
const word& group
)
{
if (group.empty())
{
os_ << indent << "patchInfo { type " << type << "; }" << endl;
}
else
{
beginDict(os_, "patchInfo");
os_ << indent << "type "<< type << ";" << endl;
os_ << indent << "inGroups (" << group << ");" << endl;
endDict(os_, false);
}
}
void Foam::snappyHexMeshConfiguration::writeRefinementSurfacesRegion
(
const word regionName,
const List<word>& regions
)
{
switch (regions.size())
{
case 0:
{
return;
}
case 1:
{
os_ << indent << regions[0] << endl;
break;
}
default:
{
os_ << indent << "\"" << regionName << ".*\"" << endl;
}
}
beginDict(os_);
writeRefinementSurfacesLevel();
word group(regionName);
if (regions.size() == 1 && regions[0] == regionName)
{
group = "";
}
writePatchInfo("patch", group);
endDict(os_, false);
}
void Foam::snappyHexMeshConfiguration::writeRefinementSurfacesRegions
(
const wordList& inletRegions,
const wordList& outletRegions
)
{
if (inletRegions.empty() && outletRegions.empty())
{
return;
}
os_ << endl;
beginDict(os_, "regions");
writeRefinementSurfacesRegion("inlet", inletRegions);
writeRefinementSurfacesRegion("outlet", outletRegions);
endDict(os_, false);
}
void Foam::snappyHexMeshConfiguration::writeRefinementSurfaces()
{
beginDict(os_, "refinementSurfaces");
forAll(surfaces_, i)
{
if (i != 0)
{
os_ << endl;
}
const word& name = surfaces_[i].name();
beginDict(os_, name);
writeRefinementSurfacesLevel(name);
const wordList& inletRegions = surfaces_[i].inletRegions();
const wordList& outletRegions = surfaces_[i].outletRegions();
switch (surfaces_[i].type())
{
case surfaceType::wall:
{
writePatchInfo("wall");
writeRefinementSurfacesRegions(inletRegions, outletRegions);
break;
}
case surfaceType::external:
{
writePatchInfo("wall", "externalWall");
writeRefinementSurfacesRegions(inletRegions, outletRegions);
break;
}
case surfaceType::cellZone:
case surfaceType::rotatingZone:
{
os_ << indent << "faceZone "
<< surfaces_[i].name() << ";" << nl
<< indent << "cellZone "
<< surfaces_[i].name() << ";" << nl
<< indent << "mode inside;" << endl;
break;
}
case surfaceType::baffle:
{
writePatchInfo("wall");
os_ << indent << "faceZone "
<< surfaces_[i].name() << ";" << nl
<< indent << "faceType boundary;" << endl;
break;
}
}
endDict(os_, false);
}
endDict(os_);
}
void Foam::snappyHexMeshConfiguration::writeRefinementRegion
(
const word& name,
const label level
)
{
beginDict(os_, name);
os_ << indent << "mode inside;" << nl
<< indent << "level " << level << ";" << endl;
endDict(os_, false);
}
void Foam::snappyHexMeshConfiguration::writeRefinementRegions()
{
if
(
refinementRegions_.empty()
&& refinementBoxes_.empty()
&& refinementDists_.empty()
)
{
os_ << indent
<< "// delete \"-disabled\" below to enable refinementRegions"
<< endl;
beginDict(os_, "refinementRegions-disabled");
writeRefinementRegion("<surface>", refinementLevel_);
endDict(os_);
}
else
{
beginDict(os_, "refinementRegions");
forAll(refinementRegions_, i)
{
writeRefinementRegion
(
refinementRegions_[i].first(),
refinementRegions_[i].second()
);
}
forAll(refinementBoxes_, i)
{
writeRefinementRegion
(
"box" + std::to_string(i),
refinementBoxes_[i].third()
);
}
forAll(refinementDists_, i)
{
beginDict(os_, refinementDists_[i].first());
os_ << indent << "mode distance;" << nl
<< indent << "levels (("
<< refinementDists_[i].second() << " "
<< refinementDists_[i].third() << "));" << endl;
endDict(os_, false);
}
endDict(os_);
}
}
void Foam::snappyHexMeshConfiguration::writeCastellatedMeshControls()
{
beginDict(os_, "castellatedMeshControls");
writeFeatures();
writeRefinementSurfaces();
writeRefinementRegions();
// Needs customising
os_ << indent << "insidePoint "
<< insidePoint_ << ";" << endl;
os_ << indent << "nCellsBetweenLevels "
<< nCellsBetweenLevels_
<< ";" << endl;
endDict(os_);
}
void Foam::snappyHexMeshConfiguration::writeSnapControls()
{
beginDict(os_, "snapControls");
os_ << indent << "explicitFeatureSnap "
<< (implicitFeatures_ ? "off" : "on") << ";" << endl;
os_ << indent << "implicitFeatureSnap "
<< (implicitFeatures_ ? "on" : "off") << ";" << endl;
endDict(os_);
}
void Foam::snappyHexMeshConfiguration::writeAddLayersControls()
{
if (layers_ == 0)
{
return;
}
beginDict(os_, "addLayersControls");
beginDict(os_, "layers");
forAll(surfaces_, i)
{
switch (surfaces_[i].type())
{
case surfaceType::wall:
case surfaceType::external:
case surfaceType::baffle:
{
os_ << indent << "\"" << surfaces_[i].name()
<< ".*\" { nSurfaceLayers "
<< layers_ << "; }" << endl;
break;
}
default: break;
}
}
endDict(os_);
os_ << indent << "relativeSizes on; "
<< "// off, usually with firstLayerThickness" << nl
<< indent << "expansionRatio 1.2;" << nl
<< indent << "finalLayerThickness 0.5;" << nl
<< indent << "minThickness 1e-3;" << nl
<< indent << "firstLayerThickness-disabled 0.01;" << nl << nl
<< indent << "maxThicknessToMedialRatio-disabled 0.3;" << endl;
endDict(os_);
}
void Foam::snappyHexMeshConfiguration::writeWriteFlags()
{
os_ << "// delete \"-disabled\" to output mesh data, e.g. for layers"
<< endl;
beginList(os_, "writeFlags-disabled");
os_ << indent << "scalarLevels" << endl;
os_ << indent << "layerSets" << endl;
os_ << indent << "layerFields" << endl;
endList(os_);
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::snappyHexMeshConfiguration::snappyHexMeshConfiguration
(
const fileName& name,
const fileName& dir,
const Time& time,
const meshingSurfaceList& surfaces,
const label refinementLevel,
const List<Tuple2<word, label>>& surfaceLevels,
const List<Tuple2<word, label>>& refinementRegions,
const List<Tuple3<vector, vector, label>>& refinementBoxes,
const List<Tuple3<word, scalar, label>>& refinementDists,
const bool implicitFeatures,
const label layers,
const point& insidePoint,
const label nCellsBetweenLevels
)
:
caseFileConfiguration(name, dir, time),
surfaces_(surfaces),
refinementLevel_(refinementLevel),
surfaceLevels_(surfaceLevels),
refinementRegions_(refinementRegions),
refinementBoxes_(refinementBoxes),
refinementDists_(refinementDists),
implicitFeatures_(implicitFeatures),
layers_(layers),
insidePoint_(insidePoint),
nCellsBetweenLevels_(nCellsBetweenLevels)
{}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::snappyHexMeshConfiguration::~snappyHexMeshConfiguration()
{}
// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
void Foam::snappyHexMeshConfiguration::write()
{
dict_.writeHeader(os_, word("dictionary"));
os_ << "#includeEtc \"caseDicts/mesh/generation/snappyHexMeshDict.cfg\""
<< nl << endl;
writeSnappySwitches();
writeSnappyGeometry();
writeCastellatedMeshControls();
writeSnapControls();
writeAddLayersControls();
writeWriteFlags();
os_ << "mergeTolerance 1e-6;";
dict_.writeEndDivider(os_);
}
// ************************************************************************* //

View File

@ -0,0 +1,211 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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 <http://www.gnu.org/licenses/>.
Class
Foam::snappyHexMeshConfiguration
Description
From a set of input surface geometry files and some configuration
parameters, writes out a snappyHexMeshDict configuration file.
SourceFiles
snappyHexMeshConfigurationI.H
snappyHexMeshConfiguration.C
\*---------------------------------------------------------------------------*/
#ifndef snappyHexMeshConfiguration_H
#define snappyHexMeshConfiguration_H
#include "caseFileConfiguration.H"
#include "meshingSurfaceList.H"
#include "Tuple3.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class snappyHexMeshConfiguration Declaration
\*---------------------------------------------------------------------------*/
class snappyHexMeshConfiguration
:
public caseFileConfiguration
{
// Private Typedefs
//- The surface type
typedef meshingSurface::surfaceType surfaceType;
// Private Data
//- List of surfaces used for meshing
const meshingSurfaceList& surfaces_;
//- Refinement level applied across the snappyHexMeshDict file
const label refinementLevel_;
//- Level of refinement on speficied surfaces
const List<Tuple2<word, label>>& surfaceLevels_;
//- Refinement regions specified by surface and level
const List<Tuple2<word, label>>& refinementRegions_;
//- Refinement boxes with level of refinement
const List<Tuple3<vector, vector, label>>& refinementBoxes_;
//- Refinement distances with level of refinement
const List<Tuple3<word, scalar, label>>& refinementDists_;
//- Using implicit feature capturing?
const bool implicitFeatures_;
//- Number of layers at wall patches, default 0
const label layers_;
//- insidePoint parameter
point insidePoint_;
//- nCellsBetweenLevels parameter
const label nCellsBetweenLevels_;
// Private Member Functions
//- Write switches
void writeSnappySwitches();
//- Write surface entry for geometry sub-dictionary
void writeGeometrySurface(const label surfID);
//- Write searchableBox entry for geometry sub-dictionary
void writeSearchableBox(const label i);
//- Write geometry sub-dictionary
void writeSnappyGeometry();
//- Write features list in castellatedMeshControls
void writeFeatures();
//- Write refinementSurfaces level entry
void writeRefinementSurfacesLevel(const label rl);
//- Write refinementSurfaces level entry using refinementLevel_
void writeRefinementSurfacesLevel();
//- Write refinementSurfaces level entry for a surface with name
void writeRefinementSurfacesLevel(const word& name);
//- Write refinementSurfaces wall patchInfo entry
void writePatchInfo(const word& type, const word& group="");
//- Write refinementSurfaces
void writeRefinementSurfaces();
//- Write a refinement surface region
void writeRefinementSurfacesRegion
(
const word regionName,
const List<word>& regions
);
//- Write refinement surface region information
void writeRefinementSurfacesRegions
(
const wordList& inletRegions,
const wordList& outletRegions
);
//- Write a refinement region
void writeRefinementRegion(const word& name, const label level);
//- Write refinementRegions
void writeRefinementRegions();
//- Write castellatedMeshControls
void writeCastellatedMeshControls();
//- Write snapControls
void writeSnapControls();
//- Write addLayersControls
void writeAddLayersControls();
//- Write writeFlags
void writeWriteFlags();
public:
// Constructors
//- Construct from components
snappyHexMeshConfiguration
(
const fileName& name,
const fileName& dir,
const Time& time,
const meshingSurfaceList& surfaces,
const label refinementLevel,
const List<Tuple2<word, label>>& surfaceLevels,
const List<Tuple2<word, label>>& refinementRegions,
const List<Tuple3<vector, vector, label>>& refinementBoxes,
const List<Tuple3<word, scalar, label>>& refinementDists,
const bool implicitFeatures,
const label layers,
const point& insidePoint,
const label nCellsBetweenLevels
);
//- Disallow default bitwise copy construction
snappyHexMeshConfiguration(const snappyHexMeshConfiguration&) = delete;
//- Destructor
~snappyHexMeshConfiguration();
// Member Functions
// Write the snappyHexMeshDict
void write();
// Member Operators
//- Disallow default bitwise assignment
void operator=(const snappyHexMeshConfiguration&) = delete;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,101 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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 <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "surfaceFeaturesConfiguration.H"
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
void Foam::surfaceFeaturesConfiguration::writeSurfaces()
{
beginList(os_, "surfaces");
forAll(surfaces_, i)
{
os_ << indent << surfaces_[i].file() << endl;
}
endList(os_);
}
void Foam::surfaceFeaturesConfiguration::writeSubsetFeatures()
{
beginDict(os_, "subsetFeatures");
os_ << indent << "nonManifoldEdges yes;" << endl;
os_ << indent << "openEdges yes;" << endl;
endDict(os_);
}
void Foam::surfaceFeaturesConfiguration::writeTrimFeatures()
{
beginDict(os_, "trimFeatures");
os_ << indent << "minElem 0;" << endl;
os_ << indent << "minLen 0;" << endl;
endDict(os_);
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::surfaceFeaturesConfiguration::surfaceFeaturesConfiguration
(
const fileName& name,
const fileName& dir,
const Time& time,
const meshingSurfaceList& surfaces
)
:
caseFileConfiguration(name, dir, time),
surfaces_(surfaces)
{}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::surfaceFeaturesConfiguration::~surfaceFeaturesConfiguration()
{}
// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
void Foam::surfaceFeaturesConfiguration::write()
{
dict_.writeHeader(os_, word("dictionary"));
writeSurfaces();
os_ << "includedAngle 150;" << nl << endl;
writeSubsetFeatures();
writeTrimFeatures();
os_ << "writeObj yes;";
dict_.writeEndDivider(os_);
}
// ************************************************************************* //

View File

@ -0,0 +1,117 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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 <http://www.gnu.org/licenses/>.
Class
Foam::surfaceFeaturesConfiguration
Description
From a set of input surface geometry files and some configuration
parameters, writes out a surfacesFeaturesDict configuration file.
SourceFiles
surfaceFeaturesConfiguration.C
\*---------------------------------------------------------------------------*/
#ifndef surfaceFeaturesConfiguration_H
#define surfaceFeaturesConfiguration_H
#include "caseFileConfiguration.H"
#include "meshingSurfaceList.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class surfaceFeaturesConfiguration Declaration
\*---------------------------------------------------------------------------*/
class surfaceFeaturesConfiguration
:
public caseFileConfiguration
{
// Private Data
//- List of surfaces used for generating features
const meshingSurfaceList& surfaces_;
// Private Member Functions
//- Write surfaces
void writeSurfaces();
//- Write subsetFeatures sub-dictionary
void writeSubsetFeatures();
//- Write trimFeatures sub-dictionary
void writeTrimFeatures();
public:
// Constructors
//- Construct from components
surfaceFeaturesConfiguration
(
const fileName& name,
const fileName& dir,
const Time& time,
const meshingSurfaceList& surfaces
);
//- Disallow default bitwise copy construction
surfaceFeaturesConfiguration
(
const surfaceFeaturesConfiguration&
) = delete;
//- Destructor
~surfaceFeaturesConfiguration();
// Member Functions
// Writing surfaceFeaturesDict
void write();
// Member Operators
//- Disallow default bitwise assignment
void operator=(const surfaceFeaturesConfiguration&) = delete;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //