diff --git a/applications/test/expressionTemplates/Make/files b/applications/test/expressionTemplates/Make/files new file mode 100644 index 0000000000..9d866b294b --- /dev/null +++ b/applications/test/expressionTemplates/Make/files @@ -0,0 +1,5 @@ +Test-expressionTemplates-volFields.C +/* Test-expressionTemplates-pointFields.C */ +/* Test-expressionTemplates-Fields.C */ + +EXE = $(FOAM_USER_APPBIN)/Test-expressionTemplates diff --git a/applications/test/expressionTemplates/Make/options b/applications/test/expressionTemplates/Make/options new file mode 100644 index 0000000000..ede08caa60 --- /dev/null +++ b/applications/test/expressionTemplates/Make/options @@ -0,0 +1,11 @@ +EXE_INC = \ + -O0 \ + -I$(FOAM_SRC)/meshTools/lnInclude \ + -I$(FOAM_SRC)/finiteVolume/lnInclude \ + +EXE_LIBS = \ +/* -rpath /Volumes/case_sensitive/OpenFOAM/work/feature-et/platforms */ \ +/* -rpath /Volumes/case_sensitive/OpenFOAM/work/feature-et/platforms/darwin64GccDPInt32Opt/lib */ \ +/* -rpath /Volumes/case_sensitive/OpenFOAM/work/feature-et/platforms/darwin64GccDPInt32Opt/lib/$(FOAM_MPI) */\ + -L/Volumes/case_sensitive/OpenFOAM/work/feature-et/platforms/darwin64GccDPInt32Opt/lib \ + -lfiniteVolume diff --git a/applications/test/expressionTemplates/Test-expressionTemplates-pointFields.C b/applications/test/expressionTemplates/Test-expressionTemplates-pointFields.C new file mode 100644 index 0000000000..47b0017c11 --- /dev/null +++ b/applications/test/expressionTemplates/Test-expressionTemplates-pointFields.C @@ -0,0 +1,126 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | www.openfoam.com + \\/ M anipulation | +------------------------------------------------------------------------------- + Copyright (C) 2025 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 . + +Application + Test-expressionTemplates + +\*---------------------------------------------------------------------------*/ + +#include "Time.H" +#include "argList.H" +#include "polyMesh.H" +#include "pointMesh.H" +#include "pointFields.H" + +using namespace Foam; + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +int main(int argc, char *argv[]) +{ + #include "setRootCase.H" + + #include "createTime.H" + #include "createPolyMesh.H" + + { + scalarField vals0({1.0, 2.0, 3.0}); + const Expression::ListConstRefWrap wvals0(vals0); + + scalarField vals1; + Expression::ListRefWrap wvals1(vals1.size(), vals1); + wvals1 = wvals0; + return 0; + } + + + + + const pointMesh& pMesh = pointMesh::New(mesh); + + // Field, dimensionedScalar as List expression + { + scalarField vals({1.0, 2.0, 3.0}); + dimensionedScalar d(dimless, 4.0); + + scalarField result(d.expr(vals.size())*vals.expr()); + + Pout<< "result:" << result << endl; + } + + Info<< "Reading field p\n" << endl; + pointScalarField p + ( + IOobject + ( + "pointDisplacement", + runTime.timeName(), + pMesh.thisDb(), + IOobject::MUST_READ, + IOobject::AUTO_WRITE + ), + pMesh + ); + + pointScalarField result + ( + IOobject + ( + "result", + runTime.timeName(), + pMesh.thisDb(), + IOobject::NO_READ, + IOobject::NO_WRITE, + IOobject::NO_REGISTER + ), + pMesh, + dimensionedScalar("zero", Foam::sqr(p().dimensions()), 0) + ); + + // Construct value + dimensions with correct sizing + const auto oneField(dimensionedScalar(dimless, 1.0).expr(p)); + + // Make expression + auto expression = oneField * p.expr() + p.expr(); + + // Combine expressions + auto newExpression = sqr(expression); + + // Assign values + result = newExpression; + + DebugVar(result); + + + // Construct from expression + pointScalarField result2("result2", pMesh, sqrt(p.expr())); + + DebugVar(result2); + + return 0; +} + + +// ************************************************************************* // diff --git a/applications/test/expressionTemplates/Test-expressionTemplates-volFields.C b/applications/test/expressionTemplates/Test-expressionTemplates-volFields.C new file mode 100644 index 0000000000..bd5b2a3219 --- /dev/null +++ b/applications/test/expressionTemplates/Test-expressionTemplates-volFields.C @@ -0,0 +1,451 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / 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 . + +Application + volPointInterpolationTest + +\*---------------------------------------------------------------------------*/ + +#include "Time.H" +#include "argList.H" +#include "fvMesh.H" +#include "ListExpression.H" +#include "GeometricFieldExpression.H" +#include "fvCFD.H" +#include "fvMatrixExpression.H" +#include +#include + +using namespace Foam; + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +tmp someFunction(const volScalarField& fld) +{ + return fld*1.0001; +} + + +template +void fusedGaussFvmLaplacian +( + fvMatrix& fvm, + const surfaceInterpolationScheme& interpGammaScheme, + const fv::snGradScheme& snGradScheme, + const GeometricField& gamma, + const GeometricField& vf +) +{ + // Replacement for gaussLaplacianScheme::fvmLaplacian with scalar gamma + typedef GeometricField surfaceType; + + const auto& mesh = vf.mesh(); + + // Expression for weights + const auto weights = interpGammaScheme.weights(gamma).expr(); + + // Expression for gamma_face * magSf + const auto gammaMagSf = + Expression::interpolate(gamma.expr(), weights, mesh) + * mesh.magSf().expr(); + + // Expression for deltaCoeffs + const auto deltaCoeffs = snGradScheme.deltaCoeffs(vf).expr(); + + // Construct matrix + Expression::fvmLaplacianUncorrected(fvm, gammaMagSf, deltaCoeffs); + + if (snGradScheme.corrected()) + { + // Wrap correction + const auto corr(snGradScheme.correction(vf).expr()); + const auto V = mesh.V().expr(); + + if (mesh.fluxRequired(vf.name())) + { + fvm.faceFluxCorrectionPtr() = std::make_unique + ( + IOobject + ( + "faceFluxCorr", + mesh.time().timeName(), + mesh, + IOobject::NO_READ, + IOobject::NO_WRITE, + IOobject::NO_REGISTER + ), + mesh, + gamma.dimensions() + *mesh.magSf().dimensions() + *corr.data().dimensions() + ); + auto& faceFluxCorr = *fvm.faceFluxCorrectionPtr(); + faceFluxCorr = gammaMagSf*corr; + + fvm.source() = + fvm.source().expr() + - ( + V * fvc::div + ( + faceFluxCorr + )().primitiveField().expr() + ); + } + else + { + // Temporary field + surfaceType faceFluxCorr + ( + IOobject + ( + "faceFluxCorr", + mesh.time().timeName(), + mesh, + IOobject::NO_READ, + IOobject::NO_WRITE, + IOobject::NO_REGISTER + ), + mesh, + gamma.dimensions() + *mesh.magSf().dimensions() + *corr.data().dimensions() + ); + faceFluxCorr = gammaMagSf*corr; + + fvm.source() = + fvm.source().expr() + - ( + V * fvc::div + ( + faceFluxCorr + )().primitiveField().expr() + ); + } + } +} + + +using namespace std::chrono; + +int main(int argc, char *argv[]) +{ + #include "setRootCase.H" + #include "createTime.H" + #include "createMesh.H" + + Info<< "Reading field p\n" << endl; + volScalarField p + ( + IOobject + ( + "p", + runTime.timeName(), + mesh.thisDb(), + IOobject::MUST_READ, + IOobject::AUTO_WRITE + ), + mesh + ); + + { + volScalarField p2("p2", p); + DebugVar(p2.boundaryFieldRef()); + + for (auto& pf : p.boundaryFieldRef()) + { + scalarField newVals(pf.size()); + forAll(pf, i) + { + newVals[i] = scalar(i); + } + pf == newVals; + } + + //std::vector ptrs; + // List ptrs; + // for (const auto& pp : p.boundaryField()) + // { + // ptrs.push_back(&pp); + // } + DebugVar(sizeof(long)); + DebugVar(p.boundaryField()); + Expression::ListsConstRefWrap expr(p.boundaryField()); + + const auto twoA = expr + expr; + Expression::ListsRefWrap expr2(p2.boundaryFieldRef()); + Pout<< "**before assignment twoA:" << twoA.size() + << " expr2:" << expr2.size() << endl; + expr2 = twoA; + Pout<< "**after assignment twoA:" << twoA.size() + << " expr2:" << expr2.size() << endl; + DebugVar(p2.boundaryField()); + // forAll(expr, i) + // { + // Pout<< "i:" << i + // //<< " expr:" << expr[i] + // //<< " twoA:" << twoA[i] + // << " expr2:" << expr2[i] + // << endl; + // } + return 0; + } + + { + //DebugVar(linearInterpolate(p)); + //auto tweights = linear(mesh).weights(p); + //DebugVar(tweights); + + surfaceScalarField result + ( + IOobject + ( + "result", + runTime.timeName(), + mesh.thisDb(), + IOobject::NO_READ, + IOobject::NO_WRITE, + IOobject::NO_REGISTER + ), + mesh, + dimensionedScalar(p.dimensions(), 0) + ); + //result = Expression::interpolate + //( + // p.expr(), + // tweights().expr(), + // mesh + //); + + result = Expression::linearInterpolate(p.expr(), mesh); + + + DebugVar(result); + + return 0; + } + + + + volScalarField p2 + ( + IOobject + ( + "p", + runTime.timeName(), + mesh.thisDb(), + IOobject::MUST_READ, + IOobject::AUTO_WRITE, + IOobject::NO_REGISTER + ), + mesh + ); + + // Expresions of volFields + { + volScalarField result + ( + IOobject + ( + "result", + runTime.timeName(), + mesh.thisDb(), + IOobject::NO_READ, + IOobject::NO_WRITE, + IOobject::NO_REGISTER + ), + mesh, + dimensionedScalar(p.dimensions(), 0) + ); + + { + Pout<< "No expression templates:" << endl; + const high_resolution_clock::time_point t1 = + high_resolution_clock::now(); + result = p + p2; + const high_resolution_clock::time_point t2 = + high_resolution_clock::now(); + const duration time_span = t2 - t1; + Pout<< "Operation time:" << time_span.count() << endl; + } + { + Pout<< "With expression templates:" << endl; + const high_resolution_clock::time_point t1 = + high_resolution_clock::now(); + result = p.expr() + p2.expr(); + const high_resolution_clock::time_point t2 = + high_resolution_clock::now(); + const duration time_span = t2 - t1; + Pout<< "Operation time:" << time_span.count() << endl; + } + +// const auto oldDimensions = p.dimensions(); +// p.dimensions().reset(dimless); +// p2.dimensions().reset(dimless); +// result.dimensions().reset(dimless); +// { +// +// Pout<< "Complex expression : No expression templates:" << endl; +// const high_resolution_clock::time_point t1 = +// high_resolution_clock::now(); +// result = cos(p + 0.5*sqrt(p2-sin(p))); +// const high_resolution_clock::time_point t2 = +// high_resolution_clock::now(); +// const duration time_span = t2 - t1; +// Pout<< "Operation time:" << time_span.count() << endl; +// } +// { +// Pout<< "Complex expression : With expression templates:" << endl; +// const high_resolution_clock::time_point t1 = +// high_resolution_clock::now(); +// const auto zeroDotFive +// ( +// dimensionedScalar(dimless, 0.5).expr(p) +// ); +// result = cos(p.expr() + zeroDotFive*sqrt(p2.expr()-sin(p.expr()))); +// const high_resolution_clock::time_point t2 = +// high_resolution_clock::now(); +// const duration time_span = t2 - t1; +// Pout<< "Operation time:" << time_span.count() << endl; +// } +// p.dimensions().reset(oldDimensions); +// p2.dimensions().reset(oldDimensions); +// result.dimensions().reset(oldDimensions); + + return 0; +// auto expression = someFunction(p).expr() + someFunction(p).expr(); +// result = expression; +// DebugVar(result); + } + { + volScalarField result + ( + IOobject + ( + "result", + runTime.timeName(), + mesh.thisDb(), + IOobject::NO_READ, + IOobject::NO_WRITE, + IOobject::NO_REGISTER + ), + mesh, + dimensionedScalar(p.dimensions(), 0) + ); + auto expression = someFunction(p).expr() + someFunction(p).expr(); + result = expression; + DebugVar(result); + } + + // Expresions of volFields + { + volScalarField result + ( + "result", + mesh, + sqr(p.expr() + p.expr()) + ); + DebugVar(result); + } + { + // Fill p with some values + forAll(p, celli) + { + p[celli] = celli; + } + p.correctBoundaryConditions(); + + // Interpolate to surface field + surfaceScalarField result + ( + "result", + mesh, + Expression::interpolate // + ( + p.expr(), + mesh.surfaceInterpolation::weights().expr(), + mesh + ) + ); + DebugVar(result); + } + { + // For testing as a replacement of laplacian weights + const volScalarField gamma + ( + IOobject + ( + "gamma", + runTime.timeName(), + mesh, + IOobject::NO_READ, + IOobject::NO_WRITE, + IOobject::NO_REGISTER + ), + mesh, + dimensionedScalar(dimless, 1.0) + ); + + fvMatrix fvm + ( + p, + gamma.dimensions()*mesh.magSf().dimensions()*p.dimensions() + ); + + const linear interpGammaScheme(mesh); + const fv::correctedSnGrad snGradScheme(mesh); + + fusedGaussFvmLaplacian + ( + fvm, + interpGammaScheme, + snGradScheme, + gamma, + p + ); + + DebugVar(fvm.source()); + } + + + + // Expressions of fvMatrix + { + tmp> tm0(fvm::laplacian(p)); + const fvMatrix& m0 = tm0(); + DebugVar(m0.dimensions()); + + tmp> tm1(fvm::laplacian(p)); + const fvMatrix& m1 = tm1(); + DebugVar(m1.dimensions()); + + fvMatrix m2(p, m0.expr() + m1.expr()); + DebugVar(m2.dimensions()); + } + + return 0; +} + + +// ************************************************************************* // diff --git a/etc/config.sh/settings b/etc/config.sh/settings index a615345631..ae5e714e64 100644 --- a/etc/config.sh/settings +++ b/etc/config.sh/settings @@ -81,8 +81,8 @@ Darwin) case "$WM_COMPILE_CONTROL" in (*version=*) ;; (*) - WM_COMPILER=Clang - echo "openfoam (darwin): using clang instead of gcc" 1>&2 + #WM_COMPILER=Clang + #echo "openfoam (darwin): using clang instead of gcc" 1>&2 ;; esac fi diff --git a/src/Allwmake b/src/Allwmake index 04f82ffe97..8e87d20311 100755 --- a/src/Allwmake +++ b/src/Allwmake @@ -55,8 +55,6 @@ wmake $targetType fileFormats wmake $targetType surfMesh wmake $targetType meshTools -#------------------------------------------------------------------------------ - wmake $targetType finiteArea wmake $targetType finiteVolume wmake $targetType fused/finiteVolume diff --git a/src/OpenFOAM/containers/Lists/List/List.H b/src/OpenFOAM/containers/Lists/List/List.H index eaaaaea6a9..fd2b176638 100644 --- a/src/OpenFOAM/containers/Lists/List/List.H +++ b/src/OpenFOAM/containers/Lists/List/List.H @@ -45,6 +45,7 @@ SourceFiles #include "autoPtr.H" #include "UList.H" +#include "SLListFwd.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // @@ -65,7 +66,6 @@ typedef List boolList; //!< A List of bools typedef List charList; //!< A List of chars typedef List