diff --git a/src/finiteVolume/Make/files b/src/finiteVolume/Make/files
index 37cfc5f166..8b184cfaf1 100644
--- a/src/finiteVolume/Make/files
+++ b/src/finiteVolume/Make/files
@@ -467,6 +467,7 @@ $(convectionSchemes)/boundedConvectionScheme/boundedConvectionSchemes.C
laplacianSchemes = finiteVolume/laplacianSchemes
$(laplacianSchemes)/laplacianScheme/laplacianSchemes.C
$(laplacianSchemes)/gaussLaplacianScheme/gaussLaplacianSchemes.C
+$(laplacianSchemes)/relaxedNonOrthoGaussLaplacianScheme/relaxedNonOrthoGaussLaplacianSchemes.C
finiteVolume/fvc/fvcFlux.C
finiteVolume/fvc/fvcMeshPhi.C
diff --git a/src/finiteVolume/finiteVolume/laplacianSchemes/relaxedNonOrthoGaussLaplacianScheme/relaxedNonOrthoGaussLaplacianScheme.C b/src/finiteVolume/finiteVolume/laplacianSchemes/relaxedNonOrthoGaussLaplacianScheme/relaxedNonOrthoGaussLaplacianScheme.C
new file mode 100644
index 0000000000..d0732bf124
--- /dev/null
+++ b/src/finiteVolume/finiteVolume/laplacianSchemes/relaxedNonOrthoGaussLaplacianScheme/relaxedNonOrthoGaussLaplacianScheme.C
@@ -0,0 +1,276 @@
+/*---------------------------------------------------------------------------*\
+ ========= |
+ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
+ \\ / O peration |
+ \\ / A nd | www.openfoam.com
+ \\/ M anipulation |
+-------------------------------------------------------------------------------
+ Copyright (C) 2019 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 .
+
+\*---------------------------------------------------------------------------*/
+
+#include "relaxedNonOrthoGaussLaplacianScheme.H"
+#include "surfaceInterpolate.H"
+#include "fvcDiv.H"
+#include "fvcGrad.H"
+#include "fvMatrices.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace fv
+{
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+template
+tmp>
+relaxedNonOrthoGaussLaplacianScheme::fvmLaplacianUncorrected
+(
+ const surfaceScalarField& gammaMagSf,
+ const surfaceScalarField& deltaCoeffs,
+ const GeometricField& vf
+)
+{
+ tmp> tfvm
+ (
+ new fvMatrix
+ (
+ vf,
+ deltaCoeffs.dimensions()*gammaMagSf.dimensions()*vf.dimensions()
+ )
+ );
+ fvMatrix& fvm = tfvm.ref();
+
+ fvm.upper() = deltaCoeffs.primitiveField()*gammaMagSf.primitiveField();
+ fvm.negSumDiag();
+
+ forAll(vf.boundaryField(), patchi)
+ {
+ const fvPatchField& pvf = vf.boundaryField()[patchi];
+ const fvsPatchScalarField& pGamma = gammaMagSf.boundaryField()[patchi];
+ const fvsPatchScalarField& pDeltaCoeffs =
+ deltaCoeffs.boundaryField()[patchi];
+
+ if (pvf.coupled())
+ {
+ fvm.internalCoeffs()[patchi] =
+ pGamma*pvf.gradientInternalCoeffs(pDeltaCoeffs);
+ fvm.boundaryCoeffs()[patchi] =
+ -pGamma*pvf.gradientBoundaryCoeffs(pDeltaCoeffs);
+ }
+ else
+ {
+ fvm.internalCoeffs()[patchi] = pGamma*pvf.gradientInternalCoeffs();
+ fvm.boundaryCoeffs()[patchi] = -pGamma*pvf.gradientBoundaryCoeffs();
+ }
+ }
+
+ return tfvm;
+}
+
+
+template
+tmp>
+relaxedNonOrthoGaussLaplacianScheme::gammaSnGradCorr
+(
+ const surfaceVectorField& SfGammaCorr,
+ const GeometricField& vf
+)
+{
+ const fvMesh& mesh = this->mesh();
+
+ tmp> tgammaSnGradCorr
+ (
+ new GeometricField
+ (
+ IOobject
+ (
+ "gammaSnGradCorr("+vf.name()+')',
+ vf.instance(),
+ mesh,
+ IOobject::NO_READ,
+ IOobject::NO_WRITE
+ ),
+ mesh,
+ SfGammaCorr.dimensions()
+ *vf.dimensions()*mesh.deltaCoeffs().dimensions()
+ )
+ );
+
+ for (direction cmpt = 0; cmpt < pTraits::nComponents; cmpt++)
+ {
+ tgammaSnGradCorr.ref().replace
+ (
+ cmpt,
+ fvc::dotInterpolate(SfGammaCorr, fvc::grad(vf.component(cmpt)))
+ );
+ }
+
+ return tgammaSnGradCorr;
+}
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+template
+tmp>
+relaxedNonOrthoGaussLaplacianScheme::fvcLaplacian
+(
+ const GeometricField& vf
+)
+{
+ const fvMesh& mesh = this->mesh();
+
+ tmp> tLaplacian
+ (
+ fvc::div(this->tsnGradScheme_().snGrad(vf)*mesh.magSf())
+ );
+
+ tLaplacian.ref().rename("laplacian(" + vf.name() + ')');
+
+ return tLaplacian;
+}
+
+
+template
+tmp>
+relaxedNonOrthoGaussLaplacianScheme::fvmLaplacian
+(
+ const GeometricField& gamma,
+ const GeometricField& vf
+)
+{
+ const fvMesh& mesh = this->mesh();
+
+ typedef GeometricField SType;
+
+ const surfaceVectorField Sn(mesh.Sf()/mesh.magSf());
+
+ const surfaceVectorField SfGamma(mesh.Sf() & gamma);
+ const GeometricField SfGammaSn
+ (
+ SfGamma & Sn
+ );
+ const surfaceVectorField SfGammaCorr(SfGamma - SfGammaSn*Sn);
+
+ tmp> tfvm = fvmLaplacianUncorrected
+ (
+ SfGammaSn,
+ this->tsnGradScheme_().deltaCoeffs(vf),
+ vf
+ );
+ fvMatrix& fvm = tfvm.ref();
+
+ tmp tfaceFluxCorrection = gammaSnGradCorr(SfGammaCorr, vf);
+
+ if (this->tsnGradScheme_().corrected())
+ {
+ tfaceFluxCorrection.ref() +=
+ SfGammaSn*this->tsnGradScheme_().correction(vf);
+ }
+
+ const word corrName(tfaceFluxCorrection().name());
+
+ tmp trelaxedCorrection(new SType(tfaceFluxCorrection()));
+
+ const word oldName(corrName + "_0");
+ const scalar relax(vf.mesh().equationRelaxationFactor(oldName));
+
+ const objectRegistry& obr = vf.db();
+ if (obr.foundObject(oldName))
+ {
+ SType& oldCorrection = obr.lookupObjectRef(oldName);
+
+ trelaxedCorrection.ref() *= relax;
+ trelaxedCorrection.ref() += (1.0-relax)*oldCorrection;
+
+ oldCorrection = tfaceFluxCorrection;
+ }
+ else
+ {
+ SType* s = new SType(oldName, tfaceFluxCorrection);
+ s->store();
+ }
+
+ fvm.source() -=
+ mesh.V()
+ *fvc::div
+ (
+ trelaxedCorrection()
+ )().primitiveField();
+
+ if (mesh.fluxRequired(vf.name()))
+ {
+ fvm.faceFluxCorrectionPtr() = trelaxedCorrection.ptr();
+ }
+
+ return tfvm;
+}
+
+
+template
+tmp>
+relaxedNonOrthoGaussLaplacianScheme::fvcLaplacian
+(
+ const GeometricField& gamma,
+ const GeometricField& vf
+)
+{
+ const fvMesh& mesh = this->mesh();
+
+ const surfaceVectorField Sn(mesh.Sf()/mesh.magSf());
+ const surfaceVectorField SfGamma(mesh.Sf() & gamma);
+ const GeometricField SfGammaSn
+ (
+ SfGamma & Sn
+ );
+ const surfaceVectorField SfGammaCorr(SfGamma - SfGammaSn*Sn);
+
+ tmp> tLaplacian
+ (
+ fvc::div
+ (
+ SfGammaSn*this->tsnGradScheme_().snGrad(vf)
+ + gammaSnGradCorr(SfGammaCorr, vf)
+ )
+ );
+
+ tLaplacian.ref().rename
+ (
+ "laplacian(" + gamma.name() + ',' + vf.name() + ')'
+ );
+
+ return tLaplacian;
+}
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace fv
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace Foam
+
+// ************************************************************************* //
diff --git a/src/finiteVolume/finiteVolume/laplacianSchemes/relaxedNonOrthoGaussLaplacianScheme/relaxedNonOrthoGaussLaplacianScheme.H b/src/finiteVolume/finiteVolume/laplacianSchemes/relaxedNonOrthoGaussLaplacianScheme/relaxedNonOrthoGaussLaplacianScheme.H
new file mode 100644
index 0000000000..ff4a7f6c67
--- /dev/null
+++ b/src/finiteVolume/finiteVolume/laplacianSchemes/relaxedNonOrthoGaussLaplacianScheme/relaxedNonOrthoGaussLaplacianScheme.H
@@ -0,0 +1,210 @@
+/*---------------------------------------------------------------------------*\
+ ========= |
+ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
+ \\ / O peration |
+ \\ / A nd | www.openfoam.com
+ \\/ M anipulation |
+-------------------------------------------------------------------------------
+ Copyright (C) 2019 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 .
+
+Class
+ Foam::fv::relaxedNonOrthoGaussLaplacianScheme
+
+Description
+ Basic second-order laplacian using face-gradients and Gauss' theorem.
+
+Usage
+ Minimal example by using \c system/fvSchemes:
+ \verbatim
+ laplacianSchemes
+ {
+ laplacian() relaxedNonOrthoGauss ;
+ }
+ \endverbatim
+
+ and by using \c system/fvSolution:
+ \verbatim
+ relaxationFactors
+ {
+ equations
+ {
+ ;
+ }
+ }
+ \endverbatim
+
+SourceFiles
+ relaxedNonOrthoGaussLaplacianScheme.C
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef relaxedNonOrthoGaussLaplacianScheme_H
+#define relaxedNonOrthoGaussLaplacianScheme_H
+
+#include "laplacianScheme.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace fv
+{
+
+/*---------------------------------------------------------------------------*\
+ Class relaxedNonOrthoGaussLaplacianScheme Declaration
+\*---------------------------------------------------------------------------*/
+
+template
+class relaxedNonOrthoGaussLaplacianScheme
+:
+ public fv::laplacianScheme
+{
+ // Private Member Functions
+
+ tmp> gammaSnGradCorr
+ (
+ const surfaceVectorField& SfGammaCorr,
+ const GeometricField&
+ );
+
+ //- No copy construct
+ relaxedNonOrthoGaussLaplacianScheme
+ (
+ const relaxedNonOrthoGaussLaplacianScheme&
+ ) = delete;
+
+ //- No copy assignment
+ void operator=(const relaxedNonOrthoGaussLaplacianScheme&) = delete;
+
+
+public:
+
+ //- Runtime type information
+ TypeName("relaxedNonOrthoGauss");
+
+
+ // Constructors
+
+ //- Construct null
+ relaxedNonOrthoGaussLaplacianScheme(const fvMesh& mesh)
+ :
+ laplacianScheme(mesh)
+ {}
+
+ //- Construct from Istream
+ relaxedNonOrthoGaussLaplacianScheme(const fvMesh& mesh, Istream& is)
+ :
+ laplacianScheme(mesh, is)
+ {}
+
+ //- Construct from mesh, interpolation and snGradScheme schemes
+ relaxedNonOrthoGaussLaplacianScheme
+ (
+ const fvMesh& mesh,
+ const tmp>& igs,
+ const tmp>& sngs
+ )
+ :
+ laplacianScheme(mesh, igs, sngs)
+ {}
+
+
+ //- Destructor
+ virtual ~relaxedNonOrthoGaussLaplacianScheme() = default;
+
+
+ // Member Functions
+
+ static tmp> fvmLaplacianUncorrected
+ (
+ const surfaceScalarField& gammaMagSf,
+ const surfaceScalarField& deltaCoeffs,
+ const GeometricField&
+ );
+
+ tmp> fvcLaplacian
+ (
+ const GeometricField&
+ );
+
+ tmp> fvmLaplacian
+ (
+ const GeometricField&,
+ const GeometricField&
+ );
+
+ tmp> fvcLaplacian
+ (
+ const GeometricField&,
+ const GeometricField&
+ );
+};
+
+
+// Use macros to emulate partial-specialisation of the Laplacian functions
+// for scalar diffusivity gamma
+
+#define defineFvmLaplacianScalarGamma(Type) \
+ \
+template<> \
+tmp> \
+relaxedNonOrthoGaussLaplacianScheme::fvmLaplacian \
+( \
+ const GeometricField&, \
+ const GeometricField& \
+); \
+ \
+template<> \
+tmp> \
+relaxedNonOrthoGaussLaplacianScheme::fvcLaplacian \
+( \
+ const GeometricField&, \
+ const GeometricField& \
+);
+
+
+defineFvmLaplacianScalarGamma(scalar);
+defineFvmLaplacianScalarGamma(vector);
+defineFvmLaplacianScalarGamma(sphericalTensor);
+defineFvmLaplacianScalarGamma(symmTensor);
+defineFvmLaplacianScalarGamma(tensor);
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace fv
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#ifdef NoRepository
+ #include "relaxedNonOrthoGaussLaplacianScheme.C"
+#endif
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/finiteVolume/finiteVolume/laplacianSchemes/relaxedNonOrthoGaussLaplacianScheme/relaxedNonOrthoGaussLaplacianSchemes.C b/src/finiteVolume/finiteVolume/laplacianSchemes/relaxedNonOrthoGaussLaplacianScheme/relaxedNonOrthoGaussLaplacianSchemes.C
new file mode 100644
index 0000000000..7aa0027ec9
--- /dev/null
+++ b/src/finiteVolume/finiteVolume/laplacianSchemes/relaxedNonOrthoGaussLaplacianScheme/relaxedNonOrthoGaussLaplacianSchemes.C
@@ -0,0 +1,140 @@
+/*---------------------------------------------------------------------------*\
+ ========= |
+ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
+ \\ / O peration |
+ \\ / A nd | www.openfoam.com
+ \\/ M anipulation |
+-------------------------------------------------------------------------------
+ Copyright (C) 2019 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 .
+
+\*---------------------------------------------------------------------------*/
+
+#include "relaxedNonOrthoGaussLaplacianScheme.H"
+#include "fvMesh.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+makeFvLaplacianScheme(relaxedNonOrthoGaussLaplacianScheme)
+
+#define declareFvmLaplacianScalarGamma(Type) \
+ \
+template<> \
+Foam::tmp> \
+Foam::fv::relaxedNonOrthoGaussLaplacianScheme:: \
+fvmLaplacian \
+( \
+ const GeometricField& gamma, \
+ const GeometricField& vf \
+) \
+{ \
+ const fvMesh& mesh = this->mesh(); \
+ \
+ typedef GeometricField SType; \
+ \
+ GeometricField gammaMagSf \
+ ( \
+ gamma*mesh.magSf() \
+ ); \
+ \
+ tmp> tfvm = fvmLaplacianUncorrected \
+ ( \
+ gammaMagSf, \
+ this->tsnGradScheme_().deltaCoeffs(vf), \
+ vf \
+ ); \
+ fvMatrix& fvm = tfvm.ref(); \
+ \
+ if (this->tsnGradScheme_().corrected()) \
+ { \
+ tmp tCorr(this->tsnGradScheme_().correction(vf)); \
+ const word corrName(tCorr().name()); \
+ tmp tfaceFluxCorrection(gammaMagSf*tCorr); \
+ \
+ tmp trelaxedCorrection(new SType(tfaceFluxCorrection())); \
+ \
+ const word oldName(corrName + "_0"); \
+ const scalar relax(vf.mesh().equationRelaxationFactor(corrName)); \
+ const objectRegistry& obr = vf.db(); \
+ if (obr.foundObject(oldName)) \
+ { \
+ SType& oldCorrection = obr.lookupObjectRef(oldName); \
+ trelaxedCorrection.ref() *= relax; \
+ trelaxedCorrection.ref() += (1.0-relax)*oldCorrection; \
+ \
+ oldCorrection = trelaxedCorrection(); \
+ } \
+ else \
+ { \
+ SType* s = new SType(oldName, tfaceFluxCorrection); \
+ s->store(); \
+ } \
+ \
+ tmp> tcorr \
+ ( \
+ mesh.V() \
+ *fvc::div \
+ ( \
+ trelaxedCorrection() \
+ )().primitiveField() \
+ ); \
+ \
+ fvm.source() -= tcorr(); \
+ \
+ if (mesh.fluxRequired(vf.name())) \
+ { \
+ fvm.faceFluxCorrectionPtr() = trelaxedCorrection.ptr(); \
+ } \
+ } \
+ \
+ return tfvm; \
+} \
+ \
+ \
+template<> \
+Foam::tmp> \
+Foam::fv::relaxedNonOrthoGaussLaplacianScheme::fvcLaplacian \
+( \
+ const GeometricField& gamma, \
+ const GeometricField& vf \
+) \
+{ \
+ const fvMesh& mesh = this->mesh(); \
+ \
+ tmp> tLaplacian \
+ ( \
+ fvc::div(gamma*this->tsnGradScheme_().snGrad(vf)*mesh.magSf()) \
+ ); \
+ \
+ tLaplacian.ref().rename \
+ ( \
+ "laplacian(" + gamma.name() + ',' + vf.name() + ')' \
+ ); \
+ \
+ return tLaplacian; \
+}
+
+
+declareFvmLaplacianScalarGamma(scalar);
+declareFvmLaplacianScalarGamma(vector);
+declareFvmLaplacianScalarGamma(sphericalTensor);
+declareFvmLaplacianScalarGamma(symmTensor);
+declareFvmLaplacianScalarGamma(tensor);
+
+
+// ************************************************************************* //