Merge branch 'master' of ssh://opencfd:8007/home/dm4/OpenFOAM/OpenFOAM-dev

This commit is contained in:
Henry
2013-06-02 22:30:36 +01:00
235 changed files with 13310 additions and 1854 deletions

View File

@ -56,6 +56,8 @@ Description
//#include "centredCFCFaceToCellStencilObject.H" //#include "centredCFCFaceToCellStencilObject.H"
#include "centredCECCellToCellStencilObject.H" #include "centredCECCellToCellStencilObject.H"
#include "centredCFCCellToCellStencilObject.H"
#include "centredCPCCellToCellStencilObject.H"
using namespace Foam; using namespace Foam;
@ -460,7 +462,63 @@ int main(int argc, char *argv[])
{ {
writeStencilOBJ writeStencilOBJ
( (
runTime.path()/"centredCell" + Foam::name(cellI) + ".obj", runTime.path()/"centredCECCell" + Foam::name(cellI) + ".obj",
mesh.cellCentres()[cellI],
stencilPoints[cellI]
);
}
}
{
const extendedCentredCellToCellStencil& addressing =
centredCPCCellToCellStencilObject::New
(
mesh
);
Info<< "cellCellCell:" << endl;
writeStencilStats(addressing.stencil());
// Collect stencil cell centres
List<List<point> > stencilPoints(mesh.nCells());
addressing.collectData
(
mesh.C(),
stencilPoints
);
forAll(stencilPoints, cellI)
{
writeStencilOBJ
(
runTime.path()/"centredCPCCell" + Foam::name(cellI) + ".obj",
mesh.cellCentres()[cellI],
stencilPoints[cellI]
);
}
}
{
const extendedCentredCellToCellStencil& addressing =
centredCFCCellToCellStencilObject::New
(
mesh
);
Info<< "cellCellCell:" << endl;
writeStencilStats(addressing.stencil());
// Collect stencil cell centres
List<List<point> > stencilPoints(mesh.nCells());
addressing.collectData
(
mesh.C(),
stencilPoints
);
forAll(stencilPoints, cellI)
{
writeStencilOBJ
(
runTime.path()/"centredCFCCell" + Foam::name(cellI) + ".obj",
mesh.cellCentres()[cellI], mesh.cellCentres()[cellI],
stencilPoints[cellI] stencilPoints[cellI]
); );

View File

@ -493,7 +493,6 @@ int main(int argc, char *argv[])
mesh.nFaces(), // start mesh.nFaces(), // start
patchI, // index patchI, // index
mesh.boundaryMesh(),// polyBoundaryMesh mesh.boundaryMesh(),// polyBoundaryMesh
Pstream::worldComm, // communicator
Pstream::myProcNo(),// myProcNo Pstream::myProcNo(),// myProcNo
nbrProcI // neighbProcNo nbrProcI // neighbProcNo
) )

View File

@ -152,6 +152,10 @@ castellatedMeshControls
inGroups (meshedPatches); inGroups (meshedPatches);
} }
//- Optional increment (on top of max level) in small gaps.
//gapLevelIncrement 2;
//- Optional angle to detect small-large cell situation //- Optional angle to detect small-large cell situation
// perpendicular to the surface. Is the angle of face w.r.t. // perpendicular to the surface. Is the angle of face w.r.t.
// the local surface normal. Use on flat(ish) surfaces only. // the local surface normal. Use on flat(ish) surfaces only.
@ -181,6 +185,15 @@ castellatedMeshControls
resolveFeatureAngle 30; resolveFeatureAngle 30;
// Planar angle:
// - used to determine if surface normals
// are roughly the same or opposite. Used e.g. in gap refinement
// and to decide when to merge free-standing baffles
//
// If not specified same as resolveFeatureAngle
planarAngle 15;
// Region-wise refinement // Region-wise refinement
// ~~~~~~~~~~~~~~~~~~~~~~ // ~~~~~~~~~~~~~~~~~~~~~~
@ -222,11 +235,6 @@ castellatedMeshControls
// are only on the boundary of corresponding cellZones or also allow // are only on the boundary of corresponding cellZones or also allow
// free-standing zone faces. Not used if there are no faceZones. // free-standing zone faces. Not used if there are no faceZones.
allowFreeStandingZoneFaces true; allowFreeStandingZoneFaces true;
// Optional: whether all baffles get eroded away. WIP. Used for
// surface simplification.
//allowFreeStandingBaffles false;
} }
// Settings for the snapping. // Settings for the snapping.
@ -456,20 +464,21 @@ meshQualityControls
// 1 = hex, <= 0 = folded or flattened illegal cell // 1 = hex, <= 0 = folded or flattened illegal cell
minDeterminant 0.001; minDeterminant 0.001;
// minFaceWeight (0 -> 0.5) // Relative position of face in relation to cell centres (0.5 for orthogonal
// mesh) (0 -> 0.5)
minFaceWeight 0.05; minFaceWeight 0.05;
// minVolRatio (0 -> 1) // Volume ratio of neighbouring cells (0 -> 1)
minVolRatio 0.01; minVolRatio 0.01;
// must be >0 for Fluent compatibility // must be >0 for Fluent compatibility
minTriangleTwist -1; minTriangleTwist -1;
//- if >0 : preserve single cells with all points on the surface if the //- if >0 : preserve cells with all points on the surface if the
// resulting volume after snapping (by approximation) is larger than // resulting volume after snapping (by approximation) is larger than
// minVolCollapseRatio times old volume (i.e. not collapsed to flat cell). // minVolCollapseRatio times old volume (i.e. not collapsed to flat cell).
// If <0 : delete always. // If <0 : delete always.
//minVolCollapseRatio 0.5; //minVolCollapseRatio 0.1;
// Advanced // Advanced

View File

@ -14,6 +14,20 @@ FoamFile
} }
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// Sample for creating baffles:
// - usually converting internal faces into two boundary faces
// - or converting boundary faces into a boundary face
// (internalFacesOnly=false)(though should use really createPatch
// to do this)
// - can also create duplicate (overlapping) sets of baffles:
// - internalFacesOnly = false
// - have 4 entries in patches:
// - master
// - slave
// - additional master
// - additional slave
// Whether to convert internal faces only (so leave boundary faces intact). // Whether to convert internal faces only (so leave boundary faces intact).
// This is only relevant if your face selection type can pick up boundary // This is only relevant if your face selection type can pick up boundary
// faces. // faces.

View File

@ -448,7 +448,6 @@ bool Foam::domainDecomposition::writeDecomposition()
curStart, curStart,
nPatches, nPatches,
procMesh.boundaryMesh(), procMesh.boundaryMesh(),
Pstream::worldComm,
procI, procI,
curNeighbourProcessors[procPatchI] curNeighbourProcessors[procPatchI]
); );
@ -476,7 +475,6 @@ bool Foam::domainDecomposition::writeDecomposition()
curStart, curStart,
nPatches, nPatches,
procMesh.boundaryMesh(), procMesh.boundaryMesh(),
Pstream::worldComm,
procI, procI,
curNeighbourProcessors[procPatchI], curNeighbourProcessors[procPatchI],
referPatch, referPatch,

View File

@ -240,7 +240,7 @@ int main(int argc, char *argv[])
wordHashSet allCloudNames; wordHashSet allCloudNames;
if (Pstream::master()) if (Pstream::master())
{ {
word geomFileName = prepend + "000"; word geomFileName = prepend + "0000";
// test pre check variable if there is a moving mesh // test pre check variable if there is a moving mesh
if (meshMoving) if (meshMoving)

View File

@ -26,7 +26,8 @@ dict.add("mergeDistance", SMALL);
labelHashSet includePatches; labelHashSet includePatches;
forAll(patches, patchI) forAll(patches, patchI)
{ {
if (!isA<processorPolyPatch>(patches[patchI])) const polyPatch& pp = patches[patchI];
if (!pp.coupled() && !isA<cyclicAMIPolyPatch>(pp))
{ {
includePatches.insert(patchI); includePatches.insert(patchI);
} }

View File

@ -44,6 +44,7 @@ Description
#include "volFields.H" #include "volFields.H"
#include "surfaceFields.H" #include "surfaceFields.H"
#include "distributedTriSurfaceMesh.H" #include "distributedTriSurfaceMesh.H"
#include "cyclicAMIPolyPatch.H"
#include "triSurfaceTools.H" #include "triSurfaceTools.H"
#include "mapDistribute.H" #include "mapDistribute.H"

View File

@ -16,6 +16,11 @@ cyclicAMI
type cyclicAMI; type cyclicAMI;
} }
cyclicACMI
{
type cyclicACMI;
}
cyclicSlip cyclicSlip
{ {
type cyclicSlip; type cyclicSlip;

View File

@ -135,7 +135,7 @@ DebugSwitches
FDIC 0; FDIC 0;
FaceCellWave 0; FaceCellWave 0;
GAMG 0; GAMG 0;
GAMGAgglomeration 0; GAMGAgglomeration 1;
GAMGInterface 0; GAMGInterface 0;
GAMGInterfaceField 0; GAMGInterfaceField 0;
Gamma 0; Gamma 0;

View File

@ -331,10 +331,8 @@ eagerGAMGProcAgglomeration = $(GAMGProcAgglomerations)/eagerGAMGProcAgglomeratio
$(eagerGAMGProcAgglomeration)/eagerGAMGProcAgglomeration.C $(eagerGAMGProcAgglomeration)/eagerGAMGProcAgglomeration.C
noneGAMGProcAgglomeration = $(GAMGProcAgglomerations)/noneGAMGProcAgglomeration noneGAMGProcAgglomeration = $(GAMGProcAgglomerations)/noneGAMGProcAgglomeration
$(noneGAMGProcAgglomeration)/noneGAMGProcAgglomeration.C $(noneGAMGProcAgglomeration)/noneGAMGProcAgglomeration.C
/* procFacesGAMGProcAgglomeration = $(GAMGProcAgglomerations)/procFacesGAMGProcAgglomeration
cellFaceRatioGAMGProcAgglomeration = $(GAMGProcAgglomerations)/cellFaceRatioGAMGProcAgglomeration $(procFacesGAMGProcAgglomeration)/procFacesGAMGProcAgglomeration.C
$(cellFaceRatioGAMGProcAgglomeration)/cellFaceRatioGAMGProcAgglomeration.C
*/
meshes/lduMesh/lduMesh.C meshes/lduMesh/lduMesh.C

View File

@ -2,7 +2,7 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -49,21 +49,16 @@ readField
<< endl; << endl;
} }
// Patch or patch-groups. (using non-wild card entries of dictionaries)
// 1. Handle explicit patch names
forAllConstIter(dictionary, dict, iter) forAllConstIter(dictionary, dict, iter)
{ {
if (iter().isDict() && !iter().keyword().isPattern()) if (iter().isDict() && !iter().keyword().isPattern())
{ {
const labelList patchIDs = bmesh_.findIndices label patchi = bmesh_.findPatchID(iter().keyword());
(
iter().keyword(),
true
);
forAll(patchIDs, i) if (patchi != -1)
{ {
label patchi = patchIDs[i];
this->set this->set
( (
patchi, patchi,
@ -78,7 +73,43 @@ readField
} }
} }
// Check for wildcard patch overrides
// 2. Patch-groups. (using non-wild card entries of dictionaries)
// (patchnames already matched above)
// Note: in order of entries in the dictionary (first patchGroups wins)
forAllConstIter(dictionary, dict, iter)
{
if (iter().isDict() && !iter().keyword().isPattern())
{
const labelList patchIDs = bmesh_.findIndices
(
iter().keyword(),
true // use patchGroups
);
forAll(patchIDs, i)
{
label patchi = patchIDs[i];
if (!this->set(patchi))
{
this->set
(
patchi,
PatchField<Type>::New
(
bmesh_[patchi],
field,
iter().dict()
)
);
}
}
}
}
// 3. Wildcard patch overrides
forAll(bmesh_, patchi) forAll(bmesh_, patchi)
{ {
if (!this->set(patchi)) if (!this->set(patchi))

View File

@ -351,7 +351,7 @@ void Foam::GAMGAgglomeration::agglomerateLduAddressing
); );
if (debug) if (debug & 2)
{ {
Pout<< "GAMGAgglomeration :" Pout<< "GAMGAgglomeration :"
<< " agglomerated level " << fineLevelIndex << " agglomerated level " << fineLevelIndex

View File

@ -27,9 +27,9 @@ License
#include "lduMesh.H" #include "lduMesh.H"
#include "lduMatrix.H" #include "lduMatrix.H"
#include "Time.H" #include "Time.H"
#include "dlLibraryTable.H"
#include "GAMGInterface.H" #include "GAMGInterface.H"
#include "GAMGProcAgglomeration.H" #include "GAMGProcAgglomeration.H"
#include "IOmanip.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
@ -67,24 +67,113 @@ void Foam::GAMGAgglomeration::compactLevels(const label nCreatedLevels)
procBoundaryFaceMap_.setSize(nCreatedLevels); procBoundaryFaceMap_.setSize(nCreatedLevels);
procAgglomeratorPtr_().agglomerate(); procAgglomeratorPtr_().agglomerate();
}
if (debug) if (debug)
{ {
Info<< "GAMGAgglomeration:" << nl
<< " local agglomerator : " << type() << nl
<< " processor agglomerator : "
<< procAgglomeratorPtr_().type() << nl
<< nl;
Info<< setw(40) << "nCells"
<< setw(24) << "nFaces/nCells"
<< setw(24) << "nInterfaces"
<< setw(24) << "nIntFaces/nCells" << nl
<< setw(8) << "Level"
<< setw(8) << "nProcs"
<< " "
<< setw(8) << "avg"
<< setw(8) << "max"
<< " "
<< setw(8) << "avg"
<< setw(8) << "max"
<< " "
<< setw(8) << "avg"
<< setw(8) << "max"
<< " " << setw(4) << "avg"
<< " " << setw(4) << "max"
<< nl
<< setw(8) << "-----"
<< setw(8) << "------"
<< " "
<< setw(8) << "---"
<< setw(8) << "---"
<< " "
<< setw(8) << "---"
<< setw(8) << "---"
<< " " << setw(4) << "---"
<< " " << setw(4) << "---"
<< nl;
for (label levelI = 0; levelI <= size(); levelI++) for (label levelI = 0; levelI <= size(); levelI++)
{ {
label nProcs = 0;
label nCells = 0;
scalar faceCellRatio = 0;
label nInterfaces = 0;
label nIntFaces = 0;
scalar ratio = 0.0;
if (hasMeshLevel(levelI)) if (hasMeshLevel(levelI))
{ {
nProcs = 1;
const lduMesh& fineMesh = meshLevel(levelI); const lduMesh& fineMesh = meshLevel(levelI);
Pout<< "Level " << levelI << " fine mesh:"<< nl; nCells = fineMesh.lduAddr().size();
Pout<< fineMesh.info() << endl; faceCellRatio =
} scalar(fineMesh.lduAddr().lowerAddr().size())/nCells;
else
const lduInterfacePtrsList interfaces =
fineMesh.interfaces();
forAll(interfaces, i)
{ {
Pout<< "Level " << levelI << " has no fine mesh:" << nl if (interfaces.set(i))
<< endl; {
nInterfaces++;
nIntFaces += interfaces[i].faceCells().size();
} }
} }
ratio = scalar(nIntFaces)/nCells;
}
label totNprocs = returnReduce(nProcs, sumOp<label>());
label maxNCells = returnReduce(nCells, maxOp<label>());
label totNCells = returnReduce(nCells, sumOp<label>());
scalar maxFaceCellRatio =
returnReduce(faceCellRatio, maxOp<scalar>());
scalar totFaceCellRatio =
returnReduce(faceCellRatio, sumOp<scalar>());
label maxNInt = returnReduce(nInterfaces, maxOp<label>());
label totNInt = returnReduce(nInterfaces, sumOp<label>());
scalar maxRatio = returnReduce(ratio, maxOp<scalar>());
scalar totRatio = returnReduce(ratio, sumOp<scalar>());
Info<< setw(8) << levelI
<< setw(8) << totNprocs
<< setw(16) << totNCells/totNprocs
<< setw(8) << maxNCells
<< " "
<< setw(8) << setprecision(4) << totFaceCellRatio/totNprocs
<< setw(8) << setprecision(4) << maxFaceCellRatio
<< " "
<< setw(8) << totNInt/totNprocs
<< setw(8) << maxNInt
<< " "
<< setw(8) << setprecision(4) << totRatio/totNprocs
<< setw(8) << setprecision(4) << maxRatio
<< nl;
}
Info<< endl;
}
} }
} }
@ -190,9 +279,9 @@ const Foam::GAMGAgglomeration& Foam::GAMGAgglomeration::New
"(const lduMesh& mesh, const dictionary& controlDict)" "(const lduMesh& mesh, const dictionary& controlDict)"
) << "Unknown GAMGAgglomeration type " ) << "Unknown GAMGAgglomeration type "
<< agglomeratorType << ".\n" << agglomeratorType << ".\n"
<< "Valid algebraic GAMGAgglomeration types are :" << "Valid matrix GAMGAgglomeration types are :"
<< lduMatrixConstructorTablePtr_->sortedToc() << endl << lduMatrixConstructorTablePtr_->sortedToc() << endl
<< "Valid algebraic GAMGAgglomeration types are :" << "Valid geometric GAMGAgglomeration types are :"
<< lduMeshConstructorTablePtr_->sortedToc() << lduMeshConstructorTablePtr_->sortedToc()
<< exit(FatalError); << exit(FatalError);
} }
@ -285,7 +374,8 @@ Foam::autoPtr<Foam::GAMGAgglomeration> Foam::GAMGAgglomeration::New
FatalErrorIn FatalErrorIn
( (
"GAMGAgglomeration::New" "GAMGAgglomeration::New"
"(const lduMesh& mesh, const dictionary& controlDict)" "(const lduMesh& mesh, const scalarField&"
", const vectorField&, const dictionary& controlDict)"
) << "Unknown GAMGAgglomeration type " ) << "Unknown GAMGAgglomeration type "
<< agglomeratorType << ".\n" << agglomeratorType << ".\n"
<< "Valid geometric GAMGAgglomeration types are :" << "Valid geometric GAMGAgglomeration types are :"

View File

@ -61,14 +61,6 @@ protected:
// Protected Member Functions // Protected Member Functions
//- Calculate and return agglomeration of given level
tmp<labelField> agglomerate
(
label& nCoarseCells,
const lduAddressing& fineMatrixAddressing,
const scalarField& faceWeights
);
//- Agglomerate all levels starting from the given face weights //- Agglomerate all levels starting from the given face weights
void agglomerate void agglomerate
( (
@ -97,6 +89,15 @@ public:
const lduMesh& mesh, const lduMesh& mesh,
const dictionary& controlDict const dictionary& controlDict
); );
//- Calculate and return agglomeration
static tmp<labelField> agglomerate
(
label& nCoarseCells,
const lduAddressing& fineMatrixAddressing,
const scalarField& faceWeights
);
}; };

View File

@ -0,0 +1,333 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2013 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 "procFacesGAMGProcAgglomeration.H"
#include "addToRunTimeSelectionTable.H"
#include "GAMGAgglomeration.H"
#include "Random.H"
#include "lduMesh.H"
#include "processorLduInterface.H"
#include "processorGAMGInterface.H"
#include "pairGAMGAgglomeration.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
defineTypeNameAndDebug(procFacesGAMGProcAgglomeration, 0);
addToRunTimeSelectionTable
(
GAMGProcAgglomeration,
procFacesGAMGProcAgglomeration,
GAMGAgglomeration
);
}
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
// Create single cell mesh
Foam::autoPtr<Foam::lduPrimitiveMesh>
Foam::procFacesGAMGProcAgglomeration::singleCellMesh
(
const label singleCellMeshComm,
const lduMesh& mesh,
scalarField& faceWeights
) const
{
// Count number of faces per processor
List<Map<label> > procFaces(UPstream::nProcs(mesh.comm()));
Map<label>& myNeighbours = procFaces[UPstream::myProcNo(mesh.comm())];
{
const lduInterfacePtrsList interfaces(mesh.interfaces());
forAll(interfaces, intI)
{
if (interfaces.set(intI))
{
const processorLduInterface& pp =
refCast<const processorLduInterface>
(
interfaces[intI]
);
label size = interfaces[intI].faceCells().size();
myNeighbours.insert(pp.neighbProcNo(), size);
}
}
}
Pstream::gatherList(procFaces, Pstream::msgType(), mesh.comm());
Pstream::scatterList(procFaces, Pstream::msgType(), mesh.comm());
autoPtr<lduPrimitiveMesh> singleCellMeshPtr;
if (Pstream::master(mesh.comm()))
{
// I am master
label nCells = Pstream::nProcs(mesh.comm());
DynamicList<label> l(3*nCells);
DynamicList<label> u(3*nCells);
DynamicList<scalar> weight(3*nCells);
DynamicList<label> nbrs;
DynamicList<scalar> weights;
forAll(procFaces, procI)
{
const Map<label>& neighbours = procFaces[procI];
// Add all the higher processors
nbrs.clear();
weights.clear();
forAllConstIter(Map<label>, neighbours, iter)
{
if (iter.key() > procI)
{
nbrs.append(iter.key());
weights.append(iter());
}
sort(nbrs);
forAll(nbrs, i)
{
l.append(procI);
u.append(nbrs[i]);
weight.append(weights[i]);
}
}
}
faceWeights.transfer(weight);
PtrList<const lduInterface> primitiveInterfaces(0);
const lduSchedule ps(0);
singleCellMeshPtr.reset
(
new lduPrimitiveMesh
(
nCells,
l,
u,
primitiveInterfaces,
ps,
singleCellMeshComm
)
);
}
return singleCellMeshPtr;
}
Foam::tmp<Foam::labelField>
Foam::procFacesGAMGProcAgglomeration::processorAgglomeration
(
const lduMesh& mesh
) const
{
label singleCellMeshComm = UPstream::allocateCommunicator
(
mesh.comm(),
labelList(1, 0) // only processor 0
);
scalarField faceWeights;
autoPtr<lduPrimitiveMesh> singleCellMeshPtr
(
singleCellMesh
(
singleCellMeshComm,
mesh,
faceWeights
)
);
tmp<labelField> tfineToCoarse(new labelField(0));
labelField& fineToCoarse = tfineToCoarse();
if (singleCellMeshPtr.valid())
{
// On master call the agglomerator
const lduPrimitiveMesh& singleCellMesh = singleCellMeshPtr();
label nCoarseProcs;
fineToCoarse = pairGAMGAgglomeration::agglomerate
(
nCoarseProcs,
singleCellMesh,
faceWeights
);
labelList coarseToMaster(nCoarseProcs, labelMax);
forAll(fineToCoarse, cellI)
{
label coarseI = fineToCoarse[cellI];
coarseToMaster[coarseI] = min(coarseToMaster[coarseI], cellI);
}
// Sort according to master and redo restriction
labelList newToOld;
sortedOrder(coarseToMaster, newToOld);
labelList oldToNew(invert(newToOld.size(), newToOld));
fineToCoarse = UIndirectList<label>(oldToNew, fineToCoarse)();
}
Pstream::scatter(fineToCoarse, Pstream::msgType(), mesh.comm());
UPstream::freeCommunicator(singleCellMeshComm);
return tfineToCoarse;
}
bool Foam::procFacesGAMGProcAgglomeration::doProcessorAgglomeration
(
const lduMesh& mesh
) const
{
// Check the need for further agglomeration on all processors
bool doAgg = mesh.lduAddr().size() < nAgglomeratingCells_;
mesh.reduce(doAgg, orOp<bool>());
return doAgg;
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::procFacesGAMGProcAgglomeration::procFacesGAMGProcAgglomeration
(
GAMGAgglomeration& agglom,
const dictionary& controlDict
)
:
GAMGProcAgglomeration(agglom, controlDict),
nAgglomeratingCells_(readLabel(controlDict.lookup("nAgglomeratingCells")))
{}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::procFacesGAMGProcAgglomeration::~procFacesGAMGProcAgglomeration()
{
forAllReverse(comms_, i)
{
if (comms_[i] != -1)
{
UPstream::freeCommunicator(comms_[i]);
}
}
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
bool Foam::procFacesGAMGProcAgglomeration::agglomerate()
{
if (debug)
{
Pout<< nl << "Starting mesh overview" << endl;
printStats(Pout, agglom_);
}
if (agglom_.size() >= 1)
{
Random rndGen(0);
for
(
label fineLevelIndex = 2;
fineLevelIndex < agglom_.size();
fineLevelIndex++
)
{
if (agglom_.hasMeshLevel(fineLevelIndex))
{
// Get the fine mesh
const lduMesh& levelMesh = agglom_.meshLevel(fineLevelIndex);
label levelComm = levelMesh.comm();
label nProcs = UPstream::nProcs(levelComm);
if (nProcs > 1 && doProcessorAgglomeration(levelMesh))
{
tmp<labelField> tprocAgglomMap
(
processorAgglomeration(levelMesh)
);
const labelField& procAgglomMap = tprocAgglomMap();
// Master processor
labelList masterProcs;
// Local processors that agglomerate. agglomProcIDs[0] is in
// masterProc.
List<int> agglomProcIDs;
GAMGAgglomeration::calculateRegionMaster
(
levelComm,
procAgglomMap,
masterProcs,
agglomProcIDs
);
// Allocate a communicator for the processor-agglomerated
// matrix
comms_.append
(
UPstream::allocateCommunicator
(
levelComm,
masterProcs
)
);
// Use procesor agglomeration maps to do the actual
// collecting.
GAMGProcAgglomeration::agglomerate
(
fineLevelIndex,
procAgglomMap,
masterProcs,
agglomProcIDs,
comms_.last()
);
}
}
}
}
// Print a bit
if (debug)
{
Pout<< nl << "Agglomerated mesh overview" << endl;
printStats(Pout, agglom_);
}
return true;
}
// ************************************************************************* //

View File

@ -0,0 +1,136 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2013 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::procFacesGAMGProcAgglomeration
Description
Processor agglomeration of GAMGAgglomerations. Needs nAgglomeratingCells
which is when to start agglomerating processors. Processors get agglomerated
by constructing a single cell mesh for each processor with each
processor interface a face. This then gets agglomerated using
the pairGAMGAgglomeration algorithm with the number of faces
on the original processor interface as face weight.
SourceFiles
procFacesGAMGProcAgglomeration.C
\*---------------------------------------------------------------------------*/
#ifndef procFacesGAMGProcAgglomeration_H
#define procFacesGAMGProcAgglomeration_H
#include "GAMGProcAgglomeration.H"
#include "DynamicList.H"
#include "labelField.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
class GAMGAgglomeration;
class lduMesh;
class lduPrimitiveMesh;
/*---------------------------------------------------------------------------*\
Class procFacesGAMGProcAgglomeration Declaration
\*---------------------------------------------------------------------------*/
class procFacesGAMGProcAgglomeration
:
public GAMGProcAgglomeration
{
// Private data
//- When to processor agglomerate
const label nAgglomeratingCells_;
//- Allocated communicators
DynamicList<label> comms_;
// Private Member Functions
//- Return (on master) all single-cell meshes collected. single-cell
// meshes are just one cell with all proc faces intact.
autoPtr<lduPrimitiveMesh> singleCellMesh
(
const label singleCellMeshComm,
const lduMesh& mesh,
scalarField& faceWeights
) const;
//- Construct processor agglomeration: for every processor the
// coarse processor-cluster it agglomerates onto
tmp<labelField> processorAgglomeration(const lduMesh&) const;
//- Do we need to agglomerate across processors?
bool doProcessorAgglomeration(const lduMesh&) const;
//- Disallow default bitwise copy construct
procFacesGAMGProcAgglomeration
(
const procFacesGAMGProcAgglomeration&
);
//- Disallow default bitwise assignment
void operator=(const procFacesGAMGProcAgglomeration&);
public:
//- Runtime type information
TypeName("procFaces");
// Constructors
//- Construct given agglomerator and controls
procFacesGAMGProcAgglomeration
(
GAMGAgglomeration& agglom,
const dictionary& controlDict
);
//- Destructor
virtual ~procFacesGAMGProcAgglomeration();
// Member Functions
//- Modify agglomeration. Return true if modified
virtual bool agglomerate();
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -2,7 +2,7 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2011 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -67,6 +67,10 @@ public:
// setting the arguments pointer to NULL // setting the arguments pointer to NULL
inline autoPtr(const autoPtr<T>&); inline autoPtr(const autoPtr<T>&);
//- Construct either by transfering pointer or cloning. Should
// only be called with type that supports cloning.
inline autoPtr(const autoPtr<T>&, const bool reUse);
//- Destructor, delete object if pointer is not NULL //- Destructor, delete object if pointer is not NULL
inline ~autoPtr(); inline ~autoPtr();

View File

@ -2,7 +2,7 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2011 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -24,6 +24,7 @@ License
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#include "error.H" #include "error.H"
#include <typeinfo>
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
@ -43,6 +44,21 @@ inline Foam::autoPtr<T>::autoPtr(const autoPtr<T>& ap)
} }
template<class T>
inline Foam::autoPtr<T>::autoPtr(const autoPtr<T>& ap, const bool reUse)
{
if (reUse)
{
ptr_ = ap.ptr_;
ap.ptr_ = 0;
}
else
{
ptr_ = ap().clone().ptr();
}
}
template<class T> template<class T>
inline Foam::autoPtr<T>::~autoPtr() inline Foam::autoPtr<T>::~autoPtr()
{ {
@ -81,7 +97,8 @@ inline void Foam::autoPtr<T>::set(T* p)
if (ptr_) if (ptr_)
{ {
FatalErrorIn("void Foam::autoPtr<T>::set(T*)") FatalErrorIn("void Foam::autoPtr<T>::set(T*)")
<< "object already allocated" << "object of type " << typeid(T).name()
<< " already allocated"
<< abort(FatalError); << abort(FatalError);
} }
@ -116,7 +133,8 @@ inline T& Foam::autoPtr<T>::operator()()
if (!ptr_) if (!ptr_)
{ {
FatalErrorIn("T& Foam::autoPtr<T>::operator()()") FatalErrorIn("T& Foam::autoPtr<T>::operator()()")
<< "object is not allocated" << "object of type " << typeid(T).name()
<< " is not allocated"
<< abort(FatalError); << abort(FatalError);
} }
@ -130,7 +148,8 @@ inline const T& Foam::autoPtr<T>::operator()() const
if (!ptr_) if (!ptr_)
{ {
FatalErrorIn("const T& Foam::autoPtr<T>::operator()() const") FatalErrorIn("const T& Foam::autoPtr<T>::operator()() const")
<< "object is not allocated" << "object of type " << typeid(T).name()
<< " is not allocated"
<< abort(FatalError); << abort(FatalError);
} }
@ -151,7 +170,8 @@ inline T* Foam::autoPtr<T>::operator->()
if (!ptr_) if (!ptr_)
{ {
FatalErrorIn("Foam::autoPtr<T>::operator->()") FatalErrorIn("Foam::autoPtr<T>::operator->()")
<< "object is not allocated" << "object of type " << typeid(T).name()
<< " is not allocated"
<< abort(FatalError); << abort(FatalError);
} }

View File

@ -2,7 +2,7 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -24,6 +24,7 @@ License
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#include "error.H" #include "error.H"
#include <typeinfo>
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
@ -62,6 +63,7 @@ inline Foam::tmp<T>::tmp(const tmp<T>& t)
{ {
FatalErrorIn("Foam::tmp<T>::tmp(const tmp<T>&)") FatalErrorIn("Foam::tmp<T>::tmp(const tmp<T>&)")
<< "attempted copy of a deallocated temporary" << "attempted copy of a deallocated temporary"
<< " of type " << typeid(T).name()
<< abort(FatalError); << abort(FatalError);
} }
} }
@ -93,6 +95,7 @@ inline Foam::tmp<T>::tmp(const tmp<T>& t, bool allowTransfer)
( (
"Foam::tmp<T>::tmp(const tmp<T>&, bool allowTransfer)" "Foam::tmp<T>::tmp(const tmp<T>&, bool allowTransfer)"
) << "attempted copy of a deallocated temporary" ) << "attempted copy of a deallocated temporary"
<< " of type " << typeid(T).name()
<< abort(FatalError); << abort(FatalError);
} }
} }
@ -149,7 +152,7 @@ inline T* Foam::tmp<T>::ptr() const
if (!ptr_) if (!ptr_)
{ {
FatalErrorIn("Foam::tmp<T>::ptr() const") FatalErrorIn("Foam::tmp<T>::ptr() const")
<< "temporary deallocated" << "temporary of type " << typeid(T).name() << " deallocated"
<< abort(FatalError); << abort(FatalError);
} }
@ -188,7 +191,7 @@ inline T& Foam::tmp<T>::operator()()
if (!ptr_) if (!ptr_)
{ {
FatalErrorIn("T& Foam::tmp<T>::operator()()") FatalErrorIn("T& Foam::tmp<T>::operator()()")
<< "temporary deallocated" << "temporary of type " << typeid(T).name() << " deallocated"
<< abort(FatalError); << abort(FatalError);
} }
@ -217,7 +220,7 @@ inline const T& Foam::tmp<T>::operator()() const
if (!ptr_) if (!ptr_)
{ {
FatalErrorIn("const T& Foam::tmp<T>::operator()() const") FatalErrorIn("const T& Foam::tmp<T>::operator()() const")
<< "temporary deallocated" << "temporary of type " << typeid(T).name() << " deallocated"
<< abort(FatalError); << abort(FatalError);
} }
@ -245,7 +248,7 @@ inline T* Foam::tmp<T>::operator->()
if (!ptr_) if (!ptr_)
{ {
FatalErrorIn("Foam::tmp<T>::operator->()") FatalErrorIn("Foam::tmp<T>::operator->()")
<< "temporary deallocated" << "temporary of type " << typeid(T).name() << " deallocated"
<< abort(FatalError); << abort(FatalError);
} }
@ -294,6 +297,7 @@ inline void Foam::tmp<T>::operator=(const tmp<T>& t)
{ {
FatalErrorIn("Foam::tmp<T>::operator=(const tmp<T>&)") FatalErrorIn("Foam::tmp<T>::operator=(const tmp<T>&)")
<< "attempted copy of a deallocated temporary" << "attempted copy of a deallocated temporary"
<< " of type " << typeid(T).name()
<< abort(FatalError); << abort(FatalError);
} }
} }
@ -301,6 +305,7 @@ inline void Foam::tmp<T>::operator=(const tmp<T>& t)
{ {
FatalErrorIn("Foam::tmp<T>::operator=(const tmp<T>&)") FatalErrorIn("Foam::tmp<T>::operator=(const tmp<T>&)")
<< "attempted to assign to a const reference to constant object" << "attempted to assign to a const reference to constant object"
<< " of type " << typeid(T).name()
<< abort(FatalError); << abort(FatalError);
} }
} }

