mirror of
https://develop.openfoam.com/Development/openfoam.git
synced 2025-11-28 03:28:01 +00:00
Merge branch 'master' of /home/dm4/OpenFOAM/OpenFOAM-dev
This commit is contained in:
@ -96,8 +96,9 @@ bool Foam::cellSizeControlSurfaces::evalCellSizeFunctions
|
|||||||
|
|
||||||
if (cellSizeFunctions_.size())
|
if (cellSizeFunctions_.size())
|
||||||
{
|
{
|
||||||
// Initialise to the last (lowest) priority
|
// Maintain priority of current hit. Initialise so it always goes
|
||||||
label previousPriority = cellSizeFunctions_.last().priority();
|
// through at least once.
|
||||||
|
label previousPriority = -1;
|
||||||
|
|
||||||
forAll(cellSizeFunctions_, i)
|
forAll(cellSizeFunctions_, i)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -196,7 +196,7 @@ void Foam::conformalVoronoiMesh::buildSurfaceConformation
|
|||||||
{
|
{
|
||||||
if (vit->internalPoint() && !vit->nearBoundary())
|
if (vit->internalPoint() && !vit->nearBoundary())
|
||||||
{
|
{
|
||||||
const Foam::point& pt = topoint(vit->point());
|
pointFromPoint pt = topoint(vit->point());
|
||||||
const scalar range = sqr(2.0*targetCellSize(pt));
|
const scalar range = sqr(2.0*targetCellSize(pt));
|
||||||
|
|
||||||
pointIndexHit pHit;
|
pointIndexHit pHit;
|
||||||
|
|||||||
@ -238,6 +238,25 @@ int main(int argc, char *argv[])
|
|||||||
dict.lookup("constructFrom")
|
dict.lookup("constructFrom")
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Any merging of small edges
|
||||||
|
const scalar mergeTol(dict.lookupOrDefault<scalar>("mergeTol", 1e-4));
|
||||||
|
|
||||||
|
Info<< "Extruding from " << ExtrudeModeNames[mode]
|
||||||
|
<< " using model " << model().type() << endl;
|
||||||
|
if (flipNormals)
|
||||||
|
{
|
||||||
|
Info<< "Flipping normals before extruding" << endl;
|
||||||
|
}
|
||||||
|
if (mergeTol > 0)
|
||||||
|
{
|
||||||
|
Info<< "Collapsing edges < " << mergeTol << " of bounding box" << endl;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Info<< "Not collapsing any edges after extrusion" << endl;
|
||||||
|
}
|
||||||
|
Info<< endl;
|
||||||
|
|
||||||
|
|
||||||
// Generated mesh (one of either)
|
// Generated mesh (one of either)
|
||||||
autoPtr<fvMesh> meshFromMesh;
|
autoPtr<fvMesh> meshFromMesh;
|
||||||
@ -715,7 +734,7 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
const boundBox& bb = mesh.bounds();
|
const boundBox& bb = mesh.bounds();
|
||||||
const vector span = bb.span();
|
const vector span = bb.span();
|
||||||
const scalar mergeDim = 1e-4 * bb.minDim();
|
const scalar mergeDim = mergeTol * bb.minDim();
|
||||||
|
|
||||||
Info<< "Mesh bounding box : " << bb << nl
|
Info<< "Mesh bounding box : " << bb << nl
|
||||||
<< " with span : " << span << nl
|
<< " with span : " << span << nl
|
||||||
@ -726,6 +745,7 @@ int main(int argc, char *argv[])
|
|||||||
// Collapse edges
|
// Collapse edges
|
||||||
// ~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
if (mergeDim > 0)
|
||||||
{
|
{
|
||||||
Info<< "Collapsing edges < " << mergeDim << " ..." << nl << endl;
|
Info<< "Collapsing edges < " << mergeDim << " ..." << nl << endl;
|
||||||
|
|
||||||
|
|||||||
@ -88,4 +88,8 @@ sigmaRadialCoeffs
|
|||||||
// degree wedges.
|
// degree wedges.
|
||||||
mergeFaces false; //true;
|
mergeFaces false; //true;
|
||||||
|
|
||||||
|
// Merge small edges. Fraction of bounding box.
|
||||||
|
mergeTol 0;
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
========= |
|
========= |
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
\\ / O peration |
|
\\ / O peration |
|
||||||
\\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
|
\\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation
|
||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
@ -206,6 +206,14 @@ int main(int argc, char *argv[])
|
|||||||
runTime
|
runTime
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// cvMesh vertices
|
||||||
|
writeMeshObject<pointIOField>
|
||||||
|
(
|
||||||
|
"internalDelaunayVertices",
|
||||||
|
regionPrefix,
|
||||||
|
runTime
|
||||||
|
);
|
||||||
|
|
||||||
if (runTime.writeFormat() == IOstream::ASCII)
|
if (runTime.writeFormat() == IOstream::ASCII)
|
||||||
{
|
{
|
||||||
// Only do zones when converting from binary to ascii
|
// Only do zones when converting from binary to ascii
|
||||||
|
|||||||
@ -51,9 +51,6 @@ Foam::autoPtr<Foam::fvMesh> Foam::loadOrCreateMesh
|
|||||||
// Check who has a mesh
|
// Check who has a mesh
|
||||||
const bool haveMesh = isDir(io.time().path()/io.instance()/meshSubDir);
|
const bool haveMesh = isDir(io.time().path()/io.instance()/meshSubDir);
|
||||||
|
|
||||||
Pout<< "meshpath:" << io.time().path()/io.instance()/meshSubDir << endl;
|
|
||||||
Pout<< "haveMesh:" << haveMesh << endl;
|
|
||||||
|
|
||||||
if (!haveMesh)
|
if (!haveMesh)
|
||||||
{
|
{
|
||||||
// Create dummy mesh. Only used on procs that don't have mesh.
|
// Create dummy mesh. Only used on procs that don't have mesh.
|
||||||
@ -293,8 +290,10 @@ Pout<< "haveMesh:" << haveMesh << endl;
|
|||||||
if (!haveMesh)
|
if (!haveMesh)
|
||||||
{
|
{
|
||||||
// We created a dummy mesh file above. Delete it.
|
// We created a dummy mesh file above. Delete it.
|
||||||
//Pout<< "Removing dummy mesh " << io.objectPath() << endl;
|
const fileName meshFiles = io.time().path()/io.instance()/meshSubDir;
|
||||||
rmDir(io.objectPath());
|
//Pout<< "Removing dummy mesh " << meshFiles << endl;
|
||||||
|
mesh.removeFiles();
|
||||||
|
rmDir(meshFiles);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Force recreation of globalMeshData.
|
// Force recreation of globalMeshData.
|
||||||
|
|||||||
24
bin/foamPack
24
bin/foamPack
@ -3,7 +3,7 @@
|
|||||||
# ========= |
|
# ========= |
|
||||||
# \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
# \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
# \\ / O peration |
|
# \\ / O peration |
|
||||||
# \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
|
# \\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation
|
||||||
# \\/ M anipulation |
|
# \\/ M anipulation |
|
||||||
#------------------------------------------------------------------------------
|
#------------------------------------------------------------------------------
|
||||||
# License
|
# License
|
||||||
@ -107,15 +107,23 @@ then
|
|||||||
echo "pack manually" 1>&2
|
echo "pack manually" 1>&2
|
||||||
foamPackSource $packDir $packFile
|
foamPackSource $packDir $packFile
|
||||||
else
|
else
|
||||||
echo "pack with git-archive" 1>&2
|
if [ ! -f $packDir/.build ]
|
||||||
( cd $packDir && git archive --format=tar --prefix=$packDir/ HEAD) > $packBase.tar
|
then
|
||||||
|
echo "Error: $packDir/.build does not exists" 1>&2
|
||||||
|
echo " Please update this by running e.g. 'wmakePrintBuild -update' in $packDir" 1>&2
|
||||||
|
exit 2
|
||||||
|
fi
|
||||||
|
|
||||||
echo "add in time-stamp and lnInclude directories" 1>&2
|
|
||||||
tar cf $packBase.tar2 $packDir/.timeStamp $packDir/.build `find -H $packDir -type d -name lnInclude`
|
|
||||||
tar Af $packBase.tar $packBase.tar2
|
|
||||||
|
|
||||||
echo "gzip tar file" 1>&2
|
echo "pack with git-archive" 1>&2 &&
|
||||||
gzip -c9 $packBase.tar > $packFile
|
( cd $packDir && git archive --format=tar --prefix=$packDir/ HEAD) > $packBase.tar &&
|
||||||
|
|
||||||
|
echo "add in time-stamp and lnInclude directories" 1>&2 &&
|
||||||
|
tar cf $packBase.tar2 $packDir/.timeStamp $packDir/.build `find -H $packDir -type d -name lnInclude` &&
|
||||||
|
tar Af $packBase.tar $packBase.tar2 &&
|
||||||
|
|
||||||
|
echo "gzip tar file" 1>&2 &&
|
||||||
|
gzip -c9 $packBase.tar > $packFile &&
|
||||||
rm -f $packBase.tar $packBase.tar2 2>/dev/null
|
rm -f $packBase.tar $packBase.tar2 2>/dev/null
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|||||||
@ -1217,7 +1217,7 @@ const Foam::globalMeshData& Foam::polyMesh::globalData() const
|
|||||||
// Remove all files and some subdirs (eg, sets)
|
// Remove all files and some subdirs (eg, sets)
|
||||||
void Foam::polyMesh::removeFiles(const fileName& instanceDir) const
|
void Foam::polyMesh::removeFiles(const fileName& instanceDir) const
|
||||||
{
|
{
|
||||||
fileName meshFilesPath = thisDb().path()/instanceDir/meshDir();
|
fileName meshFilesPath = thisDb().time().path()/instanceDir/meshDir();
|
||||||
|
|
||||||
rm(meshFilesPath/"points");
|
rm(meshFilesPath/"points");
|
||||||
rm(meshFilesPath/"faces");
|
rm(meshFilesPath/"faces");
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
========= |
|
========= |
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
\\ / O peration |
|
\\ / O peration |
|
||||||
\\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
|
\\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation
|
||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
@ -58,7 +58,7 @@ void Foam::ptscotchDecomp::check(const int retVal, const char* str)
|
|||||||
{}
|
{}
|
||||||
|
|
||||||
|
|
||||||
Foam::label Foam::ptscotchDecomp::decomposeZeroDomains
|
Foam::label Foam::ptscotchDecomp::decompose
|
||||||
(
|
(
|
||||||
const fileName& meshPath,
|
const fileName& meshPath,
|
||||||
const List<int>& initxadj,
|
const List<int>& initxadj,
|
||||||
@ -72,6 +72,7 @@ Foam::label Foam::ptscotchDecomp::decomposeZeroDomains
|
|||||||
(
|
(
|
||||||
"label ptscotchDecomp::decompose"
|
"label ptscotchDecomp::decompose"
|
||||||
"("
|
"("
|
||||||
|
"onst fileName&,"
|
||||||
"const List<int>&, "
|
"const List<int>&, "
|
||||||
"const List<int>&, "
|
"const List<int>&, "
|
||||||
"const scalarField&, "
|
"const scalarField&, "
|
||||||
@ -84,8 +85,10 @@ Foam::label Foam::ptscotchDecomp::decomposeZeroDomains
|
|||||||
Foam::label Foam::ptscotchDecomp::decompose
|
Foam::label Foam::ptscotchDecomp::decompose
|
||||||
(
|
(
|
||||||
const fileName& meshPath,
|
const fileName& meshPath,
|
||||||
const List<int>& adjncy,
|
const int adjncySize,
|
||||||
const List<int>& xadj,
|
const int adjncy[],
|
||||||
|
const int xadjSize,
|
||||||
|
const int xadj[],
|
||||||
const scalarField& cWeights,
|
const scalarField& cWeights,
|
||||||
List<int>& finalDecomp
|
List<int>& finalDecomp
|
||||||
) const
|
) const
|
||||||
@ -94,9 +97,12 @@ Foam::label Foam::ptscotchDecomp::decompose
|
|||||||
(
|
(
|
||||||
"label ptscotchDecomp::decompose"
|
"label ptscotchDecomp::decompose"
|
||||||
"("
|
"("
|
||||||
"const List<int>&, "
|
"const fileName&,"
|
||||||
"const List<int>&, "
|
"const int,"
|
||||||
"const scalarField&, "
|
"const int,"
|
||||||
|
"const int,"
|
||||||
|
"const int,"
|
||||||
|
"const scalarField&,"
|
||||||
"List<int>&"
|
"List<int>&"
|
||||||
")"
|
")"
|
||||||
) << notImplementedMessage << exit(FatalError);
|
) << notImplementedMessage << exit(FatalError);
|
||||||
|
|||||||
@ -439,6 +439,86 @@ void Foam::autoLayerDriver::handleFeatureAngle
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//Foam::tmp<Foam::scalarField> Foam::autoLayerDriver::undistortedEdgeLength
|
||||||
|
//(
|
||||||
|
// const indirectPrimitivePatch& pp,
|
||||||
|
// const bool relativeSizes,
|
||||||
|
// const bool faceSize
|
||||||
|
//)
|
||||||
|
//{
|
||||||
|
// const fvMesh& mesh = meshRefiner_.mesh();
|
||||||
|
//
|
||||||
|
// tmp<scalarField> tfld(new scalarField());
|
||||||
|
// scalarField& fld = tfld();
|
||||||
|
//
|
||||||
|
// if (faceSize)
|
||||||
|
// {
|
||||||
|
// fld.setSize(pp.size());
|
||||||
|
// }
|
||||||
|
// else
|
||||||
|
// {
|
||||||
|
// fld.setSize(pp.nPoints());
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// if (relativeSizes)
|
||||||
|
// {
|
||||||
|
// const scalar edge0Len = meshRefiner_.meshCutter().level0EdgeLength();
|
||||||
|
// const labelList& cellLevel = meshRefiner_.meshCutter().cellLevel();
|
||||||
|
//
|
||||||
|
// if (faceSize)
|
||||||
|
// {
|
||||||
|
// forAll(pp, i)
|
||||||
|
// {
|
||||||
|
// label faceI = pp.addressing()[i];
|
||||||
|
// label ownLevel = cellLevel[mesh.faceOwner()[faceI]];
|
||||||
|
// fld[i] = edge0Len/(1<<ownLevel);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// else
|
||||||
|
// {
|
||||||
|
// // Determine per point the max cell level of connected cells
|
||||||
|
// // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
//
|
||||||
|
// labelList maxPointLevel(pp.nPoints(), labelMin);
|
||||||
|
//
|
||||||
|
// forAll(pp, i)
|
||||||
|
// {
|
||||||
|
// label faceI = pp.addressing()[i];
|
||||||
|
// label ownLevel = cellLevel[mesh.faceOwner()[faceI]];
|
||||||
|
//
|
||||||
|
// const face& f = pp.localFaces()[i];
|
||||||
|
// forAll(f, fp)
|
||||||
|
// {
|
||||||
|
// maxPointLevel[f[fp]] =
|
||||||
|
// max(maxPointLevel[f[fp]], ownLevel);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// syncTools::syncPointList
|
||||||
|
// (
|
||||||
|
// mesh,
|
||||||
|
// pp.meshPoints(),
|
||||||
|
// maxPointLevel,
|
||||||
|
// maxEqOp<label>(),
|
||||||
|
// labelMin // null value
|
||||||
|
// );
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// forAll(maxPointLevel, pointI)
|
||||||
|
// {
|
||||||
|
// // Find undistorted edge size for this level.
|
||||||
|
// fld[i] = edge0Len/(1<<maxPointLevel[pointI]);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// else
|
||||||
|
// {
|
||||||
|
// // Use actual cell size
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
|
||||||
|
|
||||||
// No extrusion on cells with warped faces. Calculates the thickness of the
|
// No extrusion on cells with warped faces. Calculates the thickness of the
|
||||||
// layer and compares it to the space the warped face takes up. Disables
|
// layer and compares it to the space the warped face takes up. Disables
|
||||||
// extrusion if layer thickness is more than faceRatio of the thickness of
|
// extrusion if layer thickness is more than faceRatio of the thickness of
|
||||||
@ -2383,22 +2463,27 @@ void Foam::autoLayerDriver::addLayers
|
|||||||
|
|
||||||
// Disable extrusion on warped faces
|
// Disable extrusion on warped faces
|
||||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
// It is hard to calculate some length scale if not in relative
|
||||||
|
// mode so disable this check.
|
||||||
|
if (layerParams.relativeSizes())
|
||||||
|
{
|
||||||
|
// Undistorted edge length
|
||||||
|
const scalar edge0Len =
|
||||||
|
meshRefiner_.meshCutter().level0EdgeLength();
|
||||||
|
const labelList& cellLevel = meshRefiner_.meshCutter().cellLevel();
|
||||||
|
|
||||||
// Undistorted edge length
|
handleWarpedFaces
|
||||||
const scalar edge0Len = meshRefiner_.meshCutter().level0EdgeLength();
|
(
|
||||||
const labelList& cellLevel = meshRefiner_.meshCutter().cellLevel();
|
pp,
|
||||||
|
layerParams.maxFaceThicknessRatio(),
|
||||||
|
edge0Len,
|
||||||
|
cellLevel,
|
||||||
|
|
||||||
handleWarpedFaces
|
patchDisp,
|
||||||
(
|
patchNLayers,
|
||||||
pp,
|
extrudeStatus
|
||||||
layerParams.maxFaceThicknessRatio(),
|
);
|
||||||
edge0Len,
|
}
|
||||||
cellLevel,
|
|
||||||
|
|
||||||
patchDisp,
|
|
||||||
patchNLayers,
|
|
||||||
extrudeStatus
|
|
||||||
);
|
|
||||||
|
|
||||||
//// Disable extrusion on cells with multiple patch faces
|
//// Disable extrusion on cells with multiple patch faces
|
||||||
//// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
//// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
@ -2585,6 +2670,21 @@ void Foam::autoLayerDriver::addLayers
|
|||||||
dimensionedScalar("medialRatio", dimless, 0.0)
|
dimensionedScalar("medialRatio", dimless, 0.0)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
pointVectorField medialVec
|
||||||
|
(
|
||||||
|
IOobject
|
||||||
|
(
|
||||||
|
"medialVec",
|
||||||
|
meshRefiner_.timeName(),
|
||||||
|
mesh,
|
||||||
|
IOobject::NO_READ,
|
||||||
|
IOobject::NO_WRITE,
|
||||||
|
false
|
||||||
|
),
|
||||||
|
meshMover().pMesh(),
|
||||||
|
dimensionedVector("medialVec", dimLength, vector::zero)
|
||||||
|
);
|
||||||
|
|
||||||
// Setup information for medial axis smoothing. Calculates medial axis
|
// Setup information for medial axis smoothing. Calculates medial axis
|
||||||
// and a smoothed displacement direction.
|
// and a smoothed displacement direction.
|
||||||
// - pointMedialDist : distance to medial axis
|
// - pointMedialDist : distance to medial axis
|
||||||
@ -2600,7 +2700,8 @@ void Foam::autoLayerDriver::addLayers
|
|||||||
|
|
||||||
dispVec,
|
dispVec,
|
||||||
medialRatio,
|
medialRatio,
|
||||||
pointMedialDist
|
pointMedialDist,
|
||||||
|
medialVec
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
@ -2692,6 +2793,7 @@ void Foam::autoLayerDriver::addLayers
|
|||||||
dispVec,
|
dispVec,
|
||||||
medialRatio,
|
medialRatio,
|
||||||
pointMedialDist,
|
pointMedialDist,
|
||||||
|
medialVec,
|
||||||
|
|
||||||
extrudeStatus,
|
extrudeStatus,
|
||||||
patchDisp,
|
patchDisp,
|
||||||
@ -2830,7 +2932,7 @@ void Foam::autoLayerDriver::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
|
||||||
static_cast<polyMesh&>(mesh).readOpt(),
|
IOobject::NO_READ,
|
||||||
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
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
========= |
|
========= |
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
\\ / O peration |
|
\\ / O peration |
|
||||||
\\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
|
\\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation
|
||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
@ -460,7 +460,8 @@ class autoLayerDriver
|
|||||||
|
|
||||||
pointVectorField& dispVec,
|
pointVectorField& dispVec,
|
||||||
pointScalarField& medialRatio,
|
pointScalarField& medialRatio,
|
||||||
pointScalarField& medialDist
|
pointScalarField& medialDist,
|
||||||
|
pointVectorField& medialVec
|
||||||
) const;
|
) const;
|
||||||
|
|
||||||
//- Main routine to shrink mesh
|
//- Main routine to shrink mesh
|
||||||
@ -481,6 +482,7 @@ class autoLayerDriver
|
|||||||
const pointVectorField& dispVec,
|
const pointVectorField& dispVec,
|
||||||
const pointScalarField& medialRatio,
|
const pointScalarField& medialRatio,
|
||||||
const pointScalarField& medialDist,
|
const pointScalarField& medialDist,
|
||||||
|
const pointVectorField& medialVec,
|
||||||
|
|
||||||
List<extrudeMode>& extrudeStatus,
|
List<extrudeMode>& extrudeStatus,
|
||||||
pointField& patchDisp,
|
pointField& patchDisp,
|
||||||
|
|||||||
@ -689,7 +689,8 @@ void Foam::autoLayerDriver::medialAxisSmoothingInfo
|
|||||||
|
|
||||||
pointVectorField& dispVec,
|
pointVectorField& dispVec,
|
||||||
pointScalarField& medialRatio,
|
pointScalarField& medialRatio,
|
||||||
pointScalarField& medialDist
|
pointScalarField& medialDist,
|
||||||
|
pointVectorField& medialVec
|
||||||
) const
|
) const
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -929,7 +930,7 @@ void Foam::autoLayerDriver::medialAxisSmoothingInfo
|
|||||||
forAll(pointMedialDist, pointI)
|
forAll(pointMedialDist, pointI)
|
||||||
{
|
{
|
||||||
medialDist[pointI] = Foam::sqrt(pointMedialDist[pointI].distSqr());
|
medialDist[pointI] = Foam::sqrt(pointMedialDist[pointI].distSqr());
|
||||||
//medialVec[pointI] = pointMedialDist[pointI].origin();
|
medialVec[pointI] = pointMedialDist[pointI].origin();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -966,14 +967,14 @@ void Foam::autoLayerDriver::medialAxisSmoothingInfo
|
|||||||
<< " : normalised direction of nearest displacement" << nl
|
<< " : normalised direction of nearest displacement" << nl
|
||||||
<< " " << medialDist.name()
|
<< " " << medialDist.name()
|
||||||
<< " : distance to medial axis" << nl
|
<< " : distance to medial axis" << nl
|
||||||
//<< " " << medialVec.name()
|
<< " " << medialVec.name()
|
||||||
//<< " : nearest point on medial axis" << nl
|
<< " : nearest point on medial axis" << nl
|
||||||
<< " " << medialRatio.name()
|
<< " " << medialRatio.name()
|
||||||
<< " : ratio of medial distance to wall distance" << nl
|
<< " : ratio of medial distance to wall distance" << nl
|
||||||
<< endl;
|
<< endl;
|
||||||
dispVec.write();
|
dispVec.write();
|
||||||
medialDist.write();
|
medialDist.write();
|
||||||
//medialVec.write();
|
medialVec.write();
|
||||||
medialRatio.write();
|
medialRatio.write();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -996,7 +997,7 @@ void Foam::autoLayerDriver::shrinkMeshMedialDistance
|
|||||||
const pointVectorField& dispVec,
|
const pointVectorField& dispVec,
|
||||||
const pointScalarField& medialRatio,
|
const pointScalarField& medialRatio,
|
||||||
const pointScalarField& medialDist,
|
const pointScalarField& medialDist,
|
||||||
//const pointVectorField& medialVec,
|
const pointVectorField& medialVec,
|
||||||
|
|
||||||
List<extrudeMode>& extrudeStatus,
|
List<extrudeMode>& extrudeStatus,
|
||||||
pointField& patchDisp,
|
pointField& patchDisp,
|
||||||
@ -1066,6 +1067,24 @@ void Foam::autoLayerDriver::shrinkMeshMedialDistance
|
|||||||
<< str().name() << endl;
|
<< str().name() << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
autoPtr<OFstream> medialVecStr;
|
||||||
|
label medialVertI = 0;
|
||||||
|
if (debug)
|
||||||
|
{
|
||||||
|
medialVecStr.reset
|
||||||
|
(
|
||||||
|
new OFstream
|
||||||
|
(
|
||||||
|
mesh.time().path()
|
||||||
|
/ "thicknessRatioExcludeMedialVec_"
|
||||||
|
+ meshRefiner_.timeName()
|
||||||
|
+ ".obj"
|
||||||
|
)
|
||||||
|
);
|
||||||
|
Info<< "Writing points with too large a extrusion distance to "
|
||||||
|
<< medialVecStr().name() << endl;
|
||||||
|
}
|
||||||
|
|
||||||
forAll(meshPoints, patchPointI)
|
forAll(meshPoints, patchPointI)
|
||||||
{
|
{
|
||||||
if (extrudeStatus[patchPointI] != NOEXTRUDE)
|
if (extrudeStatus[patchPointI] != NOEXTRUDE)
|
||||||
@ -1082,12 +1101,9 @@ void Foam::autoLayerDriver::shrinkMeshMedialDistance
|
|||||||
vector n =
|
vector n =
|
||||||
patchDisp[patchPointI]
|
patchDisp[patchPointI]
|
||||||
/ (mag(patchDisp[patchPointI]) + VSMALL);
|
/ (mag(patchDisp[patchPointI]) + VSMALL);
|
||||||
//vector mVec = mesh.points()[pointI]-medialVec[pointI];
|
vector mVec = mesh.points()[pointI]-medialVec[pointI];
|
||||||
//scalar mDist = mag(mVec);
|
mVec /= mag(mVec)+VSMALL;
|
||||||
//scalar thicknessRatio =
|
thicknessRatio *= (n&mVec);
|
||||||
// (n&mVec)
|
|
||||||
// *thickness[patchPointI]
|
|
||||||
// /(mDist+VSMALL);
|
|
||||||
|
|
||||||
if (thicknessRatio > maxThicknessToMedialRatio)
|
if (thicknessRatio > maxThicknessToMedialRatio)
|
||||||
{
|
{
|
||||||
@ -1103,8 +1119,9 @@ void Foam::autoLayerDriver::shrinkMeshMedialDistance
|
|||||||
minThickness[patchPointI]
|
minThickness[patchPointI]
|
||||||
+thickness[patchPointI]
|
+thickness[patchPointI]
|
||||||
)
|
)
|
||||||
//<< " since near medial at:" << medialVec[pointI]
|
<< " medial direction:" << mVec
|
||||||
//<< " with thicknessRatio:" << thicknessRatio
|
<< " extrusion direction:" << n
|
||||||
|
<< " with thicknessRatio:" << thicknessRatio
|
||||||
<< endl;
|
<< endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1124,6 +1141,16 @@ void Foam::autoLayerDriver::shrinkMeshMedialDistance
|
|||||||
vertI++;
|
vertI++;
|
||||||
str()<< "l " << vertI-1 << ' ' << vertI << nl;
|
str()<< "l " << vertI-1 << ' ' << vertI << nl;
|
||||||
}
|
}
|
||||||
|
if (medialVecStr.valid())
|
||||||
|
{
|
||||||
|
const point& pt = mesh.points()[pointI];
|
||||||
|
meshTools::writeOBJ(medialVecStr(), pt);
|
||||||
|
medialVertI++;
|
||||||
|
meshTools::writeOBJ(medialVecStr(), medialVec[pointI]);
|
||||||
|
medialVertI++;
|
||||||
|
medialVecStr()<< "l " << medialVertI-1
|
||||||
|
<< ' ' << medialVertI << nl;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1228,6 +1255,15 @@ void Foam::autoLayerDriver::shrinkMeshMedialDistance
|
|||||||
)
|
)
|
||||||
)()
|
)()
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Above move will have changed the instance only on the points (which
|
||||||
|
// is correct).
|
||||||
|
// However the previous mesh written will be the mesh with layers
|
||||||
|
// (see autoLayerDriver.C) so we now have to force writing all files
|
||||||
|
// so we can easily step through time steps. Note that if you
|
||||||
|
// don't write the mesh with layers this is not necessary.
|
||||||
|
meshRefiner_.mesh().setInstance(meshRefiner_.timeName());
|
||||||
|
|
||||||
meshRefiner_.write
|
meshRefiner_.write
|
||||||
(
|
(
|
||||||
debug,
|
debug,
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
========= |
|
========= |
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
\\ / O peration |
|
\\ / O peration |
|
||||||
\\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
|
\\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation
|
||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
@ -103,9 +103,9 @@ License
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
Note: writes out .dgr files for debugging. Run with e.g.
|
Note: writeGraph=true : writes out .dgr files for debugging. Run with e.g.
|
||||||
|
|
||||||
mpirun -np 4 dgpart 2 'processor%r.grf'
|
mpirun -np 4 dgpart 2 'region0_%r.dgr'
|
||||||
|
|
||||||
- %r gets replaced by current processor rank
|
- %r gets replaced by current processor rank
|
||||||
- decompose into 2 domains
|
- decompose into 2 domains
|
||||||
@ -167,192 +167,192 @@ void Foam::ptscotchDecomp::check(const int retVal, const char* str)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//- Does prevention of 0 cell domains and calls ptscotch.
|
////- Does prevention of 0 cell domains and calls ptscotch.
|
||||||
Foam::label Foam::ptscotchDecomp::decomposeZeroDomains
|
//Foam::label Foam::ptscotchDecomp::decomposeZeroDomains
|
||||||
(
|
//(
|
||||||
const fileName& meshPath,
|
// const fileName& meshPath,
|
||||||
const List<int>& initadjncy,
|
// const List<int>& initadjncy,
|
||||||
const List<int>& initxadj,
|
// const List<int>& initxadj,
|
||||||
const scalarField& initcWeights,
|
// const scalarField& initcWeights,
|
||||||
|
//
|
||||||
List<int>& finalDecomp
|
// List<int>& finalDecomp
|
||||||
) const
|
//) const
|
||||||
{
|
//{
|
||||||
globalIndex globalCells(initxadj.size()-1);
|
// globalIndex globalCells(initxadj.size()-1);
|
||||||
|
//
|
||||||
bool hasZeroDomain = false;
|
// bool hasZeroDomain = false;
|
||||||
for (label procI = 0; procI < Pstream::nProcs(); procI++)
|
// for (label procI = 0; procI < Pstream::nProcs(); procI++)
|
||||||
{
|
// {
|
||||||
if (globalCells.localSize(procI) == 0)
|
// if (globalCells.localSize(procI) == 0)
|
||||||
{
|
// {
|
||||||
hasZeroDomain = true;
|
// hasZeroDomain = true;
|
||||||
break;
|
// break;
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
if (!hasZeroDomain)
|
// if (!hasZeroDomain)
|
||||||
{
|
// {
|
||||||
return decompose
|
// return decompose
|
||||||
(
|
// (
|
||||||
meshPath,
|
// meshPath,
|
||||||
initadjncy,
|
// initadjncy,
|
||||||
initxadj,
|
// initxadj,
|
||||||
initcWeights,
|
// initcWeights,
|
||||||
finalDecomp
|
// finalDecomp
|
||||||
);
|
// );
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
|
//
|
||||||
if (debug)
|
// if (debug)
|
||||||
{
|
// {
|
||||||
Info<< "ptscotchDecomp : have graphs with locally 0 cells."
|
// Info<< "ptscotchDecomp : have graphs with locally 0 cells."
|
||||||
<< " trickling down." << endl;
|
// << " trickling down." << endl;
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
// Make sure every domain has at least one cell
|
// // Make sure every domain has at least one cell
|
||||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
// // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
// (scotch does not like zero sized domains)
|
// // (scotch does not like zero sized domains)
|
||||||
// Trickle cells from processors that have them up to those that
|
// // Trickle cells from processors that have them up to those that
|
||||||
// don't.
|
// // don't.
|
||||||
|
//
|
||||||
|
//
|
||||||
// Number of cells to send to the next processor
|
// // Number of cells to send to the next processor
|
||||||
// (is same as number of cells next processor has to receive)
|
// // (is same as number of cells next processor has to receive)
|
||||||
List<int> nSendCells(Pstream::nProcs(), 0);
|
// List<int> nSendCells(Pstream::nProcs(), 0);
|
||||||
|
//
|
||||||
for (label procI = nSendCells.size()-1; procI >=1; procI--)
|
// for (label procI = nSendCells.size()-1; procI >=1; procI--)
|
||||||
{
|
// {
|
||||||
label nLocalCells = globalCells.localSize(procI);
|
// label nLocalCells = globalCells.localSize(procI);
|
||||||
if (nLocalCells-nSendCells[procI] < 1)
|
// if (nLocalCells-nSendCells[procI] < 1)
|
||||||
{
|
// {
|
||||||
nSendCells[procI-1] = nSendCells[procI]-nLocalCells+1;
|
// nSendCells[procI-1] = nSendCells[procI]-nLocalCells+1;
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
// First receive (so increasing the sizes of all arrays)
|
// // First receive (so increasing the sizes of all arrays)
|
||||||
|
//
|
||||||
Field<int> xadj(initxadj);
|
// Field<int> xadj(initxadj);
|
||||||
Field<int> adjncy(initadjncy);
|
// Field<int> adjncy(initadjncy);
|
||||||
scalarField cWeights(initcWeights);
|
// scalarField cWeights(initcWeights);
|
||||||
|
//
|
||||||
if (Pstream::myProcNo() >= 1 && nSendCells[Pstream::myProcNo()-1] > 0)
|
// if (Pstream::myProcNo() >= 1 && nSendCells[Pstream::myProcNo()-1] > 0)
|
||||||
{
|
// {
|
||||||
// Receive cells from previous processor
|
// // Receive cells from previous processor
|
||||||
IPstream fromPrevProc(Pstream::blocking, Pstream::myProcNo()-1);
|
// IPstream fromPrevProc(Pstream::blocking, Pstream::myProcNo()-1);
|
||||||
|
//
|
||||||
Field<int> prevXadj(fromPrevProc);
|
// Field<int> prevXadj(fromPrevProc);
|
||||||
Field<int> prevAdjncy(fromPrevProc);
|
// Field<int> prevAdjncy(fromPrevProc);
|
||||||
scalarField prevCellWeights(fromPrevProc);
|
// scalarField prevCellWeights(fromPrevProc);
|
||||||
|
//
|
||||||
if (prevXadj.size() != nSendCells[Pstream::myProcNo()-1])
|
// if (prevXadj.size() != nSendCells[Pstream::myProcNo()-1])
|
||||||
{
|
// {
|
||||||
FatalErrorIn("ptscotchDecomp::decompose(..)")
|
// FatalErrorIn("ptscotchDecomp::decompose(..)")
|
||||||
<< "Expected from processor " << Pstream::myProcNo()-1
|
// << "Expected from processor " << Pstream::myProcNo()-1
|
||||||
<< " connectivity for " << nSendCells[Pstream::myProcNo()-1]
|
// << " connectivity for " << nSendCells[Pstream::myProcNo()-1]
|
||||||
<< " nCells but only received " << prevXadj.size()
|
// << " nCells but only received " << prevXadj.size()
|
||||||
<< abort(FatalError);
|
// << abort(FatalError);
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
// Insert adjncy
|
// // Insert adjncy
|
||||||
prepend(prevAdjncy, adjncy);
|
// prepend(prevAdjncy, adjncy);
|
||||||
// Adapt offsets and prepend xadj
|
// // Adapt offsets and prepend xadj
|
||||||
xadj += prevAdjncy.size();
|
// xadj += prevAdjncy.size();
|
||||||
prepend(prevXadj, xadj);
|
// prepend(prevXadj, xadj);
|
||||||
// Weights
|
// // Weights
|
||||||
prepend(prevCellWeights, cWeights);
|
// prepend(prevCellWeights, cWeights);
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
|
//
|
||||||
// Send to my next processor
|
// // Send to my next processor
|
||||||
|
//
|
||||||
if (nSendCells[Pstream::myProcNo()] > 0)
|
// if (nSendCells[Pstream::myProcNo()] > 0)
|
||||||
{
|
// {
|
||||||
// Send cells to next processor
|
// // Send cells to next processor
|
||||||
OPstream toNextProc(Pstream::blocking, Pstream::myProcNo()+1);
|
// OPstream toNextProc(Pstream::blocking, Pstream::myProcNo()+1);
|
||||||
|
//
|
||||||
int nCells = nSendCells[Pstream::myProcNo()];
|
// int nCells = nSendCells[Pstream::myProcNo()];
|
||||||
int startCell = xadj.size()-1 - nCells;
|
// int startCell = xadj.size()-1 - nCells;
|
||||||
int startFace = xadj[startCell];
|
// int startFace = xadj[startCell];
|
||||||
int nFaces = adjncy.size()-startFace;
|
// int nFaces = adjncy.size()-startFace;
|
||||||
|
//
|
||||||
// Send for all cell data: last nCells elements
|
// // Send for all cell data: last nCells elements
|
||||||
// Send for all face data: last nFaces elements
|
// // Send for all face data: last nFaces elements
|
||||||
toNextProc
|
// toNextProc
|
||||||
<< Field<int>::subField(xadj, nCells, startCell)-startFace
|
// << Field<int>::subField(xadj, nCells, startCell)-startFace
|
||||||
<< Field<int>::subField(adjncy, nFaces, startFace)
|
// << Field<int>::subField(adjncy, nFaces, startFace)
|
||||||
<<
|
// <<
|
||||||
(
|
// (
|
||||||
cWeights.size()
|
// cWeights.size()
|
||||||
? static_cast<const scalarField&>
|
// ? static_cast<const scalarField&>
|
||||||
(
|
// (
|
||||||
scalarField::subField(cWeights, nCells, startCell)
|
// scalarField::subField(cWeights, nCells, startCell)
|
||||||
)
|
// )
|
||||||
: scalarField(0)
|
// : scalarField(0)
|
||||||
);
|
// );
|
||||||
|
//
|
||||||
// Remove data that has been sent
|
// // Remove data that has been sent
|
||||||
if (cWeights.size())
|
// if (cWeights.size())
|
||||||
{
|
// {
|
||||||
cWeights.setSize(cWeights.size()-nCells);
|
// cWeights.setSize(cWeights.size()-nCells);
|
||||||
}
|
// }
|
||||||
adjncy.setSize(adjncy.size()-nFaces);
|
// adjncy.setSize(adjncy.size()-nFaces);
|
||||||
xadj.setSize(xadj.size() - nCells);
|
// xadj.setSize(xadj.size() - nCells);
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
|
//
|
||||||
// Do decomposition as normal. Sets finalDecomp.
|
// // Do decomposition as normal. Sets finalDecomp.
|
||||||
label result = decompose(meshPath, adjncy, xadj, cWeights, finalDecomp);
|
// label result = decompose(meshPath, adjncy, xadj, cWeights, finalDecomp);
|
||||||
|
//
|
||||||
|
//
|
||||||
if (debug)
|
// if (debug)
|
||||||
{
|
// {
|
||||||
Info<< "ptscotchDecomp : have graphs with locally 0 cells."
|
// Info<< "ptscotchDecomp : have graphs with locally 0 cells."
|
||||||
<< " trickling up." << endl;
|
// << " trickling up." << endl;
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
|
//
|
||||||
// If we sent cells across make sure we undo it
|
// // If we sent cells across make sure we undo it
|
||||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
// // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
//
|
||||||
// Receive back from next processor if I sent something
|
// // Receive back from next processor if I sent something
|
||||||
if (nSendCells[Pstream::myProcNo()] > 0)
|
// if (nSendCells[Pstream::myProcNo()] > 0)
|
||||||
{
|
// {
|
||||||
IPstream fromNextProc(Pstream::blocking, Pstream::myProcNo()+1);
|
// IPstream fromNextProc(Pstream::blocking, Pstream::myProcNo()+1);
|
||||||
|
//
|
||||||
List<int> nextFinalDecomp(fromNextProc);
|
// List<int> nextFinalDecomp(fromNextProc);
|
||||||
|
//
|
||||||
if (nextFinalDecomp.size() != nSendCells[Pstream::myProcNo()])
|
// if (nextFinalDecomp.size() != nSendCells[Pstream::myProcNo()])
|
||||||
{
|
// {
|
||||||
FatalErrorIn("parMetisDecomp::decompose(..)")
|
// FatalErrorIn("parMetisDecomp::decompose(..)")
|
||||||
<< "Expected from processor " << Pstream::myProcNo()+1
|
// << "Expected from processor " << Pstream::myProcNo()+1
|
||||||
<< " decomposition for " << nSendCells[Pstream::myProcNo()]
|
// << " decomposition for " << nSendCells[Pstream::myProcNo()]
|
||||||
<< " nCells but only received " << nextFinalDecomp.size()
|
// << " nCells but only received " << nextFinalDecomp.size()
|
||||||
<< abort(FatalError);
|
// << abort(FatalError);
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
append(nextFinalDecomp, finalDecomp);
|
// append(nextFinalDecomp, finalDecomp);
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
// Send back to previous processor.
|
// // Send back to previous processor.
|
||||||
if (Pstream::myProcNo() >= 1 && nSendCells[Pstream::myProcNo()-1] > 0)
|
// if (Pstream::myProcNo() >= 1 && nSendCells[Pstream::myProcNo()-1] > 0)
|
||||||
{
|
// {
|
||||||
OPstream toPrevProc(Pstream::blocking, Pstream::myProcNo()-1);
|
// OPstream toPrevProc(Pstream::blocking, Pstream::myProcNo()-1);
|
||||||
|
//
|
||||||
int nToPrevious = nSendCells[Pstream::myProcNo()-1];
|
// int nToPrevious = nSendCells[Pstream::myProcNo()-1];
|
||||||
|
//
|
||||||
toPrevProc <<
|
// toPrevProc <<
|
||||||
SubList<int>
|
// SubList<int>
|
||||||
(
|
// (
|
||||||
finalDecomp,
|
// finalDecomp,
|
||||||
nToPrevious,
|
// nToPrevious,
|
||||||
finalDecomp.size()-nToPrevious
|
// finalDecomp.size()-nToPrevious
|
||||||
);
|
// );
|
||||||
|
//
|
||||||
// Remove locally what has been sent
|
// // Remove locally what has been sent
|
||||||
finalDecomp.setSize(finalDecomp.size()-nToPrevious);
|
// finalDecomp.setSize(finalDecomp.size()-nToPrevious);
|
||||||
}
|
// }
|
||||||
return result;
|
// return result;
|
||||||
}
|
//}
|
||||||
|
|
||||||
|
|
||||||
// Call scotch with options from dictionary.
|
// Call scotch with options from dictionary.
|
||||||
@ -362,13 +362,42 @@ Foam::label Foam::ptscotchDecomp::decompose
|
|||||||
const List<int>& adjncy,
|
const List<int>& adjncy,
|
||||||
const List<int>& xadj,
|
const List<int>& xadj,
|
||||||
const scalarField& cWeights,
|
const scalarField& cWeights,
|
||||||
|
List<int>& finalDecomp
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
List<int> dummyAdjncy(1);
|
||||||
|
List<int> dummyXadj(1);
|
||||||
|
dummyXadj[0] = 0;
|
||||||
|
|
||||||
|
return decompose
|
||||||
|
(
|
||||||
|
meshPath,
|
||||||
|
adjncy.size(),
|
||||||
|
(adjncy.size() ? adjncy.begin() : dummyAdjncy.begin()),
|
||||||
|
xadj.size(),
|
||||||
|
(xadj.size() ? xadj.begin() : dummyXadj.begin()),
|
||||||
|
cWeights,
|
||||||
|
finalDecomp
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Call scotch with options from dictionary.
|
||||||
|
Foam::label Foam::ptscotchDecomp::decompose
|
||||||
|
(
|
||||||
|
const fileName& meshPath,
|
||||||
|
const int adjncySize,
|
||||||
|
const int adjncy[],
|
||||||
|
const int xadjSize,
|
||||||
|
const int xadj[],
|
||||||
|
const scalarField& cWeights,
|
||||||
|
|
||||||
List<int>& finalDecomp
|
List<int>& finalDecomp
|
||||||
) const
|
) const
|
||||||
{
|
{
|
||||||
if (debug)
|
if (debug)
|
||||||
{
|
{
|
||||||
Pout<< "ptscotchDecomp : entering with xadj:" << xadj.size() << endl;
|
Pout<< "ptscotchDecomp : entering with xadj:" << xadjSize << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Dump graph
|
// Dump graph
|
||||||
@ -387,7 +416,7 @@ Foam::label Foam::ptscotchDecomp::decompose
|
|||||||
Pout<< "Dumping Scotch graph file to " << str.name() << endl
|
Pout<< "Dumping Scotch graph file to " << str.name() << endl
|
||||||
<< "Use this in combination with dgpart." << endl;
|
<< "Use this in combination with dgpart." << endl;
|
||||||
|
|
||||||
globalIndex globalCells(xadj.size()-1);
|
globalIndex globalCells(xadjSize-1);
|
||||||
|
|
||||||
// Distributed graph file (.grf)
|
// Distributed graph file (.grf)
|
||||||
label version = 2;
|
label version = 2;
|
||||||
@ -400,17 +429,17 @@ Foam::label Foam::ptscotchDecomp::decompose
|
|||||||
// Total number of vertices (vertglbnbr)
|
// Total number of vertices (vertglbnbr)
|
||||||
str << globalCells.size();
|
str << globalCells.size();
|
||||||
// Total number of connections (edgeglbnbr)
|
// Total number of connections (edgeglbnbr)
|
||||||
str << ' ' << returnReduce(xadj[xadj.size()-1], sumOp<label>())
|
str << ' ' << returnReduce(xadj[xadjSize-1], sumOp<label>())
|
||||||
<< nl;
|
<< nl;
|
||||||
// Local number of vertices (vertlocnbr)
|
// Local number of vertices (vertlocnbr)
|
||||||
str << xadj.size()-1;
|
str << xadjSize-1;
|
||||||
// Local number of connections (edgelocnbr)
|
// Local number of connections (edgelocnbr)
|
||||||
str << ' ' << xadj[xadj.size()-1] << nl;
|
str << ' ' << xadj[xadjSize-1] << nl;
|
||||||
// Numbering starts from 0
|
// Numbering starts from 0
|
||||||
label baseval = 0;
|
label baseval = 0;
|
||||||
// 100*hasVertlabels+10*hasEdgeWeights+1*hasVertWeighs
|
// 100*hasVertlabels+10*hasEdgeWeights+1*hasVertWeighs
|
||||||
str << baseval << ' ' << "000" << nl;
|
str << baseval << ' ' << "000" << nl;
|
||||||
for (label cellI = 0; cellI < xadj.size()-1; cellI++)
|
for (label cellI = 0; cellI < xadjSize-1; cellI++)
|
||||||
{
|
{
|
||||||
label start = xadj[cellI];
|
label start = xadj[cellI];
|
||||||
label end = xadj[cellI+1];
|
label end = xadj[cellI+1];
|
||||||
@ -462,8 +491,9 @@ Foam::label Foam::ptscotchDecomp::decompose
|
|||||||
// Check for externally provided cellweights and if so initialise weights
|
// Check for externally provided cellweights and if so initialise weights
|
||||||
|
|
||||||
scalar minWeights = gMin(cWeights);
|
scalar minWeights = gMin(cWeights);
|
||||||
|
scalar maxWeights = gMax(cWeights);
|
||||||
|
|
||||||
if (!cWeights.empty())
|
if (maxWeights > minWeights)
|
||||||
{
|
{
|
||||||
if (minWeights <= 0)
|
if (minWeights <= 0)
|
||||||
{
|
{
|
||||||
@ -474,13 +504,13 @@ Foam::label Foam::ptscotchDecomp::decompose
|
|||||||
<< endl;
|
<< endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cWeights.size() != xadj.size()-1)
|
if (cWeights.size() != xadjSize-1)
|
||||||
{
|
{
|
||||||
FatalErrorIn
|
FatalErrorIn
|
||||||
(
|
(
|
||||||
"ptscotchDecomp::decompose(..)"
|
"ptscotchDecomp::decompose(..)"
|
||||||
) << "Number of cell weights " << cWeights.size()
|
) << "Number of cell weights " << cWeights.size()
|
||||||
<< " does not equal number of cells " << xadj.size()-1
|
<< " does not equal number of cells " << xadjSize-1
|
||||||
<< exit(FatalError);
|
<< exit(FatalError);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -508,7 +538,7 @@ Foam::label Foam::ptscotchDecomp::decompose
|
|||||||
|
|
||||||
Pstream::scatter(rangeScale);
|
Pstream::scatter(rangeScale);
|
||||||
|
|
||||||
if (!cWeights.empty())
|
if (maxWeights > minWeights)
|
||||||
{
|
{
|
||||||
// Convert to integers.
|
// Convert to integers.
|
||||||
velotab.setSize(cWeights.size());
|
velotab.setSize(cWeights.size());
|
||||||
@ -532,11 +562,11 @@ Foam::label Foam::ptscotchDecomp::decompose
|
|||||||
if (debug)
|
if (debug)
|
||||||
{
|
{
|
||||||
Pout<< "SCOTCH_dgraphBuild with:" << nl
|
Pout<< "SCOTCH_dgraphBuild with:" << nl
|
||||||
<< "xadj.size()-1 : " << xadj.size()-1 << nl
|
<< "xadjSize-1 : " << xadjSize-1 << nl
|
||||||
<< "xadj : " << long(xadj.begin()) << nl
|
<< "xadj : " << long(xadj) << nl
|
||||||
<< "velotab : " << long(velotab.begin()) << nl
|
<< "velotab : " << long(velotab.begin()) << nl
|
||||||
<< "adjncy.size() : " << adjncy.size() << nl
|
<< "adjncySize : " << adjncySize << nl
|
||||||
<< "adjncy : " << long(adjncy.begin()) << nl
|
<< "adjncy : " << long(adjncy) << nl
|
||||||
<< endl;
|
<< endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -546,19 +576,19 @@ Foam::label Foam::ptscotchDecomp::decompose
|
|||||||
(
|
(
|
||||||
&grafdat, // grafdat
|
&grafdat, // grafdat
|
||||||
0, // baseval, c-style numbering
|
0, // baseval, c-style numbering
|
||||||
xadj.size()-1, // vertlocnbr, nCells
|
xadjSize-1, // vertlocnbr, nCells
|
||||||
xadj.size()-1, // vertlocmax
|
xadjSize-1, // vertlocmax
|
||||||
const_cast<SCOTCH_Num*>(xadj.begin()),
|
const_cast<SCOTCH_Num*>(xadj),
|
||||||
// vertloctab, start index per cell into
|
// vertloctab, start index per cell into
|
||||||
// adjncy
|
// adjncy
|
||||||
const_cast<SCOTCH_Num*>(&xadj[1]),// vendloctab, end index ,,
|
const_cast<SCOTCH_Num*>(xadj+1),// vendloctab, end index ,,
|
||||||
|
|
||||||
const_cast<SCOTCH_Num*>(velotab.begin()),// veloloctab, vtx weights
|
const_cast<SCOTCH_Num*>(velotab.begin()),// veloloctab, vtx weights
|
||||||
NULL, // vlblloctab
|
NULL, // vlblloctab
|
||||||
|
|
||||||
adjncy.size(), // edgelocnbr, number of arcs
|
adjncySize, // edgelocnbr, number of arcs
|
||||||
adjncy.size(), // edgelocsiz
|
adjncySize, // edgelocsiz
|
||||||
const_cast<SCOTCH_Num*>(adjncy.begin()), // edgeloctab
|
const_cast<SCOTCH_Num*>(adjncy), // edgeloctab
|
||||||
NULL, // edgegsttab
|
NULL, // edgegsttab
|
||||||
NULL // edlotab, edge weights
|
NULL // edlotab, edge weights
|
||||||
),
|
),
|
||||||
@ -620,12 +650,6 @@ Foam::label Foam::ptscotchDecomp::decompose
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//SCOTCH_Mapping mapdat;
|
|
||||||
//SCOTCH_dgraphMapInit(&grafdat, &mapdat, &archdat, NULL);
|
|
||||||
//SCOTCH_dgraphMapCompute(&grafdat, &mapdat, &stradat); /*Perform mapping*/
|
|
||||||
//SCOTCHdgraphMapExit(&grafdat, &mapdat);
|
|
||||||
|
|
||||||
|
|
||||||
// Hack:switch off fpu error trapping
|
// Hack:switch off fpu error trapping
|
||||||
# ifdef LINUX_GNUC
|
# ifdef LINUX_GNUC
|
||||||
int oldExcepts = fedisableexcept
|
int oldExcepts = fedisableexcept
|
||||||
@ -636,12 +660,15 @@ Foam::label Foam::ptscotchDecomp::decompose
|
|||||||
);
|
);
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
|
|
||||||
|
// Note: always provide allocated storage even if local size 0
|
||||||
|
finalDecomp.setSize(max(1, xadjSize-1));
|
||||||
|
finalDecomp = 0;
|
||||||
|
|
||||||
if (debug)
|
if (debug)
|
||||||
{
|
{
|
||||||
Pout<< "SCOTCH_dgraphMap" << endl;
|
Pout<< "SCOTCH_dgraphMap" << endl;
|
||||||
}
|
}
|
||||||
finalDecomp.setSize(xadj.size()-1);
|
|
||||||
finalDecomp = 0;
|
|
||||||
check
|
check
|
||||||
(
|
(
|
||||||
SCOTCH_dgraphMap
|
SCOTCH_dgraphMap
|
||||||
@ -660,7 +687,7 @@ Foam::label Foam::ptscotchDecomp::decompose
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
//finalDecomp.setSize(xadj.size()-1);
|
//finalDecomp.setSize(xadjSize-1);
|
||||||
//check
|
//check
|
||||||
//(
|
//(
|
||||||
// SCOTCH_dgraphPart
|
// SCOTCH_dgraphPart
|
||||||
@ -719,12 +746,6 @@ Foam::labelList Foam::ptscotchDecomp::decompose
|
|||||||
<< exit(FatalError);
|
<< exit(FatalError);
|
||||||
}
|
}
|
||||||
|
|
||||||
// // For running sequential ...
|
|
||||||
// if (Pstream::nProcs() <= 1)
|
|
||||||
// {
|
|
||||||
// return scotchDecomp(decompositionDict_, mesh_)
|
|
||||||
// .decompose(points, pointWeights);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// Make Metis CSR (Compressed Storage Format) storage
|
// Make Metis CSR (Compressed Storage Format) storage
|
||||||
// adjncy : contains neighbours (= edges in graph)
|
// adjncy : contains neighbours (= edges in graph)
|
||||||
@ -743,7 +764,7 @@ Foam::labelList Foam::ptscotchDecomp::decompose
|
|||||||
|
|
||||||
// Decompose using default weights
|
// Decompose using default weights
|
||||||
List<int> finalDecomp;
|
List<int> finalDecomp;
|
||||||
decomposeZeroDomains
|
decompose
|
||||||
(
|
(
|
||||||
mesh.time().path()/mesh.name(),
|
mesh.time().path()/mesh.name(),
|
||||||
cellCells.m(),
|
cellCells.m(),
|
||||||
@ -753,7 +774,7 @@ Foam::labelList Foam::ptscotchDecomp::decompose
|
|||||||
);
|
);
|
||||||
|
|
||||||
// Copy back to labelList
|
// Copy back to labelList
|
||||||
labelList decomp(finalDecomp.size());
|
labelList decomp(points.size());
|
||||||
forAll(decomp, i)
|
forAll(decomp, i)
|
||||||
{
|
{
|
||||||
decomp[i] = finalDecomp[i];
|
decomp[i] = finalDecomp[i];
|
||||||
@ -780,12 +801,6 @@ Foam::labelList Foam::ptscotchDecomp::decompose
|
|||||||
<< exit(FatalError);
|
<< exit(FatalError);
|
||||||
}
|
}
|
||||||
|
|
||||||
// // For running sequential ...
|
|
||||||
// if (Pstream::nProcs() <= 1)
|
|
||||||
// {
|
|
||||||
// return scotchDecomp(decompositionDict_, mesh)
|
|
||||||
// .decompose(agglom, agglomPoints, pointWeights);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// Make Metis CSR (Compressed Storage Format) storage
|
// Make Metis CSR (Compressed Storage Format) storage
|
||||||
// adjncy : contains neighbours (= edges in graph)
|
// adjncy : contains neighbours (= edges in graph)
|
||||||
@ -802,7 +817,7 @@ Foam::labelList Foam::ptscotchDecomp::decompose
|
|||||||
|
|
||||||
// Decompose using weights
|
// Decompose using weights
|
||||||
List<int> finalDecomp;
|
List<int> finalDecomp;
|
||||||
decomposeZeroDomains
|
decompose
|
||||||
(
|
(
|
||||||
mesh.time().path()/mesh.name(),
|
mesh.time().path()/mesh.name(),
|
||||||
cellCells.m(),
|
cellCells.m(),
|
||||||
@ -840,13 +855,6 @@ Foam::labelList Foam::ptscotchDecomp::decompose
|
|||||||
<< ")." << exit(FatalError);
|
<< ")." << exit(FatalError);
|
||||||
}
|
}
|
||||||
|
|
||||||
// // For running sequential ...
|
|
||||||
// if (Pstream::nProcs() <= 1)
|
|
||||||
// {
|
|
||||||
// return scotchDecomp(decompositionDict_, mesh)
|
|
||||||
// .decompose(globalCellCells, cellCentres, cWeights);
|
|
||||||
// }
|
|
||||||
|
|
||||||
|
|
||||||
// Make Metis CSR (Compressed Storage Format) storage
|
// Make Metis CSR (Compressed Storage Format) storage
|
||||||
// adjncy : contains neighbours (= edges in graph)
|
// adjncy : contains neighbours (= edges in graph)
|
||||||
@ -856,7 +864,7 @@ Foam::labelList Foam::ptscotchDecomp::decompose
|
|||||||
|
|
||||||
// Decompose using weights
|
// Decompose using weights
|
||||||
List<int> finalDecomp;
|
List<int> finalDecomp;
|
||||||
decomposeZeroDomains
|
decompose
|
||||||
(
|
(
|
||||||
"ptscotch",
|
"ptscotch",
|
||||||
cellCells.m(),
|
cellCells.m(),
|
||||||
@ -866,7 +874,7 @@ Foam::labelList Foam::ptscotchDecomp::decompose
|
|||||||
);
|
);
|
||||||
|
|
||||||
// Copy back to labelList
|
// Copy back to labelList
|
||||||
labelList decomp(finalDecomp.size());
|
labelList decomp(cellCentres.size());
|
||||||
forAll(decomp, i)
|
forAll(decomp, i)
|
||||||
{
|
{
|
||||||
decomp[i] = finalDecomp[i];
|
decomp[i] = finalDecomp[i];
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
========= |
|
========= |
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
\\ / O peration |
|
\\ / O peration |
|
||||||
\\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
|
\\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation
|
||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
@ -60,17 +60,7 @@ class ptscotchDecomp
|
|||||||
//- Check and print error message
|
//- Check and print error message
|
||||||
static void check(const int, const char*);
|
static void check(const int, const char*);
|
||||||
|
|
||||||
//- Decompose with optionally zero sized domains
|
//- Decompose. Handles size 0 arrays
|
||||||
label decomposeZeroDomains
|
|
||||||
(
|
|
||||||
const fileName& meshPath,
|
|
||||||
const List<int>& initadjncy,
|
|
||||||
const List<int>& initxadj,
|
|
||||||
const scalarField& initcWeights,
|
|
||||||
List<int>& finalDecomp
|
|
||||||
) const;
|
|
||||||
|
|
||||||
//- Decompose
|
|
||||||
label decompose
|
label decompose
|
||||||
(
|
(
|
||||||
const fileName& meshPath,
|
const fileName& meshPath,
|
||||||
@ -80,6 +70,18 @@ class ptscotchDecomp
|
|||||||
List<int>& finalDecomp
|
List<int>& finalDecomp
|
||||||
) const;
|
) const;
|
||||||
|
|
||||||
|
//- Low level decompose
|
||||||
|
label decompose
|
||||||
|
(
|
||||||
|
const fileName& meshPath,
|
||||||
|
const int adjncySize,
|
||||||
|
const int adjncy[],
|
||||||
|
const int xadjSize,
|
||||||
|
const int xadj[],
|
||||||
|
const scalarField& cWeights,
|
||||||
|
List<int>& finalDecomp
|
||||||
|
) const;
|
||||||
|
|
||||||
//- Disallow default bitwise copy construct and assignment
|
//- Disallow default bitwise copy construct and assignment
|
||||||
void operator=(const ptscotchDecomp&);
|
void operator=(const ptscotchDecomp&);
|
||||||
ptscotchDecomp(const ptscotchDecomp&);
|
ptscotchDecomp(const ptscotchDecomp&);
|
||||||
|
|||||||
@ -156,15 +156,24 @@ tmp<volScalarField> kkLOmega::gammaBP(const volScalarField& omega) const
|
|||||||
{
|
{
|
||||||
return
|
return
|
||||||
(
|
(
|
||||||
max
|
min
|
||||||
(
|
(
|
||||||
kt_/nu()
|
max
|
||||||
/ (
|
(
|
||||||
omega
|
kt_/nu()
|
||||||
+ dimensionedScalar("ROTVSMALL", omega.dimensions(), ROOTVSMALL)
|
/ (
|
||||||
)
|
omega
|
||||||
- CbpCrit_,
|
+ dimensionedScalar
|
||||||
scalar(0)
|
(
|
||||||
|
"ROTVSMALL",
|
||||||
|
omega.dimensions(),
|
||||||
|
ROOTVSMALL
|
||||||
|
)
|
||||||
|
)
|
||||||
|
- CbpCrit_,
|
||||||
|
scalar(0)
|
||||||
|
),
|
||||||
|
scalar(50.0)
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -10,12 +10,14 @@ FoamFile
|
|||||||
version 2.0;
|
version 2.0;
|
||||||
format ascii;
|
format ascii;
|
||||||
class dictionary;
|
class dictionary;
|
||||||
object extrudeProperties;
|
object extrudeMeshDict;
|
||||||
}
|
}
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
// What to extrude:
|
// What to extrude:
|
||||||
// patch : from patch of another case ('sourceCase')
|
// patch : from patch of another case ('sourceCase')
|
||||||
|
// mesh : as above but with original case included
|
||||||
|
// surface : from externally read surface
|
||||||
|
|
||||||
constructFrom patch;
|
constructFrom patch;
|
||||||
sourceCase "../wingMotion_snappyHexMesh";
|
sourceCase "../wingMotion_snappyHexMesh";
|
||||||
@ -24,7 +26,8 @@ sourcePatches (front);
|
|||||||
// If construct from patch: patch to use for back (can be same as sourcePatch)
|
// If construct from patch: patch to use for back (can be same as sourcePatch)
|
||||||
exposedPatchName back;
|
exposedPatchName back;
|
||||||
|
|
||||||
// Flip surface normals before usage.
|
// Flip surface normals before usage. Valid only for extrude from surface or
|
||||||
|
// patch.
|
||||||
flipNormals false;
|
flipNormals false;
|
||||||
|
|
||||||
//- Linear extrusion in point-normal direction
|
//- Linear extrusion in point-normal direction
|
||||||
@ -41,7 +44,10 @@ linearNormalCoeffs
|
|||||||
|
|
||||||
// Do front and back need to be merged? Usually only makes sense for 360
|
// Do front and back need to be merged? Usually only makes sense for 360
|
||||||
// degree wedges.
|
// degree wedges.
|
||||||
mergeFaces false;
|
mergeFaces false; //true;
|
||||||
|
|
||||||
|
// Merge small edges. Fraction of bounding box.
|
||||||
|
mergeTol 0;
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|||||||
@ -15,6 +15,8 @@ runApplication decomposePar
|
|||||||
|
|
||||||
cp system/decomposeParDict-par system/decomposeParDict
|
cp system/decomposeParDict-par system/decomposeParDict
|
||||||
runParallel snappyHexMesh 2 -overwrite
|
runParallel snappyHexMesh 2 -overwrite
|
||||||
|
# *ProcAddressing files written by decomposePar no longer valid
|
||||||
|
rm -f processor*/constant/polyMesh/*ProcAddressing
|
||||||
|
|
||||||
# Add wildcard entries for meshed patches since not preserved
|
# Add wildcard entries for meshed patches since not preserved
|
||||||
# by decomposePar. Notice -literalRE option to add wildcard itself
|
# by decomposePar. Notice -literalRE option to add wildcard itself
|
||||||
|
|||||||
@ -32,7 +32,7 @@ writeInterval 50;
|
|||||||
|
|
||||||
purgeWrite 0;
|
purgeWrite 0;
|
||||||
|
|
||||||
writeFormat ascii;
|
writeFormat binary; //ascii;
|
||||||
|
|
||||||
writePrecision 12;
|
writePrecision 12;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user