mirror of
https://develop.openfoam.com/Development/openfoam.git
synced 2025-11-28 03:28:01 +00:00
Merge branch 'feature-runtime-selection-geometry' into 'develop'
Feature runtime selection geometry See merge request Development/openfoam!411
This commit is contained in:
@ -704,7 +704,7 @@ int main(int argc, char *argv[])
|
|||||||
regionName,
|
regionName,
|
||||||
runTimeExtruded.constant(),
|
runTimeExtruded.constant(),
|
||||||
runTimeExtruded,
|
runTimeExtruded,
|
||||||
IOobject::NO_READ,
|
IOobject::READ_IF_PRESENT, // Read fv* if present
|
||||||
IOobject::AUTO_WRITE,
|
IOobject::AUTO_WRITE,
|
||||||
false
|
false
|
||||||
),
|
),
|
||||||
|
|||||||
@ -154,6 +154,7 @@ int main(int argc, char *argv[])
|
|||||||
"cellShapes",
|
"cellShapes",
|
||||||
"cellVolume",
|
"cellVolume",
|
||||||
"cellVolumeRatio",
|
"cellVolumeRatio",
|
||||||
|
"cellAspectRatio",
|
||||||
"minTetVolume",
|
"minTetVolume",
|
||||||
"minPyrVolume",
|
"minPyrVolume",
|
||||||
"cellRegion",
|
"cellRegion",
|
||||||
|
|||||||
@ -7,6 +7,7 @@
|
|||||||
#include "tetPointRef.H"
|
#include "tetPointRef.H"
|
||||||
#include "regionSplit.H"
|
#include "regionSplit.H"
|
||||||
#include "wallDist.H"
|
#include "wallDist.H"
|
||||||
|
#include "cellAspectRatio.H"
|
||||||
|
|
||||||
using namespace Foam;
|
using namespace Foam;
|
||||||
|
|
||||||
@ -318,6 +319,32 @@ void Foam::writeFields
|
|||||||
aspectRatio.write();
|
aspectRatio.write();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (selectedFields.found("cellAspectRatio"))
|
||||||
|
{
|
||||||
|
volScalarField aspectRatio
|
||||||
|
(
|
||||||
|
IOobject
|
||||||
|
(
|
||||||
|
"cellAspectRatio",
|
||||||
|
mesh.time().timeName(),
|
||||||
|
mesh,
|
||||||
|
IOobject::NO_READ,
|
||||||
|
IOobject::AUTO_WRITE,
|
||||||
|
false
|
||||||
|
),
|
||||||
|
mesh,
|
||||||
|
dimensionedScalar(dimless, Zero),
|
||||||
|
zeroGradientFvPatchScalarField::typeName
|
||||||
|
);
|
||||||
|
|
||||||
|
aspectRatio.ref().field() = cellAspectRatio(mesh);
|
||||||
|
|
||||||
|
aspectRatio.correctBoundaryConditions();
|
||||||
|
Info<< " Writing approximate aspect ratio to "
|
||||||
|
<< aspectRatio.name() << endl;
|
||||||
|
aspectRatio.write();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// cell type
|
// cell type
|
||||||
// ~~~~~~~~~
|
// ~~~~~~~~~
|
||||||
|
|||||||
@ -680,7 +680,7 @@ autoPtr<mapPolyMesh> createRegionMesh
|
|||||||
regionName,
|
regionName,
|
||||||
mesh.time().timeName(),
|
mesh.time().timeName(),
|
||||||
mesh.time(),
|
mesh.time(),
|
||||||
IOobject::NO_READ,
|
IOobject::READ_IF_PRESENT, // read fv* if present
|
||||||
IOobject::AUTO_WRITE
|
IOobject::AUTO_WRITE
|
||||||
),
|
),
|
||||||
mesh
|
mesh
|
||||||
|
|||||||
@ -36,6 +36,7 @@ License
|
|||||||
#include "pointSet.H"
|
#include "pointSet.H"
|
||||||
#include "faceSet.H"
|
#include "faceSet.H"
|
||||||
#include "cellSet.H"
|
#include "cellSet.H"
|
||||||
|
#include "basicFvGeometryScheme.H"
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * Global Functions * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * Global Functions * * * * * * * * * * * * * //
|
||||||
|
|
||||||
@ -254,6 +255,19 @@ Foam::autoPtr<Foam::fvMesh> Foam::loadOrCreateMesh
|
|||||||
auto meshPtr = autoPtr<fvMesh>::New(io);
|
auto meshPtr = autoPtr<fvMesh>::New(io);
|
||||||
fvMesh& mesh = *meshPtr;
|
fvMesh& mesh = *meshPtr;
|
||||||
|
|
||||||
|
// Make sure to use a non-parallel geometry calculation method
|
||||||
|
{
|
||||||
|
tmp<fvGeometryScheme> basicGeometry
|
||||||
|
(
|
||||||
|
fvGeometryScheme::New
|
||||||
|
(
|
||||||
|
mesh,
|
||||||
|
dictionary(),
|
||||||
|
basicFvGeometryScheme::typeName
|
||||||
|
)
|
||||||
|
);
|
||||||
|
mesh.geometry(basicGeometry);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Sync patches
|
// Sync patches
|
||||||
|
|||||||
@ -92,6 +92,7 @@ Usage
|
|||||||
#include "zeroGradientFvPatchFields.H"
|
#include "zeroGradientFvPatchFields.H"
|
||||||
#include "topoSet.H"
|
#include "topoSet.H"
|
||||||
#include "regionProperties.H"
|
#include "regionProperties.H"
|
||||||
|
#include "basicFvGeometryScheme.H"
|
||||||
|
|
||||||
#include "parFvFieldReconstructor.H"
|
#include "parFvFieldReconstructor.H"
|
||||||
#include "parLagrangianRedistributor.H"
|
#include "parLagrangianRedistributor.H"
|
||||||
@ -152,6 +153,30 @@ scalar getMergeDistance
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void setBasicGeometry(fvMesh& mesh)
|
||||||
|
{
|
||||||
|
// Set the fvGeometryScheme to basic since it does not require
|
||||||
|
// any parallel communication to construct the geometry. During
|
||||||
|
// redistributePar one might temporarily end up with processors
|
||||||
|
// with zero procBoundaries. Normally procBoundaries trigger geometry
|
||||||
|
// calculation (e.g. send over cellCentres) so on the processors without
|
||||||
|
// procBoundaries this will not happen. The call to the geometry calculation
|
||||||
|
// is not synchronised and this might lead to a hang for geometry schemes
|
||||||
|
// that do require synchronisation
|
||||||
|
|
||||||
|
tmp<fvGeometryScheme> basicGeometry
|
||||||
|
(
|
||||||
|
fvGeometryScheme::New
|
||||||
|
(
|
||||||
|
mesh,
|
||||||
|
dictionary(),
|
||||||
|
basicFvGeometryScheme::typeName
|
||||||
|
)
|
||||||
|
);
|
||||||
|
mesh.geometry(basicGeometry);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void printMeshData(const polyMesh& mesh)
|
void printMeshData(const polyMesh& mesh)
|
||||||
{
|
{
|
||||||
// Collect all data on master
|
// Collect all data on master
|
||||||
@ -2675,6 +2700,10 @@ int main(int argc, char *argv[])
|
|||||||
);
|
);
|
||||||
fvMesh& mesh = meshPtr();
|
fvMesh& mesh = meshPtr();
|
||||||
|
|
||||||
|
// Use basic geometry calculation to avoid synchronisation
|
||||||
|
// problems. See comment in routine
|
||||||
|
setBasicGeometry(mesh);
|
||||||
|
|
||||||
// Global matching tolerance
|
// Global matching tolerance
|
||||||
const scalar tolDim = getMergeDistance
|
const scalar tolDim = getMergeDistance
|
||||||
(
|
(
|
||||||
@ -2736,6 +2765,8 @@ int main(int argc, char *argv[])
|
|||||||
),
|
),
|
||||||
true // read on master only
|
true // read on master only
|
||||||
);
|
);
|
||||||
|
setBasicGeometry(baseMeshPtr());
|
||||||
|
|
||||||
|
|
||||||
Info<< "Reading local, decomposed mesh" << endl;
|
Info<< "Reading local, decomposed mesh" << endl;
|
||||||
autoPtr<fvMesh> meshPtr = loadOrCreateMesh
|
autoPtr<fvMesh> meshPtr = loadOrCreateMesh
|
||||||
|
|||||||
@ -438,6 +438,20 @@ Foam::IOobject::IOobject
|
|||||||
{}
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::IOobject::IOobject
|
||||||
|
(
|
||||||
|
const IOobject& io,
|
||||||
|
readOption ro,
|
||||||
|
writeOption wo
|
||||||
|
)
|
||||||
|
:
|
||||||
|
IOobject(io)
|
||||||
|
{
|
||||||
|
rOpt_ = ro;
|
||||||
|
wOpt_ = wo;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||||
|
|
||||||
const Foam::objectRegistry& Foam::IOobject::db() const
|
const Foam::objectRegistry& Foam::IOobject::db() const
|
||||||
|
|||||||
@ -340,6 +340,14 @@ public:
|
|||||||
const word& name
|
const word& name
|
||||||
);
|
);
|
||||||
|
|
||||||
|
//- Copy construct, resetting io options
|
||||||
|
IOobject
|
||||||
|
(
|
||||||
|
const IOobject& io,
|
||||||
|
readOption,
|
||||||
|
writeOption
|
||||||
|
);
|
||||||
|
|
||||||
//- Clone
|
//- Clone
|
||||||
autoPtr<IOobject> clone() const
|
autoPtr<IOobject> clone() const
|
||||||
{
|
{
|
||||||
|
|||||||
@ -63,9 +63,11 @@ else
|
|||||||
runTime.timeName(),
|
runTime.timeName(),
|
||||||
runTime,
|
runTime,
|
||||||
Foam::IOobject::MUST_READ
|
Foam::IOobject::MUST_READ
|
||||||
)
|
),
|
||||||
|
false
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
meshPtr().init(true); // initialise all (lower levels and current)
|
||||||
}
|
}
|
||||||
|
|
||||||
Foam::fvMesh& mesh = meshPtr();
|
Foam::fvMesh& mesh = meshPtr();
|
||||||
|
|||||||
@ -21,5 +21,7 @@ Foam::fvMesh mesh
|
|||||||
runTime.timeName(),
|
runTime.timeName(),
|
||||||
runTime,
|
runTime,
|
||||||
Foam::IOobject::MUST_READ
|
Foam::IOobject::MUST_READ
|
||||||
)
|
),
|
||||||
|
false
|
||||||
);
|
);
|
||||||
|
mesh.init(true); // initialise all (lower levels and current)
|
||||||
|
|||||||
@ -155,6 +155,50 @@ Foam::solution::solution
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::solution::solution
|
||||||
|
(
|
||||||
|
const objectRegistry& obr,
|
||||||
|
const fileName& dictName,
|
||||||
|
const dictionary& dict
|
||||||
|
)
|
||||||
|
:
|
||||||
|
IOdictionary
|
||||||
|
(
|
||||||
|
IOobject
|
||||||
|
(
|
||||||
|
dictName,
|
||||||
|
obr.time().system(),
|
||||||
|
obr,
|
||||||
|
(
|
||||||
|
obr.readOpt() == IOobject::MUST_READ
|
||||||
|
|| obr.readOpt() == IOobject::READ_IF_PRESENT
|
||||||
|
? IOobject::MUST_READ_IF_MODIFIED
|
||||||
|
: obr.readOpt()
|
||||||
|
),
|
||||||
|
IOobject::NO_WRITE
|
||||||
|
),
|
||||||
|
dict
|
||||||
|
),
|
||||||
|
cache_(dictionary::null),
|
||||||
|
caching_(false),
|
||||||
|
fieldRelaxDict_(dictionary::null),
|
||||||
|
eqnRelaxDict_(dictionary::null),
|
||||||
|
fieldRelaxDefault_(0),
|
||||||
|
eqnRelaxDefault_(0),
|
||||||
|
solvers_(dictionary::null)
|
||||||
|
{
|
||||||
|
if
|
||||||
|
(
|
||||||
|
readOpt() == IOobject::MUST_READ
|
||||||
|
|| readOpt() == IOobject::MUST_READ_IF_MODIFIED
|
||||||
|
|| (readOpt() == IOobject::READ_IF_PRESENT && headerOk())
|
||||||
|
)
|
||||||
|
{
|
||||||
|
read(solutionDict());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||||
|
|
||||||
Foam::label Foam::solution::upgradeSolverDict
|
Foam::label Foam::solution::upgradeSolverDict
|
||||||
|
|||||||
@ -6,6 +6,7 @@
|
|||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Copyright (C) 2011-2016 OpenFOAM Foundation
|
Copyright (C) 2011-2016 OpenFOAM Foundation
|
||||||
|
Copyright (C) 2020 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM.
|
This file is part of OpenFOAM.
|
||||||
@ -101,13 +102,22 @@ public:
|
|||||||
|
|
||||||
// Constructors
|
// Constructors
|
||||||
|
|
||||||
//- Construct for given objectRegistry and dictionary
|
//- Construct for given objectRegistry and dictionary name
|
||||||
solution
|
solution
|
||||||
(
|
(
|
||||||
const objectRegistry& obr,
|
const objectRegistry& obr,
|
||||||
const fileName& dictName
|
const fileName& dictName
|
||||||
);
|
);
|
||||||
|
|
||||||
|
//- Construct for given objectRegistry, dictionary name and (optional)
|
||||||
|
// content (gets used in case of NO_READ or dictionary cannot be read)
|
||||||
|
solution
|
||||||
|
(
|
||||||
|
const objectRegistry& obr,
|
||||||
|
const fileName& dictName,
|
||||||
|
const dictionary& dict
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
// Member Functions
|
// Member Functions
|
||||||
|
|
||||||
|
|||||||
@ -6,6 +6,7 @@
|
|||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Copyright (C) 2011-2015 OpenFOAM Foundation
|
Copyright (C) 2011-2015 OpenFOAM Foundation
|
||||||
|
Copyright (C) 2020 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM.
|
This file is part of OpenFOAM.
|
||||||
@ -54,6 +55,24 @@ Foam::data::data(const objectRegistry& obr)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::data::data(const objectRegistry& obr, const dictionary& dict)
|
||||||
|
:
|
||||||
|
IOdictionary
|
||||||
|
(
|
||||||
|
IOobject
|
||||||
|
(
|
||||||
|
"data",
|
||||||
|
obr.time().system(),
|
||||||
|
obr,
|
||||||
|
IOobject::NO_READ,
|
||||||
|
IOobject::NO_WRITE
|
||||||
|
),
|
||||||
|
dict
|
||||||
|
),
|
||||||
|
prevTimeIndex_(0)
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||||
|
|
||||||
const Foam::dictionary& Foam::data::solverPerformanceDict() const
|
const Foam::dictionary& Foam::data::solverPerformanceDict() const
|
||||||
|
|||||||
@ -6,6 +6,7 @@
|
|||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Copyright (C) 2011-2016 OpenFOAM Foundation
|
Copyright (C) 2011-2016 OpenFOAM Foundation
|
||||||
|
Copyright (C) 2020 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM.
|
This file is part of OpenFOAM.
|
||||||
@ -82,6 +83,9 @@ public:
|
|||||||
//- Construct for objectRegistry
|
//- Construct for objectRegistry
|
||||||
data(const objectRegistry& obr);
|
data(const objectRegistry& obr);
|
||||||
|
|
||||||
|
//- Construct for objectRegistry and initial contents
|
||||||
|
data(const objectRegistry& obr, const dictionary& dict);
|
||||||
|
|
||||||
|
|
||||||
// Member Functions
|
// Member Functions
|
||||||
|
|
||||||
|
|||||||
@ -70,20 +70,29 @@ void Foam::polyMesh::calcDirections() const
|
|||||||
|
|
||||||
forAll(boundaryMesh(), patchi)
|
forAll(boundaryMesh(), patchi)
|
||||||
{
|
{
|
||||||
if (boundaryMesh()[patchi].size())
|
const polyPatch& pp = boundaryMesh()[patchi];
|
||||||
|
if (isA<emptyPolyPatch>(pp))
|
||||||
{
|
{
|
||||||
if (isA<emptyPolyPatch>(boundaryMesh()[patchi]))
|
// Force calculation of geometric properties, independent of
|
||||||
|
// size. This avoids parallel synchronisation problems.
|
||||||
|
const vectorField::subField fa(pp.faceAreas());
|
||||||
|
|
||||||
|
if (pp.size())
|
||||||
{
|
{
|
||||||
nEmptyPatches++;
|
nEmptyPatches++;
|
||||||
emptyDirVec += sum(cmptMag(boundaryMesh()[patchi].faceAreas()));
|
emptyDirVec += sum(cmptMag(fa));
|
||||||
}
|
}
|
||||||
else if (isA<wedgePolyPatch>(boundaryMesh()[patchi]))
|
}
|
||||||
{
|
else if (isA<wedgePolyPatch>(pp))
|
||||||
const wedgePolyPatch& wpp = refCast<const wedgePolyPatch>
|
{
|
||||||
(
|
const wedgePolyPatch& wpp = refCast<const wedgePolyPatch>(pp);
|
||||||
boundaryMesh()[patchi]
|
|
||||||
);
|
|
||||||
|
|
||||||
|
// Force calculation of geometric properties, independent of
|
||||||
|
// size. This avoids parallel synchronisation problems.
|
||||||
|
(void)wpp.faceNormals();
|
||||||
|
|
||||||
|
if (pp.size())
|
||||||
|
{
|
||||||
nWedgePatches++;
|
nWedgePatches++;
|
||||||
wedgeDirVec += cmptMag(wpp.centreNormal());
|
wedgeDirVec += cmptMag(wpp.centreNormal());
|
||||||
}
|
}
|
||||||
@ -161,7 +170,7 @@ Foam::autoPtr<Foam::labelIOList> Foam::polyMesh::readTetBasePtIs() const
|
|||||||
|
|
||||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
Foam::polyMesh::polyMesh(const IOobject& io)
|
Foam::polyMesh::polyMesh(const IOobject& io, const bool doInit)
|
||||||
:
|
:
|
||||||
objectRegistry(io),
|
objectRegistry(io),
|
||||||
primitiveMesh(),
|
primitiveMesh(),
|
||||||
@ -328,12 +337,6 @@ Foam::polyMesh::polyMesh(const IOobject& io)
|
|||||||
neighbour_.write();
|
neighbour_.write();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Calculate topology for the patches (processor-processor comms etc.)
|
|
||||||
boundary_.updateMesh();
|
|
||||||
|
|
||||||
// Calculate the geometry for the patches (transformation tensors etc.)
|
|
||||||
boundary_.calcGeometry();
|
|
||||||
|
|
||||||
// Warn if global empty mesh
|
// Warn if global empty mesh
|
||||||
if (returnReduce(boundary_.empty(), orOp<bool>()))
|
if (returnReduce(boundary_.empty(), orOp<bool>()))
|
||||||
{
|
{
|
||||||
@ -352,8 +355,30 @@ Foam::polyMesh::polyMesh(const IOobject& io)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (doInit)
|
||||||
|
{
|
||||||
|
polyMesh::init(false); // do not init lower levels
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Foam::polyMesh::init(const bool doInit)
|
||||||
|
{
|
||||||
|
if (doInit)
|
||||||
|
{
|
||||||
|
primitiveMesh::init(doInit);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Calculate topology for the patches (processor-processor comms etc.)
|
||||||
|
boundary_.updateMesh();
|
||||||
|
|
||||||
|
// Calculate the geometry for the patches (transformation tensors etc.)
|
||||||
|
boundary_.calcGeometry();
|
||||||
|
|
||||||
// Initialise demand-driven data
|
// Initialise demand-driven data
|
||||||
calcDirections();
|
calcDirections();
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -377,7 +402,7 @@ Foam::polyMesh::polyMesh
|
|||||||
instance(),
|
instance(),
|
||||||
meshSubDir,
|
meshSubDir,
|
||||||
*this,
|
*this,
|
||||||
io.readOpt(),
|
IOobject::NO_READ, //io.readOpt(),
|
||||||
io.writeOpt()
|
io.writeOpt()
|
||||||
),
|
),
|
||||||
std::move(points)
|
std::move(points)
|
||||||
@ -390,7 +415,7 @@ Foam::polyMesh::polyMesh
|
|||||||
instance(),
|
instance(),
|
||||||
meshSubDir,
|
meshSubDir,
|
||||||
*this,
|
*this,
|
||||||
io.readOpt(),
|
IOobject::NO_READ, //io.readOpt(),
|
||||||
io.writeOpt()
|
io.writeOpt()
|
||||||
),
|
),
|
||||||
std::move(faces)
|
std::move(faces)
|
||||||
@ -403,7 +428,7 @@ Foam::polyMesh::polyMesh
|
|||||||
instance(),
|
instance(),
|
||||||
meshSubDir,
|
meshSubDir,
|
||||||
*this,
|
*this,
|
||||||
io.readOpt(),
|
IOobject::NO_READ, //io.readOpt(),
|
||||||
io.writeOpt()
|
io.writeOpt()
|
||||||
),
|
),
|
||||||
std::move(owner)
|
std::move(owner)
|
||||||
@ -416,7 +441,7 @@ Foam::polyMesh::polyMesh
|
|||||||
instance(),
|
instance(),
|
||||||
meshSubDir,
|
meshSubDir,
|
||||||
*this,
|
*this,
|
||||||
io.readOpt(),
|
IOobject::NO_READ, //io.readOpt(),
|
||||||
io.writeOpt()
|
io.writeOpt()
|
||||||
),
|
),
|
||||||
std::move(neighbour)
|
std::move(neighbour)
|
||||||
@ -430,7 +455,7 @@ Foam::polyMesh::polyMesh
|
|||||||
instance(),
|
instance(),
|
||||||
meshSubDir,
|
meshSubDir,
|
||||||
*this,
|
*this,
|
||||||
io.readOpt(),
|
IOobject::NO_READ, //io.readOpt(),
|
||||||
io.writeOpt()
|
io.writeOpt()
|
||||||
),
|
),
|
||||||
*this,
|
*this,
|
||||||
@ -440,7 +465,7 @@ Foam::polyMesh::polyMesh
|
|||||||
comm_(UPstream::worldComm),
|
comm_(UPstream::worldComm),
|
||||||
geometricD_(Zero),
|
geometricD_(Zero),
|
||||||
solutionD_(Zero),
|
solutionD_(Zero),
|
||||||
tetBasePtIsPtr_(readTetBasePtIs()),
|
tetBasePtIsPtr_(nullptr),
|
||||||
cellTreePtr_(nullptr),
|
cellTreePtr_(nullptr),
|
||||||
pointZones_
|
pointZones_
|
||||||
(
|
(
|
||||||
@ -450,7 +475,7 @@ Foam::polyMesh::polyMesh
|
|||||||
instance(),
|
instance(),
|
||||||
meshSubDir,
|
meshSubDir,
|
||||||
*this,
|
*this,
|
||||||
io.readOpt(),
|
IOobject::NO_READ, //io.readOpt(),
|
||||||
IOobject::NO_WRITE
|
IOobject::NO_WRITE
|
||||||
),
|
),
|
||||||
*this,
|
*this,
|
||||||
@ -464,7 +489,7 @@ Foam::polyMesh::polyMesh
|
|||||||
instance(),
|
instance(),
|
||||||
meshSubDir,
|
meshSubDir,
|
||||||
*this,
|
*this,
|
||||||
io.readOpt(),
|
IOobject::NO_READ, //io.readOpt(),
|
||||||
IOobject::NO_WRITE
|
IOobject::NO_WRITE
|
||||||
),
|
),
|
||||||
*this,
|
*this,
|
||||||
@ -478,7 +503,7 @@ Foam::polyMesh::polyMesh
|
|||||||
instance(),
|
instance(),
|
||||||
meshSubDir,
|
meshSubDir,
|
||||||
*this,
|
*this,
|
||||||
io.readOpt(),
|
IOobject::NO_READ, //io.readOpt(),
|
||||||
IOobject::NO_WRITE
|
IOobject::NO_WRITE
|
||||||
),
|
),
|
||||||
*this,
|
*this,
|
||||||
@ -591,7 +616,7 @@ Foam::polyMesh::polyMesh
|
|||||||
comm_(UPstream::worldComm),
|
comm_(UPstream::worldComm),
|
||||||
geometricD_(Zero),
|
geometricD_(Zero),
|
||||||
solutionD_(Zero),
|
solutionD_(Zero),
|
||||||
tetBasePtIsPtr_(readTetBasePtIs()),
|
tetBasePtIsPtr_(nullptr),
|
||||||
cellTreePtr_(nullptr),
|
cellTreePtr_(nullptr),
|
||||||
pointZones_
|
pointZones_
|
||||||
(
|
(
|
||||||
|
|||||||
@ -319,11 +319,11 @@ public:
|
|||||||
// Constructors
|
// Constructors
|
||||||
|
|
||||||
//- Read construct from IOobject
|
//- Read construct from IOobject
|
||||||
explicit polyMesh(const IOobject& io);
|
polyMesh(const IOobject& io, const bool doInit = true);
|
||||||
|
|
||||||
//- Construct from IOobject or as zero-sized mesh
|
//- Construct from IOobject or as zero-sized mesh
|
||||||
// Boundary is added using addPatches() member function
|
// Boundary is added using addPatches() member function
|
||||||
polyMesh(const IOobject& io, const zero, bool syncPar=true);
|
polyMesh(const IOobject& io, const zero, const bool syncPar=true);
|
||||||
|
|
||||||
//- Construct from IOobject or from components.
|
//- Construct from IOobject or from components.
|
||||||
// Boundary is added using addPatches() member function
|
// Boundary is added using addPatches() member function
|
||||||
@ -593,6 +593,9 @@ public:
|
|||||||
const List<cellZone*>& cz
|
const List<cellZone*>& cz
|
||||||
);
|
);
|
||||||
|
|
||||||
|
//- Initialise all non-demand-driven data
|
||||||
|
virtual bool init(const bool doInit);
|
||||||
|
|
||||||
//- Update the mesh based on the mesh files saved in
|
//- Update the mesh based on the mesh files saved in
|
||||||
// time directories
|
// time directories
|
||||||
virtual readUpdateState readUpdate();
|
virtual readUpdateState readUpdate();
|
||||||
|
|||||||
@ -753,13 +753,26 @@ bool Foam::polyMesh::checkMeshMotion
|
|||||||
vectorField fCtrs(nFaces());
|
vectorField fCtrs(nFaces());
|
||||||
vectorField fAreas(nFaces());
|
vectorField fAreas(nFaces());
|
||||||
|
|
||||||
makeFaceCentresAndAreas(newPoints, fCtrs, fAreas);
|
primitiveMeshTools::makeFaceCentresAndAreas
|
||||||
|
(
|
||||||
|
*this,
|
||||||
|
newPoints,
|
||||||
|
fCtrs,
|
||||||
|
fAreas
|
||||||
|
);
|
||||||
|
|
||||||
// Check cell volumes and calculate new cell centres
|
// Check cell volumes and calculate new cell centres
|
||||||
vectorField cellCtrs(nCells());
|
vectorField cellCtrs(nCells());
|
||||||
scalarField cellVols(nCells());
|
scalarField cellVols(nCells());
|
||||||
|
|
||||||
makeCellCentresAndVols(fCtrs, fAreas, cellCtrs, cellVols);
|
primitiveMeshTools::makeCellCentresAndVols
|
||||||
|
(
|
||||||
|
*this,
|
||||||
|
fCtrs,
|
||||||
|
fAreas,
|
||||||
|
cellCtrs,
|
||||||
|
cellVols
|
||||||
|
);
|
||||||
|
|
||||||
// Check cell volumes
|
// Check cell volumes
|
||||||
bool error = checkCellVolumes
|
bool error = checkCellVolumes
|
||||||
|
|||||||
@ -281,6 +281,44 @@ void Foam::primitiveMesh::reset
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::primitiveMesh::resetGeometry
|
||||||
|
(
|
||||||
|
pointField&& faceCentres,
|
||||||
|
pointField&& faceAreas,
|
||||||
|
pointField&& cellCentres,
|
||||||
|
scalarField&& cellVolumes
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if
|
||||||
|
(
|
||||||
|
faceCentres.size() != nFaces_
|
||||||
|
|| faceAreas.size() != nFaces_
|
||||||
|
|| cellCentres.size() != nCells_
|
||||||
|
|| cellVolumes.size() != nCells_
|
||||||
|
)
|
||||||
|
{
|
||||||
|
FatalErrorInFunction
|
||||||
|
<< "Wrong sizes of passed in face/cell data"
|
||||||
|
<< abort(FatalError);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove old geometry
|
||||||
|
clearGeom();
|
||||||
|
|
||||||
|
faceCentresPtr_ = new pointField(std::move(faceCentres));
|
||||||
|
faceAreasPtr_ = new pointField(std::move(faceAreas));
|
||||||
|
cellCentresPtr_ = new pointField(std::move(cellCentres));
|
||||||
|
cellVolumesPtr_ = new scalarField(std::move(cellVolumes));
|
||||||
|
|
||||||
|
if (debug)
|
||||||
|
{
|
||||||
|
Pout<< "primitiveMesh::resetGeometry : geometry reset for"
|
||||||
|
<< " nFaces:" << faceCentresPtr_->size()
|
||||||
|
<< " nCells:" << cellCentresPtr_->size() << endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
Foam::tmp<Foam::scalarField> Foam::primitiveMesh::movePoints
|
Foam::tmp<Foam::scalarField> Foam::primitiveMesh::movePoints
|
||||||
(
|
(
|
||||||
const pointField& newPoints,
|
const pointField& newPoints,
|
||||||
@ -324,4 +362,26 @@ const Foam::cellShapeList& Foam::primitiveMesh::cellShapes() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::primitiveMesh::updateGeom()
|
||||||
|
{
|
||||||
|
if (!faceCentresPtr_)
|
||||||
|
{
|
||||||
|
calcFaceCentresAndAreas();
|
||||||
|
}
|
||||||
|
if (!faceAreasPtr_)
|
||||||
|
{
|
||||||
|
calcFaceCentresAndAreas();
|
||||||
|
}
|
||||||
|
if (!cellCentresPtr_)
|
||||||
|
{
|
||||||
|
calcCellCentresAndVols();
|
||||||
|
}
|
||||||
|
if (!cellVolumesPtr_)
|
||||||
|
{
|
||||||
|
calcCellCentresAndVols();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
// ************************************************************************* //
|
||||||
|
|||||||
@ -255,22 +255,9 @@ protected:
|
|||||||
|
|
||||||
//- Calculate face centres and areas
|
//- Calculate face centres and areas
|
||||||
void calcFaceCentresAndAreas() const;
|
void calcFaceCentresAndAreas() const;
|
||||||
void makeFaceCentresAndAreas
|
|
||||||
(
|
|
||||||
const pointField& p,
|
|
||||||
vectorField& fCtrs,
|
|
||||||
vectorField& fAreas
|
|
||||||
) const;
|
|
||||||
|
|
||||||
//- Calculate cell centres and volumes
|
//- Calculate cell centres and volumes
|
||||||
void calcCellCentresAndVols() const;
|
void calcCellCentresAndVols() const;
|
||||||
void makeCellCentresAndVols
|
|
||||||
(
|
|
||||||
const vectorField& fCtrs,
|
|
||||||
const vectorField& fAreas,
|
|
||||||
vectorField& cellCtrs,
|
|
||||||
scalarField& cellVols
|
|
||||||
) const;
|
|
||||||
|
|
||||||
//- Calculate edge vectors
|
//- Calculate edge vectors
|
||||||
void calcEdgeVectors() const;
|
void calcEdgeVectors() const;
|
||||||
@ -476,6 +463,21 @@ public:
|
|||||||
cellList& cells
|
cellList& cells
|
||||||
);
|
);
|
||||||
|
|
||||||
|
//- Reset the local geometry
|
||||||
|
void resetGeometry
|
||||||
|
(
|
||||||
|
pointField&& faceCentres,
|
||||||
|
pointField&& faceAreas,
|
||||||
|
pointField&& cellCentres,
|
||||||
|
scalarField&& cellVolumes
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Initialise all non-demand-driven data
|
||||||
|
virtual bool init(const bool doInit)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Access
|
// Access
|
||||||
|
|
||||||
@ -891,6 +893,8 @@ public:
|
|||||||
|
|
||||||
const labelList& cellEdges(const label celli) const;
|
const labelList& cellEdges(const label celli) const;
|
||||||
|
|
||||||
|
//- Update all geometric data
|
||||||
|
virtual void updateGeom();
|
||||||
|
|
||||||
//- Clear geometry
|
//- Clear geometry
|
||||||
void clearGeom();
|
void clearGeom();
|
||||||
|
|||||||
@ -30,7 +30,7 @@ Description
|
|||||||
\*---------------------------------------------------------------------------*/
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
#include "primitiveMesh.H"
|
#include "primitiveMesh.H"
|
||||||
#include "PrecisionAdaptor.H"
|
#include "primitiveMeshTools.H"
|
||||||
|
|
||||||
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||||
|
|
||||||
@ -61,7 +61,14 @@ void Foam::primitiveMesh::calcCellCentresAndVols() const
|
|||||||
scalarField& cellVols = *cellVolumesPtr_;
|
scalarField& cellVols = *cellVolumesPtr_;
|
||||||
|
|
||||||
// Make centres and volumes
|
// Make centres and volumes
|
||||||
makeCellCentresAndVols(faceCentres(), faceAreas(), cellCtrs, cellVols);
|
primitiveMeshTools::makeCellCentresAndVols
|
||||||
|
(
|
||||||
|
*this,
|
||||||
|
faceCentres(),
|
||||||
|
faceAreas(),
|
||||||
|
cellCtrs,
|
||||||
|
cellVols
|
||||||
|
);
|
||||||
|
|
||||||
if (debug)
|
if (debug)
|
||||||
{
|
{
|
||||||
@ -72,111 +79,14 @@ void Foam::primitiveMesh::calcCellCentresAndVols() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Foam::primitiveMesh::makeCellCentresAndVols
|
|
||||||
(
|
|
||||||
const vectorField& fCtrs,
|
|
||||||
const vectorField& fAreas,
|
|
||||||
vectorField& cellCtrs_s,
|
|
||||||
scalarField& cellVols_s
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
typedef Vector<solveScalar> solveVector;
|
|
||||||
|
|
||||||
PrecisionAdaptor<solveVector, vector> tcellCtrs(cellCtrs_s, false);
|
|
||||||
Field<solveVector>& cellCtrs = tcellCtrs.ref();
|
|
||||||
PrecisionAdaptor<solveScalar, scalar> tcellVols(cellVols_s, false);
|
|
||||||
Field<solveScalar>& cellVols = tcellVols.ref();
|
|
||||||
|
|
||||||
cellCtrs = Zero;
|
|
||||||
cellVols = 0.0;
|
|
||||||
|
|
||||||
const labelList& own = faceOwner();
|
|
||||||
const labelList& nei = faceNeighbour();
|
|
||||||
|
|
||||||
// first estimate the approximate cell centre as the average of
|
|
||||||
// face centres
|
|
||||||
|
|
||||||
Field<solveVector> cEst(nCells(), Zero);
|
|
||||||
labelField nCellFaces(nCells(), Zero);
|
|
||||||
|
|
||||||
forAll(own, facei)
|
|
||||||
{
|
|
||||||
cEst[own[facei]] += solveVector(fCtrs[facei]);
|
|
||||||
++nCellFaces[own[facei]];
|
|
||||||
}
|
|
||||||
|
|
||||||
forAll(nei, facei)
|
|
||||||
{
|
|
||||||
cEst[nei[facei]] += solveVector(fCtrs[facei]);
|
|
||||||
++nCellFaces[nei[facei]];
|
|
||||||
}
|
|
||||||
|
|
||||||
forAll(cEst, celli)
|
|
||||||
{
|
|
||||||
cEst[celli] /= nCellFaces[celli];
|
|
||||||
}
|
|
||||||
|
|
||||||
forAll(own, facei)
|
|
||||||
{
|
|
||||||
const solveVector fc(fCtrs[facei]);
|
|
||||||
const solveVector fA(fAreas[facei]);
|
|
||||||
|
|
||||||
// Calculate 3*face-pyramid volume
|
|
||||||
solveScalar pyr3Vol =
|
|
||||||
fA & (fc - cEst[own[facei]]);
|
|
||||||
|
|
||||||
// Calculate face-pyramid centre
|
|
||||||
solveVector pc = (3.0/4.0)*fc + (1.0/4.0)*cEst[own[facei]];
|
|
||||||
|
|
||||||
// Accumulate volume-weighted face-pyramid centre
|
|
||||||
cellCtrs[own[facei]] += pyr3Vol*pc;
|
|
||||||
|
|
||||||
// Accumulate face-pyramid volume
|
|
||||||
cellVols[own[facei]] += pyr3Vol;
|
|
||||||
}
|
|
||||||
|
|
||||||
forAll(nei, facei)
|
|
||||||
{
|
|
||||||
const solveVector fc(fCtrs[facei]);
|
|
||||||
const solveVector fA(fAreas[facei]);
|
|
||||||
|
|
||||||
// Calculate 3*face-pyramid volume
|
|
||||||
solveScalar pyr3Vol =
|
|
||||||
fA & (cEst[nei[facei]] - fc);
|
|
||||||
|
|
||||||
// Calculate face-pyramid centre
|
|
||||||
solveVector pc = (3.0/4.0)*fc + (1.0/4.0)*cEst[nei[facei]];
|
|
||||||
|
|
||||||
// Accumulate volume-weighted face-pyramid centre
|
|
||||||
cellCtrs[nei[facei]] += pyr3Vol*pc;
|
|
||||||
|
|
||||||
// Accumulate face-pyramid volume
|
|
||||||
cellVols[nei[facei]] += pyr3Vol;
|
|
||||||
}
|
|
||||||
|
|
||||||
forAll(cellCtrs, celli)
|
|
||||||
{
|
|
||||||
if (mag(cellVols[celli]) > VSMALL)
|
|
||||||
{
|
|
||||||
cellCtrs[celli] /= cellVols[celli];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
cellCtrs[celli] = cEst[celli];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
cellVols *= (1.0/3.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||||
|
|
||||||
const Foam::vectorField& Foam::primitiveMesh::cellCentres() const
|
const Foam::vectorField& Foam::primitiveMesh::cellCentres() const
|
||||||
{
|
{
|
||||||
if (!cellCentresPtr_)
|
if (!cellCentresPtr_)
|
||||||
{
|
{
|
||||||
calcCellCentresAndVols();
|
//calcCellCentresAndVols();
|
||||||
|
const_cast<primitiveMesh&>(*this).updateGeom();
|
||||||
}
|
}
|
||||||
|
|
||||||
return *cellCentresPtr_;
|
return *cellCentresPtr_;
|
||||||
@ -187,7 +97,8 @@ const Foam::scalarField& Foam::primitiveMesh::cellVolumes() const
|
|||||||
{
|
{
|
||||||
if (!cellVolumesPtr_)
|
if (!cellVolumesPtr_)
|
||||||
{
|
{
|
||||||
calcCellCentresAndVols();
|
//calcCellCentresAndVols();
|
||||||
|
const_cast<primitiveMesh&>(*this).updateGeom();
|
||||||
}
|
}
|
||||||
|
|
||||||
return *cellVolumesPtr_;
|
return *cellVolumesPtr_;
|
||||||
|
|||||||
@ -27,11 +27,182 @@ License
|
|||||||
\*---------------------------------------------------------------------------*/
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
#include "primitiveMeshTools.H"
|
#include "primitiveMeshTools.H"
|
||||||
|
#include "primitiveMesh.H"
|
||||||
#include "syncTools.H"
|
#include "syncTools.H"
|
||||||
#include "pyramidPointFaceRef.H"
|
#include "pyramidPointFaceRef.H"
|
||||||
|
#include "PrecisionAdaptor.H"
|
||||||
|
|
||||||
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||||
|
|
||||||
|
void Foam::primitiveMeshTools::makeFaceCentresAndAreas
|
||||||
|
(
|
||||||
|
const primitiveMesh& mesh,
|
||||||
|
const pointField& p,
|
||||||
|
vectorField& fCtrs,
|
||||||
|
vectorField& fAreas
|
||||||
|
)
|
||||||
|
{
|
||||||
|
const faceList& fs = mesh.faces();
|
||||||
|
|
||||||
|
forAll(fs, facei)
|
||||||
|
{
|
||||||
|
const labelList& f = fs[facei];
|
||||||
|
const label nPoints = f.size();
|
||||||
|
|
||||||
|
// If the face is a triangle, do a direct calculation for efficiency
|
||||||
|
// and to avoid round-off error-related problems
|
||||||
|
if (nPoints == 3)
|
||||||
|
{
|
||||||
|
fCtrs[facei] = (1.0/3.0)*(p[f[0]] + p[f[1]] + p[f[2]]);
|
||||||
|
fAreas[facei] = 0.5*((p[f[1]] - p[f[0]])^(p[f[2]] - p[f[0]]));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
typedef Vector<solveScalar> solveVector;
|
||||||
|
|
||||||
|
solveVector sumN = Zero;
|
||||||
|
solveScalar sumA = 0.0;
|
||||||
|
solveVector sumAc = Zero;
|
||||||
|
|
||||||
|
solveVector fCentre = p[f[0]];
|
||||||
|
for (label pi = 1; pi < nPoints; pi++)
|
||||||
|
{
|
||||||
|
fCentre += solveVector(p[f[pi]]);
|
||||||
|
}
|
||||||
|
|
||||||
|
fCentre /= nPoints;
|
||||||
|
|
||||||
|
for (label pi = 0; pi < nPoints; pi++)
|
||||||
|
{
|
||||||
|
const label nextPi(pi == nPoints-1 ? 0 : pi+1);
|
||||||
|
const solveVector nextPoint(p[f[nextPi]]);
|
||||||
|
const solveVector thisPoint(p[f[pi]]);
|
||||||
|
|
||||||
|
solveVector c = thisPoint + nextPoint + fCentre;
|
||||||
|
solveVector n = (nextPoint - thisPoint)^(fCentre - thisPoint);
|
||||||
|
solveScalar a = mag(n);
|
||||||
|
sumN += n;
|
||||||
|
sumA += a;
|
||||||
|
sumAc += a*c;
|
||||||
|
}
|
||||||
|
|
||||||
|
// This is to deal with zero-area faces. Mark very small faces
|
||||||
|
// to be detected in e.g., processorPolyPatch.
|
||||||
|
if (sumA < ROOTVSMALL)
|
||||||
|
{
|
||||||
|
fCtrs[facei] = fCentre;
|
||||||
|
fAreas[facei] = Zero;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fCtrs[facei] = (1.0/3.0)*sumAc/sumA;
|
||||||
|
fAreas[facei] = 0.5*sumN;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::primitiveMeshTools::makeCellCentresAndVols
|
||||||
|
(
|
||||||
|
const primitiveMesh& mesh,
|
||||||
|
const vectorField& fCtrs,
|
||||||
|
const vectorField& fAreas,
|
||||||
|
vectorField& cellCtrs_s,
|
||||||
|
scalarField& cellVols_s
|
||||||
|
)
|
||||||
|
{
|
||||||
|
typedef Vector<solveScalar> solveVector;
|
||||||
|
|
||||||
|
PrecisionAdaptor<solveVector, vector> tcellCtrs(cellCtrs_s);
|
||||||
|
Field<solveVector>& cellCtrs = tcellCtrs.ref();
|
||||||
|
PrecisionAdaptor<solveScalar, scalar> tcellVols(cellVols_s);
|
||||||
|
Field<solveScalar>& cellVols = tcellVols.ref();
|
||||||
|
|
||||||
|
// Clear the fields for accumulation
|
||||||
|
cellCtrs = Zero;
|
||||||
|
cellVols = 0.0;
|
||||||
|
|
||||||
|
const labelList& own = mesh.faceOwner();
|
||||||
|
const labelList& nei = mesh.faceNeighbour();
|
||||||
|
|
||||||
|
// first estimate the approximate cell centre as the average of
|
||||||
|
// face centres
|
||||||
|
|
||||||
|
Field<solveVector> cEst(mesh.nCells(), Zero);
|
||||||
|
labelField nCellFaces(mesh.nCells(), Zero);
|
||||||
|
|
||||||
|
forAll(own, facei)
|
||||||
|
{
|
||||||
|
cEst[own[facei]] += solveVector(fCtrs[facei]);
|
||||||
|
++nCellFaces[own[facei]];
|
||||||
|
}
|
||||||
|
|
||||||
|
forAll(nei, facei)
|
||||||
|
{
|
||||||
|
cEst[nei[facei]] += solveVector(fCtrs[facei]);
|
||||||
|
++nCellFaces[nei[facei]];
|
||||||
|
}
|
||||||
|
|
||||||
|
forAll(cEst, celli)
|
||||||
|
{
|
||||||
|
cEst[celli] /= nCellFaces[celli];
|
||||||
|
}
|
||||||
|
|
||||||
|
forAll(own, facei)
|
||||||
|
{
|
||||||
|
const solveVector fc(fCtrs[facei]);
|
||||||
|
const solveVector fA(fAreas[facei]);
|
||||||
|
|
||||||
|
// Calculate 3*face-pyramid volume
|
||||||
|
solveScalar pyr3Vol =
|
||||||
|
fA & (fc - cEst[own[facei]]);
|
||||||
|
|
||||||
|
// Calculate face-pyramid centre
|
||||||
|
solveVector pc = (3.0/4.0)*fc + (1.0/4.0)*cEst[own[facei]];
|
||||||
|
|
||||||
|
// Accumulate volume-weighted face-pyramid centre
|
||||||
|
cellCtrs[own[facei]] += pyr3Vol*pc;
|
||||||
|
|
||||||
|
// Accumulate face-pyramid volume
|
||||||
|
cellVols[own[facei]] += pyr3Vol;
|
||||||
|
}
|
||||||
|
|
||||||
|
forAll(nei, facei)
|
||||||
|
{
|
||||||
|
const solveVector fc(fCtrs[facei]);
|
||||||
|
const solveVector fA(fAreas[facei]);
|
||||||
|
|
||||||
|
// Calculate 3*face-pyramid volume
|
||||||
|
solveScalar pyr3Vol =
|
||||||
|
fA & (cEst[nei[facei]] - fc);
|
||||||
|
|
||||||
|
// Calculate face-pyramid centre
|
||||||
|
solveVector pc = (3.0/4.0)*fc + (1.0/4.0)*cEst[nei[facei]];
|
||||||
|
|
||||||
|
// Accumulate volume-weighted face-pyramid centre
|
||||||
|
cellCtrs[nei[facei]] += pyr3Vol*pc;
|
||||||
|
|
||||||
|
// Accumulate face-pyramid volume
|
||||||
|
cellVols[nei[facei]] += pyr3Vol;
|
||||||
|
}
|
||||||
|
|
||||||
|
forAll(cellCtrs, celli)
|
||||||
|
{
|
||||||
|
if (mag(cellVols[celli]) > VSMALL)
|
||||||
|
{
|
||||||
|
cellCtrs[celli] /= cellVols[celli];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cellCtrs[celli] = cEst[celli];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cellVols *= (1.0/3.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
Foam::scalar Foam::primitiveMeshTools::faceSkewness
|
Foam::scalar Foam::primitiveMeshTools::faceSkewness
|
||||||
(
|
(
|
||||||
const primitiveMesh& mesh,
|
const primitiveMesh& mesh,
|
||||||
|
|||||||
@ -38,22 +38,45 @@ SourceFiles
|
|||||||
#ifndef primitiveMeshTools_H
|
#ifndef primitiveMeshTools_H
|
||||||
#define primitiveMeshTools_H
|
#define primitiveMeshTools_H
|
||||||
|
|
||||||
#include "primitiveMesh.H"
|
|
||||||
#include "bitSet.H"
|
#include "bitSet.H"
|
||||||
|
#include "primitiveFields.H"
|
||||||
|
#include "pointField.H"
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
namespace Foam
|
namespace Foam
|
||||||
{
|
{
|
||||||
|
|
||||||
|
// Forward declarations
|
||||||
|
class primitiveMesh;
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*\
|
/*---------------------------------------------------------------------------*\
|
||||||
Namespace primitiveMeshTools Declaration
|
Namespace primitiveMeshTools Declaration
|
||||||
\*---------------------------------------------------------------------------*/
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
class primitiveMeshTools
|
class primitiveMeshTools
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
//- Calculate face centres and areas
|
||||||
|
static void makeFaceCentresAndAreas
|
||||||
|
(
|
||||||
|
const primitiveMesh& mesh,
|
||||||
|
const pointField& p,
|
||||||
|
vectorField& fCtrs,
|
||||||
|
vectorField& fAreas
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Calculate cell centres and volumes from face properties
|
||||||
|
static void makeCellCentresAndVols
|
||||||
|
(
|
||||||
|
const primitiveMesh& mesh,
|
||||||
|
const vectorField& fCtrs,
|
||||||
|
const vectorField& fAreas,
|
||||||
|
vectorField& cellCtrs,
|
||||||
|
scalarField& cellVols
|
||||||
|
);
|
||||||
|
|
||||||
//- Generate non-orthogonality field (internal faces only)
|
//- Generate non-orthogonality field (internal faces only)
|
||||||
static tmp<scalarField> faceOrthogonality
|
static tmp<scalarField> faceOrthogonality
|
||||||
(
|
(
|
||||||
|
|||||||
@ -33,6 +33,7 @@ Description
|
|||||||
\*---------------------------------------------------------------------------*/
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
#include "primitiveMesh.H"
|
#include "primitiveMesh.H"
|
||||||
|
#include "primitiveMeshTools.H"
|
||||||
|
|
||||||
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||||
|
|
||||||
@ -60,7 +61,7 @@ void Foam::primitiveMesh::calcFaceCentresAndAreas() const
|
|||||||
faceAreasPtr_ = new vectorField(nFaces());
|
faceAreasPtr_ = new vectorField(nFaces());
|
||||||
vectorField& fAreas = *faceAreasPtr_;
|
vectorField& fAreas = *faceAreasPtr_;
|
||||||
|
|
||||||
makeFaceCentresAndAreas(points(), fCtrs, fAreas);
|
primitiveMeshTools::makeFaceCentresAndAreas(*this, points(), fCtrs, fAreas);
|
||||||
|
|
||||||
if (debug)
|
if (debug)
|
||||||
{
|
{
|
||||||
@ -71,81 +72,14 @@ void Foam::primitiveMesh::calcFaceCentresAndAreas() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Foam::primitiveMesh::makeFaceCentresAndAreas
|
|
||||||
(
|
|
||||||
const pointField& p,
|
|
||||||
vectorField& fCtrs,
|
|
||||||
vectorField& fAreas
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
const faceList& fs = faces();
|
|
||||||
|
|
||||||
forAll(fs, facei)
|
|
||||||
{
|
|
||||||
const labelList& f = fs[facei];
|
|
||||||
const label nPoints = f.size();
|
|
||||||
|
|
||||||
// If the face is a triangle, do a direct calculation for efficiency
|
|
||||||
// and to avoid round-off error-related problems
|
|
||||||
if (nPoints == 3)
|
|
||||||
{
|
|
||||||
fCtrs[facei] = (1.0/3.0)*(p[f[0]] + p[f[1]] + p[f[2]]);
|
|
||||||
fAreas[facei] = 0.5*((p[f[1]] - p[f[0]])^(p[f[2]] - p[f[0]]));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
typedef Vector<solveScalar> solveVector;
|
|
||||||
|
|
||||||
solveVector sumN = Zero;
|
|
||||||
solveScalar sumA = 0.0;
|
|
||||||
solveVector sumAc = Zero;
|
|
||||||
|
|
||||||
solveVector fCentre = p[f[0]];
|
|
||||||
for (label pi = 1; pi < nPoints; pi++)
|
|
||||||
{
|
|
||||||
fCentre += solveVector(p[f[pi]]);
|
|
||||||
}
|
|
||||||
|
|
||||||
fCentre /= nPoints;
|
|
||||||
|
|
||||||
for (label pi = 0; pi < nPoints; pi++)
|
|
||||||
{
|
|
||||||
const label nextPi(pi == nPoints-1 ? 0 : pi+1);
|
|
||||||
const solveVector nextPoint(p[f[nextPi]]);
|
|
||||||
const solveVector thisPoint(p[f[pi]]);
|
|
||||||
|
|
||||||
solveVector c = thisPoint + nextPoint + fCentre;
|
|
||||||
solveVector n = (nextPoint - thisPoint)^(fCentre - thisPoint);
|
|
||||||
solveScalar a = mag(n);
|
|
||||||
sumN += n;
|
|
||||||
sumA += a;
|
|
||||||
sumAc += a*c;
|
|
||||||
}
|
|
||||||
|
|
||||||
// This is to deal with zero-area faces. Mark very small faces
|
|
||||||
// to be detected in e.g., processorPolyPatch.
|
|
||||||
if (sumA < ROOTVSMALL)
|
|
||||||
{
|
|
||||||
fCtrs[facei] = fCentre;
|
|
||||||
fAreas[facei] = Zero;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
fCtrs[facei] = (1.0/3.0)*sumAc/sumA;
|
|
||||||
fAreas[facei] = 0.5*sumN;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||||
|
|
||||||
const Foam::vectorField& Foam::primitiveMesh::faceCentres() const
|
const Foam::vectorField& Foam::primitiveMesh::faceCentres() const
|
||||||
{
|
{
|
||||||
if (!faceCentresPtr_)
|
if (!faceCentresPtr_)
|
||||||
{
|
{
|
||||||
calcFaceCentresAndAreas();
|
//calcFaceCentresAndAreas();
|
||||||
|
const_cast<primitiveMesh&>(*this).updateGeom();
|
||||||
}
|
}
|
||||||
|
|
||||||
return *faceCentresPtr_;
|
return *faceCentresPtr_;
|
||||||
@ -156,7 +90,8 @@ const Foam::vectorField& Foam::primitiveMesh::faceAreas() const
|
|||||||
{
|
{
|
||||||
if (!faceAreasPtr_)
|
if (!faceAreasPtr_)
|
||||||
{
|
{
|
||||||
calcFaceCentresAndAreas();
|
//calcFaceCentresAndAreas();
|
||||||
|
const_cast<primitiveMesh&>(*this).updateGeom();
|
||||||
}
|
}
|
||||||
|
|
||||||
return *faceAreasPtr_;
|
return *faceAreasPtr_;
|
||||||
|
|||||||
@ -104,7 +104,7 @@ public:
|
|||||||
// Constructors
|
// Constructors
|
||||||
|
|
||||||
//- Construct from an IOobject
|
//- Construct from an IOobject
|
||||||
explicit dynamicFvMesh(const IOobject& io);
|
explicit dynamicFvMesh(const IOobject& io); //, const bool doInit=true);
|
||||||
|
|
||||||
//- Construct from components without boundary.
|
//- Construct from components without boundary.
|
||||||
// Boundary is added using addFvPatches() member function
|
// Boundary is added using addFvPatches() member function
|
||||||
@ -139,7 +139,11 @@ public:
|
|||||||
//- Select, construct and return the dynamicFvMesh
|
//- Select, construct and return the dynamicFvMesh
|
||||||
// If the constant/dynamicMeshDict does not exist
|
// If the constant/dynamicMeshDict does not exist
|
||||||
// a staticFvMesh is returned
|
// a staticFvMesh is returned
|
||||||
static autoPtr<dynamicFvMesh> New(const IOobject& io);
|
static autoPtr<dynamicFvMesh> New
|
||||||
|
(
|
||||||
|
const IOobject& io //,
|
||||||
|
//const bool doInit=true
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
//- Select, construct and return the dynamicFvMesh
|
//- Select, construct and return the dynamicFvMesh
|
||||||
@ -148,7 +152,8 @@ public:
|
|||||||
static autoPtr<dynamicFvMesh> New
|
static autoPtr<dynamicFvMesh> New
|
||||||
(
|
(
|
||||||
const argList& args,
|
const argList& args,
|
||||||
const Time& runTime
|
const Time& runTime //,
|
||||||
|
//const bool doInit=true
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
@ -158,6 +163,9 @@ public:
|
|||||||
|
|
||||||
// Member Functions
|
// Member Functions
|
||||||
|
|
||||||
|
//- Initialise all non-demand-driven data
|
||||||
|
//virtual bool init(const bool doInit);
|
||||||
|
|
||||||
//- Is mesh dynamic
|
//- Is mesh dynamic
|
||||||
virtual bool dynamic() const
|
virtual bool dynamic() const
|
||||||
{
|
{
|
||||||
|
|||||||
@ -1,6 +1,9 @@
|
|||||||
Info<< "Create mesh for time = "
|
Info<< "Create mesh for time = "
|
||||||
<< runTime.timeName() << nl << endl;
|
<< runTime.timeName() << nl << endl;
|
||||||
|
|
||||||
autoPtr<dynamicFvMesh> meshPtr(dynamicFvMesh::New(args, runTime));
|
autoPtr<dynamicFvMesh> meshPtr(dynamicFvMesh::New(args, runTime));//, false));
|
||||||
|
|
||||||
dynamicFvMesh& mesh = meshPtr();
|
dynamicFvMesh& mesh = meshPtr();
|
||||||
|
|
||||||
|
// initialise all (lower levels and current)
|
||||||
|
mesh.init(true);
|
||||||
|
|||||||
@ -268,7 +268,7 @@ void Foam::fvMeshSubset::removeCellsImpl
|
|||||||
baseMesh().name(),
|
baseMesh().name(),
|
||||||
baseMesh().time().timeName(),
|
baseMesh().time().timeName(),
|
||||||
baseMesh().time(),
|
baseMesh().time(),
|
||||||
IOobject::NO_READ,
|
IOobject::READ_IF_PRESENT, // read fv* if present
|
||||||
IOobject::NO_WRITE
|
IOobject::NO_WRITE
|
||||||
),
|
),
|
||||||
baseMesh(),
|
baseMesh(),
|
||||||
@ -980,9 +980,10 @@ void Foam::fvMeshSubset::setCellSubset
|
|||||||
baseMesh().name(),
|
baseMesh().name(),
|
||||||
baseMesh().time().timeName(),
|
baseMesh().time().timeName(),
|
||||||
baseMesh().time(),
|
baseMesh().time(),
|
||||||
IOobject::NO_READ,
|
IOobject::NO_READ, // do not read any dictionaries
|
||||||
IOobject::NO_WRITE
|
IOobject::NO_WRITE
|
||||||
),
|
),
|
||||||
|
baseMesh(), // get dictionaries from base mesh
|
||||||
std::move(newPoints),
|
std::move(newPoints),
|
||||||
std::move(newFaces),
|
std::move(newFaces),
|
||||||
std::move(newCells),
|
std::move(newCells),
|
||||||
|
|||||||
@ -79,7 +79,7 @@ Foam::autoPtr<Foam::fvMesh> Foam::polyMeshFilter::copyMesh(const fvMesh& mesh)
|
|||||||
mesh.name(),
|
mesh.name(),
|
||||||
mesh.polyMesh::instance(),
|
mesh.polyMesh::instance(),
|
||||||
mesh.time(),
|
mesh.time(),
|
||||||
IOobject::NO_READ,
|
IOobject::READ_IF_PRESENT, // read fv* if present
|
||||||
IOobject::NO_WRITE,
|
IOobject::NO_WRITE,
|
||||||
false
|
false
|
||||||
),
|
),
|
||||||
|
|||||||
@ -1,6 +1,17 @@
|
|||||||
fvMesh/fvMeshGeometry.C
|
fvMesh/fvMeshGeometry.C
|
||||||
fvMesh/fvMesh.C
|
fvMesh/fvMesh.C
|
||||||
|
|
||||||
|
fvGeometryScheme = fvMesh/fvGeometryScheme
|
||||||
|
$(fvGeometryScheme)/fvGeometryScheme/fvGeometryScheme.C
|
||||||
|
$(fvGeometryScheme)/basic/basicFvGeometryScheme.C
|
||||||
|
$(fvGeometryScheme)/highAspectRatio/highAspectRatioFvGeometryScheme.C
|
||||||
|
$(fvGeometryScheme)/highAspectRatio/cellAspectRatio.C
|
||||||
|
$(fvGeometryScheme)/averageNeighbour/averageNeighbourFvGeometryScheme.C
|
||||||
|
$(fvGeometryScheme)/stabilised/stabilisedFvGeometryScheme.C
|
||||||
|
|
||||||
|
surfaceInterpolation = interpolation/surfaceInterpolation
|
||||||
|
$(surfaceInterpolation)/surfaceInterpolation/surfaceInterpolation.C
|
||||||
|
|
||||||
fvMesh/singleCellFvMesh/singleCellFvMesh.C
|
fvMesh/singleCellFvMesh/singleCellFvMesh.C
|
||||||
|
|
||||||
fvMesh/simplifiedFvMesh/simplifiedFvMesh/simplifiedFvMesh.C
|
fvMesh/simplifiedFvMesh/simplifiedFvMesh/simplifiedFvMesh.C
|
||||||
@ -53,7 +64,6 @@ fvMeshMapper = fvMesh/fvMeshMapper
|
|||||||
$(fvMeshMapper)/fvPatchMapper.C
|
$(fvMeshMapper)/fvPatchMapper.C
|
||||||
$(fvMeshMapper)/fvSurfaceMapper.C
|
$(fvMeshMapper)/fvSurfaceMapper.C
|
||||||
|
|
||||||
|
|
||||||
extendedStencil = fvMesh/extendedStencil
|
extendedStencil = fvMesh/extendedStencil
|
||||||
|
|
||||||
cellToCell = $(extendedStencil)/cellToCell
|
cellToCell = $(extendedStencil)/cellToCell
|
||||||
@ -316,8 +326,6 @@ volPointInterpolation = interpolation/volPointInterpolation
|
|||||||
$(volPointInterpolation)/volPointInterpolation.C
|
$(volPointInterpolation)/volPointInterpolation.C
|
||||||
$(volPointInterpolation)/pointConstraints.C
|
$(volPointInterpolation)/pointConstraints.C
|
||||||
|
|
||||||
surfaceInterpolation = interpolation/surfaceInterpolation
|
|
||||||
$(surfaceInterpolation)/surfaceInterpolation/surfaceInterpolation.C
|
|
||||||
$(surfaceInterpolation)/surfaceInterpolationScheme/surfaceInterpolationSchemes.C
|
$(surfaceInterpolation)/surfaceInterpolationScheme/surfaceInterpolationSchemes.C
|
||||||
|
|
||||||
$(surfaceInterpolation)/blendedSchemeBase/blendedSchemeBaseName.C
|
$(surfaceInterpolation)/blendedSchemeBase/blendedSchemeBaseName.C
|
||||||
|
|||||||
@ -6,7 +6,7 @@
|
|||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Copyright (C) 2011-2015 OpenFOAM Foundation
|
Copyright (C) 2011-2015 OpenFOAM Foundation
|
||||||
Copyright (C) 2019 OpenCFD Ltd.
|
Copyright (C) 2019-2020 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM.
|
This file is part of OpenFOAM.
|
||||||
@ -327,6 +327,140 @@ Foam::fvSchemes::fvSchemes(const objectRegistry& obr)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::fvSchemes::fvSchemes(const objectRegistry& obr, const dictionary& dict)
|
||||||
|
:
|
||||||
|
IOdictionary
|
||||||
|
(
|
||||||
|
IOobject
|
||||||
|
(
|
||||||
|
"fvSchemes",
|
||||||
|
obr.time().system(),
|
||||||
|
obr,
|
||||||
|
(
|
||||||
|
obr.readOpt() == IOobject::MUST_READ
|
||||||
|
|| obr.readOpt() == IOobject::READ_IF_PRESENT
|
||||||
|
? IOobject::MUST_READ_IF_MODIFIED
|
||||||
|
: obr.readOpt()
|
||||||
|
),
|
||||||
|
IOobject::NO_WRITE
|
||||||
|
),
|
||||||
|
dict
|
||||||
|
),
|
||||||
|
ddtSchemes_
|
||||||
|
(
|
||||||
|
ITstream
|
||||||
|
(
|
||||||
|
objectPath() + ".ddtSchemes",
|
||||||
|
tokenList()
|
||||||
|
)()
|
||||||
|
),
|
||||||
|
defaultDdtScheme_
|
||||||
|
(
|
||||||
|
ddtSchemes_.name() + ".default",
|
||||||
|
tokenList()
|
||||||
|
),
|
||||||
|
d2dt2Schemes_
|
||||||
|
(
|
||||||
|
ITstream
|
||||||
|
(
|
||||||
|
objectPath() + ".d2dt2Schemes",
|
||||||
|
tokenList()
|
||||||
|
)()
|
||||||
|
),
|
||||||
|
defaultD2dt2Scheme_
|
||||||
|
(
|
||||||
|
d2dt2Schemes_.name() + ".default",
|
||||||
|
tokenList()
|
||||||
|
),
|
||||||
|
interpolationSchemes_
|
||||||
|
(
|
||||||
|
ITstream
|
||||||
|
(
|
||||||
|
objectPath() + ".interpolationSchemes",
|
||||||
|
tokenList()
|
||||||
|
)()
|
||||||
|
),
|
||||||
|
defaultInterpolationScheme_
|
||||||
|
(
|
||||||
|
interpolationSchemes_.name() + ".default",
|
||||||
|
tokenList()
|
||||||
|
),
|
||||||
|
divSchemes_
|
||||||
|
(
|
||||||
|
ITstream
|
||||||
|
(
|
||||||
|
objectPath() + ".divSchemes",
|
||||||
|
tokenList()
|
||||||
|
)()
|
||||||
|
),
|
||||||
|
defaultDivScheme_
|
||||||
|
(
|
||||||
|
divSchemes_.name() + ".default",
|
||||||
|
tokenList()
|
||||||
|
),
|
||||||
|
gradSchemes_
|
||||||
|
(
|
||||||
|
ITstream
|
||||||
|
(
|
||||||
|
objectPath() + ".gradSchemes",
|
||||||
|
tokenList()
|
||||||
|
)()
|
||||||
|
),
|
||||||
|
defaultGradScheme_
|
||||||
|
(
|
||||||
|
gradSchemes_.name() + ".default",
|
||||||
|
tokenList()
|
||||||
|
),
|
||||||
|
snGradSchemes_
|
||||||
|
(
|
||||||
|
ITstream
|
||||||
|
(
|
||||||
|
objectPath() + ".snGradSchemes",
|
||||||
|
tokenList()
|
||||||
|
)()
|
||||||
|
),
|
||||||
|
defaultSnGradScheme_
|
||||||
|
(
|
||||||
|
snGradSchemes_.name() + ".default",
|
||||||
|
tokenList()
|
||||||
|
),
|
||||||
|
laplacianSchemes_
|
||||||
|
(
|
||||||
|
ITstream
|
||||||
|
(
|
||||||
|
objectPath() + ".laplacianSchemes",
|
||||||
|
tokenList()
|
||||||
|
)()
|
||||||
|
),
|
||||||
|
defaultLaplacianScheme_
|
||||||
|
(
|
||||||
|
laplacianSchemes_.name() + ".default",
|
||||||
|
tokenList()
|
||||||
|
),
|
||||||
|
fluxRequired_
|
||||||
|
(
|
||||||
|
ITstream
|
||||||
|
(
|
||||||
|
objectPath() + ".fluxRequired",
|
||||||
|
tokenList()
|
||||||
|
)()
|
||||||
|
),
|
||||||
|
defaultFluxRequired_(false),
|
||||||
|
steady_(false)
|
||||||
|
{
|
||||||
|
if
|
||||||
|
(
|
||||||
|
readOpt() == IOobject::MUST_READ
|
||||||
|
|| readOpt() == IOobject::MUST_READ_IF_MODIFIED
|
||||||
|
|| (readOpt() == IOobject::READ_IF_PRESENT && headerOk())
|
||||||
|
)
|
||||||
|
{
|
||||||
|
read(schemesDict());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||||
|
|
||||||
bool Foam::fvSchemes::read()
|
bool Foam::fvSchemes::read()
|
||||||
|
|||||||
@ -6,6 +6,7 @@
|
|||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Copyright (C) 2011-2015 OpenFOAM Foundation
|
Copyright (C) 2011-2015 OpenFOAM Foundation
|
||||||
|
Copyright (C) 2020 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM.
|
This file is part of OpenFOAM.
|
||||||
@ -111,6 +112,11 @@ public:
|
|||||||
//- Construct for objectRegistry
|
//- Construct for objectRegistry
|
||||||
fvSchemes(const objectRegistry& obr);
|
fvSchemes(const objectRegistry& obr);
|
||||||
|
|
||||||
|
//- Construct from objectRegistry and supplied (optional) content
|
||||||
|
// (gets used in case of NO_READ or fvSchemes dictionary cannot be
|
||||||
|
// read)
|
||||||
|
fvSchemes(const objectRegistry& obr, const dictionary& dict);
|
||||||
|
|
||||||
|
|
||||||
// Member Functions
|
// Member Functions
|
||||||
|
|
||||||
|
|||||||
@ -6,6 +6,7 @@
|
|||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Copyright (C) 2011 OpenFOAM Foundation
|
Copyright (C) 2011 OpenFOAM Foundation
|
||||||
|
Copyright (C) 2020 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM.
|
This file is part of OpenFOAM.
|
||||||
@ -69,6 +70,12 @@ public:
|
|||||||
:
|
:
|
||||||
solution(obr, "fvSolution")
|
solution(obr, "fvSolution")
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
//- Construct for objectRegistry and optional contents
|
||||||
|
fvSolution(const objectRegistry& obr, const dictionary& dict)
|
||||||
|
:
|
||||||
|
solution(obr, "fvSolution", dict)
|
||||||
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -0,0 +1,880 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | www.openfoam.com
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
Copyright (C) 2020 OpenCFD Ltd.
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
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 "averageNeighbourFvGeometryScheme.H"
|
||||||
|
#include "addToRunTimeSelectionTable.H"
|
||||||
|
#include "fvMesh.H"
|
||||||
|
#include "cellAspectRatio.H"
|
||||||
|
#include "syncTools.H"
|
||||||
|
#include "polyMeshTools.H"
|
||||||
|
#include "unitConversion.H"
|
||||||
|
#include "OBJstream.H"
|
||||||
|
#include "surfaceWriter.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
defineTypeNameAndDebug(averageNeighbourFvGeometryScheme, 0);
|
||||||
|
addToRunTimeSelectionTable
|
||||||
|
(
|
||||||
|
fvGeometryScheme,
|
||||||
|
averageNeighbourFvGeometryScheme,
|
||||||
|
dict
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Foam::label Foam::averageNeighbourFvGeometryScheme::clipFaceTet
|
||||||
|
(
|
||||||
|
const scalar minRatio,
|
||||||
|
const vectorField& faceCentres,
|
||||||
|
const vectorField& faceNormals,
|
||||||
|
|
||||||
|
vectorField& faceCorrection
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
// Clip correction vector if any triangle becomes too small. Return number
|
||||||
|
// of correction vectors clipped
|
||||||
|
|
||||||
|
typedef Vector<solveScalar> solveVector;
|
||||||
|
|
||||||
|
const pointField& p = mesh_.points();
|
||||||
|
|
||||||
|
label nClipped = 0;
|
||||||
|
for (label facei = 0; facei < mesh_.nFaces(); facei++)
|
||||||
|
{
|
||||||
|
const vector& fcCorr = faceCorrection[facei];
|
||||||
|
if (fcCorr != vector::zero)
|
||||||
|
{
|
||||||
|
const vector& fn = faceNormals[facei];
|
||||||
|
const point& fc = faceCentres[facei];
|
||||||
|
const face& f = mesh_.faces()[facei];
|
||||||
|
|
||||||
|
forAll(f, fp)
|
||||||
|
{
|
||||||
|
const solveVector thisPt(p[f[fp]]);
|
||||||
|
const solveVector nextPt(p[f.fcValue(fp)]);
|
||||||
|
const solveVector d(nextPt-thisPt);
|
||||||
|
|
||||||
|
// Calculate triangle area with correction
|
||||||
|
const solveVector nCorr(d^(fc+fcCorr - thisPt));
|
||||||
|
|
||||||
|
if ((nCorr & fn) < 0)
|
||||||
|
{
|
||||||
|
// Triangle points wrong way
|
||||||
|
faceCorrection[facei] = vector::zero;
|
||||||
|
nClipped++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Calculate triangle area without correction
|
||||||
|
const solveVector n(d^(fc - thisPt));
|
||||||
|
if ((n & fn) < 0)
|
||||||
|
{
|
||||||
|
// Original triangle points the wrong way, new one is ok
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Both point correctly. Make sure triangle doesn't get
|
||||||
|
// too small
|
||||||
|
if (mag(nCorr) < minRatio*mag(n))
|
||||||
|
{
|
||||||
|
faceCorrection[facei] = vector::zero;
|
||||||
|
nClipped++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return returnReduce(nClipped, sumOp<label>());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::averageNeighbourFvGeometryScheme::makePyrHeights
|
||||||
|
(
|
||||||
|
const pointField& cellCentres,
|
||||||
|
const vectorField& faceCentres,
|
||||||
|
const vectorField& faceNormals,
|
||||||
|
|
||||||
|
scalarField& ownHeight,
|
||||||
|
scalarField& neiHeight
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
ownHeight.setSize(mesh_.nFaces());
|
||||||
|
neiHeight.setSize(mesh_.nInternalFaces());
|
||||||
|
|
||||||
|
typedef Vector<solveScalar> solveVector;
|
||||||
|
|
||||||
|
const labelList& own = mesh_.faceOwner();
|
||||||
|
const labelList& nei = mesh_.faceNeighbour();
|
||||||
|
|
||||||
|
for (label facei = 0; facei < mesh_.nInternalFaces(); facei++)
|
||||||
|
{
|
||||||
|
const solveVector n = faceNormals[facei];
|
||||||
|
const solveVector fc = faceCentres[facei];
|
||||||
|
ownHeight[facei] = ((fc-cellCentres[own[facei]])&n);
|
||||||
|
neiHeight[facei] = ((cellCentres[nei[facei]]-fc)&n);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (label facei = mesh_.nInternalFaces(); facei < mesh_.nFaces(); facei++)
|
||||||
|
{
|
||||||
|
const solveVector n = faceNormals[facei];
|
||||||
|
const solveVector fc = faceCentres[facei];
|
||||||
|
ownHeight[facei] = ((fc-cellCentres[own[facei]])&n);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::label Foam::averageNeighbourFvGeometryScheme::clipPyramids
|
||||||
|
(
|
||||||
|
const pointField& cellCentres,
|
||||||
|
const vectorField& faceCentres,
|
||||||
|
const vectorField& faceNormals,
|
||||||
|
|
||||||
|
const scalarField& minOwnHeight,
|
||||||
|
const scalarField& minNeiHeight,
|
||||||
|
|
||||||
|
vectorField& correction
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
// Clip correction vector if any pyramid becomes too small. Return number of
|
||||||
|
// cells clipped
|
||||||
|
|
||||||
|
typedef Vector<solveScalar> solveVector;
|
||||||
|
|
||||||
|
const labelList& own = mesh_.faceOwner();
|
||||||
|
const labelList& nei = mesh_.faceNeighbour();
|
||||||
|
|
||||||
|
label nClipped = 0;
|
||||||
|
for (label facei = 0; facei < mesh_.nInternalFaces(); facei++)
|
||||||
|
{
|
||||||
|
const vector& n = faceNormals[facei];
|
||||||
|
const point& fc = faceCentres[facei];
|
||||||
|
|
||||||
|
const label ownCelli = own[facei];
|
||||||
|
if (correction[ownCelli] != vector::zero)
|
||||||
|
{
|
||||||
|
const solveVector ownCc(cellCentres[ownCelli]+correction[ownCelli]);
|
||||||
|
const scalar ownHeight = ((fc-ownCc)&n);
|
||||||
|
if (ownHeight < minOwnHeight[facei])
|
||||||
|
{
|
||||||
|
//Pout<< " internalface:" << fc
|
||||||
|
// << " own:" << ownCc
|
||||||
|
// << " pyrHeight:" << ownHeight
|
||||||
|
// << " minHeight:" << minOwnHeight[facei]
|
||||||
|
// << endl;
|
||||||
|
correction[ownCelli] = vector::zero;
|
||||||
|
nClipped++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const label neiCelli = nei[facei];
|
||||||
|
if (correction[neiCelli] != vector::zero)
|
||||||
|
{
|
||||||
|
const solveVector neiCc(cellCentres[neiCelli]+correction[neiCelli]);
|
||||||
|
const scalar neiHeight = ((neiCc-fc)&n);
|
||||||
|
if (neiHeight < minNeiHeight[facei])
|
||||||
|
{
|
||||||
|
//Pout<< " internalface:" << fc
|
||||||
|
// << " nei:" << neiCc
|
||||||
|
// << " pyrHeight:" << neiHeight
|
||||||
|
// << " minHeight:" << minNeiHeight[facei]
|
||||||
|
// << endl;
|
||||||
|
correction[neiCelli] = vector::zero;
|
||||||
|
nClipped++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (label facei = mesh_.nInternalFaces(); facei < mesh_.nFaces(); facei++)
|
||||||
|
{
|
||||||
|
const vector& n = faceNormals[facei];
|
||||||
|
const point& fc = faceCentres[facei];
|
||||||
|
|
||||||
|
const label ownCelli = own[facei];
|
||||||
|
if (correction[ownCelli] != vector::zero)
|
||||||
|
{
|
||||||
|
const solveVector ownCc(cellCentres[ownCelli]+correction[ownCelli]);
|
||||||
|
const scalar ownHeight = ((fc-ownCc)&n);
|
||||||
|
if (ownHeight < minOwnHeight[facei])
|
||||||
|
{
|
||||||
|
//Pout<< " boundaryface:" << fc
|
||||||
|
// << " own:" << ownCc
|
||||||
|
// << " pyrHeight:" << ownHeight
|
||||||
|
// << " minHeight:" << minOwnHeight[facei]
|
||||||
|
// << endl;
|
||||||
|
correction[ownCelli] = vector::zero;
|
||||||
|
nClipped++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return returnReduce(nClipped, sumOp<label>());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::tmp<Foam::pointField>
|
||||||
|
Foam::averageNeighbourFvGeometryScheme::averageNeighbourCentres
|
||||||
|
(
|
||||||
|
const pointField& cellCentres,
|
||||||
|
const vectorField& faceNormals,
|
||||||
|
const scalarField& faceWeights
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
typedef Vector<solveScalar> solveVector;
|
||||||
|
|
||||||
|
const labelList& own = mesh_.faceOwner();
|
||||||
|
const labelList& nei = mesh_.faceNeighbour();
|
||||||
|
|
||||||
|
|
||||||
|
tmp<pointField> tcc(new pointField(mesh_.nCells(), Zero));
|
||||||
|
pointField& cc = tcc.ref();
|
||||||
|
|
||||||
|
Field<solveScalar> cellWeights(mesh_.nCells(), Zero);
|
||||||
|
|
||||||
|
// Internal faces
|
||||||
|
for (label facei = 0; facei < mesh_.nInternalFaces(); facei++)
|
||||||
|
{
|
||||||
|
const vector& n = faceNormals[facei];
|
||||||
|
const point& ownCc = cellCentres[own[facei]];
|
||||||
|
const point& neiCc = cellCentres[nei[facei]];
|
||||||
|
|
||||||
|
solveVector d(neiCc-ownCc);
|
||||||
|
|
||||||
|
// 1. Normalise contribution. This increases actual non-ortho
|
||||||
|
// since it does not 'see' the tangential offset of neighbours
|
||||||
|
//neiCc = ownCc + (d&n)*n;
|
||||||
|
|
||||||
|
// 2. Remove normal contribution, i.e. get tangential vector
|
||||||
|
// (= non-ortho correction vector?)
|
||||||
|
d -= (d&n)*n;
|
||||||
|
|
||||||
|
// Apply half to both sides (as a correction)
|
||||||
|
// Note: should this be linear weights instead of 0.5?
|
||||||
|
const scalar w = 0.5*faceWeights[facei];
|
||||||
|
cc[own[facei]] += w*d;
|
||||||
|
cellWeights[own[facei]] += w;
|
||||||
|
|
||||||
|
cc[nei[facei]] -= w*d;
|
||||||
|
cellWeights[nei[facei]] += w;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Boundary faces. Bypass stored cell centres
|
||||||
|
pointField neiCellCentres;
|
||||||
|
syncTools::swapBoundaryCellPositions(mesh_, cellCentres, neiCellCentres);
|
||||||
|
|
||||||
|
const polyBoundaryMesh& pbm = mesh_.boundaryMesh();
|
||||||
|
forAll(pbm, patchi)
|
||||||
|
{
|
||||||
|
const polyPatch& pp = pbm[patchi];
|
||||||
|
if (pp.coupled())
|
||||||
|
{
|
||||||
|
const labelUList& fc = pp.faceCells();
|
||||||
|
|
||||||
|
forAll(fc, i)
|
||||||
|
{
|
||||||
|
const label meshFacei = pp.start()+i;
|
||||||
|
const label bFacei = meshFacei-mesh_.nInternalFaces();
|
||||||
|
|
||||||
|
const vector& n = faceNormals[meshFacei];
|
||||||
|
|
||||||
|
const point& ownCc = cellCentres[fc[i]];
|
||||||
|
const point& neiCc = neiCellCentres[bFacei];
|
||||||
|
|
||||||
|
solveVector d(neiCc-ownCc);
|
||||||
|
|
||||||
|
// 1. Normalise contribution. This increases actual non-ortho
|
||||||
|
// since it does not 'see' the tangential offset of neighbours
|
||||||
|
//neiCc = ownCc + (d&n)*n;
|
||||||
|
|
||||||
|
// 2. Remove normal contribution, i.e. get tangential vector
|
||||||
|
// (= non-ortho correction vector?)
|
||||||
|
d -= (d&n)*n;
|
||||||
|
|
||||||
|
// Apply half to both sides (as a correction)
|
||||||
|
const scalar w = 0.5*faceWeights[meshFacei];
|
||||||
|
cc[fc[i]] += w*d;
|
||||||
|
cellWeights[fc[i]] += w;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now cc is still the correction vector. Add to cell original centres.
|
||||||
|
forAll(cc, celli)
|
||||||
|
{
|
||||||
|
if (cellWeights[celli] > VSMALL)
|
||||||
|
{
|
||||||
|
cc[celli] = cellCentres[celli] + cc[celli]/cellWeights[celli];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cc[celli] = cellCentres[celli];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return tcc;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::tmp<Foam::pointField>
|
||||||
|
Foam::averageNeighbourFvGeometryScheme::averageCentres
|
||||||
|
(
|
||||||
|
// const scalar ratio, // Amount of change in face-triangles area
|
||||||
|
const pointField& cellCentres,
|
||||||
|
const pointField& faceCentres,
|
||||||
|
const vectorField& faceNormals
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
typedef Vector<solveScalar> solveVector;
|
||||||
|
|
||||||
|
const labelList& own = mesh_.faceOwner();
|
||||||
|
const labelList& nei = mesh_.faceNeighbour();
|
||||||
|
|
||||||
|
|
||||||
|
tmp<pointField> tnewFc(new pointField(faceCentres));
|
||||||
|
pointField& newFc = tnewFc.ref();
|
||||||
|
|
||||||
|
// Internal faces
|
||||||
|
for (label facei = 0; facei < mesh_.nInternalFaces(); facei++)
|
||||||
|
{
|
||||||
|
const vector& n = faceNormals[facei];
|
||||||
|
const point& oldFc = faceCentres[facei];
|
||||||
|
|
||||||
|
const solveVector ownCc(cellCentres[own[facei]]);
|
||||||
|
const solveVector neiCc(cellCentres[nei[facei]]);
|
||||||
|
|
||||||
|
solveVector deltaCc(neiCc-ownCc);
|
||||||
|
solveVector deltaFc(oldFc-ownCc);
|
||||||
|
|
||||||
|
//solveVector d(neiCc-ownCc);
|
||||||
|
//// 1. Normalise contribution. This increases actual non-ortho
|
||||||
|
//// since it does not 'see' the tangential offset of neighbours
|
||||||
|
////neiCc = ownCc + s*n;
|
||||||
|
//
|
||||||
|
//// 2. Remove normal contribution, i.e. get tangential vector
|
||||||
|
//// (= non-ortho correction vector?)
|
||||||
|
//d -= s*n;
|
||||||
|
//newFc[facei] = faceCentres[facei]+d;
|
||||||
|
|
||||||
|
// Get linear weight (normal distance to face)
|
||||||
|
const solveScalar f = (deltaFc&n)/(deltaCc&n);
|
||||||
|
const solveVector avgCc((1.0-f)*ownCc + f*neiCc);
|
||||||
|
|
||||||
|
solveVector d(avgCc-oldFc);
|
||||||
|
// Remove normal contribution, i.e. get tangential vector
|
||||||
|
// (= non-ortho correction vector?)
|
||||||
|
d -= (d&n)*n;
|
||||||
|
|
||||||
|
// // Clip to limit change in
|
||||||
|
// d *= ratio;
|
||||||
|
|
||||||
|
|
||||||
|
newFc[facei] = oldFc + d;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Boundary faces. Bypass stored cell centres
|
||||||
|
pointField neiCellCentres;
|
||||||
|
syncTools::swapBoundaryCellPositions(mesh_, cellCentres, neiCellCentres);
|
||||||
|
|
||||||
|
const polyBoundaryMesh& pbm = mesh_.boundaryMesh();
|
||||||
|
forAll(pbm, patchi)
|
||||||
|
{
|
||||||
|
const polyPatch& pp = pbm[patchi];
|
||||||
|
const labelUList& fc = pp.faceCells();
|
||||||
|
|
||||||
|
if (pp.coupled())
|
||||||
|
{
|
||||||
|
forAll(fc, i)
|
||||||
|
{
|
||||||
|
// Same as internal faces
|
||||||
|
const label facei = pp.start()+i;
|
||||||
|
const label bFacei = facei-mesh_.nInternalFaces();
|
||||||
|
|
||||||
|
const vector& n = faceNormals[facei];
|
||||||
|
const point& oldFc = faceCentres[facei];
|
||||||
|
|
||||||
|
const solveVector ownCc(cellCentres[fc[i]]);
|
||||||
|
const solveVector neiCc(neiCellCentres[bFacei]);
|
||||||
|
|
||||||
|
solveVector deltaCc(neiCc-ownCc);
|
||||||
|
solveVector deltaFc(oldFc-ownCc);
|
||||||
|
|
||||||
|
// Get linear weight (normal distance to face)
|
||||||
|
const solveScalar f = (deltaFc&n)/(deltaCc&n);
|
||||||
|
const solveVector avgCc((1.0-f)*ownCc + f*neiCc);
|
||||||
|
|
||||||
|
solveVector d(avgCc-oldFc);
|
||||||
|
// Remove normal contribution, i.e. get tangential vector
|
||||||
|
// (= non-ortho correction vector?)
|
||||||
|
d -= (d&n)*n;
|
||||||
|
|
||||||
|
newFc[facei] = oldFc + d;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Zero-grad?
|
||||||
|
forAll(fc, i)
|
||||||
|
{
|
||||||
|
const label facei = pp.start()+i;
|
||||||
|
|
||||||
|
const vector& n = faceNormals[facei];
|
||||||
|
const point& oldFc = faceCentres[facei];
|
||||||
|
const solveVector ownCc(cellCentres[fc[i]]);
|
||||||
|
|
||||||
|
solveVector d(ownCc-oldFc);
|
||||||
|
// Remove normal contribution, i.e. get tangential vector
|
||||||
|
// (= non-ortho correction vector?)
|
||||||
|
d -= (d&n)*n;
|
||||||
|
|
||||||
|
newFc[facei] = oldFc+d;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return tnewFc;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::averageNeighbourFvGeometryScheme::makeNonOrthoWeights
|
||||||
|
(
|
||||||
|
const pointField& cellCentres,
|
||||||
|
const vectorField& faceNormals,
|
||||||
|
|
||||||
|
scalarField& cosAngles,
|
||||||
|
scalarField& faceWeights
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
cosAngles =
|
||||||
|
max
|
||||||
|
(
|
||||||
|
scalar(0),
|
||||||
|
min
|
||||||
|
(
|
||||||
|
scalar(1),
|
||||||
|
polyMeshTools::faceOrthogonality
|
||||||
|
(
|
||||||
|
mesh_,
|
||||||
|
faceNormals,
|
||||||
|
cellCentres
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
// Make weight: 0 for ortho faces, 1 for 90degrees non-ortho
|
||||||
|
//const scalarField faceWeights(scalar(1)-cosAngles);
|
||||||
|
faceWeights.setSize(cosAngles.size());
|
||||||
|
{
|
||||||
|
const scalar minCos = Foam::cos(degToRad(80));
|
||||||
|
const scalar maxCos = Foam::cos(degToRad(10));
|
||||||
|
|
||||||
|
forAll(cosAngles, facei)
|
||||||
|
{
|
||||||
|
const scalar cosAngle = cosAngles[facei];
|
||||||
|
if (cosAngle < minCos)
|
||||||
|
{
|
||||||
|
faceWeights[facei] = 1.0;
|
||||||
|
}
|
||||||
|
else if (cosAngle > maxCos)
|
||||||
|
{
|
||||||
|
faceWeights[facei] = 0.0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
faceWeights[facei] =
|
||||||
|
1.0-(cosAngle-minCos)/(maxCos-minCos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Foam::averageNeighbourFvGeometryScheme::averageNeighbourFvGeometryScheme
|
||||||
|
(
|
||||||
|
const fvMesh& mesh,
|
||||||
|
const dictionary& dict
|
||||||
|
)
|
||||||
|
:
|
||||||
|
highAspectRatioFvGeometryScheme(mesh, dict),
|
||||||
|
nIters_
|
||||||
|
(
|
||||||
|
dict.getCheckOrDefault<label>
|
||||||
|
(
|
||||||
|
"nIters",
|
||||||
|
1,
|
||||||
|
[&](const label& nIters)
|
||||||
|
{
|
||||||
|
return nIters >= 0;
|
||||||
|
}
|
||||||
|
)
|
||||||
|
),
|
||||||
|
relax_
|
||||||
|
(
|
||||||
|
dict.getCheck<scalar>
|
||||||
|
(
|
||||||
|
"relax",
|
||||||
|
[&](const scalar& relax)
|
||||||
|
{
|
||||||
|
return relax > 0 && relax <= 1;
|
||||||
|
}
|
||||||
|
)
|
||||||
|
),
|
||||||
|
minRatio_
|
||||||
|
(
|
||||||
|
dict.getCheckOrDefault<scalar>
|
||||||
|
(
|
||||||
|
"minRatio",
|
||||||
|
0.5,
|
||||||
|
[&](const scalar& minRatio)
|
||||||
|
{
|
||||||
|
return minRatio >= 0 && minRatio <= 1;
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (debug)
|
||||||
|
{
|
||||||
|
Pout<< "averageNeighbourFvGeometryScheme :"
|
||||||
|
<< " nIters:" << nIters_
|
||||||
|
<< " relax:" << relax_
|
||||||
|
<< " minRatio:" << minRatio_ << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Force local calculation
|
||||||
|
movePoints();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
void Foam::averageNeighbourFvGeometryScheme::movePoints()
|
||||||
|
{
|
||||||
|
if (debug)
|
||||||
|
{
|
||||||
|
Pout<< "averageNeighbourFvGeometryScheme::movePoints() : "
|
||||||
|
<< "recalculating primitiveMesh centres" << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
//if
|
||||||
|
//(
|
||||||
|
// !mesh_.hasCellCentres()
|
||||||
|
//&& !mesh_.hasFaceCentres()
|
||||||
|
//&& !mesh_.hasCellVolumes()
|
||||||
|
//&& !mesh_.hasFaceAreas()
|
||||||
|
//)
|
||||||
|
{
|
||||||
|
highAspectRatioFvGeometryScheme::movePoints();
|
||||||
|
|
||||||
|
// Note: at this point the highAspectRatioFvGeometryScheme constructor
|
||||||
|
// will have already reset the primitive geometry!
|
||||||
|
|
||||||
|
vectorField faceAreas(mesh_.faceAreas());
|
||||||
|
const scalarField magFaceAreas(mag(faceAreas));
|
||||||
|
const vectorField faceNormals(faceAreas/magFaceAreas);
|
||||||
|
|
||||||
|
|
||||||
|
// Calculate aspectratio weights
|
||||||
|
// - 0 if aratio < minAspect_
|
||||||
|
// - 1 if aratio >= maxAspect_
|
||||||
|
scalarField cellWeight, faceWeight;
|
||||||
|
calcAspectRatioWeights(cellWeight, faceWeight);
|
||||||
|
|
||||||
|
// Relaxation
|
||||||
|
cellWeight *= relax_;
|
||||||
|
//faceWeight *= relax_;
|
||||||
|
|
||||||
|
// Calculate current pyramid heights
|
||||||
|
scalarField minOwnHeight;
|
||||||
|
scalarField minNeiHeight;
|
||||||
|
makePyrHeights
|
||||||
|
(
|
||||||
|
mesh_.cellCentres(),
|
||||||
|
mesh_.faceCentres(),
|
||||||
|
faceNormals,
|
||||||
|
|
||||||
|
minOwnHeight,
|
||||||
|
minNeiHeight
|
||||||
|
);
|
||||||
|
|
||||||
|
// How much is the cell centre to vary inside the cell.
|
||||||
|
minOwnHeight *= minRatio_;
|
||||||
|
minNeiHeight *= minRatio_;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
autoPtr<OBJstream> osPtr;
|
||||||
|
autoPtr<surfaceWriter> writerPtr;
|
||||||
|
if (debug)
|
||||||
|
{
|
||||||
|
osPtr.set
|
||||||
|
(
|
||||||
|
new OBJstream
|
||||||
|
(
|
||||||
|
mesh_.time().timePath()
|
||||||
|
/ "cellCentre_correction.obj"
|
||||||
|
)
|
||||||
|
);
|
||||||
|
Pout<< "averageNeighbourFvGeometryScheme::movePoints() :"
|
||||||
|
<< " writing cell centre path to " << osPtr().name() << endl;
|
||||||
|
|
||||||
|
|
||||||
|
// Write current non-ortho
|
||||||
|
fileName outputDir =
|
||||||
|
(
|
||||||
|
mesh_.time().globalPath()
|
||||||
|
/ functionObject::outputPrefix
|
||||||
|
/ mesh_.pointsInstance()
|
||||||
|
);
|
||||||
|
outputDir.clean();
|
||||||
|
writerPtr = surfaceWriter::New
|
||||||
|
(
|
||||||
|
"ensight" //"vtk"
|
||||||
|
// options
|
||||||
|
);
|
||||||
|
|
||||||
|
// Use outputDir/TIME/surface-name
|
||||||
|
writerPtr->useTimeDir() = true;
|
||||||
|
|
||||||
|
writerPtr->beginTime(mesh_.time());
|
||||||
|
|
||||||
|
writerPtr->open
|
||||||
|
(
|
||||||
|
mesh_.points(),
|
||||||
|
mesh_.faces(),
|
||||||
|
(outputDir / "cosAngle"),
|
||||||
|
true // merge parallel bits
|
||||||
|
);
|
||||||
|
|
||||||
|
writerPtr->endTime();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Current cellCentres. These get adjusted to lower the
|
||||||
|
// non-orthogonality
|
||||||
|
pointField cellCentres(mesh_.cellCentres());
|
||||||
|
|
||||||
|
// Modify cell centres to be more in-line with the face normals
|
||||||
|
for (label iter = 0; iter < nIters_; iter++)
|
||||||
|
{
|
||||||
|
// Get neighbour average (weighted by face area). This gives
|
||||||
|
// preference to the dominant faces. However if the non-ortho
|
||||||
|
// is not caused by the dominant faces this moves to the wrong
|
||||||
|
// direction.
|
||||||
|
//tmp<pointField> tcc
|
||||||
|
//(
|
||||||
|
// averageNeighbourCentres
|
||||||
|
// (
|
||||||
|
// cellCentres,
|
||||||
|
// faceNormals,
|
||||||
|
// magFaceAreas
|
||||||
|
// )
|
||||||
|
//);
|
||||||
|
|
||||||
|
// Get neighbour average weighted by non-ortho. Question: how to
|
||||||
|
// weight boundary faces?
|
||||||
|
tmp<pointField> tcc;
|
||||||
|
{
|
||||||
|
scalarField cosAngles;
|
||||||
|
scalarField faceWeights;
|
||||||
|
makeNonOrthoWeights
|
||||||
|
(
|
||||||
|
cellCentres,
|
||||||
|
faceNormals,
|
||||||
|
|
||||||
|
cosAngles,
|
||||||
|
faceWeights
|
||||||
|
);
|
||||||
|
|
||||||
|
if (writerPtr.valid())
|
||||||
|
{
|
||||||
|
writerPtr->beginTime(instant(scalar(iter)));
|
||||||
|
writerPtr->write("cosAngles", cosAngles);
|
||||||
|
writerPtr->endTime();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (debug)
|
||||||
|
{
|
||||||
|
forAll(cosAngles, facei)
|
||||||
|
{
|
||||||
|
if (cosAngles[facei] < Foam::cos(degToRad(85.0)))
|
||||||
|
{
|
||||||
|
Pout<< " face:" << facei
|
||||||
|
<< " at:" << mesh_.faceCentres()[facei]
|
||||||
|
<< " cosAngle:" << cosAngles[facei]
|
||||||
|
<< " faceWeight:" << faceWeights[facei]
|
||||||
|
<< endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tcc = averageNeighbourCentres
|
||||||
|
(
|
||||||
|
cellCentres,
|
||||||
|
faceNormals,
|
||||||
|
faceWeights
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Calculate correction for cell centres. Leave low-aspect
|
||||||
|
// ratio cells unaffected (i.e. correction = 0)
|
||||||
|
vectorField correction(cellWeight*(tcc-cellCentres));
|
||||||
|
|
||||||
|
// Clip correction vector if pyramid becomes too small
|
||||||
|
const label nClipped = clipPyramids
|
||||||
|
(
|
||||||
|
cellCentres,
|
||||||
|
mesh_.faceCentres(),
|
||||||
|
faceNormals,
|
||||||
|
|
||||||
|
minOwnHeight, // minimum owner pyramid height. Usually fraction
|
||||||
|
minNeiHeight, // of starting mesh
|
||||||
|
|
||||||
|
correction
|
||||||
|
);
|
||||||
|
|
||||||
|
cellCentres += correction;
|
||||||
|
|
||||||
|
if (debug)
|
||||||
|
{
|
||||||
|
forAll(cellCentres, celli)
|
||||||
|
{
|
||||||
|
const point& cc = cellCentres[celli];
|
||||||
|
osPtr().write(linePointRef(cc-correction[celli], cc));
|
||||||
|
}
|
||||||
|
|
||||||
|
const scalarField magCorrection(mag(correction));
|
||||||
|
const scalarField faceOrthogonality
|
||||||
|
(
|
||||||
|
min
|
||||||
|
(
|
||||||
|
scalar(1),
|
||||||
|
polyMeshTools::faceOrthogonality
|
||||||
|
(
|
||||||
|
mesh_,
|
||||||
|
faceAreas,
|
||||||
|
cellCentres
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
const scalarField nonOrthoAngle
|
||||||
|
(
|
||||||
|
radToDeg
|
||||||
|
(
|
||||||
|
Foam::acos(faceOrthogonality)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
Pout<< " iter:" << iter
|
||||||
|
<< " nClipped:" << nClipped
|
||||||
|
<< " average displacement:" << gAverage(magCorrection)
|
||||||
|
<< " non-ortho angle : average:" << gAverage(nonOrthoAngle)
|
||||||
|
<< " max:" << gMax(nonOrthoAngle) << endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tmp<pointField> tfc
|
||||||
|
(
|
||||||
|
averageCentres
|
||||||
|
(
|
||||||
|
cellCentres,
|
||||||
|
mesh_.faceCentres(),
|
||||||
|
faceNormals
|
||||||
|
)
|
||||||
|
);
|
||||||
|
vectorField faceCorrection(faceWeight*(tfc-mesh_.faceCentres()));
|
||||||
|
// Clip correction vector to not have min triangle shrink
|
||||||
|
// by more than minRatio
|
||||||
|
clipFaceTet
|
||||||
|
(
|
||||||
|
minRatio_,
|
||||||
|
mesh_.faceCentres(),
|
||||||
|
faceNormals,
|
||||||
|
faceCorrection
|
||||||
|
);
|
||||||
|
vectorField faceCentres(mesh_.faceCentres() + faceCorrection);
|
||||||
|
|
||||||
|
if (debug)
|
||||||
|
{
|
||||||
|
Pout<< "averageNeighbourFvGeometryScheme::movePoints() :"
|
||||||
|
<< " averageNeighbour weight"
|
||||||
|
<< " max:" << gMax(cellWeight) << " min:" << gMin(cellWeight)
|
||||||
|
<< " average:" << gAverage(cellWeight) << endl;
|
||||||
|
|
||||||
|
// Dump lines from old to new location
|
||||||
|
const fileName tp(mesh_.time().timePath());
|
||||||
|
mkDir(tp);
|
||||||
|
OBJstream str(tp/"averageNeighbourCellCentres.obj");
|
||||||
|
Pout<< "Writing lines from old to new cell centre to " << str.name()
|
||||||
|
<< endl;
|
||||||
|
forAll(mesh_.cellCentres(), celli)
|
||||||
|
{
|
||||||
|
const point& oldCc = mesh_.cellCentres()[celli];
|
||||||
|
const point& newCc = cellCentres[celli];
|
||||||
|
str.write(linePointRef(oldCc, newCc));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (debug)
|
||||||
|
{
|
||||||
|
// Dump lines from old to new location
|
||||||
|
const fileName tp(mesh_.time().timePath());
|
||||||
|
OBJstream str(tp/"averageFaceCentres.obj");
|
||||||
|
Pout<< "Writing lines from old to new face centre to " << str.name()
|
||||||
|
<< endl;
|
||||||
|
forAll(mesh_.faceCentres(), facei)
|
||||||
|
{
|
||||||
|
const point& oldFc = mesh_.faceCentres()[facei];
|
||||||
|
const point& newFc = faceCentres[facei];
|
||||||
|
str.write(linePointRef(oldFc, newFc));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
scalarField cellVolumes(mesh_.cellVolumes());
|
||||||
|
|
||||||
|
// Store on primitiveMesh
|
||||||
|
//const_cast<fvMesh&>(mesh_).clearGeom();
|
||||||
|
const_cast<fvMesh&>(mesh_).primitiveMesh::resetGeometry
|
||||||
|
(
|
||||||
|
std::move(faceCentres),
|
||||||
|
std::move(faceAreas),
|
||||||
|
std::move(cellCentres),
|
||||||
|
std::move(cellVolumes)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -0,0 +1,178 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | www.openfoam.com
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
Copyright (C) 2020 OpenCFD Ltd.
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
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::averageNeighbourFvGeometryScheme
|
||||||
|
|
||||||
|
Description
|
||||||
|
Geometry calculation scheme to minimise non-orthogonality/
|
||||||
|
|
||||||
|
SourceFiles
|
||||||
|
averageNeighbourFvGeometryScheme.C
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef averageNeighbourFvGeometryScheme_H
|
||||||
|
#define averageNeighbourFvGeometryScheme_H
|
||||||
|
|
||||||
|
#include "highAspectRatioFvGeometryScheme.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
|
||||||
|
class primitiveMesh;
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
Class averageNeighbourFvGeometryScheme Declaration
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
class averageNeighbourFvGeometryScheme
|
||||||
|
:
|
||||||
|
public highAspectRatioFvGeometryScheme
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
|
||||||
|
//- No copy construct
|
||||||
|
averageNeighbourFvGeometryScheme
|
||||||
|
(
|
||||||
|
const averageNeighbourFvGeometryScheme&
|
||||||
|
) = delete;
|
||||||
|
|
||||||
|
//- No copy assignment
|
||||||
|
void operator=(const averageNeighbourFvGeometryScheme&) = delete;
|
||||||
|
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
//- Number of averaging iterations
|
||||||
|
const label nIters_;
|
||||||
|
|
||||||
|
//- Blending between old-iteration cell centres and current average
|
||||||
|
const scalar relax_;
|
||||||
|
|
||||||
|
//- Clipping for pyramid heights - allowable shrinkage as fraction
|
||||||
|
// of original
|
||||||
|
const scalar minRatio_;
|
||||||
|
|
||||||
|
|
||||||
|
//- Clip face-centre correction vector if new triangle area
|
||||||
|
//- would get below min. Return number of clipped faces.
|
||||||
|
label clipFaceTet
|
||||||
|
(
|
||||||
|
const scalar minRatio,
|
||||||
|
const vectorField& faceCentres,
|
||||||
|
const vectorField& faceNormals,
|
||||||
|
vectorField& faceCorrection
|
||||||
|
) const;
|
||||||
|
|
||||||
|
//- Calculate pyramid heights
|
||||||
|
void makePyrHeights
|
||||||
|
(
|
||||||
|
const pointField& cellCentres,
|
||||||
|
const vectorField& faceCentres,
|
||||||
|
const vectorField& faceNormals,
|
||||||
|
|
||||||
|
scalarField& ownHeight,
|
||||||
|
scalarField& neiHeight
|
||||||
|
) const;
|
||||||
|
|
||||||
|
//- Clip correction vector if new pyramid height would get below min.
|
||||||
|
//- Return number of clipped cells.
|
||||||
|
label clipPyramids
|
||||||
|
(
|
||||||
|
const pointField& cellCentres,
|
||||||
|
const vectorField& faceCentres,
|
||||||
|
const vectorField& faceNormals,
|
||||||
|
|
||||||
|
const scalarField& minOwnHeight,
|
||||||
|
const scalarField& minNeiHeight,
|
||||||
|
|
||||||
|
vectorField& correction
|
||||||
|
) const;
|
||||||
|
|
||||||
|
//- Average neighbouring cell centres to minimise non-ortho
|
||||||
|
tmp<pointField> averageNeighbourCentres
|
||||||
|
(
|
||||||
|
const pointField& cellCentres,
|
||||||
|
const vectorField& faceNormals,
|
||||||
|
const scalarField& faceWeights
|
||||||
|
) const;
|
||||||
|
|
||||||
|
tmp<pointField> averageCentres
|
||||||
|
(
|
||||||
|
const pointField& cellCentres,
|
||||||
|
const pointField& faceCentres,
|
||||||
|
const vectorField& faceNormals
|
||||||
|
) const;
|
||||||
|
|
||||||
|
//- Make weights based on non-orthogonality
|
||||||
|
void makeNonOrthoWeights
|
||||||
|
(
|
||||||
|
const pointField& cellCentres,
|
||||||
|
const vectorField& faceNormals,
|
||||||
|
|
||||||
|
scalarField& cosAngles,
|
||||||
|
scalarField& faceWeights
|
||||||
|
) const;
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
//- Runtime type information
|
||||||
|
TypeName("averageNeighbour");
|
||||||
|
|
||||||
|
|
||||||
|
// Constructors
|
||||||
|
|
||||||
|
//- Construct from mesh
|
||||||
|
averageNeighbourFvGeometryScheme
|
||||||
|
(
|
||||||
|
const fvMesh& mesh,
|
||||||
|
const dictionary& dict
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
//- Destructor
|
||||||
|
virtual ~averageNeighbourFvGeometryScheme() = default;
|
||||||
|
|
||||||
|
|
||||||
|
// Member Functions
|
||||||
|
|
||||||
|
//- Do what is necessary if the mesh has moved
|
||||||
|
virtual void movePoints();
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
} // End namespace Foam
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -0,0 +1,388 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | www.openfoam.com
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
Copyright (C) 2020 OpenCFD Ltd.
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
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 "basicFvGeometryScheme.H"
|
||||||
|
#include "addToRunTimeSelectionTable.H"
|
||||||
|
#include "surfaceFields.H"
|
||||||
|
#include "volFields.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
defineTypeNameAndDebug(basicFvGeometryScheme, 0);
|
||||||
|
addToRunTimeSelectionTable(fvGeometryScheme, basicFvGeometryScheme, dict);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Foam::basicFvGeometryScheme::basicFvGeometryScheme
|
||||||
|
(
|
||||||
|
const fvMesh& mesh,
|
||||||
|
const dictionary& dict
|
||||||
|
)
|
||||||
|
:
|
||||||
|
fvGeometryScheme(mesh, dict)
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
void Foam::basicFvGeometryScheme::movePoints()
|
||||||
|
{
|
||||||
|
if (debug)
|
||||||
|
{
|
||||||
|
Pout<< "basicFvGeometryScheme::movePoints() : "
|
||||||
|
<< "recalculating primitiveMesh centres" << endl;
|
||||||
|
}
|
||||||
|
// Use lower level to calculate the geometry
|
||||||
|
const_cast<fvMesh&>(mesh_).primitiveMesh::updateGeom();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::tmp<Foam::surfaceScalarField> Foam::basicFvGeometryScheme::weights() const
|
||||||
|
{
|
||||||
|
if (debug)
|
||||||
|
{
|
||||||
|
Pout<< "basicFvGeometryScheme::weights() : "
|
||||||
|
<< "Constructing weighting factors for face interpolation"
|
||||||
|
<< endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
tmp<surfaceScalarField> tweights
|
||||||
|
(
|
||||||
|
new surfaceScalarField
|
||||||
|
(
|
||||||
|
IOobject
|
||||||
|
(
|
||||||
|
"weights",
|
||||||
|
mesh_.pointsInstance(),
|
||||||
|
mesh_,
|
||||||
|
IOobject::NO_READ,
|
||||||
|
IOobject::NO_WRITE,
|
||||||
|
false // Do not register
|
||||||
|
),
|
||||||
|
mesh_,
|
||||||
|
dimless
|
||||||
|
)
|
||||||
|
);
|
||||||
|
surfaceScalarField& weights = tweights.ref();
|
||||||
|
weights.setOriented();
|
||||||
|
|
||||||
|
// Set local references to mesh data
|
||||||
|
// Note that we should not use fvMesh sliced fields at this point yet
|
||||||
|
// since this causes a loop when generating weighting factors in
|
||||||
|
// coupledFvPatchField evaluation phase
|
||||||
|
const labelUList& owner = mesh_.owner();
|
||||||
|
const labelUList& neighbour = mesh_.neighbour();
|
||||||
|
|
||||||
|
const vectorField& Cf = mesh_.faceCentres();
|
||||||
|
const vectorField& C = mesh_.cellCentres();
|
||||||
|
const vectorField& Sf = mesh_.faceAreas();
|
||||||
|
|
||||||
|
// ... and reference to the internal field of the weighting factors
|
||||||
|
scalarField& w = weights.primitiveFieldRef();
|
||||||
|
|
||||||
|
forAll(owner, facei)
|
||||||
|
{
|
||||||
|
// Note: mag in the dot-product.
|
||||||
|
// For all valid meshes, the non-orthogonality will be less than
|
||||||
|
// 90 deg and the dot-product will be positive. For invalid
|
||||||
|
// meshes (d & s <= 0), this will stabilise the calculation
|
||||||
|
// but the result will be poor.
|
||||||
|
scalar SfdOwn = mag(Sf[facei] & (Cf[facei] - C[owner[facei]]));
|
||||||
|
scalar SfdNei = mag(Sf[facei] & (C[neighbour[facei]] - Cf[facei]));
|
||||||
|
w[facei] = SfdNei/(SfdOwn + SfdNei);
|
||||||
|
}
|
||||||
|
|
||||||
|
surfaceScalarField::Boundary& wBf = weights.boundaryFieldRef();
|
||||||
|
|
||||||
|
forAll(mesh_.boundary(), patchi)
|
||||||
|
{
|
||||||
|
mesh_.boundary()[patchi].makeWeights(wBf[patchi]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (debug)
|
||||||
|
{
|
||||||
|
Pout<< "basicFvGeometryScheme::weights : "
|
||||||
|
<< "Finished constructing weighting factors for face interpolation"
|
||||||
|
<< endl;
|
||||||
|
}
|
||||||
|
return tweights;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::tmp<Foam::surfaceScalarField>
|
||||||
|
Foam::basicFvGeometryScheme::deltaCoeffs() const
|
||||||
|
{
|
||||||
|
if (debug)
|
||||||
|
{
|
||||||
|
Pout<< "basicFvGeometryScheme::deltaCoeffs() : "
|
||||||
|
<< "Constructing differencing factors array for face gradient"
|
||||||
|
<< endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Force the construction of the weighting factors
|
||||||
|
// needed to make sure deltaCoeffs are calculated for parallel runs.
|
||||||
|
(void)mesh_.weights();
|
||||||
|
|
||||||
|
tmp<surfaceScalarField> tdeltaCoeffs
|
||||||
|
(
|
||||||
|
new surfaceScalarField
|
||||||
|
(
|
||||||
|
IOobject
|
||||||
|
(
|
||||||
|
"deltaCoeffs",
|
||||||
|
mesh_.pointsInstance(),
|
||||||
|
mesh_,
|
||||||
|
IOobject::NO_READ,
|
||||||
|
IOobject::NO_WRITE,
|
||||||
|
false // Do not register
|
||||||
|
),
|
||||||
|
mesh_,
|
||||||
|
dimless/dimLength
|
||||||
|
)
|
||||||
|
);
|
||||||
|
surfaceScalarField& deltaCoeffs = tdeltaCoeffs.ref();
|
||||||
|
deltaCoeffs.setOriented();
|
||||||
|
|
||||||
|
|
||||||
|
// Set local references to mesh data
|
||||||
|
const volVectorField& C = mesh_.C();
|
||||||
|
const labelUList& owner = mesh_.owner();
|
||||||
|
const labelUList& neighbour = mesh_.neighbour();
|
||||||
|
|
||||||
|
forAll(owner, facei)
|
||||||
|
{
|
||||||
|
deltaCoeffs[facei] = 1.0/mag(C[neighbour[facei]] - C[owner[facei]]);
|
||||||
|
}
|
||||||
|
|
||||||
|
surfaceScalarField::Boundary& deltaCoeffsBf =
|
||||||
|
deltaCoeffs.boundaryFieldRef();
|
||||||
|
|
||||||
|
forAll(deltaCoeffsBf, patchi)
|
||||||
|
{
|
||||||
|
const fvPatch& p = mesh_.boundary()[patchi];
|
||||||
|
deltaCoeffsBf[patchi] = 1.0/mag(p.delta());
|
||||||
|
|
||||||
|
// Optionally correct
|
||||||
|
p.makeDeltaCoeffs(deltaCoeffsBf[patchi]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return tdeltaCoeffs;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::tmp<Foam::surfaceScalarField>
|
||||||
|
Foam::basicFvGeometryScheme::nonOrthDeltaCoeffs() const
|
||||||
|
{
|
||||||
|
if (debug)
|
||||||
|
{
|
||||||
|
Pout<< "basicFvGeometryScheme::nonOrthDeltaCoeffs() : "
|
||||||
|
<< "Constructing differencing factors array for face gradient"
|
||||||
|
<< endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Force the construction of the weighting factors
|
||||||
|
// needed to make sure deltaCoeffs are calculated for parallel runs.
|
||||||
|
weights();
|
||||||
|
|
||||||
|
tmp<surfaceScalarField> tnonOrthDeltaCoeffs
|
||||||
|
(
|
||||||
|
new surfaceScalarField
|
||||||
|
(
|
||||||
|
IOobject
|
||||||
|
(
|
||||||
|
"nonOrthDeltaCoeffs",
|
||||||
|
mesh_.pointsInstance(),
|
||||||
|
mesh_,
|
||||||
|
IOobject::NO_READ,
|
||||||
|
IOobject::NO_WRITE,
|
||||||
|
false // Do not register
|
||||||
|
),
|
||||||
|
mesh_,
|
||||||
|
dimless/dimLength
|
||||||
|
)
|
||||||
|
);
|
||||||
|
surfaceScalarField& nonOrthDeltaCoeffs = tnonOrthDeltaCoeffs.ref();
|
||||||
|
nonOrthDeltaCoeffs.setOriented();
|
||||||
|
|
||||||
|
|
||||||
|
// Set local references to mesh data
|
||||||
|
const volVectorField& C = mesh_.C();
|
||||||
|
const labelUList& owner = mesh_.owner();
|
||||||
|
const labelUList& neighbour = mesh_.neighbour();
|
||||||
|
const surfaceVectorField& Sf = mesh_.Sf();
|
||||||
|
const surfaceScalarField& magSf = mesh_.magSf();
|
||||||
|
|
||||||
|
forAll(owner, facei)
|
||||||
|
{
|
||||||
|
vector delta = C[neighbour[facei]] - C[owner[facei]];
|
||||||
|
vector unitArea = Sf[facei]/magSf[facei];
|
||||||
|
|
||||||
|
// Standard cell-centre distance form
|
||||||
|
//NonOrthDeltaCoeffs[facei] = (unitArea & delta)/magSqr(delta);
|
||||||
|
|
||||||
|
// Slightly under-relaxed form
|
||||||
|
//NonOrthDeltaCoeffs[facei] = 1.0/mag(delta);
|
||||||
|
|
||||||
|
// More under-relaxed form
|
||||||
|
//NonOrthDeltaCoeffs[facei] = 1.0/(mag(unitArea & delta) + VSMALL);
|
||||||
|
|
||||||
|
// Stabilised form for bad meshes
|
||||||
|
nonOrthDeltaCoeffs[facei] = 1.0/max(unitArea & delta, 0.05*mag(delta));
|
||||||
|
}
|
||||||
|
|
||||||
|
surfaceScalarField::Boundary& nonOrthDeltaCoeffsBf =
|
||||||
|
nonOrthDeltaCoeffs.boundaryFieldRef();
|
||||||
|
|
||||||
|
forAll(nonOrthDeltaCoeffsBf, patchi)
|
||||||
|
{
|
||||||
|
fvsPatchScalarField& patchDeltaCoeffs = nonOrthDeltaCoeffsBf[patchi];
|
||||||
|
|
||||||
|
const fvPatch& p = patchDeltaCoeffs.patch();
|
||||||
|
|
||||||
|
const vectorField patchDeltas(mesh_.boundary()[patchi].delta());
|
||||||
|
|
||||||
|
forAll(p, patchFacei)
|
||||||
|
{
|
||||||
|
vector unitArea =
|
||||||
|
Sf.boundaryField()[patchi][patchFacei]
|
||||||
|
/magSf.boundaryField()[patchi][patchFacei];
|
||||||
|
|
||||||
|
const vector& delta = patchDeltas[patchFacei];
|
||||||
|
|
||||||
|
patchDeltaCoeffs[patchFacei] =
|
||||||
|
1.0/max(unitArea & delta, 0.05*mag(delta));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Optionally correct
|
||||||
|
p.makeNonOrthoDeltaCoeffs(patchDeltaCoeffs);
|
||||||
|
}
|
||||||
|
return tnonOrthDeltaCoeffs;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::tmp<Foam::surfaceVectorField>
|
||||||
|
Foam::basicFvGeometryScheme::nonOrthCorrectionVectors() const
|
||||||
|
{
|
||||||
|
if (debug)
|
||||||
|
{
|
||||||
|
Pout<< "surfaceInterpolation::makeNonOrthCorrectionVectors() : "
|
||||||
|
<< "Constructing non-orthogonal correction vectors"
|
||||||
|
<< endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
tmp<surfaceVectorField> tnonOrthCorrectionVectors
|
||||||
|
(
|
||||||
|
new surfaceVectorField
|
||||||
|
(
|
||||||
|
IOobject
|
||||||
|
(
|
||||||
|
"nonOrthCorrectionVectors",
|
||||||
|
mesh_.pointsInstance(),
|
||||||
|
mesh_,
|
||||||
|
IOobject::NO_READ,
|
||||||
|
IOobject::NO_WRITE,
|
||||||
|
false // Do not register
|
||||||
|
),
|
||||||
|
mesh_,
|
||||||
|
dimless
|
||||||
|
)
|
||||||
|
);
|
||||||
|
surfaceVectorField& corrVecs = tnonOrthCorrectionVectors.ref();
|
||||||
|
corrVecs.setOriented();
|
||||||
|
|
||||||
|
// Set local references to mesh data
|
||||||
|
const volVectorField& C = mesh_.C();
|
||||||
|
const labelUList& owner = mesh_.owner();
|
||||||
|
const labelUList& neighbour = mesh_.neighbour();
|
||||||
|
const surfaceVectorField& Sf = mesh_.Sf();
|
||||||
|
const surfaceScalarField& magSf = mesh_.magSf();
|
||||||
|
tmp<surfaceScalarField> tNonOrthDeltaCoeffs(nonOrthDeltaCoeffs());
|
||||||
|
const surfaceScalarField& NonOrthDeltaCoeffs = tNonOrthDeltaCoeffs();
|
||||||
|
|
||||||
|
forAll(owner, facei)
|
||||||
|
{
|
||||||
|
vector unitArea = Sf[facei]/magSf[facei];
|
||||||
|
vector delta = C[neighbour[facei]] - C[owner[facei]];
|
||||||
|
|
||||||
|
corrVecs[facei] = unitArea - delta*NonOrthDeltaCoeffs[facei];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Boundary correction vectors set to zero for boundary patches
|
||||||
|
// and calculated consistently with internal corrections for
|
||||||
|
// coupled patches
|
||||||
|
|
||||||
|
surfaceVectorField::Boundary& corrVecsBf = corrVecs.boundaryFieldRef();
|
||||||
|
|
||||||
|
forAll(corrVecsBf, patchi)
|
||||||
|
{
|
||||||
|
fvsPatchVectorField& patchCorrVecs = corrVecsBf[patchi];
|
||||||
|
|
||||||
|
const fvPatch& p = patchCorrVecs.patch();
|
||||||
|
|
||||||
|
if (!patchCorrVecs.coupled())
|
||||||
|
{
|
||||||
|
patchCorrVecs = Zero;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
const fvsPatchScalarField& patchNonOrthDeltaCoeffs =
|
||||||
|
NonOrthDeltaCoeffs.boundaryField()[patchi];
|
||||||
|
|
||||||
|
const vectorField patchDeltas(mesh_.boundary()[patchi].delta());
|
||||||
|
|
||||||
|
forAll(p, patchFacei)
|
||||||
|
{
|
||||||
|
vector unitArea =
|
||||||
|
Sf.boundaryField()[patchi][patchFacei]
|
||||||
|
/magSf.boundaryField()[patchi][patchFacei];
|
||||||
|
|
||||||
|
const vector& delta = patchDeltas[patchFacei];
|
||||||
|
|
||||||
|
patchCorrVecs[patchFacei] =
|
||||||
|
unitArea - delta*patchNonOrthDeltaCoeffs[patchFacei];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Optionally correct
|
||||||
|
p.makeNonOrthoCorrVectors(patchCorrVecs);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (debug)
|
||||||
|
{
|
||||||
|
Pout<< "surfaceInterpolation::makeNonOrthCorrectionVectors() : "
|
||||||
|
<< "Finished constructing non-orthogonal correction vectors"
|
||||||
|
<< endl;
|
||||||
|
}
|
||||||
|
return tnonOrthCorrectionVectors;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -0,0 +1,107 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | www.openfoam.com
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
Copyright (C) 2020 OpenCFD Ltd.
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
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::basicFvGeometryScheme
|
||||||
|
|
||||||
|
Description
|
||||||
|
Default geometry calculation scheme. Slight stabilisation for bad meshes.
|
||||||
|
|
||||||
|
SourceFiles
|
||||||
|
basicFvGeometryScheme.C
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef basicFvGeometryScheme_H
|
||||||
|
#define basicFvGeometryScheme_H
|
||||||
|
|
||||||
|
#include "fvGeometryScheme.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
Class basicFvGeometryScheme Declaration
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
class basicFvGeometryScheme
|
||||||
|
:
|
||||||
|
public fvGeometryScheme
|
||||||
|
{
|
||||||
|
// Private Member Functions
|
||||||
|
|
||||||
|
//- No copy construct
|
||||||
|
basicFvGeometryScheme(const basicFvGeometryScheme&) = delete;
|
||||||
|
|
||||||
|
//- No copy assignment
|
||||||
|
void operator=(const basicFvGeometryScheme&) = delete;
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
//- Runtime type information
|
||||||
|
TypeName("basic");
|
||||||
|
|
||||||
|
|
||||||
|
// Constructors
|
||||||
|
|
||||||
|
//- Construct from mesh
|
||||||
|
basicFvGeometryScheme(const fvMesh& mesh, const dictionary& dict);
|
||||||
|
|
||||||
|
|
||||||
|
//- Destructor
|
||||||
|
virtual ~basicFvGeometryScheme() = default;
|
||||||
|
|
||||||
|
|
||||||
|
// Member Functions
|
||||||
|
|
||||||
|
//- Do what is necessary if the mesh has moved
|
||||||
|
virtual void movePoints();
|
||||||
|
|
||||||
|
//- Return linear difference weighting factors
|
||||||
|
virtual tmp<surfaceScalarField> weights() const;
|
||||||
|
|
||||||
|
//- Return cell-centre difference coefficients
|
||||||
|
virtual tmp<surfaceScalarField> deltaCoeffs() const;
|
||||||
|
|
||||||
|
//- Return non-orthogonal cell-centre difference coefficients
|
||||||
|
virtual tmp<surfaceScalarField> nonOrthDeltaCoeffs() const;
|
||||||
|
|
||||||
|
//- Return non-orthogonality correction vectors
|
||||||
|
virtual tmp<surfaceVectorField> nonOrthCorrectionVectors() const;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
} // End namespace Foam
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -0,0 +1,80 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | www.openfoam.com
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
Copyright (C) 2020 OpenCFD Ltd.
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
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 "fvGeometryScheme.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
defineTypeNameAndDebug(fvGeometryScheme, 0);
|
||||||
|
|
||||||
|
defineRunTimeSelectionTable(fvGeometryScheme, dict);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * Selectors * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Foam::tmp<Foam::fvGeometryScheme>
|
||||||
|
Foam::fvGeometryScheme::New
|
||||||
|
(
|
||||||
|
const fvMesh& mesh,
|
||||||
|
const dictionary& dict,
|
||||||
|
const word& defaultScheme
|
||||||
|
)
|
||||||
|
{
|
||||||
|
const entry* ePtr = dict.findEntry("method");
|
||||||
|
const word schemeName
|
||||||
|
(
|
||||||
|
ePtr
|
||||||
|
? word(ePtr->stream())
|
||||||
|
: dict.getOrDefault<word>("type", defaultScheme)
|
||||||
|
);
|
||||||
|
|
||||||
|
if (debug)
|
||||||
|
{
|
||||||
|
InfoInFunction << "Geometry scheme = " << schemeName << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto cstrIter = dictConstructorTablePtr_->cfind(schemeName);
|
||||||
|
|
||||||
|
if (!cstrIter.found())
|
||||||
|
{
|
||||||
|
FatalIOErrorInLookup
|
||||||
|
(
|
||||||
|
dict,
|
||||||
|
"fvGeometryScheme",
|
||||||
|
schemeName,
|
||||||
|
*dictConstructorTablePtr_
|
||||||
|
) << exit(FatalIOError);
|
||||||
|
}
|
||||||
|
|
||||||
|
return cstrIter()(mesh, dict);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -0,0 +1,164 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | www.openfoam.com
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
Copyright (C) 2020 OpenCFD Ltd.
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
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::fvGeometryScheme
|
||||||
|
|
||||||
|
Description
|
||||||
|
Abstract base class for geometry calculation schemes.
|
||||||
|
|
||||||
|
SourceFiles
|
||||||
|
fvGeometryScheme.C
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef fvGeometryScheme_H
|
||||||
|
#define fvGeometryScheme_H
|
||||||
|
|
||||||
|
#include "tmp.H"
|
||||||
|
#include "surfaceFieldsFwd.H"
|
||||||
|
#include "typeInfo.H"
|
||||||
|
#include "runTimeSelectionTables.H"
|
||||||
|
#include "pointField.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
|
||||||
|
class fvMesh;
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
Class fvGeometryScheme Declaration
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
class fvGeometryScheme
|
||||||
|
:
|
||||||
|
public refCount
|
||||||
|
{
|
||||||
|
// Private Member Functions
|
||||||
|
|
||||||
|
//- No copy construct
|
||||||
|
fvGeometryScheme(const fvGeometryScheme&) = delete;
|
||||||
|
|
||||||
|
//- No copy assignment
|
||||||
|
void operator=(const fvGeometryScheme&) = delete;
|
||||||
|
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
//- Hold reference to mesh
|
||||||
|
const fvMesh& mesh_;
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
//- Runtime type information
|
||||||
|
TypeName("fvGeometryScheme");
|
||||||
|
|
||||||
|
|
||||||
|
// Declare run-time constructor selection tables
|
||||||
|
|
||||||
|
declareRunTimeSelectionTable
|
||||||
|
(
|
||||||
|
tmp,
|
||||||
|
fvGeometryScheme,
|
||||||
|
dict,
|
||||||
|
(
|
||||||
|
const fvMesh& mesh,
|
||||||
|
const dictionary& dict
|
||||||
|
),
|
||||||
|
(mesh, dict)
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
// Constructors
|
||||||
|
|
||||||
|
//- Construct from mesh
|
||||||
|
fvGeometryScheme(const fvMesh& mesh, const dictionary& dict)
|
||||||
|
:
|
||||||
|
mesh_(mesh)
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
// Selectors
|
||||||
|
|
||||||
|
//- Return new tmp interpolation scheme
|
||||||
|
static tmp<fvGeometryScheme> New
|
||||||
|
(
|
||||||
|
const fvMesh& mesh,
|
||||||
|
const dictionary& dict,
|
||||||
|
const word& defaultScheme
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
//- Destructor
|
||||||
|
virtual ~fvGeometryScheme() = default;
|
||||||
|
|
||||||
|
|
||||||
|
// Member Functions
|
||||||
|
|
||||||
|
//- Return mesh reference
|
||||||
|
const fvMesh& mesh() const
|
||||||
|
{
|
||||||
|
return mesh_;
|
||||||
|
}
|
||||||
|
|
||||||
|
//- Update basic geometric properties from provided points
|
||||||
|
virtual void movePoints()
|
||||||
|
{}
|
||||||
|
|
||||||
|
//- Return linear difference weighting factors
|
||||||
|
virtual tmp<surfaceScalarField> weights() const = 0;
|
||||||
|
|
||||||
|
//- Return cell-centre difference coefficients
|
||||||
|
virtual tmp<surfaceScalarField> deltaCoeffs() const = 0;
|
||||||
|
|
||||||
|
//- Return non-orthogonal cell-centre difference coefficients
|
||||||
|
virtual tmp<surfaceScalarField> nonOrthDeltaCoeffs() const = 0;
|
||||||
|
|
||||||
|
//- Return non-orthogonality correction vectors
|
||||||
|
virtual tmp<surfaceVectorField> nonOrthCorrectionVectors() const = 0;
|
||||||
|
|
||||||
|
////- Selector for wall distance method. WIP. Ideally return wall
|
||||||
|
//// distance or meshObject?
|
||||||
|
//virtual autoPtr<patchDistMethod> newPatchDistMethod
|
||||||
|
//(
|
||||||
|
// const dictionary& dict,
|
||||||
|
// const labelHashSet& patchIDs,
|
||||||
|
// const word& defaultPatchDistMethod
|
||||||
|
//) const = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
} // End namespace Foam
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -0,0 +1,123 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | www.openfoam.com
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
Copyright (C) 2020 OpenCFD Ltd.
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
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 "cellAspectRatio.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
defineTypeNameAndDebug(cellAspectRatio, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Foam::cellAspectRatio::cellAspectRatio(const polyMesh& mesh)
|
||||||
|
:
|
||||||
|
MeshObject<polyMesh, Foam::MoveableMeshObject, cellAspectRatio>(mesh)
|
||||||
|
{
|
||||||
|
calcAspectRatio();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Foam::cellAspectRatio::~cellAspectRatio()
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
void Foam::cellAspectRatio::calcAspectRatio()
|
||||||
|
{
|
||||||
|
if (debug)
|
||||||
|
{
|
||||||
|
InfoInFunction << "Calculating cell aspect ratio" << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
const polyMesh& mesh = mesh_;
|
||||||
|
const pointField& cellCentres = mesh.cellCentres();
|
||||||
|
const scalarField& cellVolumes = mesh.cellVolumes();
|
||||||
|
const vectorField& faceAreas = mesh.faceAreas();
|
||||||
|
const vectorField& faceCentres = mesh.faceCentres();
|
||||||
|
const cellList& cells = mesh.cells();
|
||||||
|
//const faceList& faces = mesh.faces();
|
||||||
|
//const pointField& points = mesh.points();
|
||||||
|
|
||||||
|
scalarField& aRatio = *this;
|
||||||
|
aRatio.setSize(mesh.nCells());
|
||||||
|
|
||||||
|
forAll(cells, celli)
|
||||||
|
{
|
||||||
|
const point& cc = cellCentres[celli];
|
||||||
|
const cell& cFaces = cells[celli];
|
||||||
|
|
||||||
|
scalar sumA = Zero;
|
||||||
|
scalar maxMag = Zero;
|
||||||
|
|
||||||
|
for (const label facei : cFaces)
|
||||||
|
{
|
||||||
|
const vector& n = faceAreas[facei];
|
||||||
|
|
||||||
|
sumA += mag(n);
|
||||||
|
|
||||||
|
//// Max distance from point to cell centre
|
||||||
|
//const face& f = faces[facei];
|
||||||
|
//for (const label pointi : f)
|
||||||
|
//{
|
||||||
|
// const point& pt = points[pointi];
|
||||||
|
// const vector d(pt-cc);
|
||||||
|
// maxMag = max(maxMag, magSqr(d));
|
||||||
|
//}
|
||||||
|
|
||||||
|
// Max distance from face centre to cell centre
|
||||||
|
const point& fc = faceCentres[facei];
|
||||||
|
maxMag = max(maxMag, magSqr(fc-cc));
|
||||||
|
}
|
||||||
|
sumA /= cFaces.size();
|
||||||
|
|
||||||
|
// Local length scale
|
||||||
|
const scalar length = cellVolumes[celli]/sumA;
|
||||||
|
|
||||||
|
// Max edge length
|
||||||
|
maxMag = Foam::sqrt(maxMag);
|
||||||
|
|
||||||
|
//aRatio[celli] = Foam::sqrt(4.0/3.0)*maxMag/length;
|
||||||
|
aRatio[celli] = 2.0*maxMag/length;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (debug)
|
||||||
|
{
|
||||||
|
InfoInFunction << "Calculated cell aspect ratio min:" << gMin(aRatio)
|
||||||
|
<< " max:" << gMax(aRatio) << " average:" << gAverage(aRatio)
|
||||||
|
<< endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -0,0 +1,97 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | www.openfoam.com
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
Copyright (C) 2020 OpenCFD Ltd.
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
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::cellAspectRatio
|
||||||
|
|
||||||
|
Description
|
||||||
|
(Rough approximation of) cell aspect ratio
|
||||||
|
|
||||||
|
SourceFiles
|
||||||
|
cellAspectRatio.C
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef cellAspectRatio_H
|
||||||
|
#define cellAspectRatio_H
|
||||||
|
|
||||||
|
#include "MeshObject.H"
|
||||||
|
#include "polyMesh.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
Class cellAspectRatio Declaration
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
class cellAspectRatio
|
||||||
|
:
|
||||||
|
public MeshObject<polyMesh, MoveableMeshObject, cellAspectRatio>,
|
||||||
|
public scalarField
|
||||||
|
{
|
||||||
|
// Private Member Functions
|
||||||
|
|
||||||
|
//- Construct aspect ratio
|
||||||
|
void calcAspectRatio();
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
// Declare name of the class and its debug switch
|
||||||
|
TypeName("cellAspectRatio");
|
||||||
|
|
||||||
|
|
||||||
|
// Constructors
|
||||||
|
|
||||||
|
//- Construct given an polyMesh
|
||||||
|
explicit cellAspectRatio(const polyMesh&);
|
||||||
|
|
||||||
|
|
||||||
|
//- Destructor
|
||||||
|
virtual ~cellAspectRatio();
|
||||||
|
|
||||||
|
|
||||||
|
// Member functions
|
||||||
|
|
||||||
|
//- Ignore mesh motion for now
|
||||||
|
virtual bool movePoints()
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
} // End namespace Foam
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -0,0 +1,466 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | www.openfoam.com
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
Copyright (C) 2020 OpenCFD Ltd.
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
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 "highAspectRatioFvGeometryScheme.H"
|
||||||
|
#include "addToRunTimeSelectionTable.H"
|
||||||
|
#include "fvMesh.H"
|
||||||
|
#include "syncTools.H"
|
||||||
|
#include "cellAspectRatio.H"
|
||||||
|
#include "emptyPolyPatch.H"
|
||||||
|
#include "wedgePolyPatch.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
defineTypeNameAndDebug(highAspectRatioFvGeometryScheme, 0);
|
||||||
|
addToRunTimeSelectionTable
|
||||||
|
(
|
||||||
|
fvGeometryScheme,
|
||||||
|
highAspectRatioFvGeometryScheme,
|
||||||
|
dict
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||||
|
|
||||||
|
//void Foam::highAspectRatioFvGeometryScheme::cellClosedness
|
||||||
|
//(
|
||||||
|
// const vectorField& areas,
|
||||||
|
// const scalarField& vols,
|
||||||
|
// const tensorField& cellCoords,
|
||||||
|
//
|
||||||
|
// scalarField& aratio
|
||||||
|
//) const
|
||||||
|
//{
|
||||||
|
// // From primitiveMeshTools::cellClosedness:
|
||||||
|
// // calculate aspect ratio in given direction
|
||||||
|
// const labelList& own = mesh_.faceOwner();
|
||||||
|
// const labelList& nei = mesh_.faceNeighbour();
|
||||||
|
//
|
||||||
|
// // Loop through cell faces and sum up the face area vectors for each cell.
|
||||||
|
// // This should be zero in all vector components
|
||||||
|
//
|
||||||
|
// vectorField sumMagClosed(mesh_.nCells(), Zero);
|
||||||
|
//
|
||||||
|
// forAll(own, facei)
|
||||||
|
// {
|
||||||
|
// // Add to owner
|
||||||
|
// vector& v = sumMagClosed[own[facei]];
|
||||||
|
// v += cmptMag(cellCoords[own[facei]] & areas[facei]);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// forAll(nei, facei)
|
||||||
|
// {
|
||||||
|
// // Subtract from neighbour
|
||||||
|
// vector& v = sumMagClosed[nei[facei]];
|
||||||
|
// v += cmptMag(cellCoords[nei[facei]] & areas[facei]);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// // Check the sums
|
||||||
|
// aratio.setSize(mesh_.nCells());
|
||||||
|
//
|
||||||
|
// forAll(sumMagClosed, celli)
|
||||||
|
// {
|
||||||
|
// // Calculate the aspect ration as the maximum of Cartesian component
|
||||||
|
// // aspect ratio to the total area hydraulic area aspect ratio
|
||||||
|
// scalar minCmpt = VGREAT;
|
||||||
|
// scalar maxCmpt = -VGREAT;
|
||||||
|
// for (direction dir = 0; dir < vector::nComponents; dir++)
|
||||||
|
// {
|
||||||
|
// minCmpt = min(minCmpt, sumMagClosed[celli][dir]);
|
||||||
|
// maxCmpt = max(maxCmpt, sumMagClosed[celli][dir]);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// scalar aspectRatio = maxCmpt/(minCmpt + ROOTVSMALL);
|
||||||
|
// const scalar v = max(ROOTVSMALL, vols[celli]);
|
||||||
|
//
|
||||||
|
// aspectRatio = max
|
||||||
|
// (
|
||||||
|
// aspectRatio,
|
||||||
|
// 1.0/6.0*cmptSum(sumMagClosed[celli])/Foam::pow(v, 2.0/3.0)
|
||||||
|
// );
|
||||||
|
//
|
||||||
|
// aratio[celli] = aspectRatio;
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//void Foam::highAspectRatioFvGeometryScheme::cellDirections
|
||||||
|
//(
|
||||||
|
// tensorField& T,
|
||||||
|
// vectorField& lambda
|
||||||
|
//) const
|
||||||
|
//{
|
||||||
|
// // Calculate principal directions in increasing order
|
||||||
|
//
|
||||||
|
// T.setSize(mesh_.nCells());
|
||||||
|
// lambda.setSize(mesh_.nCells());
|
||||||
|
//
|
||||||
|
// forAll(T, celli)
|
||||||
|
// {
|
||||||
|
// tensor J = Zero;
|
||||||
|
// {
|
||||||
|
// const List<tetIndices> cellTets
|
||||||
|
// (
|
||||||
|
// polyMeshTetDecomposition::cellTetIndices
|
||||||
|
// (
|
||||||
|
// mesh_,
|
||||||
|
// celli
|
||||||
|
// )
|
||||||
|
// );
|
||||||
|
// triFaceList faces(cellTets.size());
|
||||||
|
// forAll(cellTets, cTI)
|
||||||
|
// {
|
||||||
|
// faces[cTI] = cellTets[cTI].faceTriIs(mesh_);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// scalar m = 0.0;
|
||||||
|
// vector cM = Zero;
|
||||||
|
// J = Zero;
|
||||||
|
// momentOfInertia::massPropertiesShell
|
||||||
|
// (
|
||||||
|
// mesh_.points(),
|
||||||
|
// faces,
|
||||||
|
// 1.0,
|
||||||
|
// m,
|
||||||
|
// cM,
|
||||||
|
// J
|
||||||
|
// );
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// lambda[celli] = Foam::eigenValues(J);
|
||||||
|
// T[celli] = Foam::eigenVectors(J, lambda[celli]);
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
|
||||||
|
void Foam::highAspectRatioFvGeometryScheme::calcAspectRatioWeights
|
||||||
|
(
|
||||||
|
scalarField& cellWeight,
|
||||||
|
scalarField& faceWeight
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
//scalarField aratio;
|
||||||
|
//{
|
||||||
|
// tensorField principalDirections;
|
||||||
|
// vectorField lambdas;
|
||||||
|
// cellDirections(principalDirections, lambdas);
|
||||||
|
//
|
||||||
|
// cellClosedness
|
||||||
|
// (
|
||||||
|
// mesh_.faceAreas(),
|
||||||
|
// mesh_.cellVolumes(),
|
||||||
|
// principalDirections,
|
||||||
|
// aratio
|
||||||
|
// );
|
||||||
|
//}
|
||||||
|
const cellAspectRatio aratio(mesh_);
|
||||||
|
|
||||||
|
// Weighting for correction
|
||||||
|
// - 0 if aratio < minAspect_
|
||||||
|
// - 1 if aratio >= maxAspect_
|
||||||
|
|
||||||
|
scalar delta(maxAspect_-minAspect_);
|
||||||
|
if (delta < ROOTVSMALL)
|
||||||
|
{
|
||||||
|
delta = SMALL;
|
||||||
|
}
|
||||||
|
|
||||||
|
cellWeight =
|
||||||
|
max
|
||||||
|
(
|
||||||
|
min
|
||||||
|
(
|
||||||
|
(aratio-minAspect_)/delta,
|
||||||
|
1.0
|
||||||
|
),
|
||||||
|
0.0
|
||||||
|
);
|
||||||
|
|
||||||
|
faceWeight.setSize(mesh_.nFaces());
|
||||||
|
|
||||||
|
for (label facei = 0; facei < mesh_.nInternalFaces(); facei++)
|
||||||
|
{
|
||||||
|
const label own = mesh_.faceOwner()[facei];
|
||||||
|
const label nei = mesh_.faceNeighbour()[facei];
|
||||||
|
faceWeight[facei] = max(cellWeight[own], cellWeight[nei]);
|
||||||
|
}
|
||||||
|
scalarField nbrCellWeight;
|
||||||
|
syncTools::swapBoundaryCellList
|
||||||
|
(
|
||||||
|
mesh_,
|
||||||
|
cellWeight,
|
||||||
|
nbrCellWeight
|
||||||
|
);
|
||||||
|
for
|
||||||
|
(
|
||||||
|
label facei = mesh_.nInternalFaces();
|
||||||
|
facei < mesh_.nFaces();
|
||||||
|
facei++
|
||||||
|
)
|
||||||
|
{
|
||||||
|
const label own = mesh_.faceOwner()[facei];
|
||||||
|
const label bFacei = facei-mesh_.nInternalFaces();
|
||||||
|
faceWeight[facei] = max(cellWeight[own], nbrCellWeight[bFacei]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::highAspectRatioFvGeometryScheme::makeAverageCentres
|
||||||
|
(
|
||||||
|
const polyMesh& mesh,
|
||||||
|
const pointField& p,
|
||||||
|
const pointField& faceAreas,
|
||||||
|
const scalarField& magFaceAreas,
|
||||||
|
pointField& faceCentres,
|
||||||
|
pointField& cellCentres
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (debug)
|
||||||
|
{
|
||||||
|
Pout<< "highAspectRatioFvGeometryScheme::makeAverageCentres() : "
|
||||||
|
<< "calculating weighted average face/cell centre" << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef Vector<solveScalar> solveVector;
|
||||||
|
|
||||||
|
const faceList& fs = mesh.faces();
|
||||||
|
|
||||||
|
// Start off from primitiveMesh faceCentres (preserved for triangles)
|
||||||
|
faceCentres.setSize(mesh.nFaces());
|
||||||
|
|
||||||
|
forAll(fs, facei)
|
||||||
|
{
|
||||||
|
const labelList& f = fs[facei];
|
||||||
|
const label nPoints = f.size();
|
||||||
|
|
||||||
|
if (nPoints == 3)
|
||||||
|
{
|
||||||
|
faceCentres[facei] = (1.0/3.0)*(p[f[0]] + p[f[1]] + p[f[2]]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
solveScalar sumA = 0.0;
|
||||||
|
solveVector sumAc = Zero;
|
||||||
|
|
||||||
|
for (label pi = 0; pi < nPoints; pi++)
|
||||||
|
{
|
||||||
|
const label nextPi(pi == nPoints-1 ? 0 : pi+1);
|
||||||
|
const solveVector nextPoint(p[f[nextPi]]);
|
||||||
|
const solveVector thisPoint(p[f[pi]]);
|
||||||
|
|
||||||
|
const solveVector eMid = 0.5*(thisPoint+nextPoint);
|
||||||
|
const solveScalar a = mag(nextPoint-thisPoint);
|
||||||
|
|
||||||
|
sumAc += a*eMid;
|
||||||
|
sumA += a;
|
||||||
|
}
|
||||||
|
// This is to deal with zero-area faces. Mark very small faces
|
||||||
|
// to be detected in e.g. processorPolyPatch.
|
||||||
|
if (sumA >= ROOTVSMALL)
|
||||||
|
{
|
||||||
|
faceCentres[facei] = sumAc/sumA;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Unweighted average of points
|
||||||
|
sumAc = Zero;
|
||||||
|
for (label pi = 0; pi < nPoints; pi++)
|
||||||
|
{
|
||||||
|
sumAc += p[f[pi]];
|
||||||
|
}
|
||||||
|
faceCentres[facei] = sumAc/nPoints;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
cellCentres.setSize(mesh.nCells());
|
||||||
|
cellCentres = Zero;
|
||||||
|
{
|
||||||
|
const labelList& own = mesh.faceOwner();
|
||||||
|
const labelList& nei = mesh.faceNeighbour();
|
||||||
|
|
||||||
|
Field<solveScalar> cellWeights(mesh.nCells(), Zero);
|
||||||
|
for (label facei = 0; facei < mesh.nInternalFaces(); facei++)
|
||||||
|
{
|
||||||
|
const solveScalar magfA(magFaceAreas[facei]);
|
||||||
|
const solveVector weightedFc(magfA*faceCentres[facei]);
|
||||||
|
|
||||||
|
// Accumulate area-weighted face-centre
|
||||||
|
cellCentres[own[facei]] += weightedFc;
|
||||||
|
cellCentres[nei[facei]] += weightedFc;
|
||||||
|
|
||||||
|
// Accumulate weights
|
||||||
|
cellWeights[own[facei]] += magfA;
|
||||||
|
cellWeights[nei[facei]] += magfA;
|
||||||
|
}
|
||||||
|
|
||||||
|
const polyBoundaryMesh& pbm = mesh.boundaryMesh();
|
||||||
|
for (const polyPatch& pp : pbm)
|
||||||
|
{
|
||||||
|
if (!isA<emptyPolyPatch>(pp) && !isA<wedgePolyPatch>(pp))
|
||||||
|
{
|
||||||
|
for
|
||||||
|
(
|
||||||
|
label facei = pp.start();
|
||||||
|
facei < pp.start()+pp.size();
|
||||||
|
facei++
|
||||||
|
)
|
||||||
|
{
|
||||||
|
const solveScalar magfA(magFaceAreas[facei]);
|
||||||
|
const solveVector weightedFc(magfA*faceCentres[facei]);
|
||||||
|
|
||||||
|
cellCentres[own[facei]] += weightedFc;
|
||||||
|
cellWeights[own[facei]] += magfA;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
forAll(cellCentres, celli)
|
||||||
|
{
|
||||||
|
if (mag(cellWeights[celli]) > VSMALL)
|
||||||
|
{
|
||||||
|
cellCentres[celli] /= cellWeights[celli];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Foam::highAspectRatioFvGeometryScheme::highAspectRatioFvGeometryScheme
|
||||||
|
(
|
||||||
|
const fvMesh& mesh,
|
||||||
|
const dictionary& dict
|
||||||
|
)
|
||||||
|
:
|
||||||
|
basicFvGeometryScheme(mesh, dict),
|
||||||
|
minAspect_(dict.get<scalar>("minAspect")),
|
||||||
|
maxAspect_(dict.get<scalar>("maxAspect"))
|
||||||
|
{
|
||||||
|
if (maxAspect_ < minAspect_)
|
||||||
|
{
|
||||||
|
FatalIOErrorInFunction(dict)
|
||||||
|
<< "minAspect " << minAspect_
|
||||||
|
<< " has to be less than maxAspect " << maxAspect_
|
||||||
|
<< exit(FatalIOError);
|
||||||
|
}
|
||||||
|
if (minAspect_ < 0 || maxAspect_ < 0)
|
||||||
|
{
|
||||||
|
FatalIOErrorInFunction(dict)
|
||||||
|
<< "Illegal aspect ratio : minAspect:" << minAspect_
|
||||||
|
<< " maxAspect:" << maxAspect_
|
||||||
|
<< exit(FatalIOError);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Force local calculation
|
||||||
|
movePoints();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
void Foam::highAspectRatioFvGeometryScheme::movePoints()
|
||||||
|
{
|
||||||
|
if (debug)
|
||||||
|
{
|
||||||
|
Pout<< "highAspectRatioFvGeometryScheme::movePoints() : "
|
||||||
|
<< "recalculating primitiveMesh centres" << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
if
|
||||||
|
(
|
||||||
|
!mesh_.hasCellCentres()
|
||||||
|
&& !mesh_.hasFaceCentres()
|
||||||
|
&& !mesh_.hasCellVolumes()
|
||||||
|
&& !mesh_.hasFaceAreas()
|
||||||
|
)
|
||||||
|
{
|
||||||
|
// Use lower level to calculate the geometry
|
||||||
|
const_cast<fvMesh&>(mesh_).primitiveMesh::updateGeom();
|
||||||
|
|
||||||
|
pointField avgFaceCentres;
|
||||||
|
pointField avgCellCentres;
|
||||||
|
makeAverageCentres
|
||||||
|
(
|
||||||
|
mesh_,
|
||||||
|
mesh_.points(),
|
||||||
|
mesh_.faceAreas(),
|
||||||
|
mag(mesh_.faceAreas()),
|
||||||
|
avgFaceCentres,
|
||||||
|
avgCellCentres
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
// Calculate aspectratio weights
|
||||||
|
// - 0 if aratio < minAspect_
|
||||||
|
// - 1 if aratio >= maxAspect_
|
||||||
|
scalarField cellWeight, faceWeight;
|
||||||
|
calcAspectRatioWeights(cellWeight, faceWeight);
|
||||||
|
|
||||||
|
|
||||||
|
// Weight with average ones
|
||||||
|
vectorField faceCentres
|
||||||
|
(
|
||||||
|
(1.0-faceWeight)*mesh_.faceCentres()
|
||||||
|
+ faceWeight*avgFaceCentres
|
||||||
|
);
|
||||||
|
vectorField cellCentres
|
||||||
|
(
|
||||||
|
(1.0-cellWeight)*mesh_.cellCentres()
|
||||||
|
+ cellWeight*avgCellCentres
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
if (debug)
|
||||||
|
{
|
||||||
|
Pout<< "highAspectRatioFvGeometryScheme::movePoints() :"
|
||||||
|
<< " highAspectRatio weight"
|
||||||
|
<< " max:" << gMax(cellWeight) << " min:" << gMin(cellWeight)
|
||||||
|
<< " average:" << gAverage(cellWeight) << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
vectorField faceAreas(mesh_.faceAreas());
|
||||||
|
scalarField cellVolumes(mesh_.cellVolumes());
|
||||||
|
|
||||||
|
// Store on primitiveMesh
|
||||||
|
//const_cast<fvMesh&>(mesh_).clearGeom();
|
||||||
|
const_cast<fvMesh&>(mesh_).primitiveMesh::resetGeometry
|
||||||
|
(
|
||||||
|
std::move(faceCentres),
|
||||||
|
std::move(faceAreas),
|
||||||
|
std::move(cellCentres),
|
||||||
|
std::move(cellVolumes)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -0,0 +1,137 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | www.openfoam.com
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
Copyright (C) 2020 OpenCFD Ltd.
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
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::highAspectRatioFvGeometryScheme
|
||||||
|
|
||||||
|
Description
|
||||||
|
Geometry calculation scheme with automatic stabilisation for high-aspect
|
||||||
|
ratio cells.
|
||||||
|
|
||||||
|
SourceFiles
|
||||||
|
highAspectRatioFvGeometryScheme.C
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef highAspectRatioFvGeometryScheme_H
|
||||||
|
#define highAspectRatioFvGeometryScheme_H
|
||||||
|
|
||||||
|
#include "basicFvGeometryScheme.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
|
||||||
|
class primitiveMesh;
|
||||||
|
class polyMesh;
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
Class highAspectRatioFvGeometryScheme Declaration
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
class highAspectRatioFvGeometryScheme
|
||||||
|
:
|
||||||
|
public basicFvGeometryScheme
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
|
||||||
|
const scalar minAspect_;
|
||||||
|
|
||||||
|
const scalar maxAspect_;
|
||||||
|
|
||||||
|
|
||||||
|
// Protected Member Functions
|
||||||
|
|
||||||
|
//- Calculate cell and face weight. Is 0 for cell < minAspect, 1 for
|
||||||
|
// cell > maxAspect
|
||||||
|
void calcAspectRatioWeights
|
||||||
|
(
|
||||||
|
scalarField& cellWeight,
|
||||||
|
scalarField& faceWeight
|
||||||
|
) const;
|
||||||
|
|
||||||
|
//- Helper : calculate (weighted) average face and cell centres
|
||||||
|
static void makeAverageCentres
|
||||||
|
(
|
||||||
|
const polyMesh& mesh,
|
||||||
|
const pointField& points,
|
||||||
|
const pointField& faceAreas,
|
||||||
|
const scalarField& magFaceAreas,
|
||||||
|
pointField& faceCentres,
|
||||||
|
pointField& cellCentres
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
// Private Member Functions
|
||||||
|
|
||||||
|
//- No copy construct
|
||||||
|
highAspectRatioFvGeometryScheme
|
||||||
|
(
|
||||||
|
const highAspectRatioFvGeometryScheme&
|
||||||
|
) = delete;
|
||||||
|
|
||||||
|
//- No copy assignment
|
||||||
|
void operator=(const highAspectRatioFvGeometryScheme&) = delete;
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
//- Runtime type information
|
||||||
|
TypeName("highAspectRatio");
|
||||||
|
|
||||||
|
|
||||||
|
// Constructors
|
||||||
|
|
||||||
|
//- Construct from mesh
|
||||||
|
highAspectRatioFvGeometryScheme
|
||||||
|
(
|
||||||
|
const fvMesh& mesh,
|
||||||
|
const dictionary& dict
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
//- Destructor
|
||||||
|
virtual ~highAspectRatioFvGeometryScheme() = default;
|
||||||
|
|
||||||
|
|
||||||
|
// Member Functions
|
||||||
|
|
||||||
|
//- Do what is necessary if the mesh has moved
|
||||||
|
virtual void movePoints();
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
} // End namespace Foam
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -0,0 +1,210 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | www.openfoam.com
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
Copyright (C) 2020 OpenFOAM Foundation
|
||||||
|
Copyright (C) 2020 OpenCFD Ltd.
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
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 "stabilisedFvGeometryScheme.H"
|
||||||
|
#include "addToRunTimeSelectionTable.H"
|
||||||
|
#include "fvMesh.H"
|
||||||
|
#include "PrecisionAdaptor.H"
|
||||||
|
#include "primitiveMeshTools.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
defineTypeNameAndDebug(stabilisedFvGeometryScheme, 0);
|
||||||
|
addToRunTimeSelectionTable
|
||||||
|
(
|
||||||
|
fvGeometryScheme,
|
||||||
|
stabilisedFvGeometryScheme,
|
||||||
|
dict
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||||
|
|
||||||
|
void Foam::stabilisedFvGeometryScheme::makeFaceCentresAndAreas
|
||||||
|
(
|
||||||
|
const polyMesh& mesh,
|
||||||
|
const pointField& p,
|
||||||
|
vectorField& fCtrs,
|
||||||
|
vectorField& fAreas
|
||||||
|
)
|
||||||
|
{
|
||||||
|
const faceList& fs = mesh.faces();
|
||||||
|
|
||||||
|
forAll(fs, facei)
|
||||||
|
{
|
||||||
|
const labelList& f = fs[facei];
|
||||||
|
label nPoints = f.size();
|
||||||
|
|
||||||
|
// If the face is a triangle, do a direct calculation for efficiency
|
||||||
|
// and to avoid round-off error-related problems
|
||||||
|
if (nPoints == 3)
|
||||||
|
{
|
||||||
|
fCtrs[facei] = (1.0/3.0)*(p[f[0]] + p[f[1]] + p[f[2]]);
|
||||||
|
fAreas[facei] = 0.5*((p[f[1]] - p[f[0]])^(p[f[2]] - p[f[0]]));
|
||||||
|
}
|
||||||
|
|
||||||
|
// For more complex faces, decompose into triangles
|
||||||
|
else
|
||||||
|
{
|
||||||
|
typedef Vector<solveScalar> solveVector;
|
||||||
|
|
||||||
|
// Compute an estimate of the centre as the average of the points
|
||||||
|
solveVector fCentre = p[f[0]];
|
||||||
|
for (label pi = 1; pi < nPoints; pi++)
|
||||||
|
{
|
||||||
|
fCentre += solveVector(p[f[pi]]);
|
||||||
|
}
|
||||||
|
fCentre /= nPoints;
|
||||||
|
|
||||||
|
// Compute the face area normal and unit normal by summing up the
|
||||||
|
// normals of the triangles formed by connecting each edge to the
|
||||||
|
// point average.
|
||||||
|
solveVector sumA = Zero;
|
||||||
|
for (label pi = 0; pi < nPoints; pi++)
|
||||||
|
{
|
||||||
|
const label nextPi(pi == nPoints-1 ? 0 : pi+1);
|
||||||
|
const solveVector nextPoint(p[f[nextPi]]);
|
||||||
|
const solveVector thisPoint(p[f[pi]]);
|
||||||
|
|
||||||
|
const solveVector a =
|
||||||
|
(nextPoint - thisPoint)^(fCentre - thisPoint);
|
||||||
|
|
||||||
|
sumA += a;
|
||||||
|
}
|
||||||
|
const solveVector sumAHat = normalised(sumA);
|
||||||
|
|
||||||
|
// Compute the area-weighted sum of the triangle centres. Note use
|
||||||
|
// the triangle area projected in the direction of the face normal
|
||||||
|
// as the weight, *not* the triangle area magnitude. Only the
|
||||||
|
// former makes the calculation independent of the initial estimate.
|
||||||
|
solveScalar sumAn = 0.0;
|
||||||
|
solveVector sumAnc = Zero;
|
||||||
|
for (label pi = 0; pi < nPoints; pi++)
|
||||||
|
{
|
||||||
|
const label nextPi(pi == nPoints-1 ? 0 : pi+1);
|
||||||
|
const solveVector nextPoint(p[f[nextPi]]);
|
||||||
|
const solveVector thisPoint(p[f[pi]]);
|
||||||
|
|
||||||
|
const solveVector c = thisPoint + nextPoint + fCentre;
|
||||||
|
const solveVector a =
|
||||||
|
(nextPoint - thisPoint)^(fCentre - thisPoint);
|
||||||
|
|
||||||
|
const scalar an = a & sumAHat;
|
||||||
|
|
||||||
|
sumAn += an;
|
||||||
|
sumAnc += an*c;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Complete calculating centres and areas. If the face is too small
|
||||||
|
// for the sums to be reliably divided then just set the centre to
|
||||||
|
// the initial estimate.
|
||||||
|
if (sumAn > ROOTVSMALL)
|
||||||
|
{
|
||||||
|
fCtrs[facei] = (1.0/3.0)*sumAnc/sumAn;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fCtrs[facei] = fCentre;
|
||||||
|
}
|
||||||
|
fAreas[facei] = 0.5*sumA;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Foam::stabilisedFvGeometryScheme::stabilisedFvGeometryScheme
|
||||||
|
(
|
||||||
|
const fvMesh& mesh,
|
||||||
|
const dictionary& dict
|
||||||
|
)
|
||||||
|
:
|
||||||
|
basicFvGeometryScheme(mesh, dict)
|
||||||
|
{
|
||||||
|
// Force local calculation
|
||||||
|
movePoints();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
void Foam::stabilisedFvGeometryScheme::movePoints()
|
||||||
|
{
|
||||||
|
if (debug)
|
||||||
|
{
|
||||||
|
Pout<< "stabilisedFvGeometryScheme::movePoints() : "
|
||||||
|
<< "recalculating primitiveMesh centres" << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
if
|
||||||
|
(
|
||||||
|
!mesh_.hasCellCentres()
|
||||||
|
&& !mesh_.hasFaceCentres()
|
||||||
|
&& !mesh_.hasCellVolumes()
|
||||||
|
&& !mesh_.hasFaceAreas()
|
||||||
|
)
|
||||||
|
{
|
||||||
|
vectorField faceCentres(mesh_.nFaces());
|
||||||
|
vectorField faceAreas(mesh_.nFaces());
|
||||||
|
|
||||||
|
makeFaceCentresAndAreas
|
||||||
|
(
|
||||||
|
mesh_,
|
||||||
|
mesh_.points(),
|
||||||
|
faceCentres,
|
||||||
|
faceAreas
|
||||||
|
);
|
||||||
|
|
||||||
|
vectorField cellCentres(mesh_.nCells());
|
||||||
|
scalarField cellVolumes(mesh_.nCells());
|
||||||
|
|
||||||
|
primitiveMeshTools::makeCellCentresAndVols
|
||||||
|
(
|
||||||
|
mesh_,
|
||||||
|
faceCentres,
|
||||||
|
faceAreas,
|
||||||
|
cellCentres,
|
||||||
|
cellVolumes
|
||||||
|
);
|
||||||
|
|
||||||
|
const_cast<fvMesh&>(mesh_).primitiveMesh::resetGeometry
|
||||||
|
(
|
||||||
|
std::move(faceCentres),
|
||||||
|
std::move(faceAreas),
|
||||||
|
std::move(cellCentres),
|
||||||
|
std::move(cellVolumes)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -0,0 +1,126 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | www.openfoam.com
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
Copyright (C) 2020 OpenCFD Ltd.
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
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::stabilisedFvGeometryScheme
|
||||||
|
|
||||||
|
Description
|
||||||
|
Geometry calculation scheme that implements face geometry calculation
|
||||||
|
using normal-component-of-area weighted triangle contributions.
|
||||||
|
|
||||||
|
This implements the Foundation 'Corrected face-centre calculations'
|
||||||
|
as a separate geometry scheme. Only implements the primitiveMesh parts,
|
||||||
|
not the individual face calculation.
|
||||||
|
|
||||||
|
SourceFiles
|
||||||
|
stabilisedFvGeometryScheme.C
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef stabilisedFvGeometryScheme_H
|
||||||
|
#define stabilisedFvGeometryScheme_H
|
||||||
|
|
||||||
|
#include "basicFvGeometryScheme.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
|
||||||
|
class primitiveMesh;
|
||||||
|
class polyMesh;
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
Class stabilisedFvGeometryScheme Declaration
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
class stabilisedFvGeometryScheme
|
||||||
|
:
|
||||||
|
public basicFvGeometryScheme
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
|
||||||
|
// Protected Member Functions
|
||||||
|
|
||||||
|
//- Calculate face area and centre weighted using pyramid height
|
||||||
|
static void makeFaceCentresAndAreas
|
||||||
|
(
|
||||||
|
const polyMesh& mesh,
|
||||||
|
const pointField& p,
|
||||||
|
vectorField& fCtrs,
|
||||||
|
vectorField& fAreas
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
// Private Member Functions
|
||||||
|
|
||||||
|
//- No copy construct
|
||||||
|
stabilisedFvGeometryScheme
|
||||||
|
(
|
||||||
|
const stabilisedFvGeometryScheme&
|
||||||
|
) = delete;
|
||||||
|
|
||||||
|
//- No copy assignment
|
||||||
|
void operator=(const stabilisedFvGeometryScheme&) = delete;
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
//- Runtime type information
|
||||||
|
TypeName("stabilised");
|
||||||
|
|
||||||
|
|
||||||
|
// Constructors
|
||||||
|
|
||||||
|
//- Construct from mesh
|
||||||
|
stabilisedFvGeometryScheme
|
||||||
|
(
|
||||||
|
const fvMesh& mesh,
|
||||||
|
const dictionary& dict
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
//- Destructor
|
||||||
|
virtual ~stabilisedFvGeometryScheme() = default;
|
||||||
|
|
||||||
|
|
||||||
|
// Member Functions
|
||||||
|
|
||||||
|
//- Do what is necessary if the mesh has moved
|
||||||
|
virtual void movePoints();
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
} // End namespace Foam
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -240,11 +240,11 @@ void Foam::fvMesh::clearOut()
|
|||||||
|
|
||||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
Foam::fvMesh::fvMesh(const IOobject& io)
|
Foam::fvMesh::fvMesh(const IOobject& io, const bool doInit)
|
||||||
:
|
:
|
||||||
polyMesh(io),
|
polyMesh(io, doInit),
|
||||||
surfaceInterpolation(*this),
|
|
||||||
fvSchemes(static_cast<const objectRegistry&>(*this)),
|
fvSchemes(static_cast<const objectRegistry&>(*this)),
|
||||||
|
surfaceInterpolation(*this),
|
||||||
fvSolution(static_cast<const objectRegistry&>(*this)),
|
fvSolution(static_cast<const objectRegistry&>(*this)),
|
||||||
data(static_cast<const objectRegistry&>(*this)),
|
data(static_cast<const objectRegistry&>(*this)),
|
||||||
boundary_(*this, boundaryMesh()),
|
boundary_(*this, boundaryMesh()),
|
||||||
@ -261,6 +261,25 @@ Foam::fvMesh::fvMesh(const IOobject& io)
|
|||||||
{
|
{
|
||||||
DebugInFunction << "Constructing fvMesh from IOobject" << endl;
|
DebugInFunction << "Constructing fvMesh from IOobject" << endl;
|
||||||
|
|
||||||
|
if (doInit)
|
||||||
|
{
|
||||||
|
fvMesh::init(false); // do not initialise lower levels
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Foam::fvMesh::init(const bool doInit)
|
||||||
|
{
|
||||||
|
if (doInit)
|
||||||
|
{
|
||||||
|
// Construct basic geometry calculation engine. Note: do before
|
||||||
|
// doing anything with primitiveMesh::cellCentres etc.
|
||||||
|
(void)geometry();
|
||||||
|
|
||||||
|
// Intialise my data
|
||||||
|
polyMesh::init(doInit);
|
||||||
|
}
|
||||||
|
|
||||||
// Check the existence of the cell volumes and read if present
|
// Check the existence of the cell volumes and read if present
|
||||||
// and set the storage of V00
|
// and set the storage of V00
|
||||||
if (fileHandler().isFile(time().timePath()/dbDir()/"V0"))
|
if (fileHandler().isFile(time().timePath()/dbDir()/"V0"))
|
||||||
@ -322,6 +341,7 @@ Foam::fvMesh::fvMesh(const IOobject& io)
|
|||||||
|
|
||||||
moving(true);
|
moving(true);
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -344,11 +364,11 @@ Foam::fvMesh::fvMesh
|
|||||||
std::move(allNeighbour),
|
std::move(allNeighbour),
|
||||||
syncPar
|
syncPar
|
||||||
),
|
),
|
||||||
surfaceInterpolation(*this),
|
|
||||||
fvSchemes(static_cast<const objectRegistry&>(*this)),
|
fvSchemes(static_cast<const objectRegistry&>(*this)),
|
||||||
|
surfaceInterpolation(*this),
|
||||||
fvSolution(static_cast<const objectRegistry&>(*this)),
|
fvSolution(static_cast<const objectRegistry&>(*this)),
|
||||||
data(static_cast<const objectRegistry&>(*this)),
|
data(static_cast<const objectRegistry&>(*this)),
|
||||||
boundary_(*this, boundaryMesh()),
|
boundary_(*this),
|
||||||
lduPtr_(nullptr),
|
lduPtr_(nullptr),
|
||||||
curTimeIndex_(time().timeIndex()),
|
curTimeIndex_(time().timeIndex()),
|
||||||
VPtr_(nullptr),
|
VPtr_(nullptr),
|
||||||
@ -381,8 +401,8 @@ Foam::fvMesh::fvMesh
|
|||||||
std::move(cells),
|
std::move(cells),
|
||||||
syncPar
|
syncPar
|
||||||
),
|
),
|
||||||
surfaceInterpolation(*this),
|
|
||||||
fvSchemes(static_cast<const objectRegistry&>(*this)),
|
fvSchemes(static_cast<const objectRegistry&>(*this)),
|
||||||
|
surfaceInterpolation(*this),
|
||||||
fvSolution(static_cast<const objectRegistry&>(*this)),
|
fvSolution(static_cast<const objectRegistry&>(*this)),
|
||||||
data(static_cast<const objectRegistry&>(*this)),
|
data(static_cast<const objectRegistry&>(*this)),
|
||||||
boundary_(*this),
|
boundary_(*this),
|
||||||
@ -407,6 +427,108 @@ Foam::fvMesh::fvMesh(const IOobject& io, const zero, const bool syncPar)
|
|||||||
{}
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::fvMesh::fvMesh
|
||||||
|
(
|
||||||
|
const IOobject& io,
|
||||||
|
const fvMesh& baseMesh,
|
||||||
|
pointField&& points,
|
||||||
|
faceList&& faces,
|
||||||
|
labelList&& allOwner,
|
||||||
|
labelList&& allNeighbour,
|
||||||
|
const bool syncPar
|
||||||
|
)
|
||||||
|
:
|
||||||
|
polyMesh
|
||||||
|
(
|
||||||
|
io,
|
||||||
|
std::move(points),
|
||||||
|
std::move(faces),
|
||||||
|
std::move(allOwner),
|
||||||
|
std::move(allNeighbour),
|
||||||
|
syncPar
|
||||||
|
),
|
||||||
|
fvSchemes
|
||||||
|
(
|
||||||
|
static_cast<const objectRegistry&>(*this),
|
||||||
|
static_cast<const fvSchemes&>(baseMesh)
|
||||||
|
),
|
||||||
|
surfaceInterpolation(*this),
|
||||||
|
fvSolution
|
||||||
|
(
|
||||||
|
static_cast<const objectRegistry&>(*this),
|
||||||
|
static_cast<const fvSolution&>(baseMesh)
|
||||||
|
),
|
||||||
|
data
|
||||||
|
(
|
||||||
|
static_cast<const objectRegistry&>(*this),
|
||||||
|
static_cast<const data&>(baseMesh)
|
||||||
|
),
|
||||||
|
boundary_(*this),
|
||||||
|
lduPtr_(nullptr),
|
||||||
|
curTimeIndex_(time().timeIndex()),
|
||||||
|
VPtr_(nullptr),
|
||||||
|
V0Ptr_(nullptr),
|
||||||
|
V00Ptr_(nullptr),
|
||||||
|
SfPtr_(nullptr),
|
||||||
|
magSfPtr_(nullptr),
|
||||||
|
CPtr_(nullptr),
|
||||||
|
CfPtr_(nullptr),
|
||||||
|
phiPtr_(nullptr)
|
||||||
|
{
|
||||||
|
DebugInFunction << "Constructing fvMesh as copy and primitives" << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::fvMesh::fvMesh
|
||||||
|
(
|
||||||
|
const IOobject& io,
|
||||||
|
const fvMesh& baseMesh,
|
||||||
|
pointField&& points,
|
||||||
|
faceList&& faces,
|
||||||
|
cellList&& cells,
|
||||||
|
const bool syncPar
|
||||||
|
)
|
||||||
|
:
|
||||||
|
polyMesh
|
||||||
|
(
|
||||||
|
io,
|
||||||
|
std::move(points),
|
||||||
|
std::move(faces),
|
||||||
|
std::move(cells),
|
||||||
|
syncPar
|
||||||
|
),
|
||||||
|
fvSchemes
|
||||||
|
(
|
||||||
|
static_cast<const objectRegistry&>(*this),
|
||||||
|
static_cast<const fvSchemes&>(baseMesh)
|
||||||
|
),
|
||||||
|
surfaceInterpolation(*this),
|
||||||
|
fvSolution
|
||||||
|
(
|
||||||
|
static_cast<const objectRegistry&>(*this),
|
||||||
|
static_cast<const fvSolution&>(baseMesh)
|
||||||
|
),
|
||||||
|
data
|
||||||
|
(
|
||||||
|
static_cast<const objectRegistry&>(*this),
|
||||||
|
static_cast<const data&>(baseMesh)
|
||||||
|
),
|
||||||
|
boundary_(*this),
|
||||||
|
lduPtr_(nullptr),
|
||||||
|
curTimeIndex_(time().timeIndex()),
|
||||||
|
VPtr_(nullptr),
|
||||||
|
V0Ptr_(nullptr),
|
||||||
|
V00Ptr_(nullptr),
|
||||||
|
SfPtr_(nullptr),
|
||||||
|
magSfPtr_(nullptr),
|
||||||
|
CPtr_(nullptr),
|
||||||
|
CfPtr_(nullptr),
|
||||||
|
phiPtr_(nullptr)
|
||||||
|
{
|
||||||
|
DebugInFunction << "Constructing fvMesh as copy and primitives" << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
Foam::fvMesh::~fvMesh()
|
Foam::fvMesh::~fvMesh()
|
||||||
@ -804,6 +926,13 @@ Foam::tmp<Foam::scalarField> Foam::fvMesh::movePoints(const pointField& p)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::fvMesh::updateGeom()
|
||||||
|
{
|
||||||
|
// Let surfaceInterpolation handle geometry calculation
|
||||||
|
surfaceInterpolation::updateGeom();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void Foam::fvMesh::updateMesh(const mapPolyMesh& mpm)
|
void Foam::fvMesh::updateMesh(const mapPolyMesh& mpm)
|
||||||
{
|
{
|
||||||
DebugInFunction << endl;
|
DebugInFunction << endl;
|
||||||
|
|||||||
@ -77,7 +77,6 @@ class volMesh;
|
|||||||
template<class Type>
|
template<class Type>
|
||||||
class fvMatrix;
|
class fvMatrix;
|
||||||
|
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*\
|
/*---------------------------------------------------------------------------*\
|
||||||
Class fvMesh Declaration
|
Class fvMesh Declaration
|
||||||
\*---------------------------------------------------------------------------*/
|
\*---------------------------------------------------------------------------*/
|
||||||
@ -86,8 +85,8 @@ class fvMesh
|
|||||||
:
|
:
|
||||||
public polyMesh,
|
public polyMesh,
|
||||||
public lduMesh,
|
public lduMesh,
|
||||||
public surfaceInterpolation,
|
|
||||||
public fvSchemes,
|
public fvSchemes,
|
||||||
|
public surfaceInterpolation, // needs input from fvSchemes
|
||||||
public fvSolution,
|
public fvSolution,
|
||||||
public data
|
public data
|
||||||
{
|
{
|
||||||
@ -98,7 +97,6 @@ protected:
|
|||||||
//- Boundary mesh
|
//- Boundary mesh
|
||||||
fvBoundaryMesh boundary_;
|
fvBoundaryMesh boundary_;
|
||||||
|
|
||||||
|
|
||||||
// Demand-driven data
|
// Demand-driven data
|
||||||
|
|
||||||
mutable fvMeshLduAddressing* lduPtr_;
|
mutable fvMeshLduAddressing* lduPtr_;
|
||||||
@ -186,7 +184,7 @@ public:
|
|||||||
// Constructors
|
// Constructors
|
||||||
|
|
||||||
//- Construct from IOobject
|
//- Construct from IOobject
|
||||||
explicit fvMesh(const IOobject& io);
|
explicit fvMesh(const IOobject& io, const bool doInit=true);
|
||||||
|
|
||||||
//- Construct from IOobject or as zero-sized mesh
|
//- Construct from IOobject or as zero-sized mesh
|
||||||
// Boundary is added using addFvPatches() member function
|
// Boundary is added using addFvPatches() member function
|
||||||
@ -215,6 +213,32 @@ public:
|
|||||||
const bool syncPar = true
|
const bool syncPar = true
|
||||||
);
|
);
|
||||||
|
|
||||||
|
//- Construct as copy (for dictionaries) and components without
|
||||||
|
// boundary. Boundary is added using addFvPatches() member function
|
||||||
|
fvMesh
|
||||||
|
(
|
||||||
|
const IOobject& io,
|
||||||
|
const fvMesh& baseMesh,
|
||||||
|
pointField&& points,
|
||||||
|
faceList&& faces,
|
||||||
|
labelList&& allOwner,
|
||||||
|
labelList&& allNeighbour,
|
||||||
|
const bool syncPar = true
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Construct as copy (for dictionaries) without boundary from cells
|
||||||
|
// rather than owner/neighbour. Boundary is added using addFvPatches()
|
||||||
|
// member function
|
||||||
|
fvMesh
|
||||||
|
(
|
||||||
|
const IOobject& io,
|
||||||
|
const fvMesh& baseMesh,
|
||||||
|
pointField&& points,
|
||||||
|
faceList&& faces,
|
||||||
|
cellList&& cells,
|
||||||
|
const bool syncPar = true
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
//- Destructor
|
//- Destructor
|
||||||
virtual ~fvMesh();
|
virtual ~fvMesh();
|
||||||
@ -224,6 +248,9 @@ public:
|
|||||||
|
|
||||||
// Helpers
|
// Helpers
|
||||||
|
|
||||||
|
//- Initialise all non-demand-driven data
|
||||||
|
virtual bool init(const bool doInit);
|
||||||
|
|
||||||
//- Add boundary patches. Constructor helper
|
//- Add boundary patches. Constructor helper
|
||||||
void addFvPatches
|
void addFvPatches
|
||||||
(
|
(
|
||||||
@ -438,6 +465,10 @@ public:
|
|||||||
//- Move points, returns volumes swept by faces in motion
|
//- Move points, returns volumes swept by faces in motion
|
||||||
virtual tmp<scalarField> movePoints(const pointField&);
|
virtual tmp<scalarField> movePoints(const pointField&);
|
||||||
|
|
||||||
|
//- Update all geometric data. This gets redirected up from
|
||||||
|
// primitiveMesh level
|
||||||
|
virtual void updateGeom();
|
||||||
|
|
||||||
//- Map all fields in time using given map.
|
//- Map all fields in time using given map.
|
||||||
virtual void mapFields(const mapPolyMesh& mpm);
|
virtual void mapFields(const mapPolyMesh& mpm);
|
||||||
|
|
||||||
|
|||||||
@ -74,7 +74,16 @@ class fvPatch
|
|||||||
const fvBoundaryMesh& boundaryMesh_;
|
const fvBoundaryMesh& boundaryMesh_;
|
||||||
|
|
||||||
|
|
||||||
protected:
|
// Private Member Functions
|
||||||
|
|
||||||
|
//- No copy construct
|
||||||
|
fvPatch(const fvPatch&) = delete;
|
||||||
|
|
||||||
|
//- No copy assignment
|
||||||
|
void operator=(const fvPatch&) = delete;
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
// Protected Member Functions
|
// Protected Member Functions
|
||||||
|
|
||||||
@ -96,11 +105,6 @@ protected:
|
|||||||
//- Correct patches after moving points
|
//- Correct patches after moving points
|
||||||
virtual void movePoints();
|
virtual void movePoints();
|
||||||
|
|
||||||
//- No copy construct
|
|
||||||
fvPatch(const fvPatch&) = delete;
|
|
||||||
|
|
||||||
//- No copy assignment
|
|
||||||
void operator=(const fvPatch&) = delete;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
|||||||
@ -6,7 +6,7 @@
|
|||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Copyright (C) 2011-2016 OpenFOAM Foundation
|
Copyright (C) 2011-2016 OpenFOAM Foundation
|
||||||
Copyright (C) 2017 OpenCFD Ltd.
|
Copyright (C) 2017-2020 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM.
|
This file is part of OpenFOAM.
|
||||||
@ -29,11 +29,12 @@ Description
|
|||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#include "surfaceInterpolation.H"
|
||||||
#include "fvMesh.H"
|
#include "fvMesh.H"
|
||||||
#include "volFields.H"
|
#include "volFields.H"
|
||||||
#include "surfaceFields.H"
|
#include "surfaceFields.H"
|
||||||
#include "demandDrivenData.H"
|
|
||||||
#include "coupledFvPatch.H"
|
#include "coupledFvPatch.H"
|
||||||
|
#include "basicFvGeometryScheme.H"
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||||
|
|
||||||
@ -47,10 +48,10 @@ namespace Foam
|
|||||||
|
|
||||||
void Foam::surfaceInterpolation::clearOut()
|
void Foam::surfaceInterpolation::clearOut()
|
||||||
{
|
{
|
||||||
deleteDemandDrivenData(weights_);
|
weights_.clear();
|
||||||
deleteDemandDrivenData(deltaCoeffs_);
|
deltaCoeffs_.clear();
|
||||||
deleteDemandDrivenData(nonOrthDeltaCoeffs_);
|
nonOrthDeltaCoeffs_.clear();
|
||||||
deleteDemandDrivenData(nonOrthCorrectionVectors_);
|
nonOrthCorrectionVectors_.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -76,358 +77,107 @@ Foam::surfaceInterpolation::~surfaceInterpolation()
|
|||||||
|
|
||||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||||
|
|
||||||
const Foam::surfaceScalarField& Foam::surfaceInterpolation::weights() const
|
const Foam::fvGeometryScheme& Foam::surfaceInterpolation::geometry() const
|
||||||
{
|
{
|
||||||
if (!weights_)
|
if (!geometryPtr_.valid())
|
||||||
{
|
{
|
||||||
makeWeights();
|
geometryPtr_ = fvGeometryScheme::New
|
||||||
|
(
|
||||||
|
mesh_,
|
||||||
|
mesh_.schemesDict().subOrEmptyDict("geometry"),
|
||||||
|
basicFvGeometryScheme::typeName
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (*weights_);
|
return geometryPtr_();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::surfaceInterpolation::geometry(tmp<fvGeometryScheme>& schemePtr)
|
||||||
|
{
|
||||||
|
geometryPtr_ = schemePtr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const Foam::surfaceScalarField& Foam::surfaceInterpolation::weights() const
|
||||||
|
{
|
||||||
|
if (!weights_.valid())
|
||||||
|
{
|
||||||
|
weights_.set(geometry().weights().ptr());
|
||||||
|
}
|
||||||
|
|
||||||
|
return weights_();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const Foam::surfaceScalarField& Foam::surfaceInterpolation::deltaCoeffs() const
|
const Foam::surfaceScalarField& Foam::surfaceInterpolation::deltaCoeffs() const
|
||||||
{
|
{
|
||||||
if (!deltaCoeffs_)
|
if (!deltaCoeffs_.valid())
|
||||||
{
|
{
|
||||||
makeDeltaCoeffs();
|
deltaCoeffs_.set(geometry().deltaCoeffs().ptr());
|
||||||
}
|
}
|
||||||
|
|
||||||
return (*deltaCoeffs_);
|
return deltaCoeffs_();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const Foam::surfaceScalarField&
|
const Foam::surfaceScalarField&
|
||||||
Foam::surfaceInterpolation::nonOrthDeltaCoeffs() const
|
Foam::surfaceInterpolation::nonOrthDeltaCoeffs() const
|
||||||
{
|
{
|
||||||
if (!nonOrthDeltaCoeffs_)
|
if (!nonOrthDeltaCoeffs_.valid())
|
||||||
{
|
{
|
||||||
makeNonOrthDeltaCoeffs();
|
nonOrthDeltaCoeffs_.set(geometry().nonOrthDeltaCoeffs().ptr());
|
||||||
}
|
}
|
||||||
|
|
||||||
return (*nonOrthDeltaCoeffs_);
|
return nonOrthDeltaCoeffs_();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const Foam::surfaceVectorField&
|
const Foam::surfaceVectorField&
|
||||||
Foam::surfaceInterpolation::nonOrthCorrectionVectors() const
|
Foam::surfaceInterpolation::nonOrthCorrectionVectors() const
|
||||||
{
|
{
|
||||||
if (!nonOrthCorrectionVectors_)
|
if (!nonOrthCorrectionVectors_.valid())
|
||||||
{
|
{
|
||||||
makeNonOrthCorrectionVectors();
|
nonOrthCorrectionVectors_.set
|
||||||
|
(
|
||||||
|
geometry().nonOrthCorrectionVectors().ptr()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (*nonOrthCorrectionVectors_);
|
return nonOrthCorrectionVectors_();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool Foam::surfaceInterpolation::movePoints()
|
bool Foam::surfaceInterpolation::movePoints()
|
||||||
{
|
{
|
||||||
deleteDemandDrivenData(weights_);
|
if (debug)
|
||||||
deleteDemandDrivenData(deltaCoeffs_);
|
{
|
||||||
deleteDemandDrivenData(nonOrthDeltaCoeffs_);
|
Pout<< "surfaceInterpolation::movePoints() : "
|
||||||
deleteDemandDrivenData(nonOrthCorrectionVectors_);
|
<< "Updating geometric properties using the fvGeometryScheme"
|
||||||
|
<< endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Do any primitive geometry calculation
|
||||||
|
const_cast<fvGeometryScheme&>(geometry()).movePoints();
|
||||||
|
|
||||||
|
weights_.clear();
|
||||||
|
deltaCoeffs_.clear();
|
||||||
|
nonOrthDeltaCoeffs_.clear();
|
||||||
|
nonOrthCorrectionVectors_.clear();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Foam::surfaceInterpolation::makeWeights() const
|
void Foam::surfaceInterpolation::updateGeom()
|
||||||
{
|
{
|
||||||
if (debug)
|
if (debug)
|
||||||
{
|
{
|
||||||
Pout<< "surfaceInterpolation::makeWeights() : "
|
Pout<< "surfaceInterpolation::updateGeom() : "
|
||||||
<< "Constructing weighting factors for face interpolation"
|
<< "Updating geometric properties" << endl;
|
||||||
<< endl;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
weights_ = new surfaceScalarField
|
const_cast<fvGeometryScheme&>(geometry()).movePoints();
|
||||||
(
|
|
||||||
IOobject
|
|
||||||
(
|
|
||||||
"weights",
|
|
||||||
mesh_.pointsInstance(),
|
|
||||||
mesh_,
|
|
||||||
IOobject::NO_READ,
|
|
||||||
IOobject::NO_WRITE,
|
|
||||||
false // Do not register
|
|
||||||
),
|
|
||||||
mesh_,
|
|
||||||
dimless
|
|
||||||
);
|
|
||||||
surfaceScalarField& weights = *weights_;
|
|
||||||
weights.setOriented();
|
|
||||||
|
|
||||||
// Set local references to mesh data
|
|
||||||
// Note that we should not use fvMesh sliced fields at this point yet
|
|
||||||
// since this causes a loop when generating weighting factors in
|
|
||||||
// coupledFvPatchField evaluation phase
|
|
||||||
const labelUList& owner = mesh_.owner();
|
|
||||||
const labelUList& neighbour = mesh_.neighbour();
|
|
||||||
|
|
||||||
const vectorField& Cf = mesh_.faceCentres();
|
|
||||||
const vectorField& C = mesh_.cellCentres();
|
|
||||||
const vectorField& Sf = mesh_.faceAreas();
|
|
||||||
|
|
||||||
// ... and reference to the internal field of the weighting factors
|
|
||||||
scalarField& w = weights.primitiveFieldRef();
|
|
||||||
forAll(owner, facei)
|
|
||||||
{
|
|
||||||
// Note: mag in the dot-product.
|
|
||||||
// For all valid meshes, the non-orthogonality will be less than
|
|
||||||
// 90 deg and the dot-product will be positive. For invalid
|
|
||||||
// meshes (d & s <= 0), this will stabilise the calculation
|
|
||||||
// but the result will be poor.
|
|
||||||
scalar SfdOwn = mag(Sf[facei] & (Cf[facei] - C[owner[facei]]));
|
|
||||||
scalar SfdNei = mag(Sf[facei] & (C[neighbour[facei]] - Cf[facei]));
|
|
||||||
w[facei] = SfdNei/(SfdOwn + SfdNei);
|
|
||||||
}
|
|
||||||
|
|
||||||
surfaceScalarField::Boundary& wBf = weights.boundaryFieldRef();
|
|
||||||
|
|
||||||
forAll(mesh_.boundary(), patchi)
|
|
||||||
{
|
|
||||||
mesh_.boundary()[patchi].makeWeights(wBf[patchi]);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (debug)
|
|
||||||
{
|
|
||||||
Pout<< "surfaceInterpolation::makeWeights() : "
|
|
||||||
<< "Finished constructing weighting factors for face interpolation"
|
|
||||||
<< endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Foam::surfaceInterpolation::makeDeltaCoeffs() const
|
|
||||||
{
|
|
||||||
if (debug)
|
|
||||||
{
|
|
||||||
Pout<< "surfaceInterpolation::makeDeltaCoeffs() : "
|
|
||||||
<< "Constructing differencing factors array for face gradient"
|
|
||||||
<< endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Force the construction of the weighting factors
|
|
||||||
// needed to make sure deltaCoeffs are calculated for parallel runs.
|
|
||||||
weights();
|
|
||||||
|
|
||||||
deltaCoeffs_ = new surfaceScalarField
|
|
||||||
(
|
|
||||||
IOobject
|
|
||||||
(
|
|
||||||
"deltaCoeffs",
|
|
||||||
mesh_.pointsInstance(),
|
|
||||||
mesh_,
|
|
||||||
IOobject::NO_READ,
|
|
||||||
IOobject::NO_WRITE,
|
|
||||||
false // Do not register
|
|
||||||
),
|
|
||||||
mesh_,
|
|
||||||
dimless/dimLength
|
|
||||||
);
|
|
||||||
surfaceScalarField& deltaCoeffs = *deltaCoeffs_;
|
|
||||||
deltaCoeffs.setOriented();
|
|
||||||
|
|
||||||
|
|
||||||
// Set local references to mesh data
|
|
||||||
const volVectorField& C = mesh_.C();
|
|
||||||
const labelUList& owner = mesh_.owner();
|
|
||||||
const labelUList& neighbour = mesh_.neighbour();
|
|
||||||
|
|
||||||
forAll(owner, facei)
|
|
||||||
{
|
|
||||||
deltaCoeffs[facei] = 1.0/mag(C[neighbour[facei]] - C[owner[facei]]);
|
|
||||||
}
|
|
||||||
|
|
||||||
surfaceScalarField::Boundary& deltaCoeffsBf =
|
|
||||||
deltaCoeffs.boundaryFieldRef();
|
|
||||||
|
|
||||||
forAll(deltaCoeffsBf, patchi)
|
|
||||||
{
|
|
||||||
const fvPatch& p = mesh_.boundary()[patchi];
|
|
||||||
deltaCoeffsBf[patchi] = 1.0/mag(p.delta());
|
|
||||||
|
|
||||||
// Optionally correct
|
|
||||||
p.makeDeltaCoeffs(deltaCoeffsBf[patchi]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Foam::surfaceInterpolation::makeNonOrthDeltaCoeffs() const
|
|
||||||
{
|
|
||||||
if (debug)
|
|
||||||
{
|
|
||||||
Pout<< "surfaceInterpolation::makeNonOrthDeltaCoeffs() : "
|
|
||||||
<< "Constructing differencing factors array for face gradient"
|
|
||||||
<< endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Force the construction of the weighting factors
|
|
||||||
// needed to make sure deltaCoeffs are calculated for parallel runs.
|
|
||||||
weights();
|
|
||||||
|
|
||||||
nonOrthDeltaCoeffs_ = new surfaceScalarField
|
|
||||||
(
|
|
||||||
IOobject
|
|
||||||
(
|
|
||||||
"nonOrthDeltaCoeffs",
|
|
||||||
mesh_.pointsInstance(),
|
|
||||||
mesh_,
|
|
||||||
IOobject::NO_READ,
|
|
||||||
IOobject::NO_WRITE,
|
|
||||||
false // Do not register
|
|
||||||
),
|
|
||||||
mesh_,
|
|
||||||
dimless/dimLength
|
|
||||||
);
|
|
||||||
surfaceScalarField& nonOrthDeltaCoeffs = *nonOrthDeltaCoeffs_;
|
|
||||||
nonOrthDeltaCoeffs.setOriented();
|
|
||||||
|
|
||||||
|
|
||||||
// Set local references to mesh data
|
|
||||||
const volVectorField& C = mesh_.C();
|
|
||||||
const labelUList& owner = mesh_.owner();
|
|
||||||
const labelUList& neighbour = mesh_.neighbour();
|
|
||||||
const surfaceVectorField& Sf = mesh_.Sf();
|
|
||||||
const surfaceScalarField& magSf = mesh_.magSf();
|
|
||||||
|
|
||||||
forAll(owner, facei)
|
|
||||||
{
|
|
||||||
vector delta = C[neighbour[facei]] - C[owner[facei]];
|
|
||||||
vector unitArea = Sf[facei]/magSf[facei];
|
|
||||||
|
|
||||||
// Standard cell-centre distance form
|
|
||||||
//NonOrthDeltaCoeffs[facei] = (unitArea & delta)/magSqr(delta);
|
|
||||||
|
|
||||||
// Slightly under-relaxed form
|
|
||||||
//NonOrthDeltaCoeffs[facei] = 1.0/mag(delta);
|
|
||||||
|
|
||||||
// More under-relaxed form
|
|
||||||
//NonOrthDeltaCoeffs[facei] = 1.0/(mag(unitArea & delta) + VSMALL);
|
|
||||||
|
|
||||||
// Stabilised form for bad meshes
|
|
||||||
nonOrthDeltaCoeffs[facei] = 1.0/max(unitArea & delta, 0.05*mag(delta));
|
|
||||||
}
|
|
||||||
|
|
||||||
surfaceScalarField::Boundary& nonOrthDeltaCoeffsBf =
|
|
||||||
nonOrthDeltaCoeffs.boundaryFieldRef();
|
|
||||||
|
|
||||||
forAll(nonOrthDeltaCoeffsBf, patchi)
|
|
||||||
{
|
|
||||||
fvsPatchScalarField& patchDeltaCoeffs = nonOrthDeltaCoeffsBf[patchi];
|
|
||||||
|
|
||||||
const fvPatch& p = patchDeltaCoeffs.patch();
|
|
||||||
|
|
||||||
const vectorField patchDeltas(mesh_.boundary()[patchi].delta());
|
|
||||||
|
|
||||||
forAll(p, patchFacei)
|
|
||||||
{
|
|
||||||
vector unitArea =
|
|
||||||
Sf.boundaryField()[patchi][patchFacei]
|
|
||||||
/magSf.boundaryField()[patchi][patchFacei];
|
|
||||||
|
|
||||||
const vector& delta = patchDeltas[patchFacei];
|
|
||||||
|
|
||||||
patchDeltaCoeffs[patchFacei] =
|
|
||||||
1.0/max(unitArea & delta, 0.05*mag(delta));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Optionally correct
|
|
||||||
p.makeNonOrthoDeltaCoeffs(patchDeltaCoeffs);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Foam::surfaceInterpolation::makeNonOrthCorrectionVectors() const
|
|
||||||
{
|
|
||||||
if (debug)
|
|
||||||
{
|
|
||||||
Pout<< "surfaceInterpolation::makeNonOrthCorrectionVectors() : "
|
|
||||||
<< "Constructing non-orthogonal correction vectors"
|
|
||||||
<< endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
nonOrthCorrectionVectors_ = new surfaceVectorField
|
|
||||||
(
|
|
||||||
IOobject
|
|
||||||
(
|
|
||||||
"nonOrthCorrectionVectors",
|
|
||||||
mesh_.pointsInstance(),
|
|
||||||
mesh_,
|
|
||||||
IOobject::NO_READ,
|
|
||||||
IOobject::NO_WRITE,
|
|
||||||
false // Do not register
|
|
||||||
),
|
|
||||||
mesh_,
|
|
||||||
dimless
|
|
||||||
);
|
|
||||||
surfaceVectorField& corrVecs = *nonOrthCorrectionVectors_;
|
|
||||||
corrVecs.setOriented();
|
|
||||||
|
|
||||||
// Set local references to mesh data
|
|
||||||
const volVectorField& C = mesh_.C();
|
|
||||||
const labelUList& owner = mesh_.owner();
|
|
||||||
const labelUList& neighbour = mesh_.neighbour();
|
|
||||||
const surfaceVectorField& Sf = mesh_.Sf();
|
|
||||||
const surfaceScalarField& magSf = mesh_.magSf();
|
|
||||||
const surfaceScalarField& NonOrthDeltaCoeffs = nonOrthDeltaCoeffs();
|
|
||||||
|
|
||||||
forAll(owner, facei)
|
|
||||||
{
|
|
||||||
vector unitArea = Sf[facei]/magSf[facei];
|
|
||||||
vector delta = C[neighbour[facei]] - C[owner[facei]];
|
|
||||||
|
|
||||||
corrVecs[facei] = unitArea - delta*NonOrthDeltaCoeffs[facei];
|
|
||||||
}
|
|
||||||
|
|
||||||
// Boundary correction vectors set to zero for boundary patches
|
|
||||||
// and calculated consistently with internal corrections for
|
|
||||||
// coupled patches
|
|
||||||
|
|
||||||
surfaceVectorField::Boundary& corrVecsBf = corrVecs.boundaryFieldRef();
|
|
||||||
|
|
||||||
forAll(corrVecsBf, patchi)
|
|
||||||
{
|
|
||||||
fvsPatchVectorField& patchCorrVecs = corrVecsBf[patchi];
|
|
||||||
|
|
||||||
const fvPatch& p = patchCorrVecs.patch();
|
|
||||||
|
|
||||||
if (!patchCorrVecs.coupled())
|
|
||||||
{
|
|
||||||
patchCorrVecs = Zero;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
const fvsPatchScalarField& patchNonOrthDeltaCoeffs =
|
|
||||||
NonOrthDeltaCoeffs.boundaryField()[patchi];
|
|
||||||
|
|
||||||
const vectorField patchDeltas(mesh_.boundary()[patchi].delta());
|
|
||||||
|
|
||||||
forAll(p, patchFacei)
|
|
||||||
{
|
|
||||||
vector unitArea =
|
|
||||||
Sf.boundaryField()[patchi][patchFacei]
|
|
||||||
/magSf.boundaryField()[patchi][patchFacei];
|
|
||||||
|
|
||||||
const vector& delta = patchDeltas[patchFacei];
|
|
||||||
|
|
||||||
patchCorrVecs[patchFacei] =
|
|
||||||
unitArea - delta*patchNonOrthDeltaCoeffs[patchFacei];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Optionally correct
|
|
||||||
p.makeNonOrthoCorrVectors(patchCorrVecs);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (debug)
|
|
||||||
{
|
|
||||||
Pout<< "surfaceInterpolation::makeNonOrthCorrectionVectors() : "
|
|
||||||
<< "Finished constructing non-orthogonal correction vectors"
|
|
||||||
<< endl;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -6,6 +6,7 @@
|
|||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Copyright (C) 2011 OpenFOAM Foundation
|
Copyright (C) 2011 OpenFOAM Foundation
|
||||||
|
Copyright (C) 2020 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM.
|
This file is part of OpenFOAM.
|
||||||
@ -48,8 +49,11 @@ SourceFiles
|
|||||||
namespace Foam
|
namespace Foam
|
||||||
{
|
{
|
||||||
|
|
||||||
|
class fvMesh;
|
||||||
|
class fvGeometryScheme;
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*\
|
/*---------------------------------------------------------------------------*\
|
||||||
Class surfaceInterpolation Declaration
|
Class surfaceInterpolation Declaration
|
||||||
\*---------------------------------------------------------------------------*/
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
class surfaceInterpolation
|
class surfaceInterpolation
|
||||||
@ -59,34 +63,23 @@ class surfaceInterpolation
|
|||||||
// Reference to fvMesh
|
// Reference to fvMesh
|
||||||
const fvMesh& mesh_;
|
const fvMesh& mesh_;
|
||||||
|
|
||||||
|
|
||||||
// Demand-driven data
|
// Demand-driven data
|
||||||
|
|
||||||
|
//- Geometry calculation
|
||||||
|
mutable tmp<fvGeometryScheme> geometryPtr_;
|
||||||
|
|
||||||
//- Linear difference weighting factors
|
//- Linear difference weighting factors
|
||||||
mutable surfaceScalarField* weights_;
|
mutable autoPtr<surfaceScalarField> weights_;
|
||||||
|
|
||||||
//- Cell-centre difference coefficients
|
//- Cell-centre difference coefficients
|
||||||
mutable surfaceScalarField* deltaCoeffs_;
|
mutable autoPtr<surfaceScalarField> deltaCoeffs_;
|
||||||
|
|
||||||
//- Non-orthogonal cell-centre difference coefficients
|
//- Non-orthogonal cell-centre difference coefficients
|
||||||
mutable surfaceScalarField* nonOrthDeltaCoeffs_;
|
mutable autoPtr<surfaceScalarField> nonOrthDeltaCoeffs_;
|
||||||
|
|
||||||
//- Non-orthogonality correction vectors
|
//- Non-orthogonality correction vectors
|
||||||
mutable surfaceVectorField* nonOrthCorrectionVectors_;
|
mutable autoPtr<surfaceVectorField> nonOrthCorrectionVectors_;
|
||||||
|
|
||||||
|
|
||||||
// Private Member Functions
|
|
||||||
|
|
||||||
//- Construct central-differencing weighting factors
|
|
||||||
void makeWeights() const;
|
|
||||||
|
|
||||||
//- Construct face-gradient difference factors
|
|
||||||
void makeDeltaCoeffs() const;
|
|
||||||
|
|
||||||
//- Construct face-gradient difference factors
|
|
||||||
void makeNonOrthDeltaCoeffs() const;
|
|
||||||
|
|
||||||
//- Construct non-orthogonality correction vectors
|
|
||||||
void makeNonOrthCorrectionVectors() const;
|
|
||||||
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
@ -112,26 +105,35 @@ public:
|
|||||||
|
|
||||||
|
|
||||||
//- Destructor
|
//- Destructor
|
||||||
~surfaceInterpolation();
|
virtual ~surfaceInterpolation();
|
||||||
|
|
||||||
|
|
||||||
// Member functions
|
// Member functions
|
||||||
|
|
||||||
|
//- Return reference to geometry calculation scheme
|
||||||
|
virtual const fvGeometryScheme& geometry() const;
|
||||||
|
|
||||||
|
//- Set geometry calculation scheme
|
||||||
|
void geometry(tmp<fvGeometryScheme>&);
|
||||||
|
|
||||||
//- Return reference to linear difference weighting factors
|
//- Return reference to linear difference weighting factors
|
||||||
const surfaceScalarField& weights() const;
|
virtual const surfaceScalarField& weights() const;
|
||||||
|
|
||||||
//- Return reference to cell-centre difference coefficients
|
//- Return reference to cell-centre difference coefficients
|
||||||
const surfaceScalarField& deltaCoeffs() const;
|
virtual const surfaceScalarField& deltaCoeffs() const;
|
||||||
|
|
||||||
//- Return reference to non-orthogonal cell-centre difference
|
//- Return reference to non-orthogonal cell-centre difference
|
||||||
// coefficients
|
// coefficients
|
||||||
const surfaceScalarField& nonOrthDeltaCoeffs() const;
|
virtual const surfaceScalarField& nonOrthDeltaCoeffs() const;
|
||||||
|
|
||||||
//- Return reference to non-orthogonality correction vectors
|
//- Return reference to non-orthogonality correction vectors
|
||||||
const surfaceVectorField& nonOrthCorrectionVectors() const;
|
virtual const surfaceVectorField& nonOrthCorrectionVectors() const;
|
||||||
|
|
||||||
//- Do what is necessary if the mesh has moved
|
//- Do what is necessary if the mesh has moved
|
||||||
bool movePoints();
|
virtual bool movePoints();
|
||||||
|
|
||||||
|
//- Update all geometric data
|
||||||
|
virtual void updateGeom();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -35,6 +35,20 @@ License
|
|||||||
|
|
||||||
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
const Foam::Enum
|
||||||
|
<
|
||||||
|
Foam::layerParameters::thicknessModelType
|
||||||
|
>
|
||||||
|
Foam::layerParameters::thicknessModelTypeNames_
|
||||||
|
({
|
||||||
|
{ thicknessModelType::FIRST_AND_TOTAL, "firstAndOverall" },
|
||||||
|
{ thicknessModelType::FIRST_AND_EXPANSION, "firstAndExpansion" },
|
||||||
|
{ thicknessModelType::FINAL_AND_TOTAL, "finalAndOverall" },
|
||||||
|
{ thicknessModelType::FINAL_AND_EXPANSION, "finalAndExpansion" },
|
||||||
|
{ thicknessModelType::TOTAL_AND_EXPANSION, "overallAndExpansion" },
|
||||||
|
{ thicknessModelType::FIRST_AND_RELATIVE_FINAL, "firstAndRelativeFinal" },
|
||||||
|
});
|
||||||
|
|
||||||
const Foam::scalar Foam::layerParameters::defaultConcaveAngle = 90;
|
const Foam::scalar Foam::layerParameters::defaultConcaveAngle = 90;
|
||||||
|
|
||||||
|
|
||||||
@ -44,7 +58,7 @@ Foam::scalar Foam::layerParameters::layerExpansionRatio
|
|||||||
(
|
(
|
||||||
const label n,
|
const label n,
|
||||||
const scalar totalOverFirst
|
const scalar totalOverFirst
|
||||||
) const
|
)
|
||||||
{
|
{
|
||||||
if (n <= 1)
|
if (n <= 1)
|
||||||
{
|
{
|
||||||
@ -66,11 +80,11 @@ Foam::scalar Foam::layerParameters::layerExpansionRatio
|
|||||||
if (totalOverFirst < n)
|
if (totalOverFirst < n)
|
||||||
{
|
{
|
||||||
minR = 0.0;
|
minR = 0.0;
|
||||||
maxR = pow(totalOverFirst/n, 1/(n-1));
|
maxR = pow(totalOverFirst/n, scalar(1)/(n-1));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
minR = pow(totalOverFirst/n, 1/(n-1));
|
minR = pow(totalOverFirst/n, scalar(1)/(n-1));
|
||||||
maxR = totalOverFirst/(n - 1);
|
maxR = totalOverFirst/(n - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -94,6 +108,253 @@ Foam::scalar Foam::layerParameters::layerExpansionRatio
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::layerParameters::readLayerParameters
|
||||||
|
(
|
||||||
|
const bool verbose,
|
||||||
|
const dictionary& dict,
|
||||||
|
const thicknessModelType& spec,
|
||||||
|
scalar& firstLayerThickness,
|
||||||
|
scalar& finalLayerThickness,
|
||||||
|
scalar& thickness,
|
||||||
|
scalar& expansionRatio
|
||||||
|
)
|
||||||
|
{
|
||||||
|
// Now we have determined the layer-specification read the actual fields
|
||||||
|
switch (spec)
|
||||||
|
{
|
||||||
|
case FIRST_AND_TOTAL:
|
||||||
|
if (verbose)
|
||||||
|
{
|
||||||
|
Info<< "Layer specification as" << nl
|
||||||
|
<< "- first layer thickness ('firstLayerThickness')" << nl
|
||||||
|
<< "- overall thickness ('thickness')" << endl;
|
||||||
|
}
|
||||||
|
firstLayerThickness = readScalar
|
||||||
|
(
|
||||||
|
dict.lookup("firstLayerThickness")
|
||||||
|
);
|
||||||
|
thickness = readScalar(dict.lookup("thickness"));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FIRST_AND_EXPANSION:
|
||||||
|
if (verbose)
|
||||||
|
{
|
||||||
|
Info<< "Layer specification as" << nl
|
||||||
|
<< "- first layer thickness ('firstLayerThickness')" << nl
|
||||||
|
<< "- expansion ratio ('expansionRatio')" << endl;
|
||||||
|
}
|
||||||
|
firstLayerThickness = readScalar
|
||||||
|
(
|
||||||
|
dict.lookup("firstLayerThickness")
|
||||||
|
);
|
||||||
|
expansionRatio = readScalar(dict.lookup("expansionRatio"));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FINAL_AND_TOTAL:
|
||||||
|
if (verbose)
|
||||||
|
{
|
||||||
|
Info<< "Layer specification as" << nl
|
||||||
|
<< "- final layer thickness ('finalLayerThickness')" << nl
|
||||||
|
<< "- overall thickness ('thickness')" << endl;
|
||||||
|
}
|
||||||
|
finalLayerThickness = readScalar
|
||||||
|
(
|
||||||
|
dict.lookup("finalLayerThickness")
|
||||||
|
);
|
||||||
|
thickness = readScalar(dict.lookup("thickness"));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FINAL_AND_EXPANSION:
|
||||||
|
if (verbose)
|
||||||
|
{
|
||||||
|
Info<< "Layer specification as" << nl
|
||||||
|
<< "- final layer thickness ('finalLayerThickness')" << nl
|
||||||
|
<< "- expansion ratio ('expansionRatio')" << endl;
|
||||||
|
}
|
||||||
|
finalLayerThickness = readScalar
|
||||||
|
(
|
||||||
|
dict.lookup("finalLayerThickness")
|
||||||
|
);
|
||||||
|
expansionRatio = readScalar(dict.lookup("expansionRatio"));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TOTAL_AND_EXPANSION:
|
||||||
|
if (verbose)
|
||||||
|
{
|
||||||
|
Info<< "Layer specification as" << nl
|
||||||
|
<< "- overall thickness ('thickness')" << nl
|
||||||
|
<< "- expansion ratio ('expansionRatio')" << endl;
|
||||||
|
}
|
||||||
|
thickness = readScalar(dict.lookup("thickness"));
|
||||||
|
expansionRatio = readScalar(dict.lookup("expansionRatio"));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FIRST_AND_RELATIVE_FINAL:
|
||||||
|
if (verbose)
|
||||||
|
{
|
||||||
|
Info<< "Layer specification as" << nl
|
||||||
|
<< "- absolute first layer thickness"
|
||||||
|
<< " ('firstLayerThickness')"
|
||||||
|
<< nl
|
||||||
|
<< "- and final layer thickness"
|
||||||
|
<< " ('finalLayerThickness')" << nl
|
||||||
|
<< endl;
|
||||||
|
}
|
||||||
|
firstLayerThickness = readScalar
|
||||||
|
(
|
||||||
|
dict.lookup("firstLayerThickness")
|
||||||
|
);
|
||||||
|
finalLayerThickness = readScalar
|
||||||
|
(
|
||||||
|
dict.lookup("finalLayerThickness")
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
FatalIOErrorIn
|
||||||
|
(
|
||||||
|
"layerParameters::layerParameters(..)",
|
||||||
|
dict
|
||||||
|
) << "problem." << exit(FatalIOError);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::layerParameters::calculateLayerParameters
|
||||||
|
(
|
||||||
|
const thicknessModelType& spec,
|
||||||
|
const label nLayers,
|
||||||
|
scalar& firstThickness,
|
||||||
|
scalar& finalThickness,
|
||||||
|
scalar& thickness,
|
||||||
|
scalar& expansionRatio
|
||||||
|
)
|
||||||
|
{
|
||||||
|
// Calculate the non-read parameters
|
||||||
|
switch (spec)
|
||||||
|
{
|
||||||
|
case FIRST_AND_TOTAL:
|
||||||
|
expansionRatio = layerExpansionRatio
|
||||||
|
(
|
||||||
|
spec,
|
||||||
|
nLayers,
|
||||||
|
firstThickness,
|
||||||
|
VGREAT,
|
||||||
|
thickness, //totalThickness
|
||||||
|
VGREAT //expansionRatio
|
||||||
|
);
|
||||||
|
finalThickness =
|
||||||
|
thickness
|
||||||
|
*finalLayerThicknessRatio(nLayers, expansionRatio);
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FIRST_AND_EXPANSION:
|
||||||
|
thickness = layerThickness
|
||||||
|
(
|
||||||
|
spec,
|
||||||
|
nLayers,
|
||||||
|
firstThickness, //firstThickness
|
||||||
|
VGREAT, //finalThickness
|
||||||
|
VGREAT, //totalThickness
|
||||||
|
expansionRatio //expansionRatio
|
||||||
|
);
|
||||||
|
finalThickness =
|
||||||
|
thickness
|
||||||
|
*finalLayerThicknessRatio(nLayers, expansionRatio);
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FINAL_AND_TOTAL:
|
||||||
|
firstThickness = firstLayerThickness
|
||||||
|
(
|
||||||
|
spec,
|
||||||
|
nLayers,
|
||||||
|
VGREAT, //firstThickness
|
||||||
|
VGREAT, //finalThickness
|
||||||
|
thickness, //totalThickness
|
||||||
|
VGREAT //expansionRatio
|
||||||
|
);
|
||||||
|
expansionRatio = layerExpansionRatio
|
||||||
|
(
|
||||||
|
spec,
|
||||||
|
nLayers,
|
||||||
|
VGREAT, //firstThickness
|
||||||
|
finalThickness, //finalThickness
|
||||||
|
thickness, //totalThickness
|
||||||
|
VGREAT //expansionRatio
|
||||||
|
);
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FINAL_AND_EXPANSION:
|
||||||
|
firstThickness = firstLayerThickness
|
||||||
|
(
|
||||||
|
spec,
|
||||||
|
nLayers,
|
||||||
|
VGREAT, //firstThickness
|
||||||
|
finalThickness, //finalThickness
|
||||||
|
VGREAT, //thickness
|
||||||
|
expansionRatio //expansionRatio
|
||||||
|
);
|
||||||
|
thickness = layerThickness
|
||||||
|
(
|
||||||
|
spec,
|
||||||
|
nLayers,
|
||||||
|
VGREAT, //firstThickness
|
||||||
|
finalThickness, //finalThickness
|
||||||
|
VGREAT, //totalThickness
|
||||||
|
expansionRatio //expansionRatio
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TOTAL_AND_EXPANSION:
|
||||||
|
firstThickness = firstLayerThickness
|
||||||
|
(
|
||||||
|
spec,
|
||||||
|
nLayers,
|
||||||
|
VGREAT, //firstThickness
|
||||||
|
finalThickness, //finalThickness
|
||||||
|
VGREAT, //thickness
|
||||||
|
expansionRatio //expansionRatio
|
||||||
|
);
|
||||||
|
finalThickness =
|
||||||
|
thickness
|
||||||
|
*finalLayerThicknessRatio(nLayers, expansionRatio);
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FIRST_AND_RELATIVE_FINAL:
|
||||||
|
thickness = layerThickness
|
||||||
|
(
|
||||||
|
spec,
|
||||||
|
nLayers,
|
||||||
|
firstThickness, //firstThickness
|
||||||
|
finalThickness, //finalThickness
|
||||||
|
VGREAT, //totalThickness
|
||||||
|
VGREAT //expansionRatio
|
||||||
|
);
|
||||||
|
expansionRatio = layerExpansionRatio
|
||||||
|
(
|
||||||
|
spec,
|
||||||
|
nLayers,
|
||||||
|
firstThickness, //firstThickness
|
||||||
|
finalThickness, //finalThickness
|
||||||
|
VGREAT, //totalThickness
|
||||||
|
VGREAT //expansionRatio
|
||||||
|
);
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
FatalErrorInFunction << "Illegal thicknessModel " << spec
|
||||||
|
<< exit(FatalError);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
Foam::layerParameters::layerParameters
|
Foam::layerParameters::layerParameters
|
||||||
@ -105,10 +366,13 @@ Foam::layerParameters::layerParameters
|
|||||||
:
|
:
|
||||||
dict_(dict),
|
dict_(dict),
|
||||||
dryRun_(dryRun),
|
dryRun_(dryRun),
|
||||||
relativeSizes_(meshRefinement::get<bool>(dict, "relativeSizes", dryRun)),
|
|
||||||
additionalReporting_(dict.getOrDefault("additionalReporting", false)),
|
|
||||||
layerSpec_(ILLEGAL),
|
|
||||||
numLayers_(boundaryMesh.size(), -1),
|
numLayers_(boundaryMesh.size(), -1),
|
||||||
|
relativeSizes_
|
||||||
|
(
|
||||||
|
boundaryMesh.size(),
|
||||||
|
meshRefinement::get<bool>(dict, "relativeSizes", dryRun)
|
||||||
|
),
|
||||||
|
layerModels_(boundaryMesh.size(), FIRST_AND_TOTAL),
|
||||||
firstLayerThickness_(boundaryMesh.size(), -123),
|
firstLayerThickness_(boundaryMesh.size(), -123),
|
||||||
finalLayerThickness_(boundaryMesh.size(), -123),
|
finalLayerThickness_(boundaryMesh.size(), -123),
|
||||||
thickness_(boundaryMesh.size(), -123),
|
thickness_(boundaryMesh.size(), -123),
|
||||||
@ -142,6 +406,7 @@ Foam::layerParameters::layerParameters
|
|||||||
),
|
),
|
||||||
nLayerIter_(meshRefinement::get<label>(dict, "nLayerIter", dryRun)),
|
nLayerIter_(meshRefinement::get<label>(dict, "nLayerIter", dryRun)),
|
||||||
nRelaxedIter_(labelMax),
|
nRelaxedIter_(labelMax),
|
||||||
|
additionalReporting_(dict.getOrDefault("additionalReporting", false)),
|
||||||
meshShrinker_
|
meshShrinker_
|
||||||
(
|
(
|
||||||
dict.getOrDefault
|
dict.getOrDefault
|
||||||
@ -153,100 +418,112 @@ Foam::layerParameters::layerParameters
|
|||||||
{
|
{
|
||||||
// Detect layer specification mode
|
// Detect layer specification mode
|
||||||
|
|
||||||
label nSpec = 0;
|
word spec;
|
||||||
|
if (dict.readIfPresent("thicknessModel", spec))
|
||||||
|
{
|
||||||
|
layerModels_ = thicknessModelTypeNames_[spec];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Count number of specifications
|
||||||
|
label nSpec = 0;
|
||||||
|
|
||||||
bool haveFirst = dict.found("firstLayerThickness");
|
bool haveFirst = dict.found("firstLayerThickness");
|
||||||
if (haveFirst)
|
if (haveFirst)
|
||||||
{
|
{
|
||||||
firstLayerThickness_ = scalarField
|
nSpec++;
|
||||||
(
|
}
|
||||||
boundaryMesh.size(),
|
bool haveFinal = dict.found("finalLayerThickness");
|
||||||
dict.get<scalar>("firstLayerThickness")
|
if (haveFinal)
|
||||||
);
|
{
|
||||||
nSpec++;
|
nSpec++;
|
||||||
}
|
}
|
||||||
bool haveFinal = dict.found("finalLayerThickness");
|
bool haveTotal = dict.found("thickness");
|
||||||
if (haveFinal)
|
if (haveTotal)
|
||||||
{
|
{
|
||||||
finalLayerThickness_ = scalarField
|
nSpec++;
|
||||||
(
|
}
|
||||||
boundaryMesh.size(),
|
bool haveExp = dict.found("expansionRatio");
|
||||||
dict.get<scalar>("finalLayerThickness")
|
if (haveExp)
|
||||||
);
|
{
|
||||||
nSpec++;
|
nSpec++;
|
||||||
}
|
}
|
||||||
bool haveTotal = dict.found("thickness");
|
|
||||||
if (haveTotal)
|
if (nSpec == 2 && haveFirst && haveTotal)
|
||||||
{
|
{
|
||||||
thickness_ = scalarField
|
layerModels_ = FIRST_AND_TOTAL;
|
||||||
(
|
//Info<< "Layer thickness specified as first layer"
|
||||||
boundaryMesh.size(),
|
// << " and overall thickness." << endl;
|
||||||
dict.get<scalar>("thickness")
|
}
|
||||||
);
|
else if (nSpec == 2 && haveFirst && haveExp)
|
||||||
nSpec++;
|
{
|
||||||
}
|
layerModels_ = FIRST_AND_EXPANSION;
|
||||||
bool haveExp = dict.found("expansionRatio");
|
//Info<< "Layer thickness specified as first layer"
|
||||||
if (haveExp)
|
// << " and expansion ratio." << endl;
|
||||||
{
|
}
|
||||||
expansionRatio_ = scalarField
|
else if (nSpec == 2 && haveFinal && haveTotal)
|
||||||
(
|
{
|
||||||
boundaryMesh.size(),
|
layerModels_ = FINAL_AND_TOTAL;
|
||||||
dict.get<scalar>("expansionRatio")
|
//Info<< "Layer thickness specified as final layer"
|
||||||
);
|
// << " and overall thickness." << endl;
|
||||||
nSpec++;
|
}
|
||||||
|
else if (nSpec == 2 && haveFinal && haveExp)
|
||||||
|
{
|
||||||
|
layerModels_ = FINAL_AND_EXPANSION;
|
||||||
|
//Info<< "Layer thickness specified as final layer"
|
||||||
|
// << " and expansion ratio." << endl;
|
||||||
|
}
|
||||||
|
else if (nSpec == 2 && haveTotal && haveExp)
|
||||||
|
{
|
||||||
|
layerModels_ = TOTAL_AND_EXPANSION;
|
||||||
|
//Info<< "Layer thickness specified as overall thickness"
|
||||||
|
// << " and expansion ratio." << endl;
|
||||||
|
}
|
||||||
|
else if (nSpec == 2 && haveFirst && haveFinal)
|
||||||
|
{
|
||||||
|
layerModels_ = FIRST_AND_RELATIVE_FINAL;
|
||||||
|
//Info<< "Layer thickness specified as absolute first and"
|
||||||
|
// << " relative final layer ratio." << endl;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
FatalIOErrorInFunction(dict)
|
||||||
|
<< "Over- or underspecified layer thickness."
|
||||||
|
<< " Please specify" << nl
|
||||||
|
<< " first layer thickness ('firstLayerThickness')"
|
||||||
|
<< " and overall thickness ('thickness') or" << nl
|
||||||
|
<< " first layer thickness ('firstLayerThickness')"
|
||||||
|
<< " and expansion ratio ('expansionRatio') or" << nl
|
||||||
|
<< " final layer thickness ('finalLayerThickness')"
|
||||||
|
<< " and expansion ratio ('expansionRatio') or" << nl
|
||||||
|
<< " final layer thickness ('finalLayerThickness')"
|
||||||
|
<< " and overall thickness ('thickness') or" << nl
|
||||||
|
<< " overall thickness ('thickness')"
|
||||||
|
<< " and expansion ratio ('expansionRatio'"
|
||||||
|
<< exit(FatalIOError);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (haveFirst && haveTotal)
|
// Now we have determined the layer-specification read the actual fields
|
||||||
{
|
scalar firstThickness;
|
||||||
layerSpec_ = FIRST_AND_TOTAL;
|
scalar finalThickness;
|
||||||
Info<< "Layer thickness specified as first layer and overall thickness."
|
scalar thickness;
|
||||||
<< endl;
|
scalar expansionRatio;
|
||||||
}
|
readLayerParameters
|
||||||
else if (haveFirst && haveExp)
|
(
|
||||||
{
|
true, // verbose
|
||||||
layerSpec_ = FIRST_AND_EXPANSION;
|
dict,
|
||||||
Info<< "Layer thickness specified as first layer and expansion ratio."
|
layerModels_[0], // spec
|
||||||
<< endl;
|
firstThickness,
|
||||||
}
|
finalThickness,
|
||||||
else if (haveFinal && haveTotal)
|
thickness,
|
||||||
{
|
expansionRatio
|
||||||
layerSpec_ = FINAL_AND_TOTAL;
|
);
|
||||||
Info<< "Layer thickness specified as final layer and overall thickness."
|
firstLayerThickness_ = firstThickness;
|
||||||
<< endl;
|
finalLayerThickness_ = finalThickness;
|
||||||
}
|
thickness_ = thickness;
|
||||||
else if (haveFinal && haveExp)
|
expansionRatio_ = expansionRatio;
|
||||||
{
|
|
||||||
layerSpec_ = FINAL_AND_EXPANSION;
|
|
||||||
Info<< "Layer thickness specified as final layer and expansion ratio."
|
|
||||||
<< endl;
|
|
||||||
}
|
|
||||||
else if (haveTotal && haveExp)
|
|
||||||
{
|
|
||||||
layerSpec_ = TOTAL_AND_EXPANSION;
|
|
||||||
Info<< "Layer thickness specified as overall thickness"
|
|
||||||
<< " and expansion ratio." << endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if (layerSpec_ == ILLEGAL || nSpec != 2)
|
|
||||||
{
|
|
||||||
FatalIOErrorInFunction(dict)
|
|
||||||
<< "Over- or underspecified layer thickness."
|
|
||||||
<< " Please specify" << nl
|
|
||||||
<< " first layer thickness ('firstLayerThickness')"
|
|
||||||
<< " and overall thickness ('thickness') or" << nl
|
|
||||||
<< " first layer thickness ('firstLayerThickness')"
|
|
||||||
<< " and expansion ratio ('expansionRatio') or" << nl
|
|
||||||
<< " final layer thickness ('finalLayerThickness')"
|
|
||||||
<< " and expansion ratio ('expansionRatio') or" << nl
|
|
||||||
<< " final layer thickness ('finalLayerThickness')"
|
|
||||||
<< " and overall thickness ('thickness') or" << nl
|
|
||||||
<< " overall thickness ('thickness')"
|
|
||||||
<< " and expansion ratio ('expansionRatio'"
|
|
||||||
<< exit(FatalIOError);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
dict.readIfPresent("nRelaxedIter", nRelaxedIter_);
|
dict.readIfPresent("nRelaxedIter", nRelaxedIter_);
|
||||||
|
|
||||||
@ -293,88 +570,147 @@ Foam::layerParameters::layerParameters
|
|||||||
numLayers_[patchi] =
|
numLayers_[patchi] =
|
||||||
layerDict.get<label>("nSurfaceLayers");
|
layerDict.get<label>("nSurfaceLayers");
|
||||||
|
|
||||||
switch (layerSpec_)
|
word spec;
|
||||||
|
if (layerDict.readIfPresent("thicknessModel", spec))
|
||||||
{
|
{
|
||||||
case FIRST_AND_TOTAL:
|
// If the thickness model is explicitly specified
|
||||||
layerDict.readIfPresent
|
// we want full specification of all parameters
|
||||||
(
|
layerModels_[patchi] = thicknessModelTypeNames_[spec];
|
||||||
"firstLayerThickness",
|
readLayerParameters
|
||||||
firstLayerThickness_[patchi]
|
(
|
||||||
);
|
false, // verbose
|
||||||
layerDict.readIfPresent
|
layerDict,
|
||||||
(
|
layerModels_[patchi], // spec
|
||||||
"thickness",
|
firstLayerThickness_[patchi],
|
||||||
thickness_[patchi]
|
finalLayerThickness_[patchi],
|
||||||
);
|
thickness_[patchi],
|
||||||
break;
|
expansionRatio_[patchi]
|
||||||
|
);
|
||||||
|
minThickness_[patchi] = readScalar
|
||||||
|
(
|
||||||
|
layerDict.lookup("minThickness")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Optional override of thickness parameters
|
||||||
|
switch (layerModels_[patchi])
|
||||||
|
{
|
||||||
|
case FIRST_AND_TOTAL:
|
||||||
|
layerDict.readIfPresent
|
||||||
|
(
|
||||||
|
"firstLayerThickness",
|
||||||
|
firstLayerThickness_[patchi]
|
||||||
|
);
|
||||||
|
layerDict.readIfPresent
|
||||||
|
(
|
||||||
|
"thickness",
|
||||||
|
thickness_[patchi]
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
|
||||||
case FIRST_AND_EXPANSION:
|
case FIRST_AND_EXPANSION:
|
||||||
layerDict.readIfPresent
|
layerDict.readIfPresent
|
||||||
(
|
(
|
||||||
"firstLayerThickness",
|
"firstLayerThickness",
|
||||||
firstLayerThickness_[patchi]
|
firstLayerThickness_[patchi]
|
||||||
);
|
);
|
||||||
layerDict.readIfPresent
|
layerDict.readIfPresent
|
||||||
(
|
(
|
||||||
"expansionRatio",
|
"expansionRatio",
|
||||||
expansionRatio_[patchi]
|
expansionRatio_[patchi]
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FINAL_AND_TOTAL:
|
case FINAL_AND_TOTAL:
|
||||||
layerDict.readIfPresent
|
layerDict.readIfPresent
|
||||||
(
|
(
|
||||||
"finalLayerThickness",
|
"finalLayerThickness",
|
||||||
finalLayerThickness_[patchi]
|
finalLayerThickness_[patchi]
|
||||||
);
|
);
|
||||||
layerDict.readIfPresent
|
layerDict.readIfPresent
|
||||||
(
|
(
|
||||||
"thickness",
|
"thickness",
|
||||||
thickness_[patchi]
|
thickness_[patchi]
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FINAL_AND_EXPANSION:
|
case FINAL_AND_EXPANSION:
|
||||||
layerDict.readIfPresent
|
layerDict.readIfPresent
|
||||||
(
|
(
|
||||||
"finalLayerThickness",
|
"finalLayerThickness",
|
||||||
finalLayerThickness_[patchi]
|
finalLayerThickness_[patchi]
|
||||||
);
|
);
|
||||||
layerDict.readIfPresent
|
layerDict.readIfPresent
|
||||||
(
|
(
|
||||||
"expansionRatio",
|
"expansionRatio",
|
||||||
expansionRatio_[patchi]
|
expansionRatio_[patchi]
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TOTAL_AND_EXPANSION:
|
case TOTAL_AND_EXPANSION:
|
||||||
layerDict.readIfPresent
|
layerDict.readIfPresent
|
||||||
(
|
(
|
||||||
"thickness",
|
"thickness",
|
||||||
thickness_[patchi]
|
thickness_[patchi]
|
||||||
);
|
);
|
||||||
layerDict.readIfPresent
|
layerDict.readIfPresent
|
||||||
(
|
(
|
||||||
"expansionRatio",
|
"expansionRatio",
|
||||||
expansionRatio_[patchi]
|
expansionRatio_[patchi]
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
case FIRST_AND_RELATIVE_FINAL:
|
||||||
FatalIOErrorInFunction(dict)
|
layerDict.readIfPresent
|
||||||
<< "problem." << exit(FatalIOError);
|
(
|
||||||
break;
|
"firstLayerThickness",
|
||||||
|
firstLayerThickness_[patchi]
|
||||||
|
);
|
||||||
|
layerDict.readIfPresent
|
||||||
|
(
|
||||||
|
"finalLayerThickness",
|
||||||
|
finalLayerThickness_[patchi]
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
FatalIOErrorInFunction(dict)
|
||||||
|
<< "problem." << exit(FatalIOError);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
layerDict.readIfPresent
|
||||||
|
(
|
||||||
|
"minThickness",
|
||||||
|
minThickness_[patchi]
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
layerDict.readIfPresent
|
layerDict.readIfPresent
|
||||||
(
|
(
|
||||||
"minThickness",
|
"relativeSizes",
|
||||||
minThickness_[patchi]
|
relativeSizes_[patchi]
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
forAll(numLayers_, patchi)
|
||||||
|
{
|
||||||
|
// Calculate the remaining parameters
|
||||||
|
calculateLayerParameters
|
||||||
|
(
|
||||||
|
layerModels_[patchi],
|
||||||
|
numLayers_[patchi],
|
||||||
|
firstLayerThickness_[patchi],
|
||||||
|
finalLayerThickness_[patchi],
|
||||||
|
thickness_[patchi],
|
||||||
|
expansionRatio_[patchi]
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -382,14 +718,15 @@ Foam::layerParameters::layerParameters
|
|||||||
|
|
||||||
Foam::scalar Foam::layerParameters::layerThickness
|
Foam::scalar Foam::layerParameters::layerThickness
|
||||||
(
|
(
|
||||||
|
const thicknessModelType layerSpec,
|
||||||
const label nLayers,
|
const label nLayers,
|
||||||
const scalar firstLayerThickess,
|
const scalar firstLayerThickness,
|
||||||
const scalar finalLayerThickess,
|
const scalar finalLayerThickness,
|
||||||
const scalar totalThickness,
|
const scalar totalThickness,
|
||||||
const scalar expansionRatio
|
const scalar expansionRatio
|
||||||
) const
|
)
|
||||||
{
|
{
|
||||||
switch (layerSpec_)
|
switch (layerSpec)
|
||||||
{
|
{
|
||||||
case FIRST_AND_TOTAL:
|
case FIRST_AND_TOTAL:
|
||||||
case FINAL_AND_TOTAL:
|
case FINAL_AND_TOTAL:
|
||||||
@ -403,11 +740,11 @@ Foam::scalar Foam::layerParameters::layerThickness
|
|||||||
{
|
{
|
||||||
if (mag(expansionRatio-1) < SMALL)
|
if (mag(expansionRatio-1) < SMALL)
|
||||||
{
|
{
|
||||||
return firstLayerThickess * nLayers;
|
return firstLayerThickness * nLayers;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return firstLayerThickess
|
return firstLayerThickness
|
||||||
*(1.0 - pow(expansionRatio, nLayers))
|
*(1.0 - pow(expansionRatio, nLayers))
|
||||||
/(1.0 - expansionRatio);
|
/(1.0 - expansionRatio);
|
||||||
}
|
}
|
||||||
@ -418,22 +755,54 @@ Foam::scalar Foam::layerParameters::layerThickness
|
|||||||
{
|
{
|
||||||
if (mag(expansionRatio-1) < SMALL)
|
if (mag(expansionRatio-1) < SMALL)
|
||||||
{
|
{
|
||||||
return finalLayerThickess * nLayers;
|
return finalLayerThickness * nLayers;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
scalar invExpansion = 1.0 / expansionRatio;
|
scalar invExpansion = 1.0 / expansionRatio;
|
||||||
return finalLayerThickess
|
return finalLayerThickness
|
||||||
*(1.0 - pow(invExpansion, nLayers))
|
*(1.0 - pow(invExpansion, nLayers))
|
||||||
/(1.0 - invExpansion);
|
/(1.0 - invExpansion);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case FIRST_AND_RELATIVE_FINAL:
|
||||||
|
{
|
||||||
|
if (mag(expansionRatio-1) < SMALL)
|
||||||
|
{
|
||||||
|
return firstLayerThickness * nLayers;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
scalar ratio = layerExpansionRatio
|
||||||
|
(
|
||||||
|
layerSpec,
|
||||||
|
nLayers,
|
||||||
|
firstLayerThickness,
|
||||||
|
finalLayerThickness,
|
||||||
|
totalThickness,
|
||||||
|
expansionRatio
|
||||||
|
);
|
||||||
|
|
||||||
|
if (mag(ratio-1) < SMALL)
|
||||||
|
{
|
||||||
|
return firstLayerThickness * nLayers;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return firstLayerThickness *
|
||||||
|
(1.0 - pow(ratio, nLayers))
|
||||||
|
/ (1.0 - ratio);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
FatalErrorInFunction
|
FatalErrorInFunction
|
||||||
<< exit(FatalError);
|
<< layerSpec << exit(FatalError);
|
||||||
return -VGREAT;
|
return -VGREAT;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -442,14 +811,15 @@ Foam::scalar Foam::layerParameters::layerThickness
|
|||||||
|
|
||||||
Foam::scalar Foam::layerParameters::layerExpansionRatio
|
Foam::scalar Foam::layerParameters::layerExpansionRatio
|
||||||
(
|
(
|
||||||
|
const thicknessModelType layerSpec,
|
||||||
const label nLayers,
|
const label nLayers,
|
||||||
const scalar firstLayerThickess,
|
const scalar firstLayerThickness,
|
||||||
const scalar finalLayerThickess,
|
const scalar finalLayerThickness,
|
||||||
const scalar totalThickness,
|
const scalar totalThickness,
|
||||||
const scalar expansionRatio
|
const scalar expansionRatio
|
||||||
) const
|
)
|
||||||
{
|
{
|
||||||
switch (layerSpec_)
|
switch (layerSpec)
|
||||||
{
|
{
|
||||||
case FIRST_AND_EXPANSION:
|
case FIRST_AND_EXPANSION:
|
||||||
case FINAL_AND_EXPANSION:
|
case FINAL_AND_EXPANSION:
|
||||||
@ -461,23 +831,58 @@ Foam::scalar Foam::layerParameters::layerExpansionRatio
|
|||||||
|
|
||||||
case FIRST_AND_TOTAL:
|
case FIRST_AND_TOTAL:
|
||||||
{
|
{
|
||||||
return layerExpansionRatio
|
if (firstLayerThickness < SMALL)
|
||||||
(
|
{
|
||||||
nLayers,
|
// Do what?
|
||||||
totalThickness/firstLayerThickess
|
return 1;
|
||||||
);
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return layerExpansionRatio
|
||||||
|
(
|
||||||
|
nLayers,
|
||||||
|
totalThickness/firstLayerThickness
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FINAL_AND_TOTAL:
|
case FINAL_AND_TOTAL:
|
||||||
{
|
{
|
||||||
return
|
if (finalLayerThickness < SMALL)
|
||||||
1.0
|
{
|
||||||
/layerExpansionRatio
|
// Do what?
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return
|
||||||
|
1.0
|
||||||
|
/ layerExpansionRatio
|
||||||
|
(
|
||||||
|
nLayers,
|
||||||
|
totalThickness/finalLayerThickness
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FIRST_AND_RELATIVE_FINAL:
|
||||||
|
{
|
||||||
|
if (firstLayerThickness < SMALL || nLayers <= 1)
|
||||||
|
{
|
||||||
|
return 1.0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Note: at this point the finalLayerThickness is already
|
||||||
|
// absolute
|
||||||
|
return pow
|
||||||
(
|
(
|
||||||
nLayers,
|
finalLayerThickness/firstLayerThickness,
|
||||||
totalThickness/finalLayerThickess
|
1.0/(nLayers-1)
|
||||||
);
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -493,24 +898,34 @@ Foam::scalar Foam::layerParameters::layerExpansionRatio
|
|||||||
|
|
||||||
Foam::scalar Foam::layerParameters::firstLayerThickness
|
Foam::scalar Foam::layerParameters::firstLayerThickness
|
||||||
(
|
(
|
||||||
|
const thicknessModelType layerSpec,
|
||||||
const label nLayers,
|
const label nLayers,
|
||||||
const scalar firstLayerThickess,
|
const scalar firstLayerThickness,
|
||||||
const scalar finalLayerThickess,
|
const scalar finalLayerThickness,
|
||||||
const scalar totalThickness,
|
const scalar totalThickness,
|
||||||
const scalar expansionRatio
|
const scalar expansionRatio
|
||||||
) const
|
)
|
||||||
{
|
{
|
||||||
switch (layerSpec_)
|
switch (layerSpec)
|
||||||
{
|
{
|
||||||
case FIRST_AND_EXPANSION:
|
case FIRST_AND_EXPANSION:
|
||||||
case FIRST_AND_TOTAL:
|
case FIRST_AND_TOTAL:
|
||||||
|
case FIRST_AND_RELATIVE_FINAL:
|
||||||
{
|
{
|
||||||
return firstLayerThickess;
|
return firstLayerThickness;
|
||||||
}
|
}
|
||||||
|
|
||||||
case FINAL_AND_EXPANSION:
|
case FINAL_AND_EXPANSION:
|
||||||
{
|
{
|
||||||
return finalLayerThickess*pow(1.0/expansionRatio, nLayers-1);
|
if (expansionRatio < SMALL)
|
||||||
|
{
|
||||||
|
// Do what?
|
||||||
|
return 0.0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return finalLayerThickness*pow(1.0/expansionRatio, nLayers-1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -518,13 +933,14 @@ Foam::scalar Foam::layerParameters::firstLayerThickness
|
|||||||
{
|
{
|
||||||
scalar r = layerExpansionRatio
|
scalar r = layerExpansionRatio
|
||||||
(
|
(
|
||||||
|
layerSpec,
|
||||||
nLayers,
|
nLayers,
|
||||||
firstLayerThickess,
|
firstLayerThickness,
|
||||||
finalLayerThickess,
|
finalLayerThickness,
|
||||||
totalThickness,
|
totalThickness,
|
||||||
expansionRatio
|
expansionRatio
|
||||||
);
|
);
|
||||||
return finalLayerThickess/pow(r, nLayers-1);
|
return finalLayerThickness/pow(r, nLayers-1);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -554,7 +970,7 @@ Foam::scalar Foam::layerParameters::finalLayerThicknessRatio
|
|||||||
(
|
(
|
||||||
const label nLayers,
|
const label nLayers,
|
||||||
const scalar expansionRatio
|
const scalar expansionRatio
|
||||||
) const
|
)
|
||||||
{
|
{
|
||||||
if (nLayers > 0)
|
if (nLayers > 0)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -41,6 +41,7 @@ SourceFiles
|
|||||||
#include "scalarField.H"
|
#include "scalarField.H"
|
||||||
#include "labelList.H"
|
#include "labelList.H"
|
||||||
#include "Switch.H"
|
#include "Switch.H"
|
||||||
|
#include "Enum.H"
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
@ -67,14 +68,14 @@ public:
|
|||||||
// - final and total thickness specified
|
// - final and total thickness specified
|
||||||
// - final and expansion ratio specified
|
// - final and expansion ratio specified
|
||||||
// - total thickness and expansion ratio specified
|
// - total thickness and expansion ratio specified
|
||||||
enum layerSpecification
|
enum thicknessModelType
|
||||||
{
|
{
|
||||||
ILLEGAL,
|
|
||||||
FIRST_AND_TOTAL,
|
FIRST_AND_TOTAL,
|
||||||
FIRST_AND_EXPANSION,
|
FIRST_AND_EXPANSION,
|
||||||
FINAL_AND_TOTAL,
|
FINAL_AND_TOTAL,
|
||||||
FINAL_AND_EXPANSION,
|
FINAL_AND_EXPANSION,
|
||||||
TOTAL_AND_EXPANSION
|
TOTAL_AND_EXPANSION,
|
||||||
|
FIRST_AND_RELATIVE_FINAL
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -85,6 +86,9 @@ private:
|
|||||||
//- Default angle for faces to be concave
|
//- Default angle for faces to be concave
|
||||||
static const scalar defaultConcaveAngle;
|
static const scalar defaultConcaveAngle;
|
||||||
|
|
||||||
|
//- thicknessModelType names
|
||||||
|
static const Enum<thicknessModelType> thicknessModelTypeNames_;
|
||||||
|
|
||||||
|
|
||||||
// Private Data
|
// Private Data
|
||||||
|
|
||||||
@ -93,28 +97,25 @@ private:
|
|||||||
//- In dry-run mode?
|
//- In dry-run mode?
|
||||||
const bool dryRun_;
|
const bool dryRun_;
|
||||||
|
|
||||||
//- Are sizes relative to local cell size
|
|
||||||
bool relativeSizes_;
|
|
||||||
|
|
||||||
//- Any additional reporting
|
|
||||||
bool additionalReporting_;
|
|
||||||
|
|
||||||
|
|
||||||
// Per patch (not region!) information
|
// Per patch (not region!) information
|
||||||
|
|
||||||
//- How thickness is specified.
|
|
||||||
layerSpecification layerSpec_;
|
|
||||||
|
|
||||||
//- How many layers to add.
|
//- How many layers to add.
|
||||||
labelList numLayers_;
|
labelList numLayers_;
|
||||||
|
|
||||||
scalarField firstLayerThickness_;
|
//- Are sizes relative to local cell size
|
||||||
|
boolList relativeSizes_;
|
||||||
|
|
||||||
scalarField finalLayerThickness_;
|
//- How thickness is specified.
|
||||||
|
List<thicknessModelType> layerModels_;
|
||||||
|
|
||||||
scalarField thickness_;
|
scalarField firstLayerThickness_;
|
||||||
|
|
||||||
scalarField expansionRatio_;
|
scalarField finalLayerThickness_;
|
||||||
|
|
||||||
|
scalarField thickness_;
|
||||||
|
|
||||||
|
scalarField expansionRatio_;
|
||||||
|
|
||||||
//- Minimum total thickness
|
//- Minimum total thickness
|
||||||
scalarField minThickness_;
|
scalarField minThickness_;
|
||||||
@ -136,6 +137,9 @@ private:
|
|||||||
|
|
||||||
label nRelaxedIter_;
|
label nRelaxedIter_;
|
||||||
|
|
||||||
|
//- Any additional reporting
|
||||||
|
bool additionalReporting_;
|
||||||
|
|
||||||
word meshShrinker_;
|
word meshShrinker_;
|
||||||
|
|
||||||
|
|
||||||
@ -143,11 +147,33 @@ private:
|
|||||||
|
|
||||||
//- Calculate expansion ratio from overall size v.s. thickness of
|
//- Calculate expansion ratio from overall size v.s. thickness of
|
||||||
// first layer.
|
// first layer.
|
||||||
scalar layerExpansionRatio
|
static scalar layerExpansionRatio
|
||||||
(
|
(
|
||||||
const label n,
|
const label n,
|
||||||
const scalar totalOverFirst
|
const scalar totalOverFirst
|
||||||
) const;
|
);
|
||||||
|
|
||||||
|
//- Read parameters according to thickness model
|
||||||
|
static void readLayerParameters
|
||||||
|
(
|
||||||
|
const bool verbose,
|
||||||
|
const dictionary&,
|
||||||
|
const thicknessModelType& spec,
|
||||||
|
scalar& firstLayerThickness,
|
||||||
|
scalar& finalLayerThickness,
|
||||||
|
scalar& thickness,
|
||||||
|
scalar& expansionRatio
|
||||||
|
);
|
||||||
|
|
||||||
|
void calculateLayerParameters
|
||||||
|
(
|
||||||
|
const thicknessModelType& spec,
|
||||||
|
const label nLayers,
|
||||||
|
scalar& firstLayerThickness,
|
||||||
|
scalar& finalLayerThickness,
|
||||||
|
scalar& thickness,
|
||||||
|
scalar& expansionRatio
|
||||||
|
);
|
||||||
|
|
||||||
//- No copy construct
|
//- No copy construct
|
||||||
layerParameters(const layerParameters&) = delete;
|
layerParameters(const layerParameters&) = delete;
|
||||||
@ -191,15 +217,15 @@ public:
|
|||||||
|
|
||||||
//- Are size parameters relative to inner cell size or
|
//- Are size parameters relative to inner cell size or
|
||||||
// absolute distances.
|
// absolute distances.
|
||||||
bool relativeSizes() const
|
const boolList& relativeSizes() const
|
||||||
{
|
{
|
||||||
return relativeSizes_;
|
return relativeSizes_;
|
||||||
}
|
}
|
||||||
|
|
||||||
//- Any additional reporting requested?
|
//- Specification of layer thickness
|
||||||
bool additionalReporting() const
|
const List<thicknessModelType>& layerModels() const
|
||||||
{
|
{
|
||||||
return additionalReporting_;
|
return layerModels_;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Expansion factor for layer mesh
|
// Expansion factor for layer mesh
|
||||||
@ -296,6 +322,12 @@ public:
|
|||||||
return nBufferCellsNoExtrude_;
|
return nBufferCellsNoExtrude_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//- Any additional reporting requested?
|
||||||
|
bool additionalReporting() const
|
||||||
|
{
|
||||||
|
return additionalReporting_;
|
||||||
|
}
|
||||||
|
|
||||||
//- Type of mesh shrinker
|
//- Type of mesh shrinker
|
||||||
const word& meshShrinker() const
|
const word& meshShrinker() const
|
||||||
{
|
{
|
||||||
@ -306,45 +338,48 @@ public:
|
|||||||
// Helper
|
// Helper
|
||||||
|
|
||||||
//- Determine overall thickness. Uses two of the four parameters
|
//- Determine overall thickness. Uses two of the four parameters
|
||||||
// according to the layerSpecification
|
// according to the thicknessModel
|
||||||
scalar layerThickness
|
static scalar layerThickness
|
||||||
(
|
(
|
||||||
|
const thicknessModelType,
|
||||||
const label nLayers,
|
const label nLayers,
|
||||||
const scalar firstLayerThickess,
|
const scalar firstLayerThickness,
|
||||||
const scalar finalLayerThickess,
|
const scalar finalLayerThickness,
|
||||||
const scalar totalThickness,
|
const scalar totalThickness,
|
||||||
const scalar expansionRatio
|
const scalar expansionRatio
|
||||||
) const;
|
);
|
||||||
|
|
||||||
//- Determine expansion ratio. Uses two of the four parameters
|
//- Determine expansion ratio. Uses two of the four parameters
|
||||||
// according to the layerSpecification
|
// according to the thicknessModel
|
||||||
scalar layerExpansionRatio
|
static scalar layerExpansionRatio
|
||||||
(
|
(
|
||||||
|
const thicknessModelType,
|
||||||
const label nLayers,
|
const label nLayers,
|
||||||
const scalar firstLayerThickess,
|
const scalar firstLayerThickness,
|
||||||
const scalar finalLayerThickess,
|
const scalar finalLayerThickness,
|
||||||
const scalar totalThickness,
|
const scalar totalThickness,
|
||||||
const scalar expansionRatio
|
const scalar expansionRatio
|
||||||
) const;
|
);
|
||||||
|
|
||||||
//- Determine first layer (near-wall) thickness. Uses two of the
|
//- Determine first layer (near-wall) thickness. Uses two of the
|
||||||
// four parameters according to the layerSpecification
|
// four parameters according to the thicknessModel
|
||||||
scalar firstLayerThickness
|
static scalar firstLayerThickness
|
||||||
(
|
(
|
||||||
|
const thicknessModelType,
|
||||||
const label nLayers,
|
const label nLayers,
|
||||||
const scalar firstLayerThickess,
|
const scalar firstLayerThickness,
|
||||||
const scalar finalLayerThickess,
|
const scalar finalLayerThickness,
|
||||||
const scalar totalThickness,
|
const scalar totalThickness,
|
||||||
const scalar expansionRatio
|
const scalar expansionRatio
|
||||||
) const;
|
);
|
||||||
|
|
||||||
//- Determine ratio of final layer thickness to
|
//- Determine ratio of final layer thickness to
|
||||||
// overall layer thickness
|
// overall layer thickness
|
||||||
scalar finalLayerThicknessRatio
|
static scalar finalLayerThicknessRatio
|
||||||
(
|
(
|
||||||
const label nLayers,
|
const label nLayers,
|
||||||
const scalar expansionRatio
|
const scalar expansionRatio
|
||||||
) const;
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -820,6 +820,7 @@ void Foam::snappyLayerDriver::handleWarpedFaces
|
|||||||
(
|
(
|
||||||
const indirectPrimitivePatch& pp,
|
const indirectPrimitivePatch& pp,
|
||||||
const scalar faceRatio,
|
const scalar faceRatio,
|
||||||
|
const boolList& relativeSizes,
|
||||||
const scalar edge0Len,
|
const scalar edge0Len,
|
||||||
const labelList& cellLevel,
|
const labelList& cellLevel,
|
||||||
pointField& patchDisp,
|
pointField& patchDisp,
|
||||||
@ -828,6 +829,7 @@ void Foam::snappyLayerDriver::handleWarpedFaces
|
|||||||
) const
|
) const
|
||||||
{
|
{
|
||||||
const fvMesh& mesh = meshRefiner_.mesh();
|
const fvMesh& mesh = meshRefiner_.mesh();
|
||||||
|
const polyBoundaryMesh& patches = mesh.boundaryMesh();
|
||||||
|
|
||||||
Info<< nl << "Handling cells with warped patch faces ..." << nl;
|
Info<< nl << "Handling cells with warped patch faces ..." << nl;
|
||||||
|
|
||||||
@ -838,16 +840,19 @@ void Foam::snappyLayerDriver::handleWarpedFaces
|
|||||||
forAll(pp, i)
|
forAll(pp, i)
|
||||||
{
|
{
|
||||||
const face& f = pp[i];
|
const face& f = pp[i];
|
||||||
|
label faceI = pp.addressing()[i];
|
||||||
|
label patchI = patches.patchID()[faceI-mesh.nInternalFaces()];
|
||||||
|
|
||||||
if (f.size() > 3)
|
// It is hard to calculate some length scale if not in relative
|
||||||
|
// mode so disable this check.
|
||||||
|
|
||||||
|
if (relativeSizes[patchI] && f.size() > 3)
|
||||||
{
|
{
|
||||||
label facei = pp.addressing()[i];
|
label ownLevel = cellLevel[mesh.faceOwner()[faceI]];
|
||||||
|
|
||||||
label ownLevel = cellLevel[mesh.faceOwner()[facei]];
|
|
||||||
scalar edgeLen = edge0Len/(1<<ownLevel);
|
scalar edgeLen = edge0Len/(1<<ownLevel);
|
||||||
|
|
||||||
// Normal distance to face centre plane
|
// Normal distance to face centre plane
|
||||||
const point& fc = mesh.faceCentres()[facei];
|
const point& fc = mesh.faceCentres()[faceI];
|
||||||
const vector& fn = pp.faceNormals()[i];
|
const vector& fn = pp.faceNormals()[i];
|
||||||
|
|
||||||
scalarField vProj(f.size());
|
scalarField vProj(f.size());
|
||||||
@ -1412,10 +1417,14 @@ void Foam::snappyLayerDriver::calculateLayerThickness
|
|||||||
minThickness.setSize(pp.nPoints());
|
minThickness.setSize(pp.nPoints());
|
||||||
minThickness = GREAT;
|
minThickness = GREAT;
|
||||||
|
|
||||||
forAll(patchIDs, i)
|
thickness.setSize(pp.nPoints());
|
||||||
{
|
thickness = GREAT;
|
||||||
label patchi = patchIDs[i];
|
|
||||||
|
|
||||||
|
expansionRatio.setSize(pp.nPoints());
|
||||||
|
expansionRatio = GREAT;
|
||||||
|
|
||||||
|
for (const label patchi : patchIDs)
|
||||||
|
{
|
||||||
const labelList& meshPoints = patches[patchi].meshPoints();
|
const labelList& meshPoints = patches[patchi].meshPoints();
|
||||||
|
|
||||||
forAll(meshPoints, patchPointi)
|
forAll(meshPoints, patchPointi)
|
||||||
@ -1495,32 +1504,11 @@ void Foam::snappyLayerDriver::calculateLayerThickness
|
|||||||
// Now the thicknesses are set according to the minimum of connected
|
// Now the thicknesses are set according to the minimum of connected
|
||||||
// patches.
|
// patches.
|
||||||
|
|
||||||
|
// Determine per point the max cell level of connected cells
|
||||||
|
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
// Rework relative thickness into absolute
|
labelList maxPointLevel(pp.nPoints(), labelMin);
|
||||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
// by multiplying with the internal cell size.
|
|
||||||
|
|
||||||
if (layerParams.relativeSizes())
|
|
||||||
{
|
{
|
||||||
if
|
|
||||||
(
|
|
||||||
min(layerParams.minThickness()) < 0
|
|
||||||
|| max(layerParams.minThickness()) > 2
|
|
||||||
)
|
|
||||||
{
|
|
||||||
FatalErrorInFunction
|
|
||||||
<< "Thickness should be factor of local undistorted cell size."
|
|
||||||
<< " Valid values are [0..2]." << nl
|
|
||||||
<< " minThickness:" << layerParams.minThickness()
|
|
||||||
<< exit(FatalError);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Determine per point the max cell level of connected cells
|
|
||||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
labelList maxPointLevel(pp.nPoints(), labelMin);
|
|
||||||
|
|
||||||
forAll(pp, i)
|
forAll(pp, i)
|
||||||
{
|
{
|
||||||
label ownLevel = cellLevel[mesh.faceOwner()[pp.addressing()[i]]];
|
label ownLevel = cellLevel[mesh.faceOwner()[pp.addressing()[i]]];
|
||||||
@ -1541,44 +1529,149 @@ void Foam::snappyLayerDriver::calculateLayerThickness
|
|||||||
maxEqOp<label>(),
|
maxEqOp<label>(),
|
||||||
labelMin // null value
|
labelMin // null value
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
forAll(maxPointLevel, pointi)
|
// Rework relative thickness into absolute
|
||||||
|
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
// by multiplying with the internal cell size.
|
||||||
|
// Note that we cannot loop over the patches since then points on
|
||||||
|
// multiple patches would get multiplied with edgeLen twice ..
|
||||||
|
{
|
||||||
|
// Multiplication factor for relative sizes
|
||||||
|
scalarField edgeLen(pp.nPoints(), GREAT);
|
||||||
|
|
||||||
|
labelList spec(pp.nPoints(), layerParameters::FIRST_AND_TOTAL);
|
||||||
|
|
||||||
|
bitSet isRelativePoint(mesh.nPoints());
|
||||||
|
|
||||||
|
for (const label patchi : patchIDs)
|
||||||
{
|
{
|
||||||
// Find undistorted edge size for this level.
|
const labelList& meshPoints = patches[patchi].meshPoints();
|
||||||
scalar edgeLen = edge0Len/(1<<maxPointLevel[pointi]);
|
const layerParameters::thicknessModelType patchSpec =
|
||||||
firstLayerThickness[pointi] *= edgeLen;
|
layerParams.layerModels()[patchi];
|
||||||
finalLayerThickness[pointi] *= edgeLen;
|
const bool relSize = layerParams.relativeSizes()[patchi];
|
||||||
totalThickness[pointi] *= edgeLen;
|
|
||||||
minThickness[pointi] *= edgeLen;
|
for (const label meshPointi : meshPoints)
|
||||||
|
{
|
||||||
|
const label ppPointi = pp.meshPointMap()[meshPointi];
|
||||||
|
|
||||||
|
// Note: who wins if different specs?
|
||||||
|
|
||||||
|
// Calculate undistorted edge size for this level.
|
||||||
|
edgeLen[ppPointi] = min
|
||||||
|
(
|
||||||
|
edgeLen[ppPointi],
|
||||||
|
edge0Len/(1<<maxPointLevel[ppPointi])
|
||||||
|
);
|
||||||
|
spec[ppPointi] = max(spec[ppPointi], patchSpec);
|
||||||
|
isRelativePoint[meshPointi] =
|
||||||
|
isRelativePoint[meshPointi]
|
||||||
|
|| relSize;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
syncTools::syncPointList
|
||||||
|
(
|
||||||
|
mesh,
|
||||||
|
pp.meshPoints(),
|
||||||
|
edgeLen,
|
||||||
|
minEqOp<scalar>(),
|
||||||
|
GREAT // null value
|
||||||
|
);
|
||||||
|
syncTools::syncPointList
|
||||||
|
(
|
||||||
|
mesh,
|
||||||
|
pp.meshPoints(),
|
||||||
|
spec,
|
||||||
|
maxEqOp<label>(),
|
||||||
|
label(layerParameters::FIRST_AND_TOTAL) // null value
|
||||||
|
);
|
||||||
|
syncTools::syncPointList
|
||||||
|
(
|
||||||
|
mesh,
|
||||||
|
isRelativePoint,
|
||||||
|
orEqOp<unsigned int>(),
|
||||||
|
0
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
forAll(pp.meshPoints(), pointi)
|
||||||
|
{
|
||||||
|
const label meshPointi = pp.meshPoints()[pointi];
|
||||||
|
const layerParameters::thicknessModelType pointSpec =
|
||||||
|
static_cast<layerParameters::thicknessModelType>(spec[pointi]);
|
||||||
|
|
||||||
|
if (pointSpec == layerParameters::FIRST_AND_RELATIVE_FINAL)
|
||||||
|
{
|
||||||
|
// This overrules the relative sizes flag for
|
||||||
|
// first (always absolute) and final (always relative)
|
||||||
|
finalLayerThickness[pointi] *= edgeLen[pointi];
|
||||||
|
if (isRelativePoint[meshPointi])
|
||||||
|
{
|
||||||
|
totalThickness[pointi] *= edgeLen[pointi];
|
||||||
|
minThickness[pointi] *= edgeLen[pointi];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (isRelativePoint[meshPointi])
|
||||||
|
{
|
||||||
|
firstLayerThickness[pointi] *= edgeLen[pointi];
|
||||||
|
finalLayerThickness[pointi] *= edgeLen[pointi];
|
||||||
|
totalThickness[pointi] *= edgeLen[pointi];
|
||||||
|
minThickness[pointi] *= edgeLen[pointi];
|
||||||
|
}
|
||||||
|
|
||||||
|
thickness[pointi] = min
|
||||||
|
(
|
||||||
|
thickness[pointi],
|
||||||
|
layerParameters::layerThickness
|
||||||
|
(
|
||||||
|
pointSpec,
|
||||||
|
patchNLayers[pointi],
|
||||||
|
firstLayerThickness[pointi],
|
||||||
|
finalLayerThickness[pointi],
|
||||||
|
totalThickness[pointi],
|
||||||
|
expRatio[pointi]
|
||||||
|
)
|
||||||
|
);
|
||||||
|
expansionRatio[pointi] = min
|
||||||
|
(
|
||||||
|
expansionRatio[pointi],
|
||||||
|
layerParameters::layerExpansionRatio
|
||||||
|
(
|
||||||
|
pointSpec,
|
||||||
|
patchNLayers[pointi],
|
||||||
|
firstLayerThickness[pointi],
|
||||||
|
finalLayerThickness[pointi],
|
||||||
|
totalThickness[pointi],
|
||||||
|
expRatio[pointi]
|
||||||
|
)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Synchronise the determined thicknes. Note that this should not be
|
||||||
|
// necessary since the inputs to the calls to layerThickness,
|
||||||
|
// layerExpansionRatio above are already parallel consistent
|
||||||
|
|
||||||
|
syncTools::syncPointList
|
||||||
// Rework thickness parameters into overall thickness
|
(
|
||||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
mesh,
|
||||||
|
pp.meshPoints(),
|
||||||
forAll(firstLayerThickness, pointi)
|
thickness,
|
||||||
{
|
minEqOp<scalar>(),
|
||||||
thickness[pointi] = layerParams.layerThickness
|
GREAT // null value
|
||||||
(
|
);
|
||||||
patchNLayers[pointi],
|
syncTools::syncPointList
|
||||||
firstLayerThickness[pointi],
|
(
|
||||||
finalLayerThickness[pointi],
|
mesh,
|
||||||
totalThickness[pointi],
|
pp.meshPoints(),
|
||||||
expRatio[pointi]
|
expansionRatio,
|
||||||
);
|
minEqOp<scalar>(),
|
||||||
|
GREAT // null value
|
||||||
expansionRatio[pointi] = layerParams.layerExpansionRatio
|
);
|
||||||
(
|
|
||||||
patchNLayers[pointi],
|
|
||||||
firstLayerThickness[pointi],
|
|
||||||
finalLayerThickness[pointi],
|
|
||||||
totalThickness[pointi],
|
|
||||||
expRatio[pointi]
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
//Info<< "calculateLayerThickness : min:" << gMin(thickness)
|
//Info<< "calculateLayerThickness : min:" << gMin(thickness)
|
||||||
// << " max:" << gMax(thickness) << endl;
|
// << " max:" << gMax(thickness) << endl;
|
||||||
@ -1614,6 +1707,8 @@ void Foam::snappyLayerDriver::calculateLayerThickness
|
|||||||
label patchi = patchIDs[i];
|
label patchi = patchIDs[i];
|
||||||
|
|
||||||
const labelList& meshPoints = patches[patchi].meshPoints();
|
const labelList& meshPoints = patches[patchi].meshPoints();
|
||||||
|
const layerParameters::thicknessModelType spec =
|
||||||
|
layerParams.layerModels()[patchi];
|
||||||
|
|
||||||
scalar sumThickness = 0;
|
scalar sumThickness = 0;
|
||||||
scalar sumNearWallThickness = 0;
|
scalar sumNearWallThickness = 0;
|
||||||
@ -1629,6 +1724,7 @@ void Foam::snappyLayerDriver::calculateLayerThickness
|
|||||||
sumThickness += thickness[ppPointi];
|
sumThickness += thickness[ppPointi];
|
||||||
sumNearWallThickness += layerParams.firstLayerThickness
|
sumNearWallThickness += layerParams.firstLayerThickness
|
||||||
(
|
(
|
||||||
|
spec,
|
||||||
patchNLayers[ppPointi],
|
patchNLayers[ppPointi],
|
||||||
firstLayerThickness[ppPointi],
|
firstLayerThickness[ppPointi],
|
||||||
finalLayerThickness[ppPointi],
|
finalLayerThickness[ppPointi],
|
||||||
@ -1806,6 +1902,8 @@ void Foam::snappyLayerDriver::getPatchDisplacement
|
|||||||
const indirectPrimitivePatch& pp,
|
const indirectPrimitivePatch& pp,
|
||||||
const scalarField& thickness,
|
const scalarField& thickness,
|
||||||
const scalarField& minThickness,
|
const scalarField& minThickness,
|
||||||
|
const scalarField& expansionRatio,
|
||||||
|
|
||||||
pointField& patchDisp,
|
pointField& patchDisp,
|
||||||
labelList& patchNLayers,
|
labelList& patchNLayers,
|
||||||
List<extrudeMode>& extrudeStatus
|
List<extrudeMode>& extrudeStatus
|
||||||
@ -1836,6 +1934,98 @@ void Foam::snappyLayerDriver::getPatchDisplacement
|
|||||||
label nExtrudeRemove = 0;
|
label nExtrudeRemove = 0;
|
||||||
|
|
||||||
|
|
||||||
|
////XXXXXXXX
|
||||||
|
// {
|
||||||
|
// OBJstream twoStr
|
||||||
|
// (
|
||||||
|
// mesh.time().path()
|
||||||
|
// / "twoFacePoints_"
|
||||||
|
// + meshRefiner_.timeName()
|
||||||
|
// + ".obj"
|
||||||
|
// );
|
||||||
|
// OBJstream multiStr
|
||||||
|
// (
|
||||||
|
// mesh.time().path()
|
||||||
|
// / "multiFacePoints_"
|
||||||
|
// + meshRefiner_.timeName()
|
||||||
|
// + ".obj"
|
||||||
|
// );
|
||||||
|
// Pout<< "Writing points inbetween two faces on same cell to "
|
||||||
|
// << twoStr.name() << endl;
|
||||||
|
// Pout<< "Writing points inbetween three or more faces on same cell to "
|
||||||
|
// << multiStr.name() << endl;
|
||||||
|
// // Check whether inbetween patch faces on same cell
|
||||||
|
// Map<labelList> cellToFaces;
|
||||||
|
// forAll(pointNormals, patchPointi)
|
||||||
|
// {
|
||||||
|
// const labelList& pFaces = pointFaces[patchPointi];
|
||||||
|
//
|
||||||
|
// cellToFaces.clear();
|
||||||
|
// forAll(pFaces, pFacei)
|
||||||
|
// {
|
||||||
|
// const label patchFacei = pFaces[pFacei];
|
||||||
|
// const label meshFacei = pp.addressing()[patchFacei];
|
||||||
|
// const label celli = mesh.faceOwner()[meshFacei];
|
||||||
|
// Map<labelList>::iterator faceFnd = cellToFaces.find(celli);
|
||||||
|
// if (faceFnd.found())
|
||||||
|
// {
|
||||||
|
// labelList& faces = faceFnd();
|
||||||
|
// if (!faces.found(patchFacei))
|
||||||
|
// {
|
||||||
|
// faces.append(patchFacei);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// else
|
||||||
|
// {
|
||||||
|
// cellToFaces.insert(celli, labelList(1, patchFacei));
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// forAllConstIter(Map<labelList>, cellToFaces, iter)
|
||||||
|
// {
|
||||||
|
// if (iter().size() == 2)
|
||||||
|
// {
|
||||||
|
// twoStr.write(pp.localPoints()[patchPointi]);
|
||||||
|
// }
|
||||||
|
// else if (iter().size() > 2)
|
||||||
|
// {
|
||||||
|
// multiStr.write(pp.localPoints()[patchPointi]);
|
||||||
|
//
|
||||||
|
// const scalar ratio =
|
||||||
|
// layerParameters::finalLayerThicknessRatio
|
||||||
|
// (
|
||||||
|
// patchNLayers[patchPointi],
|
||||||
|
// expansionRatio[patchPointi]
|
||||||
|
// );
|
||||||
|
// // Get thickness of cell next to bulk
|
||||||
|
// const vector finalDisp
|
||||||
|
// (
|
||||||
|
// ratio*patchDisp[patchPointi]
|
||||||
|
// );
|
||||||
|
//
|
||||||
|
// //Pout<< "** point:" << pp.localPoints()[patchPointi]
|
||||||
|
// // << " on cell:" << iter.key()
|
||||||
|
// // << " faces:" << iter()
|
||||||
|
// // << " displacement was:" << patchDisp[patchPointi]
|
||||||
|
// // << " ratio:" << ratio
|
||||||
|
// // << " finalDispl:" << finalDisp;
|
||||||
|
//
|
||||||
|
// // Half this thickness
|
||||||
|
// patchDisp[patchPointi] -= 0.8*finalDisp;
|
||||||
|
//
|
||||||
|
// //Pout<< " new displacement:"
|
||||||
|
// // << patchDisp[patchPointi] << endl;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// Pout<< "Written " << multiStr.nVertices()
|
||||||
|
// << " points inbetween three or more faces on same cell to "
|
||||||
|
// << multiStr.name() << endl;
|
||||||
|
// }
|
||||||
|
////XXXXXXXX
|
||||||
|
|
||||||
|
|
||||||
// Check if no extrude possible.
|
// Check if no extrude possible.
|
||||||
forAll(pointNormals, patchPointi)
|
forAll(pointNormals, patchPointi)
|
||||||
{
|
{
|
||||||
@ -3724,7 +3914,7 @@ void Foam::snappyLayerDriver::addLayers
|
|||||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
// It is hard to calculate some length scale if not in relative
|
// It is hard to calculate some length scale if not in relative
|
||||||
// mode so disable this check.
|
// mode so disable this check.
|
||||||
if (layerParams.relativeSizes())
|
if (!layerParams.relativeSizes().found(false))
|
||||||
{
|
{
|
||||||
// Undistorted edge length
|
// Undistorted edge length
|
||||||
const scalar edge0Len =
|
const scalar edge0Len =
|
||||||
@ -3735,6 +3925,7 @@ void Foam::snappyLayerDriver::addLayers
|
|||||||
(
|
(
|
||||||
*pp,
|
*pp,
|
||||||
layerParams.maxFaceThicknessRatio(),
|
layerParams.maxFaceThicknessRatio(),
|
||||||
|
layerParams.relativeSizes(),
|
||||||
edge0Len,
|
edge0Len,
|
||||||
cellLevel,
|
cellLevel,
|
||||||
|
|
||||||
@ -3948,6 +4139,8 @@ void Foam::snappyLayerDriver::addLayers
|
|||||||
*pp,
|
*pp,
|
||||||
thickness,
|
thickness,
|
||||||
minThickness,
|
minThickness,
|
||||||
|
expansionRatio,
|
||||||
|
|
||||||
patchDisp,
|
patchDisp,
|
||||||
patchNLayers,
|
patchNLayers,
|
||||||
extrudeStatus
|
extrudeStatus
|
||||||
@ -4077,7 +4270,7 @@ void Foam::snappyLayerDriver::addLayers
|
|||||||
|
|
||||||
forAll(nPatchPointLayers, i)
|
forAll(nPatchPointLayers, i)
|
||||||
{
|
{
|
||||||
scalar ratio = layerParams.finalLayerThicknessRatio
|
scalar ratio = layerParameters::finalLayerThicknessRatio
|
||||||
(
|
(
|
||||||
nPatchPointLayers[i],
|
nPatchPointLayers[i],
|
||||||
expansionRatio[i]
|
expansionRatio[i]
|
||||||
@ -4133,7 +4326,7 @@ void Foam::snappyLayerDriver::addLayers
|
|||||||
mesh.name(),
|
mesh.name(),
|
||||||
static_cast<polyMesh&>(mesh).instance(),
|
static_cast<polyMesh&>(mesh).instance(),
|
||||||
mesh.time(), // register with runTime
|
mesh.time(), // register with runTime
|
||||||
IOobject::NO_READ,
|
IOobject::READ_IF_PRESENT, // read fv* if present
|
||||||
static_cast<polyMesh&>(mesh).writeOpt()
|
static_cast<polyMesh&>(mesh).writeOpt()
|
||||||
), // io params from original mesh but new name
|
), // io params from original mesh but new name
|
||||||
mesh, // original mesh
|
mesh, // original mesh
|
||||||
|
|||||||
@ -235,6 +235,7 @@ private:
|
|||||||
(
|
(
|
||||||
const indirectPrimitivePatch& pp,
|
const indirectPrimitivePatch& pp,
|
||||||
const scalar faceRatio,
|
const scalar faceRatio,
|
||||||
|
const boolList& relativeSizes,
|
||||||
const scalar edge0Len,
|
const scalar edge0Len,
|
||||||
const labelList& cellLevel,
|
const labelList& cellLevel,
|
||||||
pointField& patchDisp,
|
pointField& patchDisp,
|
||||||
@ -328,6 +329,8 @@ private:
|
|||||||
const indirectPrimitivePatch& pp,
|
const indirectPrimitivePatch& pp,
|
||||||
const scalarField& thickness,
|
const scalarField& thickness,
|
||||||
const scalarField& minThickness,
|
const scalarField& minThickness,
|
||||||
|
const scalarField& expansionRatio,
|
||||||
|
|
||||||
pointField& patchDisp,
|
pointField& patchDisp,
|
||||||
labelList& patchNLayers,
|
labelList& patchNLayers,
|
||||||
List<extrudeMode>& extrudeStatus
|
List<extrudeMode>& extrudeStatus
|
||||||
|
|||||||
@ -1476,6 +1476,261 @@ Foam::label Foam::snappyRefineDriver::refinementInterfaceRefine
|
|||||||
return iter;
|
return iter;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Foam::snappyRefineDriver::usesHigherLevel
|
||||||
|
(
|
||||||
|
const labelUList& boundaryPointLevel,
|
||||||
|
const labelUList& f,
|
||||||
|
const label cLevel
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
for (const label pointi : f)
|
||||||
|
{
|
||||||
|
if (boundaryPointLevel[pointi] > cLevel)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::label Foam::snappyRefineDriver::boundaryRefinementInterfaceRefine
|
||||||
|
(
|
||||||
|
const refinementParameters& refineParams,
|
||||||
|
const label maxIter
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (refineParams.minRefineCells() == -1)
|
||||||
|
{
|
||||||
|
// Special setting to be able to restart shm on meshes with inconsistent
|
||||||
|
// cellLevel/pointLevel
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dryRun_)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
addProfiling(interface, "snappyHexMesh::refine::transition");
|
||||||
|
const fvMesh& mesh = meshRefiner_.mesh();
|
||||||
|
|
||||||
|
label iter = 0;
|
||||||
|
|
||||||
|
if (refineParams.interfaceRefine())
|
||||||
|
{
|
||||||
|
for (;iter < maxIter; iter++)
|
||||||
|
{
|
||||||
|
Info<< nl
|
||||||
|
<< "Boundary refinement iteration " << iter << nl
|
||||||
|
<< "-------------------------------" << nl
|
||||||
|
<< endl;
|
||||||
|
|
||||||
|
const labelList& surfaceIndex = meshRefiner_.surfaceIndex();
|
||||||
|
const hexRef8& cutter = meshRefiner_.meshCutter();
|
||||||
|
const labelList& cellLevel = cutter.cellLevel();
|
||||||
|
const faceList& faces = mesh.faces();
|
||||||
|
const cellList& cells = mesh.cells();
|
||||||
|
|
||||||
|
|
||||||
|
// Determine cells to refine
|
||||||
|
// ~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
// Point/face on boundary
|
||||||
|
bitSet isBoundaryPoint(mesh.nPoints());
|
||||||
|
bitSet isBoundaryFace(mesh.nFaces());
|
||||||
|
{
|
||||||
|
forAll(surfaceIndex, facei)
|
||||||
|
{
|
||||||
|
if (surfaceIndex[facei] != -1)
|
||||||
|
{
|
||||||
|
isBoundaryFace.set(facei);
|
||||||
|
isBoundaryPoint.set(faces[facei]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const labelList meshPatchIDs(meshRefiner_.meshedPatches());
|
||||||
|
for (const label patchi : meshPatchIDs)
|
||||||
|
{
|
||||||
|
const polyPatch& pp = mesh.boundaryMesh()[patchi];
|
||||||
|
forAll(pp, i)
|
||||||
|
{
|
||||||
|
isBoundaryFace.set(pp.start()+i);
|
||||||
|
isBoundaryPoint.set(pp[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
syncTools::syncPointList
|
||||||
|
(
|
||||||
|
mesh,
|
||||||
|
isBoundaryPoint,
|
||||||
|
orEqOp<unsigned int>(),
|
||||||
|
0
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mark max boundary face level onto boundary points. All points
|
||||||
|
// not on a boundary face stay 0.
|
||||||
|
labelList boundaryPointLevel(mesh.nPoints(), 0);
|
||||||
|
{
|
||||||
|
forAll(cells, celli)
|
||||||
|
{
|
||||||
|
const cell& cFaces = cells[celli];
|
||||||
|
const label cLevel = cellLevel[celli];
|
||||||
|
|
||||||
|
for (const label facei : cFaces)
|
||||||
|
{
|
||||||
|
if (isBoundaryFace(facei))
|
||||||
|
{
|
||||||
|
const face& f = faces[facei];
|
||||||
|
for (const label pointi : f)
|
||||||
|
{
|
||||||
|
boundaryPointLevel[pointi] =
|
||||||
|
max
|
||||||
|
(
|
||||||
|
boundaryPointLevel[pointi],
|
||||||
|
cLevel
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
syncTools::syncPointList
|
||||||
|
(
|
||||||
|
mesh,
|
||||||
|
boundaryPointLevel,
|
||||||
|
maxEqOp<label>(),
|
||||||
|
0
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Detect cells with a point but not face on the boundary
|
||||||
|
labelList candidateCells;
|
||||||
|
{
|
||||||
|
const cellList& cells = mesh.cells();
|
||||||
|
|
||||||
|
cellSet candidateCellSet
|
||||||
|
(
|
||||||
|
mesh,
|
||||||
|
"candidateCells",
|
||||||
|
cells.size()/100
|
||||||
|
);
|
||||||
|
|
||||||
|
forAll(cells, celli)
|
||||||
|
{
|
||||||
|
const cell& cFaces = cells[celli];
|
||||||
|
const label cLevel = cellLevel[celli];
|
||||||
|
|
||||||
|
bool isBoundaryCell = false;
|
||||||
|
for (const label facei : cFaces)
|
||||||
|
{
|
||||||
|
if (isBoundaryFace(facei))
|
||||||
|
{
|
||||||
|
isBoundaryCell = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isBoundaryCell)
|
||||||
|
{
|
||||||
|
for (const label facei : cFaces)
|
||||||
|
{
|
||||||
|
const face& f = mesh.faces()[facei];
|
||||||
|
if (usesHigherLevel(boundaryPointLevel, f, cLevel))
|
||||||
|
{
|
||||||
|
candidateCellSet.insert(celli);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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. After a few iterations check if too
|
||||||
|
// few cells
|
||||||
|
if
|
||||||
|
(
|
||||||
|
nCellsToRefine == 0
|
||||||
|
// || (
|
||||||
|
// iter >= 1
|
||||||
|
// && 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
|
||||||
|
(
|
||||||
|
"boundary cell refinement iteration " + name(iter),
|
||||||
|
decomposer_,
|
||||||
|
distributor_,
|
||||||
|
cellsToRefine,
|
||||||
|
refineParams.maxLoadUnbalance()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
meshRefiner_.refineAndBalance
|
||||||
|
(
|
||||||
|
"boundary cell refinement iteration " + name(iter),
|
||||||
|
decomposer_,
|
||||||
|
distributor_,
|
||||||
|
cellsToRefine,
|
||||||
|
refineParams.maxLoadUnbalance()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return iter;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void Foam::snappyRefineDriver::removeInsideCells
|
void Foam::snappyRefineDriver::removeInsideCells
|
||||||
(
|
(
|
||||||
@ -3195,6 +3450,18 @@ void Foam::snappyRefineDriver::doRefine
|
|||||||
motionDict
|
motionDict
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
|
//- Commented out for now since causes zoning errors (sigsegv) on
|
||||||
|
// case with faceZones. TBD.
|
||||||
|
//// Refine any cells are point/edge connected to the boundary and have a
|
||||||
|
//// lower refinement level than the neighbouring cells
|
||||||
|
//boundaryRefinementInterfaceRefine
|
||||||
|
//(
|
||||||
|
// refineParams,
|
||||||
|
// 10 // maxIter
|
||||||
|
//);
|
||||||
|
|
||||||
|
|
||||||
// Mesh is at its finest. Do optional zoning (cellZones and faceZones)
|
// Mesh is at its finest. Do optional zoning (cellZones and faceZones)
|
||||||
wordPairHashTable zonesToFaceZone;
|
wordPairHashTable zonesToFaceZone;
|
||||||
zonify(refineParams, zonesToFaceZone);
|
zonify(refineParams, zonesToFaceZone);
|
||||||
|
|||||||
@ -165,6 +165,21 @@ class snappyRefineDriver
|
|||||||
const label maxIter
|
const label maxIter
|
||||||
);
|
);
|
||||||
|
|
||||||
|
//- Helper: see if any element in f has higher level than cLevel
|
||||||
|
bool usesHigherLevel
|
||||||
|
(
|
||||||
|
const labelUList& boundaryPointLevel,
|
||||||
|
const labelUList& f,
|
||||||
|
const label cLevel
|
||||||
|
) const;
|
||||||
|
|
||||||
|
//- Refine cells with a point/edge but not face on the boundary
|
||||||
|
label boundaryRefinementInterfaceRefine
|
||||||
|
(
|
||||||
|
const refinementParameters& refineParams,
|
||||||
|
const label maxIter
|
||||||
|
);
|
||||||
|
|
||||||
//- Remove all cells within intersected region
|
//- Remove all cells within intersected region
|
||||||
void removeInsideCells
|
void removeInsideCells
|
||||||
(
|
(
|
||||||
|
|||||||
@ -617,7 +617,8 @@ public:
|
|||||||
const bool orderPoints = false
|
const bool orderPoints = false
|
||||||
);
|
);
|
||||||
|
|
||||||
//- Create new mesh with old mesh patches
|
//- Create new mesh with old mesh patches. Additional dictionaries
|
||||||
|
// (fv* etc) read according to IO flags
|
||||||
template<class Type>
|
template<class Type>
|
||||||
autoPtr<mapPolyMesh> makeMesh
|
autoPtr<mapPolyMesh> makeMesh
|
||||||
(
|
(
|
||||||
|
|||||||
@ -182,14 +182,14 @@ Foam::autoPtr<Foam::mapPolyMesh> Foam::polyTopoChange::makeMesh
|
|||||||
// Create the mesh
|
// Create the mesh
|
||||||
// ~~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
IOobject noReadIO(io);
|
//IOobject noReadIO(io);
|
||||||
noReadIO.readOpt() = IOobject::NO_READ;
|
//noReadIO.readOpt() = IOobject::NO_READ;
|
||||||
noReadIO.writeOpt() = IOobject::AUTO_WRITE;
|
//noReadIO.writeOpt() = IOobject::AUTO_WRITE;
|
||||||
newMeshPtr.reset
|
newMeshPtr.reset
|
||||||
(
|
(
|
||||||
new Type
|
new Type
|
||||||
(
|
(
|
||||||
noReadIO,
|
io, //noReadIO
|
||||||
std::move(newPoints),
|
std::move(newPoints),
|
||||||
std::move(faces_),
|
std::move(faces_),
|
||||||
std::move(faceOwner_),
|
std::move(faceOwner_),
|
||||||
|
|||||||
9
tutorials/mesh/snappyHexMesh/airfoilWithLayers/Allclean
Executable file
9
tutorials/mesh/snappyHexMesh/airfoilWithLayers/Allclean
Executable file
@ -0,0 +1,9 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
cd "${0%/*}" || exit # Run from this directory
|
||||||
|
. ${WM_PROJECT_DIR:?}/bin/tools/CleanFunctions # Tutorial clean functions
|
||||||
|
#------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
cleanCase0
|
||||||
|
rm -rf constant/extendedFeatureEdgeMesh
|
||||||
|
|
||||||
|
#------------------------------------------------------------------------------
|
||||||
22
tutorials/mesh/snappyHexMesh/airfoilWithLayers/Allrun
Executable file
22
tutorials/mesh/snappyHexMesh/airfoilWithLayers/Allrun
Executable file
@ -0,0 +1,22 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
cd "${0%/*}" || exit # Run from this directory
|
||||||
|
. ${WM_PROJECT_DIR:?}/bin/tools/RunFunctions # Tutorial run functions
|
||||||
|
#------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
runApplication blockMesh
|
||||||
|
runApplication surfaceFeatureExtract
|
||||||
|
|
||||||
|
mkdir -p 0
|
||||||
|
|
||||||
|
# Run with basic
|
||||||
|
foamDictionary -entry geometry.type -set basic system/fvSchemes
|
||||||
|
runApplication -s basic snappyHexMesh
|
||||||
|
runApplication -s basic checkMesh -writeAllFields
|
||||||
|
foamListTimes -rm
|
||||||
|
|
||||||
|
# Run with highAspectRatio
|
||||||
|
foamDictionary -entry geometry.type -set highAspectRatio system/fvSchemes
|
||||||
|
runApplication -s highAspectRatio snappyHexMesh
|
||||||
|
runApplication -s highAspectRatio checkMesh -writeAllFields
|
||||||
|
|
||||||
|
#------------------------------------------------------------------------------
|
||||||
@ -0,0 +1,32 @@
|
|||||||
|
/*--------------------------------*- C++ -*----------------------------------*\
|
||||||
|
| ========= | |
|
||||||
|
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
|
||||||
|
| \\ / O peration | Version: v2006 |
|
||||||
|
| \\ / A nd | Website: www.openfoam.com |
|
||||||
|
| \\/ M anipulation | |
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
FoamFile
|
||||||
|
{
|
||||||
|
version 2.0;
|
||||||
|
format ascii;
|
||||||
|
class dictionary;
|
||||||
|
object transportProperties;
|
||||||
|
}
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
// Air temperature at standard atmospheric pressure = 540 R = 300 K
|
||||||
|
// See README.md
|
||||||
|
// c = 347.336 [m/s]
|
||||||
|
// Ma = UInf/c = 0.15
|
||||||
|
// UInf = 52.1004 [m/s]
|
||||||
|
// ReChord = 6e6 (per chord)
|
||||||
|
// Chord = 1 [m]
|
||||||
|
// ReChord = UInf*Chord/nuFluid
|
||||||
|
// nuFluid = UInf*Chord/ReChord = 8.6834e-06 [m2/s]
|
||||||
|
|
||||||
|
transportModel Newtonian;
|
||||||
|
|
||||||
|
nu 8.6834e-06;
|
||||||
|
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
Binary file not shown.
Binary file not shown.
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,72 @@
|
|||||||
|
solid PART_6
|
||||||
|
facet normal -0.000000000e+00 -1.767905329e-06 -1.000000000e+00
|
||||||
|
outer loop
|
||||||
|
vertex 2.000000000e+00 -1.000000000e+00 5.352202629e-08
|
||||||
|
vertex 1.000000000e+00 -1.000000000e+00 5.352202629e-08
|
||||||
|
vertex 1.000000125e+00 0.000000000e+00 -1.714383303e-06
|
||||||
|
endloop
|
||||||
|
endfacet
|
||||||
|
facet normal -2.117582368e-22 -1.767905329e-06 -1.000000000e+00
|
||||||
|
outer loop
|
||||||
|
vertex 1.000000125e+00 0.000000000e+00 -1.714383303e-06
|
||||||
|
vertex 2.000000125e+00 0.000000000e+00 -1.714383303e-06
|
||||||
|
vertex 2.000000000e+00 -1.000000000e+00 5.352202629e-08
|
||||||
|
endloop
|
||||||
|
endfacet
|
||||||
|
facet normal -0.000000000e+00 -1.767905329e-06 -1.000000000e+00
|
||||||
|
outer loop
|
||||||
|
vertex 3.000000000e+00 -1.000000000e+00 5.352202629e-08
|
||||||
|
vertex 2.000000000e+00 -1.000000000e+00 5.352202629e-08
|
||||||
|
vertex 2.000000125e+00 0.000000000e+00 -1.714383303e-06
|
||||||
|
endloop
|
||||||
|
endfacet
|
||||||
|
facet normal 2.117582368e-22 -1.767905329e-06 -1.000000000e+00
|
||||||
|
outer loop
|
||||||
|
vertex 2.000000125e+00 0.000000000e+00 -1.714383303e-06
|
||||||
|
vertex 3.000000125e+00 0.000000000e+00 -1.714383303e-06
|
||||||
|
vertex 3.000000000e+00 -1.000000000e+00 5.352202629e-08
|
||||||
|
endloop
|
||||||
|
endfacet
|
||||||
|
facet normal -0.000000000e+00 -1.767905329e-06 -1.000000000e+00
|
||||||
|
outer loop
|
||||||
|
vertex 4.000000000e+00 -1.000000000e+00 5.352202629e-08
|
||||||
|
vertex 3.000000000e+00 -1.000000000e+00 5.352202629e-08
|
||||||
|
vertex 3.000000125e+00 0.000000000e+00 -1.714383303e-06
|
||||||
|
endloop
|
||||||
|
endfacet
|
||||||
|
facet normal 0.000000000e+00 -1.767905329e-06 -1.000000000e+00
|
||||||
|
outer loop
|
||||||
|
vertex 3.000000125e+00 0.000000000e+00 -1.714383303e-06
|
||||||
|
vertex 4.000000125e+00 0.000000000e+00 -1.714383303e-06
|
||||||
|
vertex 4.000000000e+00 -1.000000000e+00 5.352202629e-08
|
||||||
|
endloop
|
||||||
|
endfacet
|
||||||
|
facet normal 2.117582368e-22 -1.767905329e-06 -1.000000000e+00
|
||||||
|
outer loop
|
||||||
|
vertex 5.000000125e+00 0.000000000e+00 -1.714383303e-06
|
||||||
|
vertex 6.000000125e+00 0.000000000e+00 -1.714383303e-06
|
||||||
|
vertex 6.000000000e+00 -1.000000000e+00 5.352202629e-08
|
||||||
|
endloop
|
||||||
|
endfacet
|
||||||
|
facet normal 0.000000000e+00 -1.767905329e-06 -1.000000000e+00
|
||||||
|
outer loop
|
||||||
|
vertex 5.000000125e+00 0.000000000e+00 -1.714383303e-06
|
||||||
|
vertex 6.000000000e+00 -1.000000000e+00 5.352202629e-08
|
||||||
|
vertex 5.000000000e+00 -1.000000000e+00 5.352202629e-08
|
||||||
|
endloop
|
||||||
|
endfacet
|
||||||
|
facet normal -2.117582368e-22 -1.767905329e-06 -1.000000000e+00
|
||||||
|
outer loop
|
||||||
|
vertex 4.000000125e+00 0.000000000e+00 -1.714383303e-06
|
||||||
|
vertex 5.000000125e+00 0.000000000e+00 -1.714383303e-06
|
||||||
|
vertex 5.000000000e+00 -1.000000000e+00 5.352202629e-08
|
||||||
|
endloop
|
||||||
|
endfacet
|
||||||
|
facet normal 0.000000000e+00 -1.767905329e-06 -1.000000000e+00
|
||||||
|
outer loop
|
||||||
|
vertex 4.000000000e+00 -1.000000000e+00 5.352202629e-08
|
||||||
|
vertex 4.000000125e+00 0.000000000e+00 -1.714383303e-06
|
||||||
|
vertex 5.000000000e+00 -1.000000000e+00 5.352202629e-08
|
||||||
|
endloop
|
||||||
|
endfacet
|
||||||
|
endsolid
|
||||||
@ -0,0 +1,56 @@
|
|||||||
|
/*--------------------------------*- C++ -*----------------------------------*\
|
||||||
|
| ========= | |
|
||||||
|
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
|
||||||
|
| \\ / O peration | Version: dev |
|
||||||
|
| \\ / A nd | Web: www.OpenFOAM.org |
|
||||||
|
| \\/ M anipulation | |
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
FoamFile
|
||||||
|
{
|
||||||
|
version 2.0;
|
||||||
|
format ascii;
|
||||||
|
class dictionary;
|
||||||
|
object blockMeshDict;
|
||||||
|
}
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
convertToMeters 1;
|
||||||
|
|
||||||
|
vertices
|
||||||
|
(
|
||||||
|
(-1 -1 -1)
|
||||||
|
( 2 -1 -1)
|
||||||
|
( 2 0 -1)
|
||||||
|
(-1 0 -1)
|
||||||
|
(-1 -1 1)
|
||||||
|
( 2 -1 1)
|
||||||
|
( 2 0 1)
|
||||||
|
(-1 0 1)
|
||||||
|
);
|
||||||
|
|
||||||
|
blocks
|
||||||
|
(
|
||||||
|
// hex (0 1 2 3 4 5 6 7) (15 10 10) simpleGrading (1 1 1)
|
||||||
|
hex (0 1 2 3 4 5 6 7) (15 5 10) simpleGrading (1 1 1)
|
||||||
|
);
|
||||||
|
|
||||||
|
edges
|
||||||
|
();
|
||||||
|
boundary
|
||||||
|
(
|
||||||
|
airFlow
|
||||||
|
{
|
||||||
|
type patch;
|
||||||
|
faces
|
||||||
|
(
|
||||||
|
(3 7 6 2)
|
||||||
|
(1 5 4 0) //back
|
||||||
|
(2 6 5 1) //outlet
|
||||||
|
(0 4 7 3) //inlet
|
||||||
|
(0 3 2 1) //lowerWall
|
||||||
|
(4 5 6 7) //upperWall
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
);
|
||||||
@ -0,0 +1,55 @@
|
|||||||
|
/*--------------------------------*- C++ -*----------------------------------*\
|
||||||
|
| ========= | |
|
||||||
|
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
|
||||||
|
| \\ / O peration | Version: v2006 |
|
||||||
|
| \\ / A nd | Website: www.openfoam.com |
|
||||||
|
| \\/ M anipulation | |
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
FoamFile
|
||||||
|
{
|
||||||
|
version 2.0;
|
||||||
|
format ascii;
|
||||||
|
class dictionary;
|
||||||
|
object controlDict;
|
||||||
|
}
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
//DebugSwitches
|
||||||
|
//{
|
||||||
|
// fvGeometryScheme 1;
|
||||||
|
// highAspectRatio 1;
|
||||||
|
// basic 1;
|
||||||
|
//}
|
||||||
|
|
||||||
|
application simpleFoam;
|
||||||
|
|
||||||
|
startFrom startTime;
|
||||||
|
|
||||||
|
startTime 0;
|
||||||
|
|
||||||
|
stopAt endTime;
|
||||||
|
|
||||||
|
endTime 15000;
|
||||||
|
|
||||||
|
deltaT 1;
|
||||||
|
|
||||||
|
writeControl timeStep;
|
||||||
|
|
||||||
|
writeInterval 5000;
|
||||||
|
|
||||||
|
purgeWrite 2;
|
||||||
|
|
||||||
|
writeFormat binary;
|
||||||
|
|
||||||
|
writePrecision 15;
|
||||||
|
|
||||||
|
writeCompression off;
|
||||||
|
|
||||||
|
timeFormat general;
|
||||||
|
|
||||||
|
timePrecision 8;
|
||||||
|
|
||||||
|
runTimeModifiable false;
|
||||||
|
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -0,0 +1,73 @@
|
|||||||
|
/*--------------------------------*- C++ -*----------------------------------*\
|
||||||
|
| ========= | |
|
||||||
|
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
|
||||||
|
| \\ / O peration | Version: v2006 |
|
||||||
|
| \\ / A nd | Website: www.openfoam.com |
|
||||||
|
| \\/ M anipulation | |
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
FoamFile
|
||||||
|
{
|
||||||
|
version 2;
|
||||||
|
format ascii;
|
||||||
|
class dictionary;
|
||||||
|
object fvSchemes;
|
||||||
|
}
|
||||||
|
|
||||||
|
ddtSchemes
|
||||||
|
{
|
||||||
|
default steadyState;
|
||||||
|
}
|
||||||
|
|
||||||
|
gradSchemes
|
||||||
|
{
|
||||||
|
default Gauss linear;
|
||||||
|
grad(p) Gauss linear;
|
||||||
|
unlimitedGrad(U) Gauss linear;
|
||||||
|
}
|
||||||
|
|
||||||
|
divSchemes
|
||||||
|
{
|
||||||
|
default none;
|
||||||
|
div(phi,U) bounded Gauss linearUpwindV unlimitedGrad(U);
|
||||||
|
turbulence bounded Gauss limitedLinear 1;
|
||||||
|
div(phi,k) bounded Gauss limitedLinear 1;
|
||||||
|
div(phi,omega) bounded Gauss limitedLinear 1;
|
||||||
|
div(phi,nuTilda) bounded Gauss limitedLinear 1;
|
||||||
|
div(phi,epsilon) bounded Gauss limitedLinear 1;
|
||||||
|
div(phi,phit) bounded Gauss limitedLinear 1;
|
||||||
|
div(phi,f) bounded Gauss limitedLinear 1;
|
||||||
|
div(phi,gammaInt) bounded Gauss linearUpwind grad;
|
||||||
|
div(phi,ReThetat) bounded Gauss linearUpwind grad;
|
||||||
|
div((nuEff*dev2(T(grad(U))))) Gauss linear;
|
||||||
|
}
|
||||||
|
|
||||||
|
laplacianSchemes
|
||||||
|
{
|
||||||
|
default Gauss linear limited corrected 0.33;
|
||||||
|
}
|
||||||
|
|
||||||
|
interpolationSchemes
|
||||||
|
{
|
||||||
|
default linear;
|
||||||
|
}
|
||||||
|
|
||||||
|
snGradSchemes
|
||||||
|
{
|
||||||
|
default limited corrected 0.33;
|
||||||
|
}
|
||||||
|
|
||||||
|
wallDist
|
||||||
|
{
|
||||||
|
method meshWave;
|
||||||
|
}
|
||||||
|
|
||||||
|
geometry
|
||||||
|
{
|
||||||
|
type highAspectRatio;
|
||||||
|
minAspect 10;
|
||||||
|
maxAspect 100;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -0,0 +1,71 @@
|
|||||||
|
/*--------------------------------*- C++ -*----------------------------------*\
|
||||||
|
| ========= | |
|
||||||
|
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
|
||||||
|
| \\ / O peration | Version: v2006 |
|
||||||
|
| \\ / A nd | Website: www.openfoam.com |
|
||||||
|
| \\/ M anipulation | |
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
FoamFile
|
||||||
|
{
|
||||||
|
version 2.0;
|
||||||
|
format ascii;
|
||||||
|
class dictionary;
|
||||||
|
object fvSolution;
|
||||||
|
}
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
solvers
|
||||||
|
{
|
||||||
|
p
|
||||||
|
{
|
||||||
|
solver GAMG;
|
||||||
|
smoother GaussSeidel;
|
||||||
|
tolerance 1e-06;
|
||||||
|
relTol 0.1;
|
||||||
|
}
|
||||||
|
|
||||||
|
"(U|k|omega|nuTilda|gammaInt|ReThetat)"
|
||||||
|
{
|
||||||
|
solver smoothSolver;
|
||||||
|
smoother symGaussSeidel;
|
||||||
|
tolerance 1e-08;
|
||||||
|
relTol 0.1;
|
||||||
|
maxIter 50;
|
||||||
|
}
|
||||||
|
|
||||||
|
"(epsilon|phit)"
|
||||||
|
{
|
||||||
|
solver PBiCGStab;
|
||||||
|
preconditioner DILU;
|
||||||
|
tolerance 1e-8;
|
||||||
|
relTol 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
f
|
||||||
|
{
|
||||||
|
solver PBiCGStab;
|
||||||
|
preconditioner DIC;
|
||||||
|
tolerance 1e-8;
|
||||||
|
relTol 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SIMPLE
|
||||||
|
{
|
||||||
|
nNonOrthogonalCorrectors 0;
|
||||||
|
consistent true;
|
||||||
|
}
|
||||||
|
|
||||||
|
relaxationFactors
|
||||||
|
{
|
||||||
|
equations
|
||||||
|
{
|
||||||
|
".*" 0.9;
|
||||||
|
"(gammaInt|ReThetat|k|nuTilda)" 0.8;
|
||||||
|
"(phit|f)" 0.7;
|
||||||
|
epsilon 0.5;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -0,0 +1,78 @@
|
|||||||
|
/*--------------------------------*- C++ -*----------------------------------*\
|
||||||
|
| ========= | |
|
||||||
|
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
|
||||||
|
| \\ / O peration | Version: v1912 |
|
||||||
|
| \\ / A nd | Website: www.openfoam.com |
|
||||||
|
| \\/ M anipulation | |
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
FoamFile
|
||||||
|
{
|
||||||
|
version 2.0;
|
||||||
|
format ascii;
|
||||||
|
class dictionary;
|
||||||
|
object meshQualityDict;
|
||||||
|
}
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
//- Maximum non-orthogonality allowed. Set to 180 to disable.
|
||||||
|
maxNonOrtho 65;
|
||||||
|
|
||||||
|
//- Max skewness allowed. Set to <0 to disable.
|
||||||
|
maxBoundarySkewness 20;
|
||||||
|
maxInternalSkewness 4;
|
||||||
|
|
||||||
|
//- Max concaveness allowed. Is angle (in degrees) below which concavity
|
||||||
|
// is allowed. 0 is straight face, <0 would be convex face.
|
||||||
|
// Set to 180 to disable.
|
||||||
|
maxConcave 80;
|
||||||
|
|
||||||
|
//- Minimum pyramid volume. Is absolute volume of cell pyramid.
|
||||||
|
// Set to a sensible fraction of the smallest cell volume expected.
|
||||||
|
// Set to very negative number (e.g. -1E30) to disable.
|
||||||
|
minVol 1e-13;
|
||||||
|
|
||||||
|
//- Minimum quality of the tet formed by the face-centre
|
||||||
|
// and variable base point minimum decomposition triangles and
|
||||||
|
// the cell centre. Set to very negative number (e.g. -1E30) to
|
||||||
|
// disable.
|
||||||
|
// <0 = inside out tet,
|
||||||
|
// 0 = flat tet
|
||||||
|
// 1 = regular tet
|
||||||
|
minTetQuality 1e-15;
|
||||||
|
|
||||||
|
//- Minimum face area. Set to <0 to disable.
|
||||||
|
minArea -1;
|
||||||
|
|
||||||
|
//- Minimum face twist. Set to <-1 to disable. dot product of face normal
|
||||||
|
// (itself the average of the triangle normals)
|
||||||
|
// and face centre triangles normal
|
||||||
|
minTwist 0.02;
|
||||||
|
|
||||||
|
//- Minimum normalised cell determinant. This is the determinant of all
|
||||||
|
// the areas of internal faces. It is a measure of how much of the
|
||||||
|
// outside area of the cell is to other cells. The idea is that if all
|
||||||
|
// outside faces of the cell are 'floating' (zeroGradient) the
|
||||||
|
// 'fixedness' of the cell is determined by the area of the internal faces.
|
||||||
|
// 1 = hex, <= 0 = folded or flattened illegal cell
|
||||||
|
minDeterminant 0.001;
|
||||||
|
|
||||||
|
//- Relative position of face in relation to cell centres (0.5 for orthogonal
|
||||||
|
// mesh) (0 -> 0.5)
|
||||||
|
minFaceWeight 0.05;
|
||||||
|
|
||||||
|
//- Volume ratio of neighbouring cells (0 -> 1)
|
||||||
|
minVolRatio 0.01;
|
||||||
|
|
||||||
|
//- Per triangle normal compared to that of preceding triangle. Must be >0
|
||||||
|
// for Fluent compatibility
|
||||||
|
minTriangleTwist -1;
|
||||||
|
|
||||||
|
|
||||||
|
//- If >0 : preserve cells with all points on the surface if the
|
||||||
|
// resulting volume after snapping (by approximation) is larger than
|
||||||
|
// minVolCollapseRatio times old volume (i.e. not collapsed to flat cell).
|
||||||
|
// If <0 : delete always.
|
||||||
|
//minVolCollapseRatio 0.1;
|
||||||
|
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -0,0 +1,753 @@
|
|||||||
|
/*--------------------------------*- C++ -*----------------------------------*\
|
||||||
|
| ========= | |
|
||||||
|
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
|
||||||
|
| \\ / O peration | Version: v1912 |
|
||||||
|
| \\ / A nd | Website: www.openfoam.com |
|
||||||
|
| \\/ M anipulation | |
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
FoamFile
|
||||||
|
{
|
||||||
|
version 2.0;
|
||||||
|
format ascii;
|
||||||
|
class dictionary;
|
||||||
|
object snappyHexMeshDict;
|
||||||
|
}
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
// Which of the steps to run
|
||||||
|
castellatedMesh true;
|
||||||
|
snap true;
|
||||||
|
addLayers true;
|
||||||
|
|
||||||
|
|
||||||
|
// Optional: single region surfaces get patch names according to
|
||||||
|
// surface only. Multi-region surfaces get patch name
|
||||||
|
// surface "_ "region. Default is true
|
||||||
|
// singleRegionName false;
|
||||||
|
|
||||||
|
// Optional: avoid patch-face merging. Allows mesh to be used for
|
||||||
|
// refinement/unrefinement
|
||||||
|
// mergePatchFaces false; // default true
|
||||||
|
|
||||||
|
// Optional: preserve all generated patches. Default is to remove
|
||||||
|
// zero-sized patches.
|
||||||
|
// keepPatches true;
|
||||||
|
|
||||||
|
|
||||||
|
// Geometry. Definition of all surfaces. All surfaces are of class
|
||||||
|
// searchableSurface.
|
||||||
|
// Surfaces are used
|
||||||
|
// - to specify refinement for any mesh cell intersecting it
|
||||||
|
// - to specify refinement for any mesh cell inside/outside/near
|
||||||
|
// - to 'snap' the mesh boundary to the surface
|
||||||
|
geometry
|
||||||
|
{
|
||||||
|
refinement1
|
||||||
|
{
|
||||||
|
type searchableBox;
|
||||||
|
min (-1 -2 -1);
|
||||||
|
max ( 1 2 1);
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
// Shell for directional refinement
|
||||||
|
wakeBox
|
||||||
|
{
|
||||||
|
type searchableBox;
|
||||||
|
min (1.5 1 -0.5);
|
||||||
|
max (3.5 2 0.5);
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
internalFace.stl { name internalFace; type triSurfaceMesh;}
|
||||||
|
|
||||||
|
aerofoil.stl
|
||||||
|
{
|
||||||
|
name aerofoil;
|
||||||
|
type triSurfaceMesh;
|
||||||
|
|
||||||
|
//tolerance 1E-5; // optional:non-default tolerance on intersections
|
||||||
|
//maxTreeDepth 10; // optional:depth of octree. Decrease only in case
|
||||||
|
// of memory limitations.
|
||||||
|
|
||||||
|
// Per region the patchname. If not provided will be <surface>_<region>.
|
||||||
|
// Note: this name cannot be used to identity this region in any
|
||||||
|
// other part of this dictionary; it is only a name
|
||||||
|
// for the combination of surface+region (which is only used
|
||||||
|
// when creating patches)
|
||||||
|
// regions
|
||||||
|
// {
|
||||||
|
// secondSolid
|
||||||
|
// {
|
||||||
|
// name mySecondPatch;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
sphere2
|
||||||
|
{
|
||||||
|
type searchableSphere;
|
||||||
|
centre (1.5 1.5 1.5);
|
||||||
|
radius 1.03;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// Settings for the castellatedMesh generation.
|
||||||
|
castellatedMeshControls
|
||||||
|
{
|
||||||
|
|
||||||
|
// Refinement parameters
|
||||||
|
// ~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
// If local number of cells is >= maxLocalCells on any processor
|
||||||
|
// switches from from refinement followed by balancing
|
||||||
|
// (current method) to (weighted) balancing before refinement.
|
||||||
|
maxLocalCells 1000000;
|
||||||
|
|
||||||
|
// Overall cell limit (approximately). Refinement will stop immediately
|
||||||
|
// upon reaching this number so a refinement level might not complete.
|
||||||
|
// Note that this is the number of cells before removing the part which
|
||||||
|
// is not 'visible' from the keepPoint. The final number of cells might
|
||||||
|
// actually be a lot less.
|
||||||
|
maxGlobalCells 20000000;
|
||||||
|
|
||||||
|
// The surface refinement loop might spend lots of iterations refining just
|
||||||
|
// a few cells. This setting will cause refinement to stop if
|
||||||
|
// <= minRefinementCells cells are selected for refinement. Note: it will
|
||||||
|
// at least do one iteration unless
|
||||||
|
// a: the number of cells to refine is 0
|
||||||
|
// b: minRefinementCells = -1. This is a special value indicating
|
||||||
|
// no refinement.
|
||||||
|
minRefinementCells 0;
|
||||||
|
|
||||||
|
// Allow a certain level of imbalance during refining
|
||||||
|
// (since balancing is quite expensive)
|
||||||
|
// Expressed as fraction of perfect balance (= overall number of cells /
|
||||||
|
// nProcs). 0=balance always.
|
||||||
|
maxLoadUnbalance 0.10;
|
||||||
|
|
||||||
|
// Number of buffer layers between different levels.
|
||||||
|
// 1 means normal 2:1 refinement restriction, larger means slower
|
||||||
|
// refinement.
|
||||||
|
nCellsBetweenLevels 4;
|
||||||
|
|
||||||
|
|
||||||
|
// Explicit feature edge refinement
|
||||||
|
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
// Specifies a level for any cell intersected by explicitly provided
|
||||||
|
// edges.
|
||||||
|
// This is a featureEdgeMesh, read from constant/triSurface for now.
|
||||||
|
// Specify 'levels' in the same way as the 'distance' mode in the
|
||||||
|
// refinementRegions (see below). The old specification
|
||||||
|
// level 2;
|
||||||
|
// is equivalent to
|
||||||
|
// levels ((0 2));
|
||||||
|
|
||||||
|
features
|
||||||
|
(
|
||||||
|
{
|
||||||
|
file "aerofoil.eMesh";
|
||||||
|
level 0; // Have level 2 for all cells intersected
|
||||||
|
// // by feature.
|
||||||
|
// levels ((0.1 2)); // Have level 2 for all cells within
|
||||||
|
// // 0.1 of feature.
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
// Surface based refinement
|
||||||
|
// ~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
// Specifies two levels for every surface. The first is the minimum level,
|
||||||
|
// every cell intersecting a surface gets refined up to the minimum level.
|
||||||
|
// The second level is the maximum level. Cells that 'see' multiple
|
||||||
|
// intersections where the intersections make an
|
||||||
|
// angle > resolveFeatureAngle get refined up to the maximum level.
|
||||||
|
|
||||||
|
refinementSurfaces
|
||||||
|
{
|
||||||
|
internalFace { level (0 0); faceZone internalFace; }//faceType baffle;}
|
||||||
|
aerofoil
|
||||||
|
{
|
||||||
|
// Surface-wise min and max refinement level
|
||||||
|
level (2 2);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//- Optional increment (on top of max level) in small gaps
|
||||||
|
//gapLevelIncrement 2;
|
||||||
|
|
||||||
|
//- Optional angle to detect small-large cell situation
|
||||||
|
// perpendicular to the surface. Is the angle of face w.r.t.
|
||||||
|
// the local surface normal. Use on flat(ish) surfaces only.
|
||||||
|
// Otherwise leave out or set to negative number.
|
||||||
|
//perpendicularAngle 10;
|
||||||
|
|
||||||
|
//- Optional faceZone and (for closed surface) cellZone with
|
||||||
|
// how to select the cells that are in the cellZone
|
||||||
|
// (inside / outside / specified insidePoint)
|
||||||
|
// The orientation of the faceZone is
|
||||||
|
// - if on cellZone(s) : point out of (minimum) cellZone
|
||||||
|
// - if freestanding : oriented according to surface
|
||||||
|
|
||||||
|
//faceZone sphere;
|
||||||
|
//cellZone sphere;
|
||||||
|
//cellZoneInside inside; // outside/insidePoint
|
||||||
|
//insidePoint (1 1 1); // if (cellZoneInside == insidePoint)
|
||||||
|
|
||||||
|
//- Optional specification of what to do with faceZone faces:
|
||||||
|
// internal : keep them as internal faces (default)
|
||||||
|
// baffle : create baffles from them. This gives more
|
||||||
|
// freedom in mesh motion
|
||||||
|
// boundary : create free-standing boundary faces (baffles
|
||||||
|
// but without the shared points)
|
||||||
|
//faceType baffle;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Feature angle:
|
||||||
|
// - used if min and max refinement level of a surface differ
|
||||||
|
// - used if feature snapping (see snapControls below) is used
|
||||||
|
resolveFeatureAngle 30;
|
||||||
|
|
||||||
|
//- Optional increment (on top of max level) in small gaps
|
||||||
|
//gapLevelIncrement 2;
|
||||||
|
|
||||||
|
|
||||||
|
// Planar angle:
|
||||||
|
// - used to determine if surface normals
|
||||||
|
// are roughly the same or opposite. Used
|
||||||
|
// - in proximity refinement
|
||||||
|
// - to decide when to merge free-standing baffles
|
||||||
|
// (if e.g. running in surfaceSimplify mode set this to 180 to
|
||||||
|
// merge all baffles)
|
||||||
|
// - in snapping to avoid snapping to nearest on 'wrong' side
|
||||||
|
// of thin gap
|
||||||
|
//
|
||||||
|
// If not specified same as resolveFeatureAngle
|
||||||
|
planarAngle 30;
|
||||||
|
|
||||||
|
|
||||||
|
// Region-wise refinement
|
||||||
|
// ~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
// Specifies refinement level for cells in relation to a surface. One of
|
||||||
|
// three modes
|
||||||
|
// - distance. 'levels' specifies per distance to the surface the
|
||||||
|
// wanted refinement level. The distances need to be specified in
|
||||||
|
// increasing order.
|
||||||
|
// - inside. 'levels' is only one entry and only the level is used. All
|
||||||
|
// cells inside the surface get refined up to the level. The surface
|
||||||
|
// needs to be closed for this to be possible.
|
||||||
|
// - outside. Same but cells outside.
|
||||||
|
|
||||||
|
refinementRegions
|
||||||
|
{
|
||||||
|
// refinement1
|
||||||
|
// {
|
||||||
|
// mode inside;
|
||||||
|
// levels ((1.0 1));
|
||||||
|
// }
|
||||||
|
/*
|
||||||
|
//sphere.stl
|
||||||
|
//{
|
||||||
|
// mode inside;
|
||||||
|
// levels ((1.0 4));
|
||||||
|
// // Optional override of uniform refinement level such
|
||||||
|
// // that in small gaps we're getting more cells.
|
||||||
|
// // The specification is
|
||||||
|
// // - numGapCells : minimum number of cells in the gap
|
||||||
|
// // (usually >3; lower than this might not
|
||||||
|
// // resolve correctly)
|
||||||
|
// // - minLevel : min refinement level at which to kick in
|
||||||
|
// // - maxLevel : upper refinement level (to avoid refinement
|
||||||
|
// // continuing on a single extraneous feature)
|
||||||
|
// // All three settings can be overridden on a surface by
|
||||||
|
// // surface basis in the refinementSurfaces section.
|
||||||
|
// gapLevel (<numGapCells> <minLevel> <maxlevel>);
|
||||||
|
// // Optional: when doing the gapLevel refinement directly remove
|
||||||
|
// // based on orientation w.r.t. gap. This limits the
|
||||||
|
// // amount of cells before doing the 'locationInMesh'
|
||||||
|
// // cell selection. Default is 'mixed' i.e. keep cells
|
||||||
|
// // whilst doing the gap-level refinement.
|
||||||
|
// //gapMode inside; // inside/outside/mixed
|
||||||
|
//}
|
||||||
|
|
||||||
|
//wakeBox
|
||||||
|
//{
|
||||||
|
// mode inside;
|
||||||
|
// // Dummy base level
|
||||||
|
// levels ((10000 0));
|
||||||
|
//
|
||||||
|
// // Optional directional refinement (after all other refinement)
|
||||||
|
// // Directional refinement
|
||||||
|
// // for all cells according to 'mode' ('inside' or 'outside';
|
||||||
|
// // 'distance' not supported) and within certain range. E.g.
|
||||||
|
// // - for all cells with level 2-5
|
||||||
|
// // - do one split in x direction
|
||||||
|
// levelIncrement (2 5 (1 0 0));
|
||||||
|
//
|
||||||
|
// // Note
|
||||||
|
// // - ignores 'levels' and gap* settings.
|
||||||
|
// // - the cellLevel/pointLevels files are no longer consistent
|
||||||
|
// // with the mesh, the resulting mesh is no longer compatible
|
||||||
|
// // with e.g. dynamic refinement/unrefinement.
|
||||||
|
// // - cellLevel will include any directional refinement
|
||||||
|
// // (i.e. it will be the maximum of all three directions)
|
||||||
|
//}
|
||||||
|
|
||||||
|
//wakeBox
|
||||||
|
//{
|
||||||
|
// mode inside;
|
||||||
|
// // Dummy base level
|
||||||
|
// levels ((10000 0));
|
||||||
|
//
|
||||||
|
// // Optional directional refinement (after all other refinement)
|
||||||
|
// // Directional refinement
|
||||||
|
// // for all cells according to 'mode' ('inside' or 'outside';
|
||||||
|
// // 'distance' not supported) and within certain range. E.g.
|
||||||
|
// // - for all cells with level 2-5
|
||||||
|
// // - do one split in x direction
|
||||||
|
// levelIncrement (2 5 (1 0 0));
|
||||||
|
//
|
||||||
|
// // Note
|
||||||
|
// // - ignores 'levels' and gap* settings.
|
||||||
|
// // - the cellLevel/pointLevels files are no longer consistent
|
||||||
|
// // with the mesh, the resulting mesh is no longer compatible
|
||||||
|
// // with e.g. dynamic refinement/unrefinement.
|
||||||
|
// // - cellLevel will include any directional refinement
|
||||||
|
// // (i.e. it will be the maximum of all three directions)
|
||||||
|
//
|
||||||
|
// // Optional directional expansion-ratio smoothing (after all
|
||||||
|
// // refinement). This will try to smooth out edge/cell size jumps
|
||||||
|
// // Specify smoothing direction and number of iterations
|
||||||
|
// smoothDirection (1 0 0);
|
||||||
|
// // Smoothing of expansion ratio
|
||||||
|
// nSmoothExpansion 100;
|
||||||
|
// // Smoothing of positions
|
||||||
|
// nSmoothPosition 100;
|
||||||
|
//}
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Optionally limit refinement in geometric region. This limits all
|
||||||
|
// refinement (from features, refinementSurfaces, refinementRegions)
|
||||||
|
// in a given geometric region. The syntax is exactly the same as for the
|
||||||
|
// refinementRegions; the cell level now specifies the upper limit
|
||||||
|
// for any cell. (a special setting is cell level -1 which will remove
|
||||||
|
// any cells inside the region). Note that it does not override the
|
||||||
|
// refinement constraints given by the nCellsBetweenLevels setting.
|
||||||
|
limitRegions
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Mesh selection
|
||||||
|
// ~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
// After refinement patches get added for all refinementSurfaces and
|
||||||
|
// all cells intersecting the surfaces get put into these patches. The
|
||||||
|
// section reachable from the location(s)InMesh is kept.
|
||||||
|
// NOTE: This point should never be on a face, always inside a cell, even
|
||||||
|
// after refinement.
|
||||||
|
//
|
||||||
|
// There are two different ways of specifying the regions to keep:
|
||||||
|
// 1. a single locationInMesh. This is the unzoned part of the mesh.
|
||||||
|
// All the 'zoned' surfaces are marked as such
|
||||||
|
// in the refinementSurfaces with the faceZone and cellZone keywords.
|
||||||
|
// It is illegal to have the locationInMesh inside a surface for which
|
||||||
|
// a cellZone is specified.
|
||||||
|
//
|
||||||
|
// or
|
||||||
|
//
|
||||||
|
// 2. multiple locationsInMesh, with per location the name of the cellZone.
|
||||||
|
// This uses walking to determine zones and automatically creates
|
||||||
|
// faceZones on the outside of cellZones. The special name 'none' is
|
||||||
|
// used to indicate the unzoned/background part of the mesh.
|
||||||
|
|
||||||
|
|
||||||
|
// Ad 1. Specify a single location and how to treat faces inbetween
|
||||||
|
// cellZones
|
||||||
|
locationInMesh (-0.457 -0.5 0.43);
|
||||||
|
|
||||||
|
// Whether any faceZones (as specified in the refinementSurfaces)
|
||||||
|
// are only on the boundary of corresponding cellZones.
|
||||||
|
// Not used if there are no faceZones. The behaviour has changed
|
||||||
|
// with respect to previous versions:
|
||||||
|
// true : all intersections with surface are put in faceZone
|
||||||
|
// (same behaviour as before)
|
||||||
|
// false : depending on the type of surface intersected:
|
||||||
|
// - if intersecting surface has faceZone only (so no cellZone)
|
||||||
|
// leave in faceZone (so behave as if set to true) (= changed
|
||||||
|
// behaviour)
|
||||||
|
// - if intersecting surface has faceZone and cellZone
|
||||||
|
// remove if inbetween same cellZone or if on boundary
|
||||||
|
// (same behaviour as before)
|
||||||
|
allowFreeStandingZoneFaces true;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// 2. Specify multiple locations with optional cellZones for the
|
||||||
|
// regions (use cellZone "none" to specify the unzoned cells)
|
||||||
|
// FaceZones are automatically constructed from the
|
||||||
|
// names of the cellZones: <cellZoneA> _to_ <cellZoneB>
|
||||||
|
// where the cellZoneA is the lowest numbered cellZone (non-cellZone
|
||||||
|
// cells are in a special region called "none" which is always
|
||||||
|
// last).
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Optional locations that should not be reachable from
|
||||||
|
// location(s)InMesh
|
||||||
|
// locationsOutsideMesh ((100 100 100));
|
||||||
|
|
||||||
|
// Optional: do not remove cells likely to give snapping problems
|
||||||
|
// handleSnapProblems false;
|
||||||
|
|
||||||
|
// Optional: switch off topological test for cells to-be-squashed
|
||||||
|
// and use geometric test instead
|
||||||
|
//useTopologicalSnapDetection false;
|
||||||
|
|
||||||
|
// Optional: do not refine surface cells with opposite faces of
|
||||||
|
// differing refinement levels
|
||||||
|
//interfaceRefine false;
|
||||||
|
|
||||||
|
// Optional: use an erosion instead of region assignment to allocate
|
||||||
|
// left-over cells to the background region (i.e. make cellZones
|
||||||
|
// consistent with the intersections of the surface).
|
||||||
|
// Erosion is specified as a number of erosion iterations.
|
||||||
|
// Erosion has less chance of bleeding and changing the zone
|
||||||
|
// for a complete region.
|
||||||
|
//nCellZoneErodeIter 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Settings for the snapping.
|
||||||
|
snapControls
|
||||||
|
{
|
||||||
|
// Number of patch smoothing iterations before finding correspondence
|
||||||
|
// to surface
|
||||||
|
nSmoothPatch 3;
|
||||||
|
|
||||||
|
// Optional: number of smoothing iterations for internal points on
|
||||||
|
// refinement interfaces. This will reduce non-orthogonality on
|
||||||
|
// refinement interfaces.
|
||||||
|
//nSmoothInternal $nSmoothPatch;
|
||||||
|
|
||||||
|
// Maximum relative distance for points to be attracted by surface.
|
||||||
|
// True distance is this factor times local maximum edge length.
|
||||||
|
tolerance 1.0;
|
||||||
|
|
||||||
|
// Number of mesh displacement relaxation iterations.
|
||||||
|
nSolveIter 30;
|
||||||
|
|
||||||
|
// Maximum number of snapping relaxation iterations. Should stop
|
||||||
|
// before upon reaching a correct mesh.
|
||||||
|
nRelaxIter 5;
|
||||||
|
|
||||||
|
// (wip) disable snapping to opposite near surfaces (revert to 22x
|
||||||
|
// behaviour)
|
||||||
|
// detectNearSurfacesSnap false;
|
||||||
|
|
||||||
|
|
||||||
|
// Feature snapping
|
||||||
|
|
||||||
|
// Number of feature edge snapping iterations.
|
||||||
|
// Leave out altogether to disable.
|
||||||
|
nFeatureSnapIter 10;
|
||||||
|
|
||||||
|
// Detect (geometric only) features by sampling the surface
|
||||||
|
// (default=false).
|
||||||
|
implicitFeatureSnap false;
|
||||||
|
|
||||||
|
// Use castellatedMeshControls::features (default = true)
|
||||||
|
explicitFeatureSnap true;
|
||||||
|
|
||||||
|
// Detect features between multiple surfaces
|
||||||
|
// (only for explicitFeatureSnap, default = false)
|
||||||
|
multiRegionFeatureSnap false;
|
||||||
|
|
||||||
|
|
||||||
|
//- When to run face splitting (never at first iteration, always
|
||||||
|
// at last iteration). Is interval. Default -1 (disabled)
|
||||||
|
//nFaceSplitInterval 5;
|
||||||
|
|
||||||
|
|
||||||
|
// (wip) Optional for explicit feature snapping:
|
||||||
|
//- Detect baffle edges. Default is true.
|
||||||
|
//detectBaffles false;
|
||||||
|
//- On any faces where points are on multiple regions (see
|
||||||
|
// multiRegionFeatureSnap) have the other points follow these points
|
||||||
|
// instead of having their own independent movement, i.e. have snapping
|
||||||
|
// to multi-region edges/points take priority. This might aid snapping
|
||||||
|
// to sharp edges that are also region edges. The default is false.
|
||||||
|
//releasePoints true;
|
||||||
|
//- Walk along feature edges, adding missing ones. Default is true.
|
||||||
|
//stringFeatures false;
|
||||||
|
//- If diagonal attraction also attract other face points. Default is
|
||||||
|
// false
|
||||||
|
//avoidDiagonal true;
|
||||||
|
//- When splitting what concave faces to leave intact. Default is 45
|
||||||
|
// degrees.
|
||||||
|
//concaveAngle 30;
|
||||||
|
//- When splitting the minimum area ratio of faces. If face split
|
||||||
|
// causes ratio of area less than this do not split. Default is 0.3
|
||||||
|
//minAreaRatio 0.3;
|
||||||
|
//- Attract points only to the surface they originate from. Default
|
||||||
|
// false. This can improve snapping of intersecting surfaces.
|
||||||
|
strictRegionSnap true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Settings for the layer addition.
|
||||||
|
addLayersControls
|
||||||
|
{
|
||||||
|
// Are the thickness parameters below relative to the undistorted
|
||||||
|
// size of the refined cell outside layer (true) or absolute sizes (false).
|
||||||
|
relativeSizes true;
|
||||||
|
|
||||||
|
// Layer thickness specification. This can be specified in one of following
|
||||||
|
// ways:
|
||||||
|
// - expansionRatio and finalLayerThickness (cell nearest internal mesh)
|
||||||
|
// - expansionRatio and firstLayerThickness (cell on surface)
|
||||||
|
// - overall thickness and firstLayerThickness
|
||||||
|
// - overall thickness and finalLayerThickness
|
||||||
|
// - overall thickness and expansionRatio
|
||||||
|
//
|
||||||
|
// Note: the mode thus selected is global, i.e. one cannot override the
|
||||||
|
// mode on a per-patch basis (only the values can be overridden)
|
||||||
|
|
||||||
|
// Expansion factor for layer mesh
|
||||||
|
expansionRatio 1.5;
|
||||||
|
|
||||||
|
// Wanted thickness of the layer furthest away from the wall.
|
||||||
|
// If relativeSizes this is relative to undistorted size of cell
|
||||||
|
// outside layer.
|
||||||
|
finalLayerThickness 0.3;
|
||||||
|
|
||||||
|
// Wanted thickness of the layer next to the wall.
|
||||||
|
// If relativeSizes this is relative to undistorted size of cell
|
||||||
|
// outside layer.
|
||||||
|
//firstLayerThickness 0.3;
|
||||||
|
|
||||||
|
// Wanted overall thickness of layers.
|
||||||
|
// If relativeSizes this is relative to undistorted size of cell
|
||||||
|
// outside layer.
|
||||||
|
//thickness 0.5
|
||||||
|
|
||||||
|
|
||||||
|
// Minimum overall thickness of total layers. If for any reason layer
|
||||||
|
// cannot be above minThickness do not add layer.
|
||||||
|
// If relativeSizes this is relative to undistorted size of cell
|
||||||
|
// outside layer..
|
||||||
|
minThickness 0.1;
|
||||||
|
|
||||||
|
|
||||||
|
// Per final patch or faceZone (so not geometry!) the layer information
|
||||||
|
// Note: This behaviour changed after 21x. Any non-mentioned patches
|
||||||
|
// now slide unless:
|
||||||
|
// - nSurfaceLayers is explicitly mentioned to be 0.
|
||||||
|
// - angle to nearest surface < slipFeatureAngle (see below)
|
||||||
|
layers
|
||||||
|
{
|
||||||
|
"internalFace.*" {nSurfaceLayers 20; }
|
||||||
|
aerofoil
|
||||||
|
{
|
||||||
|
nSurfaceLayers 20;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If points get not extruded do nGrow layers of connected faces that are
|
||||||
|
// also not grown. This helps convergence of the layer addition process
|
||||||
|
// close to features.
|
||||||
|
// Note: changed(corrected) w.r.t 1.7.x! (didn't do anything in 1.7.x)
|
||||||
|
nGrow -1;
|
||||||
|
|
||||||
|
// Advanced settings
|
||||||
|
|
||||||
|
|
||||||
|
// Static analysis of starting mesh
|
||||||
|
|
||||||
|
// When not to extrude surface. 0 is flat surface, 90 is when two faces
|
||||||
|
// are perpendicular. Note: was not working correctly < 1806
|
||||||
|
featureAngle 180;
|
||||||
|
|
||||||
|
// When to merge patch faces. Default is featureAngle. Useful when
|
||||||
|
// featureAngle is large.
|
||||||
|
//mergePatchFacesAngle 45;
|
||||||
|
|
||||||
|
// Stop layer growth on highly warped cells
|
||||||
|
maxFaceThicknessRatio 1000;//0.5;
|
||||||
|
|
||||||
|
|
||||||
|
// Patch displacement
|
||||||
|
|
||||||
|
// Number of smoothing iterations of surface normals
|
||||||
|
nSmoothSurfaceNormals 1;
|
||||||
|
|
||||||
|
// Smooth layer thickness over surface patches
|
||||||
|
nSmoothThickness 10;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Choice of mesh shrinking algorithm
|
||||||
|
|
||||||
|
// Optional mesh shrinking algorithm (default is displacementMedialAxis)
|
||||||
|
// The displacementMotionSolver is a wrapper around the displacement
|
||||||
|
// motion solvers. It needs specification of the solver to use and
|
||||||
|
// its control dictionary.
|
||||||
|
//meshShrinker displacementMotionSolver;
|
||||||
|
//solver displacementLaplacian;
|
||||||
|
//displacementLaplacianCoeffs
|
||||||
|
//{
|
||||||
|
// diffusivity quadratic inverseDistance
|
||||||
|
// (
|
||||||
|
// sphere.stl_firstSolid
|
||||||
|
// maxY
|
||||||
|
// );
|
||||||
|
//}
|
||||||
|
// Note that e.g. displacementLaplacian needs entries in
|
||||||
|
// fvSchemes, fvSolution. Also specify a minIter > 1 when solving
|
||||||
|
// cellDisplacement since otherwise solution might not be sufficiently
|
||||||
|
// accurate on points.
|
||||||
|
|
||||||
|
|
||||||
|
// Medial axis analysis (for use with default displacementMedialAxis)
|
||||||
|
|
||||||
|
// Angle used to pick up medial axis points
|
||||||
|
// Note: changed(corrected) w.r.t 1.7.x! 90 degrees corresponds to 130
|
||||||
|
// in 1.7.x.
|
||||||
|
minMedialAxisAngle 90;
|
||||||
|
|
||||||
|
// Reduce layer growth where ratio thickness to medial
|
||||||
|
// distance is large
|
||||||
|
maxThicknessToMedialRatio 0.3;
|
||||||
|
|
||||||
|
// Number of smoothing iterations of interior mesh movement direction
|
||||||
|
nSmoothNormals 3;
|
||||||
|
|
||||||
|
// Optional: limit the number of steps walking away from the surface.
|
||||||
|
// Default is unlimited.
|
||||||
|
//nMedialAxisIter 10;
|
||||||
|
|
||||||
|
// Optional: smooth displacement after medial axis determination.
|
||||||
|
// default is 0.
|
||||||
|
//nSmoothDisplacement 90;
|
||||||
|
|
||||||
|
// (wip)Optional: do not extrude any point where
|
||||||
|
// (false) : all surrounding faces are not fully extruded
|
||||||
|
// (true) : all surrounding points are not extruded
|
||||||
|
// Default is false.
|
||||||
|
//detectExtrusionIsland true;
|
||||||
|
|
||||||
|
// Optional: do not extrude around sharp edges if both faces are not
|
||||||
|
// fully extruded i.e. if one of the faces on either side would
|
||||||
|
// become a wedge.
|
||||||
|
// Default is 0.5*featureAngle. Set to -180 always attempt extrusion
|
||||||
|
//layerTerminationAngle 25;
|
||||||
|
|
||||||
|
// Optional: disable shrinking of edges that have one (or two) points
|
||||||
|
// on an extruded patch.
|
||||||
|
// Default is false to enable single/two cell thick channels to still
|
||||||
|
// have layers. In <=1806 this was true by default. On larger gaps it
|
||||||
|
// should have no effect.
|
||||||
|
//disableWallEdges true;
|
||||||
|
|
||||||
|
// Optional: at non-patched sides allow mesh to slip if extrusion
|
||||||
|
// direction makes angle larger than slipFeatureAngle. Default is
|
||||||
|
// 0.5*featureAngle.
|
||||||
|
slipFeatureAngle 10;
|
||||||
|
|
||||||
|
// Maximum number of snapping relaxation iterations. Should stop
|
||||||
|
// before upon reaching a correct mesh.
|
||||||
|
nRelaxIter 5;
|
||||||
|
|
||||||
|
|
||||||
|
// Mesh shrinking
|
||||||
|
|
||||||
|
// Create buffer region for new layer terminations, i.e. gradually
|
||||||
|
// step down number of layers. Set to <0 to terminate layer in one go.
|
||||||
|
nBufferCellsNoExtrude 0;
|
||||||
|
|
||||||
|
// Overall max number of layer addition iterations. The mesher will
|
||||||
|
// exit if it reaches this number of iterations; possibly with an
|
||||||
|
// illegal mesh.
|
||||||
|
nLayerIter 50;
|
||||||
|
|
||||||
|
// Max number of iterations after which relaxed meshQuality controls
|
||||||
|
// get used. Up to nRelaxedIter it uses the settings in
|
||||||
|
// meshQualityControls,
|
||||||
|
// after nRelaxedIter it uses the values in
|
||||||
|
// meshQualityControls::relaxed.
|
||||||
|
nRelaxedIter 0;
|
||||||
|
|
||||||
|
// Additional reporting: if there are just a few faces where there
|
||||||
|
// are mesh errors (after adding the layers) print their face centres.
|
||||||
|
// This helps in tracking down problematic mesh areas.
|
||||||
|
//additionalReporting true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generic mesh quality settings. At any undoable phase these determine
|
||||||
|
// where to undo.
|
||||||
|
meshQualityControls
|
||||||
|
{
|
||||||
|
// Specify mesh quality constraints in separate dictionary so can
|
||||||
|
// be reused (e.g. checkMesh -meshQuality)
|
||||||
|
#include "meshQualityDict"
|
||||||
|
|
||||||
|
minDeterminant 1e-8;
|
||||||
|
|
||||||
|
// Optional : some meshing phases allow usage of relaxed rules.
|
||||||
|
// See e.g. addLayersControls::nRelaxedIter.
|
||||||
|
relaxed
|
||||||
|
{
|
||||||
|
// Maximum non-orthogonality allowed. Set to 180 to disable.
|
||||||
|
maxNonOrtho 75;
|
||||||
|
minTetQuality -1e30;
|
||||||
|
minTwist -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Advanced
|
||||||
|
|
||||||
|
// Number of error distribution iterations
|
||||||
|
nSmoothScale 4;
|
||||||
|
// amount to scale back displacement at error points
|
||||||
|
errorReduction 0.75;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Advanced
|
||||||
|
|
||||||
|
//// Debug flags
|
||||||
|
//debugFlags
|
||||||
|
//(
|
||||||
|
// mesh // write intermediate meshes
|
||||||
|
// intersections // write current mesh intersections as .obj files
|
||||||
|
// featureSeeds // write information about explicit feature edge
|
||||||
|
// // refinement
|
||||||
|
// attraction // write attraction as .obj files
|
||||||
|
// layerInfo // write information about layers
|
||||||
|
//);
|
||||||
|
//
|
||||||
|
//// Write flags
|
||||||
|
//writeFlags
|
||||||
|
//(
|
||||||
|
// scalarLevels // write volScalarField with cellLevel for postprocessing
|
||||||
|
// layerSets // write cellSets, faceSets of faces in layer
|
||||||
|
// layerFields // write volScalarField for layer coverage
|
||||||
|
//);
|
||||||
|
|
||||||
|
|
||||||
|
//// Format for writing lines. E.g. leak path. Default is vtk format.
|
||||||
|
//setFormat ensight;
|
||||||
|
|
||||||
|
// Merge tolerance. Is fraction of overall bounding box of initial mesh.
|
||||||
|
// Note: the write tolerance needs to be higher than this.
|
||||||
|
mergeTolerance 1e-6;
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -0,0 +1,47 @@
|
|||||||
|
/*--------------------------------*- C++ -*----------------------------------*\
|
||||||
|
| ========= | |
|
||||||
|
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
|
||||||
|
| \\ / O peration | Version: v1912 |
|
||||||
|
| \\ / A nd | Website: www.openfoam.com |
|
||||||
|
| \\/ M anipulation | |
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
FoamFile
|
||||||
|
{
|
||||||
|
version 2.0;
|
||||||
|
format ascii;
|
||||||
|
class dictionary;
|
||||||
|
object surfaceFeatureExtractDict;
|
||||||
|
}
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
aerofoil.stl
|
||||||
|
{
|
||||||
|
// Extract raw features (none | extractFromFile | extractFromSurface)
|
||||||
|
extractionMethod extractFromSurface;
|
||||||
|
|
||||||
|
// Mark edges whose adjacent surface normals are at an angle less
|
||||||
|
// than includedAngle as features
|
||||||
|
// - 0 : selects no edges
|
||||||
|
// - 180: selects all edges
|
||||||
|
includedAngle 120;
|
||||||
|
|
||||||
|
curvature true;
|
||||||
|
// Do not mark region edges
|
||||||
|
geometricTestOnly yes;
|
||||||
|
|
||||||
|
// Generate additional intersection features (none | self | region)
|
||||||
|
intersectionMethod none;
|
||||||
|
|
||||||
|
// Tolerance for surface intersections
|
||||||
|
// tolerance 1e-3;
|
||||||
|
|
||||||
|
// Output options:
|
||||||
|
|
||||||
|
// Write features to obj format for postprocessing
|
||||||
|
writeObj yes;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
Reference in New Issue
Block a user