View File

@ -2,7 +2,7 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation \\ / A nd | Copyright (C) 2013 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License

View File

@ -254,7 +254,7 @@ Foam::lduPrimitiveMesh::lduPrimitiveMesh
const label nCells, const label nCells,
labelList& l, labelList& l,
labelList& u, labelList& u,
const Xfer<PtrList<const lduInterface> >& primitiveInterfaces, PtrList<const lduInterface>& primitiveInterfaces,
const lduSchedule& ps, const lduSchedule& ps,
const label comm const label comm
) )
@ -262,10 +262,12 @@ Foam::lduPrimitiveMesh::lduPrimitiveMesh
lduAddressing(nCells), lduAddressing(nCells),
lowerAddr_(l, true), lowerAddr_(l, true),
upperAddr_(u, true), upperAddr_(u, true),
primitiveInterfaces_(primitiveInterfaces), primitiveInterfaces_(0),
patchSchedule_(ps), patchSchedule_(ps),
comm_(comm) comm_(comm)
{ {
primitiveInterfaces_.transfer(primitiveInterfaces);
// Create interfaces // Create interfaces
interfaces_.setSize(primitiveInterfaces_.size()); interfaces_.setSize(primitiveInterfaces_.size());
forAll(primitiveInterfaces_, i) forAll(primitiveInterfaces_, i)

View File

@ -133,7 +133,7 @@ public:
const label nCells, const label nCells,
labelList& l, labelList& l,
labelList& u, labelList& u,
const Xfer<PtrList<const lduInterface> >& primitiveInterfaces, PtrList<const lduInterface>& primitiveInterfaces,
const lduSchedule& ps, const lduSchedule& ps,
const label comm const label comm
); );

View File

@ -2,7 +2,7 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2011 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -58,6 +58,12 @@ Foam::pointBoundaryMesh::pointBoundaryMesh
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
Foam::label Foam::pointBoundaryMesh::findPatchID(const word& patchName) const
{
return mesh()().boundaryMesh().findPatchID(patchName);
}
Foam::labelList Foam::pointBoundaryMesh::findIndices Foam::labelList Foam::pointBoundaryMesh::findIndices
( (
const keyType& key, const keyType& key,

View File

@ -2,7 +2,7 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2011 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -96,6 +96,9 @@ public:
return mesh_; return mesh_;
} }
//- Find patch index given a name
label findPatchID(const word& patchName) const;
//- Find patch indices given a name //- Find patch indices given a name
labelList findIndices(const keyType&, const bool useGroups) const; labelList findIndices(const keyType&, const bool useGroups) const;

View File

@ -97,7 +97,6 @@ Foam::tmp<Foam::scalarField> Foam::polyMeshTools::faceSkewness
{ {
const labelList& own = mesh.faceOwner(); const labelList& own = mesh.faceOwner();
const labelList& nei = mesh.faceNeighbour(); const labelList& nei = mesh.faceNeighbour();
const faceList& fcs = mesh.faces();
const polyBoundaryMesh& pbm = mesh.boundaryMesh(); const polyBoundaryMesh& pbm = mesh.boundaryMesh();
tmp<scalarField> tskew(new scalarField(mesh.nFaces())); tmp<scalarField> tskew(new scalarField(mesh.nFaces()));
@ -154,31 +153,16 @@ Foam::tmp<Foam::scalarField> Foam::polyMeshTools::faceSkewness
{ {
label faceI = pp.start() + i; label faceI = pp.start() + i;
vector Cpf = fCtrs[faceI] - cellCtrs[own[faceI]]; skew[faceI] = primitiveMeshTools::boundaryFaceSkewness
(
mesh,
p,
fCtrs,
fAreas,
vector normal = fAreas[faceI]; faceI,
normal /= mag(normal) + VSMALL; cellCtrs[own[faceI]]
vector d = normal*(normal & Cpf); );
// Skewness vector
vector sv =
Cpf
- ((fAreas[faceI] & Cpf)/((fAreas[faceI] & d) + VSMALL))*d;
vector svHat = sv/(mag(sv) + VSMALL);
// Normalisation distance calculated as the approximate distance
// from the face centre to the edge of the face in the direction
// of the skewness
scalar fd = 0.4*mag(d) + VSMALL;
const face& f = fcs[faceI];
forAll(f, pi)
{
fd = max(fd, mag(svHat & (p[f[pi]] - fCtrs[faceI])));
}
// Normalised skewness
skew[faceI] = mag(sv)/fd;
} }
} }
} }

View File

@ -54,14 +54,12 @@ Foam::processorPolyPatch::processorPolyPatch
const label start, const label start,
const label index, const label index,
const polyBoundaryMesh& bm, const polyBoundaryMesh& bm,
const label comm,
const int myProcNo, const int myProcNo,
const int neighbProcNo, const int neighbProcNo,
const transformType transform const transformType transform
) )
: :
coupledPolyPatch(name, size, start, index, bm, typeName, transform), coupledPolyPatch(name, size, start, index, bm, typeName, transform),
// comm_(comm),
myProcNo_(myProcNo), myProcNo_(myProcNo),
neighbProcNo_(neighbProcNo), neighbProcNo_(neighbProcNo),
neighbFaceCentres_(), neighbFaceCentres_(),
@ -80,10 +78,6 @@ Foam::processorPolyPatch::processorPolyPatch
) )
: :
coupledPolyPatch(name, dict, index, bm, patchType), coupledPolyPatch(name, dict, index, bm, patchType),
// comm_
// (
// dict.lookupOrDefault("communicator", UPstream::worldComm)
// ),
myProcNo_(readLabel(dict.lookup("myProcNo"))), myProcNo_(readLabel(dict.lookup("myProcNo"))),
neighbProcNo_(readLabel(dict.lookup("neighbProcNo"))), neighbProcNo_(readLabel(dict.lookup("neighbProcNo"))),
neighbFaceCentres_(), neighbFaceCentres_(),
@ -99,7 +93,6 @@ Foam::processorPolyPatch::processorPolyPatch
) )
: :
coupledPolyPatch(pp, bm), coupledPolyPatch(pp, bm),
// comm_(pp.comm_),
myProcNo_(pp.myProcNo_), myProcNo_(pp.myProcNo_),
neighbProcNo_(pp.neighbProcNo_), neighbProcNo_(pp.neighbProcNo_),
neighbFaceCentres_(), neighbFaceCentres_(),
@ -118,7 +111,6 @@ Foam::processorPolyPatch::processorPolyPatch
) )
: :
coupledPolyPatch(pp, bm, index, newSize, newStart), coupledPolyPatch(pp, bm, index, newSize, newStart),
// comm_(pp.comm_),
myProcNo_(pp.myProcNo_), myProcNo_(pp.myProcNo_),
neighbProcNo_(pp.neighbProcNo_), neighbProcNo_(pp.neighbProcNo_),
neighbFaceCentres_(), neighbFaceCentres_(),
@ -137,7 +129,6 @@ Foam::processorPolyPatch::processorPolyPatch
) )
: :
coupledPolyPatch(pp, bm, index, mapAddressing, newStart), coupledPolyPatch(pp, bm, index, mapAddressing, newStart),
// comm_(pp.comm_),
myProcNo_(pp.myProcNo_), myProcNo_(pp.myProcNo_),
neighbProcNo_(pp.neighbProcNo_), neighbProcNo_(pp.neighbProcNo_),
neighbFaceCentres_(), neighbFaceCentres_(),
@ -1091,11 +1082,6 @@ bool Foam::processorPolyPatch::order
void Foam::processorPolyPatch::write(Ostream& os) const void Foam::processorPolyPatch::write(Ostream& os) const
{ {
coupledPolyPatch::write(os); coupledPolyPatch::write(os);
// if (comm_ != UPstream::worldComm)
// {
// os.writeKeyword("communicator") << comm_
// << token::END_STATEMENT << nl;
// }
os.writeKeyword("myProcNo") << myProcNo_ os.writeKeyword("myProcNo") << myProcNo_
<< token::END_STATEMENT << nl; << token::END_STATEMENT << nl;
os.writeKeyword("neighbProcNo") << neighbProcNo_ os.writeKeyword("neighbProcNo") << neighbProcNo_

View File

@ -134,7 +134,6 @@ public:
const label start, const label start,
const label index, const label index,
const polyBoundaryMesh& bm, const polyBoundaryMesh& bm,
const label comm,
const int myProcNo, const int myProcNo,
const int neighbProcNo, const int neighbProcNo,
const transformType transform = UNKNOWN // transformation type const transformType transform = UNKNOWN // transformation type

View File

@ -46,7 +46,6 @@ Foam::processorCyclicPolyPatch::processorCyclicPolyPatch
const label start, const label start,
const label index, const label index,
const polyBoundaryMesh& bm, const polyBoundaryMesh& bm,
const label comm,
const int myProcNo, const int myProcNo,
const int neighbProcNo, const int neighbProcNo,
const word& referPatchName, const word& referPatchName,
@ -60,7 +59,6 @@ Foam::processorCyclicPolyPatch::processorCyclicPolyPatch
start, start,
index, index,
bm, bm,
comm,
myProcNo, myProcNo,
neighbProcNo, neighbProcNo,
transform transform

View File

@ -119,7 +119,6 @@ public:
const label start, const label start,
const label index, const label index,
const polyBoundaryMesh& bm, const polyBoundaryMesh& bm,
const label comm,
const int myProcNo, const int myProcNo,
const int neighbProcNo, const int neighbProcNo,
const word& referPatchName, const word& referPatchName,

View File

@ -2,7 +2,7 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2012 OpenFOAM Foundation \\ / A nd | Copyright (C) 2012-2013 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -64,6 +64,44 @@ Foam::scalar Foam::primitiveMeshTools::faceSkewness
return mag(sv)/fd; return mag(sv)/fd;
} }
Foam::scalar Foam::primitiveMeshTools::boundaryFaceSkewness
(
const primitiveMesh& mesh,
const pointField& p,
const vectorField& fCtrs,
const vectorField& fAreas,
const label faceI,
const point& ownCc
)
{
vector Cpf = fCtrs[faceI] - ownCc;
vector normal = fAreas[faceI];
normal /= mag(normal) + VSMALL;
vector d = normal*(normal & Cpf);
// Skewness vector
vector sv =
Cpf
- ((fAreas[faceI] & Cpf)/((fAreas[faceI] & d) + VSMALL))*d;
vector svHat = sv/(mag(sv) + VSMALL);
// Normalisation distance calculated as the approximate distance
// from the face centre to the edge of the face in the direction
// of the skewness
scalar fd = 0.4*mag(d) + VSMALL;
const face& f = mesh.faces()[faceI];
forAll(f, pi)
{
fd = max(fd, mag(svHat & (p[f[pi]] - fCtrs[faceI])));
}
// Normalised skewness
return mag(sv)/fd;
}
Foam::scalar Foam::primitiveMeshTools::faceOrthogonality Foam::scalar Foam::primitiveMeshTools::faceOrthogonality
( (
@ -119,7 +157,6 @@ Foam::tmp<Foam::scalarField> Foam::primitiveMeshTools::faceSkewness
{ {
const labelList& own = mesh.faceOwner(); const labelList& own = mesh.faceOwner();
const labelList& nei = mesh.faceNeighbour(); const labelList& nei = mesh.faceNeighbour();
const faceList& fcs = mesh.faces();
tmp<scalarField> tskew(new scalarField(mesh.nFaces())); tmp<scalarField> tskew(new scalarField(mesh.nFaces()));
scalarField& skew = tskew(); scalarField& skew = tskew();
@ -145,31 +182,15 @@ Foam::tmp<Foam::scalarField> Foam::primitiveMeshTools::faceSkewness
for (label faceI = mesh.nInternalFaces(); faceI < mesh.nFaces(); faceI++) for (label faceI = mesh.nInternalFaces(); faceI < mesh.nFaces(); faceI++)
{ {
vector Cpf = fCtrs[faceI] - cellCtrs[own[faceI]]; skew[faceI] = boundaryFaceSkewness
(
vector normal = fAreas[faceI]; mesh,
normal /= mag(normal) + VSMALL; p,
vector d = normal*(normal & Cpf); fCtrs,
fAreas,
faceI,
// Skewness vector cellCtrs[own[faceI]]
vector sv = );
Cpf
- ((fAreas[faceI] & Cpf)/((fAreas[faceI] & d) + VSMALL))*d;
vector svHat = sv/(mag(sv) + VSMALL);
// Normalisation distance calculated as the approximate distance
// from the face centre to the edge of the face in the direction
// of the skewness
scalar fd = 0.4*mag(d) + VSMALL;
const face& f = fcs[faceI];
forAll(f, pi)
{
fd = max(fd, mag(svHat & (p[f[pi]] - fCtrs[faceI])));
}
// Normalised skewness
skew[faceI] = mag(sv)/fd;
} }
return tskew; return tskew;

View File

@ -2,7 +2,7 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2012 OpenFOAM Foundation \\ / A nd | Copyright (C) 2012-2013 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -48,32 +48,6 @@ namespace Foam
class primitiveMeshTools class primitiveMeshTools
{ {
protected:
// Protected Member Functions
//- Skewness of single face
static scalar faceSkewness
(
const primitiveMesh& mesh,
const pointField& p,
const vectorField& fCtrs,
const vectorField& fAreas,
const label faceI,
const point& ownCc,
const point& neiCc
);
//- Orthogonality of single face
static scalar faceOrthogonality
(
const point& ownCc,
const point& neiCc,
const vector& s
);
public: public:
//- Generate non-orthogonality field (internal faces only) //- Generate non-orthogonality field (internal faces only)
@ -154,6 +128,41 @@ public:
const PackedBoolList& internalOrCoupledFace const PackedBoolList& internalOrCoupledFace
); );
// Helpers: single face check
//- Skewness of single face
static scalar faceSkewness
(
const primitiveMesh& mesh,
const pointField& p,
const vectorField& fCtrs,
const vectorField& fAreas,
const label faceI,
const point& ownCc,
const point& neiCc
);
//- Skewness of single boundary face
static scalar boundaryFaceSkewness
(
const primitiveMesh& mesh,
const pointField& p,
const vectorField& fCtrs,
const vectorField& fAreas,
const label faceI,
const point& ownCc
);
//- Orthogonality of single face
static scalar faceOrthogonality
(
const point& ownCc,
const point& neiCc,
const vector& s
);
}; };

View File

@ -2,7 +2,7 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -142,9 +142,6 @@ public:
virtual void convertTimeBase(const Time& t); virtual void convertTimeBase(const Time& t);
public:
// Evaluation // Evaluation
//- Return value as a function of (scalar) independent variable //- Return value as a function of (scalar) independent variable
@ -172,14 +169,15 @@ public:
const scalarField& x const scalarField& x
) const; ) const;
//- Integrate between two scalars and returns a dimensioned type //- Integrate between two scalars and return a dimensioned type
virtual dimensioned<Type> dimIntegrate virtual dimensioned<Type> dimIntegrate
( (
const scalar x1, const scalar x1,
const scalar x2 const scalar x2
) const; ) const;
//- Integrate between two scalars and returns list of dimensioned type //- Integrate between two scalar fields and return a field of
// dimensioned type
virtual tmp<Field<dimensioned<Type> > > dimIntegrate virtual tmp<Field<dimensioned<Type> > > dimIntegrate
( (
const scalarField& x1, const scalarField& x1,

View File

@ -2,7 +2,7 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2012 OpenFOAM Foundation \\ / A nd | Copyright (C) 2012-2013 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -38,12 +38,17 @@ namespace Foam
} }
void Foam::printTable(const List<wordList>& wll, Ostream& os) void Foam::printTable
(
const List<wordList>& wll,
List<string::size_type>& columnWidth,
Ostream& os
)
{ {
if (!wll.size()) return; if (!wll.size()) return;
// Find the maximum word length for each column // Find the maximum word length for each column
List<string::size_type> columnWidth(wll[0].size(), string::size_type(0)); columnWidth.setSize(wll[0].size(), string::size_type(0));
forAll(columnWidth, j) forAll(columnWidth, j)
{ {
forAll(wll, i) forAll(wll, i)
@ -75,4 +80,11 @@ void Foam::printTable(const List<wordList>& wll, Ostream& os)
} }
void Foam::printTable(const List<wordList>& wll, Ostream& os)
{
List<string::size_type> columnWidth;
printTable(wll, columnWidth, os);
}
// ************************************************************************* // // ************************************************************************* //

View File

@ -2,7 +2,7 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2012 OpenFOAM Foundation \\ / A nd | Copyright (C) 2012-2013 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -43,6 +43,7 @@ namespace Foam
typedef IOList<wordList> wordListIOList; typedef IOList<wordList> wordListIOList;
// Print word list list as a table // Print word list list as a table
void printTable(const List<wordList>&, List<string::size_type>&, Ostream&);
void printTable(const List<wordList>&, Ostream&); void printTable(const List<wordList>&, Ostream&);
} }

View File

@ -945,7 +945,6 @@ void Foam::fvMeshDistribute::addProcPatches
mesh_.nFaces(), mesh_.nFaces(),
mesh_.boundaryMesh().size(), mesh_.boundaryMesh().size(),
mesh_.boundaryMesh(), mesh_.boundaryMesh(),
Pstream::worldComm,
Pstream::myProcNo(), Pstream::myProcNo(),
nbrProc[bFaceI] nbrProc[bFaceI]
); );
@ -989,7 +988,6 @@ void Foam::fvMeshDistribute::addProcPatches
mesh_.nFaces(), mesh_.nFaces(),
mesh_.boundaryMesh().size(), mesh_.boundaryMesh().size(),
mesh_.boundaryMesh(), mesh_.boundaryMesh(),
Pstream::worldComm,
Pstream::myProcNo(), Pstream::myProcNo(),
nbrProc[bFaceI], nbrProc[bFaceI],
cycName, cycName,

View File

