diff --git a/src/Allwmake b/src/Allwmake
index 3d2e2ac222..3700e0b7e0 100755
--- a/src/Allwmake
+++ b/src/Allwmake
@@ -55,6 +55,7 @@ wmake $targetType meshTools
wmake $targetType finiteArea
wmake $targetType finiteVolume
+wmake $targetType fused/finiteVolume
wmake $targetType mesh/blockMesh
wmake $targetType mesh/extrudeModel # Requires: blockMesh
diff --git a/src/fused/finiteVolume/Make/files b/src/fused/finiteVolume/Make/files
new file mode 100644
index 0000000000..fde0488e45
--- /dev/null
+++ b/src/fused/finiteVolume/Make/files
@@ -0,0 +1,7 @@
+fusedGaussLaplacianSchemes.C
+fusedLeastSquaresGrads.C
+fusedGaussDivSchemes.C
+fusedGaussConvectionSchemes.C
+fusedGaussGrads.C
+
+LIB = $(FOAM_LIBBIN)/libfusedFiniteVolume
diff --git a/src/fused/finiteVolume/Make/options b/src/fused/finiteVolume/Make/options
new file mode 100644
index 0000000000..f6fbc14a76
--- /dev/null
+++ b/src/fused/finiteVolume/Make/options
@@ -0,0 +1,7 @@
+EXE_INC = \
+ -I$(LIB_SRC)/finiteVolume/lnInclude \
+ -I$(LIB_SRC)/meshTools/lnInclude \
+ -I$(LIB_SRC)/sampling/lnInclude
+
+LIB_LIBS = \
+ -lfiniteVolume
diff --git a/src/fused/finiteVolume/fusedGaussConvectionScheme.C b/src/fused/finiteVolume/fusedGaussConvectionScheme.C
new file mode 100644
index 0000000000..fb73500875
--- /dev/null
+++ b/src/fused/finiteVolume/fusedGaussConvectionScheme.C
@@ -0,0 +1,265 @@
+/*---------------------------------------------------------------------------*\
+ ========= |
+ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
+ \\ / O peration |
+ \\ / A nd | www.openfoam.com
+ \\/ M anipulation |
+-------------------------------------------------------------------------------
+ Copyright (C) 2011-2016 OpenFOAM Foundation
+ Copyright (C) 2024 M. Janssens
+-------------------------------------------------------------------------------
+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 "fvcSurfaceOps.H"
+#include "fusedGaussConvectionScheme.H"
+#include "fvcSurfaceIntegrate.H"
+#include "fvMatrices.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace fv
+{
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+template
+const surfaceInterpolationScheme&
+fusedGaussConvectionScheme::interpScheme() const
+{
+ return tinterpScheme_();
+}
+
+
+template
+tmp>
+fusedGaussConvectionScheme::interpolate
+(
+ const surfaceScalarField&,
+ const GeometricField& vf
+) const
+{
+ return tinterpScheme_().interpolate(vf);
+}
+
+
+template
+tmp>
+fusedGaussConvectionScheme::flux
+(
+ const surfaceScalarField& faceFlux,
+ const GeometricField& vf
+) const
+{
+ return faceFlux*interpolate(faceFlux, vf);
+}
+
+
+template
+tmp>
+fusedGaussConvectionScheme::fvmDiv
+(
+ const surfaceScalarField& faceFlux,
+ const GeometricField& vf
+) const
+{
+ DebugPout<< "fusedGaussConvectionScheme::fvmDiv on " << vf.name()
+ << " with flux " << faceFlux.name() << endl;
+
+ tmp tweights = tinterpScheme_().weights(vf);
+ const surfaceScalarField& weights = tweights();
+
+ tmp> tfvm
+ (
+ new fvMatrix
+ (
+ vf,
+ faceFlux.dimensions()*vf.dimensions()
+ )
+ );
+ fvMatrix& fvm = tfvm.ref();
+
+ //fvm.lower() = -weights.primitiveField()*faceFlux.primitiveField();
+ multiplySubtract
+ (
+ fvm.lower(),
+ weights.primitiveField(),
+ faceFlux.primitiveField()
+ );
+
+ //fvm.upper() = fvm.lower() + faceFlux.primitiveField();
+ add(fvm.upper(), fvm.lower(), faceFlux.primitiveField());
+
+ fvm.negSumDiag();
+
+ forAll(vf.boundaryField(), patchi)
+ {
+ const fvPatchField& psf = vf.boundaryField()[patchi];
+ const fvsPatchScalarField& patchFlux = faceFlux.boundaryField()[patchi];
+ const fvsPatchScalarField& pw = weights.boundaryField()[patchi];
+
+ auto& intCoeffs = fvm.internalCoeffs()[patchi];
+ auto& bouCoeffs = fvm.boundaryCoeffs()[patchi];
+
+ //fvm.internalCoeffs()[patchi] = patchFlux*psf.valueInternalCoeffs(pw);
+ multiply(intCoeffs, patchFlux, psf.valueInternalCoeffs(pw)());
+
+ //fvm.boundaryCoeffs()[patchi] = -patchFlux*psf.valueBoundaryCoeffs(pw);
+ multiply(bouCoeffs, patchFlux, psf.valueBoundaryCoeffs(pw)());
+ bouCoeffs.negate();
+ }
+
+ if (tinterpScheme_().corrected())
+ {
+ fvm += fvc::surfaceIntegrate(faceFlux*tinterpScheme_().correction(vf));
+ }
+
+ return tfvm;
+}
+
+
+template
+tmp>
+fusedGaussConvectionScheme::fvcDiv
+(
+ const surfaceScalarField& faceFlux,
+ const GeometricField& vf
+) const
+{
+ DebugPout<< "fusedGaussConvectionScheme::fvcDiv on " << vf.name()
+ << " with flux " << faceFlux.name() << endl;
+
+ typedef GeometricField FieldType;
+
+ const fvMesh& mesh = vf.mesh();
+
+ tmp tConvection
+ (
+ new FieldType
+ (
+ IOobject
+ (
+ "convection(" + faceFlux.name() + ',' + vf.name() + ')',
+ vf.instance(),
+ mesh,
+ IOobject::NO_READ,
+ IOobject::NO_WRITE
+ ),
+ mesh,
+ dimensioned
+ (
+ faceFlux.dimensions()
+ *vf.dimensions()
+ /dimVol,
+ Zero
+ ),
+ fvPatchFieldBase::extrapolatedCalculatedType()
+ )
+ );
+
+ if (this->tinterpScheme_().corrected())
+ {
+ const auto tfaceCorr(this->tinterpScheme_().correction(vf));
+ auto& faceCorr = tfaceCorr();
+
+ const auto interpolator = [&]
+ (
+ const vector& area,
+ const scalar lambda,
+
+ const Type& ownVal,
+ const Type& neiVal,
+
+ const scalar& faceVal,
+ const Type& correction
+
+ ) -> Type
+ {
+ return faceVal*((lambda*(ownVal - neiVal) + neiVal) + correction);
+ };
+
+ fvc::surfaceSum
+ (
+ // interpolation factors for volume field
+ this->tinterpScheme_().weights(vf),
+
+ // volume field(s)
+ vf,
+
+ // surface field(s)
+ faceFlux,
+ faceCorr,
+
+ // operation
+ interpolator,
+
+ tConvection.ref(),
+ false
+ );
+ }
+ else
+ {
+ const auto interpolator = [&]
+ (
+ const vector& area,
+ const scalar lambda,
+ const Type& ownVal,
+ const Type& neiVal,
+
+ const scalar& faceVal
+ ) -> Type
+ {
+ return faceVal*(lambda*(ownVal - neiVal) + neiVal);
+ };
+
+ fvc::surfaceSum
+ (
+ tinterpScheme_().weights(vf),
+
+ vf,
+
+ faceFlux,
+
+ interpolator,
+ tConvection.ref(),
+ false
+ );
+ }
+
+ tConvection.ref().primitiveFieldRef() /= mesh.Vsc();
+
+ tConvection.ref().correctBoundaryConditions();
+
+ return tConvection;
+}
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace fv
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace Foam
+
+// ************************************************************************* //
diff --git a/src/fused/finiteVolume/fusedGaussConvectionScheme.H b/src/fused/finiteVolume/fusedGaussConvectionScheme.H
new file mode 100644
index 0000000000..677a9df827
--- /dev/null
+++ b/src/fused/finiteVolume/fusedGaussConvectionScheme.H
@@ -0,0 +1,162 @@
+/*---------------------------------------------------------------------------*\
+ ========= |
+ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
+ \\ / O peration |
+ \\ / A nd | www.openfoam.com
+ \\/ M anipulation |
+-------------------------------------------------------------------------------
+ Copyright (C) 2011-2016 OpenFOAM Foundation
+-------------------------------------------------------------------------------
+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::fusedGaussConvectionScheme
+
+Group
+ grpFvConvectionSchemes
+
+Description
+ Basic second-order convection using face-gradients and Gauss' theorem.
+
+SourceFiles
+ fusedGaussConvectionScheme.C
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef fusedGaussConvectionScheme_H
+#define fusedGaussConvectionScheme_H
+
+#include "convectionScheme.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace fv
+{
+
+/*---------------------------------------------------------------------------*\
+ Class fusedGaussConvectionScheme Declaration
+\*---------------------------------------------------------------------------*/
+
+template
+class fusedGaussConvectionScheme
+:
+ public fv::convectionScheme
+{
+ // Private data
+
+ tmp> tinterpScheme_;
+
+
+ // Private Member Functions
+
+ //- No copy construct
+ fusedGaussConvectionScheme(const fusedGaussConvectionScheme&) = delete;
+
+ //- No copy assignment
+ void operator=(const fusedGaussConvectionScheme&) = delete;
+
+
+public:
+
+ //- Runtime type information
+ TypeName("fusedGauss");
+
+
+ // Constructors
+
+ //- Construct from flux and interpolation scheme
+ fusedGaussConvectionScheme
+ (
+ const fvMesh& mesh,
+ const surfaceScalarField& faceFlux,
+ const tmp>& scheme
+ )
+ :
+ convectionScheme(mesh, faceFlux),
+ tinterpScheme_(scheme)
+ {}
+
+ //- Construct from flux and Istream
+ fusedGaussConvectionScheme
+ (
+ const fvMesh& mesh,
+ const surfaceScalarField& faceFlux,
+ Istream& is
+ )
+ :
+ convectionScheme(mesh, faceFlux),
+ tinterpScheme_
+ (
+ surfaceInterpolationScheme::New(mesh, faceFlux, is)
+ )
+ {}
+
+
+ // Member Functions
+
+ const surfaceInterpolationScheme& interpScheme() const;
+
+ tmp> interpolate
+ (
+ const surfaceScalarField&,
+ const GeometricField&
+ ) const;
+
+ tmp> flux
+ (
+ const surfaceScalarField&,
+ const GeometricField&
+ ) const;
+
+ tmp> fvmDiv
+ (
+ const surfaceScalarField&,
+ const GeometricField&
+ ) const;
+
+ tmp> fvcDiv
+ (
+ const surfaceScalarField&,
+ const GeometricField&
+ ) const;
+};
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace fv
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#ifdef NoRepository
+ #include "fusedGaussConvectionScheme.C"
+#endif
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/fused/finiteVolume/fusedGaussConvectionSchemes.C b/src/fused/finiteVolume/fusedGaussConvectionSchemes.C
new file mode 100644
index 0000000000..950406e278
--- /dev/null
+++ b/src/fused/finiteVolume/fusedGaussConvectionSchemes.C
@@ -0,0 +1,35 @@
+/*---------------------------------------------------------------------------*\
+ ========= |
+ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
+ \\ / O peration |
+ \\ / A nd | www.openfoam.com
+ \\/ M anipulation |
+-------------------------------------------------------------------------------
+ Copyright (C) 2011-2016 OpenFOAM Foundation
+-------------------------------------------------------------------------------
+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 "fusedGaussConvectionScheme.H"
+#include "fvMesh.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+makeFvConvectionScheme(fusedGaussConvectionScheme)
+
+// ************************************************************************* //
diff --git a/src/fused/finiteVolume/fusedGaussDivScheme.C b/src/fused/finiteVolume/fusedGaussDivScheme.C
new file mode 100644
index 0000000000..ffb51ac7c1
--- /dev/null
+++ b/src/fused/finiteVolume/fusedGaussDivScheme.C
@@ -0,0 +1,155 @@
+/*---------------------------------------------------------------------------*\
+ ========= |
+ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
+ \\ / O peration |
+ \\ / A nd | www.openfoam.com
+ \\/ M anipulation |
+-------------------------------------------------------------------------------
+ Copyright (C) 2011-2016 OpenFOAM Foundation
+ Copyright (C) 2024 M. Janssens
+-------------------------------------------------------------------------------
+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 "fvcSurfaceOps.H"
+#include "fusedGaussDivScheme.H"
+#include "fvcSurfaceIntegrate.H"
+#include "fvMatrices.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace fv
+{
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+template
+tmp
+<
+ GeometricField
+ ::type, fvPatchField, volMesh>
+>
+fusedGaussDivScheme::fvcDiv
+(
+ const GeometricField& vf
+)
+{
+ typedef typename innerProduct::type DivType;
+ typedef GeometricField DivFieldType;
+
+ const fvMesh& mesh = vf.mesh();
+
+ DebugPout<< "fusedGaussDivScheme::fvcDiv on " << vf.name()
+ << endl;
+
+ tmp tDiv
+ (
+ new DivFieldType
+ (
+ IOobject
+ (
+ "div(" + vf.name() + ')',
+ vf.instance(),
+ mesh,
+ IOobject::NO_READ,
+ IOobject::NO_WRITE
+ ),
+ mesh,
+ dimensioned(vf.dimensions()/dimLength, Zero),
+ fvPatchFieldBase::extrapolatedCalculatedType()
+ )
+ );
+ DivFieldType& div = tDiv.ref();
+
+ //fvcDiv(vf, this->tinterpScheme_().weights(vf), div);
+
+ if (this->tinterpScheme_().corrected())
+ {
+ const auto tfaceCorr(this->tinterpScheme_().correction(vf));
+ auto& faceCorr = tfaceCorr();
+
+ const auto dotInterpolate = [&]
+ (
+ const vector& area,
+ const scalar lambda,
+
+ const Type& ownVal,
+ const Type& neiVal,
+
+ const Type& correction
+
+ ) -> DivType
+ {
+ return area & ((lambda*(ownVal - neiVal) + neiVal) + correction);
+ };
+
+ fvc::surfaceSum
+ (
+ this->tinterpScheme_().weights(vf),
+ vf,
+ faceCorr,
+ dotInterpolate,
+ div,
+ false
+ );
+ }
+ else
+ {
+ const auto dotInterpolate = [&]
+ (
+ const vector& area,
+ const scalar lambda,
+ const Type& ownVal,
+ const Type& neiVal
+ ) -> DivType
+ {
+ return area & (lambda*(ownVal - neiVal) + neiVal);
+ };
+
+ fvc::surfaceSum
+ (
+ this->tinterpScheme_().weights(vf),
+ vf,
+ dotInterpolate,
+ div,
+ false
+ );
+ }
+
+ tDiv.ref().primitiveFieldRef() /= mesh.V();
+
+ tDiv.ref().correctBoundaryConditions();
+
+ return tDiv;
+}
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace fv
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace Foam
+
+// ************************************************************************* //
diff --git a/src/fused/finiteVolume/fusedGaussDivScheme.H b/src/fused/finiteVolume/fusedGaussDivScheme.H
new file mode 100644
index 0000000000..1a02ebadfa
--- /dev/null
+++ b/src/fused/finiteVolume/fusedGaussDivScheme.H
@@ -0,0 +1,125 @@
+/*---------------------------------------------------------------------------*\
+ ========= |
+ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
+ \\ / O peration |
+ \\ / A nd | www.openfoam.com
+ \\/ M anipulation |
+-------------------------------------------------------------------------------
+ Copyright (C) 2011-2016 OpenFOAM Foundation
+-------------------------------------------------------------------------------
+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::fusedGaussDivScheme
+
+Group
+ grpFvDivSchemes
+
+Description
+ Variant of gaussDiv that avoids intermediates
+
+SourceFiles
+ fusedGaussDivScheme.C
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef fusedGaussDivScheme_H
+#define fusedGaussDivScheme_H
+
+#include "divScheme.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace fv
+{
+
+/*---------------------------------------------------------------------------*\
+ Class fusedGaussDivScheme Declaration
+\*---------------------------------------------------------------------------*/
+
+template
+class fusedGaussDivScheme
+:
+ public fv::divScheme
+{
+ // Private Member Functions
+
+ //- No copy construct
+ fusedGaussDivScheme(const fusedGaussDivScheme&) = delete;
+
+ //- No copy assignment
+ void operator=(const fusedGaussDivScheme&) = delete;
+
+
+public:
+
+ //- Runtime type information
+ TypeName("fusedGauss");
+
+
+ // Constructors
+
+ //- Construct null
+ fusedGaussDivScheme(const fvMesh& mesh)
+ :
+ divScheme(mesh)
+ {}
+
+ //- Construct from Istream
+ fusedGaussDivScheme(const fvMesh& mesh, Istream& is)
+ :
+ divScheme(mesh, is)
+ {}
+
+
+ // Member Functions
+
+ tmp
+ <
+ GeometricField
+ ::type, fvPatchField, volMesh>
+ > fvcDiv
+ (
+ const GeometricField&
+ );
+};
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace fv
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#ifdef NoRepository
+ #include "fusedGaussDivScheme.C"
+#endif
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/fused/finiteVolume/fusedGaussDivSchemes.C b/src/fused/finiteVolume/fusedGaussDivSchemes.C
new file mode 100644
index 0000000000..2def82689a
--- /dev/null
+++ b/src/fused/finiteVolume/fusedGaussDivSchemes.C
@@ -0,0 +1,35 @@
+/*---------------------------------------------------------------------------*\
+ ========= |
+ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
+ \\ / O peration |
+ \\ / A nd | www.openfoam.com
+ \\/ M anipulation |
+-------------------------------------------------------------------------------
+ Copyright (C) 2011-2015 OpenFOAM Foundation
+-------------------------------------------------------------------------------
+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 "fusedGaussDivScheme.H"
+#include "fvMesh.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+makeFvDivScheme(fusedGaussDivScheme)
+
+// ************************************************************************* //
diff --git a/src/fused/finiteVolume/fusedGaussGrad.C b/src/fused/finiteVolume/fusedGaussGrad.C
new file mode 100644
index 0000000000..5954e5804c
--- /dev/null
+++ b/src/fused/finiteVolume/fusedGaussGrad.C
@@ -0,0 +1,263 @@
+/*---------------------------------------------------------------------------*\
+ ========= |
+ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
+ \\ / O peration |
+ \\ / A nd | www.openfoam.com
+ \\/ M anipulation |
+-------------------------------------------------------------------------------
+ Copyright (C) 2011-2016 OpenFOAM Foundation
+ Copyright (C) 2018-2021 OpenCFD Ltd.
+ Copyright (C) 2024 M. Janssens
+-------------------------------------------------------------------------------
+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 "fusedGaussGrad.H"
+#include "extrapolatedCalculatedFvPatchField.H"
+#include "fvcSurfaceOps.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+template
+Foam::tmp
+<
+ Foam::GeometricField
+ <
+ typename Foam::outerProduct::type,
+ Foam::fvPatchField,
+ Foam::volMesh
+ >
+>
+Foam::fv::fusedGaussGrad::gradf
+(
+ const GeometricField& ssf,
+ const word& name
+)
+{
+ typedef typename outerProduct::type GradType;
+ typedef GeometricField GradFieldType;
+
+ const fvMesh& mesh = ssf.mesh();
+
+ DebugPout<< "fusedGaussGrad::gradf on " << ssf.name()
+ << " with name " << name << endl;
+
+ tmp tgGrad
+ (
+ new GradFieldType
+ (
+ IOobject
+ (
+ name,
+ ssf.instance(),
+ mesh,
+ IOobject::NO_READ,
+ IOobject::NO_WRITE
+ ),
+ mesh,
+ dimensioned(ssf.dimensions()/dimLength, Zero),
+ fvPatchFieldBase::extrapolatedCalculatedType()
+ )
+ );
+ GradFieldType& gGrad = tgGrad.ref();
+
+ const labelUList& owner = mesh.owner();
+ const labelUList& neighbour = mesh.neighbour();
+ const vectorField& Sf = mesh.Sf();
+
+ Field& igGrad = gGrad;
+ const Field& issf = ssf;
+
+ forAll(owner, facei)
+ {
+ const GradType Sfssf = Sf[facei]*issf[facei];
+
+ igGrad[owner[facei]] += Sfssf;
+ igGrad[neighbour[facei]] -= Sfssf;
+ }
+
+ forAll(mesh.boundary(), patchi)
+ {
+ const labelUList& pFaceCells =
+ mesh.boundary()[patchi].faceCells();
+
+ const vectorField& pSf = mesh.Sf().boundaryField()[patchi];
+
+ const fvsPatchField& pssf = ssf.boundaryField()[patchi];
+
+ forAll(mesh.boundary()[patchi], facei)
+ {
+ igGrad[pFaceCells[facei]] += pSf[facei]*pssf[facei];
+ }
+ }
+
+ igGrad /= mesh.V();
+
+ gGrad.correctBoundaryConditions();
+
+ return tgGrad;
+}
+
+
+template
+Foam::tmp
+<
+ Foam::GeometricField
+ <
+ typename Foam::outerProduct::type,
+ Foam::fvPatchField,
+ Foam::volMesh
+ >
+>
+Foam::fv::fusedGaussGrad::calcGrad
+(
+ const GeometricField& vf,
+ const word& name
+) const
+{
+ typedef typename outerProduct::type GradType;
+ typedef GeometricField GradFieldType;
+
+ const fvMesh& mesh = vf.mesh();
+
+ DebugPout<< "fusedGaussGrad::calcGrad on " << vf.name()
+ << " with name " << name << endl;
+
+ tmp tgGrad
+ (
+ new GradFieldType
+ (
+ IOobject
+ (
+ name,
+ vf.instance(),
+ mesh,
+ IOobject::NO_READ,
+ IOobject::NO_WRITE
+ ),
+ mesh,
+ dimensioned(vf.dimensions()/dimLength, Zero),
+ fvPatchFieldBase::extrapolatedCalculatedType()
+ )
+ );
+ GradFieldType& gGrad = tgGrad.ref();
+
+ if (this->tinterpScheme_().corrected())
+ {
+ const auto tfaceCorr(this->tinterpScheme_().correction(vf));
+ auto& faceCorr = tfaceCorr();
+
+ DebugPout<< "fusedGaussGrad::calcGrad corrected interpScheme "
+ << this->tinterpScheme_().type() << endl;
+
+ const auto interpolate = [&]
+ (
+ const vector& area,
+ const scalar lambda,
+
+ const Type& ownVal,
+ const Type& neiVal,
+
+ const Type& correction
+
+ ) -> GradType
+ {
+ return area*((lambda*(ownVal - neiVal) + neiVal) + correction);
+ };
+
+ fvc::surfaceSum
+ (
+ this->tinterpScheme_().weights(vf),
+ vf,
+ faceCorr,
+ interpolate,
+ gGrad,
+ false
+ );
+ }
+ else
+ {
+ DebugPout<< "fusedGaussGrad::calcGrad uncorrected interpScheme "
+ << this->tinterpScheme_().type() << endl;
+
+ const auto interpolate = [&]
+ (
+ const vector& area,
+ const scalar lambda,
+ const Type& ownVal,
+ const Type& neiVal
+ ) -> GradType
+ {
+ return area*(lambda*(ownVal - neiVal) + neiVal);
+ };
+
+ fvc::surfaceSum
+ (
+ tinterpScheme_().weights(vf),
+ vf,
+ interpolate,
+ gGrad,
+ false
+ );
+ }
+
+ gGrad.primitiveFieldRef() /= mesh.V();
+
+ gGrad.correctBoundaryConditions();
+
+ correctBoundaryConditions(vf, gGrad);
+
+ return tgGrad;
+}
+
+
+template
+template
+void Foam::fv::fusedGaussGrad::correctBoundaryConditions
+(
+ const GeometricField& vf,
+ GeometricField& gGrad
+)
+{
+ DebugPout<< "fusedGaussGrad::correctBoundaryConditions on "
+ << vf.name() << " with gGrad " << gGrad.name() << endl;
+
+ const fvMesh& mesh = vf.mesh();
+ auto& gGradbf = gGrad.boundaryFieldRef();
+
+ forAll(vf.boundaryField(), patchi)
+ {
+ if (!vf.boundaryField()[patchi].coupled())
+ {
+ const auto& pSf = mesh.Sf().boundaryField()[patchi];
+ const auto tsnGrad(vf.boundaryField()[patchi].snGrad());
+ const auto& snGrad = tsnGrad();
+ auto& pgrad = gGradbf[patchi];
+
+ forAll(pgrad, facei)
+ {
+ const vector n(pSf[facei]/mag(pSf[facei]));
+ const Type uncorrectSnGrad(n & pgrad[facei]);
+ pgrad[facei] += n*(snGrad[facei] - uncorrectSnGrad);
+ }
+ }
+ }
+}
+
+
+// ************************************************************************* //
diff --git a/src/fused/finiteVolume/fusedGaussGrad.H b/src/fused/finiteVolume/fusedGaussGrad.H
new file mode 100644
index 0000000000..233ecdc577
--- /dev/null
+++ b/src/fused/finiteVolume/fusedGaussGrad.H
@@ -0,0 +1,177 @@
+/*---------------------------------------------------------------------------*\
+ ========= |
+ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
+ \\ / O peration |
+ \\ / A nd | www.openfoam.com
+ \\/ M anipulation |
+-------------------------------------------------------------------------------
+ Copyright (C) 2011-2016 OpenFOAM Foundation
+ Copyright (C) 2018-2021 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::fusedGaussGrad
+
+Group
+ grpFvGradSchemes
+
+Description
+ Basic second-order gradient scheme using face-interpolation
+ and Gauss' theorem.
+
+SourceFiles
+ fusedGaussGrad.C
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef Foam_fusedGaussGrad_H
+#define Foam_fusedGaussGrad_H
+
+#include "gradScheme.H"
+#include "surfaceInterpolationScheme.H"
+#include "linear.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace fv
+{
+
+/*---------------------------------------------------------------------------*\
+ Class fusedGaussGrad Declaration
+\*---------------------------------------------------------------------------*/
+
+template
+class fusedGaussGrad
+:
+ public fv::gradScheme
+{
+ // Private Data
+
+ //- Interpolation scheme
+ tmp> tinterpScheme_;
+
+
+ // Private Member Functions
+
+ //- No copy construct
+ fusedGaussGrad(const fusedGaussGrad&) = delete;
+
+ //- No copy assignment
+ void operator=(const fusedGaussGrad&) = delete;
+
+
+public:
+
+ //- Runtime type information
+ TypeName("fusedGauss");
+
+
+ // Constructors
+
+ //- Construct from mesh
+ fusedGaussGrad(const fvMesh& mesh)
+ :
+ gradScheme(mesh),
+ tinterpScheme_(new linear(mesh))
+ {}
+
+ //- Construct from mesh and Istream
+ fusedGaussGrad(const fvMesh& mesh, Istream& is)
+ :
+ gradScheme(mesh),
+ tinterpScheme_(nullptr)
+ {
+ if (is.eof())
+ {
+ tinterpScheme_.reset
+ (
+ new linear(mesh)
+ );
+ }
+ else
+ {
+ tinterpScheme_.reset
+ (
+ surfaceInterpolationScheme::New(mesh, is)
+ );
+ }
+ }
+
+
+ // Member Functions
+
+ //- Return the gradient of the given field
+ //- calculated using Gauss' theorem on the given surface field
+ static
+ tmp
+ <
+ GeometricField
+ ::type, fvPatchField, volMesh>
+ > gradf
+ (
+ const GeometricField&,
+ const word& name
+ );
+
+ //- Return the gradient of the given field to the gradScheme::grad
+ //- for optional caching
+ virtual tmp
+ <
+ GeometricField
+ ::type, fvPatchField, volMesh>
+ > calcGrad
+ (
+ const GeometricField& vsf,
+ const word& name
+ ) const;
+
+ //- Correct the boundary values of the gradient using the patchField
+ //- snGrad functions
+ template
+ static void correctBoundaryConditions
+ (
+ const GeometricField&,
+ GeometricField&
+ );
+};
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace fv
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#ifdef NoRepository
+ #include "fusedGaussGrad.C"
+#endif
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/fused/finiteVolume/fusedGaussGrads.C b/src/fused/finiteVolume/fusedGaussGrads.C
new file mode 100644
index 0000000000..86a85a8bee
--- /dev/null
+++ b/src/fused/finiteVolume/fusedGaussGrads.C
@@ -0,0 +1,35 @@
+/*---------------------------------------------------------------------------*\
+ ========= |
+ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
+ \\ / O peration |
+ \\ / A nd | www.openfoam.com
+ \\/ M anipulation |
+-------------------------------------------------------------------------------
+ Copyright (C) 2011-2015 OpenFOAM Foundation
+-------------------------------------------------------------------------------
+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 "fvMesh.H"
+#include "fusedGaussGrad.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+makeFvGradScheme(fusedGaussGrad)
+
+// ************************************************************************* //
diff --git a/src/fused/finiteVolume/fusedGaussLaplacianScheme.C b/src/fused/finiteVolume/fusedGaussLaplacianScheme.C
new file mode 100644
index 0000000000..00553d55d9
--- /dev/null
+++ b/src/fused/finiteVolume/fusedGaussLaplacianScheme.C
@@ -0,0 +1,581 @@
+/*---------------------------------------------------------------------------*\
+ ========= |
+ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
+ \\ / O peration |
+ \\ / A nd | www.openfoam.com
+ \\/ M anipulation |
+-------------------------------------------------------------------------------
+ Copyright (C) 2011-2016 OpenFOAM Foundation
+ Copyright (C) 2024 M. Janssens
+-------------------------------------------------------------------------------
+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 "fusedGaussLaplacianScheme.H"
+#include "fvcSurfaceOps.H"
+#include "surfaceInterpolate.H"
+#include "fvcDiv.H"
+#include "fvcGrad.H"
+#include "fvMatrices.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace fv
+{
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+template
+tmp>
+fusedGaussLaplacianScheme::fvmLaplacianUncorrected
+(
+ const surfaceScalarField& gammaMagSf,
+ const surfaceScalarField& deltaCoeffs,
+ const GeometricField& vf
+)
+{
+ DebugPout
+ << "fusedGaussLaplacianScheme::fvmLaplacianUncorrected on "
+ << vf.name()
+ << " with gammaMagSf " << gammaMagSf.name()
+ << " with deltaCoeffs " << deltaCoeffs.name()
+ << endl;
+
+ tmp> tfvm
+ (
+ new fvMatrix
+ (
+ vf,
+ deltaCoeffs.dimensions()*gammaMagSf.dimensions()*vf.dimensions()
+ )
+ );
+ fvMatrix& fvm = tfvm.ref();
+
+ //fvm.upper() = deltaCoeffs.primitiveField()*gammaMagSf.primitiveField();
+ multiply
+ (
+ 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];
+
+ auto& intCoeffs = fvm.internalCoeffs()[patchi];
+ auto& bouCoeffs = fvm.boundaryCoeffs()[patchi];
+
+ if (pvf.coupled())
+ {
+ //intCoeffs = pGamma*pvf.gradientInternalCoeffs(pDeltaCoeffs);
+ multiply
+ (
+ intCoeffs,
+ pGamma,
+ pvf.gradientInternalCoeffs(pDeltaCoeffs)()
+ );
+ //bouCoeffs = -pGamma*pvf.gradientBoundaryCoeffs(pDeltaCoeffs);
+ multiply
+ (
+ bouCoeffs,
+ pGamma,
+ pvf.gradientBoundaryCoeffs(pDeltaCoeffs)()
+ );
+ bouCoeffs.negate();
+ }
+ else
+ {
+ //intCoeffs = pGamma*pvf.gradientInternalCoeffs();
+ multiply
+ (
+ intCoeffs,
+ pGamma,
+ pvf.gradientInternalCoeffs()()
+ );
+ //bouCoeffs = -pGamma*pvf.gradientBoundaryCoeffs();
+ multiply
+ (
+ bouCoeffs,
+ pGamma,
+ pvf.gradientBoundaryCoeffs()()
+ );
+ bouCoeffs.negate();
+ }
+ }
+
+ return tfvm;
+}
+
+
+template
+tmp>
+fusedGaussLaplacianScheme::gammaSnGradCorr
+(
+ const surfaceVectorField& SfGammaCorr,
+ const GeometricField& vf
+)
+{
+ const fvMesh& mesh = this->mesh();
+
+ DebugPout<< "fusedGaussLaplacianScheme::gammaSnGradCorr on "
+ << vf.name() << " with SfGammCorr " << SfGammaCorr.name() << endl;
+
+ 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()
+ )
+ );
+ auto& gammaSnGradCorr = tgammaSnGradCorr.ref();
+ gammaSnGradCorr.oriented() = SfGammaCorr.oriented();
+
+ for (direction cmpt = 0; cmpt < pTraits::nComponents; cmpt++)
+ {
+ gammaSnGradCorr.replace
+ (
+ cmpt,
+ fvc::dotInterpolate(SfGammaCorr, fvc::grad(vf.component(cmpt)))
+ );
+ }
+
+ return tgammaSnGradCorr;
+}
+
+
+/*
+template
+void fusedGaussLaplacianScheme::gradComponent
+(
+ const surfaceScalarField& weights,
+ const GeometricField& vf,
+ const direction cmpt,
+ GeometricField& gGrad
+)
+{
+ gGrad = dimensioned(vf.dimensions()/dimLength, Zero);
+
+ // Calculate grad of vf.component(cmpt)
+ fvc::GaussOp
+ (
+ vf,
+ weights,
+ componentInterpolate(cmpt),
+ gGrad
+ );
+}
+template
+tmp>
+fusedGaussLaplacianScheme::gammaSnGradCorr
+(
+ const surfaceScalarField& weights,
+ const GeometricField& gamma,
+ 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,
+ gamma.dimensions()
+ *vf.dimensions()*mesh.deltaCoeffs().dimensions()
+ )
+ );
+ auto& gammaSnGradCorr = tgammaSnGradCorr.ref();
+
+ gammaSnGradCorr.oriented() = gamma.oriented();
+
+
+ GeometricField gradCmptFld
+ (
+ IOobject
+ (
+ vf.name() + ".component()",
+ vf.instance(),
+ mesh,
+ IOobject::NO_READ,
+ IOobject::NO_WRITE,
+ false
+ ),
+ mesh,
+ vf.dimensions()
+ );
+
+ for (direction cmpt = 0; cmpt < pTraits::nComponents; cmpt++)
+ {
+ // Calculate fvc::grad(vf.component(cmpt)) into gradCmptFld
+ gradComponent
+ (
+ weights,
+ vf,
+ cmpt,
+
+ gradCmptFld
+ );
+
+ //gammaSnGradCorr.replace
+ //(
+ // cmpt,
+ // fvc::dotInterpolate(SfGammaCorr, gradCmptFld)
+ //);
+
+
+ fvc::interpolate
+ (
+ weights,
+
+ gradCmptFld, // fvc::grad(vf.component(cmpt))
+
+ gamma, // weight field
+
+ tanInterpolate(cmpt),
+
+ gammaSnGradCorr
+ );
+ }
+
+ return tgammaSnGradCorr;
+}
+*/
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+template
+tmp>
+fusedGaussLaplacianScheme::fvcLaplacian
+(
+ const GeometricField& vf
+)
+{
+ typedef GeometricField FieldType;
+ //typedef GeometricField SurfaceFieldType;
+
+ tmp tresult
+ (
+ new FieldType
+ (
+ IOobject
+ (
+ "laplacian(" + vf.name() + ')',
+ vf.instance(),
+ vf.mesh(),
+ IOobject::NO_READ,
+ IOobject::NO_WRITE
+ ),
+ vf.mesh(),
+ dimensioned(vf.dimensions()/dimArea, Zero),
+ fvPatchFieldBase::extrapolatedCalculatedType()
+ )
+ );
+ FieldType& result = tresult.ref();
+
+ DebugPout
+ << "fusedGaussLaplacianScheme::fvcLaplacian on "
+ << vf.name()
+ << " to generate " << result.name() << endl;
+
+ // Note: cannot use fvc::GaussOp since specialised handling on boundary.
+ // Maybe bypass for processor boundaries?
+
+ const auto tdeltaCoeffs(this->tsnGradScheme_().deltaCoeffs(vf));
+ const auto& deltaCoeffs = tdeltaCoeffs();
+
+
+ const fvMesh& mesh = vf.mesh();
+
+ if (this->tsnGradScheme_().corrected())
+ {
+ // Problem when instantiating for tensors - outerProduct not defined.
+ // scalar/vector specialisations in *Schemes.C file.
+
+ FatalErrorInFunction<< "Corrected snGrad not supported for field "
+ << vf.name() << exit(FatalError);
+
+ //typedef typename outerProduct::type GradType;
+ //typedef GeometricField GradFieldType;
+ //// Calculate sn gradient
+ //tmp tfaceGrad
+ //(
+ // new SurfaceFieldType
+ // (
+ // IOobject
+ // (
+ // "snGradCorr("+vf.name()+')',
+ // vf.instance(),
+ // mesh,
+ // IOobject::NO_READ,
+ // IOobject::NO_WRITE
+ // ),
+ // mesh,
+ // vf.dimensions()
+ // )
+ //);
+ //
+ //{
+ // // Calculate gradient
+ // tmp tgGrad
+ // (
+ // gradScheme::New
+ // (
+ // mesh,
+ // mesh.gradScheme("grad(" + vf.name() + ')')
+ // )().grad(vf, "grad(" + vf.name() + ')')
+ // );
+ // const auto& gGrad = tgGrad();
+ //
+ // // Doing a dotinterpolate with nonOrthCorrectionVectors
+ // const auto dotInterpolate = [&]
+ // (
+ // const vector& area,
+ // const scalar lambda,
+ //
+ // const GradType& ownVal,
+ // const GradType& neiVal,
+ //
+ // const vector& dotVector,
+ //
+ // Type& result
+ // )
+ // {
+ // result = dotVector&(lambda*(ownVal - neiVal) + neiVal);
+ // };
+ //
+ // fvc::interpolate
+ // (
+ // mesh.surfaceInterpolation::weights(), // linear interp
+ // gGrad, // volume field
+ // mesh.nonOrthCorrectionVectors(),// surface multiplier
+ // dotInterpolate,
+ // tfaceGrad.ref()
+ // );
+ //}
+ //const auto& faceGrad = tfaceGrad();
+ //
+ //const auto snGrad = [&]
+ //(
+ // const vector& Sf,
+ // const scalar dc,
+ // const Type& ownVal,
+ // const Type& neiVal,
+ // const Type& correction
+ //) -> Type
+ //{
+ // const auto snGrad(dc*(neiVal-ownVal) + correction);
+ // return mag(Sf)*snGrad;
+ //};
+ //
+ //fvc::surfaceSnSum
+ //(
+ // deltaCoeffs,
+ // vf,
+ // faceGrad, // face-based addition
+ // snGrad,
+ // result,
+ // false // avoid boundary evaluation until volume division
+ //);
+ }
+ else
+ {
+ const auto snGrad = [&]
+ (
+ const vector& Sf,
+ const scalar dc,
+ const Type& ownVal,
+ const Type& neiVal
+ ) -> Type
+ {
+ const auto snGrad(dc*(neiVal-ownVal));
+ return mag(Sf)*snGrad;
+ };
+
+ fvc::surfaceSnSum
+ (
+ deltaCoeffs,
+ vf,
+ snGrad,
+ result,
+ false // avoid boundary evaluation until volume division
+ );
+ }
+
+ result.primitiveFieldRef() /= mesh.V();
+ result.correctBoundaryConditions();
+
+ return tresult;
+}
+
+
+template
+tmp>
+fusedGaussLaplacianScheme::fvcLaplacian
+(
+ const GeometricField& gamma,
+ const GeometricField& vf
+)
+{
+ DebugPout
+ << "fusedGaussLaplacianScheme::fvcLaplacian on "
+ << vf.name() << " with gamma " << gamma.name() << endl;
+
+ return fvcLaplacian(this->tinterpGammaScheme_().interpolate(gamma)(), vf);
+}
+
+
+template
+tmp>
+fusedGaussLaplacianScheme::fvmLaplacian
+(
+ const GeometricField& gamma,
+ const GeometricField& vf
+)
+{
+ DebugPout<< "fusedGaussLaplacianScheme::fvmLaplacian on "
+ << vf.name() << " with gamma " << gamma.name() << endl;
+
+ 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> 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);
+ }
+
+ fvm.source() -= mesh.V()*fvc::div(tfaceFluxCorrection())().primitiveField();
+
+ if (mesh.fluxRequired(vf.name()))
+ {
+ fvm.faceFluxCorrectionPtr(tfaceFluxCorrection.ptr());
+ }
+
+ return tfvm;
+}
+
+
+template
+tmp>
+fusedGaussLaplacianScheme::fvmLaplacian
+(
+ const GeometricField& gamma,
+ const GeometricField& vf
+)
+{
+ DebugPout<< "fusedGaussLaplacianScheme::fvmLaplacian on "
+ << vf.name() << " with gamma " << gamma.name() << endl;
+ return fvmLaplacian(this->tinterpGammaScheme_().interpolate(gamma)(), vf);
+}
+
+
+template
+tmp>
+fusedGaussLaplacianScheme::fvcLaplacian
+(
+ const GeometricField& gamma,
+ const GeometricField& vf
+)
+{
+ DebugPout<< "fusedGaussLaplacianScheme::fvcLaplacian on "
+ << vf.name() << " with gamma " << gamma.name() << endl;
+
+ 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/fused/finiteVolume/fusedGaussLaplacianScheme.H b/src/fused/finiteVolume/fusedGaussLaplacianScheme.H
new file mode 100644
index 0000000000..85753bff01
--- /dev/null
+++ b/src/fused/finiteVolume/fusedGaussLaplacianScheme.H
@@ -0,0 +1,264 @@
+/*---------------------------------------------------------------------------*\
+ ========= |
+ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
+ \\ / O peration |
+ \\ / A nd | www.openfoam.com
+ \\/ M anipulation |
+-------------------------------------------------------------------------------
+ Copyright (C) 2011-2016 OpenFOAM Foundation
+ Copyright (C) 2019 OpenCFD Ltd.
+ Copyright (C) 2024 M. Janssens
+-------------------------------------------------------------------------------
+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::GaussLaplacianScheme
+
+Group
+ grpFvLaplacianSchemes
+
+Description
+ Variant of GaussLaplacian that avoids intermediate fields
+
+SourceFiles
+ fusedGaussLaplacianScheme.C
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef fusedGaussLaplacianScheme_H
+#define fusedGaussLaplacianScheme_H
+
+#include "laplacianScheme.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace fv
+{
+
+/*---------------------------------------------------------------------------*\
+ Class fusedGaussLaplacianScheme Declaration
+\*---------------------------------------------------------------------------*/
+
+template
+class fusedGaussLaplacianScheme
+:
+ public fv::laplacianScheme
+{
+ // Private Member Functions
+
+ //- See gaussLaplacianScheme
+ tmp> gammaSnGradCorr
+ (
+ const surfaceVectorField& SfGammaCorr,
+ const GeometricField&
+ );
+
+ //- No copy construct
+ fusedGaussLaplacianScheme(const fusedGaussLaplacianScheme&)
+ = delete;
+
+ //- No copy assignment
+ void operator=(const fusedGaussLaplacianScheme&) = delete;
+
+
+public:
+
+ //- Runtime type information
+ TypeName("fusedGauss");
+
+
+ // Constructors
+
+ //- Construct null
+ fusedGaussLaplacianScheme(const fvMesh& mesh)
+ :
+ laplacianScheme(mesh)
+ {}
+
+ //- Construct from Istream
+ fusedGaussLaplacianScheme(const fvMesh& mesh, Istream& is)
+ :
+ laplacianScheme(mesh, is)
+ {}
+
+ //- Construct from mesh, interpolation and snGradScheme schemes
+ fusedGaussLaplacianScheme
+ (
+ const fvMesh& mesh,
+ const tmp>& igs,
+ const tmp>& sngs
+ )
+ :
+ laplacianScheme(mesh, igs, sngs)
+ {}
+
+
+ //- Destructor
+ virtual ~fusedGaussLaplacianScheme() = default;
+
+
+ // Member Functions
+
+ static tmp> fvmLaplacianUncorrected
+ (
+ const surfaceScalarField& gammaMagSf,
+ const surfaceScalarField& deltaCoeffs,
+ const GeometricField&
+ );
+
+ ////- Helper: grad on component. Move to GaussGrad? Template on
+ //// - cell-access operator?
+ //// - cell-to-face operator?
+ //// - face-to-cell operator?
+ //static void gradComponent
+ //(
+ // const surfaceScalarField& weights,
+ // const GeometricField& vf,
+ // const direction cmpt,
+ // GeometricField& gGrad
+ //);
+
+ virtual tmp> fvcLaplacian
+ (
+ const GeometricField&
+ );
+
+ virtual tmp> fvmLaplacian
+ (
+ const GeometricField&,
+ const GeometricField&
+ );
+
+ virtual tmp> fvcLaplacian
+ (
+ const GeometricField&,
+ const GeometricField&
+ );
+
+
+ // New: override laplacianScheme::fvc/mLaplacian for scalar gamma and
+ // scalar,vector volField
+
+ virtual tmp> fvmLaplacian
+ (
+ const GeometricField&,
+ const GeometricField&
+ );
+
+ virtual 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> fusedGaussLaplacianScheme::fvmLaplacian \
+( \
+ const GeometricField&, \
+ const GeometricField& \
+); \
+ \
+template<> \
+tmp> \
+fusedGaussLaplacianScheme::fvcLaplacian \
+( \
+ const GeometricField&, \
+ const GeometricField& \
+);
+
+defineFvmLaplacianScalarGamma(scalar);
+defineFvmLaplacianScalarGamma(vector);
+defineFvmLaplacianScalarGamma(sphericalTensor);
+defineFvmLaplacianScalarGamma(symmTensor);
+defineFvmLaplacianScalarGamma(tensor);
+
+// Unweighted laplacian
+template<>
+tmp>
+fusedGaussLaplacianScheme::fvcLaplacian
+(
+ const GeometricField&
+);
+template<>
+tmp>
+fusedGaussLaplacianScheme::fvcLaplacian
+(
+ const GeometricField&
+);
+
+// Weighted laplacian
+template<>
+tmp>
+fusedGaussLaplacianScheme::fvcLaplacian
+(
+ const GeometricField&,
+ const GeometricField&
+);
+template<>
+tmp>
+fusedGaussLaplacianScheme::fvcLaplacian
+(
+ const GeometricField&,
+ const GeometricField&
+);
+template<>
+tmp>
+fusedGaussLaplacianScheme::fvmLaplacian
+(
+ const GeometricField&,
+ const GeometricField&
+);
+template<>
+tmp>
+fusedGaussLaplacianScheme::fvmLaplacian
+(
+ const GeometricField&,
+ const GeometricField&
+);
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace fv
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#ifdef NoRepository
+ #include "fusedGaussLaplacianScheme.C"
+#endif
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/fused/finiteVolume/fusedGaussLaplacianSchemes.C b/src/fused/finiteVolume/fusedGaussLaplacianSchemes.C
new file mode 100644
index 0000000000..0433c423d3
--- /dev/null
+++ b/src/fused/finiteVolume/fusedGaussLaplacianSchemes.C
@@ -0,0 +1,866 @@
+/*---------------------------------------------------------------------------*\
+ ========= |
+ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
+ \\ / O peration |
+ \\ / A nd | www.openfoam.com
+ \\/ M anipulation |
+-------------------------------------------------------------------------------
+ Copyright (C) 2011-2016 OpenFOAM Foundation
+ Copyright (C) 2024 M. Janssens
+-------------------------------------------------------------------------------
+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 "fusedGaussLaplacianScheme.H"
+#include "fvMesh.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+makeFvLaplacianScheme(fusedGaussLaplacianScheme)
+
+#define declareFvmLaplacianScalarGamma(Type) \
+ \
+template<> \
+Foam::tmp> \
+Foam::fv::fusedGaussLaplacianScheme:: \
+fvmLaplacian \
+( \
+ const GeometricField& gamma, \
+ const GeometricField& vf \
+) \
+{ \
+ DebugPout<< "fusedGaussLaplacianScheme::fvmLaplacian on " << vf.name() \
+ << " with scalar gamma " << gamma.name() << endl; \
+ \
+ const fvMesh& mesh = this->mesh(); \
+ \
+ GeometricField gammaMagSf \
+ ( \
+ gamma*mesh.magSf() \
+ ); \
+ \
+ tmp> tfvm = fvmLaplacianUncorrected \
+ ( \
+ gammaMagSf, \
+ this->tsnGradScheme_().deltaCoeffs(vf), \
+ vf \
+ ); \
+ fvMatrix& fvm = tfvm.ref(); \
+ \
+ if (this->tsnGradScheme_().corrected()) \
+ { \
+ if (mesh.fluxRequired(vf.name())) \
+ { \
+ fvm.faceFluxCorrectionPtr() = std::make_unique \
+ < \
+ GeometricField \
+ > \
+ ( \
+ gammaMagSf*this->tsnGradScheme_().correction(vf) \
+ ); \
+ \
+ fvm.source() -= \
+ mesh.V()* \
+ fvc::div \
+ ( \
+ *fvm.faceFluxCorrectionPtr() \
+ )().primitiveField(); \
+ } \
+ else \
+ { \
+ fvm.source() -= \
+ mesh.V()* \
+ fvc::div \
+ ( \
+ gammaMagSf*this->tsnGradScheme_().correction(vf) \
+ )().primitiveField(); \
+ } \
+ } \
+ \
+ return tfvm; \
+} \
+ \
+ \
+template<> \
+Foam::tmp> \
+Foam::fv::fusedGaussLaplacianScheme:: \
+fvcLaplacian \
+( \
+ const GeometricField& gamma, \
+ const GeometricField& vf \
+) \
+{ \
+ DebugPout<< "fvcLaplacian on " << vf.name() \
+ << " with scalar gamma " << gamma.name() << endl; \
+ \
+ 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; \
+}
+
+
+template<>
+Foam::tmp
+<
+ Foam::GeometricField
+>
+Foam::fv::fusedGaussLaplacianScheme::fvcLaplacian
+(
+ const GeometricField& gamma,
+ const GeometricField