ENH: add dictionary-driven multi-pass stitchMesh facility

- the dictionary-driven variant of stitchMesh allows sequential
  application of 'stitch' operation with requiring intermediate
  writing to disk.

- Without arguments:
  * stitchMesh uses a system/stitchMeshDict or -dict dict

- With arguments:
  * master/slave patches specified on the command-line as in previous
    versions.
This commit is contained in:
Mark Olesen
2017-11-10 01:53:30 +01:00
parent d4b7fbe9a1
commit 3cafdccb4c
9 changed files with 569 additions and 233 deletions

View File

@ -66,34 +66,35 @@ Description
#include "fvCFD.H" #include "fvCFD.H"
#include "polyTopoChanger.H" #include "polyTopoChanger.H"
#include "mapPolyMesh.H" #include "mapPolyMesh.H"
#include "ListOps.H"
#include "slidingInterface.H" #include "slidingInterface.H"
#include "perfectInterface.H" #include "perfectInterface.H"
#include "IOobjectList.H" #include "IOobjectList.H"
#include "ReadFields.H" #include "ReadFields.H"
#include <numeric>
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// Checks whether patch present // Checks whether patch present and non-zero
void checkPatch(const polyBoundaryMesh& bMesh, const word& name) bool checkPatch(const polyBoundaryMesh& bMesh, const word& name)
{ {
const label patchi = bMesh.findPatchID(name); const label patchi = bMesh.findPatchID(name);
if (patchi == -1) if (patchi == -1)
{ {
FatalErrorInFunction Info<< "No patch " << name << " in mesh" << nl
<< "Cannot find patch " << name << endl << "Known patches: " << bMesh.names() << endl;
<< "It should be present and of non-zero size" << endl
<< "Valid patches are " << bMesh.names() return false;
<< exit(FatalError);
} }
if (bMesh[patchi].empty()) if (bMesh[patchi].empty())
{ {
FatalErrorInFunction Info<< "Patch " << name << " has zero size" << nl;
<< "Patch " << name << " is present but zero size"
<< exit(FatalError); return false;
} }
return true;
} }
@ -101,28 +102,38 @@ int main(int argc, char *argv[])
{ {
argList::addNote argList::addNote
( (
"Merge the faces on the specified patches (if geometrically possible)\n" "Merge the faces on specified patches (if geometrically possible)"
"so the faces become internal.\n" " so that the\n"
"Integral matching is used when the options -partial and -perfect are " "faces become internal.\n"
"omitted.\n" "This utility can be called without arguments (uses stitchMeshDict)"
" or with\n"
"two arguments (master/slave patch names)."
); );
argList::noParallel(); argList::noParallel();
#include "addOverwriteOption.H" #include "addOverwriteOption.H"
#include "addRegionOption.H" #include "addRegionOption.H"
#include "addDictOption.H"
argList::validArgs.append("masterPatch");
argList::validArgs.append("slavePatch");
argList::addBoolOption
(
"integral",
"couple integral master/slave patches (2 argument mode: default)"
);
argList::addBoolOption argList::addBoolOption
( (
"partial", "partial",
"couple partially overlapping patches (optional)" "couple partially overlapping master/slave patches (2 argument mode)"
); );
argList::addBoolOption argList::addBoolOption
( (
"perfect", "perfect",
"couple perfectly aligned patches (optional)" "couple perfectly aligned master/slave patches (2 argument mode)"
);
argList::addBoolOption
(
"intermediate",
"write intermediate stages, not just the final result"
); );
argList::addOption argList::addOption
( (
@ -131,69 +142,239 @@ int main(int argc, char *argv[])
"dictionary file with tolerances" "dictionary file with tolerances"
); );
#include "setRootCase.H" // The arguments are non-mandatory when using dictionary mode
argList::validArgs.append("masterPatch");
argList::validArgs.append("slavePatch");
#include "setRootCaseNonMandatoryArgs.H"
// We now handle checking args and general sanity etc.
const bool useCommandArgs = (args.size() > 1);
if (useCommandArgs)
{
if (args.optionFound("dict"))
{
FatalErrorInFunction
<< "Cannot specify both dictionary and command-line arguments"
<< nl
<< endl;
}
// If we have arguments - we require all arguments!
if (!args.check(true, false))
{
FatalError.exit();
}
}
else
{
// Carp about inapplicable options
if (args.optionFound("integral"))
{
FatalErrorInFunction
<< "Only specify -integral with command-line arguments"
<< endl;
}
if (args.optionFound("partial"))
{
FatalErrorInFunction
<< "Only specify -partial with command-line arguments"
<< endl;
}
if (args.optionFound("perfect"))
{
FatalErrorInFunction
<< "Only specify -perfect with command-line arguments"
<< endl;
}
}
#include "createTime.H" #include "createTime.H"
runTime.functionObjects().off(); runTime.functionObjects().off();
#include "createNamedMesh.H" #include "createNamedMesh.H"
const word oldInstance = mesh.pointsInstance(); const word oldInstance = mesh.pointsInstance();
const word masterPatchName = args[1]; const bool intermediate = args.optionFound("intermediate");
const word slavePatchName = args[2]; const bool overwrite = args.optionFound("overwrite");
const bool partialCover = args.optionFound("partial"); const word dictName("stitchMeshDict");
const bool perfectCover = args.optionFound("perfect");
const bool overwrite = args.optionFound("overwrite");
if (partialCover && perfectCover) // A validated input dictionary
dictionary validatedDict;
if (useCommandArgs)
{ {
FatalErrorInFunction // Command argument driven:
<< "Cannot supply both partial and perfect." << endl const int integralCover = args.optionFound("integral");
<< "Use perfect match option if the patches perfectly align" const int partialCover = args.optionFound("partial");
<< " (both vertex positions and face centres)" << endl const int perfectCover = args.optionFound("perfect");
<< exit(FatalError);
}
if ((integralCover + partialCover + perfectCover) > 1)
{
FatalErrorInFunction
<< "Can only specify one of -integral | -partial | -perfect."
<< nl
<< "Use perfect match option if the patches perfectly align"
<< " (both vertex positions and face centres)" << endl
<< exit(FatalError);
}
const word mergePatchName(masterPatchName + slavePatchName); // Patch names
const word cutZoneName(mergePatchName + "CutFaceZone"); const word masterPatchName(args[1]);
const word slavePatchName(args[2]);
slidingInterface::typeOfMatch tom = slidingInterface::INTEGRAL; // Patch names
Info<< " " << masterPatchName
<< " / " << slavePatchName << nl;
if (partialCover) // Bail out if either patch has problems
{ if
Info<< "Coupling partially overlapping patches " (
<< masterPatchName << " and " << slavePatchName << nl !checkPatch(mesh.boundaryMesh(), masterPatchName)
<< "Resulting internal faces will be in faceZone " << cutZoneName || !checkPatch(mesh.boundaryMesh(), slavePatchName)
<< nl )
<< "Any uncovered faces will remain in their patch" {
<< endl; FatalErrorInFunction
<< "Cannot continue"
<< exit(FatalError);
tom = slidingInterface::PARTIAL; return 1;
} }
else if (perfectCover)
{ // Input was validated
Info<< "Coupling perfectly aligned patches " dictionary dict;
<< masterPatchName << " and " << slavePatchName << nl
<< "Resulting (internal) faces will be in faceZone " << cutZoneName if (perfectCover)
<< nl << nl {
<< "Note: both patches need to align perfectly." << nl dict.add("match", word("perfect"));
<< "Both the vertex" }
<< " positions and the face centres need to align to within" << nl else if (partialCover)
<< "a tolerance given by the minimum edge length on the patch" {
<< endl; dict.add
(
"match",
slidingInterface::typeOfMatchNames[slidingInterface::PARTIAL]
);
}
else
{
dict.add
(
"match",
slidingInterface::typeOfMatchNames[slidingInterface::INTEGRAL]
);
}
// Patch names
dict.add("master", masterPatchName);
dict.add("slave", slavePatchName);
validatedDict.add("stitchMesh", dict);
} }
else else
{ {
Info<< "Coupling patches " << masterPatchName << " and " // dictionary-driven:
<< slavePatchName << nl
<< "Resulting (internal) faces will be in faceZone " << cutZoneName #include "setSystemRunTimeDictionaryIO.H"
<< nl << nl
<< "Note: the overall area covered by both patches should be" Info<< "Reading " << dictName;
<< " identical (\"integral\" interface)." << endl
<< "If this is not the case use the -partial option" << nl << endl; IOdictionary stitchDict(dictIO);
Info<< " with " << stitchDict.size() << " entries" << nl;
// Suppress duplicate names
wordHashSet requestedPatches;
forAllConstIters(stitchDict, iter)
{
if (!iter().isDict())
{
Info<< "Ignoring non-dictionary entry: "
<< iter().keyword() << nl;
continue;
}
const dictionary& dict = iter().dict();
// Match type
word matchName;
if (dict.readIfPresent("match", matchName))
{
if
(
matchName != "perfect"
&& !slidingInterface::typeOfMatchNames.hasEnum(matchName)
)
{
Info<< "Error: unknown match type - " << matchName
<< " should be one of "
<< slidingInterface::typeOfMatchNames.toc() << nl;
continue;
}
}
// Patch names
const word masterPatchName(dict["master"]);
const word slavePatchName(dict["slave"]);
// Patch names
Info<< " " << masterPatchName
<< " / " << slavePatchName << nl;
if (!requestedPatches.insert(masterPatchName))
{
Info<< "Error: patch specified multiple times - "
<< masterPatchName << nl;
continue;
}
if (!requestedPatches.insert(slavePatchName))
{
Info<< "Error: patch specified multiple times - "
<< slavePatchName << nl;
requestedPatches.erase(masterPatchName);
continue;
}
// Bail out if either patch has problems
if
(
!checkPatch(mesh.boundaryMesh(), masterPatchName)
|| !checkPatch(mesh.boundaryMesh(), slavePatchName)
)
{
requestedPatches.erase(masterPatchName);
requestedPatches.erase(slavePatchName);
continue;
}
// Input was validated
validatedDict.add(iter().keyword(), iter().dict());
}
} }
const label nActions = validatedDict.size();
Info<< nl << nActions << " validated actions" << endl;
if (!nActions)
{
Info<<"\nStopping" << nl << endl;
return 1;
}
// ------------------------------------------
// This is where the real work begins
// set up the tolerances for the sliding mesh // set up the tolerances for the sliding mesh
dictionary slidingTolerances; dictionary slidingTolerances;
if (args.optionFound("toleranceDict")) if (args.optionFound("toleranceDict"))
@ -212,120 +393,6 @@ int main(int argc, char *argv[])
slidingTolerances += toleranceFile; slidingTolerances += toleranceFile;
} }
// Check for non-empty master and slave patches
checkPatch(mesh.boundaryMesh(), masterPatchName);
checkPatch(mesh.boundaryMesh(), slavePatchName);
// Create and add face zones and mesh modifiers
// Master patch
const polyPatch& masterPatch = mesh.boundaryMesh()[masterPatchName];
// Make list of masterPatch faces
labelList isf(masterPatch.size());
forAll(isf, i)
{
isf[i] = masterPatch.start() + i;
}
polyTopoChanger stitcher(mesh, IOobject::NO_READ);
stitcher.clear();
stitcher.setSize(1);
mesh.pointZones().clearAddressing();
mesh.faceZones().clearAddressing();
mesh.cellZones().clearAddressing();
if (perfectCover)
{
// Starts as master zone, but receives the resulting internal faces
mesh.faceZones()
(
cutZoneName,
true // verbose
).resetAddressing(isf.xfer(), false);
// Add the perfect interface mesh modifier
stitcher.set
(
0,
new perfectInterface
(
"couple",
0,
stitcher,
cutZoneName,
masterPatchName,
slavePatchName
)
);
}
else
{
// An empty point zone
mesh.pointZones()
(
mergePatchName + "CutPointZone",
true // verbose
) = labelList();
// The master zone
mesh.faceZones()
(
mergePatchName + "MasterZone",
true // verbose
).resetAddressing(isf.xfer(), false);
// Slave patch
const polyPatch& slavePatch = mesh.boundaryMesh()[slavePatchName];
labelList osf(slavePatch.size());
forAll(osf, i)
{
osf[i] = slavePatch.start() + i;
}
mesh.faceZones()
(
mergePatchName + "SlaveZone",
true // verbose
).resetAddressing(osf.xfer(), false);
// An empty zone for cut faces
mesh.faceZones()
(
cutZoneName,
true // verbose
).resetAddressing(labelList(), false);
// Add the sliding interface mesh modifier
stitcher.set
(
0,
new slidingInterface
(
"couple",
0,
stitcher,
mergePatchName + "MasterZone",
mergePatchName + "SlaveZone",
mergePatchName + "CutPointZone",
cutZoneName,
masterPatchName,
slavePatchName,
tom, // integral or partial
true // couple/decouple mode
)
);
static_cast<slidingInterface&>(stitcher[0]).setTolerances
(
slidingTolerances,
true
);
}
// Search for list of objects for this time // Search for list of objects for this time
IOobjectList objects(mesh, runTime.timeName()); IOobjectList objects(mesh, runTime.timeName());
@ -358,51 +425,231 @@ int main(int argc, char *argv[])
//PtrList<surfaceTensorField> surfaceTensorFields; //PtrList<surfaceTensorField> surfaceTensorFields;
//ReadFields(mesh, objects, surfaceTensorFields); //ReadFields(mesh, objects, surfaceTensorFields);
if (!overwrite) // Increase precision for output mesh points
{
runTime++;
}
// Execute all polyMeshModifiers
autoPtr<mapPolyMesh> morphMap = stitcher.changeMesh(true);
mesh.movePoints(morphMap->preMotionPoints());
// Write mesh
if (overwrite)
{
mesh.setInstance(oldInstance);
stitcher.instance() = oldInstance;
}
Info<< nl << "Writing polyMesh to time " << runTime.timeName() << endl;
IOstream::defaultPrecision(max(10u, IOstream::defaultPrecision())); IOstream::defaultPrecision(max(10u, IOstream::defaultPrecision()));
// Bypass runTime write (since only writes at writeTime) polyTopoChanger stitcher(mesh, IOobject::NO_READ);
if
( // Step through the topology changes
!runTime.objectRegistry::writeObject label actioni = 0;
( forAllConstIters(validatedDict, iter)
runTime.writeFormat(),
IOstream::currentVersion,
runTime.writeCompression(),
true
)
)
{ {
FatalErrorInFunction const dictionary& dict = iter().dict();
<< "Failed writing polyMesh."
<< exit(FatalError); // Match type
bool perfect = false;
slidingInterface::typeOfMatch matchType = slidingInterface::PARTIAL;
word matchName;
if (dict.readIfPresent("match", matchName))
{
if (matchName == "perfect")
{
perfect = true;
}
else
{
matchType = slidingInterface::typeOfMatchNames[matchName];
}
}
// Patch names
const word masterPatchName(dict["master"]);
const word slavePatchName(dict["slave"]);
// Zone names
const word mergePatchName(masterPatchName + slavePatchName);
const word cutZoneName(mergePatchName + "CutFaceZone");
Info<< nl << "========================================" << nl;
// Information messages
if (perfect)
{
Info<< "Coupling PERFECTLY aligned patches "
<< masterPatchName << " / " << slavePatchName << nl << nl
<< "Resulting (internal) faces in faceZone "
<< cutZoneName << nl << nl
<< "The patch vertices and face centres must align within a"
<< " tolerance relative to the minimum edge length on the patch"
<< nl << endl;
}
else if (matchType == slidingInterface::INTEGRAL)
{
Info<< "Coupling INTEGRALLY matching of patches "
<< masterPatchName << " / " << slavePatchName << nl << nl
<< "Resulting (internal) faces in faceZone "
<< cutZoneName << nl << nl
<< "The overall area covered by both patches should be"
<< " identical!" << endl
<< "If this is not the case use partial"
<< nl << endl;
}
else
{
Info<< "Coupling PARTIALLY overlapping patches "
<< masterPatchName << " / " << slavePatchName << nl
<< "Resulting internal faces in faceZone "
<< cutZoneName << nl
<< "Uncovered faces remain in their patch"
<< nl << endl;
}
// Master/slave patches
const polyPatch& masterPatch = mesh.boundaryMesh()[masterPatchName];
const polyPatch& slavePatch = mesh.boundaryMesh()[slavePatchName];
mesh.pointZones().clearAddressing();
mesh.faceZones().clearAddressing();
mesh.cellZones().clearAddressing();
// Lists of master and slave faces:
labelList faceIds;
// Markup master face ids
faceIds.setSize(masterPatch.size());
std::iota(faceIds.begin(), faceIds.end(), masterPatch.start());
stitcher.clear();
stitcher.setSize(1);
if (perfect)
{
// Add new (empty) zone for resulting internal faces
mesh.faceZones()
(
cutZoneName,
true // verbose
).resetAddressing(faceIds.xfer(), false);
// Add the perfect interface mesh modifier
stitcher.set
(
0,
new perfectInterface
(
"couple" + Foam::name(actioni),
0,
stitcher,
cutZoneName,
masterPatchName,
slavePatchName
)
);
}
else
{
mesh.pointZones()
(
mergePatchName + "CutPointZone",
true // verbose
) = labelList();
mesh.faceZones()
(
mergePatchName + "MasterZone",
true // verbose
).resetAddressing(faceIds.xfer(), false);
// Markup slave face ids
faceIds.setSize(slavePatch.size());
std::iota(faceIds.begin(), faceIds.end(), slavePatch.start());
mesh.faceZones()
(
mergePatchName + "SlaveZone",
true // verbose
).resetAddressing(faceIds.xfer(), false);
// Add empty zone for cut faces
mesh.faceZones()
(
cutZoneName,
true // verbose
).resetAddressing(labelList(), false);
// Add the sliding interface mesh modifier
stitcher.set
(
0,
new slidingInterface
(
"couple" + Foam::name(actioni),
0,
stitcher,
mergePatchName + "MasterZone",
mergePatchName + "SlaveZone",
mergePatchName + "CutPointZone",
cutZoneName,
masterPatchName,
slavePatchName,
matchType, // integral or partial
true // couple/decouple mode
)
);
static_cast<slidingInterface&>(stitcher[0]).setTolerances
(
slidingTolerances,
true
);
}
++actioni;
// Advance time for intermediate results or only on final
if (!overwrite && (intermediate || actioni == nActions))
{
runTime++;
}
// Execute all polyMeshModifiers
autoPtr<mapPolyMesh> morphMap = stitcher.changeMesh(true);
mesh.movePoints(morphMap->preMotionPoints());
// Write mesh
if (overwrite)
{
mesh.setInstance(oldInstance);
stitcher.instance() = oldInstance;
}
if (intermediate || actioni == nActions)
{
Info<< nl << "Writing polyMesh to time "
<< runTime.timeName() << endl;
// Bypass runTime write (since only writes at writeTime)
if
(
!runTime.objectRegistry::writeObject
(
runTime.writeFormat(),
IOstream::currentVersion,
runTime.writeCompression(),
true
)
)
{
FatalErrorInFunction
<< "Failed writing polyMesh."
<< exit(FatalError);
}
mesh.faceZones().write();
mesh.pointZones().write();
mesh.cellZones().write();
// Write fields
runTime.write();
}
} }
mesh.faceZones().write(); Info<< "\nEnd\n" << endl;
mesh.pointZones().write();
mesh.cellZones().write();
// Write fields
runTime.write();
Info<< nl << "End" << nl << endl;
return 0; return 0;
} }

View File

@ -0,0 +1,38 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: plus |
| \\ / A nd | Web: www.OpenFOAM.com |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class dictionary;
object stitchMeshDict;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
outerx
{
match partial; // partial | integral | perfect
master outerx;
slave innerx;
}
outery
{
match partial;
master outery;
slave innery;
}
outerz
{
match partial;
master outerz;
slave innerz;
}
// ************************************************************************* //

View File

@ -79,7 +79,6 @@ Foam::pointField Foam::perfectInterface::calcFaceCentres
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
// Construct from components
Foam::perfectInterface::perfectInterface Foam::perfectInterface::perfectInterface
( (
const word& name, const word& name,
@ -97,7 +96,6 @@ Foam::perfectInterface::perfectInterface
{} {}
// Construct from dictionary
Foam::perfectInterface::perfectInterface Foam::perfectInterface::perfectInterface
( (
const word& name, const word& name,

View File

@ -45,6 +45,7 @@ namespace Foam
); );
} }
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::setUpdater::setUpdater Foam::setUpdater::setUpdater

View File

@ -52,7 +52,7 @@ const Foam::Enum
< <
Foam::slidingInterface::typeOfMatch Foam::slidingInterface::typeOfMatch
> >
Foam::slidingInterface::typeOfMatchNames_ Foam::slidingInterface::typeOfMatchNames
{ {
{ typeOfMatch::INTEGRAL, "integral" }, { typeOfMatch::INTEGRAL, "integral" },
{ typeOfMatch::PARTIAL, "partial" }, { typeOfMatch::PARTIAL, "partial" },
@ -112,8 +112,6 @@ void Foam::slidingInterface::clearOut() const
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
// Construct from components
Foam::slidingInterface::slidingInterface Foam::slidingInterface::slidingInterface
( (
const word& name, const word& name,
@ -204,7 +202,6 @@ Foam::slidingInterface::slidingInterface
} }
// Construct from components
Foam::slidingInterface::slidingInterface Foam::slidingInterface::slidingInterface
( (
const word& name, const word& name,
@ -244,7 +241,7 @@ Foam::slidingInterface::slidingInterface
dict.lookup("slavePatchName"), dict.lookup("slavePatchName"),
mme.mesh().boundaryMesh() mme.mesh().boundaryMesh()
), ),
matchType_(typeOfMatchNames_.lookup("typeOfMatch", dict)), matchType_(typeOfMatchNames.lookup("typeOfMatch", dict)),
coupleDecouple_(dict.lookup("coupleDecouple")), coupleDecouple_(dict.lookup("coupleDecouple")),
attached_(dict.lookup("attached")), attached_(dict.lookup("attached")),
projectionAlgo_ projectionAlgo_
@ -749,7 +746,7 @@ void Foam::slidingInterface::write(Ostream& os) const
<< cutFaceZoneID_.name() << nl << cutFaceZoneID_.name() << nl
<< masterPatchID_.name() << nl << masterPatchID_.name() << nl
<< slavePatchID_.name() << nl << slavePatchID_.name() << nl
<< typeOfMatchNames_[matchType_] << nl << typeOfMatchNames[matchType_] << nl
<< coupleDecouple_ << nl << coupleDecouple_ << nl
<< attached_ << endl; << attached_ << endl;
} }
@ -776,7 +773,7 @@ void Foam::slidingInterface::writeDict(Ostream& os) const
os.writeEntry("cutFaceZoneName", cutFaceZoneID_.name()); os.writeEntry("cutFaceZoneName", cutFaceZoneID_.name());
os.writeEntry("masterPatchName", masterPatchID_.name()); os.writeEntry("masterPatchName", masterPatchID_.name());
os.writeEntry("slavePatchName", slavePatchID_.name()); os.writeEntry("slavePatchName", slavePatchID_.name());
os.writeEntry("typeOfMatch", typeOfMatchNames_[matchType_]); os.writeEntry("typeOfMatch", typeOfMatchNames[matchType_]);
os.writeEntry("coupleDecouple", coupleDecouple_); os.writeEntry("coupleDecouple", coupleDecouple_);
os.writeEntry("projection", intersection::algorithmNames_[projectionAlgo_]); os.writeEntry("projection", intersection::algorithmNames_[projectionAlgo_]);
os.writeEntry("attached", attached_); os.writeEntry("attached", attached_);

View File

@ -84,8 +84,8 @@ public:
PARTIAL PARTIAL
}; };
//- Direction names //- Names for the types of matches
static const Enum<typeOfMatch> typeOfMatchNames_; static const Enum<typeOfMatch> typeOfMatchNames;
private: private:

View File

@ -4,9 +4,11 @@ cd ${0%/*} || exit 1 # Run from this directory
runApplication ./Allmesh runApplication ./Allmesh
for dir in x y z # Use stitchMesh with dictionary
do
runApplication -s dir-$dir stitchMesh -partial outer$dir inner$dir # runApplication stitchMesh -intermediate
done runApplication stitchMesh -overwrite
runApplication checkMesh
# ----------------------------------------------------------------------------- # -----------------------------------------------------------------------------

View File

@ -0,0 +1,15 @@
#!/bin/sh
cd ${0%/*} || exit 1 # Run from this directory
. $WM_PROJECT_DIR/bin/tools/RunFunctions # Tutorial run functions
runApplication ./Allmesh
# Use stitchMesh with command arguments (no dictionary)
for dir in x y z
do
runApplication -s dir-$dir stitchMesh -partial outer$dir inner$dir
done
runApplication checkMesh
# -----------------------------------------------------------------------------

View File

@ -0,0 +1,38 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: plus |
| \\ / A nd | Web: www.OpenFOAM.com |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class dictionary;
object stitchMeshDict;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
outerx
{
match partial; // partial | integral | perfect
master outerx;
slave innerx;
}
outery
{
match partial;
master outery;
slave innery;
}
outerz
{
match partial;
master outerz;
slave innerz;
}
// ************************************************************************* //