From 4e4f9e0a0a1518fa4124ea8955fe0201f6b8e7ab Mon Sep 17 00:00:00 2001 From: henry <Henry Weller h.weller@opencfd.co.uk> Date: Sun, 12 Oct 2008 11:42:20 +0100 Subject: [PATCH] Added quadraticFit snGrad. --- .../quadraticFitSnGrad/quadraticFitSnGrad.H | 161 +++++++++ .../quadraticFitSnGradData.C | 325 ++++++++++++++++++ .../quadraticFitSnGradData.H | 131 +++++++ .../quadraticFitSnGrad/quadraticFitSnGrads.C | 44 +++ 4 files changed, 661 insertions(+) create mode 100644 src/finiteVolume/finiteVolume/snGradSchemes/quadraticFitSnGrad/quadraticFitSnGrad.H create mode 100644 src/finiteVolume/finiteVolume/snGradSchemes/quadraticFitSnGrad/quadraticFitSnGradData.C create mode 100644 src/finiteVolume/finiteVolume/snGradSchemes/quadraticFitSnGrad/quadraticFitSnGradData.H create mode 100644 src/finiteVolume/finiteVolume/snGradSchemes/quadraticFitSnGrad/quadraticFitSnGrads.C diff --git a/src/finiteVolume/finiteVolume/snGradSchemes/quadraticFitSnGrad/quadraticFitSnGrad.H b/src/finiteVolume/finiteVolume/snGradSchemes/quadraticFitSnGrad/quadraticFitSnGrad.H new file mode 100644 index 00000000000..b74c3d2f205 --- /dev/null +++ b/src/finiteVolume/finiteVolume/snGradSchemes/quadraticFitSnGrad/quadraticFitSnGrad.H @@ -0,0 +1,161 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 1991-2007 OpenCFD Ltd. + \\/ M anipulation | +------------------------------------------------------------------------------- +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 2 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, write to the Free Software Foundation, + Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +Class + quadraticFitSnGrad + +Description + Simple central-difference snGrad scheme with quadratic fit correction from + a larger stencil. + +SourceFiles + quadraticFitSnGrad.C + +\*---------------------------------------------------------------------------*/ + +#ifndef quadraticFitSnGrad_H +#define quadraticFitSnGrad_H + +#include "snGradScheme.H" +#include "quadraticFitSnGradData.H" +#include "extendedStencil.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace fv +{ + +/*---------------------------------------------------------------------------*\ + Class quadraticFitSnGrad Declaration +\*---------------------------------------------------------------------------*/ + +template<class Type> +class quadraticFitSnGrad +: + public snGradScheme<Type> +{ + // Private Data + //- weights for central stencil + const scalar centralWeight_; + + // Private Member Functions + + //- Disallow default bitwise assignment + void operator=(const quadraticFitSnGrad&); + + +public: + + //- Runtime type information + TypeName("quadraticFit"); + + + // Constructors + + //- Construct from mesh and scheme data + quadraticFitSnGrad + ( + const fvMesh& mesh, + const scalar centralWeight + ) + : + snGradScheme<Type>(mesh), + centralWeight_(centralWeight) + {} + + + //- Construct from mesh and data stream + quadraticFitSnGrad(const fvMesh& mesh, Istream& is) + : + snGradScheme<Type>(mesh), + centralWeight_(readScalar(is)) + {} + + + // Destructor + + virtual ~quadraticFitSnGrad() {} + + + // Member Functions + + //- Return the interpolation weighting factors for the given field + virtual tmp<surfaceScalarField> deltaCoeffs + ( + const GeometricField<Type, fvPatchField, volMesh>& + ) const + { + return this->mesh().deltaCoeffs(); + } + + //- Return true if this scheme uses an explicit correction + virtual bool corrected() const + { + return true; + } + + //- Return the explicit correction to the quadraticFitSnGrad + // for the given field + virtual tmp<GeometricField<Type, fvsPatchField, surfaceMesh> > + correction(const GeometricField<Type, fvPatchField, volMesh>& vf) const + { + const fvMesh& mesh = this->mesh(); + + const quadraticFitSnGradData& qfd = quadraticFitSnGradData::New + ( + mesh, + centralWeight_ + ); + + const extendedStencil& stencil = qfd.stencil(); + const List<scalarList>& f = qfd.fit(); + + tmp<GeometricField<Type, fvsPatchField, surfaceMesh> > sft + = stencil.weightedSum(vf, f); + + sft().dimensions() /= dimLength; + + return sft; + } +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace fv + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/finiteVolume/finiteVolume/snGradSchemes/quadraticFitSnGrad/quadraticFitSnGradData.C b/src/finiteVolume/finiteVolume/snGradSchemes/quadraticFitSnGrad/quadraticFitSnGradData.C new file mode 100644 index 00000000000..133f1e79332 --- /dev/null +++ b/src/finiteVolume/finiteVolume/snGradSchemes/quadraticFitSnGrad/quadraticFitSnGradData.C @@ -0,0 +1,325 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 1991-2007 OpenCFD Ltd. + \\/ M anipulation | +------------------------------------------------------------------------------- +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 2 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, write to the Free Software Foundation, + Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +\*---------------------------------------------------------------------------*/ + +#include "quadraticFitSnGradData.H" +#include "surfaceFields.H" +#include "volFields.H" +#include "SVD.H" +#include "syncTools.H" + +// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // + +namespace Foam +{ + defineTypeNameAndDebug(quadraticFitSnGradData, 0); +} + + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +Foam::quadraticFitSnGradData::quadraticFitSnGradData +( + const fvMesh& mesh, + const scalar cWeight +) +: + MeshObject<fvMesh, quadraticFitSnGradData>(mesh), + centralWeight_(cWeight), + #ifdef SPHERICAL_GEOMETRY + dim_(2), + #else + dim_(mesh.nGeometricD()), + #endif + minSize_ + ( + dim_ == 1 ? 3 : + dim_ == 2 ? 6 : + dim_ == 3 ? 9 : 0 + ), + stencil_(mesh), + fit_(mesh.nInternalFaces()) +{ + if (debug) + { + Info << "Contructing quadraticFitSnGradData" << endl; + } + + // check input + if (centralWeight_ < 1 - SMALL) + { + FatalErrorIn("quadraticFitSnGradData::quadraticFitSnGradData") + << "centralWeight requested = " << centralWeight_ + << " should not be less than one" + << exit(FatalError); + } + + if (minSize_ == 0) + { + FatalErrorIn("quadraticFitSnGradData") + << " dimension must be 1,2 or 3, not" << dim_ << exit(FatalError); + } + + // store the polynomial size for each face to write out + surfaceScalarField snGradPolySize + ( + IOobject + ( + "quadraticFitSnGradPolySize", + "constant", + mesh, + IOobject::NO_READ, + IOobject::NO_WRITE + ), + mesh, + dimensionedScalar("quadraticFitSnGradPolySize", 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(stencil_.stencil().size()); + stencil_.collectData + ( + mesh.C(), + stencilPoints + ); + + // find the fit coefficients for every face in the mesh + + for(label faci = 0; faci < mesh.nInternalFaces(); faci++) + { + snGradPolySize[faci] = calcFit(stencilPoints[faci], faci); + } + + if (debug) + { + snGradPolySize.write(); + Info<< "quadraticFitSnGradData::quadraticFitSnGradData() :" + << "Finished constructing polynomialFit data" + << endl; + } +} + + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +void Foam::quadraticFitSnGradData::findFaceDirs +( + vector& idir, // value changed in return + vector& jdir, // value changed in return + vector& kdir, // value changed in return + const fvMesh& mesh, + const label faci +) +{ + idir = mesh.Sf()[faci]; + idir /= mag(idir); + + #ifndef SPHERICAL_GEOMETRY + if (mesh.nGeometricD() <= 2) // find the normal direcion + { + if (mesh.directions()[0] == -1) + { + kdir = vector(1, 0, 0); + } + else if (mesh.directions()[1] == -1) + { + kdir = vector(0, 1, 0); + } + else + { + kdir = vector(0, 0, 1); + } + } + else // 3D so find a direction in the place of the face + { + const face& f = mesh.faces()[faci]; + kdir = mesh.points()[f[0]] - mesh.points()[f[1]]; + } + #else + // Spherical geometry so kdir is the radial direction + kdir = mesh.Cf()[faci]; + #endif + + if (mesh.nGeometricD() == 3) + { + // Remove the idir component from kdir and normalise + kdir -= (idir & kdir)*idir; + + scalar magk = mag(kdir); + + if (magk < SMALL) + { + FatalErrorIn("findFaceDirs") << " calculated kdir = zero" + << exit(FatalError); + } + else + { + kdir /= magk; + } + } + + jdir = kdir ^ idir; +} + + +Foam::label Foam::quadraticFitSnGradData::calcFit +( + const List<point>& C, + const label faci +) +{ + vector idir(1,0,0); + vector jdir(0,1,0); + vector kdir(0,0,1); + findFaceDirs(idir, jdir, kdir, mesh(), faci); + + scalarList wts(C.size(), scalar(1)); + wts[0] = centralWeight_; + wts[1] = centralWeight_; + + point p0 = mesh().faceCentres()[faci]; + scalar scale = 0; + + // calculate the matrix of the polynomial components + scalarRectangularMatrix B(C.size(), minSize_, scalar(0)); + + for(label ip = 0; ip < C.size(); ip++) + { + const point& p = C[ip]; + + scalar px = (p - p0)&idir; + scalar py = (p - p0)&jdir; + #ifdef SPHERICAL_GEOMETRY + scalar pz = mag(p) - mag(p0); + #else + scalar pz = (p - p0)&kdir; + #endif + + if (ip == 0) scale = max(max(mag(px), mag(py)), mag(pz)); + + px /= scale; + py /= scale; + pz /= scale; + + label is = 0; + + B[ip][is++] = wts[0]*wts[ip]; + B[ip][is++] = wts[0]*wts[ip]*px; + B[ip][is++] = wts[ip]*sqr(px); + + if (dim_ >= 2) + { + B[ip][is++] = wts[ip]*py; + B[ip][is++] = wts[ip]*px*py; + B[ip][is++] = wts[ip]*sqr(py); + } + if (dim_ == 3) + { + B[ip][is++] = wts[ip]*pz; + B[ip][is++] = wts[ip]*px*pz; + //B[ip][is++] = wts[ip]*py*pz; + B[ip][is++] = wts[ip]*sqr(pz); + } + } + + // Set the fit + label stencilSize = C.size(); + fit_[faci].setSize(stencilSize); + scalarList singVals(minSize_); + label nSVDzeros = 0; + + const scalar& deltaCoeff = mesh().deltaCoeffs()[faci]; + + bool goodFit = false; + for(int iIt = 0; iIt < 10 && !goodFit; iIt++) + { + SVD svd(B, SMALL); + + scalar fit0 = wts[0]*wts[0]*svd.VSinvUt()[1][0]/scale; + scalar fit1 = wts[0]*wts[1]*svd.VSinvUt()[1][1]/scale; + + goodFit = + fit0 < 0 && fit1 > 0 + && mag(fit0 + deltaCoeff) < 0.5*deltaCoeff + && mag(fit1 - deltaCoeff) < 0.5*deltaCoeff; + + if (goodFit) + { + fit_[faci][0] = fit0; + fit_[faci][1] = fit1; + for(label i = 2; i < stencilSize; i++) + { + fit_[faci][i] = wts[0]*wts[i]*svd.VSinvUt()[1][i]/scale; + } + singVals = svd.S(); + nSVDzeros = svd.nZeros(); + } + else // (not good fit so increase weight in the centre and for linear) + { + wts[0] *= 10; + wts[1] *= 10; + + for(label i = 0; i < B.n(); i++) + { + B[i][0] *= 10; + B[i][1] *= 10; + } + + for(label j = 0; j < B.m(); j++) + { + B[0][j] *= 10; + B[1][j] *= 10; + } + } + } + + if (goodFit) + { + // remove the uncorrected snGradScheme coefficients + fit_[faci][0] += deltaCoeff; + fit_[faci][1] -= deltaCoeff; + } + else + { + Pout<< "quadratifFitSnGradData could not fit face " << faci + << " fit_[faci][0] = " << fit_[faci][0] + << " fit_[faci][1] = " << fit_[faci][1] + << " deltaCoeff = " << deltaCoeff << endl; + fit_[faci] = 0; + } + + return minSize_ - nSVDzeros; +} + +bool Foam::quadraticFitSnGradData::movePoints() +{ + notImplemented("quadraticFitSnGradData::movePoints()"); + + return true; +} + + +// ************************************************************************* // diff --git a/src/finiteVolume/finiteVolume/snGradSchemes/quadraticFitSnGrad/quadraticFitSnGradData.H b/src/finiteVolume/finiteVolume/snGradSchemes/quadraticFitSnGrad/quadraticFitSnGradData.H new file mode 100644 index 00000000000..0f5fda5ce6e --- /dev/null +++ b/src/finiteVolume/finiteVolume/snGradSchemes/quadraticFitSnGrad/quadraticFitSnGradData.H @@ -0,0 +1,131 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 1991-2007 OpenCFD Ltd. + \\/ M anipulation | +------------------------------------------------------------------------------- +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 2 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, write to the Free Software Foundation, + Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +Class + quadraticFitSnGradData + +Description + Data for the quadratic fit correction snGrad scheme + +SourceFiles + quadraticFitSnGradData.C + +\*---------------------------------------------------------------------------*/ + +#ifndef quadraticFitSnGradData_H +#define quadraticFitSnGradData_H + +#include "MeshObject.H" +#include "fvMesh.H" +#include "extendedStencil.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +/*---------------------------------------------------------------------------*\ + Class quadraticFitSnGradData Declaration +\*---------------------------------------------------------------------------*/ + +class quadraticFitSnGradData +: + public MeshObject<fvMesh, quadraticFitSnGradData> +{ + // Private data + + const scalar centralWeight_; + const label dim_; + + //- minimum stencil size + const label minSize_; + + //- Extended stencil addressing + extendedStencil stencil_; + + //- For each cell in the mesh store the values which multiply the + // values of the stencil to obtain the gradient for each direction + List<scalarList> fit_; + + + // Private member functions + + //- Find the normal direction and i, j and k directions for face faci + static void findFaceDirs + ( + vector& idir, // value changed in return + vector& jdir, // value changed in return + vector& kdir, // value changed in return + const fvMesh& mesh, + const label faci + ); + + label calcFit(const List<point>&, const label faci); + + +public: + + TypeName("quadraticFitSnGradData"); + + + // Constructors + + explicit quadraticFitSnGradData + ( + const fvMesh& mesh, + const scalar cWeight + ); + + + // Destructor + + virtual ~quadraticFitSnGradData() + {}; + + + // Member functions + + //- Return reference to the stencil + const extendedStencil& stencil() const + { + return stencil_; + } + + //- Return reference to fit coefficients + const List<scalarList>& fit() const { return fit_; } + + //- Delete the data when the mesh moves not implemented + virtual bool movePoints(); +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/finiteVolume/finiteVolume/snGradSchemes/quadraticFitSnGrad/quadraticFitSnGrads.C b/src/finiteVolume/finiteVolume/snGradSchemes/quadraticFitSnGrad/quadraticFitSnGrads.C new file mode 100644 index 00000000000..aee4af29e3b --- /dev/null +++ b/src/finiteVolume/finiteVolume/snGradSchemes/quadraticFitSnGrad/quadraticFitSnGrads.C @@ -0,0 +1,44 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 1991-2007 OpenCFD Ltd. + \\/ M anipulation | +------------------------------------------------------------------------------- +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 2 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, write to the Free Software Foundation, + Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +Description + Simple central-difference snGrad scheme with quadratic fit correction from + a larger stencil. + +\*---------------------------------------------------------------------------*/ + +#include "quadraticFitSnGrad.H" +#include "fvMesh.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ +namespace fv +{ + makeSnGradScheme(quadraticFitSnGrad) +} +} + +// ************************************************************************* // -- GitLab