Parallelized stencil-based fitting.

This commit is contained in:
henry
2008-10-23 22:44:27 +01:00
parent 809bbd5aeb
commit 2a1f28a3a8
9 changed files with 172 additions and 253 deletions

View File

@ -104,12 +104,12 @@ public:
); );
// Destructor // Destructors
static bool Delete(const Mesh& mesh);
virtual ~MeshObject(); virtual ~MeshObject();
static bool Delete(const Mesh& mesh);
// Member Functions // Member Functions

View File

@ -131,7 +131,6 @@ public:
const GeometricField<Type, fvPatchField, volMesh>& fld, const GeometricField<Type, fvPatchField, volMesh>& fld,
const List<List<scalar> >& stencilWeights const List<List<scalar> >& stencilWeights
); );
}; };

View File

@ -70,8 +70,7 @@ public:
{} {}
// Destructor //- Destructor
virtual ~centredCFCStencilObject() virtual ~centredCFCStencilObject()
{} {}
}; };

View File

@ -128,7 +128,6 @@ Foam::extendedStencil::weightedSum
// Boundaries. Either constrained or calculated so assign value // Boundaries. Either constrained or calculated so assign value
// directly (instead of nicely using operator==) // directly (instead of nicely using operator==)
/*
typename GeometricField<Type, fvsPatchField, surfaceMesh>:: typename GeometricField<Type, fvsPatchField, surfaceMesh>::
GeometricBoundaryField& bSfCorr = sf.boundaryField(); GeometricBoundaryField& bSfCorr = sf.boundaryField();
@ -136,6 +135,8 @@ Foam::extendedStencil::weightedSum
{ {
fvsPatchField<Type>& pSfCorr = bSfCorr[patchi]; fvsPatchField<Type>& pSfCorr = bSfCorr[patchi];
if (pSfCorr.coupled())
{
label faceI = pSfCorr.patch().patch().start(); label faceI = pSfCorr.patch().patch().start();
forAll(pSfCorr, i) forAll(pSfCorr, i)
@ -151,7 +152,7 @@ Foam::extendedStencil::weightedSum
faceI++; faceI++;
} }
} }
*/ }
return tsfCorr; return tsfCorr;
} }

View File

@ -102,6 +102,8 @@ Foam::extendedUpwindStencil::weightedSum
{ {
fvsPatchField<Type>& pSfCorr = bSfCorr[patchi]; fvsPatchField<Type>& pSfCorr = bSfCorr[patchi];
if (pSfCorr.coupled())
{
label faceI = pSfCorr.patch().patch().start(); label faceI = pSfCorr.patch().patch().start();
forAll(pSfCorr, i) forAll(pSfCorr, i)
@ -130,6 +132,7 @@ Foam::extendedUpwindStencil::weightedSum
faceI++; faceI++;
} }
} }
}
return tsfCorr; return tsfCorr;
} }

View File

@ -68,7 +68,6 @@ public:
//- Construct from mesh //- Construct from mesh
explicit cellFaceCellStencil(const polyMesh& mesh); explicit cellFaceCellStencil(const polyMesh& mesh);
}; };

View File

@ -42,9 +42,9 @@ License
#include "extendedLeastSquaresVectors.H" #include "extendedLeastSquaresVectors.H"
#include "extendedLeastSquaresVectors.H" #include "extendedLeastSquaresVectors.H"
#include "leastSquaresVectors.H" #include "leastSquaresVectors.H"
//#include "linearFitData.H" #include "CentredFitData.H"
#include "quadraticFitData.H" #include "linearFitPolynomial.H"
//#include "quadraticFitSnGradData.H" #include "quadraticLinearFitPolynomial.H"
#include "skewCorrectionVectors.H" #include "skewCorrectionVectors.H"
#include "centredCECStencilObject.H" #include "centredCECStencilObject.H"
@ -89,15 +89,13 @@ void Foam::fvMesh::clearGeom()
// Mesh motion flux cannot be deleted here because the old-time flux // Mesh motion flux cannot be deleted here because the old-time flux
// needs to be saved. // needs to be saved.
// Things geometry dependent that are not updated. // Things geometry dependent that are not updated.
volPointInterpolation::Delete(*this); volPointInterpolation::Delete(*this);
extendedLeastSquaresVectors::Delete(*this); extendedLeastSquaresVectors::Delete(*this);
extendedLeastSquaresVectors::Delete(*this); extendedLeastSquaresVectors::Delete(*this);
leastSquaresVectors::Delete(*this); leastSquaresVectors::Delete(*this);
//linearFitData::Delete(*this); CentredFitData<linearFitPolynomial>::Delete(*this);
quadraticFitData::Delete(*this); CentredFitData<quadraticLinearFitPolynomial>::Delete(*this);
//quadraticFitSnGradData::Delete(*this);
skewCorrectionVectors::Delete(*this); skewCorrectionVectors::Delete(*this);
} }
@ -112,9 +110,8 @@ void Foam::fvMesh::clearAddressing()
extendedLeastSquaresVectors::Delete(*this); extendedLeastSquaresVectors::Delete(*this);
extendedLeastSquaresVectors::Delete(*this); extendedLeastSquaresVectors::Delete(*this);
leastSquaresVectors::Delete(*this); leastSquaresVectors::Delete(*this);
//linearFitData::Delete(*this); CentredFitData<linearFitPolynomial>::Delete(*this);
quadraticFitData::Delete(*this); CentredFitData<quadraticLinearFitPolynomial>::Delete(*this);
//quadraticFitSnGradData::Delete(*this);
skewCorrectionVectors::Delete(*this); skewCorrectionVectors::Delete(*this);
centredCECStencilObject::Delete(*this); centredCECStencilObject::Delete(*this);
@ -364,7 +361,6 @@ Foam::fvMesh::~fvMesh()
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
// Helper function for construction from pieces
void Foam::fvMesh::addFvPatches void Foam::fvMesh::addFvPatches
( (
const List<polyPatch*> & p, const List<polyPatch*> & p,
@ -552,6 +548,30 @@ void Foam::fvMesh::mapFields(const mapPolyMesh& meshMap)
} }
// Temporary helper function to call move points on
// MeshObjects
template<class Type>
void MeshObjectMovePoints(const Foam::fvMesh& mesh)
{
if
(
mesh.db().objectRegistry::foundObject<Type>
(
Type::typeName
)
)
{
const_cast<Type&>
(
mesh.db().objectRegistry::lookupObject<Type>
(
Type::typeName
)
).movePoints();
}
}
Foam::tmp<Foam::scalarField> Foam::fvMesh::movePoints(const pointField& p) Foam::tmp<Foam::scalarField> Foam::fvMesh::movePoints(const pointField& p)
{ {
// Grab old time volumes if the time has been incremented // Grab old time volumes if the time has been incremented
@ -642,133 +662,12 @@ Foam::tmp<Foam::scalarField> Foam::fvMesh::movePoints(const pointField& p)
// Hack until proper callbacks. Below are all the fvMesh MeshObjects with a // Hack until proper callbacks. Below are all the fvMesh MeshObjects with a
// movePoints function. // movePoints function.
MeshObjectMovePoints<volPointInterpolation>(*this);
// volPointInterpolation MeshObjectMovePoints<extendedLeastSquaresVectors>(*this);
if MeshObjectMovePoints<leastSquaresVectors>(*this);
( MeshObjectMovePoints<CentredFitData<linearFitPolynomial> >(*this);
db().objectRegistry::foundObject<volPointInterpolation> MeshObjectMovePoints<CentredFitData<quadraticLinearFitPolynomial> >(*this);
( MeshObjectMovePoints<skewCorrectionVectors>(*this);
volPointInterpolation::typeName
)
)
{
const_cast<volPointInterpolation&>
(
db().objectRegistry::lookupObject<volPointInterpolation>
(
volPointInterpolation::typeName
)
).movePoints();
}
// extendedLeastSquaresVectors
if
(
db().objectRegistry::foundObject<extendedLeastSquaresVectors>
(
extendedLeastSquaresVectors::typeName
)
)
{
const_cast<extendedLeastSquaresVectors&>
(
db().objectRegistry::lookupObject<extendedLeastSquaresVectors>
(
extendedLeastSquaresVectors::typeName
)
).movePoints();
}
// leastSquaresVectors
if
(
db().objectRegistry::foundObject<leastSquaresVectors>
(
leastSquaresVectors::typeName
)
)
{
const_cast<leastSquaresVectors&>
(
db().objectRegistry::lookupObject<leastSquaresVectors>
(
leastSquaresVectors::typeName
)
).movePoints();
}
//// linearFitData
//if
//(
// db().objectRegistry::foundObject<linearFitData>
// (
// linearFitData::typeName
// )
//)
//{
// const_cast<linearFitData&>
// (
// db().objectRegistry::lookupObject<linearFitData>
// (
// linearFitData::typeName
// )
// ).movePoints();
//}
// quadraticFitData
if
(
db().objectRegistry::foundObject<quadraticFitData>
(
quadraticFitData::typeName
)
)
{
const_cast<quadraticFitData&>
(
db().objectRegistry::lookupObject<quadraticFitData>
(
quadraticFitData::typeName
)
).movePoints();
}
//// quadraticFitSnGradData
//if
//(
// db().objectRegistry::foundObject<quadraticFitSnGradData>
// (
// quadraticFitSnGradData::typeName
// )
//)
//{
// const_cast<quadraticFitSnGradData&>
// (
// db().objectRegistry::lookupObject<quadraticFitSnGradData>
// (
// quadraticFitSnGradData::typeName
// )
// ).movePoints();
//}
// skewCorrectionVectors
if
(
db().objectRegistry::foundObject<skewCorrectionVectors>
(
skewCorrectionVectors::typeName
)
)
{
const_cast<skewCorrectionVectors&>
(
db().objectRegistry::lookupObject<skewCorrectionVectors>
(
skewCorrectionVectors::typeName
)
).movePoints();
}
return tsweptVols; return tsweptVols;
} }

View File

@ -43,6 +43,7 @@ Foam::CentredFitData<Polynomial>::CentredFitData
) )
: :
MeshObject<fvMesh, CentredFitData<Polynomial> >(mesh), MeshObject<fvMesh, CentredFitData<Polynomial> >(mesh),
stencil_(stencil),
linearLimitFactor_(linearLimitFactor), linearLimitFactor_(linearLimitFactor),
centralWeight_(centralWeight), centralWeight_(centralWeight),
# ifdef SPHERICAL_GEOMETRY # ifdef SPHERICAL_GEOMETRY
@ -51,62 +52,29 @@ Foam::CentredFitData<Polynomial>::CentredFitData
dim_(mesh.nGeometricD()), dim_(mesh.nGeometricD()),
# endif # endif
minSize_(Polynomial::nTerms(dim_)), minSize_(Polynomial::nTerms(dim_)),
coeffs_(mesh.nInternalFaces()) coeffs_(mesh.nFaces())
{ {
if (debug) if (debug)
{ {
Info<< "Contructing CentredFitData<Polynomial>" << endl; Info<< "Contructing CentredFitData<Polynomial>" << endl;
} }
// check input // Check input
if (centralWeight_ < 1 - SMALL) if (linearLimitFactor > 1)
{ {
FatalErrorIn("CentredFitData<Polynomial>::CentredFitData") FatalErrorIn("CentredFitData<Polynomial>::CentredFitData")
<< "centralWeight requested = " << centralWeight_ << "linearLimitFactor requested = " << linearLimitFactor
<< " should not be less than one" << " should not be less than one"
<< exit(FatalError); << exit(FatalError);
} }
if (minSize_ == 0) calcFit();
{
FatalErrorIn("CentredFitSnGradData")
<< " dimension must be 1,2 or 3, not" << dim_ << exit(FatalError);
}
// store the polynomial size for each cell to write out
surfaceScalarField interpPolySize
(
IOobject
(
"CentredFitInterpPolySize",
"constant",
mesh,
IOobject::NO_READ,
IOobject::NO_WRITE
),
mesh,
dimensionedScalar("CentredFitInterpPolySize", dimless, scalar(0))
);
// Get the cell/face centres in stencil order.
// Centred face stencils no good for triangles of tets. Need bigger stencils
List<List<point> > stencilPoints(mesh.nFaces());
stencil.collectData(mesh.C(), stencilPoints);
// find the fit coefficients for every face in the mesh
for(label faci = 0; faci < mesh.nInternalFaces(); faci++)
{
interpPolySize[faci] = calcFit(stencilPoints[faci], faci);
}
if (debug) if (debug)
{ {
Info<< "CentredFitData<Polynomial>::CentredFitData() :" Info<< "CentredFitData<Polynomial>::CentredFitData() :"
<< "Finished constructing polynomialFit data" << "Finished constructing polynomialFit data"
<< endl; << endl;
interpPolySize.write();
} }
} }
@ -120,15 +88,14 @@ void Foam::CentredFitData<Polynomial>::findFaceDirs
vector& jdir, // value changed in return vector& jdir, // value changed in return
vector& kdir, // value changed in return vector& kdir, // value changed in return
const fvMesh& mesh, const fvMesh& mesh,
const label faci const label facei
) )
{ {
idir = mesh.Sf()[faci]; idir = mesh.faceAreas()[facei];
//idir = mesh.C()[mesh.neighbour()[faci]] - mesh.C()[mesh.owner()[faci]];
idir /= mag(idir); idir /= mag(idir);
# ifndef SPHERICAL_GEOMETRY # ifndef SPHERICAL_GEOMETRY
if (mesh.nGeometricD() <= 2) // find the normal direcion if (mesh.nGeometricD() <= 2) // find the normal direction
{ {
if (mesh.directions()[0] == -1) if (mesh.directions()[0] == -1)
{ {
@ -143,14 +110,14 @@ void Foam::CentredFitData<Polynomial>::findFaceDirs
kdir = vector(0, 0, 1); kdir = vector(0, 0, 1);
} }
} }
else // 3D so find a direction in the place of the face else // 3D so find a direction in the plane of the face
{ {
const face& f = mesh.faces()[faci]; const face& f = mesh.faces()[facei];
kdir = mesh.points()[f[0]] - mesh.points()[f[1]]; kdir = mesh.points()[f[0]] - mesh.faceCentres()[facei];
} }
# else # else
// Spherical geometry so kdir is the radial direction // Spherical geometry so kdir is the radial direction
kdir = mesh.Cf()[faci]; kdir = mesh.faceCentres()[facei];
# endif # endif
if (mesh.nGeometricD() == 3) if (mesh.nGeometricD() == 3)
@ -175,17 +142,58 @@ void Foam::CentredFitData<Polynomial>::findFaceDirs
} }
template<class Polynomial>
void Foam::CentredFitData<Polynomial>::calcFit()
{
const fvMesh& mesh = this->mesh();
// Get the cell/face centres in stencil order.
// Centred face stencils no good for triangles of tets.
// Need bigger stencils
List<List<point> > stencilPoints(mesh.nFaces());
stencil_.collectData(mesh.C(), stencilPoints);
// find the fit coefficients for every face in the mesh
const surfaceScalarField& w = this->mesh().surfaceInterpolation::weights();
for(label facei = 0; facei < mesh.nInternalFaces(); facei++)
{
calcFit(stencilPoints[facei], w[facei], facei);
}
const surfaceScalarField::GeometricBoundaryField& bw = w.boundaryField();
forAll(bw, patchi)
{
const fvsPatchScalarField& pw = bw[patchi];
if (pw.coupled())
{
label facei = pw.patch().patch().start();
forAll(pw, i)
{
calcFit(stencilPoints[facei], pw[i], facei);
facei++;
}
}
}
}
template<class Polynomial> template<class Polynomial>
Foam::label Foam::CentredFitData<Polynomial>::calcFit Foam::label Foam::CentredFitData<Polynomial>::calcFit
( (
const List<point>& C, const List<point>& C,
const label faci const scalar wLin,
const label facei
) )
{ {
vector idir(1,0,0); vector idir(1,0,0);
vector jdir(0,1,0); vector jdir(0,1,0);
vector kdir(0,0,1); vector kdir(0,0,1);
findFaceDirs(idir, jdir, kdir, this->mesh(), faci); findFaceDirs(idir, jdir, kdir, this->mesh(), facei);
// Setup the point weights // Setup the point weights
scalarList wts(C.size(), scalar(1)); scalarList wts(C.size(), scalar(1));
@ -193,7 +201,7 @@ Foam::label Foam::CentredFitData<Polynomial>::calcFit
wts[1] = centralWeight_; wts[1] = centralWeight_;
// Reference point // Reference point
point p0 = this->mesh().faceCentres()[faci]; point p0 = this->mesh().faceCentres()[facei];
// p0 -> p vector in the face-local coordinate system // p0 -> p vector in the face-local coordinate system
vector d; vector d;
@ -235,13 +243,10 @@ Foam::label Foam::CentredFitData<Polynomial>::calcFit
// Set the fit // Set the fit
label stencilSize = C.size(); label stencilSize = C.size();
coeffs_[faci].setSize(stencilSize); coeffs_[facei].setSize(stencilSize);
scalarList singVals(minSize_); scalarList singVals(minSize_);
label nSVDzeros = 0; label nSVDzeros = 0;
const GeometricField<scalar, fvsPatchField, surfaceMesh>& w =
this->mesh().surfaceInterpolation::weights();
bool goodFit = false; bool goodFit = false;
for(int iIt = 0; iIt < 10 && !goodFit; iIt++) for(int iIt = 0; iIt < 10 && !goodFit; iIt++)
{ {
@ -251,11 +256,11 @@ Foam::label Foam::CentredFitData<Polynomial>::calcFit
scalar fit1 = wts[1]*svd.VSinvUt()[0][1]; scalar fit1 = wts[1]*svd.VSinvUt()[0][1];
goodFit = goodFit =
(mag(fit0 - w[faci]) < linearLimitFactor_*w[faci]) (mag(fit0 - wLin) < linearLimitFactor_*wLin)
&& (mag(fit1 - (1 - w[faci])) < linearLimitFactor_*(1 - w[faci])); && (mag(fit1 - (1 - wLin)) < linearLimitFactor_*(1 - wLin));
//scalar w0Err = fit0/w[faci]; //scalar w0Err = fit0/wLin;
//scalar w1Err = fit1/(1 - w[faci]); //scalar w1Err = fit1/(1 - wLin);
//goodFit = //goodFit =
// (w0Err > linearLimitFactor_ && w0Err < (1 + linearLimitFactor_)) // (w0Err > linearLimitFactor_ && w0Err < (1 + linearLimitFactor_))
@ -263,12 +268,12 @@ Foam::label Foam::CentredFitData<Polynomial>::calcFit
if (goodFit) if (goodFit)
{ {
coeffs_[faci][0] = fit0; coeffs_[facei][0] = fit0;
coeffs_[faci][1] = fit1; coeffs_[facei][1] = fit1;
for(label i=2; i<stencilSize; i++) for(label i=2; i<stencilSize; i++)
{ {
coeffs_[faci][i] = wts[i]*svd.VSinvUt()[0][i]; coeffs_[facei][i] = wts[i]*svd.VSinvUt()[0][i];
} }
singVals = svd.S(); singVals = svd.S();
@ -300,22 +305,24 @@ Foam::label Foam::CentredFitData<Polynomial>::calcFit
// ( // (
// min // min
// ( // (
// min(alpha - beta*mag(coeffs_[faci][0] - w[faci])/w[faci], 1), // min(alpha - beta*mag(coeffs_[facei][0] - wLin)/wLin, 1),
// min(alpha - beta*mag(coeffs_[faci][1] - (1 - w[faci]))/(1 - w[faci]), 1) // min(alpha - beta*mag(coeffs_[facei][1] - (1 - wLin))
// /(1 - wLin), 1)
// ), 0 // ), 0
// ); // );
//Info<< w[faci] << " " << coeffs_[faci][0] << " " << (1 - w[faci]) << " " << coeffs_[faci][1] << endl; //Info<< wLin << " " << coeffs_[facei][0]
// << " " << (1 - wLin) << " " << coeffs_[facei][1] << endl;
// Remove the uncorrected linear coefficients // Remove the uncorrected linear ocefficients
coeffs_[faci][0] -= w[faci]; coeffs_[facei][0] -= wLin;
coeffs_[faci][1] -= 1 - w[faci]; coeffs_[facei][1] -= 1 - wLin;
// if (limiter < 0.99) // if (limiter < 0.99)
// { // {
// for(label i = 0; i < stencilSize; i++) // for(label i = 0; i < stencilSize; i++)
// { // {
// coeffs_[faci][i] *= limiter; // coeffs_[facei][i] *= limiter;
// } // }
// } // }
} }
@ -326,16 +333,16 @@ Foam::label Foam::CentredFitData<Polynomial>::calcFit
WarningIn WarningIn
( (
"CentredFitData<Polynomial>::calcFit" "CentredFitData<Polynomial>::calcFit"
"(const List<point>& C, const label faci" "(const List<point>& C, const label facei"
) << "Could not fit face " << faci ) << "Could not fit face " << facei
<< ", reverting to linear." << nl << ", reverting to linear." << nl
<< " Weights " << " Weights "
<< coeffs_[faci][0] << " " << w[faci] << nl << coeffs_[facei][0] << " " << wLin << nl
<< " Linear weights " << " Linear weights "
<< coeffs_[faci][1] << " " << 1 - w[faci] << endl; << coeffs_[facei][1] << " " << 1 - wLin << endl;
} }
coeffs_[faci] = 0; coeffs_[facei] = 0;
} }
return minSize_ - nSVDzeros; return minSize_ - nSVDzeros;
@ -345,8 +352,7 @@ Foam::label Foam::CentredFitData<Polynomial>::calcFit
template<class Polynomial> template<class Polynomial>
bool Foam::CentredFitData<Polynomial>::movePoints() bool Foam::CentredFitData<Polynomial>::movePoints()
{ {
notImplemented("CentredFitData<Polynomial>::movePoints()"); calcFit();
return true; return true;
} }

View File

@ -57,6 +57,9 @@ class CentredFitData
{ {
// Private data // Private data
//- The stencil the fit is based on
const extendedCentredStencil& stencil_;
//- Factor the fit is allowed to deviate from linear. //- Factor the fit is allowed to deviate from linear.
// This limits the amount of high-order correction and increases // This limits the amount of high-order correction and increases
// stability on bad meshes // stability on bad meshes
@ -88,7 +91,17 @@ class CentredFitData
const label faci const label faci
); );
label calcFit(const List<point>&, const label faci); //- Calculate the fit for the all the mesh faces
// and set the coefficients
void calcFit();
//- Calculate the fit for the specified face and set the coefficients
label calcFit
(
const List<point>&, // Stencil points
const scalar wLin, // Linear weight
const label faci // Current face index
);
public: public: