ENH: createBaffles: create patches and patchFields

This commit is contained in:
mattijs
2012-12-04 12:02:45 +00:00
parent 4f362ec8e6
commit 2745cd7544
10 changed files with 1445 additions and 275 deletions

View File

@ -1,3 +1,7 @@
faceSelection/faceSelection.C
faceSelection/faceZoneSelection.C
faceSelection/searchableSurfaceSelection.C
createBaffles.C createBaffles.C
EXE = $(FOAM_APPBIN)/createBaffles EXE = $(FOAM_APPBIN)/createBaffles

View File

@ -1,4 +1,5 @@
EXE_INC = \ EXE_INC = \
-IfaceSelection \
-I$(LIB_SRC)/finiteVolume/lnInclude \ -I$(LIB_SRC)/finiteVolume/lnInclude \
-I$(LIB_SRC)/dynamicMesh/lnInclude \ -I$(LIB_SRC)/dynamicMesh/lnInclude \
-I$(LIB_SRC)/meshTools/lnInclude -I$(LIB_SRC)/meshTools/lnInclude

View File

@ -26,25 +26,26 @@ Description
mergeOrSplitBaffles. mergeOrSplitBaffles.
Note: if any coupled patch face is selected for baffling the opposite Note: if any coupled patch face is selected for baffling the opposite
member has to be selected for baffling as well. Note that this member has to be selected for baffling as well.
is the same as repatching. This was added only for convenience so
you don't have to filter coupled boundary out of your set. - if the patch already exists will not override it nor its fields
- if the patch does not exist it will be created together with 'calculated'
patchfields unless the field is mentioned in the patchFields section.
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#include "syncTools.H"
#include "argList.H" #include "argList.H"
#include "Time.H" #include "Time.H"
#include "faceSet.H"
#include "polyTopoChange.H" #include "polyTopoChange.H"
#include "polyModifyFace.H" #include "polyModifyFace.H"
#include "polyAddFace.H" #include "polyAddFace.H"
#include "ReadFields.H" #include "ReadFields.H"
#include "volFields.H" #include "volFields.H"
#include "surfaceFields.H" #include "surfaceFields.H"
#include "ZoneIDs.H"
#include "fvMeshMapper.H" #include "fvMeshMapper.H"
#include "SetPatchFields.H" #include "faceSelection.H"
#include "fvMeshTools.H"
using namespace Foam; using namespace Foam;
@ -107,21 +108,6 @@ void modifyOrAddFace
} }
label findPatchID(const polyMesh& mesh, const word& name)
{
const label patchI = mesh.boundaryMesh().findPatchID(name);
if (patchI == -1)
{
FatalErrorIn("findPatchID(const polyMesh&, const word&)")
<< "Cannot find patch " << name << endl
<< "Valid patches are " << mesh.boundaryMesh().names()
<< exit(FatalError);
}
return patchI;
}
// Main program: // Main program:
int main(int argc, char *argv[]) int main(int argc, char *argv[])
@ -129,102 +115,84 @@ int main(int argc, char *argv[])
argList::addNote argList::addNote
( (
"Makes internal faces into boundary faces.\n" "Makes internal faces into boundary faces.\n"
"Does not duplicate points, unlike mergeOrSplitBaffles." "Does not duplicate points."
); );
#include "addOverwriteOption.H" #include "addOverwriteOption.H"
#include "addRegionOption.H"
argList::validArgs.append("faceZone");
argList::validArgs.append("(masterPatch slavePatch)");
argList::addOption argList::addOption
( (
"additionalPatches", "dict",
"((master2 slave2) .. (masterN slaveN))" "file",
"specify alternative dictionary for the createBaffles description"
); );
argList::addBoolOption #include "addRegionOption.H"
(
"internalFacesOnly",
"do not convert boundary faces"
);
argList::addBoolOption
(
"updateFields",
"update fields to include new patches:"
" NOTE: updated field values may need to be edited"
);
#include "setRootCase.H" #include "setRootCase.H"
#include "createTime.H" #include "createTime.H"
runTime.functionObjects().off(); runTime.functionObjects().off();
#include "createNamedMesh.H" #include "createNamedMesh.H"
const bool overwrite = args.optionFound("overwrite");
const word oldInstance = mesh.pointsInstance(); const word oldInstance = mesh.pointsInstance();
const polyBoundaryMesh& patches = mesh.boundaryMesh(); const word dictName
const faceZoneMesh& faceZones = mesh.faceZones(); (
args.optionLookupOrDefault<word>
// Faces to baffle
faceZoneID zoneID(args.additionalArgs()[0], faceZones);
Info<< "Converting faces on zone " << zoneID.name()
<< " into baffles." << nl << endl;
if (zoneID.index() == -1)
{
FatalErrorIn(args.executable()) << "Cannot find faceZone "
<< zoneID.name() << endl
<< "Valid zones are " << faceZones.names()
<< exit(FatalError);
}
const faceZone& fZone = faceZones[zoneID.index()];
Info<< "Found " << returnReduce(fZone.size(), sumOp<label>())
<< " faces on zone " << zoneID.name() << nl << endl;
// Make sure patches and zoneFaces are synchronised across couples
patches.checkParallelSync(true);
fZone.checkParallelSync(true);
// Patches to put baffles into
DynamicList<label> newMasterPatches(1);
DynamicList<label> newSlavePatches(1);
const Pair<word> patchNames(IStringStream(args.additionalArgs()[1])());
newMasterPatches.append(findPatchID(mesh, patchNames[0]));
newSlavePatches.append(findPatchID(mesh, patchNames[1]));
Info<< "Using master patch " << patchNames[0]
<< " at index " << newMasterPatches[0] << endl;
Info<< "Using slave patch " << patchNames[1]
<< " at index " << newSlavePatches[0] << endl;
// Additional patches
if (args.optionFound("additionalPatches"))
{
const List<Pair<word> > patchNames
( (
args.optionLookup("additionalPatches")() "dict",
"createBafflesDict"
)
);
Switch internalFacesOnly(false);
Switch noFields(false);
PtrList<faceSelection> selectors;
{
Info<< "Reading baffle criteria from " << dictName << nl << endl;
IOdictionary dict
(
IOobject
(
dictName,
mesh.time().system(),
mesh,
IOobject::MUST_READ,
IOobject::NO_WRITE
)
); );
newMasterPatches.reserve(patchNames.size() + 1); dict.lookup("internalFacesOnly") >> internalFacesOnly;
newSlavePatches.reserve(patchNames.size() + 1); noFields = dict.lookupOrDefault("noFields", false);
forAll(patchNames, i)
const dictionary& selectionsDict = dict.subDict("baffles");
label n = 0;
forAllConstIter(dictionary, selectionsDict, iter)
{ {
newMasterPatches.append(findPatchID(mesh, patchNames[i][0])); if (iter().isDict())
newSlavePatches.append(findPatchID(mesh, patchNames[i][1])); {
Info<< "Using additional patches " << patchNames[i] n++;
<< " at indices " << newMasterPatches.last() }
<< " and " << newSlavePatches.last() }
<< endl; selectors.setSize(n);
n = 0;
forAllConstIter(dictionary, selectionsDict, iter)
{
if (iter().isDict())
{
selectors.set
(
n++,
faceSelection::New(iter().keyword(), mesh, iter().dict())
);
}
} }
} }
const bool overwrite = args.optionFound("overwrite");
const bool internalFacesOnly = args.optionFound("internalFacesOnly");
if (internalFacesOnly) if (internalFacesOnly)
{ {
Info<< "Not converting faces on non-coupled patches." << nl << endl; Info<< "Not converting faces on non-coupled patches." << nl << endl;
@ -237,41 +205,230 @@ int main(int argc, char *argv[])
// Read vol fields. // Read vol fields.
Info<< "Reading geometric fields" << nl << endl; Info<< "Reading geometric fields" << nl << endl;
PtrList<volScalarField> vsFlds; PtrList<volScalarField> vsFlds;
ReadFields(mesh, objects, vsFlds); if (!noFields) ReadFields(mesh, objects, vsFlds);
PtrList<volVectorField> vvFlds; PtrList<volVectorField> vvFlds;
ReadFields(mesh, objects, vvFlds); if (!noFields) ReadFields(mesh, objects, vvFlds);
PtrList<volSphericalTensorField> vstFlds; PtrList<volSphericalTensorField> vstFlds;
ReadFields(mesh, objects, vstFlds); if (!noFields) ReadFields(mesh, objects, vstFlds);
PtrList<volSymmTensorField> vsymtFlds; PtrList<volSymmTensorField> vsymtFlds;
ReadFields(mesh, objects, vsymtFlds); if (!noFields) ReadFields(mesh, objects, vsymtFlds);
PtrList<volTensorField> vtFlds; PtrList<volTensorField> vtFlds;
ReadFields(mesh, objects, vtFlds); if (!noFields) ReadFields(mesh, objects, vtFlds);
// Read surface fields. // Read surface fields.
PtrList<surfaceScalarField> ssFlds; PtrList<surfaceScalarField> ssFlds;
ReadFields(mesh, objects, ssFlds); if (!noFields) ReadFields(mesh, objects, ssFlds);
PtrList<surfaceVectorField> svFlds; PtrList<surfaceVectorField> svFlds;
ReadFields(mesh, objects, svFlds); if (!noFields) ReadFields(mesh, objects, svFlds);
PtrList<surfaceSphericalTensorField> sstFlds; PtrList<surfaceSphericalTensorField> sstFlds;
ReadFields(mesh, objects, sstFlds); if (!noFields) ReadFields(mesh, objects, sstFlds);
PtrList<surfaceSymmTensorField> ssymtFlds; PtrList<surfaceSymmTensorField> ssymtFlds;
ReadFields(mesh, objects, ssymtFlds); if (!noFields) ReadFields(mesh, objects, ssymtFlds);
PtrList<surfaceTensorField> stFlds; PtrList<surfaceTensorField> stFlds;
ReadFields(mesh, objects, stFlds); if (!noFields) ReadFields(mesh, objects, stFlds);
// Creating (if necessary) baffles
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
forAll(selectors, selectorI)
{
const word& name = selectors[selectorI].name();
if (mesh.faceZones().findZoneID(name) == -1)
{
mesh.faceZones().clearAddressing();
label sz = mesh.faceZones().size();
labelList addr(0);
boolList flip(0);
mesh.faceZones().setSize(sz+1);
mesh.faceZones().set
(
sz,
new faceZone(name, addr, flip, sz, mesh.faceZones())
);
}
}
// Select faces
// ~~~~~~~~~~~~
//- Per face zoneID it is in and flip status.
labelList faceToZoneID(mesh.nFaces(), -1);
boolList faceToFlip(mesh.nFaces(), false);
forAll(selectors, selectorI)
{
const word& name = selectors[selectorI].name();
label zoneID = mesh.faceZones().findZoneID(name);
selectors[selectorI].select(zoneID, faceToZoneID, faceToFlip);
}
// Add faces to faceZones
labelList nFaces(mesh.faceZones().size(), 0);
forAll(faceToZoneID, faceI)
{
label zoneID = faceToZoneID[faceI];
if (zoneID != -1)
{
nFaces[zoneID]++;
}
}
forAll(selectors, selectorI)
{
const word& name = selectors[selectorI].name();
label zoneID = mesh.faceZones().findZoneID(name);
label& n = nFaces[zoneID];
labelList addr(n);
boolList flip(n);
n = 0;
forAll(faceToZoneID, faceI)
{
label zone = faceToZoneID[faceI];
if (zone == zoneID)
{
addr[n] = faceI;
flip[n] = faceToFlip[faceI];
n++;
}
}
Info<< "Created zone " << name
<< " at index " << zoneID
<< " with " << n << " faces" << endl;
mesh.faceZones().set
(
zoneID,
new faceZone(name, addr, flip, zoneID, mesh.faceZones())
);
}
// Count patches to add
// ~~~~~~~~~~~~~~~~~~~~
HashSet<word> bafflePatches;
{
forAll(selectors, selectorI)
{
const dictionary& patchSources
(
selectors[selectorI].dict().subDict("patches")
);
forAllConstIter(dictionary, patchSources, iter)
{
//const word& patchName = iter().keyword();
const word patchName(iter().dict()["name"]);
bafflePatches.insert(patchName);
}
}
}
// Create baffles
// ~~~~~~~~~~~~~~
// Is done in multiple steps
// - create patches with 'calculated' patchFields
// - move faces into these patches
// - change the patchFields to the wanted type
// This order is done so e.g. fixedJump works:
// - you cannot create patchfields at the same time as patches since
// they do an evaluate upon construction
// - you want to create the patchField only after you have faces
// so you don't get the 'create-from-nothing' mapping problem.
// Pass 1: add patches
// ~~~~~~~~~~~~~~~~~~~
//HashSet<word> addedPatches;
{
const polyBoundaryMesh& pbm = mesh.boundaryMesh();
forAll(selectors, selectorI)
{
const dictionary& patchSources
(
selectors[selectorI].dict().subDict("patches")
);
forAllConstIter(dictionary, patchSources, iter)
{
//const word& patchName = iter().keyword();
const word patchName(iter().dict()["name"]);
label destPatchI = pbm.findPatchID(patchName);
if (destPatchI == -1)
{
dictionary patchDict = iter().dict();
patchDict.set("nFaces", 0);
patchDict.set("startFace", 0);
Info<< "Adding new patch " << patchName
<< " from " << patchDict << endl;
autoPtr<polyPatch> ppPtr
(
polyPatch::New
(
patchName,
patchDict,
0,
pbm
)
);
// Add patch, create calculated everywhere
fvMeshTools::addPatch
(
mesh,
ppPtr(),
dictionary(), // do not set specialised patchFields
calculatedFvPatchField<scalar>::typeName,
true // parallel sync'ed addition
);
//addedPatches.insert(patchName);
}
else
{
Info<< "Patch '" << patchName << "' already exists. Only "
<< "moving patch faces - type will remain the same"
<< endl;
}
}
}
}
// Make sure patches and zoneFaces are synchronised across couples
mesh.boundaryMesh().checkParallelSync(true);
mesh.faceZones().checkParallelSync(true);
// Mesh change container // Mesh change container
polyTopoChange meshMod(mesh); polyTopoChange meshMod(mesh);
const polyBoundaryMesh& pbm = mesh.boundaryMesh();
// Do the actual changes. Note: // Do the actual changes. Note:
// - loop in incrementing face order (not necessary if faceZone ordered). // - loop in incrementing face order (not necessary if faceZone ordered).
@ -284,161 +441,197 @@ int main(int argc, char *argv[])
PackedBoolList modifiedFace(mesh.nFaces()); PackedBoolList modifiedFace(mesh.nFaces());
label nModified = 0; label nModified = 0;
forAll(newMasterPatches, i) forAll(selectors, selectorI)
{ {
// Pass 1. Do selected side of zone const word& name = selectors[selectorI].name();
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ label zoneID = mesh.faceZones().findZoneID(name);
const faceZone& fZone = mesh.faceZones()[zoneID];
for (label faceI = 0; faceI < mesh.nInternalFaces(); faceI++) const dictionary& patchSources
(
selectors[selectorI].dict().subDict("patches")
);
DynamicList<label> newMasterPatches(patchSources.size());
DynamicList<label> newSlavePatches(patchSources.size());
bool master = true;
forAllConstIter(dictionary, patchSources, iter)
{ {
label zoneFaceI = fZone.whichFace(faceI); //const word& patchName = iter().keyword();
const word patchName(iter().dict()["name"]);
if (zoneFaceI != -1) label patchI = pbm.findPatchID(patchName);
if (master)
{ {
if (!fZone.flipMap()[zoneFaceI]) newMasterPatches.append(patchI);
{
// Use owner side of face
modifyOrAddFace
(
meshMod,
mesh.faces()[faceI], // modified face
faceI, // label of face
mesh.faceOwner()[faceI],// owner
false, // face flip
newMasterPatches[i], // patch for face
zoneID.index(), // zone for face
false, // face flip in zone
modifiedFace // modify or add status
);
}
else
{
// Use neighbour side of face
modifyOrAddFace
(
meshMod,
mesh.faces()[faceI].reverseFace(), // modified face
faceI, // label of face
mesh.faceNeighbour()[faceI],// owner
true, // face flip
newMasterPatches[i], // patch for face
zoneID.index(), // zone for face
true, // face flip in zone
modifiedFace // modify or add status
);
}
nModified++;
} }
else
{
newSlavePatches.append(patchI);
}
master = !master;
} }
// Pass 2. Do other side of zone
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
for (label faceI = 0; faceI < mesh.nInternalFaces(); faceI++) forAll(newMasterPatches, i)
{ {
label zoneFaceI = fZone.whichFace(faceI); // Pass 1. Do selected side of zone
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
if (zoneFaceI != -1) for (label faceI = 0; faceI < mesh.nInternalFaces(); faceI++)
{ {
if (!fZone.flipMap()[zoneFaceI]) label zoneFaceI = fZone.whichFace(faceI);
if (zoneFaceI != -1)
{ {
// Use neighbour side of face if (!fZone.flipMap()[zoneFaceI])
modifyOrAddFace
(
meshMod,
mesh.faces()[faceI].reverseFace(), // modified face
faceI, // label of face
mesh.faceNeighbour()[faceI], // owner
true, // face flip
newSlavePatches[i], // patch for face
zoneID.index(), // zone for face
true, // face flip in zone
modifiedFace // modify or add
);
}
else
{
// Use owner side of face
modifyOrAddFace
(
meshMod,
mesh.faces()[faceI], // modified face
faceI, // label of face
mesh.faceOwner()[faceI],// owner
false, // face flip
newSlavePatches[i], // patch for face
zoneID.index(), // zone for face
false, // face flip in zone
modifiedFace // modify or add status
);
}
}
}
// Modify any boundary faces
// ~~~~~~~~~~~~~~~~~~~~~~~~~
// Normal boundary:
// - move to new patch. Might already be back-to-back baffle
// you want to add cyclic to. Do warn though.
//
// Processor boundary:
// - do not move to cyclic
// - add normal patches though.
// For warning once per patch.
labelHashSet patchWarned;
forAll(patches, patchI)
{
const polyPatch& pp = patches[patchI];
label newPatchI = newMasterPatches[i];
if (pp.coupled() && patches[newPatchI].coupled())
{
// Do not allow coupled faces to be moved to different coupled
// patches.
}
else if (pp.coupled() || !internalFacesOnly)
{
forAll(pp, i)
{
label faceI = pp.start()+i;
label zoneFaceI = fZone.whichFace(faceI);
if (zoneFaceI != -1)
{ {
if (patchWarned.insert(patchI)) // Use owner side of face
{
WarningIn(args.executable())
<< "Found boundary face (in patch " << pp.name()
<< ") in faceZone " << fZone.name()
<< " to convert to baffle patch "
<< patches[newPatchI].name()
<< endl
<< " Run with -internalFacesOnly option"
<< " if you don't wish to convert"
<< " boundary faces." << endl;
}
modifyOrAddFace modifyOrAddFace
( (
meshMod, meshMod,
mesh.faces()[faceI], // modified face mesh.faces()[faceI], // modified face
faceI, // label of face
mesh.faceOwner()[faceI],// owner
false, // face flip
newMasterPatches[i], // patch for face
fZone.index(), // zone for face
false, // face flip in zone
modifiedFace // modify or add status
);
}
else
{
// Use neighbour side of face
modifyOrAddFace
(
meshMod,
mesh.faces()[faceI].reverseFace(), // modified face
faceI, // label of face faceI, // label of face
mesh.faceOwner()[faceI], // owner mesh.faceNeighbour()[faceI],// owner
false, // face flip true, // face flip
newPatchI, // patch for face newMasterPatches[i], // patch for face
zoneID.index(), // zone for face fZone.index(), // zone for face
fZone.flipMap()[zoneFaceI], // face flip in zone true, // face flip in zone
modifiedFace // modify or add status modifiedFace // modify or add status
); );
nModified++; }
nModified++;
}
}
// Pass 2. Do other side of zone
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
for (label faceI = 0; faceI < mesh.nInternalFaces(); faceI++)
{
label zoneFaceI = fZone.whichFace(faceI);
if (zoneFaceI != -1)
{
if (!fZone.flipMap()[zoneFaceI])
{
// Use neighbour side of face
modifyOrAddFace
(
meshMod,
mesh.faces()[faceI].reverseFace(), // modified face
faceI, // label of face
mesh.faceNeighbour()[faceI], // owner
true, // face flip
newSlavePatches[i], // patch for face
fZone.index(), // zone for face
true, // face flip in zone
modifiedFace // modify or add
);
}
else
{
// Use owner side of face
modifyOrAddFace
(
meshMod,
mesh.faces()[faceI], // modified face
faceI, // label of face
mesh.faceOwner()[faceI],// owner
false, // face flip
newSlavePatches[i], // patch for face
fZone.index(), // zone for face
false, // face flip in zone
modifiedFace // modify or add status
);
}
}
}
// Modify any boundary faces
// ~~~~~~~~~~~~~~~~~~~~~~~~~
// Normal boundary:
// - move to new patch. Might already be back-to-back baffle
// you want to add cyclic to. Do warn though.
//
// Processor boundary:
// - do not move to cyclic
// - add normal patches though.
// For warning once per patch.
labelHashSet patchWarned;
forAll(pbm, patchI)
{
const polyPatch& pp = pbm[patchI];
label newPatchI = newMasterPatches[i];
if (pp.coupled() && pbm[newPatchI].coupled())
{
// Do not allow coupled faces to be moved to different
// coupled patches.
}
else if (pp.coupled() || !internalFacesOnly)
{
forAll(pp, i)
{
label faceI = pp.start()+i;
label zoneFaceI = fZone.whichFace(faceI);
if (zoneFaceI != -1)
{
if (patchWarned.insert(patchI))
{
WarningIn(args.executable())
<< "Found boundary face (in patch "
<< pp.name()
<< ") in faceZone " << fZone.name()
<< " to convert to baffle patch "
<< pbm[newPatchI].name()
<< endl
<< " Run with -internalFacesOnly option"
<< " if you don't wish to convert"
<< " boundary faces." << endl;
}
modifyOrAddFace
(
meshMod,
mesh.faces()[faceI], // modified face
faceI, // label of face
mesh.faceOwner()[faceI], // owner
false, // face flip
newPatchI, // patch for face
fZone.index(), // zone for face
fZone.flipMap()[zoneFaceI], // face flip in zone
modifiedFace // modify or add
);
nModified++;
}
} }
} }
} }
@ -447,7 +640,8 @@ int main(int argc, char *argv[])
Info<< "Converted " << returnReduce(nModified, sumOp<label>()) Info<< "Converted " << returnReduce(nModified, sumOp<label>())
<< " faces into boundary faces on patches " << patchNames << nl << endl; << " faces into boundary faces in patches "
<< bafflePatches.sortedToc() << nl << endl;
if (!overwrite) if (!overwrite)
{ {
@ -460,14 +654,20 @@ int main(int argc, char *argv[])
// Update fields // Update fields
mesh.updateMesh(map); mesh.updateMesh(map);
// Correct boundary faces mapped-out-of-nothing. // Correct boundary faces mapped-out-of-nothing.
// This is just a hack to correct the value field.
{ {
fvMeshMapper mapper(mesh, map); fvMeshMapper mapper(mesh, map);
bool hasWarned = false; bool hasWarned = false;
forAll(newMasterPatches, i)
forAllConstIter(HashSet<word>, bafflePatches, iter)
{ {
label patchI = newMasterPatches[i]; label patchI = mesh.boundaryMesh().findPatchID(iter.key());
const fvPatchMapper& pm = mapper.boundaryMap()[patchI]; const fvPatchMapper& pm = mapper.boundaryMap()[patchI];
if (pm.sizeBeforeMapping() == 0) if (pm.sizeBeforeMapping() == 0)
{ {
if (!hasWarned) if (!hasWarned)
@ -478,40 +678,48 @@ int main(int argc, char *argv[])
<< "You might have to edit these fields." << endl; << "You might have to edit these fields." << endl;
} }
SetPatchFields(vsFlds, patchI, pTraits<scalar>::zero); fvMeshTools::zeroPatchFields(mesh, patchI);
SetPatchFields(vvFlds, patchI, pTraits<vector>::zero);
SetPatchFields(vstFlds, patchI, pTraits<sphericalTensor>::zero);
SetPatchFields(vsymtFlds, patchI, pTraits<symmTensor>::zero);
SetPatchFields(vtFlds, patchI, pTraits<tensor>::zero);
SetPatchFields(ssFlds, patchI, pTraits<scalar>::zero);
SetPatchFields(svFlds, patchI, pTraits<vector>::zero);
SetPatchFields(sstFlds, patchI, pTraits<sphericalTensor>::zero);
SetPatchFields(ssymtFlds, patchI, pTraits<symmTensor>::zero);
SetPatchFields(stFlds, patchI, pTraits<tensor>::zero);
}
}
forAll(newSlavePatches, i)
{
label patchI = newSlavePatches[i];
const fvPatchMapper& pm = mapper.boundaryMap()[patchI];
if (pm.sizeBeforeMapping() == 0)
{
SetPatchFields(vsFlds, patchI, pTraits<scalar>::zero);
SetPatchFields(vvFlds, patchI, pTraits<vector>::zero);
SetPatchFields(vstFlds, patchI, pTraits<sphericalTensor>::zero);
SetPatchFields(vsymtFlds, patchI, pTraits<symmTensor>::zero);
SetPatchFields(vtFlds, patchI, pTraits<tensor>::zero);
SetPatchFields(ssFlds, patchI, pTraits<scalar>::zero);
SetPatchFields(svFlds, patchI, pTraits<vector>::zero);
SetPatchFields(sstFlds, patchI, pTraits<sphericalTensor>::zero);
SetPatchFields(ssymtFlds, patchI, pTraits<symmTensor>::zero);
SetPatchFields(stFlds, patchI, pTraits<tensor>::zero);
} }
} }
} }
// Pass 2: change patchFields
// ~~~~~~~~~~~~~~~~~~~~~~~~~~
{
const polyBoundaryMesh& pbm = mesh.boundaryMesh();
forAll(selectors, selectorI)
{
const dictionary& patchSources
(
selectors[selectorI].dict().subDict("patches")
);
forAllConstIter(dictionary, patchSources, iter)
{
//const word& patchName = iter().keyword();
const word patchName(iter().dict()["name"]);
label patchI = pbm.findPatchID(patchName);
if (iter().dict().found("patchFields"))
{
const dictionary& patchFieldsDict = iter().dict().subDict
(
"patchFields"
);
fvMeshTools::setPatchFields
(
mesh,
patchI,
patchFieldsDict
);
}
}
}
}
// Move mesh (since morphing might not do this) // Move mesh (since morphing might not do this)
if (map().hasMotionPoints()) if (map().hasMotionPoints())
{ {
@ -522,6 +730,7 @@ int main(int argc, char *argv[])
{ {
mesh.setInstance(oldInstance); mesh.setInstance(oldInstance);
} }
Info<< "Writing mesh to " << runTime.timeName() << endl; Info<< "Writing mesh to " << runTime.timeName() << endl;
mesh.write(); mesh.write();

View File

@ -0,0 +1,189 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: dev |
| \\ / A nd | Web: www.OpenFOAM.org |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class dictionary;
object createBafflesDict;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// Whether to convert internal faces only (so leave boundary faces intact).
// This is only relevant if your face selection type can pick up boundary
// faces.
internalFacesOnly true;
// Optionally do not read/convert/write any fields.
//noFields true;
// Baffles to create.
baffles
{
baffleFaces
{
//- Use predefined faceZone to select faces and orientation.
type faceZone;
zoneName baffleFaces;
//- Optional flip
//flip false;
patches
{
master
{
//- Master side patch
name baffles;
type wall;
patchFields
{
epsilon
{
type epsilonWallFunction;
Cmu 0.09;
kappa 0.41;
E 9.8;
value uniform 0;
}
k
{
type kqRWallFunction;
value uniform 0;
}
nut
{
type nutkWallFunction;
Cmu 0.09;
kappa 0.41;
E 9.8;
value uniform 0;
}
nuTilda
{
type zeroGradient;
}
p
{
type zeroGradient;
}
U
{
type fixedValue;
value uniform (0 0 0);
}
}
}
slave
{
//- Slave side patch
name baffles;
type wall;
patchFields
{
epsilon
{
type epsilonWallFunction;
Cmu 0.09;
kappa 0.41;
E 9.8;
value uniform 0;
}
k
{
type kqRWallFunction;
value uniform 0;
}
nut
{
type nutkWallFunction;
Cmu 0.09;
kappa 0.41;
E 9.8;
value uniform 0;
}
nuTilda
{
type zeroGradient;
}
p
{
type zeroGradient;
}
U
{
type fixedValue;
value uniform (0 0 0);
}
}
}
}
}
cyclicFaces
{
//- Select faces and orientation through a searchableSurface
type searchableSurface;
surface searchablePlate;
origin (0.099 -0.006 0.004);
span (0 0.012 0.012);
patches
{
master
{
//- Master side patch
name fan_half0;
type cyclic;
neighbourPatch fan_half1;
//- Optional override of added patchfields. If not specified
// any added patchfields are of type calculated.
patchFields
{
p
{
type fan;
patchType cyclic;
jump uniform 0;
value uniform 0;
jumpTable polynomial 1((100 0));
}
}
}
slave
{
//- Slave side patch
name fan_half1;
type cyclic;
neighbourPatch fan_half0;
patchFields
{
p
{
type fan;
patchType cyclic;
value uniform 0;
}
}
}
}
}
}
// ************************************************************************* //

View File

@ -0,0 +1,111 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2012 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 "faceSelection.H"
#include "fvMesh.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
defineTypeNameAndDebug(faceSelection, 0);
defineRunTimeSelectionTable(faceSelection, dictionary);
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::faceSelection::faceSelection
(
const word& name,
const fvMesh& mesh,
const dictionary& dict
)
:
name_(name),
mesh_(mesh),
dict_(dict),
flip_(dict.lookupOrDefault("flip", false))
{}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::faceSelection::~faceSelection()
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
Foam::autoPtr<Foam::faceSelection> Foam::faceSelection::New
(
const word& name,
const fvMesh& mesh,
const dictionary& dict
)
{
const word sampleType(dict.lookup("type"));
dictionaryConstructorTable::iterator cstrIter =
dictionaryConstructorTablePtr_->find(sampleType);
if (cstrIter == dictionaryConstructorTablePtr_->end())
{
FatalErrorIn
(
"faceSelection::New"
"(const word&, const fvMesh&, const dictionary&)"
) << "Unknown faceSelection type "
<< sampleType << nl << nl
<< "Valid faceSelection types : " << endl
<< dictionaryConstructorTablePtr_->sortedToc()
<< exit(FatalError);
}
return autoPtr<faceSelection>(cstrIter()(name, mesh, dict));
}
void Foam::faceSelection::select
(
const label zoneID,
labelList& faceToZoneID,
boolList& faceToFlip
) const
{
if (flip_)
{
forAll(faceToZoneID, faceI)
{
if (faceToZoneID[faceI] == zoneID)
{
faceToFlip[faceI] = !faceToFlip[faceI];
}
}
}
}
// ************************************************************************* //

View File

@ -0,0 +1,156 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2012 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::faceSelection
Description
Face selection method for createBaffles
SourceFiles
faceSelection.C
\*---------------------------------------------------------------------------*/
#ifndef faceSelection_H
#define faceSelection_H
#include "dictionary.H"
#include "typeInfo.H"
#include "runTimeSelectionTables.H"
#include "autoPtr.H"
#include "boolList.H"
#include "labelList.H"
#include "Switch.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// Forward declaration of classes
class fvMesh;
/*---------------------------------------------------------------------------*\
Class faceSelection Declaration
\*---------------------------------------------------------------------------*/
class faceSelection
{
protected:
// Protected data
//- Name
const word name_;
//- Reference to mesh
const fvMesh& mesh_;
//- Input dictionary
const dictionary dict_;
//- Switch direction?
const Switch flip_;
public:
//- Runtime type information
TypeName("faceSelection");
// Declare run-time constructor selection table
declareRunTimeSelectionTable
(
autoPtr,
faceSelection,
dictionary,
(
const word& name,
const fvMesh& mesh,
const dictionary& dict
),
(name, mesh, dict)
);
// Constructors
//- Construct from dictionary
faceSelection
(
const word& name,
const fvMesh& mesh,
const dictionary& dict
);
//- Clone
autoPtr<faceSelection> clone() const
{
notImplemented("autoPtr<faceSelection> clone() const");
return autoPtr<faceSelection>(NULL);
}
// Selectors
//- Return a reference to the selected faceSelection
static autoPtr<faceSelection> New
(
const word& name,
const fvMesh& mesh,
const dictionary& dict
);
//- Destructor
virtual ~faceSelection();
// Member Functions
const word& name() const
{
return name_;
}
const dictionary& dict() const
{
return dict_;
}
virtual void select(const label, labelList&, boolList&) const = 0;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,108 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2012 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 "faceZoneSelection.H"
#include "addToRunTimeSelectionTable.H"
#include "fvMesh.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
namespace faceSelections
{
defineTypeNameAndDebug(faceZoneSelection, 0);
addToRunTimeSelectionTable(faceSelection, faceZoneSelection, dictionary);
}
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::faceSelections::faceZoneSelection::faceZoneSelection
(
const word& name,
const fvMesh& mesh,
const dictionary& dict
)
:
faceSelection(name, mesh, dict),
zoneName_(dict_.lookup("zoneName"))
{}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::faceSelections::faceZoneSelection::~faceZoneSelection()
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
void Foam::faceSelections::faceZoneSelection::select
(
const label zoneID,
labelList& faceToZoneID,
boolList& faceToFlip
) const
{
label readID = mesh_.faceZones().findZoneID(zoneName_);
if (readID == -1)
{
FatalErrorIn
(
"faceSelections::faceZoneSelection::select(labelList&) const"
) << "Cannot find faceZone " << zoneName_ << nl << "Valid zones are "
<< mesh_.faceZones().names()
<< exit(FatalError);
}
const faceZone& fZone = mesh_.faceZones()[readID];
forAll(fZone, i)
{
label faceI = fZone[i];
if (faceToZoneID[faceI] == -1)
{
faceToZoneID[faceI] = zoneID;
faceToFlip[faceI] = fZone.flipMap()[i];
}
else if (faceToZoneID[faceI] != zoneID)
{
FatalErrorIn
(
"faceSelections::faceZoneSelection::select(labelList&) const"
) << "Face " << faceI << " already in faceZone "
<< faceToZoneID[faceI]
<< exit(FatalError);
}
}
faceSelection::select(zoneID, faceToZoneID, faceToFlip);
}
// ************************************************************************* //

View File

@ -0,0 +1,114 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2012 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::faceSelections::faceZoneSelection
Description
Deselect cells not reachable from 'inside' points
SourceFiles
faceZoneSelection.C
\*---------------------------------------------------------------------------*/
#ifndef faceZoneSelection_H
#define faceZoneSelection_H
#include "faceSelection.H"
#include "pointField.H"
#include "boolList.H"
#include "volFields.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
class regionSplit;
namespace faceSelections
{
/*---------------------------------------------------------------------------*\
Class faceZoneSelection Declaration
\*---------------------------------------------------------------------------*/
class faceZoneSelection
:
public faceSelection
{
// Private data
//- Name of faceZone
const word zoneName_;
// Private Member Functions
public:
//- Runtime type information
TypeName("faceZone");
// Constructors
//- Construct from dictionary
faceZoneSelection
(
const word& name,
const fvMesh& mesh,
const dictionary& dict
);
//- Clone
autoPtr<faceSelection> clone() const
{
notImplemented("autoPtr<faceSelection> clone() const");
return autoPtr<faceSelection>(NULL);
}
//- Destructor
virtual ~faceZoneSelection();
// Member Functions
//- Apply this selector
virtual void select(const label zoneID, labelList&, boolList&) const;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace faceSelections
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,172 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2012 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 "searchableSurfaceSelection.H"
#include "addToRunTimeSelectionTable.H"
#include "syncTools.H"
#include "searchableSurface.H"
#include "fvMesh.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
namespace faceSelections
{
defineTypeNameAndDebug(searchableSurfaceSelection, 0);
addToRunTimeSelectionTable
(
faceSelection,
searchableSurfaceSelection,
dictionary
);
}
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::faceSelections::searchableSurfaceSelection::searchableSurfaceSelection
(
const word& name,
const fvMesh& mesh,
const dictionary& dict
)
:
faceSelection(name, mesh, dict),
surfacePtr_
(
searchableSurface::New
(
word(dict.lookup("surface")),
mesh.objectRegistry::db(),
dict
)
)
{}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::faceSelections::searchableSurfaceSelection::~searchableSurfaceSelection()
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
void Foam::faceSelections::searchableSurfaceSelection::select
(
const label zoneID,
labelList& faceToZoneID,
boolList& faceToFlip
) const
{
// Get cell-cell centre vectors
pointField start(mesh_.nFaces());
pointField end(mesh_.nFaces());
// Internal faces
for (label faceI = 0; faceI < mesh_.nInternalFaces(); faceI++)
{
start[faceI] = mesh_.cellCentres()[mesh_.faceOwner()[faceI]];
end[faceI] = mesh_.cellCentres()[mesh_.faceNeighbour()[faceI]];
}
// Boundary faces
vectorField neighbourCellCentres;
syncTools::swapBoundaryCellList
(
mesh_,
mesh_.cellCentres(),
neighbourCellCentres
);
const polyBoundaryMesh& pbm = mesh_.boundaryMesh();
forAll(pbm, patchI)
{
const polyPatch& pp = pbm[patchI];
if (pp.coupled())
{
forAll(pp, i)
{
label faceI = pp.start()+i;
start[faceI] = mesh_.cellCentres()[mesh_.faceOwner()[faceI]];
end[faceI] = neighbourCellCentres[faceI-mesh_.nInternalFaces()];
}
}
else
{
forAll(pp, i)
{
label faceI = pp.start()+i;
start[faceI] = mesh_.cellCentres()[mesh_.faceOwner()[faceI]];
end[faceI] = mesh_.faceCentres()[faceI];
}
}
}
List<pointIndexHit> hits;
surfacePtr_().findLine(start, end, hits);
pointField normals;
surfacePtr_().getNormal(hits, normals);
//- Note: do not select boundary faces.
for (label faceI = 0; faceI < mesh_.nInternalFaces(); faceI++)
{
if (hits[faceI].hit())
{
faceToZoneID[faceI] = zoneID;
vector d = end[faceI]-start[faceI];
faceToFlip[faceI] = ((normals[faceI] & d) < 0);
}
}
forAll(pbm, patchI)
{
const polyPatch& pp = pbm[patchI];
if (pp.coupled())
{
forAll(pp, i)
{
label faceI = pp.start()+i;
if (hits[faceI].hit())
{
faceToZoneID[faceI] = zoneID;
vector d = end[faceI]-start[faceI];
faceToFlip[faceI] = ((normals[faceI] & d) < 0);
}
}
}
}
faceSelection::select(zoneID, faceToZoneID, faceToFlip);
}
// ************************************************************************* //

View File

@ -0,0 +1,106 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2012 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::faceSelections::searchableSurfaceSelection
Description
Selects all (internal or coupled) faces intersecting the searchableSurface.
SourceFiles
searchableSurfaceSelection.C
\*---------------------------------------------------------------------------*/
#ifndef searchableSurfaceSelection_H
#define searchableSurfaceSelection_H
#include "faceSelection.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
class searchableSurface;
namespace faceSelections
{
/*---------------------------------------------------------------------------*\
Class searchableSurfaceSelection Declaration
\*---------------------------------------------------------------------------*/
class searchableSurfaceSelection
:
public faceSelection
{
// Private data
autoPtr<searchableSurface> surfacePtr_;
public:
//- Runtime type information
TypeName("searchableSurface");
// Constructors
//- Construct from dictionary
searchableSurfaceSelection
(
const word& name,
const fvMesh& mesh,
const dictionary& dict
);
//- Clone
autoPtr<faceSelection> clone() const
{
notImplemented("autoPtr<faceSelection> clone() const");
return autoPtr<faceSelection>(NULL);
}
//- Destructor
virtual ~searchableSurfaceSelection();
// Member Functions
virtual void select(const label zoneID, labelList&, boolList&) const;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace faceSelections
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //