Commit c06c63f4 authored by mattijs's avatar mattijs
Browse files

ENH: snappyHexMesh: handle parallel cyclics. Fixes #1731.

parent 423bbcef
......@@ -17,6 +17,7 @@ meshRefinement/meshRefinementGapRefine.C
meshRefinement/meshRefinementBlock.C
meshRefinement/wallPoints.C
meshRefinement/patchFaceOrientation.C
meshRefinement/weightedPosition.C
refinementFeatures/refinementFeatures.C
refinementSurfaces/surfaceZonesInfo.C
......
......@@ -1093,7 +1093,7 @@ Foam::labelList Foam::meshRefinement::markFacesOnProblemCellsGeometric
newPoints[meshPoints[i]] += disp[i];
}
syncTools::syncPointList
syncTools::syncPointPositions
(
mesh_,
newPoints,
......
/*---------------------------------------------------------------------------*\
========= |
\\ / 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());
  • for safety if increasing the length of out ?

    out.resize(in.size(), Tuple2<scalar, point>(Zero, Zero));

    But if that did occur, the following weighted output would be zero. So actually need 1 for the weighting? Or I am just worry about nothing.

    Edited by Mark Olesen
Please register or sign in to reply
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);
}
// ************************************************************************* //
/*---------------------------------------------------------------------------*\
========= |
\\ / 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
// ************************************************************************* //
/*---------------------------------------------------------------------------*\
========= |
\\ / 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 |
-------------------------------------------------------------------------------
Copyright (C) 2011-2015 OpenFOAM Foundation
Copyright (C) 2015-2019 OpenCFD Ltd.
Copyright (C) 2015-2020 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
......@@ -48,6 +48,7 @@ Description
#include "localPointRegion.H"
#include "PatchTools.H"
#include "refinementFeatures.H"
#include "weightedPosition.H"
#include "profiling.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
......@@ -234,8 +235,11 @@ Foam::tmp<Foam::pointField> Foam::snappySnapDriver::smoothInternalDisplacement
// Calculate average of connected cells
labelList nCells(mesh.nPoints(), Zero);
pointField sumLocation(mesh.nPoints(), Zero);
Field<weightedPosition> sumLocation
(
mesh.nPoints(),
pTraits<weightedPosition>::zero
);
forAll(isMovingPoint, pointi)
{
......@@ -243,22 +247,22 @@ Foam::tmp<Foam::pointField> Foam::snappySnapDriver::smoothInternalDisplacement
{
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]];
nCells[pointi]++;
sumLocation[pointi].second() += mesh.cellCentres()[celli];
}
}
}
// Sum
syncTools::syncPointList(mesh, nCells, plusEqOp<label>(), label(0));
syncTools::syncPointList
(
mesh,
sumLocation,
plusEqOp<point>(),
vector::zero
weightedPosition::plusEqOp, // combine op
pTraits<weightedPosition>::zero,// null value (not used)
pTraits<weightedPosition>::zero // transform class
);
tmp<pointField> tdisplacement(new pointField(mesh.nPoints(), Zero));
......@@ -268,10 +272,12 @@ Foam::tmp<Foam::pointField> Foam::snappySnapDriver::smoothInternalDisplacement
forAll(displacement, pointi)
{
if (nCells[pointi] > 0)
const weightedPosition& wp = sumLocation[pointi];
if (mag(wp.first()) > VSMALL)
{
displacement[pointi] =
sumLocation[pointi]/nCells[pointi]-mesh.points()[pointi];
wp.second()/wp.first()
- mesh.points()[pointi];
nAdapted++;
}
}
......@@ -355,56 +361,61 @@ Foam::tmp<Foam::pointField> Foam::snappySnapDriver::smoothPatchDisplacement
// Get average position of boundary face centres
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
vectorField avgBoundary(pointFaces.size(), Zero);
labelList nBoundary(pointFaces.size(), Zero);
forAll(pointFaces, patchPointi)
Field<weightedPosition> avgBoundary
(
pointFaces.size(),
pTraits<weightedPosition>::zero
);
{
const labelList& pFaces = pointFaces[patchPointi];
forAll(pFaces, pfi)
forAll(pointFaces, patchPointi)
{
label facei = pFaces[pfi];
const labelList& pFaces = pointFaces[patchPointi];
if (isMasterFace.test(pp.addressing()[facei]))
forAll(pFaces, pfi)
{
avgBoundary[patchPointi] += pp[facei].centre(points);
nBoundary[patchPointi]++;
label facei = pFaces[pfi];
if (isMasterFace.test(pp.addressing()[facei]))
{
avgBoundary[patchPointi].first() += 1.0;
avgBoundary[patchPointi].second() +=
pp[facei].centre(points);
}
}
}
}
syncTools::syncPointList
(
mesh,
pp.meshPoints(),
avgBoundary,
plusEqOp<point>(), // combine op
vector::zero // null value
);
syncTools::syncPointList
(
mesh,
pp.meshPoints(),
nBoundary,
plusEqOp<label>(), // combine op
label(0) // null value
);
syncTools::syncPointList
(
mesh,
pp.meshPoints(),
avgBoundary,
weightedPosition::plusEqOp, // combine op
pTraits<weightedPosition>::zero,// null value (not used)
pTraits<weightedPosition>::zero // transform class
);
forAll(avgBoundary, i)
{
avgBoundary[i] /= nBoundary[i];
// Normalise
forAll(avgBoundary, 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
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
vectorField avgInternal;
labelList nInternal;
Field<weightedPosition> avgInternal;
{
vectorField globalSum(mesh.nPoints(), Zero);
labelList globalNum(mesh.nPoints(), Zero);
Field<weightedPosition> globalSum
(
mesh.nPoints(),
pTraits<weightedPosition>::zero
);
// Note: no use of pointFaces
const faceList& faces = mesh.faces();
......@@ -416,8 +427,9 @@ Foam::tmp<Foam::pointField> Foam::snappySnapDriver::smoothPatchDisplacement
forAll(f, fp)
{
globalSum[f[fp]] += fc;
globalNum[f[fp]]++;
weightedPosition& wp = globalSum[f[fp]];
wp.first() += 1.0;
wp.second() += fc;
}
}
......@@ -444,8 +456,9 @@ Foam::tmp<Foam::pointField> Foam::snappySnapDriver::smoothPatchDisplacement
forAll(f, fp)
{
globalSum[f[fp]] += fc;
globalNum[f[fp]]++;
weightedPosition& wp = globalSum[f[fp]];
wp.first() += 1.0;
wp.second() += fc;
}
}