@ -2,7 +2,7 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -239,6 +239,7 @@ bool Foam::motionSmoother::checkMesh
maxIntSkew, maxIntSkew,
maxBounSkew, maxBounSkew,
mesh, mesh,
mesh.points(),
mesh.cellCentres(), mesh.cellCentres(),
mesh.faceCentres(), mesh.faceCentres(),
mesh.faceAreas(), mesh.faceAreas(),
@ -481,14 +482,14 @@ bool Foam::motionSmoother::checkMesh
( (
readScalar(dict.lookup("minArea", true)) readScalar(dict.lookup("minArea", true))
); );
const scalar maxIntSkew //const scalar maxIntSkew
( //(
readScalar(dict.lookup("maxInternalSkewness", true)) // readScalar(dict.lookup("maxInternalSkewness", true))
); //);
const scalar maxBounSkew //const scalar maxBounSkew
( //(
readScalar(dict.lookup("maxBoundarySkewness", true)) // readScalar(dict.lookup("maxBoundarySkewness", true))
); //);
const scalar minWeight const scalar minWeight
( (
readScalar(dict.lookup("minFaceWeight", true)) readScalar(dict.lookup("minFaceWeight", true))
@ -615,27 +616,30 @@ bool Foam::motionSmoother::checkMesh
nWrongFaces = nNewWrongFaces; nWrongFaces = nNewWrongFaces;
} }
if (maxIntSkew > 0 || maxBounSkew > 0)
{
meshGeom.checkFaceSkewness
(
report,
maxIntSkew,
maxBounSkew,
checkFaces,
baffles,
&wrongFaces
);
label nNewWrongFaces = returnReduce(wrongFaces.size(), sumOp<label>()); //- Note: cannot check the skewness without the points and don't want
// to store them on polyMeshGeometry.
Info<< " faces with skewness > " //if (maxIntSkew > 0 || maxBounSkew > 0)
<< setw(3) << maxIntSkew //{
<< " (internal) or " << setw(3) << maxBounSkew // meshGeom.checkFaceSkewness
<< " (boundary) : " << nNewWrongFaces-nWrongFaces << endl; // (
// report,
nWrongFaces = nNewWrongFaces; // maxIntSkew,
} // maxBounSkew,
// checkFaces,
// baffles,
// &wrongFaces
// );
//
// label nNewWrongFaces = returnReduce(wrongFaces.size(),sumOp<label>());
//
// Info<< " faces with skewness > "
// << setw(3) << maxIntSkew
// << " (internal) or " << setw(3) << maxBounSkew
// << " (boundary) : " << nNewWrongFaces-nWrongFaces << endl;
//
// nWrongFaces = nNewWrongFaces;
//}
if (minWeight >= 0 && minWeight < 1) if (minWeight >= 0 && minWeight < 1)
{ {

View File

@ -29,6 +29,7 @@ License
#include "tetrahedron.H" #include "tetrahedron.H"
#include "syncTools.H" #include "syncTools.H"
#include "unitConversion.H" #include "unitConversion.H"
#include "primitiveMeshTools.H"
namespace Foam namespace Foam
{ {
@ -286,29 +287,6 @@ Foam::scalar Foam::polyMeshGeometry::checkNonOrtho
} }
Foam::scalar Foam::polyMeshGeometry::calcSkewness
(
const point& ownCc,
const point& neiCc,
const point& fc
)
{
scalar dOwn = mag(fc - ownCc);
scalar dNei = mag(fc - neiCc);
point faceIntersection =
ownCc*dNei/(dOwn+dNei+VSMALL)
+ neiCc*dOwn/(dOwn+dNei+VSMALL);
return
mag(fc - faceIntersection)
/ (
mag(neiCc-ownCc)
+ VSMALL
);
}
// Create the neighbour pyramid - it will have positive volume // Create the neighbour pyramid - it will have positive volume
bool Foam::polyMeshGeometry::checkFaceTet bool Foam::polyMeshGeometry::checkFaceTet
( (
@ -1008,6 +986,7 @@ bool Foam::polyMeshGeometry::checkFaceSkewness
const scalar internalSkew, const scalar internalSkew,
const scalar boundarySkew, const scalar boundarySkew,
const polyMesh& mesh, const polyMesh& mesh,
const pointField& points,
const vectorField& cellCentres, const vectorField& cellCentres,
const vectorField& faceCentres, const vectorField& faceCentres,
const vectorField& faceAreas, const vectorField& faceAreas,
@ -1024,14 +1003,8 @@ bool Foam::polyMeshGeometry::checkFaceSkewness
const polyBoundaryMesh& patches = mesh.boundaryMesh(); const polyBoundaryMesh& patches = mesh.boundaryMesh();
// Calculate coupled cell centre // Calculate coupled cell centre
pointField neiCc(mesh.nFaces()-mesh.nInternalFaces()); pointField neiCc;
syncTools::swapBoundaryCellPositions(mesh, cellCentres, neiCc);
for (label faceI = mesh.nInternalFaces(); faceI < mesh.nFaces(); faceI++)
{
neiCc[faceI-mesh.nInternalFaces()] = cellCentres[own[faceI]];
}
syncTools::swapBoundaryFacePositions(mesh, neiCc);
scalar maxSkew = 0; scalar maxSkew = 0;
@ -1043,11 +1016,16 @@ bool Foam::polyMeshGeometry::checkFaceSkewness
if (mesh.isInternalFace(faceI)) if (mesh.isInternalFace(faceI))
{ {
scalar skewness = calcSkewness scalar skewness = primitiveMeshTools::faceSkewness
( (
mesh,
points,
faceCentres,
faceAreas,
faceI,
cellCentres[own[faceI]], cellCentres[own[faceI]],
cellCentres[nei[faceI]], cellCentres[nei[faceI]]
faceCentres[faceI]
); );
// Check if the skewness vector is greater than the PN vector. // Check if the skewness vector is greater than the PN vector.
@ -1073,11 +1051,16 @@ bool Foam::polyMeshGeometry::checkFaceSkewness
} }
else if (patches[patches.whichPatch(faceI)].coupled()) else if (patches[patches.whichPatch(faceI)].coupled())
{ {
scalar skewness = calcSkewness scalar skewness = primitiveMeshTools::faceSkewness
( (
mesh,
points,
faceCentres,
faceAreas,
faceI,
cellCentres[own[faceI]], cellCentres[own[faceI]],
neiCc[faceI-mesh.nInternalFaces()], neiCc[faceI-mesh.nInternalFaces()]
faceCentres[faceI]
); );
// Check if the skewness vector is greater than the PN vector. // Check if the skewness vector is greater than the PN vector.
@ -1103,21 +1086,17 @@ bool Foam::polyMeshGeometry::checkFaceSkewness
} }
else else
{ {
// Boundary faces: consider them to have only skewness error. scalar skewness = primitiveMeshTools::boundaryFaceSkewness
// (i.e. treat as if mirror cell on other side) (
mesh,
points,
faceCentres,
faceAreas,
vector faceNormal = faceAreas[faceI]; faceI,
faceNormal /= mag(faceNormal) + ROOTVSMALL; cellCentres[own[faceI]]
);
vector dOwn = faceCentres[faceI] - cellCentres[own[faceI]];
vector dWall = faceNormal*(faceNormal & dOwn);
point faceIntersection = cellCentres[own[faceI]] + dWall;
scalar skewness =
mag(faceCentres[faceI] - faceIntersection)
/(2*mag(dWall) + ROOTVSMALL);
// Check if the skewness vector is greater than the PN vector. // Check if the skewness vector is greater than the PN vector.
// This does not cause trouble but is a good indication of a poor // This does not cause trouble but is a good indication of a poor
@ -1148,12 +1127,18 @@ bool Foam::polyMeshGeometry::checkFaceSkewness
label face1 = baffles[i].second(); label face1 = baffles[i].second();
const point& ownCc = cellCentres[own[face0]]; const point& ownCc = cellCentres[own[face0]];
const point& neiCc = cellCentres[own[face1]];
scalar skewness = calcSkewness scalar skewness = primitiveMeshTools::faceSkewness
( (
mesh,
points,
faceCentres,
faceAreas,
face0,
ownCc, ownCc,
cellCentres[own[face1]], neiCc
faceCentres[face0]
); );
// Check if the skewness vector is greater than the PN vector. // Check if the skewness vector is greater than the PN vector.
@ -2361,30 +2346,30 @@ bool Foam::polyMeshGeometry::checkFaceTets
} }
bool Foam::polyMeshGeometry::checkFaceSkewness //bool Foam::polyMeshGeometry::checkFaceSkewness
( //(
const bool report, // const bool report,
const scalar internalSkew, // const scalar internalSkew,
const scalar boundarySkew, // const scalar boundarySkew,
const labelList& checkFaces, // const labelList& checkFaces,
const List<labelPair>& baffles, // const List<labelPair>& baffles,
labelHashSet* setPtr // labelHashSet* setPtr
) const //) const
{ //{
return checkFaceSkewness // return checkFaceSkewness
( // (
report, // report,
internalSkew, // internalSkew,
boundarySkew, // boundarySkew,
mesh_, // mesh_,
cellCentres_, // cellCentres_,
faceCentres_, // faceCentres_,
faceAreas_, // faceAreas_,
checkFaces, // checkFaces,
baffles, // baffles,
setPtr // setPtr
); // );
} //}
bool Foam::polyMeshGeometry::checkFaceWeights bool Foam::polyMeshGeometry::checkFaceWeights

View File

@ -2,7 +2,7 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -229,6 +229,7 @@ public:
const scalar internalSkew, const scalar internalSkew,
const scalar boundarySkew, const scalar boundarySkew,
const polyMesh& mesh, const polyMesh& mesh,
const pointField& points,
const vectorField& cellCentres, const vectorField& cellCentres,
const vectorField& faceCentres, const vectorField& faceCentres,
const vectorField& faceAreas, const vectorField& faceAreas,
@ -372,16 +373,6 @@ public:
labelHashSet* setPtr labelHashSet* setPtr
) const; ) const;
bool checkFaceSkewness
(
const bool report,
const scalar internalSkew,
const scalar boundarySkew,
const labelList& checkFaces,
const List<labelPair>& baffles,
labelHashSet* setPtr
) const;
bool checkFaceWeights bool checkFaceWeights
( (
const bool report, const bool report,

View File

@ -18,6 +18,7 @@ $(basicFvPatches)/generic/genericFvPatch.C
constraintFvPatches = $(fvPatches)/constraint constraintFvPatches = $(fvPatches)/constraint
$(constraintFvPatches)/cyclic/cyclicFvPatch.C $(constraintFvPatches)/cyclic/cyclicFvPatch.C
$(constraintFvPatches)/cyclicAMI/cyclicAMIFvPatch.C $(constraintFvPatches)/cyclicAMI/cyclicAMIFvPatch.C
$(constraintFvPatches)/cyclicACMI/cyclicACMIFvPatch.C
$(constraintFvPatches)/cyclicSlip/cyclicSlipFvPatch.C $(constraintFvPatches)/cyclicSlip/cyclicSlipFvPatch.C
$(constraintFvPatches)/empty/emptyFvPatch.C $(constraintFvPatches)/empty/emptyFvPatch.C
$(constraintFvPatches)/nonuniformTransformCyclic/nonuniformTransformCyclicFvPatch.C $(constraintFvPatches)/nonuniformTransformCyclic/nonuniformTransformCyclicFvPatch.C
@ -109,6 +110,7 @@ $(basicFvPatchFields)/zeroGradient/zeroGradientFvPatchFields.C
constraintFvPatchFields = $(fvPatchFields)/constraint constraintFvPatchFields = $(fvPatchFields)/constraint
$(constraintFvPatchFields)/cyclic/cyclicFvPatchFields.C $(constraintFvPatchFields)/cyclic/cyclicFvPatchFields.C
$(constraintFvPatchFields)/cyclicAMI/cyclicAMIFvPatchFields.C $(constraintFvPatchFields)/cyclicAMI/cyclicAMIFvPatchFields.C
$(constraintFvPatchFields)/cyclicACMI/cyclicACMIFvPatchFields.C
$(constraintFvPatchFields)/cyclicSlip/cyclicSlipFvPatchFields.C $(constraintFvPatchFields)/cyclicSlip/cyclicSlipFvPatchFields.C
$(constraintFvPatchFields)/empty/emptyFvPatchFields.C $(constraintFvPatchFields)/empty/emptyFvPatchFields.C
$(constraintFvPatchFields)/jumpCyclic/jumpCyclicFvPatchFields.C $(constraintFvPatchFields)/jumpCyclic/jumpCyclicFvPatchFields.C
@ -203,6 +205,7 @@ $(basicFvsPatchFields)/sliced/slicedFvsPatchFields.C
constraintFvsPatchFields = $(fvsPatchFields)/constraint constraintFvsPatchFields = $(fvsPatchFields)/constraint
$(constraintFvsPatchFields)/cyclic/cyclicFvsPatchFields.C $(constraintFvsPatchFields)/cyclic/cyclicFvsPatchFields.C
$(constraintFvsPatchFields)/cyclicAMI/cyclicAMIFvsPatchFields.C $(constraintFvsPatchFields)/cyclicAMI/cyclicAMIFvsPatchFields.C
$(constraintFvsPatchFields)/cyclicACMI/cyclicACMIFvsPatchFields.C
$(constraintFvsPatchFields)/cyclicSlip/cyclicSlipFvsPatchFields.C $(constraintFvsPatchFields)/cyclicSlip/cyclicSlipFvsPatchFields.C
$(constraintFvsPatchFields)/empty/emptyFvsPatchFields.C $(constraintFvsPatchFields)/empty/emptyFvsPatchFields.C
$(constraintFvsPatchFields)/nonuniformTransformCyclic/nonuniformTransformCyclicFvsPatchFields.C $(constraintFvsPatchFields)/nonuniformTransformCyclic/nonuniformTransformCyclicFvsPatchFields.C

View File

@ -2,7 +2,7 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2011 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -56,11 +56,7 @@ bool Foam::adjustPhi
if (!isA<processorFvsPatchScalarField>(phip)) if (!isA<processorFvsPatchScalarField>(phip))
{ {
if if (Up.fixesValue() && !isA<inletOutletFvPatchVectorField>(Up))
(
Up.fixesValue()
&& !isA<inletOutletFvPatchVectorField>(Up)
)
{ {
forAll(phip, i) forAll(phip, i)
{ {
@ -113,8 +109,12 @@ bool Foam::adjustPhi
{ {
FatalErrorIn FatalErrorIn
( (
"adjustPhi(surfaceScalarField& phi, const volVectorField& U," "adjustPhi"
"const volScalarField& p" "("
"surfaceScalarField&, "
"const volVectorField&,"
"volScalarField&"
")"
) << "Continuity error cannot be removed by adjusting the" ) << "Continuity error cannot be removed by adjusting the"
" outflow.\nPlease check the velocity boundary conditions" " outflow.\nPlease check the velocity boundary conditions"
" and/or run potentialFoam to initialise the outflow." << nl " and/or run potentialFoam to initialise the outflow." << nl

View File

@ -130,8 +130,8 @@ void Foam::porosityModels::DarcyForchheimer::calcForce
vectorField& force vectorField& force
) const ) const
{ {
scalarField Udiag(U.size()); scalarField Udiag(U.size(), 0.0);
vectorField Usource(U.size()); vectorField Usource(U.size(), vector::zero);
const scalarField& V = mesh_.V(); const scalarField& V = mesh_.V();
apply(Udiag, Usource, V, rho, mu, U); apply(Udiag, Usource, V, rho, mu, U);

View File

@ -183,8 +183,8 @@ void Foam::porosityModels::fixedCoeff::calcForce
vectorField& force vectorField& force
) const ) const
{ {
scalarField Udiag(U.size()); scalarField Udiag(U.size(), 0.0);
vectorField Usource(U.size()); vectorField Usource(U.size(), vector::zero);
const scalarField& V = mesh_.V(); const scalarField& V = mesh_.V();
scalar rhoRef = readScalar(coeffs_.lookup("rhoRef")); scalar rhoRef = readScalar(coeffs_.lookup("rhoRef"));

View File

@ -155,7 +155,7 @@ Foam::tmp<Foam::vectorField> Foam::porosityModel::porosityModel::force
} }
void Foam::porosityModel::porosityModel::addResistance void Foam::porosityModel::addResistance
( (
fvVectorMatrix& UEqn fvVectorMatrix& UEqn
) const ) const
@ -169,7 +169,7 @@ void Foam::porosityModel::porosityModel::addResistance
} }
void Foam::porosityModel::porosityModel::addResistance void Foam::porosityModel::addResistance
( (
fvVectorMatrix& UEqn, fvVectorMatrix& UEqn,
const volScalarField& rho, const volScalarField& rho,
@ -185,7 +185,7 @@ void Foam::porosityModel::porosityModel::addResistance
} }
void Foam::porosityModel::porosityModel::addResistance void Foam::porosityModel::addResistance
( (
const fvVectorMatrix& UEqn, const fvVectorMatrix& UEqn,
volTensorField& AU, volTensorField& AU,
@ -209,14 +209,14 @@ void Foam::porosityModel::porosityModel::addResistance
} }
bool Foam::porosityModel::porosityModel::movePoints() bool Foam::porosityModel::movePoints()
{ {
// no updates necessary; all member data independent of mesh // no updates necessary; all member data independent of mesh
return true; return true;
} }
void Foam::porosityModel::porosityModel::updateMesh(const mapPolyMesh& mpm) void Foam::porosityModel::updateMesh(const mapPolyMesh& mpm)
{ {
// no updates necessary; all member data independent of mesh // no updates necessary; all member data independent of mesh
} }

View File

@ -74,7 +74,7 @@ void Foam::porosityModels::powerLaw::calcForce
vectorField& force vectorField& force
) const ) const
{ {
scalarField Udiag(U.size()); scalarField Udiag(U.size(), 0.0);
const scalarField& V = mesh_.V(); const scalarField& V = mesh_.V();
apply(Udiag, V, rho, U); apply(Udiag, V, rho, U);

View File

@ -0,0 +1,411 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2013 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 "cyclicACMIFvPatchField.H"
#include "transformField.H"
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
template<class Type>
Foam::cyclicACMIFvPatchField<Type>::cyclicACMIFvPatchField
(
const fvPatch& p,
const DimensionedField<Type, volMesh>& iF
)
:
cyclicACMILduInterfaceField(),
coupledFvPatchField<Type>(p, iF),
cyclicACMIPatch_(refCast<const cyclicACMIFvPatch>(p))
{}
template<class Type>
Foam::cyclicACMIFvPatchField<Type>::cyclicACMIFvPatchField
(
const cyclicACMIFvPatchField<Type>& ptf,
const fvPatch& p,
const DimensionedField<Type, volMesh>& iF,
const fvPatchFieldMapper& mapper
)
:
cyclicACMILduInterfaceField(),
coupledFvPatchField<Type>(ptf, p, iF, mapper),
cyclicACMIPatch_(refCast<const cyclicACMIFvPatch>(p))
{
if (!isA<cyclicACMIFvPatch>(this->patch()))
{
FatalErrorIn
(
"cyclicACMIFvPatchField<Type>::cyclicACMIFvPatchField"
"("
"const cyclicACMIFvPatchField<Type>& ,"
"const fvPatch&, "
"const DimensionedField<Type, volMesh>&, "
"const fvPatchFieldMapper&"
")"
) << " patch type '" << p.type()
<< "' not constraint type '" << typeName << "'"
<< "\n for patch " << p.name()
<< " of field " << this->dimensionedInternalField().name()
<< " in file " << this->dimensionedInternalField().objectPath()
<< exit(FatalIOError);
}
}
template<class Type>
Foam::cyclicACMIFvPatchField<Type>::cyclicACMIFvPatchField
(
const fvPatch& p,
const DimensionedField<Type, volMesh>& iF,
const dictionary& dict
)
:
cyclicACMILduInterfaceField(),
coupledFvPatchField<Type>(p, iF, dict),
cyclicACMIPatch_(refCast<const cyclicACMIFvPatch>(p))
{
if (!isA<cyclicACMIFvPatch>(p))
{
FatalIOErrorIn
(
"cyclicACMIFvPatchField<Type>::cyclicACMIFvPatchField"
"("
"const fvPatch&, "
"const DimensionedField<Type, volMesh>&, "
"const dictionary&"
")",
dict
) << " patch type '" << p.type()
<< "' not constraint type '" << typeName << "'"
<< "\n for patch " << p.name()
<< " of field " << this->dimensionedInternalField().name()
<< " in file " << this->dimensionedInternalField().objectPath()
<< exit(FatalIOError);
}
if (!dict.found("value") && this->coupled())
{
this->evaluate(Pstream::blocking);
}
}
template<class Type>
Foam::cyclicACMIFvPatchField<Type>::cyclicACMIFvPatchField
(
const cyclicACMIFvPatchField<Type>& ptf
)
:
cyclicACMILduInterfaceField(),
coupledFvPatchField<Type>(ptf),
cyclicACMIPatch_(ptf.cyclicACMIPatch_)
{}
template<class Type>
Foam::cyclicACMIFvPatchField<Type>::cyclicACMIFvPatchField
(
const cyclicACMIFvPatchField<Type>& ptf,
const DimensionedField<Type, volMesh>& iF
)
:
cyclicACMILduInterfaceField(),
coupledFvPatchField<Type>(ptf, iF),
cyclicACMIPatch_(ptf.cyclicACMIPatch_)
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class Type>
bool Foam::cyclicACMIFvPatchField<Type>::coupled() const
{
return cyclicACMIPatch_.coupled();
}
template<class Type>
Foam::tmp<Foam::Field<Type> >
Foam::cyclicACMIFvPatchField<Type>::patchNeighbourField() const
{
const Field<Type>& iField = this->internalField();
const labelUList& nbrFaceCellsCoupled =
cyclicACMIPatch_.cyclicACMIPatch().neighbPatch().faceCells();
const labelUList& nbrFaceCellsNonOverlap =
cyclicACMIPatch_.cyclicACMIPatch().nonOverlapPatch().faceCells();
Field<Type> pnfCoupled(iField, nbrFaceCellsCoupled);
Field<Type> pnfNonOverlap(iField, nbrFaceCellsNonOverlap);
tmp<Field<Type> > tpnf
(
new Field<Type>
(
cyclicACMIPatch_.interpolate
(
pnfCoupled,
pnfNonOverlap
)
)
);
if (doTransform())
{
tpnf() = transform(forwardT(), tpnf());
}
return tpnf;
}
template<class Type>
const Foam::cyclicACMIFvPatchField<Type>&
Foam::cyclicACMIFvPatchField<Type>::neighbourPatchField() const
{
const GeometricField<Type, fvPatchField, volMesh>& fld =
static_cast<const GeometricField<Type, fvPatchField, volMesh>&>
(
this->internalField()
);
return refCast<const cyclicACMIFvPatchField<Type> >
(
fld.boundaryField()[cyclicACMIPatch_.neighbPatchID()]
);
}
template<class Type>
const Foam::fvPatchField<Type>&
Foam::cyclicACMIFvPatchField<Type>::nonOverlapPatchField() const
{
const GeometricField<Type, fvPatchField, volMesh>& fld =
static_cast<const GeometricField<Type, fvPatchField, volMesh>&>
(
this->internalField()
);
return fld.boundaryField()[cyclicACMIPatch_.nonOverlapPatchID()];
}
template<class Type>
void Foam::cyclicACMIFvPatchField<Type>::updateInterfaceMatrix
(
scalarField& result,
const scalarField& psiInternal,
const scalarField& coeffs,
const direction cmpt,
const Pstream::commsTypes
) const
{
// note: only applying coupled contribution
const labelUList& nbrFaceCellsCoupled =
cyclicACMIPatch_.cyclicACMIPatch().neighbPatch().faceCells();
scalarField pnf(psiInternal, nbrFaceCellsCoupled);
// Transform according to the transformation tensors
transformCoupleField(pnf, cmpt);
const labelUList& faceCells = cyclicACMIPatch_.faceCells();
pnf = cyclicACMIPatch_.interpolate(pnf);
forAll(faceCells, elemI)
{
result[faceCells[elemI]] -= coeffs[elemI]*pnf[elemI];
}
}
template<class Type>
void Foam::cyclicACMIFvPatchField<Type>::updateInterfaceMatrix
(
Field<Type>& result,
const Field<Type>& psiInternal,
const scalarField& coeffs,
const Pstream::commsTypes
) const
{
// note: only applying coupled contribution
const labelUList& nbrFaceCellsCoupled =
cyclicACMIPatch_.cyclicACMIPatch().neighbPatch().faceCells();
Field<Type> pnf(psiInternal, nbrFaceCellsCoupled);
// Transform according to the transformation tensors
transformCoupleField(pnf);
const labelUList& faceCells = cyclicACMIPatch_.faceCells();
pnf = cyclicACMIPatch_.interpolate(pnf);
forAll(faceCells, elemI)
{
result[faceCells[elemI]] -= coeffs[elemI]*pnf[elemI];
}
}
template<class Type>
Foam::tmp<Foam::Field<Type> > Foam::cyclicACMIFvPatchField<Type>::snGrad
(
const scalarField& deltaCoeffs
) const
{
// note: only applying coupled contribution
return coupledFvPatchField<Type>::snGrad(deltaCoeffs);
}
template<class Type>
void Foam::cyclicACMIFvPatchField<Type>::updateCoeffs()
{
const scalarField& mask = cyclicACMIPatch_.cyclicACMIPatch().mask();
const fvPatchField<Type>& npf = nonOverlapPatchField();
const_cast<fvPatchField<Type>&>(npf).updateCoeffs(mask);
}
template<class Type>
void Foam::cyclicACMIFvPatchField<Type>::evaluate
(
const Pstream::commsTypes comms
)
{
// blend contrubutions from the coupled and non-overlap patches
const fvPatchField<Type>& npf = nonOverlapPatchField();
const_cast<fvPatchField<Type>&>(npf).evaluate();
coupledFvPatchField<Type>::evaluate(comms);
const Field<Type>& cpf = *this;
const scalarField& mask = cyclicACMIPatch_.cyclicACMIPatch().mask();
Field<Type>::operator=(mask*cpf + (1.0 - mask)*npf);
fvPatchField<Type>::evaluate();
}
template<class Type>
Foam::tmp<Foam::Field<Type> >
Foam::cyclicACMIFvPatchField<Type>::valueInternalCoeffs
(
const tmp<scalarField>& w
) const
{
// note: do not blend based on mask field
// - when applied this is scaled by the areas which area already scaled
return coupledFvPatchField<Type>::valueInternalCoeffs(w);
}
template<class Type>
Foam::tmp<Foam::Field<Type> >
Foam::cyclicACMIFvPatchField<Type>::valueBoundaryCoeffs
(
const tmp<scalarField>& w
) const
{
// note: do not blend based on mask field
// - when applied this is scaled by the areas which area already scaled
return coupledFvPatchField<Type>::valueBoundaryCoeffs(w);
}
template<class Type>
Foam::tmp<Foam::Field<Type> >
Foam::cyclicACMIFvPatchField<Type>::gradientInternalCoeffs
(
const scalarField& deltaCoeffs
) const
{
// note: do not blend based on mask field
// - when applied this is scaled by the areas which area already scaled
return coupledFvPatchField<Type>::gradientInternalCoeffs(deltaCoeffs);
}
template<class Type>
Foam::tmp<Foam::Field<Type> >
Foam::cyclicACMIFvPatchField<Type>::gradientInternalCoeffs() const
{
// note: do not blend based on mask field
// - when applied this is scaled by the areas which area already scaled
return coupledFvPatchField<Type>::gradientInternalCoeffs();
}
template<class Type>
Foam::tmp<Foam::Field<Type> >
Foam::cyclicACMIFvPatchField<Type>::gradientBoundaryCoeffs
(
const scalarField& deltaCoeffs
) const
{
// note: do not blend based on mask field
// - when applied this is scaled by the areas which area already scaled
return coupledFvPatchField<Type>::gradientBoundaryCoeffs(deltaCoeffs);
}
template<class Type>
Foam::tmp<Foam::Field<Type> >
Foam::cyclicACMIFvPatchField<Type>::gradientBoundaryCoeffs() const
{
// note: do not blend based on mask field
// - when applied this is scaled by the areas which area already scaled
return coupledFvPatchField<Type>::gradientBoundaryCoeffs();
}
template<class Type>
void Foam::cyclicACMIFvPatchField<Type>::manipulateMatrix
(
fvMatrix<Type>& matrix
)
{
// blend contrubutions from the coupled and non-overlap patches
const fvPatchField<Type>& npf = nonOverlapPatchField();
const scalarField& mask = cyclicACMIPatch_.cyclicACMIPatch().mask();
const_cast<fvPatchField<Type>&>(npf).manipulateMatrix(matrix, mask);
}
template<class Type>
void Foam::cyclicACMIFvPatchField<Type>::write(Ostream& os) const
{
fvPatchField<Type>::write(os);
this->writeEntry("value", os);
}
// ************************************************************************* //

View File

@ -0,0 +1,304 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2013 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::cyclicACMIFvPatchField
Group
grpCoupledBoundaryConditions
Description
This boundary condition enforces a cyclic condition between a pair of
boundaries, whereby communication between the patches is performed using
an arbitrarily coupled mesh interface (ACMI) interpolation.
\heading Patch usage
Example of the boundary condition specification:
\verbatim
myPatch
{
type cyclicACMI;
}
\endverbatim
SeeAlso
Foam::AMIInterpolation
SourceFiles
cyclicACMIFvPatchField.C
\*---------------------------------------------------------------------------*/
#ifndef cyclicACMIFvPatchField_H
#define cyclicACMIFvPatchField_H
#include "coupledFvPatchField.H"
#include "cyclicACMILduInterfaceField.H"
#include "cyclicACMIFvPatch.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class cyclicACMIFvPatchField Declaration
\*---------------------------------------------------------------------------*/
template<class Type>
class cyclicACMIFvPatchField
:
virtual public cyclicACMILduInterfaceField,
public coupledFvPatchField<Type>
{
// Private data
//- Local reference cast into the cyclic patch
const cyclicACMIFvPatch& cyclicACMIPatch_;
// Private Member Functions
//- Return neighbour side field given internal fields
template<class Type2>
tmp<Field<Type2> > neighbourSideField
(
const Field<Type2>&
) const;
public:
//- Runtime type information
TypeName(cyclicACMIFvPatch::typeName_());
// Constructors
//- Construct from patch and internal field
cyclicACMIFvPatchField
(
const fvPatch&,
const DimensionedField<Type, volMesh>&
);
//- Construct from patch, internal field and dictionary
cyclicACMIFvPatchField
(
const fvPatch&,
const DimensionedField<Type, volMesh>&,
const dictionary&
);
//- Construct by mapping given cyclicACMIFvPatchField onto a new patch
cyclicACMIFvPatchField
(
const cyclicACMIFvPatchField<Type>&,
const fvPatch&,
const DimensionedField<Type, volMesh>&,
const fvPatchFieldMapper&
);
//- Construct as copy
cyclicACMIFvPatchField(const cyclicACMIFvPatchField<Type>&);
//- Construct and return a clone
virtual tmp<fvPatchField<Type> > clone() const
{
return tmp<fvPatchField<Type> >
(
new cyclicACMIFvPatchField<Type>(*this)
);
}
//- Construct as copy setting internal field reference
cyclicACMIFvPatchField
(
const cyclicACMIFvPatchField<Type>&,
const DimensionedField<Type, volMesh>&
);
//- Construct and return a clone setting internal field reference
virtual tmp<fvPatchField<Type> > clone
(
const DimensionedField<Type, volMesh>& iF
) const
{
return tmp<fvPatchField<Type> >
(
new cyclicACMIFvPatchField<Type>(*this, iF)
);
}
// Member functions
// Access
//- Return local reference cast into the cyclic AMI patch
const cyclicACMIFvPatch& cyclicACMIPatch() const
{
return cyclicACMIPatch_;
}
// Evaluation functions
//- Return true if coupled. Note that the underlying patch
// is not coupled() - the points don't align.
virtual bool coupled() const;
//- Return neighbour coupled internal cell data
virtual tmp<Field<Type> > patchNeighbourField() const;
//- Return reference to neighbour patchField
const cyclicACMIFvPatchField<Type>& neighbourPatchField() const;
//- Return reference to non-overlapping patchField
const fvPatchField<Type>& nonOverlapPatchField() const;
//- Update result field based on interface functionality
virtual void updateInterfaceMatrix
(
scalarField& result,
const scalarField& psiInternal,
const scalarField& coeffs,
const direction cmpt,
const Pstream::commsTypes commsType
) const;
//- Update result field based on interface functionality
virtual void updateInterfaceMatrix
(
Field<Type>&,
const Field<Type>&,
const scalarField&,
const Pstream::commsTypes commsType
) const;
//- Return patch-normal gradient
virtual tmp<Field<Type> > snGrad
(
const scalarField& deltaCoeffs
) const;
//- Update the coefficients associated with the patch field
void updateCoeffs();
//- Evaluate the patch field
virtual void evaluate
(
const Pstream::commsTypes commsType
);
//- Return the matrix diagonal coefficients corresponding to the
// evaluation of the value of this patchField with given weights
virtual tmp<Field<Type> > valueInternalCoeffs
(
const tmp<scalarField>&
) const;
//- Return the matrix source coefficients corresponding to the
// evaluation of the value of this patchField with given weights
virtual tmp<Field<Type> > valueBoundaryCoeffs
(
const tmp<scalarField>&
) const;
//- Return the matrix diagonal coefficients corresponding to the
// evaluation of the gradient of this patchField
virtual tmp<Field<Type> > gradientInternalCoeffs
(
const scalarField& deltaCoeffs
) const;
//- Return the matrix diagonal coefficients corresponding to the
// evaluation of the gradient of this patchField
virtual tmp<Field<Type> > gradientInternalCoeffs() const;
//- Return the matrix source coefficients corresponding to the
// evaluation of the gradient of this patchField
virtual tmp<Field<Type> > gradientBoundaryCoeffs
(
const scalarField& deltaCoeffs
) const;
//- Return the matrix source coefficients corresponding to the
// evaluation of the gradient of this patchField
virtual tmp<Field<Type> > gradientBoundaryCoeffs() const;
//- Manipulate matrix
virtual void manipulateMatrix(fvMatrix<Type>& matrix);
// Cyclic AMI coupled interface functions
//- Does the patch field perform the transformation
virtual bool doTransform() const
{
return
!(cyclicACMIPatch_.parallel() || pTraits<Type>::rank == 0);
}
//- Return face transformation tensor
virtual const tensorField& forwardT() const
{
return cyclicACMIPatch_.forwardT();
}
//- Return neighbour-cell transformation tensor
virtual const tensorField& reverseT() const
{
return cyclicACMIPatch_.reverseT();
}
//- Return rank of component for transform
virtual int rank() const
{
return pTraits<Type>::rank;
}
// I-O
//- Write
virtual void write(Ostream& os) const;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository
# include "cyclicACMIFvPatchField.C"
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,43 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2013 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 "cyclicACMIFvPatchFields.H"
#include "addToRunTimeSelectionTable.H"
#include "volFields.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
makePatchFields(cyclicACMI);
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// ************************************************************************* //

View File

@ -0,0 +1,49 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2013 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/>.
\*---------------------------------------------------------------------------*/
#ifndef cyclicACMIFvPatchFields_H
#define cyclicACMIFvPatchFields_H
#include "cyclicACMIFvPatchField.H"
#include "fieldTypes.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
makePatchTypeFieldTypedefs(cyclicACMI);
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,50 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2013 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/>.
\*---------------------------------------------------------------------------*/
#ifndef cyclicACMIFvPatchFieldsFwd_H
#define cyclicACMIFvPatchFieldsFwd_H
#include "fieldTypes.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
template<class Type> class cyclicACMIFvPatchField;
makePatchTypeFieldTypedefs(cyclicACMI);
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -46,6 +46,7 @@ timeVaryingMappedFixedValueFvPatchField
fieldTableName_(iF.name()), fieldTableName_(iF.name()),
setAverage_(false), setAverage_(false),
perturb_(0), perturb_(0),
mapperPtr_(NULL),
sampleTimes_(0), sampleTimes_(0),
startSampleTime_(-1), startSampleTime_(-1),
startSampledValues_(0), startSampledValues_(0),
@ -71,7 +72,7 @@ timeVaryingMappedFixedValueFvPatchField
fieldTableName_(ptf.fieldTableName_), fieldTableName_(ptf.fieldTableName_),
setAverage_(ptf.setAverage_), setAverage_(ptf.setAverage_),
perturb_(ptf.perturb_), perturb_(ptf.perturb_),
mapperPtr_(ptf.mapperPtr_), mapperPtr_(NULL),
sampleTimes_(0), sampleTimes_(0),
startSampleTime_(-1), startSampleTime_(-1),
startSampledValues_(0), startSampledValues_(0),
@ -79,7 +80,12 @@ timeVaryingMappedFixedValueFvPatchField
endSampleTime_(-1), endSampleTime_(-1),
endSampledValues_(0), endSampledValues_(0),
endAverage_(pTraits<Type>::zero), endAverage_(pTraits<Type>::zero),
offset_(ptf.offset_().clone().ptr()) offset_
(
ptf.offset_.valid()
? ptf.offset_().clone().ptr()
: NULL
)
{} {}
@ -130,7 +136,7 @@ timeVaryingMappedFixedValueFvPatchField
fieldTableName_(ptf.fieldTableName_), fieldTableName_(ptf.fieldTableName_),
setAverage_(ptf.setAverage_), setAverage_(ptf.setAverage_),
perturb_(ptf.perturb_), perturb_(ptf.perturb_),
mapperPtr_(ptf.mapperPtr_), mapperPtr_(NULL),
sampleTimes_(ptf.sampleTimes_), sampleTimes_(ptf.sampleTimes_),
startSampleTime_(ptf.startSampleTime_), startSampleTime_(ptf.startSampleTime_),
startSampledValues_(ptf.startSampledValues_), startSampledValues_(ptf.startSampledValues_),
@ -138,11 +144,15 @@ timeVaryingMappedFixedValueFvPatchField
endSampleTime_(ptf.endSampleTime_), endSampleTime_(ptf.endSampleTime_),
endSampledValues_(ptf.endSampledValues_), endSampledValues_(ptf.endSampledValues_),
endAverage_(ptf.endAverage_), endAverage_(ptf.endAverage_),
offset_(ptf.offset_().clone().ptr()) offset_
(
ptf.offset_.valid()
? ptf.offset_().clone().ptr()
: NULL
)
{} {}
template<class Type> template<class Type>
timeVaryingMappedFixedValueFvPatchField<Type>:: timeVaryingMappedFixedValueFvPatchField<Type>::
timeVaryingMappedFixedValueFvPatchField timeVaryingMappedFixedValueFvPatchField
@ -155,7 +165,7 @@ timeVaryingMappedFixedValueFvPatchField
fieldTableName_(ptf.fieldTableName_), fieldTableName_(ptf.fieldTableName_),
setAverage_(ptf.setAverage_), setAverage_(ptf.setAverage_),
perturb_(ptf.perturb_), perturb_(ptf.perturb_),
mapperPtr_(ptf.mapperPtr_), mapperPtr_(NULL),
sampleTimes_(ptf.sampleTimes_), sampleTimes_(ptf.sampleTimes_),
startSampleTime_(ptf.startSampleTime_), startSampleTime_(ptf.startSampleTime_),
startSampledValues_(ptf.startSampledValues_), startSampledValues_(ptf.startSampledValues_),
@ -163,7 +173,12 @@ timeVaryingMappedFixedValueFvPatchField
endSampleTime_(ptf.endSampleTime_), endSampleTime_(ptf.endSampleTime_),
endSampledValues_(ptf.endSampledValues_), endSampledValues_(ptf.endSampledValues_),
endAverage_(ptf.endAverage_), endAverage_(ptf.endAverage_),
offset_(ptf.offset_().clone().ptr()) offset_
(
ptf.offset_.valid()
? ptf.offset_().clone().ptr()
: NULL
)
{} {}

View File

@ -42,6 +42,7 @@ Foam::fvPatchField<Type>::fvPatchField
patch_(p), patch_(p),
internalField_(iF), internalField_(iF),
updated_(false), updated_(false),
manipulatedMatrix_(false),
patchType_(word::null) patchType_(word::null)
{} {}
@ -58,6 +59,7 @@ Foam::fvPatchField<Type>::fvPatchField
patch_(p), patch_(p),
internalField_(iF), internalField_(iF),
updated_(false), updated_(false),
manipulatedMatrix_(false),
patchType_(word::null) patchType_(word::null)
{} {}
@ -75,6 +77,7 @@ Foam::fvPatchField<Type>::fvPatchField
patch_(p), patch_(p),
internalField_(iF), internalField_(iF),
updated_(false), updated_(false),
manipulatedMatrix_(false),
patchType_(ptf.patchType_) patchType_(ptf.patchType_)
{} {}
@ -92,6 +95,7 @@ Foam::fvPatchField<Type>::fvPatchField
patch_(p), patch_(p),
internalField_(iF), internalField_(iF),
updated_(false), updated_(false),
manipulatedMatrix_(false),
patchType_(dict.lookupOrDefault<word>("patchType", word::null)) patchType_(dict.lookupOrDefault<word>("patchType", word::null))
{ {
if (dict.found("value")) if (dict.found("value"))
@ -133,6 +137,7 @@ Foam::fvPatchField<Type>::fvPatchField
patch_(ptf.patch_), patch_(ptf.patch_),
internalField_(ptf.internalField_), internalField_(ptf.internalField_),
updated_(false), updated_(false),
manipulatedMatrix_(false),
patchType_(ptf.patchType_) patchType_(ptf.patchType_)
{} {}
@ -148,6 +153,7 @@ Foam::fvPatchField<Type>::fvPatchField
patch_(ptf.patch_), patch_(ptf.patch_),
internalField_(iF), internalField_(iF),
updated_(false), updated_(false),
manipulatedMatrix_(false),
patchType_(ptf.patchType_) patchType_(ptf.patchType_)
{} {}
@ -267,6 +273,28 @@ void Foam::fvPatchField<Type>::rmap
} }
template<class Type>
void Foam::fvPatchField<Type>::updateCoeffs()
{
updated_ = true;
}
template<class Type>
void Foam::fvPatchField<Type>::updateCoeffs(const scalarField& weights)
{
if (!updated_)
{
updateCoeffs();
Field<Type>& fld = *this;
fld *= weights;
updated_ = true;
}
}
template<class Type> template<class Type>
void Foam::fvPatchField<Type>::evaluate(const Pstream::commsTypes) void Foam::fvPatchField<Type>::evaluate(const Pstream::commsTypes)
{ {
@ -276,13 +304,25 @@ void Foam::fvPatchField<Type>::evaluate(const Pstream::commsTypes)
} }
updated_ = false; updated_ = false;
manipulatedMatrix_ = false;
} }
template<class Type> template<class Type>
void Foam::fvPatchField<Type>::manipulateMatrix(fvMatrix<Type>& matrix) void Foam::fvPatchField<Type>::manipulateMatrix(fvMatrix<Type>& matrix)
{ {
// do nothing manipulatedMatrix_ = true;
}
template<class Type>
void Foam::fvPatchField<Type>::manipulateMatrix
(
fvMatrix<Type>& matrix,
const scalarField& weights
)
{
manipulatedMatrix_ = true;
} }

View File

@ -93,6 +93,10 @@ class fvPatchField
// the construction of the matrix // the construction of the matrix
bool updated_; bool updated_;
//- Update index used so that manipulateMatrix is called only once
// during the construction of the matrix
bool manipulatedMatrix_;
//- Optional patch type, used to allow specified boundary conditions //- Optional patch type, used to allow specified boundary conditions
// to be applied to constraint patches by providing the constraint // to be applied to constraint patches by providing the constraint
// patch type as 'patchType' // patch type as 'patchType'
@ -327,6 +331,12 @@ public:
return updated_; return updated_;
} }
//- Return true if the matrix has already been manipulated
bool manipulatedMatrix() const
{
return manipulatedMatrix_;
}
// Mapping functions // Mapping functions
@ -365,10 +375,12 @@ public:
//- Update the coefficients associated with the patch field //- Update the coefficients associated with the patch field
// Sets Updated to true // Sets Updated to true
virtual void updateCoeffs() virtual void updateCoeffs();
{
updated_ = true; //- Update the coefficients associated with the patch field
} // and apply weight field
// Sets Updated to true
virtual void updateCoeffs(const scalarField& weights);
//- Return internal field next to patch as patch field //- Return internal field next to patch as patch field
virtual tmp<Field<Type> > patchInternalField() const; virtual tmp<Field<Type> > patchInternalField() const;
@ -479,6 +491,13 @@ public:
//- Manipulate matrix //- Manipulate matrix
virtual void manipulateMatrix(fvMatrix<Type>& matrix); virtual void manipulateMatrix(fvMatrix<Type>& matrix);
//- Manipulate matrix with given weights
virtual void manipulateMatrix
(
fvMatrix<Type>& matrix,
const scalarField& weights
);
// I-O // I-O

View File

@ -0,0 +1,149 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2013 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 "cyclicACMIFvsPatchField.H"
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
template<class Type>
Foam::cyclicACMIFvsPatchField<Type>::cyclicACMIFvsPatchField
(
const fvPatch& p,
const DimensionedField<Type, surfaceMesh>& iF
)
:
coupledFvsPatchField<Type>(p, iF),
cyclicACMIPatch_(refCast<const cyclicACMIFvPatch>(p))
{}
template<class Type>
Foam::cyclicACMIFvsPatchField<Type>::cyclicACMIFvsPatchField
(
const cyclicACMIFvsPatchField<Type>& ptf,
const fvPatch& p,
const DimensionedField<Type, surfaceMesh>& iF,
const fvPatchFieldMapper& mapper
)
:
coupledFvsPatchField<Type>(ptf, p, iF, mapper),
cyclicACMIPatch_(refCast<const cyclicACMIFvPatch>(p))
{
if (!isA<cyclicACMIFvPatch>(this->patch()))
{
FatalErrorIn
(
"cyclicACMIFvsPatchField<Type>::cyclicACMIFvsPatchField\n"
"("
"const cyclicACMIFvsPatchField<Type>&, "
"const fvPatch&, "
"const DimensionedField<Type, surfaceMesh>&, "
"const fvPatchFieldMapper&"
")"
) << "Field type does not correspond to patch type for patch "
<< this->patch().index() << "." << endl
<< "Field type: " << typeName << endl
<< "Patch type: " << this->patch().type()
<< exit(FatalError);
}
}
template<class Type>
Foam::cyclicACMIFvsPatchField<Type>::cyclicACMIFvsPatchField
(
const fvPatch& p,
const DimensionedField<Type, surfaceMesh>& iF,
const dictionary& dict
)
:
coupledFvsPatchField<Type>(p, iF, dict),
cyclicACMIPatch_(refCast<const cyclicACMIFvPatch>(p))
{
if (!isA<cyclicACMIFvPatch>(p))
{
FatalIOErrorIn
(
"cyclicACMIFvsPatchField<Type>::cyclicACMIFvsPatchField"
"("
"const fvPatch&, "
"const Field<Type>&, "
"const dictionary&"
")",
dict
) << "patch " << this->patch().index() << " not cyclicACMI type. "
<< "Patch type = " << p.type()
<< exit(FatalIOError);
}
}
template<class Type>
Foam::cyclicACMIFvsPatchField<Type>::cyclicACMIFvsPatchField
(
const cyclicACMIFvsPatchField<Type>& ptf
)
:
coupledFvsPatchField<Type>(ptf),
cyclicACMIPatch_(ptf.cyclicACMIPatch_)
{}
template<class Type>
Foam::cyclicACMIFvsPatchField<Type>::cyclicACMIFvsPatchField
(
const cyclicACMIFvsPatchField<Type>& ptf,
const DimensionedField<Type, surfaceMesh>& iF
)
:
coupledFvsPatchField<Type>(ptf, iF),
cyclicACMIPatch_(ptf.cyclicACMIPatch_)
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class Type>
bool Foam::cyclicACMIFvsPatchField<Type>::coupled() const
{
if
(
Pstream::parRun()
|| (
this->cyclicACMIPatch_.size()
&& this->cyclicACMIPatch_.cyclicACMIPatch().neighbPatch().size()
)
)
{
return true;
}
else
{
return false;
}
}
// ************************************************************************* //

View File

@ -0,0 +1,150 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2013 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::cyclicACMIFvsPatchField
Description
Foam::cyclicACMIFvsPatchField
SourceFiles
cyclicACMIFvsPatchField.C
\*---------------------------------------------------------------------------*/
#ifndef cyclicACMIFvsPatchField_H
#define cyclicACMIFvsPatchField_H
#include "coupledFvsPatchField.H"
#include "cyclicACMIFvPatch.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class cyclicACMIFvsPatchField Declaration
\*---------------------------------------------------------------------------*/
template<class Type>
class cyclicACMIFvsPatchField
:
public coupledFvsPatchField<Type>
{
// Private data
//- Local reference cast into the cyclic patch
const cyclicACMIFvPatch& cyclicACMIPatch_;
public:
//- Runtime type information
TypeName(cyclicACMIFvPatch::typeName_());
// Constructors
//- Construct from patch and internal field
cyclicACMIFvsPatchField
(
const fvPatch&,
const DimensionedField<Type, surfaceMesh>&
);
//- Construct from patch, internal field and dictionary
cyclicACMIFvsPatchField
(
const fvPatch&,
const DimensionedField<Type, surfaceMesh>&,
const dictionary&
);
//- Construct by mapping given cyclicACMIFvsPatchField onto a new patch
cyclicACMIFvsPatchField
(
const cyclicACMIFvsPatchField<Type>&,
const fvPatch&,
const DimensionedField<Type, surfaceMesh>&,
const fvPatchFieldMapper&
);
//- Construct as copy
cyclicACMIFvsPatchField
(
const cyclicACMIFvsPatchField<Type>&
);
//- Construct and return a clone
virtual tmp<fvsPatchField<Type> > clone() const
{
return tmp<fvsPatchField<Type> >
(
new cyclicACMIFvsPatchField<Type>(*this)
);
}
//- Construct as copy setting internal field reference
cyclicACMIFvsPatchField
(
const cyclicACMIFvsPatchField<Type>&,
const DimensionedField<Type, surfaceMesh>&
);
//- Construct and return a clone setting internal field reference
virtual tmp<fvsPatchField<Type> > clone
(
const DimensionedField<Type, surfaceMesh>& iF
) const
{
return tmp<fvsPatchField<Type> >
(
new cyclicACMIFvsPatchField<Type>(*this, iF)
);
}
// Member functions
// Access
//- Return true if running parallel
virtual bool coupled() const;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository
# include "cyclicACMIFvsPatchField.C"
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,43 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2013 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 "cyclicACMIFvsPatchFields.H"
#include "fvsPatchFields.H"
#include "addToRunTimeSelectionTable.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
makeFvsPatchFields(cyclicACMI);
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// ************************************************************************* //

View File

@ -0,0 +1,49 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2013 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/>.
\*---------------------------------------------------------------------------*/
#ifndef cyclicACMIFvsPatchFields_H
#define cyclicACMIFvsPatchFields_H
#include "cyclicACMIFvsPatchField.H"
#include "fieldTypes.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
makeFvsPatchTypeFieldTypedefs(cyclicACMI);
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,50 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2013 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/>.
\*---------------------------------------------------------------------------*/
#ifndef cyclicACMIFvsPatchFieldsFwd_H
#define cyclicACMIFvsPatchFieldsFwd_H
#include "fieldTypes.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
template<class Type> class cyclicACMIFvsPatchField;
makeFvsPatchTypeFieldTypedefs(cyclicACMI);
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -90,8 +90,6 @@ Foam::faceAreaPairGAMGAgglomeration::faceAreaPairGAMGAgglomeration
: :
pairGAMGAgglomeration(mesh, controlDict) pairGAMGAgglomeration(mesh, controlDict)
{ {
vectorField n(faceAreas/mag(faceAreas));
//agglomerate(mesh, sqrt(mag(faceAreas))); //agglomerate(mesh, sqrt(mag(faceAreas)));
agglomerate agglomerate
( (
@ -100,7 +98,8 @@ Foam::faceAreaPairGAMGAgglomeration::faceAreaPairGAMGAgglomeration
( (
cmptMultiply cmptMultiply
( (
n, faceAreas
/sqrt(mag(faceAreas)),
vector(1, 1.01, 1.02) vector(1, 1.01, 1.02)
//vector::one //vector::one
) )

View File

@ -0,0 +1,202 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2013 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 "cyclicACMIFvPatch.H"
#include "addToRunTimeSelectionTable.H"
#include "fvMesh.H"
#include "transform.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
defineTypeNameAndDebug(cyclicACMIFvPatch, 0);
addToRunTimeSelectionTable(fvPatch, cyclicACMIFvPatch, polyPatch);
}
// * * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * //
void Foam::cyclicACMIFvPatch::updateAreas() const
{
if (cyclicACMIPolyPatch_.updated())
{
// Set Sf and magSf for both sides' coupled and non-overlapping patches
// owner couple
const_cast<vectorField&>(Sf()) = patch().faceAreas();
const_cast<scalarField&>(magSf()) = mag(patch().faceAreas());
// owner non-overlapping
const fvPatch& nonOverlapPatch = this->nonOverlapPatch();
const_cast<vectorField&>(nonOverlapPatch.Sf()) =
nonOverlapPatch.patch().faceAreas();
const_cast<scalarField&>(nonOverlapPatch.magSf()) =
mag(nonOverlapPatch.patch().faceAreas());
// neighbour couple
const cyclicACMIFvPatch& nbrACMI = neighbPatch();
const_cast<vectorField&>(nbrACMI.Sf()) =
nbrACMI.patch().faceAreas();
const_cast<scalarField&>(nbrACMI.magSf()) =
mag(nbrACMI.patch().faceAreas());
// neighbour non-overlapping
const fvPatch& nbrNonOverlapPatch = nbrACMI.nonOverlapPatch();
const_cast<vectorField&>(nbrNonOverlapPatch.Sf()) =
nbrNonOverlapPatch.patch().faceAreas();
const_cast<scalarField&>(nbrNonOverlapPatch.magSf()) =
mag(nbrNonOverlapPatch.patch().faceAreas());
// set the updated flag
cyclicACMIPolyPatch_.setUpdated(false);
}
}
void Foam::cyclicACMIFvPatch::makeWeights(scalarField& w) const
{
if (coupled())
{
const cyclicACMIFvPatch& nbrPatch = neighbFvPatch();
const fvPatch& nbrPatchNonOverlap = nonOverlapPatch();
const scalarField deltas(nf() & fvPatch::delta());
const scalarField nbrDeltas
(
interpolate
(
nbrPatch.nf() & nbrPatch.fvPatch::delta(),
nbrPatchNonOverlap.nf() & nbrPatchNonOverlap.delta()
)
);
forAll(deltas, faceI)
{
scalar di = deltas[faceI];
scalar dni = nbrDeltas[faceI];
w[faceI] = dni/(di + dni);
}
}
else
{
// Behave as uncoupled patch
fvPatch::makeWeights(w);
}
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
bool Foam::cyclicACMIFvPatch::coupled() const
{
return Pstream::parRun() || (this->size() && neighbFvPatch().size());
}
Foam::tmp<Foam::vectorField> Foam::cyclicACMIFvPatch::delta() const
{
if (coupled())
{
const cyclicACMIFvPatch& nbrPatchCoupled = neighbFvPatch();
const fvPatch& nbrPatchNonOverlap = nonOverlapPatch();
const vectorField patchD(fvPatch::delta());
vectorField nbrPatchD
(
interpolate
(
nbrPatchCoupled.fvPatch::delta(),
nbrPatchNonOverlap.delta()
)
);
const vectorField nbrPatchD0
(
interpolate
(
vectorField(nbrPatchCoupled.size(), vector::zero),
nbrPatchNonOverlap.delta()()
)
);
nbrPatchD -= nbrPatchD0;
tmp<vectorField> tpdv(new vectorField(patchD.size()));
vectorField& pdv = tpdv();
// do the transformation if necessary
if (parallel())
{
forAll(patchD, faceI)
{
const vector& ddi = patchD[faceI];
const vector& dni = nbrPatchD[faceI];
pdv[faceI] = ddi - dni;
}
}
else
{
forAll(patchD, faceI)
{
const vector& ddi = patchD[faceI];
const vector& dni = nbrPatchD[faceI];
pdv[faceI] = ddi - transform(forwardT()[0], dni);
}
}
return tpdv;
}
else
{
return fvPatch::delta();
}
}
Foam::tmp<Foam::labelField> Foam::cyclicACMIFvPatch::interfaceInternalField
(
const labelUList& internalData
) const
{
return patchInternalField(internalData);
}
Foam::tmp<Foam::labelField> Foam::cyclicACMIFvPatch::internalFieldTransfer
(
const Pstream::commsTypes commsType,
const labelUList& iF
) const
{
return neighbFvPatch().patchInternalField(iF);
}
// ************************************************************************* //

View File

@ -0,0 +1,268 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2013 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::cyclicACMIFvPatch
Description
Cyclic patch for Arbitrarily Coupled Mesh Interface (ACMI)
SourceFiles
cyclicACMIFvPatch.C
\*---------------------------------------------------------------------------*/
#ifndef cyclicACMIFvPatch_H
#define cyclicACMIFvPatch_H
#include "coupledFvPatch.H"
#include "cyclicACMILduInterface.H"
#include "cyclicACMIPolyPatch.H"
#include "fvBoundaryMesh.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class cyclicACMIFvPatch Declaration
\*---------------------------------------------------------------------------*/
class cyclicACMIFvPatch
:
public coupledFvPatch,
public cyclicACMILduInterface
{
// Private data
const cyclicACMIPolyPatch& cyclicACMIPolyPatch_;
protected:
// Protected Member functions
//- Update the patch areas after AMI update
void updateAreas() const;
//- Make patch weighting factors
void makeWeights(scalarField&) const;
public:
//- Runtime type information
TypeName(cyclicACMIPolyPatch::typeName_());
// Constructors
//- Construct from polyPatch
cyclicACMIFvPatch(const polyPatch& patch, const fvBoundaryMesh& bm)
:
coupledFvPatch(patch, bm),
cyclicACMILduInterface(),
cyclicACMIPolyPatch_(refCast<const cyclicACMIPolyPatch>(patch))
{}
// Member functions
// Access
//- Return local reference cast into the cyclic patch
const cyclicACMIPolyPatch& cyclicACMIPatch() const
{
return cyclicACMIPolyPatch_;
}
//- Return neighbour
virtual label neighbPatchID() const
{
return cyclicACMIPolyPatch_.neighbPatchID();
}
virtual bool owner() const
{
return cyclicACMIPolyPatch_.owner();
}
//- Return neighbour fvPatch
virtual const cyclicACMIFvPatch& neighbPatch() const
{
return refCast<const cyclicACMIFvPatch>
(
this->boundaryMesh()[cyclicACMIPolyPatch_.neighbPatchID()]
);
}
//- Return neighbour
virtual label nonOverlapPatchID() const
{
return cyclicACMIPolyPatch_.nonOverlapPatchID();
}
//- Return non-overlapping fvPatch
virtual const fvPatch& nonOverlapPatch() const
{
return this->boundaryMesh()[nonOverlapPatchID()];
}
//- Return a reference to the AMI interpolator
virtual const AMIPatchToPatchInterpolation& AMI() const
{
const AMIPatchToPatchInterpolation& AMI =
cyclicACMIPolyPatch_.AMI();
updateAreas();
return AMI;
}
//- Are the cyclic planes parallel
virtual bool parallel() const
{
return cyclicACMIPolyPatch_.parallel();
}
//- Return face transformation tensor
virtual const tensorField& forwardT() const
{
return cyclicACMIPolyPatch_.forwardT();
}
//- Return neighbour-cell transformation tensor
virtual const tensorField& reverseT() const
{
return cyclicACMIPolyPatch_.reverseT();
}
const cyclicACMIFvPatch& neighbFvPatch() const
{
return refCast<const cyclicACMIFvPatch>
(
this->boundaryMesh()[cyclicACMIPolyPatch_.neighbPatchID()]
);
}
//- Return true if this patch is coupled. This is equivalent
// to the coupledPolyPatch::coupled() if parallel running or
// both sides present, false otherwise
virtual bool coupled() const;
//- Return delta (P to N) vectors across coupled patch
virtual tmp<vectorField> delta() const;
template<class Type>
tmp<Field<Type> > interpolate
(
const Field<Type>& fldCoupled
) const
{
updateAreas();
return
cyclicACMIPolyPatch_.cyclicAMIPolyPatch::interpolate
(
fldCoupled
);
}
template<class Type>
tmp<Field<Type> > interpolate
(
const tmp<Field<Type> >& tfldCoupled
) const
{
updateAreas();
return
cyclicACMIPolyPatch_.cyclicAMIPolyPatch::interpolate
(
tfldCoupled
);
}
template<class Type>
tmp<Field<Type> > interpolate
(
const Field<Type>& fldCoupled,
const Field<Type>& fldNonOverlap
) const
{
updateAreas();
return
cyclicACMIPolyPatch_.interpolate
(
fldCoupled,
fldNonOverlap
);
}
template<class Type>
tmp<Field<Type> > interpolate
(
const tmp<Field<Type> >& tFldCoupled,
const tmp<Field<Type> >& tFldNonOverlap
) const
{
updateAreas();
return
cyclicACMIPolyPatch_.interpolate
(
tFldCoupled,
tFldNonOverlap
);
}
// Interface transfer functions
//- Return the values of the given internal data adjacent to
// the interface as a field
virtual tmp<labelField> interfaceInternalField
(
const labelUList& internalData
) const;
//- Return neighbour field
virtual tmp<labelField> internalFieldTransfer
(
const Pstream::commsTypes commsType,
const labelUList& internalData
) const;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -59,7 +59,11 @@ Foam::MGridGenGAMGAgglomeration::MGridGenGAMGAgglomeration
// Start geometric agglomeration from the cell volumes and areas of the mesh // Start geometric agglomeration from the cell volumes and areas of the mesh
scalarField* VPtr = const_cast<scalarField*>(&fvMesh_.cellVolumes()); scalarField* VPtr = const_cast<scalarField*>(&fvMesh_.cellVolumes());
vectorField* SfPtr = const_cast<vectorField*>(&fvMesh_.faceAreas()); SubField<vector> Sf(fvMesh_.faceAreas(), fvMesh_.nInternalFaces());
vectorField* SfPtr = const_cast<vectorField*>
(
&Sf.operator const vectorField&()
);
// Create the boundary area cell field // Create the boundary area cell field
scalarField* SbPtr(new scalarField(fvMesh_.nCells(), 0)); scalarField* SbPtr(new scalarField(fvMesh_.nCells(), 0));

View File

@ -44,9 +44,7 @@ bool Foam::pairPatchAgglomeration::continueAgglomerating
{ {
// Check the need for further agglomeration on all processors // Check the need for further agglomeration on all processors
label localnCoarseFaces = nCoarseFaces; label localnCoarseFaces = nCoarseFaces;
// reduce(localnCoarseFaces, sumOp<label>());
bool contAgg = localnCoarseFaces >= nFacesInCoarsestLevel_; bool contAgg = localnCoarseFaces >= nFacesInCoarsestLevel_;
//reduce(contAgg, andOp<bool>());
return contAgg; return contAgg;
} }

View File

@ -566,7 +566,11 @@ void Foam::KinematicCloud<CloudType>::checkParcelProperties
{ {
const scalar carrierDt = mesh_.time().deltaTValue(); const scalar carrierDt = mesh_.time().deltaTValue();
parcel.stepFraction() = (carrierDt - lagrangianDt)/carrierDt; parcel.stepFraction() = (carrierDt - lagrangianDt)/carrierDt;
if (parcel.typeId() == -1)
{
parcel.typeId() = constProps_.parcelTypeId(); parcel.typeId() = constProps_.parcelTypeId();
}
} }

View File

@ -2,7 +2,7 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -167,7 +167,8 @@ Foam::ConeNozzleInjection<CloudType>::ConeNozzleInjection
"Foam::ConeNozzleInjection<CloudType>::ConeNozzleInjection" "Foam::ConeNozzleInjection<CloudType>::ConeNozzleInjection"
"(" "("
"const dictionary&, " "const dictionary&, "
"CloudType&" "CloudType&, "
"const word&"
")" ")"
)<< "innerNozzleDiameter >= outerNozzleDiameter" << nl )<< "innerNozzleDiameter >= outerNozzleDiameter" << nl
<< exit(FatalError); << exit(FatalError);
@ -369,6 +370,7 @@ void Foam::ConeNozzleInjection<CloudType>::setPositionAndCell
"const scalar, " "const scalar, "
"vector&, " "vector&, "
"label&, " "label&, "
"label&, "
"label&" "label&"
")" ")"
)<< "Unknown injectionMethod type" << nl )<< "Unknown injectionMethod type" << nl

View File

@ -2,7 +2,7 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -43,6 +43,7 @@ Foam::KinematicLookupTableInjection<CloudType>::KinematicLookupTableInjection
( (
readScalar(this->coeffDict().lookup("parcelsPerSecond")) readScalar(this->coeffDict().lookup("parcelsPerSecond"))
), ),
randomise_(readBool(this->coeffDict().lookup("randomise"))),
injectors_ injectors_
( (
IOobject IOobject
@ -87,6 +88,7 @@ Foam::KinematicLookupTableInjection<CloudType>::KinematicLookupTableInjection
inputFileName_(im.inputFileName_), inputFileName_(im.inputFileName_),
duration_(im.duration_), duration_(im.duration_),
parcelsPerSecond_(im.parcelsPerSecond_), parcelsPerSecond_(im.parcelsPerSecond_),
randomise_(im.randomise_),
injectors_(im.injectors_), injectors_(im.injectors_),
injectorCells_(im.injectorCells_), injectorCells_(im.injectorCells_),
injectorTetFaces_(im.injectorTetFaces_), injectorTetFaces_(im.injectorTetFaces_),
@ -177,7 +179,16 @@ void Foam::KinematicLookupTableInjection<CloudType>::setPositionAndCell
label& tetPtI label& tetPtI
) )
{ {
label injectorI = parcelI*injectorCells_.size()/nParcels; label injectorI = 0;
if (randomise_)
{
cachedRandom& rnd = this->owner().rndGen();
injectorI = rnd.position<label>(0, injectorCells_.size() - 1);
}
else
{
injectorI = parcelI*injectorCells_.size()/nParcels;
}
position = injectors_[injectorI].x(); position = injectors_[injectorI].x();
cellOwner = injectorCells_[injectorI]; cellOwner = injectorCells_[injectorI];

View File

@ -2,7 +2,7 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -78,6 +78,9 @@ class KinematicLookupTableInjection
//- Number of parcels per injector - common to all injection sources //- Number of parcels per injector - common to all injection sources
const scalar parcelsPerSecond_; const scalar parcelsPerSecond_;
//- Flag to indicate to randomise injection positions
bool randomise_;
//- List of injectors //- List of injectors
kinematicParcelInjectionDataIOList injectors_; kinematicParcelInjectionDataIOList injectors_;

View File

@ -2,7 +2,7 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2012 OpenFOAM Foundation \\ / A nd | Copyright (C) 2012-2013 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -141,7 +141,7 @@ Foam::forceSuSp Foam::LiftForce<CloudType>::calcCoupled
scalar Cl = this->Cl(p, curlUc, Re, muc); scalar Cl = this->Cl(p, curlUc, Re, muc);
value.Su() = mass/p.rho()*p.d()/2.0*p.rhoc()*Cl*((p.Uc() - p.U())^curlUc); value.Su() = mass/p.rho()*p.rhoc()*Cl*((p.Uc() - p.U())^curlUc);
return value; return value;
} }

View File

@ -2,7 +2,7 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2011 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -95,7 +95,9 @@ Foam::forceSuSp Foam::SRFForce<CloudType>::calcNonCoupled
const vector& r = p.position(); const vector& r = p.position();
// Coriolis and centrifugal acceleration terms // Coriolis and centrifugal acceleration terms
value.Su() = mass*(2.0*(p.U() ^ omega) + (omega ^ (r ^ omega))); value.Su() =
mass*(1.0 - p.rhoc()/p.rho())
*(2.0*(p.U() ^ omega) + (omega ^ (r ^ omega)));
return value; return value;
} }

View File

@ -2,7 +2,7 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -42,6 +42,7 @@ Foam::ReactingLookupTableInjection<CloudType>::ReactingLookupTableInjection
( (
readScalar(this->coeffDict().lookup("parcelsPerSecond")) readScalar(this->coeffDict().lookup("parcelsPerSecond"))
), ),
randomise_(readBool(this->coeffDict().lookup("randomise"))),
injectors_ injectors_
( (
IOobject IOobject
@ -86,6 +87,7 @@ Foam::ReactingLookupTableInjection<CloudType>::ReactingLookupTableInjection
inputFileName_(im.inputFileName_), inputFileName_(im.inputFileName_),
duration_(im.duration_), duration_(im.duration_),
parcelsPerSecond_(im.parcelsPerSecond_), parcelsPerSecond_(im.parcelsPerSecond_),
randomise_(im.randomise_),
injectors_(im.injectors_), injectors_(im.injectors_),
injectorCells_(im.injectorCells_), injectorCells_(im.injectorCells_),
injectorTetFaces_(im.injectorTetFaces_), injectorTetFaces_(im.injectorTetFaces_),
@ -176,7 +178,16 @@ void Foam::ReactingLookupTableInjection<CloudType>::setPositionAndCell
label& tetPtI label& tetPtI
) )
{ {
label injectorI = parcelI*injectorCells_.size()/nParcels; label injectorI = 0;
if (randomise_)
{
cachedRandom& rnd = this->owner().rndGen();
injectorI = rnd.position<label>(0, injectorCells_.size() - 1);
}
else
{
injectorI = parcelI*injectorCells_.size()/nParcels;
}
position = injectors_[injectorI].x(); position = injectors_[injectorI].x();
cellOwner = injectorCells_[injectorI]; cellOwner = injectorCells_[injectorI];

View File

@ -2,7 +2,7 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -81,6 +81,9 @@ class ReactingLookupTableInjection
//- Number of parcels per injector - common to all injection sources //- Number of parcels per injector - common to all injection sources
const scalar parcelsPerSecond_; const scalar parcelsPerSecond_;
//- Flag to indicate to randomise injection positions
bool randomise_;
//- List of injectors //- List of injectors
reactingParcelInjectionDataIOList injectors_; reactingParcelInjectionDataIOList injectors_;

View File

@ -2,7 +2,7 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -43,6 +43,7 @@ ReactingMultiphaseLookupTableInjection
( (
readScalar(this->coeffDict().lookup("parcelsPerSecond")) readScalar(this->coeffDict().lookup("parcelsPerSecond"))
), ),
randomise_(readBool(this->coeffDict().lookup("randomise"))),
injectors_ injectors_
( (
IOobject IOobject
@ -88,6 +89,7 @@ ReactingMultiphaseLookupTableInjection
inputFileName_(im.inputFileName_), inputFileName_(im.inputFileName_),
duration_(im.duration_), duration_(im.duration_),
parcelsPerSecond_(im.parcelsPerSecond_), parcelsPerSecond_(im.parcelsPerSecond_),
randomise_(im.randomise_),
injectors_(im.injectors_), injectors_(im.injectors_),
injectorCells_(im.injectorCells_), injectorCells_(im.injectorCells_),
injectorTetFaces_(im.injectorTetFaces_), injectorTetFaces_(im.injectorTetFaces_),
@ -182,7 +184,16 @@ void Foam::ReactingMultiphaseLookupTableInjection<CloudType>::setPositionAndCell
label& tetPtI label& tetPtI
) )
{ {
label injectorI = parcelI*injectorCells_.size()/nParcels; label injectorI = 0;
if (randomise_)
{
cachedRandom& rnd = this->owner().rndGen();
injectorI = rnd.position<label>(0, injectorCells_.size() - 1);
}
else
{
injectorI = parcelI*injectorCells_.size()/nParcels;
}
position = injectors_[injectorI].x(); position = injectors_[injectorI].x();
cellOwner = injectorCells_[injectorI]; cellOwner = injectorCells_[injectorI];

View File

@ -2,7 +2,7 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -84,6 +84,9 @@ class ReactingMultiphaseLookupTableInjection
//- Number of parcels per injector - common to all injection sources //- Number of parcels per injector - common to all injection sources
const scalar parcelsPerSecond_; const scalar parcelsPerSecond_;
//- Flag to indicate to randomise injection positions
bool randomise_;
//- List of injectors //- List of injectors
reactingMultiphaseParcelInjectionDataIOList injectors_; reactingMultiphaseParcelInjectionDataIOList injectors_;

View File

@ -2,7 +2,7 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -43,6 +43,7 @@ Foam::ThermoLookupTableInjection<CloudType>::ThermoLookupTableInjection
( (
readScalar(this->coeffDict().lookup("parcelsPerSecond")) readScalar(this->coeffDict().lookup("parcelsPerSecond"))
), ),
randomise_(readBool(this->coeffDict().lookup("randomise"))),
injectors_ injectors_
( (
IOobject IOobject
@ -87,6 +88,7 @@ Foam::ThermoLookupTableInjection<CloudType>::ThermoLookupTableInjection
inputFileName_(im.inputFileName_), inputFileName_(im.inputFileName_),
duration_(im.duration_), duration_(im.duration_),
parcelsPerSecond_(im.parcelsPerSecond_), parcelsPerSecond_(im.parcelsPerSecond_),
randomise_(im.randomise_),
injectors_(im.injectors_), injectors_(im.injectors_),
injectorCells_(im.injectorCells_), injectorCells_(im.injectorCells_),
injectorTetFaces_(im.injectorTetFaces_), injectorTetFaces_(im.injectorTetFaces_),
@ -177,7 +179,16 @@ void Foam::ThermoLookupTableInjection<CloudType>::setPositionAndCell
label& tetPtI label& tetPtI
) )
{ {
label injectorI = parcelI*injectorCells_.size()/nParcels; label injectorI = 0;
if (randomise_)
{
cachedRandom& rnd = this->owner().rndGen();
injectorI = rnd.position<label>(0, injectorCells_.size() - 1);
}
else
{
injectorI = parcelI*injectorCells_.size()/nParcels;
}
position = injectors_[injectorI].x(); position = injectors_[injectorI].x();
cellOwner = injectorCells_[injectorI]; cellOwner = injectorCells_[injectorI];

View File

@ -2,7 +2,7 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -80,6 +80,9 @@ class ThermoLookupTableInjection
//- Number of parcels per injector - common to all injection sources //- Number of parcels per injector - common to all injection sources
const scalar parcelsPerSecond_; const scalar parcelsPerSecond_;
//- Flag to indicate to randomise injection positions
bool randomise_;
//- List of injectors //- List of injectors
kinematicParcelInjectionDataIOList injectors_; kinematicParcelInjectionDataIOList injectors_;

View File

@ -336,7 +336,7 @@ void Foam::autoLayerDriver::smoothNormals
) const ) const
{ {
// Get smoothly varying internal normals field. // Get smoothly varying internal normals field.
Info<< "shrinkMeshDistance : Smoothing normals ..." << endl; Info<< "shrinkMeshDistance : Smoothing normals in interior ..." << endl;
const fvMesh& mesh = meshRefiner_.mesh(); const fvMesh& mesh = meshRefiner_.mesh();
const edgeList& edges = mesh.edges(); const edgeList& edges = mesh.edges();
@ -1161,6 +1161,11 @@ void Foam::autoLayerDriver::medialAxisSmoothingInfo
scalar mDist = medialDist[pointI]; scalar mDist = medialDist[pointI];
if (wDist2 < sqr(SMALL) && mDist < SMALL) if (wDist2 < sqr(SMALL) && mDist < SMALL)
//- Note: maybe less strict:
//(
// wDist2 < sqr(meshRefiner_.mergeDistance())
// && mDist < meshRefiner_.mergeDistance()
//)
{ {
medialRatio[pointI] = 0.0; medialRatio[pointI] = 0.0;
} }

View File

@ -46,9 +46,6 @@ defineTypeNameAndDebug(autoRefineDriver, 0);
} // End namespace Foam } // End namespace Foam
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
// Construct from components // Construct from components
@ -97,12 +94,14 @@ Foam::label Foam::autoRefineDriver::featureEdgeRefine
( (
refineParams.keepPoints()[0], // For now only use one. refineParams.keepPoints()[0], // For now only use one.
refineParams.curvature(), refineParams.curvature(),
refineParams.planarAngle(),
true, // featureRefinement true, // featureRefinement
false, // featureDistanceRefinement false, // featureDistanceRefinement
false, // internalRefinement false, // internalRefinement
false, // surfaceRefinement false, // surfaceRefinement
false, // curvatureRefinement false, // curvatureRefinement
false, // gapRefinement
refineParams.maxGlobalCells(), refineParams.maxGlobalCells(),
refineParams.maxLocalCells() refineParams.maxLocalCells()
) )
@ -208,12 +207,14 @@ Foam::label Foam::autoRefineDriver::surfaceOnlyRefine
( (
refineParams.keepPoints()[0], refineParams.keepPoints()[0],
refineParams.curvature(), refineParams.curvature(),
refineParams.planarAngle(),
false, // featureRefinement false, // featureRefinement
false, // featureDistanceRefinement false, // featureDistanceRefinement
false, // internalRefinement false, // internalRefinement
true, // surfaceRefinement true, // surfaceRefinement
true, // curvatureRefinement true, // curvatureRefinement
false, // gapRefinement
refineParams.maxGlobalCells(), refineParams.maxGlobalCells(),
refineParams.maxLocalCells() refineParams.maxLocalCells()
) )
@ -294,6 +295,371 @@ Foam::label Foam::autoRefineDriver::surfaceOnlyRefine
} }
Foam::label Foam::autoRefineDriver::gapOnlyRefine
(
const refinementParameters& refineParams,
const label maxIter
)
{
const fvMesh& mesh = meshRefiner_.mesh();
// Determine the maximum refinement level over all surfaces. This
// determines the minumum number of surface refinement iterations.
label maxIncrement = 0;
const labelList& maxLevel = meshRefiner_.surfaces().maxLevel();
const labelList& gapLevel = meshRefiner_.surfaces().gapLevel();
forAll(maxLevel, i)
{
maxIncrement = max(maxIncrement, gapLevel[i]-maxLevel[i]);
}
label iter = 0;
if (maxIncrement == 0)
{
return iter;
}
for (iter = 0; iter < maxIter; iter++)
{
Info<< nl
<< "Gap refinement iteration " << iter << nl
<< "--------------------------" << nl
<< endl;
// Determine cells to refine
// ~~~~~~~~~~~~~~~~~~~~~~~~~
// Only look at surface intersections (minLevel and surface curvature),
// do not do internal refinement (refinementShells)
labelList candidateCells
(
meshRefiner_.refineCandidates
(
refineParams.keepPoints()[0],
refineParams.curvature(),
refineParams.planarAngle(),
false, // featureRefinement
false, // featureDistanceRefinement
false, // internalRefinement
false, // surfaceRefinement
false, // curvatureRefinement
true, // gapRefinement
refineParams.maxGlobalCells(),
refineParams.maxLocalCells()
)
);
if (debug&meshRefinement::MESH)
{
Pout<< "Dumping " << candidateCells.size()
<< " cells to cellSet candidateCellsFromGap." << endl;
cellSet c(mesh, "candidateCellsFromGap", candidateCells);
c.instance() = meshRefiner_.timeName();
c.write();
}
// Grow by one layer to make sure we're covering the gap
{
boolList isCandidateCell(mesh.nCells(), false);
forAll(candidateCells, i)
{
isCandidateCell[candidateCells[i]] = true;
}
for (label i=0; i<1; i++)
{
boolList newIsCandidateCell(isCandidateCell);
// Internal faces
for (label faceI = 0; faceI < mesh.nInternalFaces(); faceI++)
{
label own = mesh.faceOwner()[faceI];
label nei = mesh.faceNeighbour()[faceI];
if (isCandidateCell[own] != isCandidateCell[nei])
{
newIsCandidateCell[own] = true;
newIsCandidateCell[nei] = true;
}
}
// Get coupled boundary condition values
boolList neiIsCandidateCell;
syncTools::swapBoundaryCellList
(
mesh,
isCandidateCell,
neiIsCandidateCell
);
// Boundary faces
for
(
label faceI = mesh.nInternalFaces();
faceI < mesh.nFaces();
faceI++
)
{
label own = mesh.faceOwner()[faceI];
label bFaceI = faceI-mesh.nInternalFaces();
if (isCandidateCell[own] != neiIsCandidateCell[bFaceI])
{
newIsCandidateCell[own] = true;
}
}
isCandidateCell.transfer(newIsCandidateCell);
}
label n = 0;
forAll(isCandidateCell, cellI)
{
if (isCandidateCell[cellI])
{
n++;
}
}
candidateCells.setSize(n);
n = 0;
forAll(isCandidateCell, cellI)
{
if (isCandidateCell[cellI])
{
candidateCells[n++] = cellI;
}
}
}
if (debug&meshRefinement::MESH)
{
Pout<< "Dumping " << candidateCells.size()
<< " cells to cellSet candidateCellsFromGapPlusBuffer." << endl;
cellSet c(mesh, "candidateCellsFromGapPlusBuffer", candidateCells);
c.instance() = meshRefiner_.timeName();
c.write();
}
labelList cellsToRefine
(
meshRefiner_.meshCutter().consistentRefinement
(
candidateCells,
true
)
);
Info<< "Determined cells to refine in = "
<< mesh.time().cpuTimeIncrement() << " s" << endl;
label nCellsToRefine = cellsToRefine.size();
reduce(nCellsToRefine, sumOp<label>());
Info<< "Selected for refinement : " << nCellsToRefine
<< " cells (out of " << mesh.globalData().nTotalCells()
<< ')' << endl;
// Stop when no cells to refine or have done minimum necessary
// iterations and not enough cells to refine.
if
(
nCellsToRefine == 0
|| (
iter >= maxIncrement
&& nCellsToRefine <= refineParams.minRefineCells()
)
)
{
Info<< "Stopping refining since too few cells selected."
<< nl << endl;
break;
}
if (debug)
{
const_cast<Time&>(mesh.time())++;
}
if
(
returnReduce
(
(mesh.nCells() >= refineParams.maxLocalCells()),
orOp<bool>()
)
)
{
meshRefiner_.balanceAndRefine
(
"gap refinement iteration " + name(iter),
decomposer_,
distributor_,
cellsToRefine,
refineParams.maxLoadUnbalance()
);
}
else
{
meshRefiner_.refineAndBalance
(
"gap refinement iteration " + name(iter),
decomposer_,
distributor_,
cellsToRefine,
refineParams.maxLoadUnbalance()
);
}
}
return iter;
}
Foam::label Foam::autoRefineDriver::danglingCellRefine
(
const refinementParameters& refineParams,
const label nFaces,
const label maxIter
)
{
const fvMesh& mesh = meshRefiner_.mesh();
label iter;
for (iter = 0; iter < maxIter; iter++)
{
Info<< nl
<< "Dangling coarse cells refinement iteration " << iter << nl
<< "--------------------------------------------" << nl
<< endl;
// Determine cells to refine
// ~~~~~~~~~~~~~~~~~~~~~~~~~
const cellList& cells = mesh.cells();
const polyBoundaryMesh& pbm = mesh.boundaryMesh();
labelList candidateCells;
{
cellSet candidateCellSet(mesh, "candidateCells", cells.size()/1000);
forAll(cells, cellI)
{
const cell& cFaces = cells[cellI];
label nIntFaces = 0;
forAll(cFaces, i)
{
label bFaceI = cFaces[i]-mesh.nInternalFaces();
if (bFaceI < 0)
{
nIntFaces++;
}
else
{
label patchI = pbm.patchID()[bFaceI];
if (pbm[patchI].coupled())
{
nIntFaces++;
}
}
}
if (nIntFaces == nFaces)
{
candidateCellSet.insert(cellI);
}
}
if (debug&meshRefinement::MESH)
{
Pout<< "Dumping " << candidateCellSet.size()
<< " cells to cellSet candidateCellSet." << endl;
candidateCellSet.instance() = meshRefiner_.timeName();
candidateCellSet.write();
}
candidateCells = candidateCellSet.toc();
}
labelList cellsToRefine
(
meshRefiner_.meshCutter().consistentRefinement
(
candidateCells,
true
)
);
Info<< "Determined cells to refine in = "
<< mesh.time().cpuTimeIncrement() << " s" << endl;
label nCellsToRefine = cellsToRefine.size();
reduce(nCellsToRefine, sumOp<label>());
Info<< "Selected for refinement : " << nCellsToRefine
<< " cells (out of " << mesh.globalData().nTotalCells()
<< ')' << endl;
// Stop when no cells to refine. No checking of minRefineCells since
// too few cells
if (nCellsToRefine == 0)
{
Info<< "Stopping refining since too few cells selected."
<< nl << endl;
break;
}
if (debug)
{
const_cast<Time&>(mesh.time())++;
}
if
(
returnReduce
(
(mesh.nCells() >= refineParams.maxLocalCells()),
orOp<bool>()
)
)
{
meshRefiner_.balanceAndRefine
(
"coarse cell refinement iteration " + name(iter),
decomposer_,
distributor_,
cellsToRefine,
refineParams.maxLoadUnbalance()
);
}
else
{
meshRefiner_.refineAndBalance
(
"coarse cell refinement iteration " + name(iter),
decomposer_,
distributor_,
cellsToRefine,
refineParams.maxLoadUnbalance()
);
}
}
return iter;
}
void Foam::autoRefineDriver::removeInsideCells void Foam::autoRefineDriver::removeInsideCells
( (
const refinementParameters& refineParams, const refinementParameters& refineParams,
@ -371,12 +737,14 @@ Foam::label Foam::autoRefineDriver::shellRefine
( (
refineParams.keepPoints()[0], refineParams.keepPoints()[0],
refineParams.curvature(), refineParams.curvature(),
refineParams.planarAngle(),
false, // featureRefinement false, // featureRefinement
true, // featureDistanceRefinement true, // featureDistanceRefinement
true, // internalRefinement true, // internalRefinement
false, // surfaceRefinement false, // surfaceRefinement
false, // curvatureRefinement false, // curvatureRefinement
false, // gapRefinement
refineParams.maxGlobalCells(), refineParams.maxGlobalCells(),
refineParams.maxLocalCells() refineParams.maxLocalCells()
) )
@ -522,6 +890,7 @@ void Foam::autoRefineDriver::baffleAndSplitMesh
false, // perpendicular edge connected cells false, // perpendicular edge connected cells
scalarField(0), // per region perpendicular angle scalarField(0), // per region perpendicular angle
!handleSnapProblems, // merge free standing baffles? !handleSnapProblems, // merge free standing baffles?
refineParams.planarAngle(),
motionDict, motionDict,
const_cast<Time&>(mesh.time()), const_cast<Time&>(mesh.time()),
globalToMasterPatch_, globalToMasterPatch_,
@ -606,8 +975,8 @@ void Foam::autoRefineDriver::splitAndMergeBaffles
handleSnapProblems, handleSnapProblems,
handleSnapProblems, // remove perp edge connected cells handleSnapProblems, // remove perp edge connected cells
perpAngle, // perp angle perpAngle, // perp angle
false, // merge free standing baffles? true, // merge free standing baffles?
//true, // merge free standing baffles? refineParams.planarAngle(), // planar angle
motionDict, motionDict,
const_cast<Time&>(mesh.time()), const_cast<Time&>(mesh.time()),
globalToMasterPatch_, globalToMasterPatch_,
@ -652,6 +1021,16 @@ void Foam::autoRefineDriver::splitAndMergeBaffles
// Debug:test all is still synced across proc patches // Debug:test all is still synced across proc patches
meshRefiner_.checkData(); meshRefiner_.checkData();
} }
// Remove any now dangling parts
meshRefiner_.splitMeshRegions(refineParams.keepPoints()[0]);
if (debug)
{
// Debug:test all is still synced across proc patches
meshRefiner_.checkData();
}
Info<< "Merged free-standing baffles in = " Info<< "Merged free-standing baffles in = "
<< mesh.time().cpuTimeIncrement() << " s." << endl; << mesh.time().cpuTimeIncrement() << " s." << endl;
} }
@ -731,6 +1110,12 @@ void Foam::autoRefineDriver::doRefine
100 // maxIter 100 // maxIter
); );
gapOnlyRefine
(
refineParams,
100 // maxIter
);
// Remove cells (a certain distance) beyond surface intersections // Remove cells (a certain distance) beyond surface intersections
removeInsideCells removeInsideCells
( (
@ -745,6 +1130,20 @@ void Foam::autoRefineDriver::doRefine
100 // maxIter 100 // maxIter
); );
// Refine any hexes with 5 or 6 faces refined to make smooth edges
danglingCellRefine
(
refineParams,
21, // 1 coarse face + 5 refined faces
100 // maxIter
);
danglingCellRefine
(
refineParams,
24, // 0 coarse faces + 6 refined faces
100 // maxIter
);
// Introduce baffles at surface intersections. Remove sections unreachable // Introduce baffles at surface intersections. Remove sections unreachable
// from keepPoint. // from keepPoint.
baffleAndSplitMesh(refineParams, prepareForSnapping, motionDict); baffleAndSplitMesh(refineParams, prepareForSnapping, motionDict);

View File

@ -2,7 +2,7 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -88,6 +88,21 @@ class autoRefineDriver
const label maxIter const label maxIter
); );
//- Refine all cells in small gaps
label gapOnlyRefine
(
const refinementParameters& refineParams,
const label maxIter
);
//- Refine cells with almost all sides refined
label danglingCellRefine
(
const refinementParameters& refineParams,
const label nFaces,
const label maxIter
);
//- Remove all cells within intersected region //- Remove all cells within intersected region
void removeInsideCells void removeInsideCells
( (

View File

@ -2,7 +2,7 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -41,6 +41,7 @@ Foam::refinementParameters::refinementParameters
maxLocalCells_(readLabel(dict.lookup("procCellLimit"))), maxLocalCells_(readLabel(dict.lookup("procCellLimit"))),
minRefineCells_(readLabel(dict.lookup("minimumRefine"))), minRefineCells_(readLabel(dict.lookup("minimumRefine"))),
curvature_(readScalar(dict.lookup("curvature"))), curvature_(readScalar(dict.lookup("curvature"))),
planarAngle_(dict.lookupOrDefault("planarAngle", curvature_)),
nBufferLayers_(readLabel(dict.lookup("nBufferLayers"))), nBufferLayers_(readLabel(dict.lookup("nBufferLayers"))),
keepPoints_(dict.lookup("keepPoints")), keepPoints_(dict.lookup("keepPoints")),
allowFreeStandingZoneFaces_(dict.lookup("allowFreeStandingZoneFaces")), allowFreeStandingZoneFaces_(dict.lookup("allowFreeStandingZoneFaces")),
@ -53,6 +54,14 @@ Foam::refinementParameters::refinementParameters(const dictionary& dict)
maxGlobalCells_(readLabel(dict.lookup("maxGlobalCells"))), maxGlobalCells_(readLabel(dict.lookup("maxGlobalCells"))),
maxLocalCells_(readLabel(dict.lookup("maxLocalCells"))), maxLocalCells_(readLabel(dict.lookup("maxLocalCells"))),
minRefineCells_(readLabel(dict.lookup("minRefinementCells"))), minRefineCells_(readLabel(dict.lookup("minRefinementCells"))),
planarAngle_
(
dict.lookupOrDefault
(
"planarAngle",
readScalar(dict.lookup("resolveFeatureAngle"))
)
),
nBufferLayers_(readLabel(dict.lookup("nCellsBetweenLevels"))), nBufferLayers_(readLabel(dict.lookup("nCellsBetweenLevels"))),
keepPoints_(pointField(1, dict.lookup("locationInMesh"))), keepPoints_(pointField(1, dict.lookup("locationInMesh"))),
allowFreeStandingZoneFaces_(dict.lookup("allowFreeStandingZoneFaces")), allowFreeStandingZoneFaces_(dict.lookup("allowFreeStandingZoneFaces")),

View File

@ -2,7 +2,7 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2011 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -67,6 +67,9 @@ class refinementParameters
//- Curvature //- Curvature
scalar curvature_; scalar curvature_;
//- Planarity criterion
scalar planarAngle_;
//- Number of layers between different refinement levels //- Number of layers between different refinement levels
const label nBufferLayers_; const label nBufferLayers_;
@ -129,6 +132,12 @@ public:
return curvature_; return curvature_;
} }
//- Angle when two intersections are considered to be planar
scalar planarAngle() const
{
return planarAngle_;
}
//- Number of layers between different refinement levels //- Number of layers between different refinement levels
label nBufferLayers() const label nBufferLayers() const
{ {

View File

@ -253,6 +253,14 @@ private:
label& nRefine label& nRefine
); );
//- Mark every cell with level of feature passing through it
// (or -1 if not passed through). Uses tracking.
void markFeatureCellLevel
(
const point& keepPoint,
labelList& maxFeatureLevel
) const;
//- Calculate list of cells to refine based on intersection of //- Calculate list of cells to refine based on intersection of
// features. // features.
label markFeatureRefinement label markFeatureRefinement
@ -327,6 +335,48 @@ private:
label& nRefine label& nRefine
) const; ) const;
//- Is local topology a small gap?
bool isGap
(
const scalar,
const vector&,
const vector&,
const vector&,
const vector&
) const;
//- Mark cell if local a gap topology or
bool checkProximity
(
const scalar planarCos,
const label nAllowRefine,
const label surfaceLevel,
const vector& surfaceLocation,
const vector& surfaceNormal,
const label cellI,
label& cellMaxLevel,
vector& cellMaxLocation,
vector& cellMaxNormal,
labelList& refineCell,
label& nRefine
) const;
//- Mark cells for surface proximity based refinement.
label markProximityRefinement
(
const scalar curvature,
const label nAllowRefine,
const labelList& neiLevel,
const pointField& neiCc,
labelList& refineCell,
label& nRefine
) const;
// Baffle handling // Baffle handling
//- Get faces to repatch. Returns map from face to patch. //- Get faces to repatch. Returns map from face to patch.
@ -337,16 +387,6 @@ private:
const labelList& globalToSlavePatch const labelList& globalToSlavePatch
) const; ) const;
//- Geometric test on see whether face needs to be baffled:
// is face boundary face and perpendicular to surface normal?
bool validBaffleTopology
(
const label faceI,
const vector& n1,
const vector& n2,
const vector& testDir
) const;
//- Determine patches for baffles //- Determine patches for baffles
void getBafflePatches void getBafflePatches
( (
@ -435,7 +475,11 @@ private:
//- Extract those baffles (duplicate) faces that are on the edge //- Extract those baffles (duplicate) faces that are on the edge
// of a baffle region. These are candidates for merging. // of a baffle region. These are candidates for merging.
List<labelPair> freeStandingBaffles(const List<labelPair>&) const; List<labelPair> freeStandingBaffles
(
const List<labelPair>&,
const scalar freeStandingAngle
) const;
// Zone handling // Zone handling
@ -489,6 +533,16 @@ private:
labelList& namedSurfaceIndex labelList& namedSurfaceIndex
) const; ) const;
//- Remove any loose standing cells
void handleSnapProblems
(
const bool removeEdgeConnectedCells,
const scalarField& perpendicularAngle,
const dictionary& motionDict,
Time& runTime,
const labelList& globalToMasterPatch,
const labelList& globalToSlavePatch
);
//- Disallow default bitwise copy construct //- Disallow default bitwise copy construct
meshRefinement(const meshRefinement&); meshRefinement(const meshRefinement&);
@ -664,12 +718,14 @@ public:
( (
const point& keepPoint, const point& keepPoint,
const scalar curvature, const scalar curvature,
const scalar planarAngle,
const bool featureRefinement, const bool featureRefinement,
const bool featureDistanceRefinement, const bool featureDistanceRefinement,
const bool internalRefinement, const bool internalRefinement,
const bool surfaceRefinement, const bool surfaceRefinement,
const bool curvatureRefinement, const bool curvatureRefinement,
const bool gapRefinement,
const label maxGlobalCells, const label maxGlobalCells,
const label maxLocalCells const label maxLocalCells
) const; ) const;
@ -707,6 +763,7 @@ public:
const bool removeEdgeConnectedCells, const bool removeEdgeConnectedCells,
const scalarField& perpendicularAngle, const scalarField& perpendicularAngle,
const bool mergeFreeStanding, const bool mergeFreeStanding,
const scalar freeStandingAngle,
const dictionary& motionDict, const dictionary& motionDict,
Time& runTime, Time& runTime,
const labelList& globalToMasterPatch, const labelList& globalToMasterPatch,

View File

@ -44,6 +44,7 @@ License
#include "regionSplit.H" #include "regionSplit.H"
#include "removeCells.H" #include "removeCells.H"
#include "unitConversion.H" #include "unitConversion.H"
#include "OBJstream.H"
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
@ -217,43 +218,43 @@ Foam::label Foam::meshRefinement::getBafflePatch
} }
// Check if we are a boundary face and normal of surface does //// Check if we are a boundary face and normal of surface does
// not align with test vector. In this case there'd probably be //// not align with test vector. In this case there'd probably be
// a freestanding 'baffle' so we might as well not create it. //// a freestanding 'baffle' so we might as well not create it.
// Note that since it is not a proper baffle we cannot detect it //// Note that since it is not a proper baffle we cannot detect it
// afterwards so this code cannot be merged with the //// afterwards so this code cannot be merged with the
// filterDuplicateFaces code. //// filterDuplicateFaces code.
bool Foam::meshRefinement::validBaffleTopology //bool Foam::meshRefinement::validBaffleTopology
( //(
const label faceI, // const label faceI,
const vector& n1, // const vector& n1,
const vector& n2, // const vector& n2,
const vector& testDir // const vector& testDir
) const //) const
{ //{
//
label patchI = mesh_.boundaryMesh().whichPatch(faceI); // label patchI = mesh_.boundaryMesh().whichPatch(faceI);
if (patchI == -1 || mesh_.boundaryMesh()[patchI].coupled()) // if (patchI == -1 || mesh_.boundaryMesh()[patchI].coupled())
{ // {
return true; // return true;
} // }
else if (mag(n1&n2) > cos(degToRad(30))) // else if (mag(n1&n2) > cos(degToRad(30)))
{ // {
// Both normals aligned. Check that test vector perpendicularish to // // Both normals aligned. Check that test vector perpendicularish to
// surface normal // // surface normal
scalar magTestDir = mag(testDir); // scalar magTestDir = mag(testDir);
if (magTestDir > VSMALL) // if (magTestDir > VSMALL)
{ // {
if (mag(n1&(testDir/magTestDir)) < cos(degToRad(45))) // if (mag(n1&(testDir/magTestDir)) < cos(degToRad(45)))
{ // {
//Pout<< "** disabling baffling face " // //Pout<< "** disabling baffling face "
// << mesh_.faceCentres()[faceI] << endl; // // << mesh_.faceCentres()[faceI] << endl;
return false; // return false;
} // }
} // }
} // }
return true; // return true;
} //}
// Determine patches for baffles on all intersected unnamed faces // Determine patches for baffles on all intersected unnamed faces
@ -800,7 +801,8 @@ Foam::autoPtr<Foam::mapPolyMesh> Foam::meshRefinement::createZoneBaffles
// region. // region.
Foam::List<Foam::labelPair> Foam::meshRefinement::freeStandingBaffles Foam::List<Foam::labelPair> Foam::meshRefinement::freeStandingBaffles
( (
const List<labelPair>& couples const List<labelPair>& couples,
const scalar planarAngle
) const ) const
{ {
// All duplicate faces on edge of the patch are to be merged. // All duplicate faces on edge of the patch are to be merged.
@ -809,6 +811,22 @@ Foam::List<Foam::labelPair> Foam::meshRefinement::freeStandingBaffles
labelList nBafflesPerEdge(mesh_.nEdges(), 0); labelList nBafflesPerEdge(mesh_.nEdges(), 0);
// This algorithm is quite tricky. We don't want to use edgeFaces and
// also want it to run in parallel so it is now an algorithm over
// all (boundary) faces instead.
// We want to pick up any edges that are only used by the baffle
// or internal faces but not by any other boundary faces. So
// - increment count on an edge by 1 if it is used by any (uncoupled)
// boundary face.
// - increment count on an edge by 1000000 if it is used by a baffle face
// - sum in parallel
//
// So now any edge that is used by baffle faces only will have the
// value 2*1000000+2*1.
const label baffleValue = 1000000;
// Count number of boundary faces per edge // Count number of boundary faces per edge
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@ -847,18 +865,22 @@ Foam::List<Foam::labelPair> Foam::meshRefinement::freeStandingBaffles
forAll(couples, i) forAll(couples, i)
{ {
const labelList& fEdges0 = mesh_.faceEdges(couples[i].first(), fe0); {
label f0 = couples[i].first();
const labelList& fEdges0 = mesh_.faceEdges(f0, fe0);
forAll(fEdges0, fEdgeI) forAll(fEdges0, fEdgeI)
{ {
nBafflesPerEdge[fEdges0[fEdgeI]] += 1000000; nBafflesPerEdge[fEdges0[fEdgeI]] += baffleValue;
}
} }
const labelList& fEdges1 = mesh_.faceEdges(couples[i].second(), fe1); {
label f1 = couples[i].second();
const labelList& fEdges1 = mesh_.faceEdges(f1, fe1);
forAll(fEdges1, fEdgeI) forAll(fEdges1, fEdgeI)
{ {
nBafflesPerEdge[fEdges1[fEdgeI]] += 1000000; nBafflesPerEdge[fEdges1[fEdgeI]] += baffleValue;
}
} }
} }
@ -873,8 +895,8 @@ Foam::List<Foam::labelPair> Foam::meshRefinement::freeStandingBaffles
// Baffles which are not next to other boundaries and baffles will have // Baffles which are not next to other boundaries and baffles will have
// nBafflesPerEdge value 2*1000000+2*1 (from 2 boundary faces which are // nBafflesPerEdge value 2*baffleValue+2*1 (from 2 boundary faces which
// both baffle faces) // are both baffle faces)
List<labelPair> filteredCouples(couples.size()); List<labelPair> filteredCouples(couples.size());
label filterI = 0; label filterI = 0;
@ -889,15 +911,15 @@ Foam::List<Foam::labelPair> Foam::meshRefinement::freeStandingBaffles
== patches.whichPatch(couple.second()) == patches.whichPatch(couple.second())
) )
{ {
const labelList& fEdges = mesh_.faceEdges(couples[i].first()); const labelList& fEdges = mesh_.faceEdges(couple.first());
forAll(fEdges, fEdgeI) forAll(fEdges, fEdgeI)
{ {
label edgeI = fEdges[fEdgeI]; label edgeI = fEdges[fEdgeI];
if (nBafflesPerEdge[edgeI] == 2*1000000+2*1) if (nBafflesPerEdge[edgeI] == 2*baffleValue+2*1)
{ {
filteredCouples[filterI++] = couples[i]; filteredCouples[filterI++] = couple;
break; break;
} }
} }
@ -905,111 +927,127 @@ Foam::List<Foam::labelPair> Foam::meshRefinement::freeStandingBaffles
} }
filteredCouples.setSize(filterI); filteredCouples.setSize(filterI);
//Info<< "freeStandingBaffles : from "
// << returnReduce(couples.size(), sumOp<label>()) label nFiltered = returnReduce(filteredCouples.size(), sumOp<label>());
// << " down to "
// << returnReduce(filteredCouples.size(), sumOp<label>()) Info<< "freeStandingBaffles : detected "
// << " baffles." << nl << endl; << nFiltered
<< " free-standing baffles out of "
<< returnReduce(couples.size(), sumOp<label>())
<< nl << endl;
if (nFiltered > 0)
{
// Collect segments
// ~~~~~~~~~~~~~~~~
//XXXXXX pointField start(filteredCouples.size());
// { pointField end(filteredCouples.size());
// // Collect segments
// // ~~~~~~~~~~~~~~~~
//
// pointField start(filteredCouples.size());
// pointField end(filteredCouples.size());
//
// const pointField& cellCentres = mesh_.cellCentres();
//
// forAll(filteredCouples, i)
// {
// const labelPair& couple = couples[i];
// start[i] = cellCentres[mesh_.faceOwner()[couple.first()]];
// end[i] = cellCentres[mesh_.faceOwner()[couple.second()]];
// }
//
// // Extend segments a bit
// {
// const vectorField smallVec(Foam::sqrt(SMALL)*(end-start));
// start -= smallVec;
// end += smallVec;
// }
//
//
// // Do test for intersections
// // ~~~~~~~~~~~~~~~~~~~~~~~~~
// labelList surface1;
// List<pointIndexHit> hit1;
// labelList region1;
// vectorField normal1;
//
// labelList surface2;
// List<pointIndexHit> hit2;
// labelList region2;
// vectorField normal2;
//
// surfaces_.findNearestIntersection
// (
// surfacesToBaffle,
// start,
// end,
//
// surface1,
// hit1,
// region1,
// normal1,
//
// surface2,
// hit2,
// region2,
// normal2
// );
//
// forAll(testFaces, i)
// {
// if (hit1[i].hit() && hit2[i].hit())
// {
// bool createBaffle = true;
//
// label faceI = couples[i].first();
// label patchI = mesh_.boundaryMesh().whichPatch(faceI);
// if (patchI != -1 && !mesh_.boundaryMesh()[patchI].coupled())
// {
// // Check if we are a boundary face and normal of surface
// // does
// // not align with test vector. In this case there'd
// // probably be
// // a freestanding 'baffle' so we might as well not
// // create it.
// // Note that since it is not a proper baffle we cannot
// // detect it
// // afterwards so this code cannot be merged with the
// // filterDuplicateFaces code.
// if (mag(normal1[i]&normal2[i]) > cos(degToRad(30)))
// {
// // Both normals aligned
// vector n = end[i]-start[i];
// scalar magN = mag(n);
// if (magN > VSMALL)
// {
// n /= magN;
//
// if (mag(normal1[i]&n) < cos(degToRad(45)))
// {
// Pout<< "** disabling baffling face "
// << mesh_.faceCentres()[faceI] << endl;
// createBaffle = false;
// }
// }
// }
// }
//
//
// }
//XXXXXX
const pointField& cellCentres = mesh_.cellCentres();
forAll(filteredCouples, i)
{
const labelPair& couple = filteredCouples[i];
start[i] = cellCentres[mesh_.faceOwner()[couple.first()]];
end[i] = cellCentres[mesh_.faceOwner()[couple.second()]];
}
// Extend segments a bit
{
const vectorField smallVec(Foam::sqrt(SMALL)*(end-start));
start -= smallVec;
end += smallVec;
}
// Do test for intersections
// ~~~~~~~~~~~~~~~~~~~~~~~~~
labelList surface1;
List<pointIndexHit> hit1;
labelList region1;
vectorField normal1;
labelList surface2;
List<pointIndexHit> hit2;
labelList region2;
vectorField normal2;
surfaces_.findNearestIntersection
(
identity(surfaces_.surfaces().size()),
start,
end,
surface1,
hit1,
region1,
normal1,
surface2,
hit2,
region2,
normal2
);
//mkDir(mesh_.time().path()/timeName());
//OBJstream str
//(
// mesh_.time().path()/timeName()/"flatBaffles.obj"
//);
const scalar planarAngleCos = Foam::cos(degToRad(planarAngle));
label filterI = 0;
forAll(filteredCouples, i)
{
const labelPair& couple = filteredCouples[i];
if
(
hit1[i].hit()
&& hit2[i].hit()
&& (
surface1[i] != surface2[i]
|| hit1[i].index() != hit2[i].index()
)
)
{
// Two different hits. Check angle.
//str.write
//(
// linePointRef(hit1[i].hitPoint(), hit2[i].hitPoint()),
// normal1[i],
// normal2[i]
//);
if ((normal1[i]&normal2[i]) > planarAngleCos)
{
// Both normals aligned
vector n = end[i]-start[i];
scalar magN = mag(n);
if (magN > VSMALL)
{
filteredCouples[filterI++] = couple;
}
}
}
else if (hit1[i].hit() || hit2[i].hit())
{
// Single hit. Do not include in freestanding baffles.
}
}
filteredCouples.setSize(filterI);
Info<< "freeStandingBaffles : detected "
<< returnReduce(filterI, sumOp<label>())
<< " planar (within " << planarAngle
<< " degrees) free-standing baffles out of "
<< nFiltered
<< nl << endl;
}
return filteredCouples; return filteredCouples;
} }
@ -1832,15 +1870,102 @@ void Foam::meshRefinement::makeConsistentFaceIndex
} }
void Foam::meshRefinement::handleSnapProblems
(
const bool removeEdgeConnectedCells,
const scalarField& perpendicularAngle,
const dictionary& motionDict,
Time& runTime,
const labelList& globalToMasterPatch,
const labelList& globalToSlavePatch
)
{
Info<< nl
<< "Introducing baffles to block off problem cells" << nl
<< "----------------------------------------------" << nl
<< endl;
labelList facePatch
(
markFacesOnProblemCells
(
motionDict,
removeEdgeConnectedCells,
perpendicularAngle,
globalToMasterPatch
)
);
Info<< "Analyzed problem cells in = "
<< runTime.cpuTimeIncrement() << " s\n" << nl << endl;
if (debug&meshRefinement::MESH)
{
faceSet problemTopo(mesh_, "problemFacesTopo", 100);
const labelList facePatchTopo
(
markFacesOnProblemCells
(
motionDict,
removeEdgeConnectedCells,
perpendicularAngle,
globalToMasterPatch
)
);
forAll(facePatchTopo, faceI)
{
if (facePatchTopo[faceI] != -1)
{
problemTopo.insert(faceI);
}
}
problemTopo.instance() = timeName();
Pout<< "Dumping " << problemTopo.size()
<< " problem faces to " << problemTopo.objectPath() << endl;
problemTopo.write();
}
Info<< "Introducing baffles to delete problem cells." << nl << endl;
if (debug)
{
runTime++;
}
// Create baffles with same owner and neighbour for now.
createBaffles(facePatch, facePatch);
if (debug)
{
// Debug:test all is still synced across proc patches
checkData();
}
Info<< "Created baffles in = "
<< runTime.cpuTimeIncrement() << " s\n" << nl << endl;
printMeshInfo(debug, "After introducing baffles");
if (debug&meshRefinement::MESH)
{
Pout<< "Writing extra baffled mesh to time "
<< timeName() << endl;
write(debug, runTime.path()/"extraBaffles");
Pout<< "Dumped debug data in = "
<< runTime.cpuTimeIncrement() << " s\n" << nl << endl;
}
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
// Split off unreachable areas of mesh. // Split off unreachable areas of mesh.
void Foam::meshRefinement::baffleAndSplitMesh void Foam::meshRefinement::baffleAndSplitMesh
( (
const bool handleSnapProblems, const bool doHandleSnapProblems,
const bool removeEdgeConnectedCells, const bool removeEdgeConnectedCells,
const scalarField& perpendicularAngle, const scalarField& perpendicularAngle,
const bool mergeFreeStanding, const bool mergeFreeStanding,
const scalar planarAngle,
const dictionary& motionDict, const dictionary& motionDict,
Time& runTime, Time& runTime,
const labelList& globalToMasterPatch, const labelList& globalToMasterPatch,
@ -1902,82 +2027,92 @@ void Foam::meshRefinement::baffleAndSplitMesh
// Create some additional baffles where we want surface cells removed. // Create some additional baffles where we want surface cells removed.
if (handleSnapProblems) if (doHandleSnapProblems)
{ {
Info<< nl //Info<< nl
<< "Introducing baffles to block off problem cells" << nl // << "Introducing baffles to block off problem cells" << nl
<< "----------------------------------------------" << nl // << "----------------------------------------------" << nl
<< endl; // << endl;
//
//labelList facePatch
//(
// markFacesOnProblemCells
// (
// motionDict,
// removeEdgeConnectedCells,
// perpendicularAngle,
// globalToMasterPatch
// )
// //markFacesOnProblemCellsGeometric(motionDict)
//);
//Info<< "Analyzed problem cells in = "
// << runTime.cpuTimeIncrement() << " s\n" << nl << endl;
//
//if (debug&meshRefinement::MESH)
//{
// faceSet problemTopo(mesh_, "problemFacesTopo", 100);
//
// const labelList facePatchTopo
// (
// markFacesOnProblemCells
// (
// motionDict,
// removeEdgeConnectedCells,
// perpendicularAngle,
// globalToMasterPatch
// )
// );
// forAll(facePatchTopo, faceI)
// {
// if (facePatchTopo[faceI] != -1)
// {
// problemTopo.insert(faceI);
// }
// }
// problemTopo.instance() = timeName();
// Pout<< "Dumping " << problemTopo.size()
// << " problem faces to " << problemTopo.objectPath() << endl;
// problemTopo.write();
//}
//
//Info<< "Introducing baffles to delete problem cells." << nl << endl;
//
//if (debug)
//{
// runTime++;
//}
//
//// Create baffles with same owner and neighbour for now.
//createBaffles(facePatch, facePatch);
//
//if (debug)
//{
// // Debug:test all is still synced across proc patches
// checkData();
//}
//Info<< "Created baffles in = "
// << runTime.cpuTimeIncrement() << " s\n" << nl << endl;
//
//printMeshInfo(debug, "After introducing baffles");
//
//if (debug&meshRefinement::MESH)
//{
// Pout<< "Writing extra baffled mesh to time "
// << timeName() << endl;
// write(debug, runTime.path()/"extraBaffles");
// Pout<< "Dumped debug data in = "
// << runTime.cpuTimeIncrement() << " s\n" << nl << endl;
//}
labelList facePatch handleSnapProblems
( (
markFacesOnProblemCells
(
motionDict,
removeEdgeConnectedCells, removeEdgeConnectedCells,
perpendicularAngle, perpendicularAngle,
globalToMasterPatch
)
//markFacesOnProblemCellsGeometric(motionDict)
);
Info<< "Analyzed problem cells in = "
<< runTime.cpuTimeIncrement() << " s\n" << nl << endl;
if (debug&meshRefinement::MESH)
{
faceSet problemTopo(mesh_, "problemFacesTopo", 100);
const labelList facePatchTopo
(
markFacesOnProblemCells
(
motionDict, motionDict,
removeEdgeConnectedCells, runTime,
perpendicularAngle, globalToMasterPatch,
globalToMasterPatch globalToSlavePatch
)
); );
forAll(facePatchTopo, faceI)
{
if (facePatchTopo[faceI] != -1)
{
problemTopo.insert(faceI);
}
}
problemTopo.instance() = timeName();
Pout<< "Dumping " << problemTopo.size()
<< " problem faces to " << problemTopo.objectPath() << endl;
problemTopo.write();
}
Info<< "Introducing baffles to delete problem cells." << nl << endl;
if (debug)
{
runTime++;
}
// Create baffles with same owner and neighbour for now.
createBaffles(facePatch, facePatch);
if (debug)
{
// Debug:test all is still synced across proc patches
checkData();
}
Info<< "Created baffles in = "
<< runTime.cpuTimeIncrement() << " s\n" << nl << endl;
printMeshInfo(debug, "After introducing baffles");
if (debug&meshRefinement::MESH)
{
Pout<< "Writing extra baffled mesh to time "
<< timeName() << endl;
write(debug, runTime.path()/"extraBaffles");
Pout<< "Dumped debug data in = "
<< runTime.cpuTimeIncrement() << " s\n" << nl << endl;
}
} }
@ -2036,7 +2171,8 @@ void Foam::meshRefinement::baffleAndSplitMesh
( (
identity(mesh_.nFaces()-mesh_.nInternalFaces()) identity(mesh_.nFaces()-mesh_.nInternalFaces())
+mesh_.nInternalFaces() +mesh_.nInternalFaces()
) ),
planarAngle
) )
); );
@ -2052,6 +2188,18 @@ void Foam::meshRefinement::baffleAndSplitMesh
// from them. // from them.
mergeBaffles(couples); mergeBaffles(couples);
// Detect any problem cells resulting from merging of baffles
// and delete them
handleSnapProblems
(
removeEdgeConnectedCells,
perpendicularAngle,
motionDict,
runTime,
globalToMasterPatch,
globalToSlavePatch
);
if (debug) if (debug)
{ {
// Debug:test all is still synced across proc patches // Debug:test all is still synced across proc patches
@ -2663,18 +2811,6 @@ Foam::autoPtr<Foam::mapPolyMesh> Foam::meshRefinement::zonify
if (surface1[i] != -1) if (surface1[i] != -1)
{ {
//- Not allowed not to create baffle - is vital for regioning.
// Have logic instead at erosion!
//bool createBaffle = validBaffleTopology
//(
// faceI,
// normal1[i],
// normal2[i],
// end[i]-start[i]
//);
//
// If both hit should probably choose 'nearest' // If both hit should probably choose 'nearest'
if if
( (

View File

@ -38,6 +38,7 @@ License
#include "featureEdgeMesh.H" #include "featureEdgeMesh.H"
#include "Cloud.H" #include "Cloud.H"
//#include "globalIndex.H" //#include "globalIndex.H"
//#include "OBJstream.H"
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
@ -244,14 +245,10 @@ bool Foam::meshRefinement::markForRefine
} }
// Calculates list of cells to refine based on intersection with feature edge. void Foam::meshRefinement::markFeatureCellLevel
Foam::label Foam::meshRefinement::markFeatureRefinement
( (
const point& keepPoint, const point& keepPoint,
const label nAllowRefine, labelList& maxFeatureLevel
labelList& refineCell,
label& nRefine
) const ) const
{ {
// We want to refine all cells containing a feature edge. // We want to refine all cells containing a feature edge.
@ -384,7 +381,7 @@ Foam::label Foam::meshRefinement::markFeatureRefinement
// Largest refinement level of any feature passed through // Largest refinement level of any feature passed through
labelList maxFeatureLevel(mesh_.nCells(), -1); maxFeatureLevel = labelList(mesh_.nCells(), -1);
// Database to pass into trackedParticle::move // Database to pass into trackedParticle::move
trackedParticle::trackingData td(cloud, maxFeatureLevel); trackedParticle::trackingData td(cloud, maxFeatureLevel);
@ -467,8 +464,23 @@ Foam::label Foam::meshRefinement::markFeatureRefinement
// Track all particles to their end position. // Track all particles to their end position.
cloud.move(td, GREAT); cloud.move(td, GREAT);
} }
}
// Calculates list of cells to refine based on intersection with feature edge.
Foam::label Foam::meshRefinement::markFeatureRefinement
(
const point& keepPoint,
const label nAllowRefine,
labelList& refineCell,
label& nRefine
) const
{
// Largest refinement level of any feature passed through
labelList maxFeatureLevel;
markFeatureCellLevel(keepPoint, maxFeatureLevel);
// See which cells to refine. maxFeatureLevel will hold highest level // See which cells to refine. maxFeatureLevel will hold highest level
// of any feature edge that passed through. // of any feature edge that passed through.
@ -1011,6 +1023,9 @@ Foam::label Foam::meshRefinement::markSurfaceCurvatureRefinement
end, end,
minLevel, // max level of surface has to be bigger minLevel, // max level of surface has to be bigger
// than min level of neighbouring cells // than min level of neighbouring cells
surfaces_.maxLevel(),
surfaceNormal, surfaceNormal,
surfaceLevel surfaceLevel
); );
@ -1199,6 +1214,473 @@ Foam::label Foam::meshRefinement::markSurfaceCurvatureRefinement
} }
// Mark small gaps
bool Foam::meshRefinement::isGap
(
const scalar planarCos,
const vector& point0,
const vector& normal0,
const vector& point1,
const vector& normal1
) const
{
////- hits differ and angles are oppositeish
//return
// (mag(point0-point1) > mergeDistance())
// && ((normal0 & normal1) < (-1+planarCos));
//- hits differ and angles are oppositeish and
// hits have a normal distance
vector d = point1-point0;
scalar magD = mag(d);
if (magD > mergeDistance())
{
scalar cosAngle = (normal0 & normal1);
vector avg = vector::zero;
if (cosAngle < (-1+planarCos))
{
// Opposite normals
avg = 0.5*(normal0-normal1);
}
else if (cosAngle > (1-planarCos))
{
avg = 0.5*(normal0+normal1);
}
if (avg != vector::zero)
{
avg /= mag(avg);
d /= magD;
// Check average normal with respect to intersection locations
if (mag(avg&d) > Foam::cos(degToRad(45)))
{
return true;
}
else
{
return false;
}
}
else
{
return false;
}
}
else
{
return false;
}
}
bool Foam::meshRefinement::checkProximity
(
const scalar planarCos,
const label nAllowRefine,
const label surfaceLevel, // current intersection max level
const vector& surfaceLocation, // current intersection location
const vector& surfaceNormal, // current intersection normal
const label cellI,
label& cellMaxLevel, // cached max surface level for this cell
vector& cellMaxLocation, // cached surface normal for this cell
vector& cellMaxNormal, // cached surface normal for this cell
labelList& refineCell,
label& nRefine
) const
{
const labelList& cellLevel = meshCutter_.cellLevel();
// Test if surface applicable
if (surfaceLevel > cellLevel[cellI])
{
if (cellMaxLevel == -1)
{
// First visit of cell. Store
cellMaxLevel = surfaceLevel;
cellMaxLocation = surfaceLocation;
cellMaxNormal = surfaceNormal;
}
else
{
// Second or more visit.
// Check if
// - different location
// - opposite surface
bool closeSurfaces = isGap
(
planarCos,
cellMaxLocation,
cellMaxNormal,
surfaceLocation,
surfaceNormal
);
// Set normal to that of highest surface. Not really necessary
// over here but we reuse cellMax info when doing coupled faces.
if (surfaceLevel > cellMaxLevel)
{
cellMaxLevel = surfaceLevel;
cellMaxLocation = surfaceLocation;
cellMaxNormal = surfaceNormal;
}
if (closeSurfaces)
{
//Pout<< "Found gap:" << nl
// << " location:" << surfaceLocation
// << "\tnormal :" << surfaceNormal << nl
/// << " location:" << cellMaxLocation
// << "\tnormal :" << cellMaxNormal << nl
// << "\tcos :" << (surfaceNormal&cellMaxNormal) << nl
// << endl;
return markForRefine
(
surfaceLevel, // mark with any non-neg number.
nAllowRefine,
refineCell[cellI],
nRefine
);
}
}
}
// Did not reach refinement limit.
return true;
}
Foam::label Foam::meshRefinement::markProximityRefinement
(
const scalar planarCos,
const label nAllowRefine,
const labelList& neiLevel,
const pointField& neiCc,
labelList& refineCell,
label& nRefine
) const
{
const labelList& cellLevel = meshCutter_.cellLevel();
const pointField& cellCentres = mesh_.cellCentres();
label oldNRefine = nRefine;
// 1. local test: any cell on more than one surface gets refined
// (if its current level is < max of the surface max level)
// 2. 'global' test: any cell on only one surface with a neighbour
// on a different surface gets refined (if its current level etc.)
// Collect candidate faces (i.e. intersecting any surface and
// owner/neighbour not yet refined.
labelList testFaces(getRefineCandidateFaces(refineCell));
// Collect segments
pointField start(testFaces.size());
pointField end(testFaces.size());
labelList minLevel(testFaces.size());
forAll(testFaces, i)
{
label faceI = testFaces[i];
label own = mesh_.faceOwner()[faceI];
if (mesh_.isInternalFace(faceI))
{
label nei = mesh_.faceNeighbour()[faceI];
start[i] = cellCentres[own];
end[i] = cellCentres[nei];
minLevel[i] = min(cellLevel[own], cellLevel[nei]);
}
else
{
label bFaceI = faceI - mesh_.nInternalFaces();
start[i] = cellCentres[own];
end[i] = neiCc[bFaceI];
minLevel[i] = min(cellLevel[own], neiLevel[bFaceI]);
}
}
// Extend segments a bit
{
const vectorField smallVec(Foam::sqrt(SMALL)*(end-start));
start -= smallVec;
end += smallVec;
}
// Test for all intersections (with surfaces of higher gap level than
// minLevel) and cache per cell the max surface level and the local normal
// on that surface.
labelList cellMaxLevel(mesh_.nCells(), -1);
vectorField cellMaxNormal(mesh_.nCells(), vector::zero);
pointField cellMaxLocation(mesh_.nCells(), vector::zero);
{
// Per segment the normals of the surfaces
List<vectorList> surfaceLocation;
List<vectorList> surfaceNormal;
// Per segment the list of levels of the surfaces
labelListList surfaceLevel;
surfaces_.findAllHigherIntersections
(
start,
end,
minLevel, // gap level of surface has to be bigger
// than min level of neighbouring cells
surfaces_.gapLevel(),
surfaceLocation,
surfaceNormal,
surfaceLevel
);
// Clear out unnecessary data
start.clear();
end.clear();
minLevel.clear();
//// Extract per cell information on the surface with the highest max
//OBJstream str
//(
// mesh_.time().path()
// / "findAllHigherIntersections_"
// + mesh_.time().timeName()
// + ".obj"
//);
//// All intersections
//OBJstream str2
//(
// mesh_.time().path()
// / "findAllHigherIntersections2_"
// + mesh_.time().timeName()
// + ".obj"
//);
forAll(testFaces, i)
{
label faceI = testFaces[i];
label own = mesh_.faceOwner()[faceI];
const labelList& fLevels = surfaceLevel[i];
const vectorList& fPoints = surfaceLocation[i];
const vectorList& fNormals = surfaceNormal[i];
forAll(fLevels, hitI)
{
checkProximity
(
planarCos,
nAllowRefine,
fLevels[hitI],
fPoints[hitI],
fNormals[hitI],
own,
cellMaxLevel[own],
cellMaxLocation[own],
cellMaxNormal[own],
refineCell,
nRefine
);
}
if (mesh_.isInternalFace(faceI))
{
label nei = mesh_.faceNeighbour()[faceI];
forAll(fLevels, hitI)
{
checkProximity
(
planarCos,
nAllowRefine,
fLevels[hitI],
fPoints[hitI],
fNormals[hitI],
nei,
cellMaxLevel[nei],
cellMaxLocation[nei],
cellMaxNormal[nei],
refineCell,
nRefine
);
}
}
}
}
// 2. Find out a measure of surface curvature and region edges.
// Send over surface region and surface normal to neighbour cell.
labelList neiBndMaxLevel(mesh_.nFaces()-mesh_.nInternalFaces());
pointField neiBndMaxLocation(mesh_.nFaces()-mesh_.nInternalFaces());
vectorField neiBndMaxNormal(mesh_.nFaces()-mesh_.nInternalFaces());
for (label faceI = mesh_.nInternalFaces(); faceI < mesh_.nFaces(); faceI++)
{
label bFaceI = faceI-mesh_.nInternalFaces();
label own = mesh_.faceOwner()[faceI];
neiBndMaxLevel[bFaceI] = cellMaxLevel[own];
neiBndMaxLocation[bFaceI] = cellMaxLocation[own];
neiBndMaxNormal[bFaceI] = cellMaxNormal[own];
}
syncTools::swapBoundaryFaceList(mesh_, neiBndMaxLevel);
syncTools::swapBoundaryFaceList(mesh_, neiBndMaxLocation);
syncTools::swapBoundaryFaceList(mesh_, neiBndMaxNormal);
// Loop over all faces. Could only be checkFaces.. except if they're coupled
// Internal faces
for (label faceI = 0; faceI < mesh_.nInternalFaces(); faceI++)
{
label own = mesh_.faceOwner()[faceI];
label nei = mesh_.faceNeighbour()[faceI];
if (cellMaxLevel[own] != -1 && cellMaxLevel[nei] != -1)
{
// Have valid data on both sides. Check planarCos.
if
(
isGap
(
planarCos,
cellMaxLocation[own],
cellMaxNormal[own],
cellMaxLocation[nei],
cellMaxNormal[nei]
)
)
{
// See which side to refine
if (cellLevel[own] < cellMaxLevel[own])
{
if
(
!markForRefine
(
cellMaxLevel[own],
nAllowRefine,
refineCell[own],
nRefine
)
)
{
if (debug)
{
Pout<< "Stopped refining since reaching my cell"
<< " limit of " << mesh_.nCells()+7*nRefine
<< endl;
}
break;
}
}
if (cellLevel[nei] < cellMaxLevel[nei])
{
if
(
!markForRefine
(
cellMaxLevel[nei],
nAllowRefine,
refineCell[nei],
nRefine
)
)
{
if (debug)
{
Pout<< "Stopped refining since reaching my cell"
<< " limit of " << mesh_.nCells()+7*nRefine
<< endl;
}
break;
}
}
}
}
}
// Boundary faces
for (label faceI = mesh_.nInternalFaces(); faceI < mesh_.nFaces(); faceI++)
{
label own = mesh_.faceOwner()[faceI];
label bFaceI = faceI - mesh_.nInternalFaces();
if (cellLevel[own] < cellMaxLevel[own] && neiBndMaxLevel[bFaceI] != -1)
{
// Have valid data on both sides. Check planarCos.
if
(
isGap
(
planarCos,
cellMaxLocation[own],
cellMaxNormal[own],
neiBndMaxLocation[bFaceI],
neiBndMaxNormal[bFaceI]
)
)
{
if
(
!markForRefine
(
cellMaxLevel[own],
nAllowRefine,
refineCell[own],
nRefine
)
)
{
if (debug)
{
Pout<< "Stopped refining since reaching my cell"
<< " limit of " << mesh_.nCells()+7*nRefine
<< endl;
}
break;
}
}
}
}
if
(
returnReduce(nRefine, sumOp<label>())
> returnReduce(nAllowRefine, sumOp<label>())
)
{
Info<< "Reached refinement limit." << endl;
}
return returnReduce(nRefine-oldNRefine, sumOp<label>());
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
// Calculate list of cells to refine. Gets for any edge (start - end) // Calculate list of cells to refine. Gets for any edge (start - end)
@ -1210,12 +1692,14 @@ Foam::labelList Foam::meshRefinement::refineCandidates
( (
const point& keepPoint, const point& keepPoint,
const scalar curvature, const scalar curvature,
const scalar planarAngle,
const bool featureRefinement, const bool featureRefinement,
const bool featureDistanceRefinement, const bool featureDistanceRefinement,
const bool internalRefinement, const bool internalRefinement,
const bool surfaceRefinement, const bool surfaceRefinement,
const bool curvatureRefinement, const bool curvatureRefinement,
const bool gapRefinement,
const label maxGlobalCells, const label maxGlobalCells,
const label maxLocalCells const label maxLocalCells
) const ) const
@ -1359,6 +1843,35 @@ Foam::labelList Foam::meshRefinement::refineCandidates
<< ": " << nCurv << " cells." << endl; << ": " << nCurv << " cells." << endl;
} }
const scalar planarCos = Foam::cos(degToRad(planarAngle));
if
(
gapRefinement
&& (planarCos >= -1 && planarCos <= 1)
&& (max(surfaces_.gapLevel()) > -1)
)
{
Info<< "Specified gap level : " << max(surfaces_.gapLevel())
<< ", planar angle " << planarAngle << endl;
label nGap = markProximityRefinement
(
planarCos,
nAllowRefine,
neiLevel,
neiCc,
refineCell,
nRefine
);
Info<< "Marked for refinement due to close opposite surfaces "
<< ": " << nGap << " cells." << endl;
}
// Pack cells-to-refine // Pack cells-to-refine
// ~~~~~~~~~~~~~~~~~~~~ // ~~~~~~~~~~~~~~~~~~~~

View File

@ -116,10 +116,12 @@ Foam::refinementSurfaces::refinementSurfaces
labelList globalMinLevel(surfI, 0); labelList globalMinLevel(surfI, 0);
labelList globalMaxLevel(surfI, 0); labelList globalMaxLevel(surfI, 0);
labelList globalLevelIncr(surfI, 0);
scalarField globalAngle(surfI, -GREAT); scalarField globalAngle(surfI, -GREAT);
PtrList<dictionary> globalPatchInfo(surfI); PtrList<dictionary> globalPatchInfo(surfI);
List<Map<label> > regionMinLevel(surfI); List<Map<label> > regionMinLevel(surfI);
List<Map<label> > regionMaxLevel(surfI); List<Map<label> > regionMaxLevel(surfI);
List<Map<label> > regionLevelIncr(surfI);
List<Map<scalar> > regionAngle(surfI); List<Map<scalar> > regionAngle(surfI);
List<Map<autoPtr<dictionary> > > regionPatchInfo(surfI); List<Map<autoPtr<dictionary> > > regionPatchInfo(surfI);
@ -138,6 +140,31 @@ Foam::refinementSurfaces::refinementSurfaces
const labelPair refLevel(dict.lookup("level")); const labelPair refLevel(dict.lookup("level"));
globalMinLevel[surfI] = refLevel[0]; globalMinLevel[surfI] = refLevel[0];
globalMaxLevel[surfI] = refLevel[1]; globalMaxLevel[surfI] = refLevel[1];
globalLevelIncr[surfI] = dict.lookupOrDefault
(
"gapLevelIncrement",
0
);
if
(
globalMinLevel[surfI] < 0
|| globalMaxLevel[surfI] < globalMinLevel[surfI]
|| globalLevelIncr[surfI] < 0
)
{
FatalErrorIn
(
"refinementSurfaces::refinementSurfaces"
"(const searchableSurfaces&, const dictionary>&"
) << "Illegal level specification for surface "
<< names_[surfI]
<< " : minLevel:" << globalMinLevel[surfI]
<< " maxLevel:" << globalMaxLevel[surfI]
<< " levelIncrement:" << globalLevelIncr[surfI]
<< exit(FatalError);
}
// Global zone names per surface // Global zone names per surface
if (dict.readIfPresent("faceZone", faceZoneNames_[surfI])) if (dict.readIfPresent("faceZone", faceZoneNames_[surfI]))
@ -244,6 +271,34 @@ Foam::refinementSurfaces::refinementSurfaces
regionMinLevel[surfI].insert(regionI, refLevel[0]); regionMinLevel[surfI].insert(regionI, refLevel[0]);
regionMaxLevel[surfI].insert(regionI, refLevel[1]); regionMaxLevel[surfI].insert(regionI, refLevel[1]);
label levelIncr = regionDict.lookupOrDefault
(
"gapLevelIncrement",
0
);
regionLevelIncr[surfI].insert(regionI, levelIncr);
if
(
refLevel[0] < 0
|| refLevel[1] < refLevel[0]
|| levelIncr < 0
)
{
FatalErrorIn
(
"refinementSurfaces::refinementSurfaces"
"(const searchableSurfaces&, const dictionary>&"
) << "Illegal level specification for surface "
<< names_[surfI] << " region "
<< regionNames[regionI]
<< " : minLevel:" << refLevel[0]
<< " maxLevel:" << refLevel[1]
<< " levelIncrement:" << levelIncr
<< exit(FatalError);
}
if (regionDict.found("perpendicularAngle")) if (regionDict.found("perpendicularAngle"))
{ {
@ -286,6 +341,8 @@ Foam::refinementSurfaces::refinementSurfaces
minLevel_ = 0; minLevel_ = 0;
maxLevel_.setSize(nRegions); maxLevel_.setSize(nRegions);
maxLevel_ = 0; maxLevel_ = 0;
gapLevel_.setSize(nRegions);
gapLevel_ = -1;
perpendicularAngle_.setSize(nRegions); perpendicularAngle_.setSize(nRegions);
perpendicularAngle_ = -GREAT; perpendicularAngle_ = -GREAT;
patchInfo_.setSize(nRegions); patchInfo_.setSize(nRegions);
@ -301,6 +358,10 @@ Foam::refinementSurfaces::refinementSurfaces
label globalRegionI = regionOffset_[surfI] + i; label globalRegionI = regionOffset_[surfI] + i;
minLevel_[globalRegionI] = globalMinLevel[surfI]; minLevel_[globalRegionI] = globalMinLevel[surfI];
maxLevel_[globalRegionI] = globalMaxLevel[surfI]; maxLevel_[globalRegionI] = globalMaxLevel[surfI];
gapLevel_[globalRegionI] =
maxLevel_[globalRegionI]
+ globalLevelIncr[surfI];
perpendicularAngle_[globalRegionI] = globalAngle[surfI]; perpendicularAngle_[globalRegionI] = globalAngle[surfI];
if (globalPatchInfo.set(surfI)) if (globalPatchInfo.set(surfI))
{ {
@ -319,24 +380,9 @@ Foam::refinementSurfaces::refinementSurfaces
minLevel_[globalRegionI] = iter(); minLevel_[globalRegionI] = iter();
maxLevel_[globalRegionI] = regionMaxLevel[surfI][iter.key()]; maxLevel_[globalRegionI] = regionMaxLevel[surfI][iter.key()];
gapLevel_[globalRegionI] =
// Check validity maxLevel_[globalRegionI]
if + regionLevelIncr[surfI][iter.key()];
(
minLevel_[globalRegionI] < 0
|| maxLevel_[globalRegionI] < minLevel_[globalRegionI]
)
{
FatalErrorIn
(
"refinementSurfaces::refinementSurfaces"
"(const searchableSurfaces&, const dictionary>&"
) << "Illegal level or layer specification for surface "
<< names_[surfI]
<< " : minLevel:" << minLevel_[globalRegionI]
<< " maxLevel:" << maxLevel_[globalRegionI]
<< exit(FatalError);
}
} }
forAllConstIter(Map<scalar>, regionAngle[surfI], iter) forAllConstIter(Map<scalar>, regionAngle[surfI], iter)
{ {
@ -714,6 +760,8 @@ void Foam::refinementSurfaces::findAllHigherIntersections
const pointField& end, const pointField& end,
const labelList& currentLevel, // current cell refinement level const labelList& currentLevel, // current cell refinement level
const labelList& globalRegionLevel,
List<vectorList>& surfaceNormal, List<vectorList>& surfaceNormal,
labelListList& surfaceLevel labelListList& surfaceLevel
) const ) const
@ -777,7 +825,7 @@ void Foam::refinementSurfaces::findAllHigherIntersections
label region = globalRegion(surfI, surfRegion[i]); label region = globalRegion(surfI, surfRegion[i]);
label pointI = pointMap[i]; label pointI = pointMap[i];
if (maxLevel_[region] > currentLevel[pointI]) if (globalRegionLevel[region] > currentLevel[pointI])
{ {
// Append to pointI info // Append to pointI info
label sz = surfaceNormal[pointI].size(); label sz = surfaceNormal[pointI].size();
@ -785,7 +833,95 @@ void Foam::refinementSurfaces::findAllHigherIntersections
surfaceNormal[pointI][sz] = surfNormal[i]; surfaceNormal[pointI][sz] = surfNormal[i];
surfaceLevel[pointI].setSize(sz+1); surfaceLevel[pointI].setSize(sz+1);
surfaceLevel[pointI][sz] = maxLevel_[region]; surfaceLevel[pointI][sz] = globalRegionLevel[region];
}
}
}
}
void Foam::refinementSurfaces::findAllHigherIntersections
(
const pointField& start,
const pointField& end,
const labelList& currentLevel, // current cell refinement level
const labelList& globalRegionLevel,
List<pointList>& surfaceLocation,
List<vectorList>& surfaceNormal,
labelListList& surfaceLevel
) const
{
surfaceLevel.setSize(start.size());
surfaceNormal.setSize(start.size());
surfaceLocation.setSize(start.size());
if (surfaces_.empty())
{
return;
}
// Work arrays
List<List<pointIndexHit> > hitInfo;
labelList pRegions;
vectorField pNormals;
forAll(surfaces_, surfI)
{
allGeometry_[surfaces_[surfI]].findLineAll(start, end, hitInfo);
// Repack hits for surface into flat list
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// To avoid overhead of calling getRegion for every point
label n = 0;
forAll(hitInfo, pointI)
{
n += hitInfo[pointI].size();
}
List<pointIndexHit> surfInfo(n);
labelList pointMap(n);
n = 0;
forAll(hitInfo, pointI)
{
const List<pointIndexHit>& pHits = hitInfo[pointI];
forAll(pHits, i)
{
surfInfo[n] = pHits[i];
pointMap[n] = pointI;
n++;
}
}
labelList surfRegion(n);
vectorField surfNormal(n);
allGeometry_[surfaces_[surfI]].getRegion(surfInfo, surfRegion);
allGeometry_[surfaces_[surfI]].getNormal(surfInfo, surfNormal);
// Extract back into pointwise
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~
forAll(surfRegion, i)
{
label region = globalRegion(surfI, surfRegion[i]);
label pointI = pointMap[i];
if (globalRegionLevel[region] > currentLevel[pointI])
{
// Append to pointI info
label sz = surfaceNormal[pointI].size();
surfaceLocation[pointI].setSize(sz+1);
surfaceLocation[pointI][sz] = surfInfo[i].hitPoint();
surfaceNormal[pointI].setSize(sz+1);
surfaceNormal[pointI][sz] = surfNormal[i];
surfaceLevel[pointI].setSize(sz+1);
surfaceLevel[pointI][sz] = globalRegionLevel[region];
} }
} }
} }

