mirror of
https://develop.openfoam.com/Development/openfoam.git
synced 2025-11-28 03:28:01 +00:00
ENH: snappyHexMesh: handle parallel cyclics. Fixes #1731.
This commit is contained in:
@ -17,6 +17,7 @@ meshRefinement/meshRefinementGapRefine.C
|
|||||||
meshRefinement/meshRefinementBlock.C
|
meshRefinement/meshRefinementBlock.C
|
||||||
meshRefinement/wallPoints.C
|
meshRefinement/wallPoints.C
|
||||||
meshRefinement/patchFaceOrientation.C
|
meshRefinement/patchFaceOrientation.C
|
||||||
|
meshRefinement/weightedPosition.C
|
||||||
|
|
||||||
refinementFeatures/refinementFeatures.C
|
refinementFeatures/refinementFeatures.C
|
||||||
refinementSurfaces/surfaceZonesInfo.C
|
refinementSurfaces/surfaceZonesInfo.C
|
||||||
|
|||||||
@ -1093,7 +1093,7 @@ Foam::labelList Foam::meshRefinement::markFacesOnProblemCellsGeometric
|
|||||||
newPoints[meshPoints[i]] += disp[i];
|
newPoints[meshPoints[i]] += disp[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
syncTools::syncPointList
|
syncTools::syncPointPositions
|
||||||
(
|
(
|
||||||
mesh_,
|
mesh_,
|
||||||
newPoints,
|
newPoints,
|
||||||
|
|||||||
153
src/mesh/snappyHexMesh/meshRefinement/weightedPosition.C
Normal file
153
src/mesh/snappyHexMesh/meshRefinement/weightedPosition.C
Normal file
@ -0,0 +1,153 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / 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 "weightedPosition.H"
|
||||||
|
#include "vectorTensorTransform.H"
|
||||||
|
#include "coupledPolyPatch.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
const Foam::weightedPosition Foam::pTraits<Foam::weightedPosition>::zero
|
||||||
|
(
|
||||||
|
scalar(0),
|
||||||
|
Foam::point::zero
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Foam::weightedPosition::weightedPosition()
|
||||||
|
:
|
||||||
|
Tuple2<scalar, point>()
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::weightedPosition::weightedPosition(const scalar s, const point& p)
|
||||||
|
:
|
||||||
|
Tuple2<scalar, point>(s, p)
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
void Foam::weightedPosition::getPoints
|
||||||
|
(
|
||||||
|
const UList<weightedPosition>& in,
|
||||||
|
List<point>& out
|
||||||
|
)
|
||||||
|
{
|
||||||
|
out.setSize(in.size());
|
||||||
|
forAll(in, i)
|
||||||
|
{
|
||||||
|
out[i] = in[i].second();
|
||||||
|
|
||||||
|
if (mag(in[i].first()) > VSMALL)
|
||||||
|
{
|
||||||
|
out[i] /= in[i].first();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::weightedPosition::setPoints
|
||||||
|
(
|
||||||
|
const UList<point>& in,
|
||||||
|
List<weightedPosition>& out
|
||||||
|
)
|
||||||
|
{
|
||||||
|
out.setSize(in.size());
|
||||||
|
forAll(in, i)
|
||||||
|
{
|
||||||
|
out[i].second() = out[i].first()*in[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::weightedPosition::plusEqOp
|
||||||
|
(
|
||||||
|
weightedPosition& x,
|
||||||
|
const weightedPosition& y
|
||||||
|
)
|
||||||
|
{
|
||||||
|
x.first() += y.first();
|
||||||
|
x.second() += y.second();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::weightedPosition::operator()
|
||||||
|
(
|
||||||
|
const vectorTensorTransform& vt,
|
||||||
|
const bool forward,
|
||||||
|
List<weightedPosition>& fld
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
pointField pfld;
|
||||||
|
getPoints(fld, pfld);
|
||||||
|
|
||||||
|
if (forward)
|
||||||
|
{
|
||||||
|
pfld = vt.transformPosition(pfld);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pfld = vt.invTransformPosition(pfld);
|
||||||
|
}
|
||||||
|
|
||||||
|
setPoints(pfld, fld);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::weightedPosition::operator()
|
||||||
|
(
|
||||||
|
const vectorTensorTransform& vt,
|
||||||
|
const bool forward,
|
||||||
|
List<List<weightedPosition>>& flds
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
for (List<weightedPosition>& fld : flds)
|
||||||
|
{
|
||||||
|
operator()(vt, forward, fld);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::weightedPosition::operator()
|
||||||
|
(
|
||||||
|
const coupledPolyPatch& cpp,
|
||||||
|
Field<weightedPosition>& fld
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
pointField pfld;
|
||||||
|
getPoints(fld, pfld);
|
||||||
|
|
||||||
|
cpp.transformPosition(pfld);
|
||||||
|
|
||||||
|
setPoints(pfld, fld);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
180
src/mesh/snappyHexMesh/meshRefinement/weightedPosition.H
Normal file
180
src/mesh/snappyHexMesh/meshRefinement/weightedPosition.H
Normal file
@ -0,0 +1,180 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / 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::weightedPosition
|
||||||
|
|
||||||
|
Description
|
||||||
|
Wrapper for position + weight to be used in e.g. averaging.
|
||||||
|
|
||||||
|
This avoids the problems when synchronising locations with e.g.
|
||||||
|
parallel cyclics. The separation vector only applies to locations
|
||||||
|
and not e.g. summed locations. Note that there is no corresponding
|
||||||
|
problem for rotational cyclics.
|
||||||
|
|
||||||
|
Typical use might be to e.g. average face centres to points on a patch
|
||||||
|
|
||||||
|
const labelListList& pointFaces = pp.pointFaces();
|
||||||
|
const pointField& faceCentres = pp.faceCentres();
|
||||||
|
|
||||||
|
Field<weightedPosition> avgBoundary(pointFaces.size());
|
||||||
|
|
||||||
|
forAll(pointFaces, pointi)
|
||||||
|
{
|
||||||
|
const labelList& pFaces = pointFaces[pointi];
|
||||||
|
avgBoundary[pointi].first() = pFaces.size();
|
||||||
|
avgBoundary[pointi].second() = sum(pointField(faceCentres, pFaces));
|
||||||
|
}
|
||||||
|
syncTools::syncPointList
|
||||||
|
(
|
||||||
|
mesh,
|
||||||
|
pp.meshPoints(),
|
||||||
|
avgBoundary,
|
||||||
|
weightedPosition::plusEqOp, // combine op
|
||||||
|
pTraits<weightedPosition>::zero,// null value (not used)
|
||||||
|
pTraits<weightedPosition>::zero // transform class
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
SourceFiles
|
||||||
|
weightedPosition.C
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef weightedPosition_H
|
||||||
|
#define weightedPosition_H
|
||||||
|
|
||||||
|
#include "Tuple2.H"
|
||||||
|
#include "point.H"
|
||||||
|
#include "Field.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
|
||||||
|
// Forward declarations
|
||||||
|
class weightedPosition;
|
||||||
|
class vectorTensorTransform;
|
||||||
|
class coupledPolyPatch;
|
||||||
|
|
||||||
|
//- pTraits
|
||||||
|
template<>
|
||||||
|
class pTraits<weightedPosition>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef weightedPosition cmptType;
|
||||||
|
static const weightedPosition zero;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
Class weightedPosition Declaration
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
class weightedPosition
|
||||||
|
:
|
||||||
|
public Tuple2<scalar, point>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
// Constructors
|
||||||
|
|
||||||
|
//- Construct null
|
||||||
|
weightedPosition();
|
||||||
|
|
||||||
|
//- Construct from components
|
||||||
|
weightedPosition(const scalar s, const point& p);
|
||||||
|
|
||||||
|
|
||||||
|
// Member Functions
|
||||||
|
|
||||||
|
// Helpers
|
||||||
|
|
||||||
|
//- Get points
|
||||||
|
static void getPoints
|
||||||
|
(
|
||||||
|
const UList<weightedPosition>& in,
|
||||||
|
List<point>& out
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Set points
|
||||||
|
static void setPoints
|
||||||
|
(
|
||||||
|
const UList<point>& in,
|
||||||
|
List<weightedPosition>& out
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
//- Summation operator
|
||||||
|
static void plusEqOp(weightedPosition& x, const weightedPosition& y);
|
||||||
|
|
||||||
|
|
||||||
|
// Transformation operators
|
||||||
|
|
||||||
|
void operator()
|
||||||
|
(
|
||||||
|
const vectorTensorTransform& vt,
|
||||||
|
const bool forward,
|
||||||
|
List<weightedPosition>& fld
|
||||||
|
) const;
|
||||||
|
|
||||||
|
void operator()
|
||||||
|
(
|
||||||
|
const vectorTensorTransform& vt,
|
||||||
|
const bool forward,
|
||||||
|
List<List<weightedPosition>>& flds
|
||||||
|
) const;
|
||||||
|
|
||||||
|
void operator()
|
||||||
|
(
|
||||||
|
const coupledPolyPatch& cpp,
|
||||||
|
Field<weightedPosition>& fld
|
||||||
|
) const;
|
||||||
|
|
||||||
|
template<template<class> class Container>
|
||||||
|
void operator()
|
||||||
|
(
|
||||||
|
const coupledPolyPatch& cpp,
|
||||||
|
Container<weightedPosition>& map
|
||||||
|
) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
} // End namespace Foam
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
#ifdef NoRepository
|
||||||
|
#include "weightedPositionTemplates.C"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -0,0 +1,61 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / 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 "vectorTensorTransform.H"
|
||||||
|
#include "coupledPolyPatch.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
template<template<class> class Container>
|
||||||
|
void Foam::weightedPosition::operator()
|
||||||
|
(
|
||||||
|
const coupledPolyPatch& cpp,
|
||||||
|
Container<weightedPosition>& map
|
||||||
|
)
|
||||||
|
const
|
||||||
|
{
|
||||||
|
Field<point> fld(map.size());
|
||||||
|
label i = 0;
|
||||||
|
forAllConstIters(map, iter)
|
||||||
|
{
|
||||||
|
point pt(iter->second());
|
||||||
|
if (mag(iter->first()) > VSMALL)
|
||||||
|
{
|
||||||
|
pt /= iter->first();
|
||||||
|
}
|
||||||
|
fld[i++] = pt;
|
||||||
|
}
|
||||||
|
cpp.transformPosition(fld);
|
||||||
|
i = 0;
|
||||||
|
forAllIters(map, iter)
|
||||||
|
{
|
||||||
|
iter->second() = fld[i++]*iter->first();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -6,7 +6,7 @@
|
|||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Copyright (C) 2011-2015 OpenFOAM Foundation
|
Copyright (C) 2011-2015 OpenFOAM Foundation
|
||||||
Copyright (C) 2015-2019 OpenCFD Ltd.
|
Copyright (C) 2015-2020 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM.
|
This file is part of OpenFOAM.
|
||||||
@ -48,6 +48,7 @@ Description
|
|||||||
#include "localPointRegion.H"
|
#include "localPointRegion.H"
|
||||||
#include "PatchTools.H"
|
#include "PatchTools.H"
|
||||||
#include "refinementFeatures.H"
|
#include "refinementFeatures.H"
|
||||||
|
#include "weightedPosition.H"
|
||||||
#include "profiling.H"
|
#include "profiling.H"
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||||
@ -234,8 +235,11 @@ Foam::tmp<Foam::pointField> Foam::snappySnapDriver::smoothInternalDisplacement
|
|||||||
|
|
||||||
|
|
||||||
// Calculate average of connected cells
|
// Calculate average of connected cells
|
||||||
labelList nCells(mesh.nPoints(), Zero);
|
Field<weightedPosition> sumLocation
|
||||||
pointField sumLocation(mesh.nPoints(), Zero);
|
(
|
||||||
|
mesh.nPoints(),
|
||||||
|
pTraits<weightedPosition>::zero
|
||||||
|
);
|
||||||
|
|
||||||
forAll(isMovingPoint, pointi)
|
forAll(isMovingPoint, pointi)
|
||||||
{
|
{
|
||||||
@ -243,22 +247,22 @@ Foam::tmp<Foam::pointField> Foam::snappySnapDriver::smoothInternalDisplacement
|
|||||||
{
|
{
|
||||||
const labelList& pCells = mesh.pointCells(pointi);
|
const labelList& pCells = mesh.pointCells(pointi);
|
||||||
|
|
||||||
forAll(pCells, i)
|
sumLocation[pointi].first() = pCells.size();
|
||||||
|
for (const label celli : pCells)
|
||||||
{
|
{
|
||||||
sumLocation[pointi] += mesh.cellCentres()[pCells[i]];
|
sumLocation[pointi].second() += mesh.cellCentres()[celli];
|
||||||
nCells[pointi]++;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sum
|
// Sum
|
||||||
syncTools::syncPointList(mesh, nCells, plusEqOp<label>(), label(0));
|
|
||||||
syncTools::syncPointList
|
syncTools::syncPointList
|
||||||
(
|
(
|
||||||
mesh,
|
mesh,
|
||||||
sumLocation,
|
sumLocation,
|
||||||
plusEqOp<point>(),
|
weightedPosition::plusEqOp, // combine op
|
||||||
vector::zero
|
pTraits<weightedPosition>::zero,// null value (not used)
|
||||||
|
pTraits<weightedPosition>::zero // transform class
|
||||||
);
|
);
|
||||||
|
|
||||||
tmp<pointField> tdisplacement(new pointField(mesh.nPoints(), Zero));
|
tmp<pointField> tdisplacement(new pointField(mesh.nPoints(), Zero));
|
||||||
@ -268,10 +272,12 @@ Foam::tmp<Foam::pointField> Foam::snappySnapDriver::smoothInternalDisplacement
|
|||||||
|
|
||||||
forAll(displacement, pointi)
|
forAll(displacement, pointi)
|
||||||
{
|
{
|
||||||
if (nCells[pointi] > 0)
|
const weightedPosition& wp = sumLocation[pointi];
|
||||||
|
if (mag(wp.first()) > VSMALL)
|
||||||
{
|
{
|
||||||
displacement[pointi] =
|
displacement[pointi] =
|
||||||
sumLocation[pointi]/nCells[pointi]-mesh.points()[pointi];
|
wp.second()/wp.first()
|
||||||
|
- mesh.points()[pointi];
|
||||||
nAdapted++;
|
nAdapted++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -355,56 +361,61 @@ Foam::tmp<Foam::pointField> Foam::snappySnapDriver::smoothPatchDisplacement
|
|||||||
// Get average position of boundary face centres
|
// Get average position of boundary face centres
|
||||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
vectorField avgBoundary(pointFaces.size(), Zero);
|
Field<weightedPosition> avgBoundary
|
||||||
labelList nBoundary(pointFaces.size(), Zero);
|
(
|
||||||
|
pointFaces.size(),
|
||||||
forAll(pointFaces, patchPointi)
|
pTraits<weightedPosition>::zero
|
||||||
|
);
|
||||||
{
|
{
|
||||||
const labelList& pFaces = pointFaces[patchPointi];
|
forAll(pointFaces, patchPointi)
|
||||||
|
|
||||||
forAll(pFaces, pfi)
|
|
||||||
{
|
{
|
||||||
label facei = pFaces[pfi];
|
const labelList& pFaces = pointFaces[patchPointi];
|
||||||
|
|
||||||
if (isMasterFace.test(pp.addressing()[facei]))
|
forAll(pFaces, pfi)
|
||||||
{
|
{
|
||||||
avgBoundary[patchPointi] += pp[facei].centre(points);
|
label facei = pFaces[pfi];
|
||||||
nBoundary[patchPointi]++;
|
|
||||||
|
if (isMasterFace.test(pp.addressing()[facei]))
|
||||||
|
{
|
||||||
|
avgBoundary[patchPointi].first() += 1.0;
|
||||||
|
avgBoundary[patchPointi].second() +=
|
||||||
|
pp[facei].centre(points);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
syncTools::syncPointList
|
syncTools::syncPointList
|
||||||
(
|
(
|
||||||
mesh,
|
mesh,
|
||||||
pp.meshPoints(),
|
pp.meshPoints(),
|
||||||
avgBoundary,
|
avgBoundary,
|
||||||
plusEqOp<point>(), // combine op
|
weightedPosition::plusEqOp, // combine op
|
||||||
vector::zero // null value
|
pTraits<weightedPosition>::zero,// null value (not used)
|
||||||
);
|
pTraits<weightedPosition>::zero // transform class
|
||||||
syncTools::syncPointList
|
);
|
||||||
(
|
|
||||||
mesh,
|
|
||||||
pp.meshPoints(),
|
|
||||||
nBoundary,
|
|
||||||
plusEqOp<label>(), // combine op
|
|
||||||
label(0) // null value
|
|
||||||
);
|
|
||||||
|
|
||||||
forAll(avgBoundary, i)
|
// Normalise
|
||||||
{
|
forAll(avgBoundary, i)
|
||||||
avgBoundary[i] /= nBoundary[i];
|
{
|
||||||
|
// Note: what if there is no master boundary face?
|
||||||
|
if (mag(avgBoundary[i].first()) > VSMALL)
|
||||||
|
{
|
||||||
|
avgBoundary[i].second() /= avgBoundary[i].first();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Get average position of internal face centres
|
// Get average position of internal face centres
|
||||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
vectorField avgInternal;
|
Field<weightedPosition> avgInternal;
|
||||||
labelList nInternal;
|
|
||||||
{
|
{
|
||||||
vectorField globalSum(mesh.nPoints(), Zero);
|
Field<weightedPosition> globalSum
|
||||||
labelList globalNum(mesh.nPoints(), Zero);
|
(
|
||||||
|
mesh.nPoints(),
|
||||||
|
pTraits<weightedPosition>::zero
|
||||||
|
);
|
||||||
|
|
||||||
// Note: no use of pointFaces
|
// Note: no use of pointFaces
|
||||||
const faceList& faces = mesh.faces();
|
const faceList& faces = mesh.faces();
|
||||||
@ -416,8 +427,9 @@ Foam::tmp<Foam::pointField> Foam::snappySnapDriver::smoothPatchDisplacement
|
|||||||
|
|
||||||
forAll(f, fp)
|
forAll(f, fp)
|
||||||
{
|
{
|
||||||
globalSum[f[fp]] += fc;
|
weightedPosition& wp = globalSum[f[fp]];
|
||||||
globalNum[f[fp]]++;
|
wp.first() += 1.0;
|
||||||
|
wp.second() += fc;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -444,8 +456,9 @@ Foam::tmp<Foam::pointField> Foam::snappySnapDriver::smoothPatchDisplacement
|
|||||||
|
|
||||||
forAll(f, fp)
|
forAll(f, fp)
|
||||||
{
|
{
|
||||||
globalSum[f[fp]] += fc;
|
weightedPosition& wp = globalSum[f[fp]];
|
||||||
globalNum[f[fp]]++;
|
wp.first() += 1.0;
|
||||||
|
wp.second() += fc;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -455,35 +468,28 @@ Foam::tmp<Foam::pointField> Foam::snappySnapDriver::smoothPatchDisplacement
|
|||||||
(
|
(
|
||||||
mesh,
|
mesh,
|
||||||
globalSum,
|
globalSum,
|
||||||
plusEqOp<vector>(), // combine op
|
weightedPosition::plusEqOp, // combine op
|
||||||
vector::zero // null value
|
pTraits<weightedPosition>::zero,// null value (not used)
|
||||||
);
|
pTraits<weightedPosition>::zero // transform class
|
||||||
syncTools::syncPointList
|
|
||||||
(
|
|
||||||
mesh,
|
|
||||||
globalNum,
|
|
||||||
plusEqOp<label>(), // combine op
|
|
||||||
label(0) // null value
|
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
avgInternal.setSize(meshPoints.size());
|
avgInternal.setSize(meshPoints.size());
|
||||||
nInternal.setSize(meshPoints.size());
|
|
||||||
|
|
||||||
forAll(avgInternal, patchPointi)
|
forAll(avgInternal, patchPointi)
|
||||||
{
|
{
|
||||||
label meshPointi = meshPoints[patchPointi];
|
label meshPointi = meshPoints[patchPointi];
|
||||||
|
const weightedPosition& wp = globalSum[meshPointi];
|
||||||
|
|
||||||
nInternal[patchPointi] = globalNum[meshPointi];
|
avgInternal[patchPointi].first() = wp.first();
|
||||||
|
if (mag(wp.first()) < VSMALL)
|
||||||
if (nInternal[patchPointi] == 0)
|
|
||||||
{
|
{
|
||||||
avgInternal[patchPointi] = globalSum[meshPointi];
|
// Set to zero?
|
||||||
|
avgInternal[patchPointi].second() = wp.second();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
avgInternal[patchPointi] =
|
avgInternal[patchPointi].second() = wp.second()/wp.first();
|
||||||
globalSum[meshPointi]
|
|
||||||
/ nInternal[patchPointi];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -514,13 +520,15 @@ Foam::tmp<Foam::pointField> Foam::snappySnapDriver::smoothPatchDisplacement
|
|||||||
label meshPointi = meshPoints[i];
|
label meshPointi = meshPoints[i];
|
||||||
const point& currentPos = pp.points()[meshPointi];
|
const point& currentPos = pp.points()[meshPointi];
|
||||||
|
|
||||||
// Now we have the two average points: avgBoundary and avgInternal
|
// Now we have the two average points and their counts:
|
||||||
// and how many boundary/internal faces connect to the point
|
// avgBoundary and avgInternal
|
||||||
// (nBoundary, nInternal)
|
|
||||||
// Do some blending between the two.
|
// Do some blending between the two.
|
||||||
// Note: the following section has some reasoning behind it but the
|
// Note: the following section has some reasoning behind it but the
|
||||||
// blending factors can be experimented with.
|
// blending factors can be experimented with.
|
||||||
|
|
||||||
|
const weightedPosition& internal = avgInternal[i];
|
||||||
|
const weightedPosition& boundary = avgBoundary[i];
|
||||||
|
|
||||||
point newPos;
|
point newPos;
|
||||||
|
|
||||||
if (!nonManifoldPoint.test(i))
|
if (!nonManifoldPoint.test(i))
|
||||||
@ -532,14 +540,17 @@ Foam::tmp<Foam::pointField> Foam::snappySnapDriver::smoothPatchDisplacement
|
|||||||
|
|
||||||
point avgPos =
|
point avgPos =
|
||||||
(
|
(
|
||||||
internalBlend*nInternal[i]*avgInternal[i]
|
internalBlend*internal.first()*internal.second()
|
||||||
+(1-internalBlend)*nBoundary[i]*avgBoundary[i]
|
+(1-internalBlend)*boundary.first()*boundary.second()
|
||||||
)
|
)
|
||||||
/ (internalBlend*nInternal[i]+(1-internalBlend)*nBoundary[i]);
|
/ (
|
||||||
|
internalBlend*internal.first()
|
||||||
|
+(1-internalBlend)*boundary.first()
|
||||||
|
);
|
||||||
|
|
||||||
newPos = (1-blend)*avgPos + blend*currentPos;
|
newPos = (1-blend)*avgPos + blend*currentPos;
|
||||||
}
|
}
|
||||||
else if (nInternal[i] == 0)
|
else if (internal.first() == 0)
|
||||||
{
|
{
|
||||||
// Non-manifold without internal faces. Use any connected cell
|
// Non-manifold without internal faces. Use any connected cell
|
||||||
// as internal point instead. Use precalculated any cell to avoid
|
// as internal point instead. Use precalculated any cell to avoid
|
||||||
@ -550,7 +561,7 @@ Foam::tmp<Foam::pointField> Foam::snappySnapDriver::smoothPatchDisplacement
|
|||||||
scalar cellCBlend = 0.8;
|
scalar cellCBlend = 0.8;
|
||||||
scalar blend = 0.1;
|
scalar blend = 0.1;
|
||||||
|
|
||||||
point avgPos = (1-cellCBlend)*avgBoundary[i] + cellCBlend*cc;
|
point avgPos = (1-cellCBlend)*boundary.second() + cellCBlend*cc;
|
||||||
|
|
||||||
newPos = (1-blend)*avgPos + blend*currentPos;
|
newPos = (1-blend)*avgPos + blend*currentPos;
|
||||||
}
|
}
|
||||||
@ -561,8 +572,8 @@ Foam::tmp<Foam::pointField> Foam::snappySnapDriver::smoothPatchDisplacement
|
|||||||
scalar blend = 0.1;
|
scalar blend = 0.1;
|
||||||
|
|
||||||
point avgPos =
|
point avgPos =
|
||||||
internalBlend*avgInternal[i]
|
internalBlend*internal.second()
|
||||||
+ (1-internalBlend)*avgBoundary[i];
|
+ (1-internalBlend)*boundary.second();
|
||||||
|
|
||||||
newPos = (1-blend)*avgPos + blend*currentPos;
|
newPos = (1-blend)*avgPos + blend*currentPos;
|
||||||
}
|
}
|
||||||
@ -980,26 +991,22 @@ Foam::tmp<Foam::pointField> Foam::snappySnapDriver::avgCellCentres
|
|||||||
{
|
{
|
||||||
const labelListList& pointFaces = pp.pointFaces();
|
const labelListList& pointFaces = pp.pointFaces();
|
||||||
|
|
||||||
|
Field<weightedPosition> avgBoundary
|
||||||
tmp<pointField> tavgBoundary
|
|
||||||
(
|
(
|
||||||
new pointField(pointFaces.size(), Zero)
|
pointFaces.size(),
|
||||||
|
pTraits<weightedPosition>::zero
|
||||||
);
|
);
|
||||||
pointField& avgBoundary = tavgBoundary.ref();
|
|
||||||
labelList nBoundary(pointFaces.size(), Zero);
|
|
||||||
|
|
||||||
forAll(pointFaces, pointi)
|
forAll(pointFaces, pointi)
|
||||||
{
|
{
|
||||||
const labelList& pFaces = pointFaces[pointi];
|
const labelList& pFaces = pointFaces[pointi];
|
||||||
|
|
||||||
|
avgBoundary[pointi].first() = pFaces.size();
|
||||||
forAll(pFaces, pfi)
|
forAll(pFaces, pfi)
|
||||||
{
|
{
|
||||||
label facei = pFaces[pfi];
|
label facei = pFaces[pfi];
|
||||||
label meshFacei = pp.addressing()[facei];
|
label own = mesh.faceOwner()[pp.addressing()[facei]];
|
||||||
|
avgBoundary[pointi].second() += mesh.cellCentres()[own];
|
||||||
label own = mesh.faceOwner()[meshFacei];
|
|
||||||
avgBoundary[pointi] += mesh.cellCentres()[own];
|
|
||||||
nBoundary[pointi]++;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1008,22 +1015,14 @@ Foam::tmp<Foam::pointField> Foam::snappySnapDriver::avgCellCentres
|
|||||||
mesh,
|
mesh,
|
||||||
pp.meshPoints(),
|
pp.meshPoints(),
|
||||||
avgBoundary,
|
avgBoundary,
|
||||||
plusEqOp<point>(), // combine op
|
weightedPosition::plusEqOp, // combine op
|
||||||
vector::zero // null value
|
pTraits<weightedPosition>::zero,// null value (not used)
|
||||||
);
|
pTraits<weightedPosition>::zero // transform class
|
||||||
syncTools::syncPointList
|
|
||||||
(
|
|
||||||
mesh,
|
|
||||||
pp.meshPoints(),
|
|
||||||
nBoundary,
|
|
||||||
plusEqOp<label>(), // combine op
|
|
||||||
label(0) // null value
|
|
||||||
);
|
);
|
||||||
|
|
||||||
forAll(avgBoundary, i)
|
tmp<pointField> tavgBoundary(new pointField(avgBoundary.size()));
|
||||||
{
|
weightedPosition::getPoints(avgBoundary, tavgBoundary.ref());
|
||||||
avgBoundary[i] /= nBoundary[i];
|
|
||||||
}
|
|
||||||
return tavgBoundary;
|
return tavgBoundary;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -676,15 +676,42 @@ void Foam::snappySnapDriver::calcNearestFacePointProperties
|
|||||||
List<point>(),
|
List<point>(),
|
||||||
mapDistribute::transform()
|
mapDistribute::transform()
|
||||||
);
|
);
|
||||||
syncTools::syncPointList
|
|
||||||
(
|
{
|
||||||
mesh,
|
// Make into displacement before synchronising to avoid any problems
|
||||||
pp.meshPoints(),
|
// with parallel cyclics
|
||||||
pointFaceCentres,
|
pointField localPoints(pp.points(), pp.meshPoints());
|
||||||
listPlusEqOp<point>(),
|
forAll(pointFaceCentres, pointi)
|
||||||
List<point>(),
|
{
|
||||||
mapDistribute::transformPosition()
|
const point& pt = pp.points()[pp.meshPoints()[pointi]];
|
||||||
);
|
|
||||||
|
List<point>& pFc = pointFaceCentres[pointi];
|
||||||
|
for (point& p : pFc)
|
||||||
|
{
|
||||||
|
p -= pt;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
syncTools::syncPointList
|
||||||
|
(
|
||||||
|
mesh,
|
||||||
|
pp.meshPoints(),
|
||||||
|
pointFaceCentres,
|
||||||
|
listPlusEqOp<point>(),
|
||||||
|
List<point>(),
|
||||||
|
mapDistribute::transform()
|
||||||
|
);
|
||||||
|
forAll(pointFaceCentres, pointi)
|
||||||
|
{
|
||||||
|
const point& pt = pp.points()[pp.meshPoints()[pointi]];
|
||||||
|
|
||||||
|
List<point>& pFc = pointFaceCentres[pointi];
|
||||||
|
for (point& p : pFc)
|
||||||
|
{
|
||||||
|
p += pt;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
syncTools::syncPointList
|
syncTools::syncPointList
|
||||||
(
|
(
|
||||||
mesh,
|
mesh,
|
||||||
|
|||||||
Reference in New Issue
Block a user