View File

@ -2,7 +2,7 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -51,6 +51,8 @@ class searchableSurfaces;
class shellSurfaces; class shellSurfaces;
class triSurfaceMesh; class triSurfaceMesh;
typedef List<point> pointList;
/*---------------------------------------------------------------------------*\ /*---------------------------------------------------------------------------*\
Class refinementSurfaces Declaration Class refinementSurfaces Declaration
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
@ -120,6 +122,9 @@ private:
//- From global region number to refinement level //- From global region number to refinement level
labelList maxLevel_; labelList maxLevel_;
//- From global region number to small-gap level
labelList gapLevel_;
//- From global region number to perpendicular angle //- From global region number to perpendicular angle
scalarField perpendicularAngle_; scalarField perpendicularAngle_;
@ -226,6 +231,12 @@ public:
return maxLevel_; return maxLevel_;
} }
//- From global region number to small gap refinement level
const labelList& gapLevel() const
{
return gapLevel_;
}
//- From global region number to perpendicular angle //- From global region number to perpendicular angle
const scalarField& perpendicularAngle() const const scalarField& perpendicularAngle() const
{ {
@ -295,11 +306,25 @@ public:
const pointField& start, const pointField& start,
const pointField& end, const pointField& end,
const labelList& currentLevel, // current cell refinement level const labelList& currentLevel, // current cell refinement level
const labelList& globalRegionLevel, // level per surfregion
List<vectorList>& surfaceNormal, List<vectorList>& surfaceNormal,
labelListList& surfaceLevel labelListList& surfaceLevel
) const; ) const;
//- Find all intersections of edge. Unsorted order.
void findAllHigherIntersections
(
const pointField& start,
const pointField& end,
const labelList& currentLevel, // current cell refinement level
const labelList& globalRegionLevel, // level per surfregion
List<pointList>& surfaceLocation,
List<vectorList>& surfaceNormal,
labelListList& surfaceLevel
) const;
//- Find intersection nearest to the endpoints. surface1,2 are //- Find intersection nearest to the endpoints. surface1,2 are
// not indices into surfacesToTest but refinement surface indices. // not indices into surfacesToTest but refinement surface indices.
// Returns surface, region on surface (so not global surface) // Returns surface, region on surface (so not global surface)

View File

@ -56,6 +56,11 @@ Foam::AMIInterpolation<SourcePatch, TargetPatch>::interpolationMethodToWord
method = "faceAreaWeightAMI"; method = "faceAreaWeightAMI";
break; break;
} }
case imPartialFaceAreaWeight:
{
method = "partialFaceAreaWeightAMI";
break;
}
default: default:
{ {
FatalErrorIn FatalErrorIn
@ -87,7 +92,15 @@ Foam::AMIInterpolation<SourcePatch, TargetPatch>::wordTointerpolationMethod
wordList methods wordList methods
( (
IStringStream("(directAMI mapNearestAMI faceAreaWeightAMI)")() IStringStream
(
"("
"directAMI "
"mapNearestAMI "
"faceAreaWeightAMI "
"partialFaceAreaWeightAMI"
")"
)()
); );
if (im == "directAMI") if (im == "directAMI")
@ -102,6 +115,10 @@ Foam::AMIInterpolation<SourcePatch, TargetPatch>::wordTointerpolationMethod
{ {
method = imFaceAreaWeight; method = imFaceAreaWeight;
} }
else if (im == "partialFaceAreaWeightAMI")
{
method = imPartialFaceAreaWeight;
}
else else
{ {
FatalErrorIn FatalErrorIn
@ -183,6 +200,7 @@ void Foam::AMIInterpolation<SourcePatch, TargetPatch>::normaliseWeights
const labelListList& addr, const labelListList& addr,
scalarListList& wght, scalarListList& wght,
scalarField& wghtSum, scalarField& wghtSum,
const bool conformal,
const bool output const bool output
) )
{ {
@ -191,12 +209,19 @@ void Foam::AMIInterpolation<SourcePatch, TargetPatch>::normaliseWeights
forAll(wght, faceI) forAll(wght, faceI)
{ {
scalarList& w = wght[faceI]; scalarList& w = wght[faceI];
scalar denom = patchAreas[faceI];
scalar s = sum(w); scalar s = sum(w);
scalar t = s/patchAreas[faceI]; scalar t = s/denom;
if (conformal)
{
denom = s;
}
forAll(w, i) forAll(w, i)
{ {
w[i] /= s; w[i] /= denom;
} }
wghtSum[faceI] = t; wghtSum[faceI] = t;
@ -476,6 +501,7 @@ void Foam::AMIInterpolation<SourcePatch, TargetPatch>::agglomerate
srcAddress, srcAddress,
srcWeights, srcWeights,
srcWeightsSum, srcWeightsSum,
true,
false false
); );
} }
@ -749,7 +775,6 @@ void Foam::AMIInterpolation<SourcePatch, TargetPatch>::update
tgtMagSf_[faceI] = tgtPatch[faceI].mag(tgtPatch.points()); tgtMagSf_[faceI] = tgtPatch[faceI].mag(tgtPatch.points());
} }
// Calculate if patches present on multiple processors // Calculate if patches present on multiple processors
singlePatchProc_ = calcDistribution(srcPatch, tgtPatch); singlePatchProc_ = calcDistribution(srcPatch, tgtPatch);
@ -794,9 +819,7 @@ void Foam::AMIInterpolation<SourcePatch, TargetPatch>::update
newTgtPoints newTgtPoints
); );
// calculate AMI interpolation // calculate AMI interpolation
{
autoPtr<AMIMethod<SourcePatch, TargetPatch> > AMIPtr autoPtr<AMIMethod<SourcePatch, TargetPatch> > AMIPtr
( (
AMIMethod<SourcePatch, TargetPatch>::New AMIMethod<SourcePatch, TargetPatch>::New
@ -818,8 +841,6 @@ void Foam::AMIInterpolation<SourcePatch, TargetPatch>::update
tgtAddress_, tgtAddress_,
tgtWeights_ tgtWeights_
); );
}
// Now // Now
// ~~~ // ~~~
@ -886,6 +907,7 @@ void Foam::AMIInterpolation<SourcePatch, TargetPatch>::update
srcAddress_, srcAddress_,
srcWeights_, srcWeights_,
srcWeightsSum_, srcWeightsSum_,
AMIPtr->conformal(),
true true
); );
normaliseWeights normaliseWeights
@ -895,6 +917,7 @@ void Foam::AMIInterpolation<SourcePatch, TargetPatch>::update
tgtAddress_, tgtAddress_,
tgtWeights_, tgtWeights_,
tgtWeightsSum_, tgtWeightsSum_,
AMIPtr->conformal(),
true true
); );
@ -903,7 +926,6 @@ void Foam::AMIInterpolation<SourcePatch, TargetPatch>::update
srcMapPtr_.reset(new mapDistribute(globalSrcFaces, tgtAddress_, cMap)); srcMapPtr_.reset(new mapDistribute(globalSrcFaces, tgtAddress_, cMap));
tgtMapPtr_.reset(new mapDistribute(globalTgtFaces, srcAddress_, cMap)); tgtMapPtr_.reset(new mapDistribute(globalTgtFaces, srcAddress_, cMap));
if (debug) if (debug)
{ {
writeFaceConnectivity(srcPatch, newTgtPatch, srcAddress_); writeFaceConnectivity(srcPatch, newTgtPatch, srcAddress_);
@ -913,7 +935,6 @@ void Foam::AMIInterpolation<SourcePatch, TargetPatch>::update
{ {
// calculate AMI interpolation // calculate AMI interpolation
{
autoPtr<AMIMethod<SourcePatch, TargetPatch> > AMIPtr autoPtr<AMIMethod<SourcePatch, TargetPatch> > AMIPtr
( (
AMIMethod<SourcePatch, TargetPatch>::New AMIMethod<SourcePatch, TargetPatch>::New
@ -935,7 +956,6 @@ void Foam::AMIInterpolation<SourcePatch, TargetPatch>::update
tgtAddress_, tgtAddress_,
tgtWeights_ tgtWeights_
); );
}
normaliseWeights normaliseWeights
( (
@ -944,6 +964,7 @@ void Foam::AMIInterpolation<SourcePatch, TargetPatch>::update
srcAddress_, srcAddress_,
srcWeights_, srcWeights_,
srcWeightsSum_, srcWeightsSum_,
AMIPtr->conformal(),
true true
); );
normaliseWeights normaliseWeights
@ -953,6 +974,7 @@ void Foam::AMIInterpolation<SourcePatch, TargetPatch>::update
tgtAddress_, tgtAddress_,
tgtWeights_, tgtWeights_,
tgtWeightsSum_, tgtWeightsSum_,
AMIPtr->conformal(),
true true
); );
} }

View File

@ -88,7 +88,8 @@ public:
{ {
imDirect, imDirect,
imMapNearest, imMapNearest,
imFaceAreaWeight imFaceAreaWeight,
imPartialFaceAreaWeight
}; };
//- Convert interpolationMethod to word representation //- Convert interpolationMethod to word representation
@ -236,6 +237,7 @@ private:
const labelListList& addr, const labelListList& addr,
scalarListList& wght, scalarListList& wght,
scalarField& wghtSum, scalarField& wghtSum,
const bool conformal,
const bool output const bool output
); );

View File

@ -41,6 +41,8 @@ void Foam::AMIMethod<SourcePatch, TargetPatch>::checkPatches() const
} }
if (conformal())
{
const scalar maxBoundsError = 0.05; const scalar maxBoundsError = 0.05;
// check bounds of source and target // check bounds of source and target
@ -53,13 +55,15 @@ void Foam::AMIMethod<SourcePatch, TargetPatch>::checkPatches() const
if (!bbTgtInf.contains(bbSrc)) if (!bbTgtInf.contains(bbSrc))
{ {
WarningIn("AMIMethod<SourcePatch, TargetPatch>::checkPatches()") WarningIn("AMIMethod<SourcePatch, TargetPatch>::checkPatches()")
<< "Source and target patch bounding boxes are not similar" << nl << "Source and target patch bounding boxes are not similar"
<< nl
<< " source box span : " << bbSrc.span() << nl << " source box span : " << bbSrc.span() << nl
<< " target box span : " << bbTgt.span() << nl << " target box span : " << bbTgt.span() << nl
<< " source box : " << bbSrc << nl << " source box : " << bbSrc << nl
<< " target box : " << bbTgt << nl << " target box : " << bbTgt << nl
<< " inflated target box : " << bbTgtInf << endl; << " inflated target box : " << bbTgtInf << endl;
} }
}
} }
@ -74,6 +78,8 @@ bool Foam::AMIMethod<SourcePatch, TargetPatch>::initialise
label& tgtFaceI label& tgtFaceI
) )
{ {
checkPatches();
// set initial sizes for weights and addressing - must be done even if // set initial sizes for weights and addressing - must be done even if
// returns false below // returns false below
srcAddress.setSize(srcPatch_.size()); srcAddress.setSize(srcPatch_.size());
@ -241,6 +247,9 @@ Foam::label Foam::AMIMethod<SourcePatch, TargetPatch>::findTargetFace
pointIndexHit sample = treePtr_->findNearest(srcPt, 10.0*srcFaceArea); pointIndexHit sample = treePtr_->findNearest(srcPt, 10.0*srcFaceArea);
if (sample.hit())
{
targetFaceI = sample.index();
if (debug) if (debug)
{ {
@ -248,10 +257,6 @@ Foam::label Foam::AMIMethod<SourcePatch, TargetPatch>::findTargetFace
<< sample.hitPoint() << ", Sample index = " << sample.index() << sample.hitPoint() << ", Sample index = " << sample.index()
<< endl; << endl;
} }
if (sample.hit())
{
targetFaceI = sample.index();
} }
return targetFaceI; return targetFaceI;
@ -334,8 +339,6 @@ Foam::AMIMethod<SourcePatch, TargetPatch>::AMIMethod
srcNonOverlap_(), srcNonOverlap_(),
triMode_(triMode) triMode_(triMode)
{ {
checkPatches();
label srcSize = returnReduce(srcPatch_.size(), sumOp<label>()); label srcSize = returnReduce(srcPatch_.size(), sumOp<label>());
label tgtSize = returnReduce(tgtPatch_.size(), sumOp<label>()); label tgtSize = returnReduce(tgtPatch_.size(), sumOp<label>());
@ -352,4 +355,13 @@ Foam::AMIMethod<SourcePatch, TargetPatch>::~AMIMethod()
{} {}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class SourcePatch, class TargetPatch>
bool Foam::AMIMethod<SourcePatch, TargetPatch>::conformal() const
{
return true;
}
// ************************************************************************* // // ************************************************************************* //

View File

@ -207,6 +207,9 @@ public:
// Note: this should be empty for correct functioning // Note: this should be empty for correct functioning
inline const labelList& srcNonOverlap() const; inline const labelList& srcNonOverlap() const;
//- Flag to indicate that interpolation patches are conformal
virtual bool conformal() const;
// Manipulation // Manipulation

View File

@ -25,7 +25,85 @@ License
#include "faceAreaWeightAMI.H" #include "faceAreaWeightAMI.H"
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // // * * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * //
template<class SourcePatch, class TargetPatch>
void Foam::faceAreaWeightAMI<SourcePatch, TargetPatch>::calcAddressing
(
List<DynamicList<label> >& srcAddr,
List<DynamicList<scalar> >& srcWght,
List<DynamicList<label> >& tgtAddr,
List<DynamicList<scalar> >& tgtWght,
label srcFaceI,
label tgtFaceI
)
{
// construct weights and addressing
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
label nFacesRemaining = srcAddr.size();
// list of tgt face neighbour faces
DynamicList<label> nbrFaces(10);
// list of faces currently visited for srcFaceI to avoid multiple hits
DynamicList<label> visitedFaces(10);
// list to keep track of tgt faces used to seed src faces
labelList seedFaces(nFacesRemaining, -1);
seedFaces[srcFaceI] = tgtFaceI;
// list to keep track of whether src face can be mapped
boolList mapFlag(nFacesRemaining, true);
// reset starting seed
label startSeedI = 0;
DynamicList<label> nonOverlapFaces;
do
{
// Do advancing front starting from srcFaceI,tgtFaceI
bool faceProcessed = processSourceFace
(
srcFaceI,
tgtFaceI,
nbrFaces,
visitedFaces,
srcAddr,
srcWght,
tgtAddr,
tgtWght
);
mapFlag[srcFaceI] = false;
nFacesRemaining--;
if (!faceProcessed)
{
nonOverlapFaces.append(srcFaceI);
}
// choose new src face from current src face neighbour
if (nFacesRemaining > 0)
{
setNextFaces
(
startSeedI,
srcFaceI,
tgtFaceI,
mapFlag,
seedFaces,
visitedFaces
);
}
} while (nFacesRemaining > 0);
this->srcNonOverlap_.transfer(nonOverlapFaces);
}
template<class SourcePatch, class TargetPatch> template<class SourcePatch, class TargetPatch>
bool Foam::faceAreaWeightAMI<SourcePatch, TargetPatch>::processSourceFace bool Foam::faceAreaWeightAMI<SourcePatch, TargetPatch>::processSourceFace
@ -45,6 +123,11 @@ bool Foam::faceAreaWeightAMI<SourcePatch, TargetPatch>::processSourceFace
List<DynamicList<scalar> >& tgtWght List<DynamicList<scalar> >& tgtWght
) )
{ {
if (tgtStartFaceI == -1)
{
return false;
}
nbrFaces.clear(); nbrFaces.clear();
visitedFaces.clear(); visitedFaces.clear();
@ -101,11 +184,15 @@ void Foam::faceAreaWeightAMI<SourcePatch, TargetPatch>::setNextFaces
label& tgtFaceI, label& tgtFaceI,
const boolList& mapFlag, const boolList& mapFlag,
labelList& seedFaces, labelList& seedFaces,
const DynamicList<label>& visitedFaces const DynamicList<label>& visitedFaces,
bool errorOnNotFound
) const ) const
{ {
const labelList& srcNbrFaces = this->srcPatch_.faceFaces()[srcFaceI]; const labelList& srcNbrFaces = this->srcPatch_.faceFaces()[srcFaceI];
// initialise tgtFaceI
tgtFaceI = -1;
// set possible seeds for later use // set possible seeds for later use
bool valuesSet = false; bool valuesSet = false;
forAll(srcNbrFaces, i) forAll(srcNbrFaces, i)
@ -195,6 +282,8 @@ void Foam::faceAreaWeightAMI<SourcePatch, TargetPatch>::setNextFaces
} }
} }
if (errorOnNotFound)
{
FatalErrorIn FatalErrorIn
( (
"void Foam::faceAreaWeightAMI<SourcePatch, TargetPatch>::" "void Foam::faceAreaWeightAMI<SourcePatch, TargetPatch>::"
@ -205,10 +294,12 @@ void Foam::faceAreaWeightAMI<SourcePatch, TargetPatch>::setNextFaces
"label&, " "label&, "
"const boolList&, " "const boolList&, "
"labelList&, " "labelList&, "
"const DynamicList<label>&" "const DynamicList<label>&, "
"bool"
") const" ") const"
) << "Unable to set source and target faces" << abort(FatalError); ) << "Unable to set source and target faces" << abort(FatalError);
} }
}
} }
@ -447,77 +538,21 @@ void Foam::faceAreaWeightAMI<SourcePatch, TargetPatch>::calculate
List<DynamicList<label> > tgtAddr(this->tgtPatch_.size()); List<DynamicList<label> > tgtAddr(this->tgtPatch_.size());
List<DynamicList<scalar> > tgtWght(tgtAddr.size()); List<DynamicList<scalar> > tgtWght(tgtAddr.size());
calcAddressing
// construct weights and addressing
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
label nFacesRemaining = srcAddr.size();
// list of tgt face neighbour faces
DynamicList<label> nbrFaces(10);
// list of faces currently visited for srcFaceI to avoid multiple hits
DynamicList<label> visitedFaces(10);
// list to keep track of tgt faces used to seed src faces
labelList seedFaces(nFacesRemaining, -1);
seedFaces[srcFaceI] = tgtFaceI;
// list to keep track of whether src face can be mapped
boolList mapFlag(nFacesRemaining, true);
// reset starting seed
label startSeedI = 0;
DynamicList<label> nonOverlapFaces;
do
{
// Do advancing front starting from srcFaceI,tgtFaceI
bool faceProcessed = processSourceFace
( (
srcFaceI,
tgtFaceI,
nbrFaces,
visitedFaces,
srcAddr, srcAddr,
srcWght, srcWght,
tgtAddr, tgtAddr,
tgtWght tgtWght,
);
mapFlag[srcFaceI] = false;
nFacesRemaining--;
if (!faceProcessed)
{
nonOverlapFaces.append(srcFaceI);
}
// choose new src face from current src face neighbour
if (nFacesRemaining > 0)
{
setNextFaces
(
startSeedI,
srcFaceI, srcFaceI,
tgtFaceI, tgtFaceI
mapFlag,
seedFaces,
visitedFaces
); );
}
} while (nFacesRemaining > 0);
if (nonOverlapFaces.size() != 0) if (this->srcNonOverlap_.size() != 0)
{ {
Pout<< " AMI: " << nonOverlapFaces.size() Pout<< " AMI: " << this->srcNonOverlap_.size()
<< " non-overlap faces identified" << " non-overlap faces identified"
<< endl; << endl;
this->srcNonOverlap_.transfer(nonOverlapFaces);
} }

View File

@ -52,9 +52,9 @@ class faceAreaWeightAMI
public AMIMethod<SourcePatch, TargetPatch> public AMIMethod<SourcePatch, TargetPatch>
{ {
private: protected:
// Private Member Functions // Protected Member Functions
//- Disallow default bitwise copy construct //- Disallow default bitwise copy construct
faceAreaWeightAMI(const faceAreaWeightAMI&); faceAreaWeightAMI(const faceAreaWeightAMI&);
@ -64,8 +64,19 @@ private:
// Marching front // Marching front
//- Calculate addressing and weights using temporary storage
virtual void calcAddressing
(
List<DynamicList<label> >& srcAddress,
List<DynamicList<scalar> >& srcWeights,
List<DynamicList<label> >& tgtAddress,
List<DynamicList<scalar> >& tgtWeights,
label srcFaceI,
label tgtFaceI
);
//- Determine overlap contributions for source face srcFaceI //- Determine overlap contributions for source face srcFaceI
bool processSourceFace virtual bool processSourceFace
( (
const label srcFaceI, const label srcFaceI,
const label tgtStartFaceI, const label tgtStartFaceI,
@ -78,7 +89,7 @@ private:
); );
//- Attempt to re-evaluate source faces that have not been included //- Attempt to re-evaluate source faces that have not been included
void restartUncoveredSourceFace virtual void restartUncoveredSourceFace
( (
List<DynamicList<label> >& srcAddr, List<DynamicList<label> >& srcAddr,
List<DynamicList<scalar> >& srcWght, List<DynamicList<scalar> >& srcWght,
@ -87,21 +98,22 @@ private:
); );
//- Set the source and target seed faces //- Set the source and target seed faces
void setNextFaces virtual void setNextFaces
( (
label& startSeedI, label& startSeedI,
label& srcFaceI, label& srcFaceI,
label& tgtFaceI, label& tgtFaceI,
const boolList& mapFlag, const boolList& mapFlag,
labelList& seedFaces, labelList& seedFaces,
const DynamicList<label>& visitedFaces const DynamicList<label>& visitedFaces,
bool errorOnNotFound = true
) const; ) const;
// Evaluation // Evaluation
//- Area of intersection between source and target faces //- Area of intersection between source and target faces
scalar interArea virtual scalar interArea
( (
const label srcFaceI, const label srcFaceI,
const label tgtFaceI const label tgtFaceI

View File

@ -0,0 +1,155 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2013 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 "partialFaceAreaWeightAMI.H"
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
template<class SourcePatch, class TargetPatch>
void Foam::partialFaceAreaWeightAMI<SourcePatch, TargetPatch>::setNextFaces
(
label& startSeedI,
label& srcFaceI,
label& tgtFaceI,
const boolList& mapFlag,
labelList& seedFaces,
const DynamicList<label>& visitedFaces,
const bool errorOnNotFound
) const
{
faceAreaWeightAMI<SourcePatch, TargetPatch>::setNextFaces
(
startSeedI,
srcFaceI,
tgtFaceI,
mapFlag,
seedFaces,
visitedFaces,
false // no error on not found
);
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
template<class SourcePatch, class TargetPatch>
Foam::partialFaceAreaWeightAMI<SourcePatch, TargetPatch>::
partialFaceAreaWeightAMI
(
const SourcePatch& srcPatch,
const TargetPatch& tgtPatch,
const scalarField& srcMagSf,
const scalarField& tgtMagSf,
const faceAreaIntersect::triangulationMode& triMode,
const bool reverseTarget
)
:
faceAreaWeightAMI<SourcePatch, TargetPatch>
(
srcPatch,
tgtPatch,
srcMagSf,
tgtMagSf,
triMode,
reverseTarget
)
{}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
template<class SourcePatch, class TargetPatch>
Foam::partialFaceAreaWeightAMI<SourcePatch, TargetPatch>::
~partialFaceAreaWeightAMI()
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class SourcePatch, class TargetPatch>
bool Foam::partialFaceAreaWeightAMI<SourcePatch, TargetPatch>::conformal() const
{
return false;
}
template<class SourcePatch, class TargetPatch>
void Foam::partialFaceAreaWeightAMI<SourcePatch, TargetPatch>::calculate
(
labelListList& srcAddress,
scalarListList& srcWeights,
labelListList& tgtAddress,
scalarListList& tgtWeights,
label srcFaceI,
label tgtFaceI
)
{
bool ok =
this->initialise
(
srcAddress,
srcWeights,
tgtAddress,
tgtWeights,
srcFaceI,
tgtFaceI
);
if (!ok)
{
return;
}
// temporary storage for addressing and weights
List<DynamicList<label> > srcAddr(this->srcPatch_.size());
List<DynamicList<scalar> > srcWght(srcAddr.size());
List<DynamicList<label> > tgtAddr(this->tgtPatch_.size());
List<DynamicList<scalar> > tgtWght(tgtAddr.size());
faceAreaWeightAMI<SourcePatch, TargetPatch>::calcAddressing
(
srcAddr,
srcWght,
tgtAddr,
tgtWght,
srcFaceI,
tgtFaceI
);
// transfer data to persistent storage
forAll(srcAddr, i)
{
srcAddress[i].transfer(srcAddr[i]);
srcWeights[i].transfer(srcWght[i]);
}
forAll(tgtAddr, i)
{
tgtAddress[i].transfer(tgtAddr[i]);
tgtWeights[i].transfer(tgtWght[i]);
}
}
// ************************************************************************* //

View File

@ -0,0 +1,141 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2013 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::partialFaceAreaWeightAMI
Description
Partial face area weighted Arbitrary Mesh Interface (AMI) method
SourceFiles
partialFaceAreaWeightAMI.C
\*---------------------------------------------------------------------------*/
#ifndef partialFaceAreaWeightAMI_H
#define partialFaceAreaWeightAMI_H
#include "faceAreaWeightAMI.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class partialFaceAreaWeightAMI Declaration
\*---------------------------------------------------------------------------*/
template<class SourcePatch, class TargetPatch>
class partialFaceAreaWeightAMI
:
public faceAreaWeightAMI<SourcePatch, TargetPatch>
{
private:
// Private Member Functions
//- Disallow default bitwise copy construct
partialFaceAreaWeightAMI(const partialFaceAreaWeightAMI&);
//- Disallow default bitwise assignment
void operator=(const partialFaceAreaWeightAMI&);
// Marching front
//- Set the source and target seed faces
virtual void setNextFaces
(
label& startSeedI,
label& srcFaceI,
label& tgtFaceI,
const boolList& mapFlag,
labelList& seedFaces,
const DynamicList<label>& visitedFaces,
bool errorOnNotFound = true
) const;
public:
//- Runtime type information
TypeName("partialFaceAreaWeightAMI");
// Constructors
//- Construct from components
partialFaceAreaWeightAMI
(
const SourcePatch& srcPatch,
const TargetPatch& tgtPatch,
const scalarField& srcMagSf,
const scalarField& tgtMagSf,
const faceAreaIntersect::triangulationMode& triMode,
const bool reverseTarget = false
);
//- Destructor
virtual ~partialFaceAreaWeightAMI();
// Member Functions
// Access
//- Flag to indicate that interpolation patches are conformal
virtual bool conformal() const;
// Manipulation
//- Update addressing and weights
virtual void calculate
(
labelListList& srcAddress,
scalarListList& srcWeights,
labelListList& tgtAddress,
scalarListList& tgtWeights,
label srcFaceI = -1,
label tgtFaceI = -1
);
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository
# include "partialFaceAreaWeightAMI.C"
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -28,6 +28,7 @@ License
#include "directAMI.H" #include "directAMI.H"
#include "mapNearestAMI.H" #include "mapNearestAMI.H"
#include "faceAreaWeightAMI.H" #include "faceAreaWeightAMI.H"
#include "partialFaceAreaWeightAMI.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -38,6 +39,7 @@ namespace Foam
makeAMIMethodType(AMIPatchToPatchInterpolation, directAMI); makeAMIMethodType(AMIPatchToPatchInterpolation, directAMI);
makeAMIMethodType(AMIPatchToPatchInterpolation, mapNearestAMI); makeAMIMethodType(AMIPatchToPatchInterpolation, mapNearestAMI);
makeAMIMethodType(AMIPatchToPatchInterpolation, faceAreaWeightAMI); makeAMIMethodType(AMIPatchToPatchInterpolation, faceAreaWeightAMI);
makeAMIMethodType(AMIPatchToPatchInterpolation, partialFaceAreaWeightAMI);
} }

View File

@ -0,0 +1,129 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2013 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 "cyclicACMIGAMGInterfaceField.H"
#include "addToRunTimeSelectionTable.H"
#include "lduMatrix.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
defineTypeNameAndDebug(cyclicACMIGAMGInterfaceField, 0);
addToRunTimeSelectionTable
(
GAMGInterfaceField,
cyclicACMIGAMGInterfaceField,
lduInterface
);
addToRunTimeSelectionTable
(
GAMGInterfaceField,
cyclicACMIGAMGInterfaceField,
lduInterfaceField
);
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::cyclicACMIGAMGInterfaceField::cyclicACMIGAMGInterfaceField
(
const GAMGInterface& GAMGCp,
const lduInterfaceField& fineInterface
)
:
GAMGInterfaceField(GAMGCp, fineInterface),
cyclicACMIInterface_(refCast<const cyclicACMIGAMGInterface>(GAMGCp)),
doTransform_(false),
rank_(0)
{
const cyclicAMILduInterfaceField& p =
refCast<const cyclicAMILduInterfaceField>(fineInterface);
doTransform_ = p.doTransform();
rank_ = p.rank();
}
Foam::cyclicACMIGAMGInterfaceField::cyclicACMIGAMGInterfaceField
(
const GAMGInterface& GAMGCp,
const bool doTransform,
const int rank
)
:
GAMGInterfaceField(GAMGCp, doTransform, rank),
cyclicACMIInterface_(refCast<const cyclicACMIGAMGInterface>(GAMGCp)),
doTransform_(doTransform),
rank_(rank)
{}
// * * * * * * * * * * * * * * * * Desstructor * * * * * * * * * * * * * * * //
Foam::cyclicACMIGAMGInterfaceField::~cyclicACMIGAMGInterfaceField()
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
void Foam::cyclicACMIGAMGInterfaceField::updateInterfaceMatrix
(
scalarField& result,
const scalarField& psiInternal,
const scalarField& coeffs,
const direction cmpt,
const Pstream::commsTypes
) const
{
// Get neighbouring field
scalarField pnf
(
cyclicACMIInterface_.neighbPatch().interfaceInternalField(psiInternal)
);
// Transform according to the transformation tensors
transformCoupleField(pnf, cmpt);
if (cyclicACMIInterface_.owner())
{
pnf = cyclicACMIInterface_.AMI().interpolateToSource(pnf);
}
else
{
pnf = cyclicACMIInterface_.neighbPatch().AMI().interpolateToTarget(pnf);
}
const labelUList& faceCells = cyclicACMIInterface_.faceCells();
forAll(faceCells, elemI)
{
result[faceCells[elemI]] -= coeffs[elemI]*pnf[elemI];
}
}
// ************************************************************************* //

View File

@ -0,0 +1,166 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2013 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::cyclicACMIGAMGInterfaceField
Description
GAMG agglomerated cyclic interface for Arbitrarily Coupled Mesh Interface
(ACMI) fields.
SourceFiles
cyclicACMIGAMGInterfaceField.C
\*---------------------------------------------------------------------------*/
#ifndef cyclicACMIGAMGInterfaceField_H
#define cyclicACMIGAMGInterfaceField_H
#include "GAMGInterfaceField.H"
#include "cyclicACMIGAMGInterface.H"
#include "cyclicACMILduInterfaceField.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class cyclicACMIGAMGInterfaceField Declaration
\*---------------------------------------------------------------------------*/
class cyclicACMIGAMGInterfaceField
:
public GAMGInterfaceField,
virtual public cyclicACMILduInterfaceField
{
// Private data
//- Local reference cast into the cyclic interface
const cyclicACMIGAMGInterface& cyclicACMIInterface_;
//- Is the transform required
bool doTransform_;
//- Rank of component for transformation
int rank_;
// Private Member Functions
//- Disallow default bitwise copy construct
cyclicACMIGAMGInterfaceField(const cyclicACMIGAMGInterfaceField&);
//- Disallow default bitwise assignment
void operator=(const cyclicACMIGAMGInterfaceField&);
public:
//- Runtime type information
TypeName("cyclicACMI");
// Constructors
//- Construct from GAMG interface and fine level interface field
cyclicACMIGAMGInterfaceField
(
const GAMGInterface& GAMGCp,
const lduInterfaceField& fineInterfaceField
);
//- Construct from GAMG interface and fine level interface field
cyclicACMIGAMGInterfaceField
(
const GAMGInterface& GAMGCp,
const bool doTransform,
const int rank
);
//- Destructor
virtual ~cyclicACMIGAMGInterfaceField();
// Member Functions
// Access
//- Return size
label size() const
{
return cyclicACMIInterface_.size();
}
// Interface matrix update
//- Update result field based on interface functionality
virtual void updateInterfaceMatrix
(
scalarField& result,
const scalarField& psiInternal,
const scalarField& coeffs,
const direction cmpt,
const Pstream::commsTypes commsType
) const;
//- Cyclic interface functions
//- Does the interface field perform the transfromation
virtual bool doTransform() const
{
return doTransform_;
}
//- Return face transformation tensor
virtual const tensorField& forwardT() const
{
return cyclicACMIInterface_.forwardT();
}
//- Return neighbour-cell transformation tensor
virtual const tensorField& reverseT() const
{
return cyclicACMIInterface_.reverseT();
}
//- Return rank of component for transform
virtual int rank() const
{
return rank_;
}
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,198 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2013 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 "AMIInterpolation.H"
#include "cyclicACMIGAMGInterface.H"
#include "addToRunTimeSelectionTable.H"
#include "Map.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
defineTypeNameAndDebug(cyclicACMIGAMGInterface, 0);
addToRunTimeSelectionTable
(
GAMGInterface,
cyclicACMIGAMGInterface,
lduInterface
);
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::cyclicACMIGAMGInterface::cyclicACMIGAMGInterface
(
const label index,
const lduInterfacePtrsList& coarseInterfaces,
const lduInterface& fineInterface,
const labelField& localRestrictAddressing,
const labelField& neighbourRestrictAddressing,
const label fineLevelIndex,
const label coarseComm
)
:
GAMGInterface
(
index,
coarseInterfaces
),
fineCyclicACMIInterface_
(
refCast<const cyclicACMILduInterface>(fineInterface)
)
{
// Construct face agglomeration from cell agglomeration
{
// From coarse face to cell
DynamicList<label> dynFaceCells(localRestrictAddressing.size());
// From face to coarse face
DynamicList<label> dynFaceRestrictAddressing
(
localRestrictAddressing.size()
);
Map<label> masterToCoarseFace(localRestrictAddressing.size());
forAll(localRestrictAddressing, ffi)
{
label curMaster = localRestrictAddressing[ffi];
Map<label>::const_iterator fnd = masterToCoarseFace.find
(
curMaster
);
if (fnd == masterToCoarseFace.end())
{
// New coarse face
label coarseI = dynFaceCells.size();
dynFaceRestrictAddressing.append(coarseI);
dynFaceCells.append(curMaster);
masterToCoarseFace.insert(curMaster, coarseI);
}
else
{
// Already have coarse face
dynFaceRestrictAddressing.append(fnd());
}
}
faceCells_.transfer(dynFaceCells);
faceRestrictAddressing_.transfer(dynFaceRestrictAddressing);
}
// On the owner side construct the AMI
if (fineCyclicACMIInterface_.owner())
{
// Construct the neighbour side agglomeration (as the neighbour would
// do it so it the exact loop above using neighbourRestrictAddressing
// instead of localRestrictAddressing)
labelList nbrFaceRestrictAddressing;
{
// From face to coarse face
DynamicList<label> dynNbrFaceRestrictAddressing
(
neighbourRestrictAddressing.size()
);
Map<label> masterToCoarseFace(neighbourRestrictAddressing.size());
forAll(neighbourRestrictAddressing, ffi)
{
label curMaster = neighbourRestrictAddressing[ffi];
Map<label>::const_iterator fnd = masterToCoarseFace.find
(
curMaster
);
if (fnd == masterToCoarseFace.end())
{
// New coarse face
label coarseI = masterToCoarseFace.size();
dynNbrFaceRestrictAddressing.append(coarseI);
masterToCoarseFace.insert(curMaster, coarseI);
}
else
{
// Already have coarse face
dynNbrFaceRestrictAddressing.append(fnd());
}
}
nbrFaceRestrictAddressing.transfer(dynNbrFaceRestrictAddressing);
}
amiPtr_.reset
(
new AMIPatchToPatchInterpolation
(
fineCyclicACMIInterface_.AMI(),
faceRestrictAddressing_,
nbrFaceRestrictAddressing
)
);
}
}
// * * * * * * * * * * * * * * * * Desstructor * * * * * * * * * * * * * * * //
Foam::cyclicACMIGAMGInterface::~cyclicACMIGAMGInterface()
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
Foam::tmp<Foam::labelField>
Foam::cyclicACMIGAMGInterface::internalFieldTransfer
(
const Pstream::commsTypes,
const labelUList& iF
) const
{
const cyclicACMIGAMGInterface& nbr =
dynamic_cast<const cyclicACMIGAMGInterface&>(neighbPatch());
const labelUList& nbrFaceCells = nbr.faceCells();
tmp<labelField> tpnf(new labelField(nbrFaceCells.size()));
labelField& pnf = tpnf();
forAll(pnf, facei)
{
pnf[facei] = iF[nbrFaceCells[facei]];
}
return tpnf;
}
// ************************************************************************* //

View File

@ -0,0 +1,174 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2013 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::cyclicACMIGAMGInterface
Description
GAMG agglomerated cyclic ACMI interface.
SourceFiles
cyclicACMIGAMGInterface.C
\*---------------------------------------------------------------------------*/
#ifndef cyclicACMIGAMGInterface_H
#define cyclicACMIGAMGInterface_H
#include "GAMGInterface.H"
#include "cyclicACMILduInterface.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class cyclicACMIGAMGInterface Declaration
\*---------------------------------------------------------------------------*/
class cyclicACMIGAMGInterface
:
public GAMGInterface,
virtual public cyclicACMILduInterface
{
// Private data
//- Reference for the cyclicLduInterface from which this is
// agglomerated
const cyclicACMILduInterface& fineCyclicACMIInterface_;
//- AMI interface
autoPtr<AMIPatchToPatchInterpolation> amiPtr_;
// Private Member Functions
//- Disallow default bitwise copy construct
cyclicACMIGAMGInterface(const cyclicACMIGAMGInterface&);
//- Disallow default bitwise assignment
void operator=(const cyclicACMIGAMGInterface&);
public:
//- Runtime type information
TypeName("cyclicACMI");
// Constructors
//- Construct from fine level interface,
// local and neighbour restrict addressing
cyclicACMIGAMGInterface
(
const label index,
const lduInterfacePtrsList& coarseInterfaces,
const lduInterface& fineInterface,
const labelField& restrictAddressing,
const labelField& neighbourRestrictAddressing,
const label fineLevelIndex,
const label coarseComm
);
//- Destructor
virtual ~cyclicACMIGAMGInterface();
// Member Functions
// Interface transfer functions
//- Transfer and return internal field adjacent to the interface
virtual tmp<labelField> internalFieldTransfer
(
const Pstream::commsTypes commsType,
const labelUList& iF
) const;
//- Cyclic interface functions
//- Return neigbour processor number
virtual label neighbPatchID() const
{
return fineCyclicACMIInterface_.neighbPatchID();
}
virtual bool owner() const
{
return fineCyclicACMIInterface_.owner();
}
virtual const cyclicACMIGAMGInterface& neighbPatch() const
{
return dynamic_cast<const cyclicACMIGAMGInterface&>
(
coarseInterfaces_[neighbPatchID()]
);
}
virtual const AMIPatchToPatchInterpolation& AMI() const
{
return amiPtr_();
}
//- Return face transformation tensor
virtual const tensorField& forwardT() const
{
return fineCyclicACMIInterface_.forwardT();
}
//- Return neighbour-cell transformation tensor
virtual const tensorField& reverseT() const
{
return fineCyclicACMIInterface_.reverseT();
}
// I/O
//- Write to stream
virtual void write(Ostream&) const
{
//TBD. How to serialise the AMI such that we can stream
// cyclicACMIGAMGInterface.
notImplemented
(
"cyclicACMIGAMGInterface::write(Ostream&) const"
);
}
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,42 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2013 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 "cyclicACMILduInterface.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
defineTypeNameAndDebug(cyclicACMILduInterface, 0);
}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::cyclicACMILduInterface::~cyclicACMILduInterface()
{}
// ************************************************************************* //

View File

@ -0,0 +1,80 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2013 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::cyclicACMILduInterface
Description
An abstract base class for cyclic ACMI coupled interfaces
SourceFiles
cyclicACMILduInterface.C
\*---------------------------------------------------------------------------*/
#ifndef cyclicACMILduInterface_H
#define cyclicACMILduInterface_H
#include "cyclicAMILduInterface.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class cyclicACMILduInterface Declaration
\*---------------------------------------------------------------------------*/
class cyclicACMILduInterface
:
public cyclicAMILduInterface
{
public:
//- Runtime type information
TypeName("cyclicACMILduInterface");
// Constructors
//- Construct null
cyclicACMILduInterface()
{}
//- Destructor
virtual ~cyclicACMILduInterface();
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

Some files were not shown because too many files have changed in this diff Show More