Compare commits
9 Commits
multi-fini
...
develop
| Author | SHA1 | Date | |
|---|---|---|---|
| 6b3e65d17d | |||
| 572fa22bae | |||
| e100e4d084 | |||
| f186b0098b | |||
| b0066fc550 | |||
| 7fb4e77583 | |||
| 78cf2ce5db | |||
| f2793f2ac8 | |||
| 013dbb8248 |
5
applications/test/expressionTemplates/Make/files
Normal file
5
applications/test/expressionTemplates/Make/files
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
Test-expressionTemplates-volFields.C
|
||||||
|
/* Test-expressionTemplates-pointFields.C */
|
||||||
|
/* Test-expressionTemplates-Fields.C */
|
||||||
|
|
||||||
|
EXE = $(FOAM_USER_APPBIN)/Test-expressionTemplates
|
||||||
11
applications/test/expressionTemplates/Make/options
Normal file
11
applications/test/expressionTemplates/Make/options
Normal file
@ -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
|
||||||
@ -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 <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
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<scalar> wvals0(vals0);
|
||||||
|
|
||||||
|
scalarField vals1;
|
||||||
|
Expression::ListRefWrap<scalar> 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -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 <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
Application
|
||||||
|
volPointInterpolationTest
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#include "Time.H"
|
||||||
|
#include "argList.H"
|
||||||
|
#include "fvMesh.H"
|
||||||
|
#include "ListExpression.H"
|
||||||
|
#include "GeometricFieldExpression.H"
|
||||||
|
#include "fvCFD.H"
|
||||||
|
#include "fvMatrixExpression.H"
|
||||||
|
#include <ratio>
|
||||||
|
#include <chrono>
|
||||||
|
|
||||||
|
using namespace Foam;
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
tmp<volScalarField> someFunction(const volScalarField& fld)
|
||||||
|
{
|
||||||
|
return fld*1.0001;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class Type>
|
||||||
|
void fusedGaussFvmLaplacian
|
||||||
|
(
|
||||||
|
fvMatrix<Type>& fvm,
|
||||||
|
const surfaceInterpolationScheme<scalar>& interpGammaScheme,
|
||||||
|
const fv::snGradScheme<Type>& snGradScheme,
|
||||||
|
const GeometricField<scalar, fvPatchField, volMesh>& gamma,
|
||||||
|
const GeometricField<Type, fvPatchField, volMesh>& vf
|
||||||
|
)
|
||||||
|
{
|
||||||
|
// Replacement for gaussLaplacianScheme::fvmLaplacian with scalar gamma
|
||||||
|
typedef GeometricField<Type, fvsPatchField, surfaceMesh> 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<surfaceType>
|
||||||
|
(
|
||||||
|
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<const scalarField*> ptrs;
|
||||||
|
// List<const scalarField*> ptrs;
|
||||||
|
// for (const auto& pp : p.boundaryField())
|
||||||
|
// {
|
||||||
|
// ptrs.push_back(&pp);
|
||||||
|
// }
|
||||||
|
DebugVar(sizeof(long));
|
||||||
|
DebugVar(p.boundaryField());
|
||||||
|
Expression::ListsConstRefWrap<scalarField> expr(p.boundaryField());
|
||||||
|
|
||||||
|
const auto twoA = expr + expr;
|
||||||
|
Expression::ListsRefWrap<scalarField> 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<scalar>(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<double> 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<double> 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<double> 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<double> 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 //<volExpr, surfaceExpr>
|
||||||
|
(
|
||||||
|
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<scalar> fvm
|
||||||
|
(
|
||||||
|
p,
|
||||||
|
gamma.dimensions()*mesh.magSf().dimensions()*p.dimensions()
|
||||||
|
);
|
||||||
|
|
||||||
|
const linear<scalar> interpGammaScheme(mesh);
|
||||||
|
const fv::correctedSnGrad<scalar> snGradScheme(mesh);
|
||||||
|
|
||||||
|
fusedGaussFvmLaplacian
|
||||||
|
(
|
||||||
|
fvm,
|
||||||
|
interpGammaScheme,
|
||||||
|
snGradScheme,
|
||||||
|
gamma,
|
||||||
|
p
|
||||||
|
);
|
||||||
|
|
||||||
|
DebugVar(fvm.source());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Expressions of fvMatrix
|
||||||
|
{
|
||||||
|
tmp<fvMatrix<scalar>> tm0(fvm::laplacian(p));
|
||||||
|
const fvMatrix<scalar>& m0 = tm0();
|
||||||
|
DebugVar(m0.dimensions());
|
||||||
|
|
||||||
|
tmp<fvMatrix<scalar>> tm1(fvm::laplacian(p));
|
||||||
|
const fvMatrix<scalar>& m1 = tm1();
|
||||||
|
DebugVar(m1.dimensions());
|
||||||
|
|
||||||
|
fvMatrix<scalar> m2(p, m0.expr() + m1.expr());
|
||||||
|
DebugVar(m2.dimensions());
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -49,7 +49,8 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
Info<< "mesh 0: " << mesh.sortedNames() << nl;
|
Info<< "mesh 0: " << mesh.sortedNames() << nl;
|
||||||
|
|
||||||
auto& reg = const_cast<faMeshesRegistry&>(faMeshesRegistry::New(mesh));
|
faMeshesRegistry& reg =
|
||||||
|
const_cast<faMeshesRegistry&>(faMeshesRegistry::New(mesh));
|
||||||
|
|
||||||
// faMeshesRegistry faReg = faMeshesRegistry(mesh);
|
// faMeshesRegistry faReg = faMeshesRegistry(mesh);
|
||||||
|
|
||||||
|
|||||||
@ -1,3 +1,3 @@
|
|||||||
foamToEnsight-check.cxx
|
foamToEnsight-check.C
|
||||||
|
|
||||||
EXE = $(FOAM_USER_APPBIN)/foamToEnsight-check
|
EXE = $(FOAM_USER_APPBIN)/foamToEnsight-check
|
||||||
|
|||||||
@ -5,7 +5,7 @@
|
|||||||
\\ / A nd | www.openfoam.com
|
\\ / A nd | www.openfoam.com
|
||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Copyright (C) 2022-2025 OpenCFD Ltd.
|
Copyright (C) 2022-2023 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM.
|
This file is part of OpenFOAM.
|
||||||
@ -203,7 +203,6 @@ int main(int argc, char *argv[])
|
|||||||
argList::addVerboseOption();
|
argList::addVerboseOption();
|
||||||
|
|
||||||
#include "addAllRegionOptions.H"
|
#include "addAllRegionOptions.H"
|
||||||
#include "addAllFaRegionOptions.H"
|
|
||||||
|
|
||||||
argList::addBoolOption
|
argList::addBoolOption
|
||||||
(
|
(
|
||||||
@ -252,14 +251,6 @@ int main(int argc, char *argv[])
|
|||||||
// Handle -allRegions, -regions, -region
|
// Handle -allRegions, -regions, -region
|
||||||
#include "getAllRegionOptions.H"
|
#include "getAllRegionOptions.H"
|
||||||
|
|
||||||
// Handle -all-area-regions, -area-regions, -area-region
|
|
||||||
#include "getAllFaRegionOptions.H"
|
|
||||||
|
|
||||||
if (!doFiniteArea)
|
|
||||||
{
|
|
||||||
areaRegionNames.clear(); // For consistency
|
|
||||||
}
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
|
|
||||||
#include "createNamedMeshes.H"
|
#include "createNamedMeshes.H"
|
||||||
@ -268,8 +259,8 @@ int main(int argc, char *argv[])
|
|||||||
/// #include "createMeshAccounting.H"
|
/// #include "createMeshAccounting.H"
|
||||||
|
|
||||||
PtrList<ensightMesh> ensightMeshes(regionNames.size());
|
PtrList<ensightMesh> ensightMeshes(regionNames.size());
|
||||||
List<PtrList<faMesh>> meshesFa(regionNames.size());
|
PtrList<faMesh> meshesFa(regionNames.size());
|
||||||
List<PtrList<ensightFaMesh>> ensightMeshesFa(regionNames.size());
|
PtrList<ensightFaMesh> ensightMeshesFa(regionNames.size());
|
||||||
|
|
||||||
forAll(regionNames, regioni)
|
forAll(regionNames, regioni)
|
||||||
{
|
{
|
||||||
@ -282,32 +273,21 @@ int main(int argc, char *argv[])
|
|||||||
);
|
);
|
||||||
ensightMeshes[regioni].verbose(optVerbose);
|
ensightMeshes[regioni].verbose(optVerbose);
|
||||||
|
|
||||||
if (!doFiniteArea)
|
|
||||||
|
if (doFiniteArea)
|
||||||
{
|
{
|
||||||
continue;
|
autoPtr<faMesh> faMeshPtr(faMesh::TryNew(mesh));
|
||||||
}
|
|
||||||
|
|
||||||
meshesFa[regioni].resize_null(areaRegionNames.size());
|
|
||||||
ensightMeshesFa[regioni].resize_null(areaRegionNames.size());
|
|
||||||
|
|
||||||
autoPtr<faMesh> faMeshPtr(faMesh::TryNew(mesh));
|
|
||||||
|
|
||||||
forAll(areaRegionNames, areai)
|
|
||||||
{
|
|
||||||
const word& areaName = areaRegionNames[areai];
|
|
||||||
|
|
||||||
autoPtr<faMesh> faMeshPtr(faMesh::TryNew(areaName, mesh));
|
|
||||||
|
|
||||||
if (faMeshPtr)
|
if (faMeshPtr)
|
||||||
{
|
{
|
||||||
meshesFa[regioni].set(areai, std::move(faMeshPtr));
|
meshesFa.set(regioni, std::move(faMeshPtr));
|
||||||
|
|
||||||
ensightMeshesFa[regioni].set
|
ensightMeshesFa.set
|
||||||
(
|
(
|
||||||
areai,
|
regioni,
|
||||||
new ensightFaMesh(meshesFa[regioni][areai])
|
new ensightFaMesh(meshesFa[regioni])
|
||||||
);
|
);
|
||||||
ensightMeshesFa[regioni][areai].verbose(optVerbose);
|
ensightMeshesFa[regioni].verbose(optVerbose);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -315,7 +295,7 @@ int main(int argc, char *argv[])
|
|||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
if (UPstream::master())
|
if (Pstream::master())
|
||||||
{
|
{
|
||||||
Info<< "Checking " << timeDirs.size() << " time steps" << nl;
|
Info<< "Checking " << timeDirs.size() << " time steps" << nl;
|
||||||
}
|
}
|
||||||
@ -337,20 +317,17 @@ int main(int argc, char *argv[])
|
|||||||
auto& ensMesh = ensightMeshes[regioni];
|
auto& ensMesh = ensightMeshes[regioni];
|
||||||
|
|
||||||
// Finite-area (can be missing)
|
// Finite-area (can be missing)
|
||||||
auto& ensFaMeshes = ensightMeshesFa[regioni];
|
auto* ensFaMeshPtr = ensightMeshesFa.get(regioni);
|
||||||
|
|
||||||
if (moving)
|
if (moving)
|
||||||
{
|
{
|
||||||
ensMesh.expire();
|
ensMesh.expire();
|
||||||
ensMesh.correct();
|
ensMesh.correct();
|
||||||
|
|
||||||
forAll(areaRegionNames, areai)
|
if (ensFaMeshPtr)
|
||||||
{
|
{
|
||||||
if (auto* ensFaMeshPtr = ensFaMeshes.get(areai))
|
ensFaMeshPtr->expire();
|
||||||
{
|
ensFaMeshPtr->correct();
|
||||||
ensFaMeshPtr->expire();
|
|
||||||
ensFaMeshPtr->correct();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -363,15 +340,9 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
printInfo(ensMesh, optVerbose);
|
printInfo(ensMesh, optVerbose);
|
||||||
|
|
||||||
// finite-area
|
if (ensFaMeshPtr)
|
||||||
forAll(areaRegionNames, areai)
|
|
||||||
{
|
{
|
||||||
auto* ensFaMeshPtr = ensFaMeshes.get(areai);
|
printInfo(*ensFaMeshPtr, optVerbose);
|
||||||
|
|
||||||
if (ensFaMeshPtr)
|
|
||||||
{
|
|
||||||
printInfo(*ensFaMeshPtr, optVerbose);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -6,7 +6,7 @@
|
|||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Copyright (C) 2016-2017 Wikki Ltd
|
Copyright (C) 2016-2017 Wikki Ltd
|
||||||
Copyright (C) 2021-2025 OpenCFD Ltd.
|
Copyright (C) 2021-2023 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM.
|
This file is part of OpenFOAM.
|
||||||
@ -28,7 +28,7 @@ Application
|
|||||||
makeFaMesh
|
makeFaMesh
|
||||||
|
|
||||||
Description
|
Description
|
||||||
Check a finite-area mesh
|
Check a finiteArea mesh
|
||||||
|
|
||||||
Original Authors
|
Original Authors
|
||||||
Zeljko Tukovic, FAMENA
|
Zeljko Tukovic, FAMENA
|
||||||
@ -39,7 +39,6 @@ Original Authors
|
|||||||
#include "Time.H"
|
#include "Time.H"
|
||||||
#include "argList.H"
|
#include "argList.H"
|
||||||
#include "faMesh.H"
|
#include "faMesh.H"
|
||||||
#include "faMeshTools.H"
|
|
||||||
#include "polyMesh.H"
|
#include "polyMesh.H"
|
||||||
#include "areaFaMesh.H"
|
#include "areaFaMesh.H"
|
||||||
#include "edgeFaMesh.H"
|
#include "edgeFaMesh.H"
|
||||||
@ -48,7 +47,7 @@ Original Authors
|
|||||||
#include "processorFaPatch.H"
|
#include "processorFaPatch.H"
|
||||||
#include "foamVtkIndPatchWriter.H"
|
#include "foamVtkIndPatchWriter.H"
|
||||||
#include "foamVtkLineWriter.H"
|
#include "foamVtkLineWriter.H"
|
||||||
#include "regionProperties.H"
|
#include "faMeshTools.H"
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
@ -60,7 +59,7 @@ int main(int argc, char *argv[])
|
|||||||
{
|
{
|
||||||
argList::addNote
|
argList::addNote
|
||||||
(
|
(
|
||||||
"Check a finite-area mesh"
|
"Check a finiteArea mesh"
|
||||||
);
|
);
|
||||||
|
|
||||||
argList::addBoolOption
|
argList::addBoolOption
|
||||||
@ -78,15 +77,9 @@ int main(int argc, char *argv[])
|
|||||||
);
|
);
|
||||||
|
|
||||||
#include "addRegionOption.H"
|
#include "addRegionOption.H"
|
||||||
#include "addAllFaRegionOptions.H"
|
#include "addFaRegionOption.H"
|
||||||
#include "setRootCase.H"
|
#include "setRootCase.H"
|
||||||
#include "createTime.H"
|
#include "createTime.H"
|
||||||
|
|
||||||
// Handle -all-area-regions, -area-regions, -area-region
|
|
||||||
#include "getAllFaRegionOptions.H"
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------
|
|
||||||
|
|
||||||
#include "createNamedPolyMesh.H"
|
#include "createNamedPolyMesh.H"
|
||||||
|
|
||||||
int geometryOrder(1);
|
int geometryOrder(1);
|
||||||
@ -98,41 +91,16 @@ int main(int argc, char *argv[])
|
|||||||
faMesh::geometryOrder(geometryOrder);
|
faMesh::geometryOrder(geometryOrder);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const word& areaName : areaRegionNames)
|
#include "createNamedFaMesh.H"
|
||||||
|
|
||||||
|
Info<< "Time = " << runTime.timeName() << nl << endl;
|
||||||
|
|
||||||
|
// Mesh information (verbose)
|
||||||
|
faMeshTools::printMeshChecks(aMesh);
|
||||||
|
|
||||||
|
if (args.found("write-vtk"))
|
||||||
{
|
{
|
||||||
Info<< "Create faMesh";
|
#include "faMeshWriteVTK.H"
|
||||||
if (!polyMesh::regionName(areaName).empty())
|
|
||||||
{
|
|
||||||
Info<< " [" << areaName << "]";
|
|
||||||
}
|
|
||||||
Info<< " for time = " << runTime.timeName() << nl;
|
|
||||||
|
|
||||||
autoPtr<faMesh> faMeshPtr(faMesh::TryNew(areaName, mesh));
|
|
||||||
|
|
||||||
if (!faMeshPtr)
|
|
||||||
{
|
|
||||||
Info<< " ...failed to create area-mesh";
|
|
||||||
if (!polyMesh::regionName(areaName).empty())
|
|
||||||
{
|
|
||||||
Info<< " [" << areaName << "]";
|
|
||||||
}
|
|
||||||
Info<< endl;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Info<< endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
const auto& aMesh = faMeshPtr();
|
|
||||||
|
|
||||||
// Mesh information (verbose)
|
|
||||||
faMeshTools::printMeshChecks(aMesh);
|
|
||||||
|
|
||||||
if (args.found("write-vtk"))
|
|
||||||
{
|
|
||||||
#include "faMeshWriteVTK.H"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Info<< "\nEnd\n" << endl;
|
Info<< "\nEnd\n" << endl;
|
||||||
|
|||||||
@ -5,7 +5,7 @@
|
|||||||
\\ / A nd | www.openfoam.com
|
\\ / A nd | www.openfoam.com
|
||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Copyright (C) 2021-2025 OpenCFD Ltd.
|
Copyright (C) 2021-2023 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM, distributed under GPL-3.0-or-later.
|
This file is part of OpenFOAM, distributed under GPL-3.0-or-later.
|
||||||
@ -15,16 +15,6 @@ Description
|
|||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
// The base name for output files
|
|
||||||
word vtkBaseFileName(aMesh.regionName());
|
|
||||||
if (polyMesh::regionName(vtkBaseFileName).empty())
|
|
||||||
{
|
|
||||||
vtkBaseFileName = "finiteArea";
|
|
||||||
}
|
|
||||||
|
|
||||||
Info<< nl;
|
|
||||||
Info<< "Write faMesh in vtk format:" << nl;
|
|
||||||
|
|
||||||
{
|
{
|
||||||
// finiteArea - faces
|
// finiteArea - faces
|
||||||
vtk::uindirectPatchWriter writer
|
vtk::uindirectPatchWriter writer
|
||||||
@ -33,7 +23,7 @@ Info<< "Write faMesh in vtk format:" << nl;
|
|||||||
// vtk::formatType::INLINE_ASCII,
|
// vtk::formatType::INLINE_ASCII,
|
||||||
fileName
|
fileName
|
||||||
(
|
(
|
||||||
aMesh.time().globalPath() / vtkBaseFileName
|
aMesh.time().globalPath() / "finiteArea"
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -42,7 +32,7 @@ Info<< "Write faMesh in vtk format:" << nl;
|
|||||||
globalIndex procAddr(aMesh.nFaces());
|
globalIndex procAddr(aMesh.nFaces());
|
||||||
labelList cellIDs;
|
labelList cellIDs;
|
||||||
|
|
||||||
if (UPstream::master())
|
if (Pstream::master())
|
||||||
{
|
{
|
||||||
cellIDs.resize(procAddr.totalSize());
|
cellIDs.resize(procAddr.totalSize());
|
||||||
for (const labelRange& range : procAddr.ranges())
|
for (const labelRange& range : procAddr.ranges())
|
||||||
@ -63,7 +53,8 @@ Info<< "Write faMesh in vtk format:" << nl;
|
|||||||
writer.beginPointData(1);
|
writer.beginPointData(1);
|
||||||
writer.write("normal", aMesh.pointAreaNormals());
|
writer.write("normal", aMesh.pointAreaNormals());
|
||||||
|
|
||||||
Info<< " " << writer.output().name() << nl;
|
Info<< nl
|
||||||
|
<< "Wrote faMesh in vtk format: " << writer.output().name() << nl;
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
@ -75,7 +66,7 @@ Info<< "Write faMesh in vtk format:" << nl;
|
|||||||
// vtk::formatType::INLINE_ASCII,
|
// vtk::formatType::INLINE_ASCII,
|
||||||
fileName
|
fileName
|
||||||
(
|
(
|
||||||
aMesh.time().globalPath() / (vtkBaseFileName + "-edges")
|
aMesh.time().globalPath() / "finiteArea-edges"
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -97,7 +88,8 @@ Info<< "Write faMesh in vtk format:" << nl;
|
|||||||
writer.beginPointData(1);
|
writer.beginPointData(1);
|
||||||
writer.write("normal", aMesh.pointAreaNormals());
|
writer.write("normal", aMesh.pointAreaNormals());
|
||||||
|
|
||||||
Info<< " " << writer.output().name() << nl;
|
Info<< nl
|
||||||
|
<< "Wrote faMesh in vtk format: " << writer.output().name() << nl;
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
@ -116,7 +108,7 @@ Info<< "Write faMesh in vtk format:" << nl;
|
|||||||
// vtk::formatType::INLINE_ASCII,
|
// vtk::formatType::INLINE_ASCII,
|
||||||
fileName
|
fileName
|
||||||
(
|
(
|
||||||
aMesh.time().globalPath() / (vtkBaseFileName + "-edgesCentres")
|
aMesh.time().globalPath() / "finiteArea-edgesCentres"
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -142,7 +134,8 @@ Info<< "Write faMesh in vtk format:" << nl;
|
|||||||
writer.write("normal", fld);
|
writer.write("normal", fld);
|
||||||
}
|
}
|
||||||
|
|
||||||
Info<< " " << writer.output().name() << nl;
|
Info<< nl
|
||||||
|
<< "Wrote faMesh in vtk format: " << writer.output().name() << nl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -5,7 +5,7 @@
|
|||||||
\\ / A nd | www.openfoam.com
|
\\ / A nd | www.openfoam.com
|
||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Copyright (C) 2023-2025 OpenCFD Ltd.
|
Copyright (C) 2023 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM, distributed under GPL-3.0-or-later.
|
This file is part of OpenFOAM, distributed under GPL-3.0-or-later.
|
||||||
@ -15,7 +15,7 @@ Description
|
|||||||
|
|
||||||
Input
|
Input
|
||||||
mesh (polyMesh)
|
mesh (polyMesh)
|
||||||
meshDefDict (system/finite-area/faMeshDefinition)
|
meshDefDict (system/faMeshDefintion)
|
||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
@ -25,16 +25,13 @@ Input
|
|||||||
|
|
||||||
const polyBoundaryMesh& pbm = mesh.boundaryMesh();
|
const polyBoundaryMesh& pbm = mesh.boundaryMesh();
|
||||||
|
|
||||||
labelList patchIDs;
|
wordRes polyPatchNames;
|
||||||
|
meshDefDict.readIfPresent("polyMeshPatches", polyPatchNames);
|
||||||
|
|
||||||
if
|
const labelList patchIDs
|
||||||
(
|
(
|
||||||
wordRes select;
|
pbm.indices(polyPatchNames, true) // useGroups
|
||||||
meshDefDict.readIfPresent("polyMeshPatches", select)
|
);
|
||||||
)
|
|
||||||
{
|
|
||||||
patchIDs = pbm.indices(select, true); // useGroups
|
|
||||||
}
|
|
||||||
|
|
||||||
label nFaceLabels = 0;
|
label nFaceLabels = 0;
|
||||||
for (const label patchi : patchIDs)
|
for (const label patchi : patchIDs)
|
||||||
|
|||||||
@ -5,7 +5,7 @@
|
|||||||
\\ / A nd | www.openfoam.com
|
\\ / A nd | www.openfoam.com
|
||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Copyright (C) 2021-2025 OpenCFD Ltd.
|
Copyright (C) 2021-2024 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM, distributed under GPL-3.0-or-later.
|
This file is part of OpenFOAM, distributed under GPL-3.0-or-later.
|
||||||
@ -13,18 +13,6 @@ License
|
|||||||
Description
|
Description
|
||||||
Search for the appropriate faMeshDefinition dictionary...
|
Search for the appropriate faMeshDefinition dictionary...
|
||||||
|
|
||||||
Expects to find a faMeshDefinition file in a location specified
|
|
||||||
by the command-line option, or one of the standard locations.
|
|
||||||
|
|
||||||
For default area region (region0):
|
|
||||||
(1) system/finite-area/faMeshDefinition
|
|
||||||
(2) system/faMeshDefinition [legacy location - v2312 and earlier]
|
|
||||||
|
|
||||||
For a named area region:
|
|
||||||
(1) system/finite-area/<area-name>/faMeshDefinition
|
|
||||||
(2) system/finite-area/faMeshDefinition.<area-name>
|
|
||||||
[symmetric with faOptions]
|
|
||||||
|
|
||||||
Required Classes
|
Required Classes
|
||||||
- Foam::polyMesh
|
- Foam::polyMesh
|
||||||
- Foam::IOdictionary
|
- Foam::IOdictionary
|
||||||
@ -36,185 +24,81 @@ Required Variables
|
|||||||
- runTime [Time]
|
- runTime [Time]
|
||||||
|
|
||||||
Provided Variables
|
Provided Variables
|
||||||
- faMeshDefinitionPtr [autoPtr<IOdictionary>]
|
- meshDefDict [IOdictionary]
|
||||||
|
- meshDictPtr [autoPtr<IOdictionary>]
|
||||||
If the dictionary cannot be found, exits with an error message or
|
|
||||||
reports a warning (dry-run mode)
|
|
||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
const word dictName("faMeshDefinition");
|
const word dictName("faMeshDefinition");
|
||||||
|
|
||||||
autoPtr<IOdictionary> faMeshDefinitionPtr;
|
autoPtr<IOdictionary> meshDictPtr;
|
||||||
|
|
||||||
{
|
{
|
||||||
// Exit unless dry-run?
|
fileName dictPath;
|
||||||
const bool exitOnFailure = (!args.dryRun());
|
const word& regionDir = Foam::polyMesh::regionName(regionName);
|
||||||
|
const word& areaRegionDir = Foam::polyMesh::regionName(areaRegionName);
|
||||||
|
|
||||||
const word& regionDir = polyMesh::regionName(regionName);
|
if (args.readIfPresent("dict", dictPath))
|
||||||
const word& areaRegionDir = polyMesh::regionName(areaRegionName);
|
|
||||||
|
|
||||||
// Canonical location
|
|
||||||
fileName dictPath
|
|
||||||
(
|
|
||||||
runTime.system()/regionDir
|
|
||||||
/ faMesh::prefix()/areaRegionDir/dictName
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
// Dictionary specified on the command-line ...
|
|
||||||
const bool specified = args.readIfPresent("dict", dictPath);
|
|
||||||
|
|
||||||
if (specified)
|
|
||||||
{
|
{
|
||||||
|
// Dictionary specified on the command-line ...
|
||||||
|
|
||||||
if (isDir(dictPath))
|
if (isDir(dictPath))
|
||||||
{
|
{
|
||||||
dictPath /= dictName;
|
dictPath /= dictName;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if
|
||||||
|
(
|
||||||
|
// Dictionary under system/faMeshDefinition ?
|
||||||
|
// (v2312 and earlier)
|
||||||
|
|
||||||
|
areaRegionDir.empty()
|
||||||
|
&& exists
|
||||||
|
(
|
||||||
|
runTime.path()/runTime.caseSystem()
|
||||||
|
/ regionDir/faMesh::meshSubDir/dictName
|
||||||
|
)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
// Dictionary present directly in system/ (v2312 and earlier)
|
||||||
|
|
||||||
|
dictPath = runTime.system()/regionDir/dictName;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Use system/finite-area/ directory, with region qualifications
|
||||||
|
|
||||||
|
dictPath =
|
||||||
|
(
|
||||||
|
runTime.system()/regionDir
|
||||||
|
/ faMesh::prefix()/areaRegionDir/dictName
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
IOobject meshDictIO
|
IOobject meshDictIO
|
||||||
(
|
(
|
||||||
dictPath,
|
dictPath,
|
||||||
runTime,
|
runTime,
|
||||||
IOobjectOption::MUST_READ,
|
IOobject::MUST_READ,
|
||||||
IOobjectOption::NO_WRITE,
|
IOobject::NO_WRITE,
|
||||||
IOobjectOption::NO_REGISTER,
|
IOobject::NO_REGISTER,
|
||||||
true // is globalObject
|
true // is globalObject
|
||||||
);
|
);
|
||||||
|
|
||||||
refPtr<IOobject> meshDictIOPtr;
|
if (!meshDictIO.typeHeaderOk<IOdictionary>(true))
|
||||||
|
|
||||||
bool foundIOobject = meshDictIO.typeHeaderOk<IOdictionary>(true);
|
|
||||||
|
|
||||||
// For reporting any alternative locations
|
|
||||||
dictPath.clear();
|
|
||||||
|
|
||||||
if (!foundIOobject && !specified)
|
|
||||||
{
|
{
|
||||||
if (!areaRegionDir.empty())
|
FatalErrorInFunction
|
||||||
{
|
<< meshDictIO.objectPath() << nl
|
||||||
// Alternative location
|
<< exit(FatalError);
|
||||||
// - system/finite-area/faMeshDefinition.<area-name>
|
|
||||||
|
|
||||||
dictPath =
|
|
||||||
(
|
|
||||||
runTime.system()/regionDir
|
|
||||||
/ faMesh::prefix()/IOobject::groupName(dictName, areaRegionDir)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// legacy location (v2312 and earlier)
|
|
||||||
// - system/faMeshDefinition
|
|
||||||
|
|
||||||
dictPath = runTime.system()/regionDir/dictName;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!dictPath.empty())
|
|
||||||
{
|
|
||||||
auto ioptr = autoPtr<IOobject>::New
|
|
||||||
(
|
|
||||||
dictPath,
|
|
||||||
runTime,
|
|
||||||
IOobjectOption::MUST_READ,
|
|
||||||
IOobjectOption::NO_WRITE,
|
|
||||||
IOobjectOption::NO_REGISTER,
|
|
||||||
true // is globalObject
|
|
||||||
);
|
|
||||||
|
|
||||||
foundIOobject =
|
|
||||||
(
|
|
||||||
ioptr && ioptr->typeHeaderOk<IOdictionary>(true)
|
|
||||||
);
|
|
||||||
|
|
||||||
if (foundIOobject)
|
|
||||||
{
|
|
||||||
// Use if found
|
|
||||||
meshDictIOPtr = std::move(ioptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Generally retain dictPath for error messages,
|
|
||||||
// but don't mention the really old legacy location
|
|
||||||
if (areaRegionDir.empty())
|
|
||||||
{
|
|
||||||
dictPath.clear();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Alternative location or regular location?
|
Info<< "Creating faMesh from definition: "
|
||||||
if (!meshDictIOPtr)
|
<< meshDictIO.objectRelPath() << endl;
|
||||||
{
|
|
||||||
meshDictIOPtr.cref(meshDictIO);
|
|
||||||
}
|
|
||||||
const auto& io = meshDictIOPtr();
|
|
||||||
|
|
||||||
|
meshDictPtr = autoPtr<IOdictionary>::New(meshDictIO);
|
||||||
// Handle final success or failure
|
|
||||||
if (foundIOobject)
|
|
||||||
{
|
|
||||||
Info<< "----------------" << nl
|
|
||||||
<< "Using area-mesh definition";
|
|
||||||
if (!areaRegionDir.empty())
|
|
||||||
{
|
|
||||||
Info<< " [" << areaRegionName << "]";
|
|
||||||
}
|
|
||||||
|
|
||||||
Info<< nl
|
|
||||||
<< " " << io.objectRelPath() << nl << endl;
|
|
||||||
|
|
||||||
faMeshDefinitionPtr = autoPtr<IOdictionary>::New(io);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Failure
|
|
||||||
|
|
||||||
if (exitOnFailure)
|
|
||||||
{
|
|
||||||
auto& err =
|
|
||||||
FatalErrorInFunction
|
|
||||||
<< "Did not find area-mesh definition";
|
|
||||||
|
|
||||||
if (!areaRegionDir.empty())
|
|
||||||
{
|
|
||||||
err<< " [" << areaRegionName << "]";
|
|
||||||
}
|
|
||||||
|
|
||||||
err << nl
|
|
||||||
<< " " << io.objectRelPath() << nl;
|
|
||||||
|
|
||||||
if (!dictPath.empty())
|
|
||||||
{
|
|
||||||
err << " " << dictPath << nl;
|
|
||||||
}
|
|
||||||
|
|
||||||
FatalError<< exit(FatalError);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// dry-run: warning
|
|
||||||
auto& err =
|
|
||||||
Warning << nl
|
|
||||||
<< "----------------" << nl
|
|
||||||
<< "Did not find area-mesh definition";
|
|
||||||
|
|
||||||
if (!areaRegionDir.empty())
|
|
||||||
{
|
|
||||||
err << " [" << areaRegionName << "]";
|
|
||||||
}
|
|
||||||
|
|
||||||
err << nl
|
|
||||||
<< " " << io.objectRelPath() << nl;
|
|
||||||
|
|
||||||
if (!dictPath.empty())
|
|
||||||
{
|
|
||||||
err << " " << dictPath << nl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
IOdictionary& meshDefDict = *meshDictPtr;
|
||||||
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
// ************************************************************************* //
|
||||||
|
|||||||
@ -6,7 +6,7 @@
|
|||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Copyright (C) 2016-2017 Wikki Ltd
|
Copyright (C) 2016-2017 Wikki Ltd
|
||||||
Copyright (C) 2021-2025 OpenCFD Ltd.
|
Copyright (C) 2021-2023 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM.
|
This file is part of OpenFOAM.
|
||||||
@ -40,6 +40,7 @@ Original Authors
|
|||||||
|
|
||||||
#include "Time.H"
|
#include "Time.H"
|
||||||
#include "argList.H"
|
#include "argList.H"
|
||||||
|
#include "OSspecific.H"
|
||||||
#include "faMesh.H"
|
#include "faMesh.H"
|
||||||
#include "faMeshTools.H"
|
#include "faMeshTools.H"
|
||||||
#include "IOdictionary.H"
|
#include "IOdictionary.H"
|
||||||
@ -52,7 +53,6 @@ Original Authors
|
|||||||
#include "PtrListOps.H"
|
#include "PtrListOps.H"
|
||||||
#include "foamVtkLineWriter.H"
|
#include "foamVtkLineWriter.H"
|
||||||
#include "foamVtkIndPatchWriter.H"
|
#include "foamVtkIndPatchWriter.H"
|
||||||
#include "regionProperties.H"
|
|
||||||
#include "syncTools.H"
|
#include "syncTools.H"
|
||||||
#include "OBJstream.H"
|
#include "OBJstream.H"
|
||||||
|
|
||||||
@ -104,14 +104,12 @@ int main(int argc, char *argv[])
|
|||||||
);
|
);
|
||||||
|
|
||||||
#include "addRegionOption.H"
|
#include "addRegionOption.H"
|
||||||
#include "addAllFaRegionOptions.H"
|
#include "addFaRegionOption.H"
|
||||||
|
|
||||||
#include "setRootCase.H"
|
#include "setRootCase.H"
|
||||||
#include "createTime.H"
|
#include "createTime.H"
|
||||||
#include "createNamedPolyMesh.H"
|
#include "createNamedPolyMesh.H"
|
||||||
|
|
||||||
// Handle -all-area-regions, -area-regions, -area-region
|
#include "getFaRegionOption.H"
|
||||||
#include "getAllFaRegionOptions.H"
|
|
||||||
|
|
||||||
const bool doDecompose = !args.found("no-decompose");
|
const bool doDecompose = !args.found("no-decompose");
|
||||||
const bool doDecompFields = !args.found("no-fields");
|
const bool doDecompFields = !args.found("no-fields");
|
||||||
@ -125,83 +123,56 @@ int main(int argc, char *argv[])
|
|||||||
Info<< "Skip decompose of finiteArea fields" << nl;
|
Info<< "Skip decompose of finiteArea fields" << nl;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------
|
// Reading faMeshDefinition dictionary
|
||||||
|
#include "findMeshDefinitionDict.H"
|
||||||
|
|
||||||
for (const word& areaRegionName : areaRegionNames)
|
// Inject/overwrite name for optional 'empty' patch
|
||||||
|
word patchName;
|
||||||
|
if (args.readIfPresent("empty-patch", patchName))
|
||||||
{
|
{
|
||||||
// Reading faMeshDefinition dictionary
|
meshDefDict.add("emptyPatch", patchName, true);
|
||||||
#include "findMeshDefinitionDict.H"
|
}
|
||||||
|
|
||||||
if (!faMeshDefinitionPtr)
|
// Preliminary checks
|
||||||
{
|
#include "checkPatchTopology.H"
|
||||||
if (args.dryRun())
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
FatalErrorInFunction
|
|
||||||
<< "Did not find area-mesh definition"<< nl
|
|
||||||
<< exit(FatalError);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
auto& meshDefDict = (*faMeshDefinitionPtr);
|
Info << "Create areaMesh";
|
||||||
|
if (!Foam::polyMesh::regionName(areaRegionName).empty())
|
||||||
|
{
|
||||||
|
Foam::Info << ' ' << areaRegionName;
|
||||||
|
}
|
||||||
|
Info << " for polyMesh at time = " << runTime.timeName() << nl;
|
||||||
|
|
||||||
|
// Create
|
||||||
|
faMesh aMesh(areaRegionName, mesh, meshDefDict);
|
||||||
|
|
||||||
// Inject/overwrite name for optional 'empty' patch
|
// Mesh information (less verbose)
|
||||||
if (word name; args.readIfPresent("empty-patch", name))
|
faMeshTools::printMeshChecks(aMesh, 0);
|
||||||
{
|
|
||||||
meshDefDict.add("emptyPatch", name, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Preliminary checks
|
if (args.found("write-edges-obj"))
|
||||||
#include "checkPatchTopology.H"
|
{
|
||||||
|
#include "faMeshWriteEdgesOBJ.H"
|
||||||
|
}
|
||||||
|
|
||||||
Info<< "Create area-mesh";
|
if (args.found("write-vtk"))
|
||||||
if (!polyMesh::regionName(areaRegionName).empty())
|
{
|
||||||
{
|
#include "faMeshWriteVTK.H"
|
||||||
Info<< " [" << areaRegionName << "]";
|
}
|
||||||
}
|
|
||||||
Info<< " with polyMesh at time = " << runTime.timeName() << nl;
|
|
||||||
|
|
||||||
// Create
|
if (args.dryRun())
|
||||||
faMesh aMesh(areaRegionName, mesh, meshDefDict);
|
{
|
||||||
|
Info<< "\ndry-run: not writing mesh or decomposing fields\n" << nl;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// More precision (for points data)
|
||||||
|
IOstream::minPrecision(10);
|
||||||
|
|
||||||
// Mesh information (less verbose)
|
Info<< nl << "Write finite area mesh." << nl;
|
||||||
faMeshTools::printMeshChecks(aMesh, 0);
|
aMesh.write();
|
||||||
|
|
||||||
if (args.found("write-edges-obj"))
|
Info<< endl;
|
||||||
{
|
#include "decomposeFaFields.H"
|
||||||
#include "faMeshWriteEdgesOBJ.H"
|
|
||||||
}
|
|
||||||
|
|
||||||
if (args.found("write-vtk"))
|
|
||||||
{
|
|
||||||
#include "faMeshWriteVTK.H"
|
|
||||||
}
|
|
||||||
|
|
||||||
if (args.dryRun())
|
|
||||||
{
|
|
||||||
Info<< "\ndry-run: not writing mesh or decomposing fields\n" << nl;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// More precision (for points data)
|
|
||||||
IOstream::minPrecision(10);
|
|
||||||
|
|
||||||
Info<< nl << "Write finite area mesh";
|
|
||||||
if (const word& name = aMesh.regionName(); !name.empty())
|
|
||||||
{
|
|
||||||
Info<< " [" << name << "]";
|
|
||||||
}
|
|
||||||
Info<< nl;
|
|
||||||
|
|
||||||
aMesh.write();
|
|
||||||
|
|
||||||
Info<< endl;
|
|
||||||
#include "decomposeFaFields.H"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Info<< "\nEnd\n" << endl;
|
Info<< "\nEnd\n" << endl;
|
||||||
|
|||||||
@ -334,7 +334,6 @@ int main(int argc, char *argv[])
|
|||||||
);
|
);
|
||||||
|
|
||||||
#include "addAllRegionOptions.H"
|
#include "addAllRegionOptions.H"
|
||||||
#include "addAllFaRegionOptions.H"
|
|
||||||
|
|
||||||
argList::addDryRunOption
|
argList::addDryRunOption
|
||||||
(
|
(
|
||||||
@ -443,6 +442,7 @@ int main(int argc, char *argv[])
|
|||||||
bool decomposeFieldsOnly = args.found("fields");
|
bool decomposeFieldsOnly = args.found("fields");
|
||||||
bool forceOverwrite = args.found("force");
|
bool forceOverwrite = args.found("force");
|
||||||
|
|
||||||
|
|
||||||
// Set time from database
|
// Set time from database
|
||||||
#include "createTime.H"
|
#include "createTime.H"
|
||||||
|
|
||||||
@ -491,17 +491,9 @@ int main(int argc, char *argv[])
|
|||||||
decompDictFile = runTime.globalPath()/decompDictFile;
|
decompDictFile = runTime.globalPath()/decompDictFile;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle -allRegions, -regions, -region
|
// Get region names
|
||||||
#include "getAllRegionOptions.H"
|
#include "getAllRegionOptions.H"
|
||||||
|
|
||||||
// Handle -all-area-regions, -area-regions, -area-region
|
|
||||||
#include "getAllFaRegionOptions.H"
|
|
||||||
|
|
||||||
if (!doFiniteArea)
|
|
||||||
{
|
|
||||||
areaRegionNames.clear(); // For consistency
|
|
||||||
}
|
|
||||||
|
|
||||||
const bool optRegions =
|
const bool optRegions =
|
||||||
(regionNames.size() != 1 || regionNames[0] != polyMesh::defaultRegion);
|
(regionNames.size() != 1 || regionNames[0] != polyMesh::defaultRegion);
|
||||||
|
|
||||||
@ -821,76 +813,56 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
// Field objects at this time
|
// Field objects at this time
|
||||||
IOobjectList objects;
|
IOobjectList objects;
|
||||||
|
IOobjectList faObjects;
|
||||||
// faMesh fields - can have multiple finite-area per volume
|
|
||||||
HashTable<IOobjectList> faObjects;
|
|
||||||
|
|
||||||
if (doDecompFields)
|
if (doDecompFields)
|
||||||
{
|
{
|
||||||
// List of volume mesh objects for this instance
|
// List of volume mesh objects for this instance
|
||||||
objects = IOobjectList(mesh, runTime.timeName());
|
objects = IOobjectList(mesh, runTime.timeName());
|
||||||
|
|
||||||
|
// List of area mesh objects (assuming single region)
|
||||||
|
faObjects = IOobjectList
|
||||||
|
(
|
||||||
|
mesh.time(),
|
||||||
|
runTime.timeName(),
|
||||||
|
faMesh::dbDir(mesh, word::null),
|
||||||
|
IOobjectOption::NO_REGISTER
|
||||||
|
);
|
||||||
|
|
||||||
// Ignore generated fields: (cellDist)
|
// Ignore generated fields: (cellDist)
|
||||||
objects.remove("cellDist");
|
objects.remove("cellDist");
|
||||||
|
|
||||||
// Lists of finite-area fields
|
|
||||||
faObjects.reserve(areaRegionNames.size());
|
|
||||||
|
|
||||||
for (const word& areaName : areaRegionNames)
|
|
||||||
{
|
|
||||||
// The finite-area objects for this area region
|
|
||||||
IOobjectList objs
|
|
||||||
(
|
|
||||||
faMesh::Registry(mesh),
|
|
||||||
runTime.timeName(),
|
|
||||||
polyMesh::regionName(areaName),
|
|
||||||
IOobjectOption::NO_REGISTER
|
|
||||||
);
|
|
||||||
|
|
||||||
if (!objs.empty())
|
|
||||||
{
|
|
||||||
faObjects.emplace_set(areaName, std::move(objs));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Finite area handling
|
// Finite area handling
|
||||||
// - all area regions use the same volume decomposition
|
autoPtr<faMeshDecomposition> faMeshDecompPtr;
|
||||||
|
|
||||||
HashPtrTable<faMeshDecomposition> faMeshDecompHashes;
|
|
||||||
if (doFiniteArea)
|
if (doFiniteArea)
|
||||||
{
|
{
|
||||||
const word boundaryInst =
|
const word boundaryInst =
|
||||||
mesh.time().findInstance(mesh.meshDir(), "boundary");
|
mesh.time().findInstance(mesh.meshDir(), "boundary");
|
||||||
|
|
||||||
for (const word& areaName : areaRegionNames)
|
IOobject io
|
||||||
{
|
(
|
||||||
IOobject io
|
"faBoundary",
|
||||||
(
|
boundaryInst,
|
||||||
"faBoundary",
|
faMesh::meshDir(mesh, word::null),
|
||||||
boundaryInst,
|
mesh.time(),
|
||||||
faMesh::meshDir(mesh, areaName),
|
IOobject::READ_IF_PRESENT,
|
||||||
mesh.time(),
|
IOobject::NO_WRITE,
|
||||||
IOobject::READ_IF_PRESENT,
|
IOobject::NO_REGISTER
|
||||||
IOobject::NO_WRITE,
|
);
|
||||||
IOobject::NO_REGISTER
|
|
||||||
);
|
|
||||||
|
|
||||||
if (io.typeHeaderOk<faBoundaryMesh>(true))
|
if (io.typeHeaderOk<faBoundaryMesh>(true))
|
||||||
{
|
{
|
||||||
// Always based on the volume decomposition!
|
// Always based on the volume decomposition!
|
||||||
faMeshDecompHashes.set
|
faMeshDecompPtr.reset
|
||||||
|
(
|
||||||
|
new faMeshDecomposition
|
||||||
(
|
(
|
||||||
areaName,
|
mesh,
|
||||||
autoPtr<faMeshDecomposition>::New
|
mesh.nProcs(),
|
||||||
(
|
mesh.model()
|
||||||
areaName,
|
)
|
||||||
mesh,
|
);
|
||||||
mesh.nProcs(),
|
|
||||||
mesh.model()
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1094,7 +1066,7 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
processorDb.setTime(runTime);
|
processorDb.setTime(runTime);
|
||||||
|
|
||||||
// Read the mesh
|
// read the mesh
|
||||||
if (!procMeshList.set(proci))
|
if (!procMeshList.set(proci))
|
||||||
{
|
{
|
||||||
procMeshList.set
|
procMeshList.set
|
||||||
@ -1301,15 +1273,12 @@ int main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Finite-area mesh and field decomposition
|
// Finite area mesh and field decomposition
|
||||||
for (auto& iter : faMeshDecompHashes.sorted())
|
if (faMeshDecompPtr)
|
||||||
{
|
{
|
||||||
const word& areaName = iter.key();
|
Info<< "\nFinite area mesh decomposition" << endl;
|
||||||
|
|
||||||
faMeshDecomposition& aMesh = *(iter.val());
|
faMeshDecomposition& aMesh = faMeshDecompPtr();
|
||||||
|
|
||||||
Info<< "\nFinite area mesh decomposition: "
|
|
||||||
<< areaName << endl;
|
|
||||||
|
|
||||||
aMesh.decomposeMesh();
|
aMesh.decomposeMesh();
|
||||||
aMesh.writeDecomposition();
|
aMesh.writeDecomposition();
|
||||||
@ -1320,13 +1289,9 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
faFieldDecomposer::fieldsCache areaFieldCache;
|
faFieldDecomposer::fieldsCache areaFieldCache;
|
||||||
|
|
||||||
if
|
if (doDecompFields)
|
||||||
(
|
|
||||||
const auto objs = faObjects.cfind(areaName);
|
|
||||||
doDecompFields && objs.good()
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
areaFieldCache.readAllFields(aMesh, objs.val());
|
areaFieldCache.readAllFields(aMesh, faObjects);
|
||||||
}
|
}
|
||||||
|
|
||||||
const label nAreaFields = areaFieldCache.size();
|
const label nAreaFields = areaFieldCache.size();
|
||||||
@ -1357,7 +1322,7 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
processorDb.setTime(runTime);
|
processorDb.setTime(runTime);
|
||||||
|
|
||||||
// Read the volume mesh
|
// Read the mesh
|
||||||
fvMesh procFvMesh
|
fvMesh procFvMesh
|
||||||
(
|
(
|
||||||
IOobject
|
IOobject
|
||||||
@ -1368,7 +1333,7 @@ int main(int argc, char *argv[])
|
|||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
faMesh procMesh(areaName, procFvMesh);
|
faMesh procMesh(procFvMesh);
|
||||||
|
|
||||||
// // Does not work. HJ, 15/Aug/2017
|
// // Does not work. HJ, 15/Aug/2017
|
||||||
// const labelIOList& faceProcAddressing =
|
// const labelIOList& faceProcAddressing =
|
||||||
@ -1427,11 +1392,7 @@ int main(int argc, char *argv[])
|
|||||||
boundaryProcAddressing
|
boundaryProcAddressing
|
||||||
);
|
);
|
||||||
|
|
||||||
areaFieldCache.decomposeAllFields
|
areaFieldCache.decomposeAllFields(fieldDecomposer);
|
||||||
(
|
|
||||||
fieldDecomposer,
|
|
||||||
args.verbose() // report
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -6,7 +6,7 @@
|
|||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Copyright (C) 2011-2017 OpenFOAM Foundation
|
Copyright (C) 2011-2017 OpenFOAM Foundation
|
||||||
Copyright (C) 2015-2025 OpenCFD Ltd.
|
Copyright (C) 2015-2023 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM.
|
This file is part of OpenFOAM.
|
||||||
@ -91,7 +91,6 @@ int main(int argc, char *argv[])
|
|||||||
argList::noParallel();
|
argList::noParallel();
|
||||||
|
|
||||||
#include "addAllRegionOptions.H"
|
#include "addAllRegionOptions.H"
|
||||||
#include "addAllFaRegionOptions.H"
|
|
||||||
|
|
||||||
argList::addVerboseOption();
|
argList::addVerboseOption();
|
||||||
argList::addOption
|
argList::addOption
|
||||||
@ -202,17 +201,9 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
const bool newTimes = args.found("newTimes");
|
const bool newTimes = args.found("newTimes");
|
||||||
|
|
||||||
// Handle -allRegions, -regions, -region
|
// Get region names
|
||||||
#include "getAllRegionOptions.H"
|
#include "getAllRegionOptions.H"
|
||||||
|
|
||||||
// Handle -all-area-regions, -area-regions, -area-region
|
|
||||||
#include "getAllFaRegionOptions.H"
|
|
||||||
|
|
||||||
if (!doFiniteArea)
|
|
||||||
{
|
|
||||||
areaRegionNames.clear(); // For consistency
|
|
||||||
}
|
|
||||||
|
|
||||||
// Determine the processor count
|
// Determine the processor count
|
||||||
label nProcs{0};
|
label nProcs{0};
|
||||||
|
|
||||||
@ -400,30 +391,19 @@ int main(int argc, char *argv[])
|
|||||||
IOobjectOption::NO_REGISTER
|
IOobjectOption::NO_REGISTER
|
||||||
);
|
);
|
||||||
|
|
||||||
// The finite-area fields (multiple finite-area per volume)
|
IOobjectList faObjects;
|
||||||
HashTable<IOobjectList> faObjects;
|
|
||||||
|
|
||||||
if (doFiniteArea && doFields)
|
if (doFiniteArea && doFields)
|
||||||
{
|
{
|
||||||
// Lists of finite-area fields - scan on processor0
|
// List of area mesh objects (assuming single region)
|
||||||
faObjects.reserve(areaRegionNames.size());
|
// - scan on processor0
|
||||||
|
faObjects = IOobjectList
|
||||||
for (const word& areaName : areaRegionNames)
|
(
|
||||||
{
|
procMeshes.meshes()[0],
|
||||||
// The finite-area objects for this area region
|
databases[0].timeName(),
|
||||||
IOobjectList objs
|
faMesh::dbDir(word::null), // local relative to mesh
|
||||||
(
|
IOobjectOption::NO_REGISTER
|
||||||
procMeshes.meshes()[0],
|
);
|
||||||
databases[0].timeName(),
|
|
||||||
faMesh::dbDir(areaName), // local relative to mesh
|
|
||||||
IOobjectOption::NO_REGISTER
|
|
||||||
);
|
|
||||||
|
|
||||||
if (!objs.empty())
|
|
||||||
{
|
|
||||||
faObjects.emplace_set(areaName, std::move(objs));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (doFields)
|
if (doFields)
|
||||||
@ -573,60 +553,42 @@ int main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Reconstruct any finite-area fields
|
// If there are any FA fields, reconstruct them
|
||||||
if (doFiniteArea)
|
|
||||||
|
if (!doFiniteArea)
|
||||||
{
|
{
|
||||||
bool hadFaFields = false;
|
|
||||||
for (const word& areaName : areaRegionNames)
|
|
||||||
{
|
|
||||||
const auto objs = faObjects.cfind(areaName);
|
|
||||||
if (!objs.good())
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
const auto& faObjs = objs.val();
|
|
||||||
|
|
||||||
if
|
|
||||||
(
|
|
||||||
!faObjs.count(fieldTypes::is_area)
|
|
||||||
&& !faObjs.count<edgeScalarField>()
|
|
||||||
)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
hadFaFields = true;
|
|
||||||
|
|
||||||
Info<< "Reconstructing finite-area fields ["
|
|
||||||
<< polyMesh::regionName(areaName)
|
|
||||||
<< "]" << nl << endl;
|
|
||||||
|
|
||||||
const faMesh aMesh(areaName, mesh);
|
|
||||||
|
|
||||||
processorFaMeshes procFaMeshes
|
|
||||||
(
|
|
||||||
procMeshes.meshes(),
|
|
||||||
areaName
|
|
||||||
);
|
|
||||||
|
|
||||||
faFieldReconstructor reconstructor
|
|
||||||
(
|
|
||||||
aMesh,
|
|
||||||
procFaMeshes.meshes(),
|
|
||||||
procFaMeshes.edgeProcAddressing(),
|
|
||||||
procFaMeshes.faceProcAddressing(),
|
|
||||||
procFaMeshes.boundaryProcAddressing()
|
|
||||||
);
|
|
||||||
|
|
||||||
reconstructor.reconstructAllFields(faObjs);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!hadFaFields)
|
|
||||||
{
|
|
||||||
Info << "No finite-area fields" << nl << endl;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
else if
|
||||||
|
(
|
||||||
|
faObjects.count<areaScalarField>()
|
||||||
|
|| faObjects.count<areaVectorField>()
|
||||||
|
|| faObjects.count<areaSphericalTensorField>()
|
||||||
|
|| faObjects.count<areaSymmTensorField>()
|
||||||
|
|| faObjects.count<areaTensorField>()
|
||||||
|
|| faObjects.count<edgeScalarField>()
|
||||||
|
)
|
||||||
|
{
|
||||||
|
Info << "Reconstructing FA fields" << nl << endl;
|
||||||
|
|
||||||
|
faMesh aMesh(mesh);
|
||||||
|
|
||||||
|
processorFaMeshes procFaMeshes(procMeshes.meshes());
|
||||||
|
|
||||||
|
faFieldReconstructor reconstructor
|
||||||
|
(
|
||||||
|
aMesh,
|
||||||
|
procFaMeshes.meshes(),
|
||||||
|
procFaMeshes.edgeProcAddressing(),
|
||||||
|
procFaMeshes.faceProcAddressing(),
|
||||||
|
procFaMeshes.boundaryProcAddressing()
|
||||||
|
);
|
||||||
|
|
||||||
|
reconstructor.reconstructAllFields(faObjects);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Info << "No FA fields" << nl << endl;
|
||||||
|
}
|
||||||
|
|
||||||
if (doReconstructSets)
|
if (doReconstructSets)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -119,10 +119,17 @@ autoPtr<faceCoupleInfo> determineCoupledFaces
|
|||||||
const polyBoundaryMesh& masterPatches = masterMesh.boundaryMesh();
|
const polyBoundaryMesh& masterPatches = masterMesh.boundaryMesh();
|
||||||
|
|
||||||
|
|
||||||
DynamicList<label> masterFaces(masterMesh.nBoundaryFaces());
|
DynamicList<label> masterFaces
|
||||||
|
(
|
||||||
|
masterMesh.nFaces()
|
||||||
|
- masterMesh.nInternalFaces()
|
||||||
|
);
|
||||||
|
|
||||||
for (const polyPatch& pp : masterPatches)
|
|
||||||
|
forAll(masterPatches, patchi)
|
||||||
{
|
{
|
||||||
|
const polyPatch& pp = masterPatches[patchi];
|
||||||
|
|
||||||
if (isA<processorPolyPatch>(pp))
|
if (isA<processorPolyPatch>(pp))
|
||||||
{
|
{
|
||||||
for
|
for
|
||||||
@ -132,8 +139,11 @@ autoPtr<faceCoupleInfo> determineCoupledFaces
|
|||||||
proci++
|
proci++
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
const string toProcString("to" + Foam::name(proci));
|
const string toProcString("to" + name(proci));
|
||||||
if (pp.name().ends_with(toProcString))
|
if (
|
||||||
|
pp.name().rfind(toProcString)
|
||||||
|
== (pp.name().size()-toProcString.size())
|
||||||
|
)
|
||||||
{
|
{
|
||||||
label meshFacei = pp.start();
|
label meshFacei = pp.start();
|
||||||
forAll(pp, i)
|
forAll(pp, i)
|
||||||
@ -146,6 +156,7 @@ autoPtr<faceCoupleInfo> determineCoupledFaces
|
|||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
masterFaces.shrink();
|
||||||
|
|
||||||
|
|
||||||
// Pick up all patches on meshToAdd ending in "procBoundaryDDDtoYYY"
|
// Pick up all patches on meshToAdd ending in "procBoundaryDDDtoYYY"
|
||||||
@ -153,10 +164,16 @@ autoPtr<faceCoupleInfo> determineCoupledFaces
|
|||||||
|
|
||||||
const polyBoundaryMesh& addPatches = meshToAdd.boundaryMesh();
|
const polyBoundaryMesh& addPatches = meshToAdd.boundaryMesh();
|
||||||
|
|
||||||
DynamicList<label> addFaces(meshToAdd.nBoundaryFaces());
|
DynamicList<label> addFaces
|
||||||
|
(
|
||||||
|
meshToAdd.nFaces()
|
||||||
|
- meshToAdd.nInternalFaces()
|
||||||
|
);
|
||||||
|
|
||||||
for (const polyPatch& pp : addPatches)
|
forAll(addPatches, patchi)
|
||||||
{
|
{
|
||||||
|
const polyPatch& pp = addPatches[patchi];
|
||||||
|
|
||||||
if (isA<processorPolyPatch>(pp))
|
if (isA<processorPolyPatch>(pp))
|
||||||
{
|
{
|
||||||
bool isConnected = false;
|
bool isConnected = false;
|
||||||
@ -198,6 +215,7 @@ autoPtr<faceCoupleInfo> determineCoupledFaces
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
addFaces.shrink();
|
||||||
|
|
||||||
return autoPtr<faceCoupleInfo>::New
|
return autoPtr<faceCoupleInfo>::New
|
||||||
(
|
(
|
||||||
@ -484,14 +502,15 @@ void writeMaps
|
|||||||
|
|
||||||
Info<< " pointProcAddressing" << endl;
|
Info<< " pointProcAddressing" << endl;
|
||||||
ioAddr.rename("pointProcAddressing");
|
ioAddr.rename("pointProcAddressing");
|
||||||
labelIOList::writeContents(ioAddr, pointProcAddressing);
|
IOList<label>::writeContents(ioAddr, pointProcAddressing);
|
||||||
|
|
||||||
// From processor face to reconstructed mesh face
|
// From processor face to reconstructed mesh face
|
||||||
// - add turning index to faceProcAddressing.
|
Info<< " faceProcAddressing" << endl;
|
||||||
// See reconstructPar for meaning of turning index.
|
ioAddr.rename("faceProcAddressing");
|
||||||
|
labelIOList faceProcAddr(ioAddr, faceProcAddressing);
|
||||||
labelList faceProcAddr(faceProcAddressing);
|
|
||||||
|
|
||||||
|
// Now add turning index to faceProcAddressing.
|
||||||
|
// See reconstructPar for meaning of turning index.
|
||||||
forAll(faceProcAddr, procFacei)
|
forAll(faceProcAddr, procFacei)
|
||||||
{
|
{
|
||||||
const label masterFacei = faceProcAddr[procFacei];
|
const label masterFacei = faceProcAddr[procFacei];
|
||||||
@ -526,21 +545,19 @@ void writeMaps
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Info<< " faceProcAddressing" << endl;
|
faceProcAddr.write();
|
||||||
ioAddr.rename("faceProcAddressing");
|
|
||||||
labelIOList::writeContents(ioAddr, faceProcAddr);
|
|
||||||
faceProcAddr.clear();
|
|
||||||
|
|
||||||
// From processor cell to reconstructed mesh cell
|
// From processor cell to reconstructed mesh cell
|
||||||
Info<< " cellProcAddressing" << endl;
|
Info<< " cellProcAddressing" << endl;
|
||||||
ioAddr.rename("cellProcAddressing");
|
ioAddr.rename("cellProcAddressing");
|
||||||
labelIOList::writeContents(ioAddr, cellProcAddressing);
|
IOList<label>::writeContents(ioAddr, cellProcAddressing);
|
||||||
|
|
||||||
|
|
||||||
// From processor patch to reconstructed mesh patch
|
// From processor patch to reconstructed mesh patch
|
||||||
Info<< " boundaryProcAddressing" << endl;
|
Info<< " boundaryProcAddressing" << endl;
|
||||||
ioAddr.rename("boundaryProcAddressing");
|
ioAddr.rename("boundaryProcAddressing");
|
||||||
labelIOList::writeContents(ioAddr, boundProcAddressing);
|
IOList<label>::writeContents(ioAddr, boundProcAddressing);
|
||||||
|
|
||||||
Info<< endl;
|
Info<< endl;
|
||||||
}
|
}
|
||||||
@ -628,8 +645,7 @@ void sortFaEdgeMapping
|
|||||||
{
|
{
|
||||||
// From faMeshReconstructor.C - edge shuffling on patches
|
// From faMeshReconstructor.C - edge shuffling on patches
|
||||||
|
|
||||||
Map<label> remapGlobal;
|
Map<label> remapGlobal(2*onePatch.nEdges());
|
||||||
remapGlobal.reserve(onePatch.nEdges());
|
|
||||||
for (label edgei = 0; edgei < onePatch.nInternalEdges(); ++edgei)
|
for (label edgei = 0; edgei < onePatch.nInternalEdges(); ++edgei)
|
||||||
{
|
{
|
||||||
remapGlobal.insert(edgei, remapGlobal.size());
|
remapGlobal.insert(edgei, remapGlobal.size());
|
||||||
@ -763,11 +779,6 @@ int main(int argc, char *argv[])
|
|||||||
);
|
);
|
||||||
|
|
||||||
#include "addAllRegionOptions.H"
|
#include "addAllRegionOptions.H"
|
||||||
#include "addAllFaRegionOptions.H"
|
|
||||||
|
|
||||||
// Prevent volume fields [with regionFaModels] from incidental
|
|
||||||
// triggering finite-area
|
|
||||||
regionModels::allowFaModels(false);
|
|
||||||
|
|
||||||
// Prevent volume BCs from triggering finite-area
|
// Prevent volume BCs from triggering finite-area
|
||||||
regionModels::allowFaModels(false);
|
regionModels::allowFaModels(false);
|
||||||
@ -830,17 +841,9 @@ int main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle -allRegions, -regions, -region
|
// Get region names
|
||||||
#include "getAllRegionOptions.H"
|
#include "getAllRegionOptions.H"
|
||||||
|
|
||||||
// Handle -all-area-regions, -area-regions, -area-region
|
|
||||||
#include "getAllFaRegionOptions.H"
|
|
||||||
|
|
||||||
if (!doFiniteArea)
|
|
||||||
{
|
|
||||||
areaRegionNames.clear(); // For consistency
|
|
||||||
}
|
|
||||||
|
|
||||||
// Determine the processor count
|
// Determine the processor count
|
||||||
label nProcs{0};
|
label nProcs{0};
|
||||||
|
|
||||||
@ -932,8 +935,7 @@ int main(int argc, char *argv[])
|
|||||||
polyMesh::meshDir(regionName),
|
polyMesh::meshDir(regionName),
|
||||||
databases[0],
|
databases[0],
|
||||||
IOobject::NO_READ,
|
IOobject::NO_READ,
|
||||||
IOobject::NO_WRITE,
|
IOobject::NO_WRITE
|
||||||
IOobject::NO_REGISTER
|
|
||||||
);
|
);
|
||||||
|
|
||||||
// Problem: faceCompactIOList recognises both 'faceList' and
|
// Problem: faceCompactIOList recognises both 'faceList' and
|
||||||
@ -1403,12 +1405,8 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
|
|
||||||
// Read finite-area
|
// Read finite-area
|
||||||
// For each named area region that exists create a HashTable
|
PtrList<faMesh> procFaMeshes(databases.size());
|
||||||
// entry that will contain the PtrList for all processors
|
|
||||||
|
|
||||||
PtrList<polyMesh> procMeshes(databases.size());
|
PtrList<polyMesh> procMeshes(databases.size());
|
||||||
HashTable<PtrList<faMesh>> procAreaRegionMeshes;
|
|
||||||
procAreaRegionMeshes.reserve(areaRegionNames.size());
|
|
||||||
|
|
||||||
forAll(databases, proci)
|
forAll(databases, proci)
|
||||||
{
|
{
|
||||||
@ -1416,16 +1414,20 @@ int main(int argc, char *argv[])
|
|||||||
<< "Read processor mesh: "
|
<< "Read processor mesh: "
|
||||||
<< (databases[proci].caseName()/regionDir) << endl;
|
<< (databases[proci].caseName()/regionDir) << endl;
|
||||||
|
|
||||||
const polyMesh& procMesh = procMeshes.emplace
|
procMeshes.set
|
||||||
(
|
(
|
||||||
proci,
|
proci,
|
||||||
IOobject
|
new polyMesh
|
||||||
(
|
(
|
||||||
regionName,
|
IOobject
|
||||||
databases[proci].timeName(),
|
(
|
||||||
databases[proci]
|
regionName,
|
||||||
|
databases[proci].timeName(),
|
||||||
|
databases[proci]
|
||||||
|
)
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
const polyMesh& procMesh = procMeshes[proci];
|
||||||
|
|
||||||
writeMaps
|
writeMaps
|
||||||
(
|
(
|
||||||
@ -1448,67 +1450,38 @@ int main(int argc, char *argv[])
|
|||||||
"boundary"
|
"boundary"
|
||||||
);
|
);
|
||||||
|
|
||||||
for (const word& areaName : areaRegionNames)
|
IOobject io
|
||||||
|
(
|
||||||
|
"faBoundary",
|
||||||
|
boundaryInst,
|
||||||
|
faMesh::meshDir(procMesh, word::null),
|
||||||
|
procMesh.time(),
|
||||||
|
IOobject::READ_IF_PRESENT,
|
||||||
|
IOobject::NO_WRITE,
|
||||||
|
IOobject::NO_REGISTER
|
||||||
|
);
|
||||||
|
|
||||||
|
if (io.typeHeaderOk<faBoundaryMesh>(true))
|
||||||
{
|
{
|
||||||
IOobject io
|
// Always based on the volume decomposition!
|
||||||
(
|
procFaMeshes.set(proci, new faMesh(procMesh));
|
||||||
"faBoundary",
|
|
||||||
boundaryInst,
|
|
||||||
faMesh::meshDir(procMesh, areaName),
|
|
||||||
procMesh.time(),
|
|
||||||
IOobject::READ_IF_PRESENT,
|
|
||||||
IOobject::NO_WRITE,
|
|
||||||
IOobject::NO_REGISTER
|
|
||||||
);
|
|
||||||
|
|
||||||
if (io.typeHeaderOk<faBoundaryMesh>(true))
|
|
||||||
{
|
|
||||||
// Always based on the volume decomposition!
|
|
||||||
auto& procFaMeshes = procAreaRegionMeshes(areaName);
|
|
||||||
procFaMeshes.resize(databases.size());
|
|
||||||
|
|
||||||
procFaMeshes.set
|
|
||||||
(
|
|
||||||
proci,
|
|
||||||
new faMesh(areaName, procMesh)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// A finite-area mapping exists if procFaMeshes was filled
|
// Finite-area mapping
|
||||||
|
doFiniteArea = false;
|
||||||
// Re-read reconstructed polyMesh. Note: could probably be avoided
|
forAll(procFaMeshes, proci)
|
||||||
// by merging into loops above.
|
|
||||||
refPtr<polyMesh> masterPolyMeshPtr;
|
|
||||||
|
|
||||||
if (!procAreaRegionMeshes.empty())
|
|
||||||
{
|
{
|
||||||
masterPolyMeshPtr.reset
|
if (procFaMeshes.set(proci))
|
||||||
(
|
{
|
||||||
new polyMesh
|
doFiniteArea = true;
|
||||||
(
|
}
|
||||||
IOobject
|
|
||||||
(
|
|
||||||
regionName,
|
|
||||||
runTime.timeName(),
|
|
||||||
runTime
|
|
||||||
),
|
|
||||||
true
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Process any finite-area meshes
|
if (doFiniteArea)
|
||||||
for (const auto& iter : procAreaRegionMeshes.csorted())
|
|
||||||
{
|
{
|
||||||
const auto& areaName = iter.key();
|
|
||||||
const auto& procFaMeshes = iter.val();
|
|
||||||
|
|
||||||
const polyMesh& masterMesh = masterPolyMeshPtr();
|
|
||||||
|
|
||||||
// Addressing from processor to reconstructed case
|
// Addressing from processor to reconstructed case
|
||||||
labelListList faFaceProcAddressing(nProcs);
|
labelListList faFaceProcAddressing(nProcs);
|
||||||
labelListList faEdgeProcAddressing(nProcs);
|
labelListList faEdgeProcAddressing(nProcs);
|
||||||
@ -1526,10 +1499,32 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
faBoundProcAddressing[proci] = identity(bm.size());
|
faBoundProcAddressing[proci] = identity(bm.size());
|
||||||
// Mark processor patches
|
// Mark processor patches
|
||||||
faBoundProcAddressing[proci].slice(bm.nNonProcessor()) = -1;
|
for
|
||||||
|
(
|
||||||
|
label patchi = bm.nNonProcessor();
|
||||||
|
patchi < bm.size();
|
||||||
|
++patchi
|
||||||
|
)
|
||||||
|
{
|
||||||
|
faBoundProcAddressing[proci][patchi] = -1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Re-read reconstructed polyMesh. Note: could probably be avoided
|
||||||
|
// by merging into loops above.
|
||||||
|
const polyMesh masterMesh
|
||||||
|
(
|
||||||
|
IOobject
|
||||||
|
(
|
||||||
|
regionName,
|
||||||
|
runTime.timeName(),
|
||||||
|
runTime
|
||||||
|
),
|
||||||
|
true
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
// faceProcAddressing
|
// faceProcAddressing
|
||||||
// ~~~~~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
@ -1564,13 +1559,13 @@ int main(int argc, char *argv[])
|
|||||||
// Construct without patches
|
// Construct without patches
|
||||||
faMesh masterFaMesh
|
faMesh masterFaMesh
|
||||||
(
|
(
|
||||||
areaName,
|
|
||||||
masterMesh,
|
masterMesh,
|
||||||
std::move(masterFaceLabels),
|
std::move(masterFaceLabels),
|
||||||
io
|
io
|
||||||
);
|
);
|
||||||
|
|
||||||
const auto& masterPatch = masterFaMesh.patch();
|
const uindirectPrimitivePatch& masterPatch =
|
||||||
|
masterFaMesh.patch();
|
||||||
|
|
||||||
|
|
||||||
// pointProcAddressing
|
// pointProcAddressing
|
||||||
@ -1582,7 +1577,7 @@ int main(int argc, char *argv[])
|
|||||||
const auto& procPatch = procFaMeshes[proci].patch();
|
const auto& procPatch = procFaMeshes[proci].patch();
|
||||||
const auto& mp = procPatch.meshPoints();
|
const auto& mp = procPatch.meshPoints();
|
||||||
|
|
||||||
auto& pointAddr = faPointProcAddressing[proci];
|
labelList& pointAddr = faPointProcAddressing[proci];
|
||||||
pointAddr.resize_nocopy(mp.size());
|
pointAddr.resize_nocopy(mp.size());
|
||||||
|
|
||||||
forAll(mp, i)
|
forAll(mp, i)
|
||||||
@ -1631,7 +1626,8 @@ int main(int argc, char *argv[])
|
|||||||
label nPatches = 0;
|
label nPatches = 0;
|
||||||
forAll(completePatches, patchi)
|
forAll(completePatches, patchi)
|
||||||
{
|
{
|
||||||
const auto& patchEdgeLabels = singlePatchEdgeLabels[patchi];
|
const labelList& patchEdgeLabels =
|
||||||
|
singlePatchEdgeLabels[patchi];
|
||||||
|
|
||||||
const faPatch& fap = procMesh0.boundary()[patchi];
|
const faPatch& fap = procMesh0.boundary()[patchi];
|
||||||
|
|
||||||
@ -1662,11 +1658,11 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
// Serial mesh - no parallel communication
|
// Serial mesh - no parallel communication
|
||||||
|
|
||||||
const bool oldParRun = UPstream::parRun(false);
|
const bool oldParRun = Pstream::parRun(false);
|
||||||
|
|
||||||
masterFaMesh.addFaPatches(completePatches);
|
masterFaMesh.addFaPatches(completePatches);
|
||||||
|
|
||||||
UPstream::parRun(oldParRun); // Restore parallel state
|
Pstream::parRun(oldParRun); // Restore parallel state
|
||||||
|
|
||||||
|
|
||||||
// Write mesh & individual addressing
|
// Write mesh & individual addressing
|
||||||
|
|||||||
@ -33,266 +33,99 @@ License
|
|||||||
#include "decomposedBlockData.H"
|
#include "decomposedBlockData.H"
|
||||||
#include "IFstream.H"
|
#include "IFstream.H"
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * Global Functions * * * * * * * * * * * * * //
|
||||||
|
|
||||||
// Trimmed-down version of lookupAndCacheProcessorsPath
|
bool Foam::checkFileExistence(const fileName& fName)
|
||||||
// with Foam::exists() check. No caching.
|
|
||||||
|
|
||||||
// Check for two conditions:
|
|
||||||
// - file has to exist
|
|
||||||
// - if collated the entry has to exist inside the file
|
|
||||||
|
|
||||||
// Note: bypass fileOperation::filePath(IOobject&) since has problems
|
|
||||||
// with going to a different number of processors
|
|
||||||
// (in collated format). Use file-based searching instead
|
|
||||||
|
|
||||||
namespace Foam
|
|
||||||
{
|
{
|
||||||
|
// Trimmed-down version of lookupAndCacheProcessorsPath
|
||||||
|
// with Foam::exists() check. No caching.
|
||||||
|
|
||||||
// If indeed collated format:
|
// Check for two conditions:
|
||||||
// Collect block-number in individual filenames
|
// - file has to exist
|
||||||
// (might differ on different processors)
|
// - if collated the entry has to exist inside the file
|
||||||
static bool checkFileExistenceCollated
|
|
||||||
(
|
// Note: bypass fileOperation::filePath(IOobject&) since has problems
|
||||||
const Foam::fileOperation& handler,
|
// with going to a different number of processors
|
||||||
const Foam::fileName& fName
|
// (in collated format). Use file-based searching instead
|
||||||
)
|
|
||||||
{
|
const auto& handler = Foam::fileHandler();
|
||||||
// using namespace Foam;
|
typedef fileOperation::procRangeType procRangeType;
|
||||||
|
|
||||||
|
fileName path, pDir, local;
|
||||||
|
procRangeType group;
|
||||||
|
label numProcs;
|
||||||
|
const label proci =
|
||||||
|
fileOperation::splitProcessorPath
|
||||||
|
(fName, path, pDir, local, group, numProcs);
|
||||||
|
|
||||||
bool found = false;
|
bool found = false;
|
||||||
|
|
||||||
|
if (proci != -1)
|
||||||
{
|
{
|
||||||
const label handlerComm = handler.comm();
|
// Read all directories to see any beginning with processor
|
||||||
|
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
const label globalProci = UPstream::myProcNo(UPstream::worldComm);
|
const fileNameList dirEntries
|
||||||
const label handlerProci = UPstream::myProcNo(handlerComm);
|
|
||||||
const label nHandlerProcs = UPstream::nProcs(handlerComm);
|
|
||||||
|
|
||||||
// Determine my local block number
|
|
||||||
label myBlockNumber = -1;
|
|
||||||
{
|
|
||||||
fileOperation::procRangeType group;
|
|
||||||
label proci = fileOperation::detectProcessorPath(fName, group);
|
|
||||||
|
|
||||||
if (proci == -1 && group.empty())
|
|
||||||
{
|
|
||||||
// 'processorsXXX' format so contains all ranks
|
|
||||||
// according to worldComm
|
|
||||||
myBlockNumber = globalProci;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// 'processorsXXX_n-m' format so check for relative rank
|
|
||||||
myBlockNumber = handlerProci;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Since we are streaming anyhow, could also pack as tuple:
|
|
||||||
// Tuple2<fileName, label>
|
|
||||||
|
|
||||||
|
|
||||||
// Collect file names on master of local communicator
|
|
||||||
const fileNameList fNames
|
|
||||||
(
|
(
|
||||||
Pstream::listGatherValues
|
handler.readDir(path, fileName::Type::DIRECTORY)
|
||||||
(
|
|
||||||
fName,
|
|
||||||
handlerComm,
|
|
||||||
UPstream::msgType()
|
|
||||||
)
|
|
||||||
);
|
);
|
||||||
|
|
||||||
// Collect block numbers on master of local communicator
|
// Extract info from processorN or processorsNN
|
||||||
const labelList myBlockNumbers
|
// - highest processor number
|
||||||
(
|
// - directory+offset containing data for proci
|
||||||
Pstream::listGatherValues
|
|
||||||
(
|
|
||||||
myBlockNumber,
|
|
||||||
handlerComm,
|
|
||||||
UPstream::msgType()
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
// Determine for all whether the filename exists in the collated file.
|
// label nProcs = 0;
|
||||||
boolList allFound;
|
for (const fileName& dirN : dirEntries)
|
||||||
|
|
||||||
if (UPstream::master(handlerComm))
|
|
||||||
{
|
{
|
||||||
allFound.resize(nHandlerProcs, false);
|
// Analyse directory name
|
||||||
|
label rNum(-1);
|
||||||
|
const label readProci =
|
||||||
|
fileOperation::detectProcessorPath(dirN, group, &rNum);
|
||||||
|
|
||||||
// Store nBlocks and index of file that was used for nBlocks
|
if (proci == readProci)
|
||||||
label nBlocks = -1;
|
|
||||||
label blockRanki = -1;
|
|
||||||
forAll(fNames, ranki)
|
|
||||||
{
|
{
|
||||||
if
|
// Found "processorN"
|
||||||
(
|
if (Foam::exists(path/dirN/local))
|
||||||
blockRanki == -1
|
|
||||||
|| (fNames[ranki] != fNames[blockRanki])
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
blockRanki = ranki;
|
found = true;
|
||||||
IFstream is(fNames[ranki]);
|
break;
|
||||||
nBlocks = decomposedBlockData::getNumBlocks(is);
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
else if (rNum != -1)
|
||||||
|
{
|
||||||
|
// "processorsNN" or "processorsNN_start-end"
|
||||||
|
if (group.empty())
|
||||||
|
{
|
||||||
|
// "processorsNN"
|
||||||
|
if (proci < rNum && Foam::exists(path/dirN/local))
|
||||||
|
{
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (group.contains(proci))
|
||||||
|
{
|
||||||
|
// "processorsNN_start-end"
|
||||||
|
// - save the local proc offset
|
||||||
|
|
||||||
allFound[ranki] = (myBlockNumbers[ranki] < nBlocks);
|
if (Foam::exists(path/dirN/local))
|
||||||
|
{
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Scatter using the handler communicator
|
if (!found)
|
||||||
found = Pstream::listScatterValues
|
{
|
||||||
(
|
found = Foam::exists(fName);
|
||||||
allFound,
|
|
||||||
handlerComm,
|
|
||||||
UPstream::msgType()
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return found;
|
return found;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // End namespace
|
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * Global Functions * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
Foam::bitSet Foam::haveProcessorFile
|
|
||||||
(
|
|
||||||
const word& name, // eg "faces"
|
|
||||||
const fileName& instance, // eg "constant"
|
|
||||||
const fileName& local, // eg, polyMesh
|
|
||||||
const Time& runTime,
|
|
||||||
const bool verbose
|
|
||||||
)
|
|
||||||
{
|
|
||||||
const auto& handler = Foam::fileHandler();
|
|
||||||
|
|
||||||
const fileName fName
|
|
||||||
(
|
|
||||||
handler.filePath(runTime.path()/instance/local/name)
|
|
||||||
);
|
|
||||||
|
|
||||||
bool found = handler.isFile(fName);
|
|
||||||
|
|
||||||
// Assume non-collated (as fallback value).
|
|
||||||
// If everyone claims to have the file, use master to verify if
|
|
||||||
// collated is involved.
|
|
||||||
|
|
||||||
bool isCollated = false;
|
|
||||||
|
|
||||||
if (returnReduceAnd(found, UPstream::worldComm))
|
|
||||||
{
|
|
||||||
// Test for collated format.
|
|
||||||
// Note: can test only world-master. Since even host-collated will have
|
|
||||||
// same file format type for all processors
|
|
||||||
if (UPstream::master(UPstream::worldComm))
|
|
||||||
{
|
|
||||||
const bool oldParRun = UPstream::parRun(false);
|
|
||||||
|
|
||||||
if (IFstream is(fName); is.good())
|
|
||||||
{
|
|
||||||
IOobject io(name, instance, local, runTime);
|
|
||||||
io.readHeader(is);
|
|
||||||
|
|
||||||
isCollated = decomposedBlockData::isCollatedType(io);
|
|
||||||
}
|
|
||||||
|
|
||||||
UPstream::parRun(oldParRun);
|
|
||||||
}
|
|
||||||
Pstream::broadcast(isCollated, UPstream::worldComm);
|
|
||||||
}
|
|
||||||
|
|
||||||
// For collated, check that the corresponding blocks exist
|
|
||||||
if (isCollated)
|
|
||||||
{
|
|
||||||
found = checkFileExistenceCollated(handler, fName);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Globally consistent information about who has the file
|
|
||||||
bitSet haveFileOnProc = bitSet::allGather(found, UPstream::worldComm);
|
|
||||||
|
|
||||||
if (verbose)
|
|
||||||
{
|
|
||||||
Info<< "Per processor availability of \""
|
|
||||||
<< name << "\" file in " << instance/local << nl
|
|
||||||
<< " " << flatOutput(haveFileOnProc) << nl << endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
return haveFileOnProc;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Foam::boolList Foam::haveMeshFile
|
|
||||||
(
|
|
||||||
const word& name, // eg "faces"
|
|
||||||
const fileName& instance, // eg "constant"
|
|
||||||
const fileName& local, // eg, polyMesh
|
|
||||||
const Time& runTime,
|
|
||||||
const bool verbose
|
|
||||||
)
|
|
||||||
{
|
|
||||||
const auto& handler = Foam::fileHandler();
|
|
||||||
|
|
||||||
const fileName fName
|
|
||||||
(
|
|
||||||
handler.filePath(runTime.path()/instance/local/name)
|
|
||||||
);
|
|
||||||
|
|
||||||
bool found = handler.isFile(fName);
|
|
||||||
|
|
||||||
// Assume non-collated (as fallback value).
|
|
||||||
// If everyone claims to have the file, use master to verify if
|
|
||||||
// collated is involved.
|
|
||||||
|
|
||||||
bool isCollated = false;
|
|
||||||
|
|
||||||
if (returnReduceAnd(found, UPstream::worldComm))
|
|
||||||
{
|
|
||||||
// Test for collated format.
|
|
||||||
// Note: can test only world-master. Since even host-collated will have
|
|
||||||
// same file format type for all processors
|
|
||||||
if (UPstream::master(UPstream::worldComm))
|
|
||||||
{
|
|
||||||
const bool oldParRun = UPstream::parRun(false);
|
|
||||||
|
|
||||||
if (IFstream is(fName); is.good())
|
|
||||||
{
|
|
||||||
IOobject io(name, instance, local, runTime);
|
|
||||||
io.readHeader(is);
|
|
||||||
|
|
||||||
isCollated = decomposedBlockData::isCollatedType(io);
|
|
||||||
}
|
|
||||||
|
|
||||||
UPstream::parRun(oldParRun);
|
|
||||||
}
|
|
||||||
Pstream::broadcast(isCollated, UPstream::worldComm);
|
|
||||||
}
|
|
||||||
|
|
||||||
// For collated, check that the corresponding blocks exist
|
|
||||||
if (isCollated)
|
|
||||||
{
|
|
||||||
found = checkFileExistenceCollated(handler, fName);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Globally consistent information about who has a mesh
|
|
||||||
boolList haveFileOnProc
|
|
||||||
(
|
|
||||||
UPstream::allGatherValues<bool>(found, UPstream::worldComm)
|
|
||||||
);
|
|
||||||
|
|
||||||
if (verbose)
|
|
||||||
{
|
|
||||||
Info<< "Per processor availability of \""
|
|
||||||
<< name << "\" file in " << instance/local << nl
|
|
||||||
<< " " << flatOutput(haveFileOnProc) << nl << endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
return haveFileOnProc;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Foam::boolList Foam::haveMeshFile
|
Foam::boolList Foam::haveMeshFile
|
||||||
(
|
(
|
||||||
@ -302,49 +135,143 @@ Foam::boolList Foam::haveMeshFile
|
|||||||
const bool verbose
|
const bool verbose
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
#if 0
|
||||||
|
|
||||||
|
// Simple directory scanning - too fragile
|
||||||
|
bool found = checkFileExistence(runTime.path()/meshPath/meshFile);
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
// Trimmed-down version of lookupAndCacheProcessorsPath
|
||||||
|
// with Foam::exists() check. No caching.
|
||||||
|
|
||||||
|
// Check for two conditions:
|
||||||
|
// - file has to exist
|
||||||
|
// - if collated the entry has to exist inside the file
|
||||||
|
|
||||||
|
// Note: bypass fileOperation::filePath(IOobject&) since has problems
|
||||||
|
// with going to a different number of processors
|
||||||
|
// (in collated format). Use file-based searching instead
|
||||||
|
|
||||||
const auto& handler = Foam::fileHandler();
|
const auto& handler = Foam::fileHandler();
|
||||||
|
typedef fileOperation::procRangeType procRangeType;
|
||||||
|
|
||||||
const fileName fName
|
const fileName fName
|
||||||
(
|
(
|
||||||
handler.filePath(runTime.path()/meshPath/meshFile)
|
handler.filePath(runTime.path()/meshPath/meshFile)
|
||||||
);
|
);
|
||||||
|
|
||||||
bool found = handler.isFile(fName);
|
bool found = handler.isFile(fName);
|
||||||
|
if (returnReduceAnd(found)) // worldComm
|
||||||
// Assume non-collated (as fallback value).
|
|
||||||
// If everyone claims to have the file, use master to verify if
|
|
||||||
// collated is involved.
|
|
||||||
|
|
||||||
bool isCollated = false;
|
|
||||||
|
|
||||||
if (returnReduceAnd(found, UPstream::worldComm))
|
|
||||||
{
|
{
|
||||||
// Test for collated format.
|
// Bit tricky: avoid having all slaves open file since this involves
|
||||||
|
// reading it on master and broadcasting it. This fails if file > 2G.
|
||||||
|
// So instead only read on master
|
||||||
|
|
||||||
|
bool isCollated = false;
|
||||||
|
|
||||||
// Note: can test only world-master. Since even host-collated will have
|
// Note: can test only world-master. Since even host-collated will have
|
||||||
// same file format type for all processors
|
// same file format type for all processors
|
||||||
if (UPstream::master(UPstream::worldComm))
|
if (UPstream::master(UPstream::worldComm))
|
||||||
{
|
{
|
||||||
const bool oldParRun = UPstream::parRun(false);
|
const bool oldParRun = UPstream::parRun(false);
|
||||||
|
|
||||||
if (IFstream is(fName); is.good())
|
IFstream is(fName);
|
||||||
|
if (is.good())
|
||||||
{
|
{
|
||||||
IOobject io(meshFile, meshPath, runTime);
|
IOobject io(meshFile, meshPath, runTime);
|
||||||
io.readHeader(is);
|
io.readHeader(is);
|
||||||
|
|
||||||
isCollated = decomposedBlockData::isCollatedType(io);
|
isCollated = decomposedBlockData::isCollatedType(io);
|
||||||
}
|
}
|
||||||
|
|
||||||
UPstream::parRun(oldParRun);
|
UPstream::parRun(oldParRun);
|
||||||
}
|
}
|
||||||
Pstream::broadcast(isCollated, UPstream::worldComm);
|
Pstream::broadcast(isCollated); //UPstream::worldComm
|
||||||
}
|
|
||||||
|
|
||||||
// For collated, check that the corresponding blocks exist
|
|
||||||
if (isCollated)
|
|
||||||
{
|
|
||||||
found = checkFileExistenceCollated(handler, fName);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
// Collect block-number in individual filenames (might differ
|
||||||
|
// on different processors)
|
||||||
|
if (isCollated)
|
||||||
|
{
|
||||||
|
const label nProcs = UPstream::nProcs(fileHandler().comm());
|
||||||
|
const label myProcNo = UPstream::myProcNo(fileHandler().comm());
|
||||||
|
|
||||||
|
// Collect file names on master of local communicator
|
||||||
|
const fileNameList fNames
|
||||||
|
(
|
||||||
|
Pstream::listGatherValues
|
||||||
|
(
|
||||||
|
fName,
|
||||||
|
fileHandler().comm(),
|
||||||
|
UPstream::msgType()
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
// Collect local block number
|
||||||
|
label myBlockNumber = -1;
|
||||||
|
{
|
||||||
|
procRangeType group;
|
||||||
|
label proci = fileOperation::detectProcessorPath(fName, group);
|
||||||
|
|
||||||
|
if (proci == -1 && group.empty())
|
||||||
|
{
|
||||||
|
// 'processorsXXX' format so contains all ranks
|
||||||
|
// according to worldComm
|
||||||
|
myBlockNumber = UPstream::myProcNo(UPstream::worldComm);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// 'processorsXXX_n-m' format so check for the
|
||||||
|
// relative rank
|
||||||
|
myBlockNumber = myProcNo;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const labelList myBlockNumbers
|
||||||
|
(
|
||||||
|
Pstream::listGatherValues
|
||||||
|
(
|
||||||
|
myBlockNumber,
|
||||||
|
fileHandler().comm(),
|
||||||
|
UPstream::msgType()
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Determine for all whether the filename exists in the collated
|
||||||
|
// file.
|
||||||
|
boolList allFound(nProcs, false);
|
||||||
|
|
||||||
|
if (UPstream::master(fileHandler().comm()))
|
||||||
|
{
|
||||||
|
// Store nBlocks and index of file that was used for nBlocks
|
||||||
|
label nBlocks = -1;
|
||||||
|
label blockRanki = -1;
|
||||||
|
forAll(fNames, ranki)
|
||||||
|
{
|
||||||
|
if
|
||||||
|
(
|
||||||
|
blockRanki == -1
|
||||||
|
|| (fNames[ranki] != fNames[blockRanki])
|
||||||
|
)
|
||||||
|
{
|
||||||
|
blockRanki = ranki;
|
||||||
|
IFstream is(fNames[ranki]);
|
||||||
|
nBlocks = decomposedBlockData::getNumBlocks(is);
|
||||||
|
}
|
||||||
|
|
||||||
|
allFound[ranki] = (myBlockNumbers[ranki] < nBlocks);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
found = Pstream::listScatterValues
|
||||||
|
(
|
||||||
|
allFound,
|
||||||
|
fileHandler().comm(),
|
||||||
|
UPstream::msgType()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// Globally consistent information about who has a mesh
|
// Globally consistent information about who has a mesh
|
||||||
boolList haveFileOnProc
|
boolList haveFileOnProc
|
||||||
|
|||||||
@ -6,7 +6,7 @@
|
|||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Copyright (C) 2012 OpenFOAM Foundation
|
Copyright (C) 2012 OpenFOAM Foundation
|
||||||
Copyright (C) 2022-2025 OpenCFD Ltd.
|
Copyright (C) 2022-2023 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM.
|
This file is part of OpenFOAM.
|
||||||
@ -48,32 +48,15 @@ namespace Foam
|
|||||||
// Forward Declarations
|
// Forward Declarations
|
||||||
class faMesh;
|
class faMesh;
|
||||||
|
|
||||||
//- Check for availability of specified file (on all ranks)
|
//- Check for availability of given file
|
||||||
bitSet haveProcessorFile
|
bool checkFileExistence(const fileName& fName);
|
||||||
(
|
|
||||||
const word& name, // eg, "faces"
|
|
||||||
const fileName& instance, // eg, "constant"
|
|
||||||
const fileName& local, // eg, "polyMesh"
|
|
||||||
const Time& runTime,
|
|
||||||
const bool verbose = true
|
|
||||||
);
|
|
||||||
|
|
||||||
//- Check for availability of specified file (on all ranks)
|
//- Check for availability of specified mesh file (default: "faces")
|
||||||
boolList haveMeshFile
|
|
||||||
(
|
|
||||||
const word& name, // eg, "faces"
|
|
||||||
const fileName& instance, // eg, "constant"
|
|
||||||
const fileName& local, // eg, "polyMesh"
|
|
||||||
const Time& runTime,
|
|
||||||
const bool verbose = true
|
|
||||||
);
|
|
||||||
|
|
||||||
//- Check for availability of specified mesh file
|
|
||||||
boolList haveMeshFile
|
boolList haveMeshFile
|
||||||
(
|
(
|
||||||
const Time& runTime,
|
const Time& runTime,
|
||||||
const fileName& meshPath,
|
const fileName& meshPath,
|
||||||
const word& meshFile,
|
const word& meshFile = "faces",
|
||||||
const bool verbose = true
|
const bool verbose = true
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -92,7 +75,7 @@ void masterMeshInstance
|
|||||||
fileName& pointsInstance
|
fileName& pointsInstance
|
||||||
);
|
);
|
||||||
|
|
||||||
} // End namespace Foam
|
}
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@ -21,59 +21,44 @@ Requires
|
|||||||
|
|
||||||
// Initially all possible objects that are available at the final time
|
// Initially all possible objects that are available at the final time
|
||||||
List<wordHashSet> availableRegionObjectNames(meshes.size());
|
List<wordHashSet> availableRegionObjectNames(meshes.size());
|
||||||
List<HashTable<wordHashSet>> availableFaRegionObjectNames(meshes.size());
|
List<wordHashSet> availableFaRegionObjectNames(meshes.size());
|
||||||
|
|
||||||
forAll(meshes, regioni)
|
forAll(meshes, regioni)
|
||||||
{
|
{
|
||||||
const auto& mesh = meshes[regioni];
|
const auto& mesh = meshes[regioni];
|
||||||
|
|
||||||
IOobjectList objects;
|
IOobjectList objects;
|
||||||
HashTable<IOobjectList> faObjects;
|
IOobjectList faObjects;
|
||||||
|
|
||||||
if (doConvertFields && !timeDirs.empty())
|
if (doConvertFields && !timeDirs.empty())
|
||||||
{
|
{
|
||||||
// const word& checkTimeDir = timeDirs.back().name();
|
|
||||||
|
|
||||||
// List of volume mesh objects for this instance
|
// List of volume mesh objects for this instance
|
||||||
objects = IOobjectList(mesh, timeDirs.back().name());
|
objects = IOobjectList(mesh, timeDirs.back().name());
|
||||||
|
|
||||||
|
// List of area mesh objects (assuming single region)
|
||||||
|
faObjects = IOobjectList
|
||||||
|
(
|
||||||
|
mesh.time(),
|
||||||
|
timeDirs.back().name(),
|
||||||
|
faMesh::dbDir(mesh, word::null),
|
||||||
|
IOobjectOption::NO_REGISTER
|
||||||
|
);
|
||||||
|
|
||||||
if (fieldSelector)
|
if (fieldSelector)
|
||||||
{
|
{
|
||||||
objects.filterObjects(fieldSelector);
|
objects.filterObjects(fieldSelector);
|
||||||
|
faObjects.filterObjects(fieldSelector);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove "*_0" restart fields
|
// Remove "*_0" restart fields
|
||||||
objects.prune_0();
|
objects.prune_0();
|
||||||
|
faObjects.prune_0();
|
||||||
|
|
||||||
if (!doPointValues)
|
if (!doPointValues)
|
||||||
{
|
{
|
||||||
// Prune point fields if disabled
|
// Prune point fields if disabled
|
||||||
objects.filterClasses(Foam::fieldTypes::is_point, true);
|
objects.filterClasses(Foam::fieldTypes::is_point, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// The finite-area regions and their fields for this volume region
|
|
||||||
// and instance
|
|
||||||
faObjects.reserve(areaRegionNames.size());
|
|
||||||
for (const word& areaName : areaRegionNames)
|
|
||||||
{
|
|
||||||
IOobjectList objs
|
|
||||||
(
|
|
||||||
faMesh::Registry(mesh),
|
|
||||||
timeDirs.back().name(),
|
|
||||||
polyMesh::regionName(areaName),
|
|
||||||
IOobjectOption::NO_REGISTER
|
|
||||||
);
|
|
||||||
|
|
||||||
if (fieldSelector)
|
|
||||||
{
|
|
||||||
objs.filterObjects(fieldSelector);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Remove "*_0" restart fields
|
|
||||||
objs.prune_0();
|
|
||||||
faObjects(areaName) = std::move(objs);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Volume fields
|
// Volume fields
|
||||||
@ -93,29 +78,20 @@ forAll(meshes, regioni)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Area fields
|
// Area fields
|
||||||
for (const word& areaName : areaRegionNames)
|
if (!faObjects.empty())
|
||||||
{
|
{
|
||||||
wordList objectNames;
|
wordList objectNames(faObjects.sortedNames());
|
||||||
|
|
||||||
if (const auto iter = faObjects.cfind(areaName); iter.good())
|
// Check availability for all times... (assuming single region)
|
||||||
{
|
checkData
|
||||||
objectNames = iter.val().sortedNames();
|
|
||||||
|
|
||||||
// Check availability for all times...
|
|
||||||
checkData
|
|
||||||
(
|
|
||||||
faMesh::Registry(mesh),
|
|
||||||
timeDirs,
|
|
||||||
objectNames,
|
|
||||||
polyMesh::regionName(areaName)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
availableFaRegionObjectNames[regioni].emplace_set
|
|
||||||
(
|
(
|
||||||
areaName,
|
mesh.time(),
|
||||||
std::move(objectNames)
|
timeDirs,
|
||||||
|
objectNames,
|
||||||
|
faMesh::dbDir(mesh, word::null)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
availableFaRegionObjectNames[regioni] = objectNames;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -5,7 +5,7 @@
|
|||||||
\\ / A nd | www.openfoam.com
|
\\ / A nd | www.openfoam.com
|
||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Copyright (C) 2021-2025 OpenCFD Ltd.
|
Copyright (C) 2021-2022 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM, distributed under GPL-3.0-or-later.
|
This file is part of OpenFOAM, distributed under GPL-3.0-or-later.
|
||||||
@ -15,14 +15,12 @@ Description
|
|||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
// Cases and meshes per volume region
|
|
||||||
PtrList<ensightCase> ensightCases(regionNames.size());
|
PtrList<ensightCase> ensightCases(regionNames.size());
|
||||||
PtrList<ensightMesh> ensightMeshes(regionNames.size());
|
PtrList<ensightMesh> ensightMeshes(regionNames.size());
|
||||||
|
|
||||||
// Per volume region can have multiple finite-area regions
|
PtrList<faMesh> meshesFa(regionNames.size());
|
||||||
List<PtrDynList<faMesh>> meshesFa(regionNames.size());
|
PtrList<ensightCase> ensightCasesFa(regionNames.size());
|
||||||
List<PtrDynList<ensightCase>> ensightCasesFa(regionNames.size());
|
PtrList<ensightFaMesh> ensightMeshesFa(regionNames.size());
|
||||||
List<PtrDynList<ensightFaMesh>> ensightMeshesFa(regionNames.size());
|
|
||||||
|
|
||||||
{
|
{
|
||||||
forAll(regionNames, regioni)
|
forAll(regionNames, regioni)
|
||||||
@ -47,7 +45,6 @@ List<PtrDynList<ensightFaMesh>> ensightMeshesFa(regionNames.size());
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Volume mesh
|
|
||||||
ensightMeshes.set
|
ensightMeshes.set
|
||||||
(
|
(
|
||||||
regioni,
|
regioni,
|
||||||
@ -62,59 +59,32 @@ List<PtrDynList<ensightFaMesh>> ensightMeshesFa(regionNames.size());
|
|||||||
new ensightCase(ensCasePath, ensCaseName, caseOpts)
|
new ensightCase(ensCasePath, ensCaseName, caseOpts)
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!doFiniteArea)
|
if (doFiniteArea)
|
||||||
{
|
{
|
||||||
continue;
|
autoPtr<faMesh> faMeshPtr(faMesh::TryNew(mesh));
|
||||||
}
|
|
||||||
|
|
||||||
// Note: not every volume region is guaranteed to have
|
|
||||||
// any or all area region(s)
|
|
||||||
|
|
||||||
meshesFa[regioni].reserve_exact(areaRegionNames.size());
|
|
||||||
|
|
||||||
for (const word& areaName : areaRegionNames)
|
|
||||||
{
|
|
||||||
auto faMeshPtr = faMesh::TryNew(areaName, mesh);
|
|
||||||
|
|
||||||
if (faMeshPtr)
|
if (faMeshPtr)
|
||||||
{
|
{
|
||||||
meshesFa[regioni].push_back(std::move(faMeshPtr));
|
ensightCasesFa.set
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Setup the ensight components
|
|
||||||
const label nAreas = meshesFa[regioni].size();
|
|
||||||
ensightCasesFa[regioni].reserve_exact(nAreas);
|
|
||||||
ensightMeshesFa[regioni].reserve_exact(nAreas);
|
|
||||||
|
|
||||||
for (const faMesh& areaMesh : meshesFa[regioni])
|
|
||||||
{
|
|
||||||
// Use regionName() - automatically filters for defaultRegion
|
|
||||||
const word& areaName = areaMesh.regionName();
|
|
||||||
|
|
||||||
if (areaName.empty())
|
|
||||||
{
|
|
||||||
// single-region
|
|
||||||
ensightCasesFa[regioni].emplace_back
|
|
||||||
(
|
(
|
||||||
ensCasePath/"finite-area",
|
regioni,
|
||||||
"finite-area",
|
new ensightCase
|
||||||
caseOpts
|
(
|
||||||
|
ensCasePath/"finite-area",
|
||||||
|
"finite-area",
|
||||||
|
caseOpts
|
||||||
|
)
|
||||||
);
|
);
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// multi-region
|
|
||||||
ensightCasesFa[regioni].emplace_back
|
|
||||||
(
|
|
||||||
ensCasePath/"finite-area"/areaName,
|
|
||||||
areaName,
|
|
||||||
caseOpts
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
auto& ensFaMesh = ensightMeshesFa[regioni].emplace_back(areaMesh);
|
meshesFa.set(regioni, std::move(faMeshPtr));
|
||||||
ensFaMesh.verbose(optVerbose);
|
|
||||||
|
ensightMeshesFa.set
|
||||||
|
(
|
||||||
|
regioni,
|
||||||
|
new ensightFaMesh(meshesFa[regioni])
|
||||||
|
);
|
||||||
|
ensightMeshesFa[regioni].verbose(optVerbose);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -124,7 +124,6 @@ Usage
|
|||||||
#include "OFstream.H"
|
#include "OFstream.H"
|
||||||
#include "Pstream.H"
|
#include "Pstream.H"
|
||||||
#include "HashOps.H"
|
#include "HashOps.H"
|
||||||
#include "PtrDynList.H"
|
|
||||||
#include "regionProperties.H"
|
#include "regionProperties.H"
|
||||||
|
|
||||||
#include "fvc.H"
|
#include "fvc.H"
|
||||||
@ -173,7 +172,6 @@ int main(int argc, char *argv[])
|
|||||||
argList::addVerboseOption();
|
argList::addVerboseOption();
|
||||||
|
|
||||||
#include "addAllRegionOptions.H"
|
#include "addAllRegionOptions.H"
|
||||||
#include "addAllFaRegionOptions.H"
|
|
||||||
|
|
||||||
argList::addBoolOption
|
argList::addBoolOption
|
||||||
(
|
(
|
||||||
@ -441,14 +439,6 @@ int main(int argc, char *argv[])
|
|||||||
// Handle -allRegions, -regions, -region
|
// Handle -allRegions, -regions, -region
|
||||||
#include "getAllRegionOptions.H"
|
#include "getAllRegionOptions.H"
|
||||||
|
|
||||||
// Handle -all-area-regions, -area-regions, -area-region
|
|
||||||
#include "getAllFaRegionOptions.H"
|
|
||||||
|
|
||||||
if (!doFiniteArea)
|
|
||||||
{
|
|
||||||
areaRegionNames.clear(); // For consistency
|
|
||||||
}
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
// Directory management
|
// Directory management
|
||||||
|
|
||||||
@ -528,32 +518,29 @@ int main(int argc, char *argv[])
|
|||||||
polyMesh::readUpdateState meshState = mesh.readUpdate();
|
polyMesh::readUpdateState meshState = mesh.readUpdate();
|
||||||
const bool moving = (meshState != polyMesh::UNCHANGED);
|
const bool moving = (meshState != polyMesh::UNCHANGED);
|
||||||
|
|
||||||
// Ensight (fvMesh)
|
// Ensight
|
||||||
auto& ensCase = ensightCases[regioni];
|
auto& ensCase = ensightCases[regioni];
|
||||||
auto& ensMesh = ensightMeshes[regioni];
|
auto& ensMesh = ensightMeshes[regioni];
|
||||||
|
|
||||||
|
// Finite-area (can be missing)
|
||||||
|
auto* ensFaCasePtr = ensightCasesFa.get(regioni);
|
||||||
|
auto* ensFaMeshPtr = ensightMeshesFa.get(regioni);
|
||||||
|
|
||||||
ensCase.setTime(timeDirs[timei], timeIndex);
|
ensCase.setTime(timeDirs[timei], timeIndex);
|
||||||
|
if (ensFaCasePtr)
|
||||||
// Finite-area (optional)
|
|
||||||
// Accounting exists for each volume region but may be empty
|
|
||||||
auto& ensFaCases = ensightCasesFa[regioni];
|
|
||||||
auto& ensFaMeshes = ensightMeshesFa[regioni];
|
|
||||||
|
|
||||||
for (auto& ensFaCase : ensFaCases)
|
|
||||||
{
|
{
|
||||||
ensFaCase.setTime(timeDirs[timei], timeIndex);
|
ensFaCasePtr->setTime(timeDirs[timei], timeIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Movement
|
|
||||||
if (moving)
|
if (moving)
|
||||||
{
|
{
|
||||||
ensMesh.expire();
|
ensMesh.expire();
|
||||||
ensMesh.correct();
|
ensMesh.correct();
|
||||||
|
|
||||||
for (auto& ensFaMesh : ensFaMeshes)
|
if (ensFaMeshPtr)
|
||||||
{
|
{
|
||||||
ensFaMesh.expire();
|
ensFaMeshPtr->expire();
|
||||||
ensFaMesh.correct();
|
ensFaMeshPtr->correct();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -568,19 +555,15 @@ int main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
|
|
||||||
// finite-area
|
// finite-area
|
||||||
forAll(ensFaMeshes, areai)
|
if (ensFaCasePtr && ensFaMeshPtr)
|
||||||
{
|
{
|
||||||
const auto& ensFaCase = ensFaCases[areai];
|
|
||||||
const auto& ensFaMesh = ensFaMeshes[areai];
|
|
||||||
|
|
||||||
autoPtr<ensightGeoFile> os =
|
autoPtr<ensightGeoFile> os =
|
||||||
ensFaCase.newGeometry(hasMovingMesh);
|
ensFaCasePtr->newGeometry(hasMovingMesh);
|
||||||
|
|
||||||
ensFaMesh.write(os.ref());
|
ensFaMeshPtr->write(os.ref());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Objects at this time
|
// Objects at this time
|
||||||
IOobjectList objects(mesh, runTime.timeName());
|
IOobjectList objects(mesh, runTime.timeName());
|
||||||
|
|
||||||
@ -592,37 +575,23 @@ int main(int argc, char *argv[])
|
|||||||
// Volume, internal, point fields
|
// Volume, internal, point fields
|
||||||
#include "convertVolumeFields.H"
|
#include "convertVolumeFields.H"
|
||||||
|
|
||||||
// finite-area
|
// The finite-area objects at this time
|
||||||
forAll(ensFaMeshes, areai)
|
IOobjectList faObjects;
|
||||||
|
|
||||||
|
if (ensFaMeshPtr)
|
||||||
{
|
{
|
||||||
auto* ensFaCasePtr = ensFaCases.get(areai);
|
faObjects =
|
||||||
auto* ensFaMeshPtr = ensFaMeshes.get(areai);
|
IOobjectList(ensFaMeshPtr->mesh(), runTime.timeName());
|
||||||
|
|
||||||
// The finite-area region objects at this time
|
faObjects.filterObjects
|
||||||
IOobjectList faObjects;
|
(
|
||||||
|
availableFaRegionObjectNames[regioni]
|
||||||
if (ensFaMeshPtr)
|
);
|
||||||
{
|
|
||||||
const word& areaName = ensFaMeshPtr->mesh().name();
|
|
||||||
|
|
||||||
faObjects = IOobjectList
|
|
||||||
(
|
|
||||||
faMesh::Registry(mesh),
|
|
||||||
runTime.timeName(),
|
|
||||||
polyMesh::regionName(areaName),
|
|
||||||
IOobjectOption::NO_REGISTER
|
|
||||||
);
|
|
||||||
|
|
||||||
faObjects.filterObjects
|
|
||||||
(
|
|
||||||
availableFaRegionObjectNames[regioni](areaName)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// The finiteArea fields
|
|
||||||
#include "convertAreaFields.H"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// The finiteArea fields
|
||||||
|
#include "convertAreaFields.H"
|
||||||
|
|
||||||
// Lagrangian fields
|
// Lagrangian fields
|
||||||
#include "convertLagrangian.H"
|
#include "convertLagrangian.H"
|
||||||
}
|
}
|
||||||
@ -635,13 +604,14 @@ int main(int argc, char *argv[])
|
|||||||
// Write cases
|
// Write cases
|
||||||
forAll(ensightCases, regioni)
|
forAll(ensightCases, regioni)
|
||||||
{
|
{
|
||||||
// finite-volume
|
|
||||||
ensightCases[regioni].write();
|
ensightCases[regioni].write();
|
||||||
|
}
|
||||||
|
|
||||||
// Finite-area (if any)
|
forAll(ensightCasesFa, regioni)
|
||||||
for (const auto& ensFaCase : ensightCasesFa[regioni])
|
{
|
||||||
|
if (ensightCasesFa.set(regioni))
|
||||||
{
|
{
|
||||||
ensFaCase.write();
|
ensightCasesFa[regioni].write();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -5,7 +5,7 @@
|
|||||||
\\ / A nd | www.openfoam.com
|
\\ / A nd | www.openfoam.com
|
||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Copyright (C) 2018-2025 OpenCFD Ltd.
|
Copyright (C) 2018-2023 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM.
|
This file is part of OpenFOAM.
|
||||||
@ -26,6 +26,7 @@ License
|
|||||||
\*---------------------------------------------------------------------------*/
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
#include "readFields.H"
|
#include "readFields.H"
|
||||||
|
#include "volFields.H"
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * Global Functions * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * Global Functions * * * * * * * * * * * * * //
|
||||||
|
|
||||||
@ -41,30 +42,26 @@ Foam::label Foam::checkData
|
|||||||
|
|
||||||
wordHashSet goodFields;
|
wordHashSet goodFields;
|
||||||
|
|
||||||
IOobject io
|
|
||||||
(
|
|
||||||
"any-name", // placeholder
|
|
||||||
"constant", // placeholder
|
|
||||||
local,
|
|
||||||
obr,
|
|
||||||
IOobjectOption::NO_READ,
|
|
||||||
IOobjectOption::NO_WRITE,
|
|
||||||
IOobjectOption::NO_REGISTER
|
|
||||||
);
|
|
||||||
|
|
||||||
for (const word& fieldName : objectNames)
|
for (const word& fieldName : objectNames)
|
||||||
{
|
{
|
||||||
// In case prune_0() not previously used...
|
// // If prune_0() not previously used...
|
||||||
if (fieldName.ends_with("_0")) continue;
|
// if (objectNames.ends_with("_0")) continue;
|
||||||
|
|
||||||
bool good = false;
|
bool good = false;
|
||||||
|
|
||||||
for (const instant& inst : timeDirs)
|
for (const instant& inst : timeDirs)
|
||||||
{
|
{
|
||||||
io.resetHeader(fieldName);
|
good =
|
||||||
io.instance() = inst.name();
|
IOobject
|
||||||
|
(
|
||||||
good = io.typeHeaderOk<regIOobject>(false, false);
|
fieldName,
|
||||||
|
inst.name(),
|
||||||
|
local,
|
||||||
|
obr,
|
||||||
|
IOobject::NO_READ,
|
||||||
|
IOobject::NO_WRITE,
|
||||||
|
IOobject::NO_REGISTER
|
||||||
|
).typeHeaderOk<volScalarField>(false, false);
|
||||||
|
|
||||||
if (!good)
|
if (!good)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -22,66 +22,24 @@ Description
|
|||||||
//
|
//
|
||||||
|
|
||||||
// No subsetting!
|
// No subsetting!
|
||||||
if (doFiniteArea && !areaRegionNames.empty())
|
if (doFiniteArea)
|
||||||
{
|
{
|
||||||
using reportFields = foamToVtkReportFields;
|
using reportFields = foamToVtkReportFields;
|
||||||
|
|
||||||
// The (region) polyMesh being used. No subsetting possible
|
autoPtr<faMesh> faMeshPtr;
|
||||||
const auto& basePolyMesh = meshProxy.baseMesh();
|
|
||||||
|
|
||||||
for (const word& areaName : areaRegionNames)
|
const label nAreaFields = faObjects.count(Foam::fieldTypes::is_area);
|
||||||
|
|
||||||
|
if (nAreaFields || withMeshIds)
|
||||||
{
|
{
|
||||||
const bool isDefaultRegion(polyMesh::regionName(areaName).empty());
|
faMeshPtr = faMesh::TryNew(meshProxy.baseMesh());
|
||||||
|
}
|
||||||
|
|
||||||
// CAUTION
|
if (faMeshPtr && (nAreaFields || withMeshIds))
|
||||||
// If we want to have constant access to the HashTable:
|
{
|
||||||
//
|
const faMesh& areaMesh = faMeshPtr();
|
||||||
// (SEGFAULT)
|
|
||||||
// const auto& faObjs = faObjects.lookup(areaName, IOobjectList());
|
|
||||||
//
|
|
||||||
// Use an empty fallback to avoid binding to a temporary:
|
|
||||||
//
|
|
||||||
// const IOobjectList emptyObjectList;
|
|
||||||
// const auto& faObjs = faObjects.lookup(areaName, emptyObjectList);
|
|
||||||
|
|
||||||
// Since we do not need the area fields afterwards,
|
reportFields::area(Info, faObjects);
|
||||||
// just move them out from the HashTable
|
|
||||||
|
|
||||||
IOobjectList faObjs;
|
|
||||||
if (auto iter = faObjects.find(areaName); iter.good())
|
|
||||||
{
|
|
||||||
faObjs = std::move(iter.val());
|
|
||||||
}
|
|
||||||
|
|
||||||
const label nAreaFields = faObjs.count(Foam::fieldTypes::is_area);
|
|
||||||
|
|
||||||
autoPtr<faMesh> faMeshPtr;
|
|
||||||
|
|
||||||
if (nAreaFields || withMeshIds)
|
|
||||||
{
|
|
||||||
faMeshPtr = faMesh::TryNew(areaName, basePolyMesh);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!faMeshPtr)
|
|
||||||
{
|
|
||||||
if (!isDefaultRegion)
|
|
||||||
{
|
|
||||||
// Report any area region specified but missing
|
|
||||||
// - silently ignore region0
|
|
||||||
Info<< "No area-mesh [" << polyMesh::regionName(areaName)
|
|
||||||
<< "] on volume-region ["
|
|
||||||
<< basePolyMesh.regionName() << "]" << endl;
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
const auto& areaMesh = faMeshPtr();
|
|
||||||
|
|
||||||
Info<< "Using area-mesh [" << polyMesh::regionName(areaName)
|
|
||||||
<< "] on volume-region ["
|
|
||||||
<< basePolyMesh.regionName() << "]" << endl;
|
|
||||||
|
|
||||||
|
|
||||||
reportFields::area(Info, faObjs);
|
|
||||||
|
|
||||||
const auto& pp = faMeshPtr->patch();
|
const auto& pp = faMeshPtr->patch();
|
||||||
|
|
||||||
@ -91,12 +49,7 @@ if (doFiniteArea && !areaRegionNames.empty())
|
|||||||
writeOpts,
|
writeOpts,
|
||||||
(
|
(
|
||||||
outputDir/regionDir/"finite-area"
|
outputDir/regionDir/"finite-area"
|
||||||
/ (
|
/ "finiteArea" + timeDesc
|
||||||
isDefaultRegion
|
|
||||||
? fileName("finiteArea")
|
|
||||||
: fileName(areaName/areaName)
|
|
||||||
)
|
|
||||||
+ timeDesc
|
|
||||||
),
|
),
|
||||||
UPstream::parRun()
|
UPstream::parRun()
|
||||||
);
|
);
|
||||||
@ -143,7 +96,7 @@ if (doFiniteArea && !areaRegionNames.empty())
|
|||||||
(
|
(
|
||||||
writer,
|
writer,
|
||||||
areaMesh,
|
areaMesh,
|
||||||
faObjs,
|
faObjects,
|
||||||
true // syncPar
|
true // syncPar
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@ -135,13 +135,13 @@ Note
|
|||||||
#include "emptyPolyPatch.H"
|
#include "emptyPolyPatch.H"
|
||||||
#include "volPointInterpolation.H"
|
#include "volPointInterpolation.H"
|
||||||
#include "faceZoneMesh.H"
|
#include "faceZoneMesh.H"
|
||||||
#include "faMesh.H"
|
|
||||||
#include "areaFields.H"
|
#include "areaFields.H"
|
||||||
#include "fvMeshSubsetProxy.H"
|
#include "fvMeshSubsetProxy.H"
|
||||||
#include "faceSet.H"
|
#include "faceSet.H"
|
||||||
#include "pointSet.H"
|
#include "pointSet.H"
|
||||||
#include "HashOps.H"
|
#include "HashOps.H"
|
||||||
#include "regionProperties.H"
|
#include "regionProperties.H"
|
||||||
|
#include "stringListOps.H" // For stringListOps::findMatching()
|
||||||
|
|
||||||
#include "Cloud.H"
|
#include "Cloud.H"
|
||||||
#include "readFields.H"
|
#include "readFields.H"
|
||||||
@ -434,7 +434,6 @@ int main(int argc, char *argv[])
|
|||||||
argList::addOptionCompat("one-boundary", {"allPatches", 1806});
|
argList::addOptionCompat("one-boundary", {"allPatches", 1806});
|
||||||
|
|
||||||
#include "addAllRegionOptions.H"
|
#include "addAllRegionOptions.H"
|
||||||
#include "addAllFaRegionOptions.H"
|
|
||||||
|
|
||||||
argList::addOption
|
argList::addOption
|
||||||
(
|
(
|
||||||
@ -631,16 +630,6 @@ int main(int argc, char *argv[])
|
|||||||
// Handle -allRegions, -regions, -region
|
// Handle -allRegions, -regions, -region
|
||||||
#include "getAllRegionOptions.H"
|
#include "getAllRegionOptions.H"
|
||||||
|
|
||||||
// Handle -all-area-regions, -area-regions, -area-region
|
|
||||||
#include "getAllFaRegionOptions.H"
|
|
||||||
|
|
||||||
if (!doFiniteArea)
|
|
||||||
{
|
|
||||||
areaRegionNames.clear(); // For consistency
|
|
||||||
}
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------
|
|
||||||
|
|
||||||
// Names for sets and zones
|
// Names for sets and zones
|
||||||
word cellSelectionName;
|
word cellSelectionName;
|
||||||
word faceSetName;
|
word faceSetName;
|
||||||
@ -788,11 +777,8 @@ int main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// fvMesh fields
|
|
||||||
IOobjectList objects;
|
IOobjectList objects;
|
||||||
|
IOobjectList faObjects;
|
||||||
// faMesh fields (multiple finite-area regions per volume region)
|
|
||||||
HashTable<IOobjectList> faObjects;
|
|
||||||
|
|
||||||
if (doConvertFields)
|
if (doConvertFields)
|
||||||
{
|
{
|
||||||
@ -800,51 +786,33 @@ int main(int argc, char *argv[])
|
|||||||
objects =
|
objects =
|
||||||
IOobjectList(meshProxy.baseMesh(), runTime.timeName());
|
IOobjectList(meshProxy.baseMesh(), runTime.timeName());
|
||||||
|
|
||||||
|
// List of area mesh objects (assuming single region)
|
||||||
|
faObjects =
|
||||||
|
IOobjectList
|
||||||
|
(
|
||||||
|
runTime,
|
||||||
|
runTime.timeName(),
|
||||||
|
faMesh::dbDir(meshProxy.baseMesh(), word::null),
|
||||||
|
IOobjectOption::NO_REGISTER
|
||||||
|
);
|
||||||
|
|
||||||
if (fieldSelector)
|
if (fieldSelector)
|
||||||
{
|
{
|
||||||
objects.filterObjects(fieldSelector);
|
objects.filterObjects(fieldSelector);
|
||||||
|
faObjects.filterObjects(fieldSelector);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove "*_0" restart fields
|
// Remove "*_0" restart fields
|
||||||
objects.prune_0();
|
objects.prune_0();
|
||||||
|
faObjects.prune_0();
|
||||||
|
|
||||||
if (!doPointValues)
|
if (!doPointValues)
|
||||||
{
|
{
|
||||||
// Prune point fields if disabled
|
// Prune point fields if disabled
|
||||||
objects.filterClasses(Foam::fieldTypes::is_point, true);
|
objects.filterClasses(Foam::fieldTypes::is_point, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Lists of finite-area fields
|
|
||||||
faObjects.reserve(areaRegionNames.size());
|
|
||||||
|
|
||||||
for (const word& areaName : areaRegionNames)
|
|
||||||
{
|
|
||||||
// The finite-area objects for given area region.
|
|
||||||
// Add as method to faMeshesRegistry?
|
|
||||||
|
|
||||||
IOobjectList objs
|
|
||||||
(
|
|
||||||
faMesh::Registry(meshProxy.baseMesh()),
|
|
||||||
runTime.timeName(),
|
|
||||||
polyMesh::regionName(areaName),
|
|
||||||
IOobjectOption::NO_REGISTER
|
|
||||||
);
|
|
||||||
|
|
||||||
if (fieldSelector)
|
|
||||||
{
|
|
||||||
objs.filterObjects(fieldSelector);
|
|
||||||
}
|
|
||||||
// Remove "*_0" restart fields
|
|
||||||
objs.prune_0();
|
|
||||||
|
|
||||||
if (!objs.empty())
|
|
||||||
{
|
|
||||||
faObjects.emplace_set(areaName, std::move(objs));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (processorFieldsOnly)
|
if (processorFieldsOnly)
|
||||||
{
|
{
|
||||||
// Processor-patches only and continue
|
// Processor-patches only and continue
|
||||||
|
|||||||
@ -1,10 +1,10 @@
|
|||||||
EXE_INC = \
|
EXE_INC = \
|
||||||
-I$(LIB_SRC)/meshTools/lnInclude \
|
|
||||||
-I$(LIB_SRC)/finiteVolume/lnInclude \
|
-I$(LIB_SRC)/finiteVolume/lnInclude \
|
||||||
-I$(LIB_SRC)/finiteArea/lnInclude
|
-I$(LIB_SRC)/finiteArea/lnInclude \
|
||||||
|
-I$(LIB_SRC)/meshTools/lnInclude
|
||||||
|
|
||||||
EXE_LIBS = \
|
EXE_LIBS = \
|
||||||
-lmeshTools \
|
|
||||||
-lfiniteVolume \
|
-lfiniteVolume \
|
||||||
-lfiniteArea \
|
-lfiniteArea \
|
||||||
|
-lmeshTools \
|
||||||
-lgenericPatchFields
|
-lgenericPatchFields
|
||||||
|
|||||||
@ -6,7 +6,7 @@
|
|||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Copyright (C) 2011-2016 OpenFOAM Foundation
|
Copyright (C) 2011-2016 OpenFOAM Foundation
|
||||||
Copyright (C) 2022-2025 OpenCFD Ltd.
|
Copyright (C) 2022-2024 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM.
|
This file is part of OpenFOAM.
|
||||||
@ -47,7 +47,6 @@ Description
|
|||||||
#include "areaFields.H"
|
#include "areaFields.H"
|
||||||
#include "coupledFvPatch.H"
|
#include "coupledFvPatch.H"
|
||||||
#include "coupledFaPatch.H"
|
#include "coupledFaPatch.H"
|
||||||
#include "regionProperties.H"
|
|
||||||
|
|
||||||
using namespace Foam;
|
using namespace Foam;
|
||||||
|
|
||||||
@ -87,18 +86,17 @@ bool consumeUnusedType(const fieldDescription& fieldDesc, Istream& is)
|
|||||||
//? typedef GeometricField<Type, faePatchField, areaMesh> fieldType3;
|
//? typedef GeometricField<Type, faePatchField, areaMesh> fieldType3;
|
||||||
//? typedef GeometricField<Type, fvsPatchField, volMesh> fieldType4;
|
//? typedef GeometricField<Type, fvsPatchField, volMesh> fieldType4;
|
||||||
|
|
||||||
const bool isExpectedType
|
if
|
||||||
(
|
(
|
||||||
fieldDesc.type() == fieldType1::typeName
|
fieldDesc.type() == fieldType1::typeName
|
||||||
|| fieldDesc.type() == fieldType2::typeName
|
|| fieldDesc.type() == fieldType2::typeName
|
||||||
);
|
)
|
||||||
|
|
||||||
if (isExpectedType)
|
|
||||||
{
|
{
|
||||||
(void) pTraits<Type>(is);
|
(void) pTraits<Type>(is);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return isExpectedType;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -124,18 +122,13 @@ bool setCellFieldType
|
|||||||
(
|
(
|
||||||
const fieldDescription& fieldDesc,
|
const fieldDescription& fieldDesc,
|
||||||
const fvMesh& mesh,
|
const fvMesh& mesh,
|
||||||
const labelUList& selectedCells,
|
const labelList& selectedCells,
|
||||||
Istream& is
|
Istream& is
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
typedef GeometricField<Type, fvPatchField, volMesh> fieldType;
|
typedef GeometricField<Type, fvPatchField, volMesh> fieldType;
|
||||||
|
|
||||||
const bool isExpectedType
|
if (fieldDesc.type() != fieldType::typeName)
|
||||||
(
|
|
||||||
fieldDesc.type() == fieldType::typeName
|
|
||||||
);
|
|
||||||
|
|
||||||
if (!isExpectedType)
|
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -150,9 +143,7 @@ bool setCellFieldType
|
|||||||
fieldDesc.name(),
|
fieldDesc.name(),
|
||||||
mesh.thisDb().time().timeName(),
|
mesh.thisDb().time().timeName(),
|
||||||
mesh.thisDb(),
|
mesh.thisDb(),
|
||||||
IOobjectOption::MUST_READ,
|
IOobject::MUST_READ
|
||||||
IOobjectOption::NO_WRITE,
|
|
||||||
IOobjectOption::NO_REGISTER
|
|
||||||
);
|
);
|
||||||
|
|
||||||
bool found = fieldHeader.typeHeaderOk<fieldType>(true);
|
bool found = fieldHeader.typeHeaderOk<fieldType>(true);
|
||||||
@ -160,8 +151,13 @@ bool setCellFieldType
|
|||||||
if (!found)
|
if (!found)
|
||||||
{
|
{
|
||||||
// Fallback to "constant" directory
|
// Fallback to "constant" directory
|
||||||
fieldHeader.resetHeader();
|
fieldHeader = IOobject
|
||||||
fieldHeader.instance() = mesh.thisDb().time().constant();
|
(
|
||||||
|
fieldDesc.name(),
|
||||||
|
mesh.thisDb().time().constant(),
|
||||||
|
mesh.thisDb(),
|
||||||
|
IOobject::MUST_READ
|
||||||
|
);
|
||||||
found = fieldHeader.typeHeaderOk<fieldType>(true);
|
found = fieldHeader.typeHeaderOk<fieldType>(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -175,7 +171,7 @@ bool setCellFieldType
|
|||||||
|
|
||||||
fieldType field(fieldHeader, mesh, false);
|
fieldType field(fieldHeader, mesh, false);
|
||||||
|
|
||||||
if (isNull(selectedCells) || (selectedCells.size() == field.size()))
|
if (isNull(selectedCells) || selectedCells.size() == field.size())
|
||||||
{
|
{
|
||||||
field.primitiveFieldRef() = fieldValue;
|
field.primitiveFieldRef() = fieldValue;
|
||||||
}
|
}
|
||||||
@ -208,7 +204,7 @@ bool setCellFieldType
|
|||||||
<< "Field " << fieldDesc.name() << " not found" << endl;
|
<< "Field " << fieldDesc.name() << " not found" << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
return isExpectedType;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -220,18 +216,13 @@ bool setAreaFieldType
|
|||||||
(
|
(
|
||||||
const fieldDescription& fieldDesc,
|
const fieldDescription& fieldDesc,
|
||||||
const faMesh& mesh,
|
const faMesh& mesh,
|
||||||
const labelUList& selectedFaces,
|
const labelList& selectedFaces,
|
||||||
Istream& is
|
Istream& is
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
typedef GeometricField<Type, faPatchField, areaMesh> fieldType;
|
typedef GeometricField<Type, faPatchField, areaMesh> fieldType;
|
||||||
|
|
||||||
const bool isExpectedType
|
if (fieldDesc.type() != fieldType::typeName)
|
||||||
(
|
|
||||||
fieldDesc.type() == fieldType::typeName
|
|
||||||
);
|
|
||||||
|
|
||||||
if (!isExpectedType)
|
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -246,9 +237,7 @@ bool setAreaFieldType
|
|||||||
fieldDesc.name(),
|
fieldDesc.name(),
|
||||||
mesh.thisDb().time().timeName(),
|
mesh.thisDb().time().timeName(),
|
||||||
mesh.thisDb(),
|
mesh.thisDb(),
|
||||||
IOobjectOption::MUST_READ,
|
IOobject::MUST_READ
|
||||||
IOobjectOption::NO_WRITE,
|
|
||||||
IOobjectOption::NO_REGISTER
|
|
||||||
);
|
);
|
||||||
|
|
||||||
bool found = fieldHeader.typeHeaderOk<fieldType>(true);
|
bool found = fieldHeader.typeHeaderOk<fieldType>(true);
|
||||||
@ -256,8 +245,13 @@ bool setAreaFieldType
|
|||||||
if (!found)
|
if (!found)
|
||||||
{
|
{
|
||||||
// Fallback to "constant" directory
|
// Fallback to "constant" directory
|
||||||
fieldHeader.resetHeader();
|
fieldHeader = IOobject
|
||||||
fieldHeader.instance() = mesh.thisDb().time().constant(),
|
(
|
||||||
|
fieldDesc.name(),
|
||||||
|
mesh.thisDb().time().constant(),
|
||||||
|
mesh.thisDb(),
|
||||||
|
IOobject::MUST_READ
|
||||||
|
);
|
||||||
found = fieldHeader.typeHeaderOk<fieldType>(true);
|
found = fieldHeader.typeHeaderOk<fieldType>(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -298,7 +292,7 @@ bool setAreaFieldType
|
|||||||
<< "Field " << fieldDesc.name() << " not found" << endl;
|
<< "Field " << fieldDesc.name() << " not found" << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
return isExpectedType;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -310,18 +304,13 @@ bool setFaceFieldType
|
|||||||
(
|
(
|
||||||
const fieldDescription& fieldDesc,
|
const fieldDescription& fieldDesc,
|
||||||
const fvMesh& mesh,
|
const fvMesh& mesh,
|
||||||
const labelUList& selectedFaces,
|
const labelList& selectedFaces,
|
||||||
Istream& is
|
Istream& is
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
typedef GeometricField<Type, fvPatchField, volMesh> fieldType;
|
typedef GeometricField<Type, fvPatchField, volMesh> fieldType;
|
||||||
|
|
||||||
const bool isExpectedType
|
if (fieldDesc.type() != fieldType::typeName)
|
||||||
(
|
|
||||||
fieldDesc.type() == fieldType::typeName
|
|
||||||
);
|
|
||||||
|
|
||||||
if (!isExpectedType)
|
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -336,9 +325,7 @@ bool setFaceFieldType
|
|||||||
fieldDesc.name(),
|
fieldDesc.name(),
|
||||||
mesh.thisDb().time().timeName(),
|
mesh.thisDb().time().timeName(),
|
||||||
mesh.thisDb(),
|
mesh.thisDb(),
|
||||||
IOobjectOption::MUST_READ,
|
IOobject::MUST_READ
|
||||||
IOobjectOption::NO_WRITE,
|
|
||||||
IOobjectOption::NO_REGISTER
|
|
||||||
);
|
);
|
||||||
|
|
||||||
bool found = fieldHeader.typeHeaderOk<fieldType>(true);
|
bool found = fieldHeader.typeHeaderOk<fieldType>(true);
|
||||||
@ -346,8 +333,13 @@ bool setFaceFieldType
|
|||||||
if (!found)
|
if (!found)
|
||||||
{
|
{
|
||||||
// Fallback to "constant" directory
|
// Fallback to "constant" directory
|
||||||
fieldHeader.resetHeader();
|
fieldHeader = IOobject
|
||||||
fieldHeader.instance() = mesh.thisDb().time().constant();
|
(
|
||||||
|
fieldDesc.name(),
|
||||||
|
mesh.thisDb().time().constant(),
|
||||||
|
mesh.thisDb(),
|
||||||
|
IOobject::MUST_READ
|
||||||
|
);
|
||||||
found = fieldHeader.typeHeaderOk<fieldType>(true);
|
found = fieldHeader.typeHeaderOk<fieldType>(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -363,14 +355,15 @@ bool setFaceFieldType
|
|||||||
|
|
||||||
// Create flat list of selected faces and their value.
|
// Create flat list of selected faces and their value.
|
||||||
Field<Type> allBoundaryValues(mesh.nBoundaryFaces());
|
Field<Type> allBoundaryValues(mesh.nBoundaryFaces());
|
||||||
for (const auto& pfld : field.boundaryField())
|
forAll(field.boundaryField(), patchi)
|
||||||
{
|
{
|
||||||
SubField<Type>
|
SubField<Type>
|
||||||
(
|
(
|
||||||
allBoundaryValues,
|
allBoundaryValues,
|
||||||
pfld.size(),
|
field.boundaryField()[patchi].size(),
|
||||||
pfld.patch().offset()
|
field.boundaryField()[patchi].patch().start()
|
||||||
) = pfld;
|
- mesh.nInternalFaces()
|
||||||
|
) = field.boundaryField()[patchi];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Override
|
// Override
|
||||||
@ -431,7 +424,8 @@ bool setFaceFieldType
|
|||||||
(
|
(
|
||||||
allBoundaryValues,
|
allBoundaryValues,
|
||||||
fieldBf[patchi].size(),
|
fieldBf[patchi].size(),
|
||||||
fieldBf[patchi].patch().offset()
|
fieldBf[patchi].patch().start()
|
||||||
|
- mesh.nInternalFaces()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -451,7 +445,7 @@ bool setFaceFieldType
|
|||||||
<< "Field " << fieldDesc.name() << " not found" << endl;
|
<< "Field " << fieldDesc.name() << " not found" << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
return isExpectedType;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -466,7 +460,7 @@ struct setCellField
|
|||||||
(
|
(
|
||||||
const fieldDescription& fieldDesc,
|
const fieldDescription& fieldDesc,
|
||||||
const fvMesh& m,
|
const fvMesh& m,
|
||||||
const labelUList& selectedCells,
|
const labelList& selectedCells,
|
||||||
Istream& is
|
Istream& is
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
@ -483,11 +477,11 @@ struct setCellField
|
|||||||
class iNew
|
class iNew
|
||||||
{
|
{
|
||||||
const fvMesh& mesh_;
|
const fvMesh& mesh_;
|
||||||
const labelUList& selected_;
|
const labelList& selected_;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
iNew(const fvMesh& mesh, const labelUList& selectedCells) noexcept
|
iNew(const fvMesh& mesh, const labelList& selectedCells)
|
||||||
:
|
:
|
||||||
mesh_(mesh),
|
mesh_(mesh),
|
||||||
selected_(selectedCells)
|
selected_(selectedCells)
|
||||||
@ -534,7 +528,7 @@ struct setFaceField
|
|||||||
(
|
(
|
||||||
const fieldDescription& fieldDesc,
|
const fieldDescription& fieldDesc,
|
||||||
const fvMesh& m,
|
const fvMesh& m,
|
||||||
const labelUList& selectedFaces,
|
const labelList& selectedFaces,
|
||||||
Istream& is
|
Istream& is
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
@ -551,11 +545,11 @@ struct setFaceField
|
|||||||
class iNew
|
class iNew
|
||||||
{
|
{
|
||||||
const fvMesh& mesh_;
|
const fvMesh& mesh_;
|
||||||
const labelUList& selected_;
|
const labelList& selected_;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
iNew(const fvMesh& mesh, const labelUList& selectedFaces) noexcept
|
iNew(const fvMesh& mesh, const labelList& selectedFaces)
|
||||||
:
|
:
|
||||||
mesh_(mesh),
|
mesh_(mesh),
|
||||||
selected_(selectedFaces)
|
selected_(selectedFaces)
|
||||||
@ -602,7 +596,7 @@ struct setAreaField
|
|||||||
(
|
(
|
||||||
const fieldDescription& fieldDesc,
|
const fieldDescription& fieldDesc,
|
||||||
const faMesh& m,
|
const faMesh& m,
|
||||||
const labelUList& selectedFaces,
|
const labelList& selectedFaces,
|
||||||
Istream& is
|
Istream& is
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
@ -619,11 +613,11 @@ struct setAreaField
|
|||||||
class iNew
|
class iNew
|
||||||
{
|
{
|
||||||
const faMesh& mesh_;
|
const faMesh& mesh_;
|
||||||
const labelUList& selected_;
|
const labelList& selected_;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
iNew(const faMesh& mesh, const labelUList& selectedFaces) noexcept
|
iNew(const faMesh& mesh, const labelList& selectedFaces)
|
||||||
:
|
:
|
||||||
mesh_(mesh),
|
mesh_(mesh),
|
||||||
selected_(selectedFaces)
|
selected_(selectedFaces)
|
||||||
@ -681,7 +675,6 @@ int main(int argc, char *argv[])
|
|||||||
);
|
);
|
||||||
|
|
||||||
#include "addRegionOption.H"
|
#include "addRegionOption.H"
|
||||||
#include "addAllFaRegionOptions.H"
|
|
||||||
|
|
||||||
// -------------------------
|
// -------------------------
|
||||||
|
|
||||||
@ -693,59 +686,15 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
#include "createNamedMesh.H"
|
#include "createNamedMesh.H"
|
||||||
|
|
||||||
// Handle -all-area-regions, -area-regions, -area-region
|
autoPtr<faMesh> faMeshPtr;
|
||||||
#include "getAllFaRegionOptions.H"
|
|
||||||
|
|
||||||
if (args.found("no-finite-area"))
|
if (!args.found("no-finite-area"))
|
||||||
{
|
{
|
||||||
areaRegionNames.clear(); // For consistency
|
faMeshPtr = faMesh::TryNew(mesh);
|
||||||
}
|
}
|
||||||
|
if (faMeshPtr)
|
||||||
// ------------------------------------------------------------------------
|
|
||||||
|
|
||||||
PtrList<faMesh> faMeshes;
|
|
||||||
|
|
||||||
// Setup all area meshes on this region
|
|
||||||
if (!areaRegionNames.empty()) // ie, !args.found("no-finite-area")
|
|
||||||
{
|
{
|
||||||
faMeshes.resize(areaRegionNames.size());
|
Info<< "Detected finite-area mesh" << nl;
|
||||||
|
|
||||||
label nGoodRegions(0);
|
|
||||||
|
|
||||||
for (const word& areaName : areaRegionNames)
|
|
||||||
{
|
|
||||||
autoPtr<faMesh> faMeshPtr = faMesh::TryNew(areaName, mesh);
|
|
||||||
|
|
||||||
if (faMeshPtr)
|
|
||||||
{
|
|
||||||
faMeshes.set(nGoodRegions++, std::move(faMeshPtr));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
faMeshes.resize(nGoodRegions);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (faMeshes.size() == 1)
|
|
||||||
{
|
|
||||||
Info<< "Using finite-area mesh";
|
|
||||||
if
|
|
||||||
(
|
|
||||||
const word& name = polyMesh::regionName(faMeshes[0].name());
|
|
||||||
!name.empty()
|
|
||||||
)
|
|
||||||
{
|
|
||||||
Info<< " [" << name << "]";
|
|
||||||
}
|
|
||||||
Info<< nl;
|
|
||||||
}
|
|
||||||
else if (faMeshes.size() > 1)
|
|
||||||
{
|
|
||||||
Info<< "Detected finite-area meshes:";
|
|
||||||
for (const faMesh& areaMesh : faMeshes)
|
|
||||||
{
|
|
||||||
Info<< " [" << areaMesh.name() << "]";
|
|
||||||
}
|
|
||||||
Info<< nl;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const word dictName("setFieldsDict");
|
const word dictName("setFieldsDict");
|
||||||
@ -763,45 +712,37 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
|
|
||||||
// Default field values
|
// Default field values
|
||||||
if
|
|
||||||
(
|
|
||||||
const auto* eptr
|
|
||||||
= setFieldsDict.findEntry("defaultFieldValues", keyType::LITERAL)
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
ITstream& is = eptr->stream();
|
const entry* eptr =
|
||||||
|
setFieldsDict.findEntry("defaultFieldValues", keyType::LITERAL);
|
||||||
|
|
||||||
Info<< "Setting volume field default values" << endl;
|
if (eptr)
|
||||||
|
|
||||||
PtrList<setCellField> defaultFieldValues
|
|
||||||
(
|
|
||||||
is,
|
|
||||||
setCellField::iNew(mesh, labelList::null())
|
|
||||||
);
|
|
||||||
|
|
||||||
for (const faMesh& areaMesh : faMeshes)
|
|
||||||
{
|
{
|
||||||
Info<< "Setting area field default values";
|
ITstream& is = eptr->stream();
|
||||||
|
|
||||||
if
|
Info<< "Setting volume field default values" << endl;
|
||||||
(
|
|
||||||
const word& name = polyMesh::regionName(areaMesh.name());
|
|
||||||
!name.empty()
|
|
||||||
)
|
|
||||||
{
|
|
||||||
Info<< " [" << name << "]";
|
|
||||||
}
|
|
||||||
Info<< endl;
|
|
||||||
|
|
||||||
is.rewind();
|
PtrList<setCellField> defaultFieldValues
|
||||||
|
|
||||||
PtrList<setAreaField> defaultAreaFieldValues
|
|
||||||
(
|
(
|
||||||
is,
|
is,
|
||||||
setAreaField::iNew(areaMesh, labelList::null())
|
setCellField::iNew(mesh, labelList::null())
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if (faMeshPtr)
|
||||||
|
{
|
||||||
|
const faMesh& areaMesh = faMeshPtr();
|
||||||
|
is.rewind();
|
||||||
|
|
||||||
|
Info<< "Setting area field default values" << endl;
|
||||||
|
|
||||||
|
PtrList<setAreaField> defaultFieldValues
|
||||||
|
(
|
||||||
|
is,
|
||||||
|
setAreaField::iNew(areaMesh, labelList::null())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
Info<< endl;
|
||||||
}
|
}
|
||||||
Info<< endl;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -827,15 +768,11 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
labelList selectedCells(subset.sortedToc());
|
labelList selectedCells(subset.sortedToc());
|
||||||
|
|
||||||
{
|
Info<< " Selected "
|
||||||
FixedList<label, 2> stats;
|
<< returnReduce(selectedCells.size(), sumOp<label>())
|
||||||
stats[0] = selectedCells.size();
|
<< '/'
|
||||||
stats[1] = mesh.nCells();
|
<< returnReduce(mesh.nCells(), sumOp<label>())
|
||||||
reduce(stats, sumOp<label>());
|
<< " cells" << nl;
|
||||||
|
|
||||||
Info<< " Selected " << stats[0] << '/' << stats[1]
|
|
||||||
<< " cells" << nl;
|
|
||||||
}
|
|
||||||
|
|
||||||
ITstream& is = region.dict().lookup("fieldValues");
|
ITstream& is = region.dict().lookup("fieldValues");
|
||||||
|
|
||||||
@ -869,8 +806,10 @@ int main(int argc, char *argv[])
|
|||||||
setFaceField::iNew(mesh, selectedFaces)
|
setFaceField::iNew(mesh, selectedFaces)
|
||||||
);
|
);
|
||||||
|
|
||||||
for (const faMesh& areaMesh : faMeshes)
|
if (faMeshPtr)
|
||||||
{
|
{
|
||||||
|
const faMesh& areaMesh = faMeshPtr();
|
||||||
|
|
||||||
const labelUList& faceLabels = areaMesh.faceLabels();
|
const labelUList& faceLabels = areaMesh.faceLabels();
|
||||||
|
|
||||||
// Transcribe from mesh faces to finite-area addressing
|
// Transcribe from mesh faces to finite-area addressing
|
||||||
@ -889,15 +828,11 @@ int main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
areaFaces.resize(nUsed);
|
areaFaces.resize(nUsed);
|
||||||
|
|
||||||
{
|
Info<< " Selected "
|
||||||
FixedList<label, 2> stats;
|
<< returnReduce(areaFaces.size(), sumOp<label>())
|
||||||
stats[0] = areaFaces.size();
|
<< '/'
|
||||||
stats[1] = faceLabels.size();
|
<< returnReduce(faceLabels.size(), sumOp<label>())
|
||||||
reduce(stats, sumOp<label>());
|
<< " area faces" << nl;
|
||||||
|
|
||||||
Info<< " Selected " << stats[0] << '/' << stats[1]
|
|
||||||
<< " area faces for " << areaMesh.name() << endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
is.rewind();
|
is.rewind();
|
||||||
|
|
||||||
|
|||||||
@ -55,8 +55,6 @@ wmake $targetType fileFormats
|
|||||||
wmake $targetType surfMesh
|
wmake $targetType surfMesh
|
||||||
wmake $targetType meshTools
|
wmake $targetType meshTools
|
||||||
|
|
||||||
#------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
wmake $targetType finiteArea
|
wmake $targetType finiteArea
|
||||||
wmake $targetType finiteVolume
|
wmake $targetType finiteVolume
|
||||||
wmake $targetType fused/finiteVolume
|
wmake $targetType fused/finiteVolume
|
||||||
|
|||||||
@ -45,6 +45,7 @@ SourceFiles
|
|||||||
|
|
||||||
#include "autoPtr.H"
|
#include "autoPtr.H"
|
||||||
#include "UList.H"
|
#include "UList.H"
|
||||||
|
#include "SLListFwd.H"
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
@ -65,7 +66,6 @@ typedef List<bool> boolList; //!< A List of bools
|
|||||||
typedef List<char> charList; //!< A List of chars
|
typedef List<char> charList; //!< A List of chars
|
||||||
typedef List<label> labelList; //!< A List of labels
|
typedef List<label> labelList; //!< A List of labels
|
||||||
|
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*\
|
/*---------------------------------------------------------------------------*\
|
||||||
Class List Declaration
|
Class List Declaration
|
||||||
\*---------------------------------------------------------------------------*/
|
\*---------------------------------------------------------------------------*/
|
||||||
@ -395,6 +395,37 @@ public:
|
|||||||
|
|
||||||
//- Alias for resize()
|
//- Alias for resize()
|
||||||
void setSize(label n, const T& val) { this->resize(n, val); }
|
void setSize(label n, const T& val) { this->resize(n, val); }
|
||||||
|
|
||||||
|
|
||||||
|
// Expression templates
|
||||||
|
|
||||||
|
//- Construct from value expression
|
||||||
|
template<typename E>
|
||||||
|
explicit List
|
||||||
|
(
|
||||||
|
const Expression::ListExpression
|
||||||
|
<
|
||||||
|
E,
|
||||||
|
typename E::value_type
|
||||||
|
>& expr
|
||||||
|
)
|
||||||
|
{
|
||||||
|
expr.evaluate(*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
//- Assign values from expression
|
||||||
|
template<typename E>
|
||||||
|
void operator=
|
||||||
|
(
|
||||||
|
const Expression::ListExpression
|
||||||
|
<
|
||||||
|
E,
|
||||||
|
typename E::value_type
|
||||||
|
>& expr
|
||||||
|
)
|
||||||
|
{
|
||||||
|
expr.evaluate(*this);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -80,6 +80,11 @@ typedef UList<bool> boolUList; //!< A UList of bools
|
|||||||
typedef UList<char> charUList; //!< A UList of chars
|
typedef UList<char> charUList; //!< A UList of chars
|
||||||
typedef UList<label> labelUList; //!< A UList of labels
|
typedef UList<label> labelUList; //!< A UList of labels
|
||||||
|
|
||||||
|
namespace Expression
|
||||||
|
{
|
||||||
|
template<class E, typename ValType> class ListExpression;
|
||||||
|
template<class T> class ListConstRefWrap;
|
||||||
|
}
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*\
|
/*---------------------------------------------------------------------------*\
|
||||||
Class UList Declaration
|
Class UList Declaration
|
||||||
@ -697,6 +702,39 @@ public:
|
|||||||
{
|
{
|
||||||
return this->contains(val, pos);
|
return this->contains(val, pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Expression templates
|
||||||
|
|
||||||
|
//- Have unique tag
|
||||||
|
using is_List = void;
|
||||||
|
|
||||||
|
//- Wrap value as expression
|
||||||
|
auto expr() const
|
||||||
|
{
|
||||||
|
return Expression::ListConstRefWrap<T>
|
||||||
|
(
|
||||||
|
reinterpret_cast<const List<T>&>(*this)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
//- Assign values from expression
|
||||||
|
template<typename E>
|
||||||
|
void operator=
|
||||||
|
(
|
||||||
|
const Expression::ListExpression
|
||||||
|
<
|
||||||
|
E,
|
||||||
|
typename E::value_type
|
||||||
|
>& expr
|
||||||
|
)
|
||||||
|
{
|
||||||
|
// bypass expr.evaluate to avoid resize ...
|
||||||
|
for (label i = 0; i < expr.size(); ++i)
|
||||||
|
{
|
||||||
|
operator[](i) = expr[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -60,6 +60,12 @@ template<class Type> class dimensioned;
|
|||||||
template<class Type>
|
template<class Type>
|
||||||
Istream& operator>>(Istream& is, dimensioned<Type>& dt);
|
Istream& operator>>(Istream& is, dimensioned<Type>& dt);
|
||||||
|
|
||||||
|
namespace Expression
|
||||||
|
{
|
||||||
|
template<class T> class UniformListWrap;
|
||||||
|
template<class GeoField> class UniformGeometricFieldWrap;
|
||||||
|
}
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*\
|
/*---------------------------------------------------------------------------*\
|
||||||
Class dimensioned Declaration
|
Class dimensioned Declaration
|
||||||
\*---------------------------------------------------------------------------*/
|
\*---------------------------------------------------------------------------*/
|
||||||
@ -449,6 +455,28 @@ public:
|
|||||||
{
|
{
|
||||||
return getOrAddToDict(name, dict, deflt);
|
return getOrAddToDict(name, dict, deflt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Expression templates
|
||||||
|
|
||||||
|
//- Wrap value as constant-value List expression
|
||||||
|
auto expr(const label size) const
|
||||||
|
{
|
||||||
|
return Expression::UniformListWrap<Type>(size, value_);
|
||||||
|
}
|
||||||
|
|
||||||
|
//- Wrap value as constant-value GeometricField expression. Supplied
|
||||||
|
// fields is used for sizing only and needs to be valid at time of
|
||||||
|
// evaluation.
|
||||||
|
template<class GeoField>
|
||||||
|
auto expr(const GeoField& fld) const
|
||||||
|
{
|
||||||
|
return Expression::UniformGeometricFieldWrap<GeoField>
|
||||||
|
(
|
||||||
|
fld,
|
||||||
|
*this
|
||||||
|
);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
252
src/OpenFOAM/expressionTemplates/GenericExpression.H
Normal file
252
src/OpenFOAM/expressionTemplates/GenericExpression.H
Normal file
@ -0,0 +1,252 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / 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 <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
Namespace
|
||||||
|
Foam::GenericExpression
|
||||||
|
|
||||||
|
Description
|
||||||
|
Expression templates.
|
||||||
|
|
||||||
|
SourceFiles
|
||||||
|
GenericExpression.H
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef Foam_GenericExpression_H
|
||||||
|
#define Foam_GenericExpression_H
|
||||||
|
|
||||||
|
#include <cassert>
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
namespace Expression
|
||||||
|
{
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
Class GenericExpression Declarations
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
template<typename E>
|
||||||
|
class GenericExpression
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static constexpr bool is_leaf = false;
|
||||||
|
|
||||||
|
auto evaluate() const
|
||||||
|
{
|
||||||
|
// Delegation to the actual expression type. This avoids dynamic
|
||||||
|
// polymorphism (a.k.a. virtual functions in C++)
|
||||||
|
return static_cast<E const&>(*this).evaluate();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// Macros
|
||||||
|
// ~~~~~~
|
||||||
|
|
||||||
|
#define EXPRESSION_FUNCTION1(BaseClass, Func, BaseFunc, OpFunc) \
|
||||||
|
template<typename E1> \
|
||||||
|
class OpFunc \
|
||||||
|
: \
|
||||||
|
public BaseClass<OpFunc<E1>> \
|
||||||
|
{ \
|
||||||
|
typename std::conditional<E1::is_leaf, const E1&, const E1>::type u_; \
|
||||||
|
\
|
||||||
|
public: \
|
||||||
|
static constexpr bool is_leaf = false; \
|
||||||
|
\
|
||||||
|
OpFunc(const E1& u) \
|
||||||
|
: \
|
||||||
|
u_(u) \
|
||||||
|
{} \
|
||||||
|
\
|
||||||
|
auto evaluate() const \
|
||||||
|
{ \
|
||||||
|
return BaseFunc(u_.evaluate()); \
|
||||||
|
} \
|
||||||
|
}; \
|
||||||
|
template<typename E1> \
|
||||||
|
OpFunc<E1> Func \
|
||||||
|
( \
|
||||||
|
const BaseClass<E1>& u \
|
||||||
|
) \
|
||||||
|
{ \
|
||||||
|
return OpFunc<E1>(static_cast<const E1&>(u)); \
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#define EXPRESSION_FUNCTION2(BaseClass, Func, BaseFunc, OpFunc) \
|
||||||
|
template<typename E1, typename E2> \
|
||||||
|
class OpFunc \
|
||||||
|
: \
|
||||||
|
public BaseClass<OpFunc<E1, E2>> \
|
||||||
|
{ \
|
||||||
|
typename std::conditional<E1::is_leaf, const E1&, const E1>::type u_; \
|
||||||
|
typename std::conditional<E2::is_leaf, const E2&, const E2>::type v_; \
|
||||||
|
\
|
||||||
|
public: \
|
||||||
|
static constexpr bool is_leaf = false; \
|
||||||
|
\
|
||||||
|
OpFunc(const E1& u, const E2& v) \
|
||||||
|
: \
|
||||||
|
u_(u), v_(v) \
|
||||||
|
{} \
|
||||||
|
auto evaluate() const \
|
||||||
|
{ \
|
||||||
|
return BaseFunc(u_.evaluate(), v_.evaluate()); \
|
||||||
|
} \
|
||||||
|
}; \
|
||||||
|
template<typename E1, typename E2> \
|
||||||
|
OpFunc<E1, E2> Func \
|
||||||
|
( \
|
||||||
|
const BaseClass<E1>& u, \
|
||||||
|
const BaseClass<E2>& v \
|
||||||
|
) \
|
||||||
|
{ \
|
||||||
|
return OpFunc<E1, E2> \
|
||||||
|
( \
|
||||||
|
static_cast<const E1&>(u), \
|
||||||
|
static_cast<const E2&>(v) \
|
||||||
|
); \
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#define EXPRESSION_OPERATOR(BaseClass, Op, BaseOp, OpFunc) \
|
||||||
|
template<typename E1, typename E2> \
|
||||||
|
class OpFunc \
|
||||||
|
: \
|
||||||
|
public BaseClass \
|
||||||
|
< \
|
||||||
|
OpFunc<E1, E2> \
|
||||||
|
> \
|
||||||
|
{ \
|
||||||
|
/* cref if leaf, copy otherwise */ \
|
||||||
|
typename std::conditional<E1::is_leaf, const E1&, const E1>::type u_; \
|
||||||
|
typename std::conditional<E2::is_leaf, const E2&, const E2>::type v_; \
|
||||||
|
\
|
||||||
|
public: \
|
||||||
|
static constexpr bool is_leaf = false; \
|
||||||
|
\
|
||||||
|
OpFunc(const E1& u, const E2& v) \
|
||||||
|
: \
|
||||||
|
u_(u), v_(v) \
|
||||||
|
{} \
|
||||||
|
auto evaluate() const \
|
||||||
|
{ \
|
||||||
|
return u_.evaluate() BaseOp v_.evaluate(); \
|
||||||
|
} \
|
||||||
|
}; \
|
||||||
|
template<typename E1, typename E2> \
|
||||||
|
OpFunc<E1, E2> \
|
||||||
|
operator Op \
|
||||||
|
( \
|
||||||
|
BaseClass<E1> const& u, \
|
||||||
|
BaseClass<E2> const& v \
|
||||||
|
) \
|
||||||
|
{ \
|
||||||
|
return OpFunc<E1, E2> \
|
||||||
|
( \
|
||||||
|
static_cast<const E1&>(u), \
|
||||||
|
static_cast<const E2&>(v) \
|
||||||
|
); \
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Do '-' separately until we work out macro expansion...
|
||||||
|
template<typename E1>
|
||||||
|
class g_negate
|
||||||
|
:
|
||||||
|
public GenericExpression
|
||||||
|
<
|
||||||
|
g_negate<E1>
|
||||||
|
>
|
||||||
|
{
|
||||||
|
typename std::conditional<E1::is_leaf, const E1&, const E1>::type u_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
static constexpr bool is_leaf = false;
|
||||||
|
|
||||||
|
g_negate(const E1& u)
|
||||||
|
:
|
||||||
|
u_(u)
|
||||||
|
{}
|
||||||
|
|
||||||
|
auto evaluate() const
|
||||||
|
{
|
||||||
|
return -u_.evaluate();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
template<typename E1>
|
||||||
|
g_negate<E1> operator-
|
||||||
|
(
|
||||||
|
const GenericExpression<E1>& u
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return g_negate<E1>(static_cast<const E1&>(u));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
EXPRESSION_FUNCTION1(GenericExpression, sqr, Foam::sqr, g_sqr)
|
||||||
|
EXPRESSION_FUNCTION1(GenericExpression, sqrt, Foam::sqrt, g_sqrt)
|
||||||
|
EXPRESSION_FUNCTION1(GenericExpression, magSqr, Foam::magSqr, g_magSqr)
|
||||||
|
EXPRESSION_FUNCTION1(GenericExpression, symm, Foam::symm, g_symm)
|
||||||
|
EXPRESSION_FUNCTION1(GenericExpression, pow2, Foam::pow2, g_pow2)
|
||||||
|
EXPRESSION_FUNCTION1(GenericExpression, pow3, Foam::pow3, g_pow3)
|
||||||
|
EXPRESSION_FUNCTION1(GenericExpression, pow4, Foam::pow4, g_pow4)
|
||||||
|
EXPRESSION_FUNCTION1(GenericExpression, operator~, Foam::operator~, g_compl)
|
||||||
|
|
||||||
|
//TBD. Parse problem
|
||||||
|
//EXPRESSION_FUNCTION1(GenericExpression, operator!, Foam::operator!, g_not)
|
||||||
|
|
||||||
|
#undef EXPRESSION_FUNCTION1
|
||||||
|
|
||||||
|
EXPRESSION_FUNCTION2(GenericExpression, operator+, Foam::operator+, g_add);
|
||||||
|
EXPRESSION_FUNCTION2(GenericExpression, operator-, Foam::operator-, g_subtract);
|
||||||
|
EXPRESSION_FUNCTION2(GenericExpression, operator*, Foam::operator*, g_multiply);
|
||||||
|
EXPRESSION_FUNCTION2(GenericExpression, operator/, Foam::operator/, g_divide);
|
||||||
|
|
||||||
|
#undef EXPRESSION_FUNCTION2
|
||||||
|
|
||||||
|
EXPRESSION_OPERATOR(GenericExpression, ||, ||, g_or)
|
||||||
|
EXPRESSION_OPERATOR(GenericExpression, &&, &&, g_and)
|
||||||
|
EXPRESSION_OPERATOR(GenericExpression, &, &, g_bitand)
|
||||||
|
EXPRESSION_OPERATOR(GenericExpression, |, |, g_bitor)
|
||||||
|
EXPRESSION_OPERATOR(GenericExpression, ^, ^, g_xor)
|
||||||
|
|
||||||
|
#undef EXPRESSION_OPERATOR
|
||||||
|
|
||||||
|
} // End namespace Expression
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
} // End namespace Foam
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
1879
src/OpenFOAM/expressionTemplates/GeometricFieldExpression.H
Normal file
1879
src/OpenFOAM/expressionTemplates/GeometricFieldExpression.H
Normal file
File diff suppressed because it is too large
Load Diff
2416
src/OpenFOAM/expressionTemplates/ListExpression.H
Normal file
2416
src/OpenFOAM/expressionTemplates/ListExpression.H
Normal file
File diff suppressed because it is too large
Load Diff
145
src/OpenFOAM/expressionTemplates/boolExpression.H
Normal file
145
src/OpenFOAM/expressionTemplates/boolExpression.H
Normal file
@ -0,0 +1,145 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / 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 <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
Namespace
|
||||||
|
Foam::boolExpression
|
||||||
|
|
||||||
|
Description
|
||||||
|
Expression templates for bool
|
||||||
|
|
||||||
|
SourceFiles
|
||||||
|
boolExpression.H
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef Foam_boolExpression_H
|
||||||
|
#define Foam_boolExpression_H
|
||||||
|
|
||||||
|
#include "GenericExpression.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
namespace Expression
|
||||||
|
{
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
Namespace Expression Declarations
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
// Wrap of non-const bool
|
||||||
|
// ~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
class boolWrap
|
||||||
|
:
|
||||||
|
public GenericExpression<boolWrap>
|
||||||
|
{
|
||||||
|
bool elems_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
static constexpr bool is_leaf = false; //true;
|
||||||
|
|
||||||
|
//- Construct from components
|
||||||
|
boolWrap(const bool elems)
|
||||||
|
:
|
||||||
|
elems_(elems)
|
||||||
|
{}
|
||||||
|
|
||||||
|
// Construct from GenericExpression, forcing its evaluation.
|
||||||
|
template<typename E>
|
||||||
|
boolWrap
|
||||||
|
(
|
||||||
|
const GenericExpression<E>& expr
|
||||||
|
)
|
||||||
|
:
|
||||||
|
elems_(expr.evaluate())
|
||||||
|
{}
|
||||||
|
|
||||||
|
auto evaluate() const
|
||||||
|
{
|
||||||
|
return elems_;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename E>
|
||||||
|
auto evaluate
|
||||||
|
(
|
||||||
|
const GenericExpression<E>& expr
|
||||||
|
)
|
||||||
|
{
|
||||||
|
elems_ = expr.evaluate();
|
||||||
|
return elems_;
|
||||||
|
}
|
||||||
|
|
||||||
|
//- Assignment
|
||||||
|
template<typename E>
|
||||||
|
void operator=
|
||||||
|
(
|
||||||
|
const GenericExpression<E>& expr
|
||||||
|
)
|
||||||
|
{
|
||||||
|
elems_ = expr.evaluate();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// Wrap of const bool
|
||||||
|
// ~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
class boolConstWrap
|
||||||
|
:
|
||||||
|
public GenericExpression<boolConstWrap>
|
||||||
|
{
|
||||||
|
const bool elems_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
// ! Store as copy (since holds reference)
|
||||||
|
static constexpr bool is_leaf = false;
|
||||||
|
|
||||||
|
// construct from components
|
||||||
|
boolConstWrap(const bool elems)
|
||||||
|
:
|
||||||
|
elems_(elems)
|
||||||
|
{}
|
||||||
|
|
||||||
|
auto evaluate() const
|
||||||
|
{
|
||||||
|
return elems_;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
} // End namespace Expression
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
} // End namespace Foam
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
148
src/OpenFOAM/expressionTemplates/dimensionSetExpression.H
Normal file
148
src/OpenFOAM/expressionTemplates/dimensionSetExpression.H
Normal file
@ -0,0 +1,148 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / 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 <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
Namespace
|
||||||
|
Foam::dimensionSetExpression
|
||||||
|
|
||||||
|
Description
|
||||||
|
Expression templates for dimensionSet
|
||||||
|
|
||||||
|
SourceFiles
|
||||||
|
dimensionSetExpression.H
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef Foam_dimensionSetExpression_H
|
||||||
|
#define Foam_dimensionSetExpression_H
|
||||||
|
|
||||||
|
#include "GenericExpression.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
namespace Expression
|
||||||
|
{
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
Namespace Expression Declarations
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
// Wrap of non-const reference to dimensionSet
|
||||||
|
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
class dimensionSetRefWrap
|
||||||
|
:
|
||||||
|
public GenericExpression<dimensionSetRefWrap>
|
||||||
|
{
|
||||||
|
dimensionSet& elems_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
static constexpr bool is_leaf = false; //true;
|
||||||
|
|
||||||
|
//- Construct from components
|
||||||
|
dimensionSetRefWrap(dimensionSet& elems)
|
||||||
|
:
|
||||||
|
elems_(elems)
|
||||||
|
{}
|
||||||
|
|
||||||
|
// Construct from GenericExpression, forcing its evaluation.
|
||||||
|
template<typename E>
|
||||||
|
dimensionSetRefWrap
|
||||||
|
(
|
||||||
|
dimensionSet& elems,
|
||||||
|
const GenericExpression<E>& expr
|
||||||
|
)
|
||||||
|
:
|
||||||
|
elems_(elems)
|
||||||
|
{
|
||||||
|
elems_ = expr.evaluate();
|
||||||
|
}
|
||||||
|
|
||||||
|
auto evaluate() const
|
||||||
|
{
|
||||||
|
return elems_;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename E>
|
||||||
|
auto& evaluate
|
||||||
|
(
|
||||||
|
const GenericExpression<E>& expr
|
||||||
|
)
|
||||||
|
{
|
||||||
|
elems_ = expr.evaluate();
|
||||||
|
return elems_;
|
||||||
|
}
|
||||||
|
|
||||||
|
//- Assignment
|
||||||
|
template<typename E>
|
||||||
|
void operator=
|
||||||
|
(
|
||||||
|
const GenericExpression<E>& expr
|
||||||
|
)
|
||||||
|
{
|
||||||
|
elems_ = expr.evaluate();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// Wrap of const reference to dimensionSet
|
||||||
|
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
class dimensionSetConstRefWrap
|
||||||
|
:
|
||||||
|
public GenericExpression<dimensionSetConstRefWrap>
|
||||||
|
{
|
||||||
|
const dimensionSet& elems_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
// ! Store as copy (since holds reference)
|
||||||
|
static constexpr bool is_leaf = false;
|
||||||
|
|
||||||
|
// construct from components
|
||||||
|
dimensionSetConstRefWrap(const dimensionSet& elems)
|
||||||
|
:
|
||||||
|
elems_(elems)
|
||||||
|
{}
|
||||||
|
|
||||||
|
auto evaluate() const
|
||||||
|
{
|
||||||
|
return elems_;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
} // End namespace Expression
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
} // End namespace Foam
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -582,6 +582,37 @@ public:
|
|||||||
|
|
||||||
friend Ostream& operator<< <Type>
|
friend Ostream& operator<< <Type>
|
||||||
(Ostream&, const tmp<Field<Type>>&);
|
(Ostream&, const tmp<Field<Type>>&);
|
||||||
|
|
||||||
|
|
||||||
|
// Expression templates
|
||||||
|
|
||||||
|
//- Construct from value expression
|
||||||
|
template<typename E>
|
||||||
|
explicit Field
|
||||||
|
(
|
||||||
|
const Expression::ListExpression
|
||||||
|
<
|
||||||
|
E,
|
||||||
|
typename E::value_type
|
||||||
|
>& expr
|
||||||
|
)
|
||||||
|
{
|
||||||
|
expr.evaluate(*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
//- Assign values from expression
|
||||||
|
template<typename E>
|
||||||
|
void operator=
|
||||||
|
(
|
||||||
|
const Expression::ListExpression
|
||||||
|
<
|
||||||
|
E,
|
||||||
|
typename E::value_type
|
||||||
|
>& expr
|
||||||
|
)
|
||||||
|
{
|
||||||
|
expr.evaluate(*this);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -1675,6 +1675,124 @@ Foam::Ostream& Foam::operator<<
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * Expression Templates * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
template<class Type, template<class> class PatchField, class GeoMesh>
|
||||||
|
template<typename E>
|
||||||
|
Foam::GeometricField<Type, PatchField, GeoMesh>::GeometricField
|
||||||
|
(
|
||||||
|
const IOobject& io,
|
||||||
|
const Mesh& mesh,
|
||||||
|
const Expression::GeometricFieldExpression
|
||||||
|
<
|
||||||
|
E,
|
||||||
|
typename E::IntExpr,
|
||||||
|
typename E::UncoupledPatchExpr,
|
||||||
|
typename E::CoupledPatchExpr,
|
||||||
|
typename E::value_type
|
||||||
|
>& expr
|
||||||
|
)
|
||||||
|
:
|
||||||
|
Internal(io, mesh, expr.dimensions(), false),
|
||||||
|
timeIndex_(this->time().timeIndex()),
|
||||||
|
boundaryField_(mesh.boundary(), *this, PatchField<Type>::calculatedType())
|
||||||
|
{
|
||||||
|
DebugInFunction
|
||||||
|
<< "Creating from expression " << nl << this->info() << endl;
|
||||||
|
|
||||||
|
bool hasRead = readIfPresent();
|
||||||
|
if (!hasRead)
|
||||||
|
{
|
||||||
|
expr.evaluate(*this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class Type, template<class> class PatchField, class GeoMesh>
|
||||||
|
template<typename E>
|
||||||
|
Foam::GeometricField<Type, PatchField, GeoMesh>::GeometricField
|
||||||
|
(
|
||||||
|
const word& name,
|
||||||
|
const Mesh& mesh,
|
||||||
|
const Expression::GeometricFieldExpression
|
||||||
|
<
|
||||||
|
E,
|
||||||
|
typename E::IntExpr,
|
||||||
|
typename E::UncoupledPatchExpr,
|
||||||
|
typename E::CoupledPatchExpr,
|
||||||
|
typename E::value_type
|
||||||
|
>& expr
|
||||||
|
)
|
||||||
|
:
|
||||||
|
Internal
|
||||||
|
(
|
||||||
|
IOobject
|
||||||
|
(
|
||||||
|
name,
|
||||||
|
mesh.time().timeName(),
|
||||||
|
mesh.thisDb()
|
||||||
|
),
|
||||||
|
mesh,
|
||||||
|
expr.dimensions(),
|
||||||
|
false
|
||||||
|
),
|
||||||
|
timeIndex_(this->time().timeIndex()),
|
||||||
|
boundaryField_(mesh.boundary(), *this, PatchField<Type>::calculatedType())
|
||||||
|
{
|
||||||
|
DebugInFunction
|
||||||
|
<< "Creating from expression " << nl << this->info() << endl;
|
||||||
|
|
||||||
|
expr.evaluate(*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class Type, template<class> class PatchField, class GeoMesh>
|
||||||
|
Foam::Expression::GeometricFieldConstRefWrap
|
||||||
|
<
|
||||||
|
Foam::GeometricField<Type, PatchField, GeoMesh>
|
||||||
|
>
|
||||||
|
Foam::GeometricField<Type, PatchField, GeoMesh>::expr() const
|
||||||
|
{
|
||||||
|
return Expression::GeometricFieldConstRefWrap<this_type>(*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class Type, template<class> class PatchField, class GeoMesh>
|
||||||
|
template<typename E>
|
||||||
|
void Foam::GeometricField<Type, PatchField, GeoMesh>::operator=
|
||||||
|
(
|
||||||
|
const Expression::GeometricFieldExpression
|
||||||
|
<
|
||||||
|
E,
|
||||||
|
typename E::IntExpr,
|
||||||
|
typename E::UncoupledPatchExpr,
|
||||||
|
typename E::CoupledPatchExpr,
|
||||||
|
typename E::value_type
|
||||||
|
>& expr
|
||||||
|
)
|
||||||
|
{
|
||||||
|
Expression::GeometricFieldRefWrap<this_type>(*this, expr);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class Type, template<class> class PatchField, class GeoMesh>
|
||||||
|
template<typename E>
|
||||||
|
void Foam::GeometricField<Type, PatchField, GeoMesh>::operator==
|
||||||
|
(
|
||||||
|
const Expression::GeometricFieldExpression
|
||||||
|
<
|
||||||
|
E,
|
||||||
|
typename E::IntExpr,
|
||||||
|
typename E::UncoupledPatchExpr,
|
||||||
|
typename E::CoupledPatchExpr,
|
||||||
|
typename E::value_type
|
||||||
|
>& expr
|
||||||
|
)
|
||||||
|
{
|
||||||
|
expr.evaluate(*this, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
#undef checkField
|
#undef checkField
|
||||||
|
|||||||
@ -42,6 +42,7 @@ SourceFiles
|
|||||||
#define Foam_GeometricField_H
|
#define Foam_GeometricField_H
|
||||||
|
|
||||||
#include "GeometricBoundaryField.H"
|
#include "GeometricBoundaryField.H"
|
||||||
|
#include "GeometricFieldExpression.H"
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
@ -1142,6 +1143,79 @@ public:
|
|||||||
{
|
{
|
||||||
return this->clamp_range(lo.value(), hi.value());
|
return this->clamp_range(lo.value(), hi.value());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Expression templates
|
||||||
|
|
||||||
|
//- Have unique tag
|
||||||
|
using is_GeometricField = void;
|
||||||
|
|
||||||
|
//- Construct from IOobject and value expression. Supports
|
||||||
|
// read_if_present
|
||||||
|
template<typename E>
|
||||||
|
GeometricField
|
||||||
|
(
|
||||||
|
const IOobject& io,
|
||||||
|
const Mesh& mesh,
|
||||||
|
const Expression::GeometricFieldExpression
|
||||||
|
<
|
||||||
|
E,
|
||||||
|
typename E::IntExpr,
|
||||||
|
typename E::UncoupledPatchExpr,
|
||||||
|
typename E::CoupledPatchExpr,
|
||||||
|
typename E::value_type
|
||||||
|
>& expr
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Construct from name, mesh and value expression.
|
||||||
|
template<typename E>
|
||||||
|
GeometricField
|
||||||
|
(
|
||||||
|
const word& name,
|
||||||
|
const Mesh& mesh,
|
||||||
|
const Expression::GeometricFieldExpression
|
||||||
|
<
|
||||||
|
E,
|
||||||
|
typename E::IntExpr,
|
||||||
|
typename E::UncoupledPatchExpr,
|
||||||
|
typename E::CoupledPatchExpr,
|
||||||
|
typename E::value_type
|
||||||
|
>& expr
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Wrap value as expression
|
||||||
|
typename Expression::GeometricFieldConstRefWrap
|
||||||
|
<
|
||||||
|
this_type
|
||||||
|
> expr() const;
|
||||||
|
|
||||||
|
//- Assign values from expression
|
||||||
|
template<typename E>
|
||||||
|
void operator=
|
||||||
|
(
|
||||||
|
const Expression::GeometricFieldExpression
|
||||||
|
<
|
||||||
|
E,
|
||||||
|
typename E::IntExpr,
|
||||||
|
typename E::UncoupledPatchExpr,
|
||||||
|
typename E::CoupledPatchExpr,
|
||||||
|
typename E::value_type
|
||||||
|
>& expr
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Assign values from expression. Override asssignable.
|
||||||
|
template<typename E>
|
||||||
|
void operator==
|
||||||
|
(
|
||||||
|
const Expression::GeometricFieldExpression
|
||||||
|
<
|
||||||
|
E,
|
||||||
|
typename E::IntExpr,
|
||||||
|
typename E::UncoupledPatchExpr,
|
||||||
|
typename E::CoupledPatchExpr,
|
||||||
|
typename E::value_type
|
||||||
|
>& expr
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -59,8 +59,17 @@ See also
|
|||||||
namespace Foam
|
namespace Foam
|
||||||
{
|
{
|
||||||
|
|
||||||
|
namespace Expression
|
||||||
|
{
|
||||||
|
template<class GeoField> class GeometricFieldConstTmpWrap;
|
||||||
|
template<class T> class ListConstTmpWrap;
|
||||||
|
}
|
||||||
|
|
||||||
// Forward Declarations
|
// Forward Declarations
|
||||||
template<class T> class refPtr;
|
template<class T> class refPtr;
|
||||||
|
template<class T> class tmp;
|
||||||
|
template<class Type, template<class> class PatchField, class GeoMesh>
|
||||||
|
class GeometricField;
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*\
|
/*---------------------------------------------------------------------------*\
|
||||||
Class tmp Declaration
|
Class tmp Declaration
|
||||||
@ -352,6 +361,33 @@ public:
|
|||||||
// \deprecated(2020-07) - use bool operator
|
// \deprecated(2020-07) - use bool operator
|
||||||
FOAM_DEPRECATED_FOR(2020-07, "bool operator")
|
FOAM_DEPRECATED_FOR(2020-07, "bool operator")
|
||||||
bool empty() const noexcept { return !ptr_; }
|
bool empty() const noexcept { return !ptr_; }
|
||||||
|
|
||||||
|
|
||||||
|
// Expression templates
|
||||||
|
|
||||||
|
//- Wrap value as expression
|
||||||
|
auto expr() const
|
||||||
|
{
|
||||||
|
// Add 'using is_GeometricField = void' to GeometricField
|
||||||
|
// Add 'using is_List = void' to List
|
||||||
|
|
||||||
|
if constexpr
|
||||||
|
(
|
||||||
|
std::is_void_v<typename T::is_GeometricField>
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return Expression::GeometricFieldConstTmpWrap<T>(*this);
|
||||||
|
}
|
||||||
|
else //if constexpr (std::is_void_v<T::is_List>)
|
||||||
|
{
|
||||||
|
return Expression::ListConstTmpWrap<T>(*this);
|
||||||
|
}
|
||||||
|
//else
|
||||||
|
//{
|
||||||
|
// //static_assert("XXX",YYY);
|
||||||
|
// return;
|
||||||
|
//}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -131,7 +131,7 @@ inline Foam::tmp<T>::tmp(const tmp<T>& rhs)
|
|||||||
if (ptr_)
|
if (ptr_)
|
||||||
{
|
{
|
||||||
ptr_->refCount::operator++();
|
ptr_->refCount::operator++();
|
||||||
this->checkUseCount();
|
//this->checkUseCount();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -162,7 +162,7 @@ inline Foam::tmp<T>::tmp(const tmp<T>& rhs, bool reuse)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
ptr_->refCount::operator++();
|
ptr_->refCount::operator++();
|
||||||
this->checkUseCount();
|
//this->checkUseCount();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|||||||
@ -855,7 +855,7 @@ bool Foam::UPstream::finishedRequest(const label i)
|
|||||||
// This allows MPI to progress behind the scenes if it wishes.
|
// This allows MPI to progress behind the scenes if it wishes.
|
||||||
|
|
||||||
int flag = 0;
|
int flag = 0;
|
||||||
if (i < 0 || i >= PstreamGlobals::outstandingRequests_.size())
|
if (i >= 0 && i < PstreamGlobals::outstandingRequests_.size())
|
||||||
{
|
{
|
||||||
auto& request = PstreamGlobals::outstandingRequests_[i];
|
auto& request = PstreamGlobals::outstandingRequests_[i];
|
||||||
|
|
||||||
|
|||||||
@ -218,9 +218,11 @@ tmp<vectorField> atmBoundaryLayer::U(const vectorField& pCf) const
|
|||||||
const scalar groundMin = zDir() & ppMin_;
|
const scalar groundMin = zDir() & ppMin_;
|
||||||
|
|
||||||
// (YGCJ:Table 1, RH:Eq. 6, HW:Eq. 5)
|
// (YGCJ:Table 1, RH:Eq. 6, HW:Eq. 5)
|
||||||
|
scalarField zEff(max((zDir() & pCf) - groundMin - d + z0, z0));
|
||||||
|
|
||||||
scalarField Un
|
scalarField Un
|
||||||
(
|
(
|
||||||
(Ustar(z0)/kappa_)*log(((zDir() & pCf) - groundMin - d + z0)/z0)
|
(Ustar(z0)/kappa_)*log(zEff/z0)
|
||||||
);
|
);
|
||||||
|
|
||||||
return flowDir()*Un;
|
return flowDir()*Un;
|
||||||
@ -235,9 +237,9 @@ tmp<scalarField> atmBoundaryLayer::k(const vectorField& pCf) const
|
|||||||
const scalar groundMin = zDir() & ppMin_;
|
const scalar groundMin = zDir() & ppMin_;
|
||||||
|
|
||||||
// (YGCJ:Eq. 21; RH:Eq. 7, HW:Eq. 6 when C1=0 and C2=1)
|
// (YGCJ:Eq. 21; RH:Eq. 7, HW:Eq. 6 when C1=0 and C2=1)
|
||||||
return
|
scalarField zEff(max((zDir() & pCf) - groundMin - d + z0, z0));
|
||||||
sqr(Ustar(z0))/sqrt(Cmu_)
|
|
||||||
*sqrt(C1_*log(((zDir() & pCf) - groundMin - d + z0)/z0) + C2_);
|
return sqr(Ustar(z0))/sqrt(Cmu_)*sqrt(C1_*log(zEff/z0) + C2_);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -249,9 +251,9 @@ tmp<scalarField> atmBoundaryLayer::epsilon(const vectorField& pCf) const
|
|||||||
const scalar groundMin = zDir() & ppMin_;
|
const scalar groundMin = zDir() & ppMin_;
|
||||||
|
|
||||||
// (YGCJ:Eq. 22; RH:Eq. 8, HW:Eq. 7 when C1=0 and C2=1)
|
// (YGCJ:Eq. 22; RH:Eq. 8, HW:Eq. 7 when C1=0 and C2=1)
|
||||||
return
|
scalarField zEff(max((zDir() & pCf) - groundMin - d + z0, z0));
|
||||||
pow3(Ustar(z0))/(kappa_*((zDir() & pCf) - groundMin - d + z0))
|
|
||||||
*sqrt(C1_*log(((zDir() & pCf) - groundMin - d + z0)/z0) + C2_);
|
return pow3(Ustar(z0))/(kappa_*zEff)*sqrt(C1_*log(zEff/z0) + C2_);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -263,7 +265,9 @@ tmp<scalarField> atmBoundaryLayer::omega(const vectorField& pCf) const
|
|||||||
const scalar groundMin = zDir() & ppMin_;
|
const scalar groundMin = zDir() & ppMin_;
|
||||||
|
|
||||||
// (YGJ:Eq. 13)
|
// (YGJ:Eq. 13)
|
||||||
return Ustar(z0)/(kappa_*sqrt(Cmu_)*((zDir() & pCf) - groundMin - d + z0));
|
scalarField zEff(max((zDir() & pCf) - groundMin - d + z0, z0));
|
||||||
|
|
||||||
|
return Ustar(z0)/(kappa_*sqrt(Cmu_)*zEff);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -9,7 +9,7 @@ faceSetOption/faceSetOption.C
|
|||||||
derivedSources=sources/derived
|
derivedSources=sources/derived
|
||||||
|
|
||||||
$(derivedSources)/externalHeatFluxSource/externalHeatFluxSource.C
|
$(derivedSources)/externalHeatFluxSource/externalHeatFluxSource.C
|
||||||
$(derivedSources)/jouleHeatingSource/jouleHeatingSource.cxx
|
$(derivedSources)/jouleHeatingSource/jouleHeatingSource.C
|
||||||
$(derivedSources)/contactHeatFluxSource/contactHeatFluxSource.C
|
$(derivedSources)/contactHeatFluxSource/contactHeatFluxSource.C
|
||||||
$(derivedSources)/externalFileSource/externalFileSource.C
|
$(derivedSources)/externalFileSource/externalFileSource.C
|
||||||
|
|
||||||
|
|||||||
@ -81,33 +81,6 @@ Foam::fa::option::option
|
|||||||
active_(dict.getOrDefault("active", true)),
|
active_(dict.getOrDefault("active", true)),
|
||||||
log(true)
|
log(true)
|
||||||
{
|
{
|
||||||
// Suffix hint for variable names
|
|
||||||
if
|
|
||||||
(
|
|
||||||
coeffs_.readIfPresent("suffixing", suffixHint_)
|
|
||||||
|| dict.readIfPresent("suffixing", suffixHint_)
|
|
||||||
)
|
|
||||||
{
|
|
||||||
Switch sw = Switch::find(suffixHint_);
|
|
||||||
|
|
||||||
if (sw.good())
|
|
||||||
{
|
|
||||||
if (!sw) // No suffix
|
|
||||||
{
|
|
||||||
suffixHint_.clear();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (suffixHint_ == "default")
|
|
||||||
{
|
|
||||||
sw = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sw) // Default suffix
|
|
||||||
{
|
|
||||||
suffixHint_ = '_' + regionName_;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dict.readIfPresent("area", areaName_))
|
if (dict.readIfPresent("area", areaName_))
|
||||||
{
|
{
|
||||||
if (!sameRegionNames(areaName_, defaultAreaName))
|
if (!sameRegionNames(areaName_, defaultAreaName))
|
||||||
@ -122,14 +95,9 @@ Foam::fa::option::option
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Log << incrIndent << indent << "Source: " << name_;
|
Log << incrIndent << indent << "Source: " << name_
|
||||||
|
<< " [" << polyMesh::regionName(areaName_) << ']' << endl
|
||||||
if (!polyMesh::regionName(areaName_).empty())
|
<< decrIndent;
|
||||||
{
|
|
||||||
Log<< " [" << areaName_ << ']';
|
|
||||||
}
|
|
||||||
|
|
||||||
Info<< decrIndent << endl;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -149,20 +117,13 @@ Foam::autoPtr<Foam::fa::option> Foam::fa::option::New
|
|||||||
coeffs.readIfPresent("area", areaName);
|
coeffs.readIfPresent("area", areaName);
|
||||||
|
|
||||||
Info<< indent
|
Info<< indent
|
||||||
<< "Selecting finite-area option, type " << modelType;
|
<< "Selecting finite-area option, type " << modelType
|
||||||
|
<< " [" << polyMesh::regionName(areaName) << ']';
|
||||||
|
|
||||||
if (sameRegionNames(areaName, defaultAreaName))
|
if (!sameRegionNames(areaName, defaultAreaName))
|
||||||
{
|
{
|
||||||
if (!polyMesh::regionName(areaName).empty())
|
Info<< " != " << defaultAreaName << nl;
|
||||||
{
|
|
||||||
Info<< " [" << areaName << ']';
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
Info<< " [" << areaName << "] != [" << defaultAreaName << ']';
|
|
||||||
}
|
|
||||||
|
|
||||||
Info<< endl;
|
Info<< endl;
|
||||||
|
|
||||||
mesh.time().libs().open
|
mesh.time().libs().open
|
||||||
|
|||||||
@ -65,13 +65,10 @@ Usage
|
|||||||
--> the selected faOption settings | dictionary | no | -
|
--> the selected faOption settings | dictionary | no | -
|
||||||
active | Flag to (de)activate faOption | bool | no | true
|
active | Flag to (de)activate faOption | bool | no | true
|
||||||
log | Flag to log faOption-related info | bool | no | true
|
log | Flag to log faOption-related info | bool | no | true
|
||||||
suffixing | Suffix hint for option variables | word | no | -
|
|
||||||
\endtable
|
\endtable
|
||||||
|
|
||||||
Note
|
Note
|
||||||
- Source/sink options are to be added to the right-hand side of equations.
|
- Source/sink options are to be added to the right-hand side of equations.
|
||||||
- Suffixing (true|false|none|default|...) currently selects between
|
|
||||||
no suffix and ('_'+region).
|
|
||||||
|
|
||||||
SourceFiles
|
SourceFiles
|
||||||
faOption.C
|
faOption.C
|
||||||
@ -139,9 +136,6 @@ protected:
|
|||||||
//- The model region name (finite-area)
|
//- The model region name (finite-area)
|
||||||
word regionName_;
|
word regionName_;
|
||||||
|
|
||||||
//- Suffix hint for variable names (default: "")
|
|
||||||
word suffixHint_;
|
|
||||||
|
|
||||||
|
|
||||||
// Protected Member Functions
|
// Protected Member Functions
|
||||||
|
|
||||||
@ -279,7 +273,7 @@ public:
|
|||||||
//- The source name
|
//- The source name
|
||||||
const word& name() const noexcept { return name_; }
|
const word& name() const noexcept { return name_; }
|
||||||
|
|
||||||
//- Return const access to the volume mesh
|
//- Return const access to the mesh database
|
||||||
const fvMesh& mesh() const noexcept { return mesh_; }
|
const fvMesh& mesh() const noexcept { return mesh_; }
|
||||||
|
|
||||||
//- Return dictionary
|
//- Return dictionary
|
||||||
@ -310,18 +304,6 @@ public:
|
|||||||
inline bool active(bool on) noexcept;
|
inline bool active(bool on) noexcept;
|
||||||
|
|
||||||
|
|
||||||
// Helper Functions
|
|
||||||
|
|
||||||
//- The suffix hint when generating variable names
|
|
||||||
const word& suffixHint() const noexcept { return suffixHint_; }
|
|
||||||
|
|
||||||
//- Return the concatenation of \p base and the suffix hint
|
|
||||||
inline word suffixed(const char* base) const;
|
|
||||||
|
|
||||||
//- Return the concatenation of \p base and the suffix hint
|
|
||||||
inline word suffixed(const std::string& base) const;
|
|
||||||
|
|
||||||
|
|
||||||
// Checks
|
// Checks
|
||||||
|
|
||||||
//- Is the source active?
|
//- Is the source active?
|
||||||
|
|||||||
@ -61,18 +61,4 @@ inline const Foam::volSurfaceMapping& Foam::fa::option::vsm() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
inline Foam::word
|
|
||||||
Foam::fa::option::suffixed(const char* base) const
|
|
||||||
{
|
|
||||||
return word(base + suffixHint_);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline Foam::word
|
|
||||||
Foam::fa::option::suffixed(const std::string& base) const
|
|
||||||
{
|
|
||||||
return word(base + suffixHint_);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
// ************************************************************************* //
|
||||||
|
|||||||
@ -27,6 +27,7 @@ License
|
|||||||
|
|
||||||
#include "faOptions.H"
|
#include "faOptions.H"
|
||||||
#include "faMesh.H"
|
#include "faMesh.H"
|
||||||
|
#include "faMeshesRegistry.H"
|
||||||
#include "Time.H"
|
#include "Time.H"
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||||
@ -67,7 +68,7 @@ Foam::IOobject createIOobject
|
|||||||
lookupName,
|
lookupName,
|
||||||
mesh.time().constant(),
|
mesh.time().constant(),
|
||||||
// located under finite-area
|
// located under finite-area
|
||||||
faMesh::Registry(mesh),
|
faMeshesRegistry::New(mesh).thisDb(),
|
||||||
IOobjectOption::MUST_READ,
|
IOobjectOption::MUST_READ,
|
||||||
IOobjectOption::NO_WRITE,
|
IOobjectOption::NO_WRITE,
|
||||||
IOobjectOption::REGISTER
|
IOobjectOption::REGISTER
|
||||||
@ -187,7 +188,11 @@ Foam::fa::options& Foam::fa::options::New
|
|||||||
);
|
);
|
||||||
|
|
||||||
// Registered under finite-area?
|
// Registered under finite-area?
|
||||||
auto* ptr = faMesh::Registry(mesh).getObjectPtr<fa::options>(lookupName);
|
auto* ptr =
|
||||||
|
faMeshesRegistry::New(mesh).thisDb().getObjectPtr<fa::options>
|
||||||
|
(
|
||||||
|
lookupName
|
||||||
|
);
|
||||||
|
|
||||||
if (!ptr && polyMesh::regionName(defaultAreaName).empty())
|
if (!ptr && polyMesh::regionName(defaultAreaName).empty())
|
||||||
{
|
{
|
||||||
|
|||||||
@ -30,6 +30,7 @@ License
|
|||||||
#include "addToRunTimeSelectionTable.H"
|
#include "addToRunTimeSelectionTable.H"
|
||||||
#include "volFields.H"
|
#include "volFields.H"
|
||||||
#include "famSup.H"
|
#include "famSup.H"
|
||||||
|
#include "zeroGradientFaPatchFields.H"
|
||||||
|
|
||||||
// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
|
||||||
|
|
||||||
@ -56,10 +57,13 @@ Foam::fa::contactHeatFluxSource::contactHeatFluxSource
|
|||||||
:
|
:
|
||||||
fa::faceSetOption(sourceName, modelType, dict, mesh, defaultAreaName),
|
fa::faceSetOption(sourceName, modelType, dict, mesh, defaultAreaName),
|
||||||
TName_(dict.getOrDefault<word>("T", "T")),
|
TName_(dict.getOrDefault<word>("T", "T")),
|
||||||
TprimaryName_(dict.getOrDefault<word>("Tprimary", "T")),
|
TprimaryName_(dict.get<word>("Tprimary")),
|
||||||
Tprimary_(mesh_.lookupObject<volScalarField>(TprimaryName_)),
|
Tprimary_(mesh_.lookupObject<volScalarField>(TprimaryName_)),
|
||||||
|
thicknessLayers_(),
|
||||||
|
kappaLayers_(),
|
||||||
contactRes_(0),
|
contactRes_(0),
|
||||||
curTimeIndex_(-1)
|
curTimeIndex_(-1),
|
||||||
|
coupling_()
|
||||||
{
|
{
|
||||||
fieldNames_.resize(1, TName_);
|
fieldNames_.resize(1, TName_);
|
||||||
|
|
||||||
@ -127,30 +131,30 @@ void Foam::fa::contactHeatFluxSource::addSup
|
|||||||
const label fieldi
|
const label fieldi
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
if (!isActive())
|
if (isActive())
|
||||||
{
|
{
|
||||||
return;
|
DebugInfo
|
||||||
}
|
<< name() << ": applying source to "
|
||||||
|
<< eqn.psi().name() << endl;
|
||||||
|
|
||||||
DebugInfo<< name() << ": applying source to " << eqn.psi().name() << endl;
|
if (curTimeIndex_ != mesh().time().timeIndex())
|
||||||
|
{
|
||||||
|
tmp<DimensionedField<scalar, areaMesh>> htcw(htc());
|
||||||
|
|
||||||
if (curTimeIndex_ != mesh().time().timeIndex())
|
// Wall temperature - mapped from primary field to finite-area
|
||||||
{
|
auto Twall = DimensionedField<scalar, areaMesh>::New
|
||||||
tmp<DimensionedField<scalar, areaMesh>> htcw(htc());
|
(
|
||||||
|
"Tw_" + option::name(),
|
||||||
|
regionMesh(),
|
||||||
|
dimensionedScalar(dimTemperature, Zero)
|
||||||
|
);
|
||||||
|
|
||||||
// Wall temperature - mapped from primary field to finite-area
|
vsm().mapInternalToSurface<scalar>(Tprimary_, Twall.ref().field());
|
||||||
auto Twall = DimensionedField<scalar, areaMesh>::New
|
|
||||||
(
|
|
||||||
"Tw_" + option::name(),
|
|
||||||
regionMesh(),
|
|
||||||
dimensionedScalar(dimTemperature, Zero)
|
|
||||||
);
|
|
||||||
|
|
||||||
vsm().mapInternalToSurface<scalar>(Tprimary_, Twall.ref().field());
|
eqn += -fam::Sp(htcw(), eqn.psi()) + htcw()*Twall;
|
||||||
|
|
||||||
eqn += -fam::Sp(htcw(), eqn.psi()) + htcw()*Twall;
|
curTimeIndex_ = mesh().time().timeIndex();
|
||||||
|
}
|
||||||
curTimeIndex_ = mesh().time().timeIndex();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -186,14 +190,8 @@ bool Foam::fa::contactHeatFluxSource::read(const dictionary& dict)
|
|||||||
|
|
||||||
const labelList& patches = regionMesh().whichPolyPatches();
|
const labelList& patches = regionMesh().whichPolyPatches();
|
||||||
|
|
||||||
if (patches.empty())
|
coupling_.clear();
|
||||||
{
|
coupling_.resize(patches.empty() ? 0 : (patches.last()+1));
|
||||||
coupling_.clear();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
coupling_.resize_null(patches.back()+1);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const label patchi : patches)
|
for (const label patchi : patches)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -40,8 +40,6 @@ Usage
|
|||||||
{
|
{
|
||||||
// Mandatory entries (unmodifiable)
|
// Mandatory entries (unmodifiable)
|
||||||
type contactHeatFluxSource;
|
type contactHeatFluxSource;
|
||||||
|
|
||||||
// Optional entries (unmodifiable)
|
|
||||||
Tprimary <TprimaryFieldName>;
|
Tprimary <TprimaryFieldName>;
|
||||||
|
|
||||||
// Optional entries (runtime modifiable)
|
// Optional entries (runtime modifiable)
|
||||||
@ -62,19 +60,12 @@ Usage
|
|||||||
\table
|
\table
|
||||||
Property | Description | Type | Reqd | Dflt
|
Property | Description | Type | Reqd | Dflt
|
||||||
type | Type name: contactHeatFluxSource | word | yes | -
|
type | Type name: contactHeatFluxSource | word | yes | -
|
||||||
|
Tprimary | Name of primary temperature field | word | yes | -
|
||||||
T | Name of operand temperature field | word | no | T
|
T | Name of operand temperature field | word | no | T
|
||||||
Tprimary | Name of primary temperature field | word | no | T
|
|
||||||
thicknessLayers | List of thicknesses of layers | scalarList | no | -
|
thicknessLayers | List of thicknesses of layers | scalarList | no | -
|
||||||
kappaLayers | List of conductivities of layers | scalarList | cndtnl | -
|
kappaLayers | List of conductivities of layers | scalarList | cndtnl | -
|
||||||
\endtable
|
\endtable
|
||||||
|
|
||||||
Fields/variables used:
|
|
||||||
\table
|
|
||||||
Property | Description | Type | Deflt
|
|
||||||
T | Temperature | shell | T
|
|
||||||
Tprimary | Temperature | volume | T
|
|
||||||
\endtable
|
|
||||||
|
|
||||||
The inherited entries are elaborated in:
|
The inherited entries are elaborated in:
|
||||||
- \link faOption.H \endlink
|
- \link faOption.H \endlink
|
||||||
- \link faceSetOption.H \endlink
|
- \link faceSetOption.H \endlink
|
||||||
@ -133,13 +124,13 @@ class contactHeatFluxSource
|
|||||||
|
|
||||||
// Private Data
|
// Private Data
|
||||||
|
|
||||||
//- Name of shell temperature field (default: "T")
|
//- Name of temperature field
|
||||||
word TName_;
|
word TName_;
|
||||||
|
|
||||||
//- Name of volume temperature field (default: "T")
|
//- Name of primary temperature field
|
||||||
const word TprimaryName_;
|
word TprimaryName_;
|
||||||
|
|
||||||
//- Primary (volume) region temperature
|
//- Primary region temperature
|
||||||
const volScalarField& Tprimary_;
|
const volScalarField& Tprimary_;
|
||||||
|
|
||||||
//- Thickness of layers
|
//- Thickness of layers
|
||||||
|
|||||||
@ -72,6 +72,10 @@ Foam::fa::externalHeatFluxSource::externalHeatFluxSource
|
|||||||
fa::faceSetOption(sourceName, modelType, dict, m, defaultAreaName),
|
fa::faceSetOption(sourceName, modelType, dict, m, defaultAreaName),
|
||||||
mode_(operationModeNames.get("mode", dict)),
|
mode_(operationModeNames.get("mode", dict)),
|
||||||
TName_(dict.getOrDefault<word>("T", "T")),
|
TName_(dict.getOrDefault<word>("T", "T")),
|
||||||
|
Q_(nullptr),
|
||||||
|
q_(nullptr),
|
||||||
|
h_(nullptr),
|
||||||
|
Ta_(nullptr),
|
||||||
emissivity_(dict.getOrDefault<scalar>("emissivity", 0))
|
emissivity_(dict.getOrDefault<scalar>("emissivity", 0))
|
||||||
{
|
{
|
||||||
fieldNames_.resize(1, TName_);
|
fieldNames_.resize(1, TName_);
|
||||||
@ -201,11 +205,6 @@ bool Foam::fa::externalHeatFluxSource::read(const dictionary& dict)
|
|||||||
|
|
||||||
mode_ = operationModeNames.get("mode", dict);
|
mode_ = operationModeNames.get("mode", dict);
|
||||||
|
|
||||||
Q_.reset(nullptr);
|
|
||||||
q_.reset(nullptr);
|
|
||||||
h_.reset(nullptr);
|
|
||||||
Ta_.reset(nullptr);
|
|
||||||
|
|
||||||
switch (mode_)
|
switch (mode_)
|
||||||
{
|
{
|
||||||
case fixedPower:
|
case fixedPower:
|
||||||
|
|||||||
@ -103,7 +103,7 @@ Usage
|
|||||||
\verbatim
|
\verbatim
|
||||||
power | Use fixed power (supply Q)
|
power | Use fixed power (supply Q)
|
||||||
flux | Use fixed heat flux (supply q)
|
flux | Use fixed heat flux (supply q)
|
||||||
coefficient | Use fixes heat transfer coefficient (supply h and Ta)
|
coefficient | Use fixes heat transfer coefficient (supply h and T)
|
||||||
\endverbatim
|
\endverbatim
|
||||||
|
|
||||||
See also
|
See also
|
||||||
@ -159,7 +159,7 @@ private:
|
|||||||
//- Operation mode
|
//- Operation mode
|
||||||
operationMode mode_;
|
operationMode mode_;
|
||||||
|
|
||||||
//- Name of shell temperature field (default: "T")
|
//- Name of temperature field
|
||||||
word TName_;
|
word TName_;
|
||||||
|
|
||||||
//- Heat power [W]
|
//- Heat power [W]
|
||||||
@ -174,7 +174,7 @@ private:
|
|||||||
//- Ambient temperature [K]
|
//- Ambient temperature [K]
|
||||||
autoPtr<Function1<scalar>> Ta_;
|
autoPtr<Function1<scalar>> Ta_;
|
||||||
|
|
||||||
//- Surface emissivity for radiative transfer to ambient (default: 0)
|
//- Optional surface emissivity for radiative transfer to ambient
|
||||||
scalar emissivity_;
|
scalar emissivity_;
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -42,12 +42,6 @@ namespace fa
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
// Implementation
|
|
||||||
#include "jouleHeatingSourceImpl.cxx"
|
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
Foam::fa::jouleHeatingSource::jouleHeatingSource
|
Foam::fa::jouleHeatingSource::jouleHeatingSource
|
||||||
@ -65,7 +59,7 @@ Foam::fa::jouleHeatingSource::jouleHeatingSource
|
|||||||
(
|
(
|
||||||
IOobject
|
IOobject
|
||||||
(
|
(
|
||||||
suffixed(IOobject::scopedName(typeName, "V")),
|
IOobject::scopedName(typeName, "V_" + regionName_),
|
||||||
regionMesh().thisDb().time().timeName(),
|
regionMesh().thisDb().time().timeName(),
|
||||||
regionMesh().thisDb(),
|
regionMesh().thisDb(),
|
||||||
IOobject::MUST_READ,
|
IOobject::MUST_READ,
|
||||||
@ -74,6 +68,8 @@ Foam::fa::jouleHeatingSource::jouleHeatingSource
|
|||||||
),
|
),
|
||||||
regionMesh()
|
regionMesh()
|
||||||
),
|
),
|
||||||
|
scalarSigmaVsTPtr_(nullptr),
|
||||||
|
tensorSigmaVsTPtr_(nullptr),
|
||||||
curTimeIndex_(-1),
|
curTimeIndex_(-1),
|
||||||
nIter_(1),
|
nIter_(1),
|
||||||
anisotropicElectricalConductivity_(false)
|
anisotropicElectricalConductivity_(false)
|
||||||
@ -82,8 +78,6 @@ Foam::fa::jouleHeatingSource::jouleHeatingSource
|
|||||||
|
|
||||||
fa::option::resetApplied();
|
fa::option::resetApplied();
|
||||||
|
|
||||||
read(dict);
|
|
||||||
|
|
||||||
if (anisotropicElectricalConductivity_)
|
if (anisotropicElectricalConductivity_)
|
||||||
{
|
{
|
||||||
Info<< " Using tensor electrical conductivity" << endl;
|
Info<< " Using tensor electrical conductivity" << endl;
|
||||||
@ -96,6 +90,8 @@ Foam::fa::jouleHeatingSource::jouleHeatingSource
|
|||||||
|
|
||||||
initialiseSigma(coeffs_, scalarSigmaVsTPtr_);
|
initialiseSigma(coeffs_, scalarSigmaVsTPtr_);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
read(dict);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -109,14 +105,12 @@ void Foam::fa::jouleHeatingSource::addSup
|
|||||||
const label fieldi
|
const label fieldi
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
if (!isActive())
|
if (isActive())
|
||||||
{
|
{
|
||||||
return;
|
DebugInfo
|
||||||
}
|
<< name() << ": applying source to "
|
||||||
|
<< eqn.psi().name() << endl;
|
||||||
|
|
||||||
DebugInfo<< name() << ": applying source to " << eqn.psi().name() << endl;
|
|
||||||
|
|
||||||
{
|
|
||||||
if (curTimeIndex_ != mesh().time().timeIndex())
|
if (curTimeIndex_ != mesh().time().timeIndex())
|
||||||
{
|
{
|
||||||
for (label i = 0; i < nIter_; ++i)
|
for (label i = 0; i < nIter_; ++i)
|
||||||
@ -124,7 +118,8 @@ void Foam::fa::jouleHeatingSource::addSup
|
|||||||
if (anisotropicElectricalConductivity_)
|
if (anisotropicElectricalConductivity_)
|
||||||
{
|
{
|
||||||
// Update sigma as a function of T if required
|
// Update sigma as a function of T if required
|
||||||
const auto& sigma = updateSigma(tensorSigmaVsTPtr_);
|
const areaTensorField& sigma =
|
||||||
|
updateSigma(tensorSigmaVsTPtr_);
|
||||||
|
|
||||||
// Solve the electrical potential equation
|
// Solve the electrical potential equation
|
||||||
faScalarMatrix VEqn(fam::laplacian(h*sigma, V_));
|
faScalarMatrix VEqn(fam::laplacian(h*sigma, V_));
|
||||||
@ -134,7 +129,8 @@ void Foam::fa::jouleHeatingSource::addSup
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Update sigma as a function of T if required
|
// Update sigma as a function of T if required
|
||||||
const auto& sigma = updateSigma(scalarSigmaVsTPtr_);
|
const areaScalarField& sigma =
|
||||||
|
updateSigma(scalarSigmaVsTPtr_);
|
||||||
|
|
||||||
// Solve the electrical potential equation
|
// Solve the electrical potential equation
|
||||||
faScalarMatrix VEqn(fam::laplacian(h*sigma, V_));
|
faScalarMatrix VEqn(fam::laplacian(h*sigma, V_));
|
||||||
@ -149,7 +145,7 @@ void Foam::fa::jouleHeatingSource::addSup
|
|||||||
// Add the Joule heating contribution
|
// Add the Joule heating contribution
|
||||||
const word sigmaName
|
const word sigmaName
|
||||||
(
|
(
|
||||||
IOobject::scopedName(typeName, "sigma") + suffixHint()
|
IOobject::scopedName(typeName, "sigma_" + regionName_)
|
||||||
);
|
);
|
||||||
|
|
||||||
areaVectorField gradV("gradV", fac::grad(V_));
|
areaVectorField gradV("gradV", fac::grad(V_));
|
||||||
@ -166,13 +162,15 @@ void Foam::fa::jouleHeatingSource::addSup
|
|||||||
|
|
||||||
if (anisotropicElectricalConductivity_)
|
if (anisotropicElectricalConductivity_)
|
||||||
{
|
{
|
||||||
const auto& sigma = obr.lookupObject<areaTensorField>(sigmaName);
|
const auto& sigma =
|
||||||
|
obr.lookupObject<areaTensorField>(sigmaName);
|
||||||
|
|
||||||
tsource = (h*sigma & gradV) & gradV;
|
tsource = (h*sigma & gradV) & gradV;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
const auto& sigma = obr.lookupObject<areaScalarField>(sigmaName);
|
const auto& sigma =
|
||||||
|
obr.lookupObject<areaScalarField>(sigmaName);
|
||||||
|
|
||||||
tsource = (h*sigma*gradV) & gradV;
|
tsource = (h*sigma*gradV) & gradV;
|
||||||
}
|
}
|
||||||
@ -115,30 +115,23 @@ Usage
|
|||||||
- \link faceSetOption.H \endlink
|
- \link faceSetOption.H \endlink
|
||||||
|
|
||||||
Note
|
Note
|
||||||
If the \c sigma entry is present, the electrical conductivity is specified
|
- \c anisotropicElectricalConductivity=true enables
|
||||||
as a function of temperature using a \c Function1 type, otherwise
|
anisotropic (tensorial) electrical conductivity.
|
||||||
the \c sigma field will be read from file.
|
- \c anisotropicElectricalConductivity=false enables
|
||||||
When the \c anisotropicElectricalConductivity flag is set to \c true,
|
isotropic (scalar) electrical conductivity.
|
||||||
\c sigma should be specified as a \em tensor quantity instead of as
|
- The electrical conductivity can be specified using either:
|
||||||
an isotropic \em scalar quantity.
|
- If the \c sigma entry is present the electrical conductivity is specified
|
||||||
|
as a function of temperature using a \c Function1 type.
|
||||||
BREAKING Naming changes from 2056 and earlier for the fields:
|
- If not present the \c sigma field will be read from file.
|
||||||
\table
|
- If the \c anisotropicElectricalConductivity flag is set to \c true,
|
||||||
Field | Scoped names | Scoped names (old)
|
\c sigma should be specified as a tensor quantity.
|
||||||
V | \<scope\>:V (suffix) | \<scope\>:V_ + regionName
|
|
||||||
sigma | \<scope\>:sigma (suffix) | \<scope\>:sigma_ + regionName
|
|
||||||
\endtable
|
|
||||||
|
|
||||||
It is possible to replicate the older naming by specifying
|
|
||||||
the \c suffixing to ('_' + regionName).
|
|
||||||
|
|
||||||
See also
|
See also
|
||||||
- Foam::Function1
|
- Foam::Function1
|
||||||
- Foam::fv::jouleHeatingSource
|
|
||||||
|
|
||||||
SourceFiles
|
SourceFiles
|
||||||
jouleHeatingSource.cxx
|
jouleHeatingSource.C
|
||||||
jouleHeatingSourceImpl.cxx
|
jouleHeatingSourceTemplates.C
|
||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
@ -195,13 +188,13 @@ class jouleHeatingSource
|
|||||||
void initialiseSigma
|
void initialiseSigma
|
||||||
(
|
(
|
||||||
const dictionary& dict,
|
const dictionary& dict,
|
||||||
autoPtr<Function1<Type>>& sigmaFunctionPtr
|
autoPtr<Function1<Type>>& sigmaVsTPtr
|
||||||
);
|
);
|
||||||
|
|
||||||
//- Update the electrical conductivity field
|
//- Update the electrical conductivity field
|
||||||
template<class Type>
|
template<class Type>
|
||||||
const GeometricField<Type, faPatchField, areaMesh>&
|
const GeometricField<Type, faPatchField, areaMesh>&
|
||||||
updateSigma(const autoPtr<Function1<Type>>& sigmaFunctionPtr) const;
|
updateSigma(const autoPtr<Function1<Type>>& sigmaVsTPtr) const;
|
||||||
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@ -236,22 +229,22 @@ public:
|
|||||||
|
|
||||||
// Member Functions
|
// Member Functions
|
||||||
|
|
||||||
// Evaluation
|
// Evaluation
|
||||||
|
|
||||||
//- Add explicit contribution to energy equation
|
//- Add explicit contribution to compressible momentum equation
|
||||||
virtual void addSup
|
virtual void addSup
|
||||||
(
|
(
|
||||||
const areaScalarField& h,
|
const areaScalarField& h,
|
||||||
const areaScalarField& rho,
|
const areaScalarField& rho,
|
||||||
faMatrix<scalar>& eqn,
|
faMatrix<scalar>& eqn,
|
||||||
const label fieldi
|
const label fieldi
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
// IO
|
// IO
|
||||||
|
|
||||||
//- Read source dictionary
|
//- Read source dictionary
|
||||||
virtual bool read(const dictionary& dict);
|
virtual bool read(const dictionary& dict);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -262,6 +255,12 @@ public:
|
|||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
#ifdef NoRepository
|
||||||
|
#include "jouleHeatingSourceTemplates.C"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// ************************************************************************* //
|
// ************************************************************************* //
|
||||||
|
|||||||
@ -5,7 +5,7 @@
|
|||||||
\\ / A nd | www.openfoam.com
|
\\ / A nd | www.openfoam.com
|
||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Copyright (C) 2019-2025 OpenCFD Ltd.
|
Copyright (C) 2019-2024 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM.
|
This file is part of OpenFOAM.
|
||||||
@ -33,21 +33,16 @@ template<class Type>
|
|||||||
void Foam::fa::jouleHeatingSource::initialiseSigma
|
void Foam::fa::jouleHeatingSource::initialiseSigma
|
||||||
(
|
(
|
||||||
const dictionary& dict,
|
const dictionary& dict,
|
||||||
autoPtr<Function1<Type>>& sigmaFunctionPtr
|
autoPtr<Function1<Type>>& sigmaVsTPtr
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
typedef GeometricField<Type, faPatchField, areaMesh> FieldType;
|
typedef GeometricField<Type, faPatchField, areaMesh> FieldType;
|
||||||
|
|
||||||
const word sigmaName
|
|
||||||
(
|
|
||||||
IOobject::scopedName(typeName, "sigma") + suffixHint()
|
|
||||||
);
|
|
||||||
|
|
||||||
auto& obr = regionMesh().thisDb();
|
auto& obr = regionMesh().thisDb();
|
||||||
|
|
||||||
IOobject io
|
IOobject io
|
||||||
(
|
(
|
||||||
sigmaName,
|
IOobject::scopedName(typeName, "sigma_" + regionName_),
|
||||||
obr.time().timeName(),
|
obr.time().timeName(),
|
||||||
obr,
|
obr,
|
||||||
IOobject::NO_READ,
|
IOobject::NO_READ,
|
||||||
@ -57,11 +52,11 @@ void Foam::fa::jouleHeatingSource::initialiseSigma
|
|||||||
|
|
||||||
autoPtr<FieldType> tsigma;
|
autoPtr<FieldType> tsigma;
|
||||||
|
|
||||||
// Is sigma defined using a Function1 type?
|
if (dict.found("sigma"))
|
||||||
sigmaFunctionPtr = Function1<Type>::NewIfPresent("sigma", dict, &mesh_);
|
|
||||||
|
|
||||||
if (sigmaFunctionPtr)
|
|
||||||
{
|
{
|
||||||
|
// Sigma to be defined using a Function1 type
|
||||||
|
sigmaVsTPtr = Function1<Type>::New("sigma", dict, &mesh_);
|
||||||
|
|
||||||
tsigma.reset
|
tsigma.reset
|
||||||
(
|
(
|
||||||
new FieldType
|
new FieldType
|
||||||
@ -94,34 +89,31 @@ template<class Type>
|
|||||||
const Foam::GeometricField<Type, Foam::faPatchField, Foam::areaMesh>&
|
const Foam::GeometricField<Type, Foam::faPatchField, Foam::areaMesh>&
|
||||||
Foam::fa::jouleHeatingSource::updateSigma
|
Foam::fa::jouleHeatingSource::updateSigma
|
||||||
(
|
(
|
||||||
const autoPtr<Function1<Type>>& sigmaFunctionPtr
|
const autoPtr<Function1<Type>>& sigmaVsTPtr
|
||||||
) const
|
) const
|
||||||
{
|
{
|
||||||
typedef GeometricField<Type, faPatchField, areaMesh> FieldType;
|
typedef GeometricField<Type, faPatchField, areaMesh> FieldType;
|
||||||
|
|
||||||
const word sigmaName
|
|
||||||
(
|
|
||||||
IOobject::scopedName(typeName, "sigma") + suffixHint()
|
|
||||||
);
|
|
||||||
|
|
||||||
const auto& obr = regionMesh().thisDb();
|
const auto& obr = regionMesh().thisDb();
|
||||||
|
|
||||||
auto& sigma = obr.lookupObjectRef<FieldType>(sigmaName);
|
auto& sigma =
|
||||||
|
obr.lookupObjectRef<FieldType>
|
||||||
|
(
|
||||||
|
IOobject::scopedName(typeName, "sigma_" + regionName_)
|
||||||
|
);
|
||||||
|
|
||||||
if (!sigmaFunctionPtr)
|
if (!sigmaVsTPtr)
|
||||||
{
|
{
|
||||||
// Electrical conductivity field, sigma, was specified by the user
|
// Electrical conductivity field, sigma, was specified by the user
|
||||||
return sigma;
|
return sigma;
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto& sigmaFunction = sigmaFunctionPtr();
|
|
||||||
|
|
||||||
const auto& T = obr.lookupObject<areaScalarField>(TName_);
|
const auto& T = obr.lookupObject<areaScalarField>(TName_);
|
||||||
|
|
||||||
// Internal field
|
// Internal field
|
||||||
forAll(sigma, i)
|
forAll(sigma, i)
|
||||||
{
|
{
|
||||||
sigma[i] = sigmaFunction.value(T[i]);
|
sigma[i] = sigmaVsTPtr->value(T[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -135,7 +127,7 @@ Foam::fa::jouleHeatingSource::updateSigma
|
|||||||
const scalarField& Tbf = T.boundaryField()[patchi];
|
const scalarField& Tbf = T.boundaryField()[patchi];
|
||||||
forAll(pf, facei)
|
forAll(pf, facei)
|
||||||
{
|
{
|
||||||
pf[facei] = sigmaFunction.value(Tbf[facei]);
|
pf[facei] = sigmaVsTPtr->value(Tbf[facei]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -28,7 +28,6 @@ License
|
|||||||
|
|
||||||
#include "faMesh.H"
|
#include "faMesh.H"
|
||||||
#include "faMeshBoundaryHalo.H"
|
#include "faMeshBoundaryHalo.H"
|
||||||
#include "faMeshesRegistry.H"
|
|
||||||
#include "faGlobalMeshData.H"
|
#include "faGlobalMeshData.H"
|
||||||
#include "Time.H"
|
#include "Time.H"
|
||||||
#include "polyMesh.H"
|
#include "polyMesh.H"
|
||||||
@ -160,12 +159,6 @@ const Foam::objectRegistry* Foam::faMesh::registry(const polyMesh& pMesh)
|
|||||||
// return obr.cfindObject<objectRegistry>(faMesh::prefix());
|
// return obr.cfindObject<objectRegistry>(faMesh::prefix());
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// Forwarding
|
|
||||||
const Foam::objectRegistry& Foam::faMesh::Registry(const polyMesh& pMesh)
|
|
||||||
{
|
|
||||||
return faMeshesRegistry::Registry(pMesh);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
const Foam::faMesh& Foam::faMesh::mesh
|
const Foam::faMesh& Foam::faMesh::mesh
|
||||||
(
|
(
|
||||||
|
|||||||
@ -751,14 +751,10 @@ public:
|
|||||||
|
|
||||||
// Database
|
// Database
|
||||||
|
|
||||||
//- Find the singleton parent registry (on the polyMesh)
|
//- The parent registry containing all finite-area meshes
|
||||||
//- that contains all objects related to finite-area.
|
//- on the polyMesh.
|
||||||
static const objectRegistry* registry(const polyMesh& pMesh);
|
static const objectRegistry* registry(const polyMesh& pMesh);
|
||||||
|
|
||||||
//- Return the singleton parent registry (on the polyMesh)
|
|
||||||
//- that contains all objects related to finite-area.
|
|
||||||
static const objectRegistry& Registry(const polyMesh& pMesh);
|
|
||||||
|
|
||||||
//- The single-region finite-area region on the polyMesh.
|
//- The single-region finite-area region on the polyMesh.
|
||||||
//- Uses lookupObject semantics - Fatal if non-existent
|
//- Uses lookupObject semantics - Fatal if non-existent
|
||||||
static const faMesh& mesh(const polyMesh& pMesh);
|
static const faMesh& mesh(const polyMesh& pMesh);
|
||||||
|
|||||||
@ -27,8 +27,8 @@ License
|
|||||||
|
|
||||||
#include "faMesh.H"
|
#include "faMesh.H"
|
||||||
#include "faMeshesRegistry.H"
|
#include "faMeshesRegistry.H"
|
||||||
#include "polyMesh.H"
|
|
||||||
#include "Time.H"
|
#include "Time.H"
|
||||||
|
#include "polyMesh.H"
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
@ -43,7 +43,6 @@ Foam::faMeshRegistry::faMeshRegistry
|
|||||||
IOobject
|
IOobject
|
||||||
(
|
(
|
||||||
(areaName.empty() ? polyMesh::defaultRegion : areaName),
|
(areaName.empty() ? polyMesh::defaultRegion : areaName),
|
||||||
mesh.thisDb().time().timeName(),
|
|
||||||
faMeshesRegistry::New(mesh).thisDb(),
|
faMeshesRegistry::New(mesh).thisDb(),
|
||||||
IOobjectOption::NO_READ,
|
IOobjectOption::NO_READ,
|
||||||
IOobjectOption::AUTO_WRITE,
|
IOobjectOption::AUTO_WRITE,
|
||||||
|
|||||||
@ -5,7 +5,7 @@
|
|||||||
\\ / A nd | www.openfoam.com
|
\\ / A nd | www.openfoam.com
|
||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Copyright (C) 2023-2025 OpenCFD Ltd.
|
Copyright (C) 2023-2024 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM.
|
This file is part of OpenFOAM.
|
||||||
@ -86,8 +86,6 @@ bool Foam::faMeshesRegistry::writeObject
|
|||||||
const bool writeOnProc
|
const bool writeOnProc
|
||||||
) const
|
) const
|
||||||
{
|
{
|
||||||
// Could also restrict to faMesh only...
|
|
||||||
//
|
|
||||||
// for (const faMesh& m : objects_.csorted<faMesh>())
|
// for (const faMesh& m : objects_.csorted<faMesh>())
|
||||||
// {
|
// {
|
||||||
// m.write(writeOnProc);
|
// m.write(writeOnProc);
|
||||||
|
|||||||
@ -5,7 +5,7 @@
|
|||||||
\\ / A nd | www.openfoam.com
|
\\ / A nd | www.openfoam.com
|
||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Copyright (C) 2023-2025 OpenCFD Ltd.
|
Copyright (C) 2023-2024 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM.
|
This file is part of OpenFOAM.
|
||||||
@ -144,34 +144,14 @@ public:
|
|||||||
explicit faMeshesRegistry(const polyMesh& mesh);
|
explicit faMeshesRegistry(const polyMesh& mesh);
|
||||||
|
|
||||||
|
|
||||||
// Factory Methods
|
|
||||||
|
|
||||||
//- Return the registry of objects on the singleton.
|
|
||||||
// Same as New(mesh).thisDb()
|
|
||||||
FOAM_NO_DANGLING_REFERENCE //< Reference stored in registry
|
|
||||||
static const objectRegistry& Registry(const polyMesh& mesh)
|
|
||||||
{
|
|
||||||
return MeshObject_type::New(mesh).thisDb();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Database
|
// Database
|
||||||
|
|
||||||
// It redirects to the private objects but uses some
|
//- Return the object registry
|
||||||
// objectRegistry method naming
|
|
||||||
|
|
||||||
//- The registry of the objects
|
|
||||||
const objectRegistry& thisDb() const noexcept
|
const objectRegistry& thisDb() const noexcept
|
||||||
{
|
{
|
||||||
return objects_;
|
return objects_;
|
||||||
}
|
}
|
||||||
|
|
||||||
//- Local relative to time
|
|
||||||
const fileName& dbDir() const
|
|
||||||
{
|
|
||||||
return objects_.dbDir();
|
|
||||||
}
|
|
||||||
|
|
||||||
//- The polyMesh reference
|
//- The polyMesh reference
|
||||||
const polyMesh& mesh() const noexcept
|
const polyMesh& mesh() const noexcept
|
||||||
{
|
{
|
||||||
|
|||||||
1747
src/finiteVolume/expressionTemplates/fvMatrixExpression.H
Normal file
1747
src/finiteVolume/expressionTemplates/fvMatrixExpression.H
Normal file
File diff suppressed because it is too large
Load Diff
@ -1,4 +1,4 @@
|
|||||||
/*---------------------------------------------------------------------------*\
|
/*---------------------------------------------------------------------------*\
|
||||||
========= |
|
========= |
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
\\ / O peration |
|
\\ / O peration |
|
||||||
@ -36,23 +36,18 @@ License
|
|||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
template<class Type, class Stencil>
|
template<class Type, class Stencil>
|
||||||
Foam::tmp
|
void Foam::fv::LeastSquaresGrad<Type, Stencil>::calcGrad
|
||||||
<
|
|
||||||
Foam::GeometricField
|
|
||||||
<
|
|
||||||
typename Foam::outerProduct<Foam::vector, Type>::type,
|
|
||||||
Foam::fvPatchField,
|
|
||||||
Foam::volMesh
|
|
||||||
>
|
|
||||||
>
|
|
||||||
Foam::fv::LeastSquaresGrad<Type, Stencil>::calcGrad
|
|
||||||
(
|
(
|
||||||
const GeometricField<Type, fvPatchField, volMesh>& vtf,
|
GeometricField
|
||||||
const word& name
|
<
|
||||||
|
typename outerProduct<vector, Type>::type,
|
||||||
|
fvPatchField,
|
||||||
|
volMesh
|
||||||
|
>& lsGrad,
|
||||||
|
const GeometricField<Type, fvPatchField, volMesh>& vtf
|
||||||
) const
|
) const
|
||||||
{
|
{
|
||||||
typedef typename outerProduct<vector, Type>::type GradType;
|
typedef typename outerProduct<vector, Type>::type GradType;
|
||||||
typedef GeometricField<GradType, fvPatchField, volMesh> GradFieldType;
|
|
||||||
|
|
||||||
const fvMesh& mesh = vtf.mesh();
|
const fvMesh& mesh = vtf.mesh();
|
||||||
|
|
||||||
@ -62,24 +57,7 @@ Foam::fv::LeastSquaresGrad<Type, Stencil>::calcGrad
|
|||||||
mesh
|
mesh
|
||||||
);
|
);
|
||||||
|
|
||||||
tmp<GradFieldType> tlsGrad
|
lsGrad = dimensioned<GradType>(vtf.dimensions()/dimLength, Zero);
|
||||||
(
|
|
||||||
new GradFieldType
|
|
||||||
(
|
|
||||||
IOobject
|
|
||||||
(
|
|
||||||
name,
|
|
||||||
vtf.instance(),
|
|
||||||
mesh,
|
|
||||||
IOobject::NO_READ,
|
|
||||||
IOobject::NO_WRITE
|
|
||||||
),
|
|
||||||
mesh,
|
|
||||||
dimensioned<GradType>(vtf.dimensions()/dimLength, Zero),
|
|
||||||
fvPatchFieldBase::extrapolatedCalculatedType()
|
|
||||||
)
|
|
||||||
);
|
|
||||||
GradFieldType& lsGrad = tlsGrad.ref();
|
|
||||||
Field<GradType>& lsGradIf = lsGrad;
|
Field<GradType>& lsGradIf = lsGrad;
|
||||||
|
|
||||||
const extendedCentredCellToCellStencil& stencil = lsv.stencil();
|
const extendedCentredCellToCellStencil& stencil = lsv.stencil();
|
||||||
@ -131,6 +109,50 @@ Foam::fv::LeastSquaresGrad<Type, Stencil>::calcGrad
|
|||||||
// Correct the boundary conditions
|
// Correct the boundary conditions
|
||||||
lsGrad.correctBoundaryConditions();
|
lsGrad.correctBoundaryConditions();
|
||||||
gaussGrad<Type>::correctBoundaryConditions(vtf, lsGrad);
|
gaussGrad<Type>::correctBoundaryConditions(vtf, lsGrad);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class Type, class Stencil>
|
||||||
|
Foam::tmp
|
||||||
|
<
|
||||||
|
Foam::GeometricField
|
||||||
|
<
|
||||||
|
typename Foam::outerProduct<Foam::vector, Type>::type,
|
||||||
|
Foam::fvPatchField,
|
||||||
|
Foam::volMesh
|
||||||
|
>
|
||||||
|
>
|
||||||
|
Foam::fv::LeastSquaresGrad<Type, Stencil>::calcGrad
|
||||||
|
(
|
||||||
|
const GeometricField<Type, fvPatchField, volMesh>& vtf,
|
||||||
|
const word& name
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
typedef typename outerProduct<vector, Type>::type GradType;
|
||||||
|
typedef GeometricField<GradType, fvPatchField, volMesh> GradFieldType;
|
||||||
|
|
||||||
|
const fvMesh& mesh = vtf.mesh();
|
||||||
|
|
||||||
|
tmp<GradFieldType> tlsGrad
|
||||||
|
(
|
||||||
|
new GradFieldType
|
||||||
|
(
|
||||||
|
IOobject
|
||||||
|
(
|
||||||
|
name,
|
||||||
|
vtf.instance(),
|
||||||
|
mesh,
|
||||||
|
IOobject::NO_READ,
|
||||||
|
IOobject::NO_WRITE
|
||||||
|
),
|
||||||
|
mesh,
|
||||||
|
vtf.dimensions()/dimLength,
|
||||||
|
fvPatchFieldBase::extrapolatedCalculatedType()
|
||||||
|
)
|
||||||
|
);
|
||||||
|
GradFieldType& lsGrad = tlsGrad.ref();
|
||||||
|
|
||||||
|
calcGrad(lsGrad, vtf);
|
||||||
|
|
||||||
return tlsGrad;
|
return tlsGrad;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -132,6 +132,14 @@ public:
|
|||||||
const GeometricField<Type, fvPatchField, volMesh>& vsf,
|
const GeometricField<Type, fvPatchField, volMesh>& vsf,
|
||||||
const word& name
|
const word& name
|
||||||
) const;
|
) const;
|
||||||
|
|
||||||
|
//- Calculate the grad of the given field into supplied field
|
||||||
|
virtual void calcGrad
|
||||||
|
(
|
||||||
|
GeometricField
|
||||||
|
<typename outerProduct<vector, Type>::type, fvPatchField, volMesh>& res,
|
||||||
|
const GeometricField<Type, fvPatchField, volMesh>&
|
||||||
|
) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -38,19 +38,21 @@ License
|
|||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
template<class Type>
|
template<class Type>
|
||||||
Foam::tmp
|
void Foam::fv::fourthGrad<Type>::calcGrad
|
||||||
<
|
|
||||||
Foam::GeometricField
|
|
||||||
<
|
|
||||||
typename Foam::outerProduct<Foam::vector, Type>::type,
|
|
||||||
Foam::fvPatchField,
|
|
||||||
Foam::volMesh
|
|
||||||
>
|
|
||||||
>
|
|
||||||
Foam::fv::fourthGrad<Type>::calcGrad
|
|
||||||
(
|
(
|
||||||
|
GeometricField
|
||||||
|
<
|
||||||
|
typename outerProduct<vector, Type>::type,
|
||||||
|
fvPatchField,
|
||||||
|
volMesh
|
||||||
|
>& fGrad,
|
||||||
const GeometricField<Type, fvPatchField, volMesh>& vsf,
|
const GeometricField<Type, fvPatchField, volMesh>& vsf,
|
||||||
const word& name
|
const GeometricField
|
||||||
|
<
|
||||||
|
typename outerProduct<vector, Type>::type,
|
||||||
|
fvPatchField,
|
||||||
|
volMesh
|
||||||
|
>& secondfGrad
|
||||||
) const
|
) const
|
||||||
{
|
{
|
||||||
// The fourth-order gradient is calculated in two passes. First,
|
// The fourth-order gradient is calculated in two passes. First,
|
||||||
@ -59,37 +61,11 @@ Foam::fv::fourthGrad<Type>::calcGrad
|
|||||||
// gradient to complete the accuracy.
|
// gradient to complete the accuracy.
|
||||||
|
|
||||||
typedef typename outerProduct<vector, Type>::type GradType;
|
typedef typename outerProduct<vector, Type>::type GradType;
|
||||||
typedef GeometricField<GradType, fvPatchField, volMesh> GradFieldType;
|
|
||||||
|
|
||||||
const fvMesh& mesh = vsf.mesh();
|
const fvMesh& mesh = vsf.mesh();
|
||||||
|
|
||||||
// Assemble the second-order least-square gradient
|
// Initialise to gradient
|
||||||
// Calculate the second-order least-square gradient
|
fGrad = secondfGrad;
|
||||||
tmp<GradFieldType> tsecondfGrad
|
|
||||||
= leastSquaresGrad<Type>(mesh).grad
|
|
||||||
(
|
|
||||||
vsf,
|
|
||||||
"leastSquaresGrad(" + vsf.name() + ")"
|
|
||||||
);
|
|
||||||
const GradFieldType& secondfGrad =
|
|
||||||
tsecondfGrad();
|
|
||||||
|
|
||||||
tmp<GradFieldType> tfGrad
|
|
||||||
(
|
|
||||||
new GradFieldType
|
|
||||||
(
|
|
||||||
IOobject
|
|
||||||
(
|
|
||||||
name,
|
|
||||||
vsf.instance(),
|
|
||||||
mesh,
|
|
||||||
IOobject::NO_READ,
|
|
||||||
IOobject::NO_WRITE
|
|
||||||
),
|
|
||||||
secondfGrad
|
|
||||||
)
|
|
||||||
);
|
|
||||||
GradFieldType& fGrad = tfGrad.ref();
|
|
||||||
|
|
||||||
const vectorField& C = mesh.C();
|
const vectorField& C = mesh.C();
|
||||||
|
|
||||||
@ -158,9 +134,102 @@ Foam::fv::fourthGrad<Type>::calcGrad
|
|||||||
|
|
||||||
fGrad.correctBoundaryConditions();
|
fGrad.correctBoundaryConditions();
|
||||||
gaussGrad<Type>::correctBoundaryConditions(vsf, fGrad);
|
gaussGrad<Type>::correctBoundaryConditions(vsf, fGrad);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class Type>
|
||||||
|
Foam::tmp
|
||||||
|
<
|
||||||
|
Foam::GeometricField
|
||||||
|
<
|
||||||
|
typename Foam::outerProduct<Foam::vector, Type>::type,
|
||||||
|
Foam::fvPatchField,
|
||||||
|
Foam::volMesh
|
||||||
|
>
|
||||||
|
>
|
||||||
|
Foam::fv::fourthGrad<Type>::calcGrad
|
||||||
|
(
|
||||||
|
const GeometricField<Type, fvPatchField, volMesh>& vsf,
|
||||||
|
const word& name
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
// The fourth-order gradient is calculated in two passes. First,
|
||||||
|
// the standard least-square gradient is assembled. Then, the
|
||||||
|
// fourth-order correction is added to the second-order accurate
|
||||||
|
// gradient to complete the accuracy.
|
||||||
|
|
||||||
|
typedef typename outerProduct<vector, Type>::type GradType;
|
||||||
|
typedef GeometricField<GradType, fvPatchField, volMesh> GradFieldType;
|
||||||
|
|
||||||
|
const fvMesh& mesh = vsf.mesh();
|
||||||
|
|
||||||
|
// Assemble the second-order least-square gradient
|
||||||
|
// Calculate the second-order least-square gradient
|
||||||
|
tmp<GradFieldType> tsecondfGrad
|
||||||
|
= leastSquaresGrad<Type>(mesh).grad
|
||||||
|
(
|
||||||
|
vsf,
|
||||||
|
"leastSquaresGrad(" + vsf.name() + ")"
|
||||||
|
);
|
||||||
|
const GradFieldType& secondfGrad = tsecondfGrad();
|
||||||
|
|
||||||
|
tmp<GradFieldType> tfGrad
|
||||||
|
(
|
||||||
|
new GradFieldType
|
||||||
|
(
|
||||||
|
IOobject
|
||||||
|
(
|
||||||
|
name,
|
||||||
|
vsf.instance(),
|
||||||
|
mesh,
|
||||||
|
IOobject::NO_READ,
|
||||||
|
IOobject::NO_WRITE
|
||||||
|
),
|
||||||
|
mesh,
|
||||||
|
vsf.dimensions()/dimLength,
|
||||||
|
fvPatchFieldBase::extrapolatedCalculatedType()
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
calcGrad(tfGrad.ref(), vsf, secondfGrad);
|
||||||
|
|
||||||
return tfGrad;
|
return tfGrad;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class Type>
|
||||||
|
void Foam::fv::fourthGrad<Type>::calcGrad
|
||||||
|
(
|
||||||
|
GeometricField
|
||||||
|
<
|
||||||
|
typename outerProduct<vector, Type>::type,
|
||||||
|
fvPatchField,
|
||||||
|
volMesh
|
||||||
|
>& fGrad,
|
||||||
|
const GeometricField<Type, fvPatchField, volMesh>& vsf
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
// The fourth-order gradient is calculated in two passes. First,
|
||||||
|
// the standard least-square gradient is assembled. Then, the
|
||||||
|
// fourth-order correction is added to the second-order accurate
|
||||||
|
// gradient to complete the accuracy.
|
||||||
|
|
||||||
|
typedef typename outerProduct<vector, Type>::type GradType;
|
||||||
|
typedef GeometricField<GradType, fvPatchField, volMesh> GradFieldType;
|
||||||
|
|
||||||
|
const fvMesh& mesh = vsf.mesh();
|
||||||
|
|
||||||
|
// Assemble the second-order least-square gradient
|
||||||
|
// Calculate the second-order least-square gradient
|
||||||
|
tmp<GradFieldType> tsecondfGrad
|
||||||
|
= leastSquaresGrad<Type>(mesh).grad
|
||||||
|
(
|
||||||
|
vsf,
|
||||||
|
"leastSquaresGrad(" + vsf.name() + ")"
|
||||||
|
);
|
||||||
|
|
||||||
|
calcGrad(fGrad, vsf, tsecondfGrad());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
// ************************************************************************* //
|
||||||
|
|||||||
@ -99,6 +99,32 @@ public:
|
|||||||
const GeometricField<Type, fvPatchField, volMesh>& vsf,
|
const GeometricField<Type, fvPatchField, volMesh>& vsf,
|
||||||
const word& name
|
const word& name
|
||||||
) const;
|
) const;
|
||||||
|
|
||||||
|
//- Calculate the grad of the given field into supplied field
|
||||||
|
virtual void calcGrad
|
||||||
|
(
|
||||||
|
GeometricField
|
||||||
|
<typename outerProduct<vector, Type>::type, fvPatchField, volMesh>& res,
|
||||||
|
const GeometricField<Type, fvPatchField, volMesh>&
|
||||||
|
) const;
|
||||||
|
|
||||||
|
//- Helper : calculate the grad of the given field into supplied field
|
||||||
|
void calcGrad
|
||||||
|
(
|
||||||
|
GeometricField
|
||||||
|
<
|
||||||
|
typename outerProduct<vector, Type>::type,
|
||||||
|
fvPatchField,
|
||||||
|
volMesh
|
||||||
|
>& fGrad,
|
||||||
|
const GeometricField<Type, fvPatchField, volMesh>& vsf,
|
||||||
|
const GeometricField
|
||||||
|
<
|
||||||
|
typename outerProduct<vector, Type>::type,
|
||||||
|
fvPatchField,
|
||||||
|
volMesh
|
||||||
|
>& secondfGrad
|
||||||
|
) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -140,6 +140,67 @@ Foam::fv::gaussGrad<Type>::calcGrad
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class Type>
|
||||||
|
void Foam::fv::gaussGrad<Type>::calcGrad
|
||||||
|
(
|
||||||
|
GeometricField
|
||||||
|
<
|
||||||
|
typename outerProduct<vector, Type>::type,
|
||||||
|
fvPatchField,
|
||||||
|
volMesh
|
||||||
|
>& gGrad,
|
||||||
|
const GeometricField<Type, fvPatchField, volMesh>& vsf
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
typedef typename outerProduct<vector, Type>::type GradType;
|
||||||
|
|
||||||
|
DebugPout<< "gaussGrad<Type>::calcGrad on " << vsf.name()
|
||||||
|
<< " into " << gGrad.name() << endl;
|
||||||
|
|
||||||
|
const fvMesh& mesh = vsf.mesh();
|
||||||
|
const labelUList& owner = mesh.owner();
|
||||||
|
const labelUList& neighbour = mesh.neighbour();
|
||||||
|
const vectorField& Sf = mesh.Sf();
|
||||||
|
|
||||||
|
const auto tssf(tinterpScheme_().interpolate(vsf));
|
||||||
|
const auto& ssf = tssf();
|
||||||
|
|
||||||
|
gGrad = dimensioned<GradType>(vsf.dimensions()/dimLength, Zero);
|
||||||
|
|
||||||
|
Field<GradType>& igGrad = gGrad;
|
||||||
|
const Field<Type>& 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<Type>& pssf = ssf.boundaryField()[patchi];
|
||||||
|
|
||||||
|
forAll(mesh.boundary()[patchi], facei)
|
||||||
|
{
|
||||||
|
igGrad[pFaceCells[facei]] += pSf[facei]*pssf[facei];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
igGrad /= mesh.V();
|
||||||
|
|
||||||
|
gGrad.correctBoundaryConditions();
|
||||||
|
|
||||||
|
correctBoundaryConditions(vsf, gGrad);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
template<class Type>
|
template<class Type>
|
||||||
void Foam::fv::gaussGrad<Type>::correctBoundaryConditions
|
void Foam::fv::gaussGrad<Type>::correctBoundaryConditions
|
||||||
(
|
(
|
||||||
|
|||||||
@ -145,6 +145,14 @@ public:
|
|||||||
const word& name
|
const word& name
|
||||||
) const;
|
) const;
|
||||||
|
|
||||||
|
//- Calculate the grad of the given field into supplied field
|
||||||
|
virtual void calcGrad
|
||||||
|
(
|
||||||
|
GeometricField
|
||||||
|
<typename outerProduct<vector, Type>::type, fvPatchField, volMesh>& res,
|
||||||
|
const GeometricField<Type, fvPatchField, volMesh>&
|
||||||
|
) const;
|
||||||
|
|
||||||
//- Correct the boundary values of the gradient using the patchField
|
//- Correct the boundary values of the gradient using the patchField
|
||||||
//- snGrad functions
|
//- snGrad functions
|
||||||
static void correctBoundaryConditions
|
static void correctBoundaryConditions
|
||||||
|
|||||||
@ -96,7 +96,7 @@ Foam::fv::gradScheme<Type>::grad
|
|||||||
GradFieldType* pgGrad =
|
GradFieldType* pgGrad =
|
||||||
mesh().objectRegistry::template getObjectPtr<GradFieldType>(name);
|
mesh().objectRegistry::template getObjectPtr<GradFieldType>(name);
|
||||||
|
|
||||||
if (!this->mesh().cache(name) || this->mesh().changing())
|
if (!this->mesh().cache(name) || this->mesh().topoChanging())
|
||||||
{
|
{
|
||||||
// Delete any old occurrences to avoid double registration
|
// Delete any old occurrences to avoid double registration
|
||||||
if (pgGrad && pgGrad->ownedByRegistry())
|
if (pgGrad && pgGrad->ownedByRegistry())
|
||||||
@ -119,17 +119,14 @@ Foam::fv::gradScheme<Type>::grad
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (pgGrad->upToDate(vsf))
|
if (pgGrad->upToDate(vsf) && this->mesh().upToDatePoints(*pgGrad))
|
||||||
{
|
{
|
||||||
solution::cachePrintMessage("Reusing", name, vsf);
|
solution::cachePrintMessage("Reusing", name, vsf);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
solution::cachePrintMessage("Updating", name, vsf);
|
solution::cachePrintMessage("Updating", name, vsf);
|
||||||
delete pgGrad;
|
calcGrad(*pgGrad, vsf);
|
||||||
|
|
||||||
pgGrad = calcGrad(vsf, name).ptr();
|
|
||||||
regIOobject::store(pgGrad);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -180,4 +177,23 @@ Foam::fv::gradScheme<Type>::grad
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class Type>
|
||||||
|
void Foam::fv::gradScheme<Type>::calcGrad
|
||||||
|
(
|
||||||
|
GeometricField
|
||||||
|
<
|
||||||
|
typename outerProduct<vector, Type>::type,
|
||||||
|
fvPatchField,
|
||||||
|
volMesh
|
||||||
|
>& result,
|
||||||
|
const GeometricField<Type, fvPatchField, volMesh>& vsf
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
DebugPout<< "gradScheme<Type>::calcGrad on " << vsf.name()
|
||||||
|
<< " into " << result.name() << endl;
|
||||||
|
|
||||||
|
result = calcGrad(vsf, result.name());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
// ************************************************************************* //
|
||||||
|
|||||||
@ -142,6 +142,14 @@ public:
|
|||||||
const word& name
|
const word& name
|
||||||
) const = 0;
|
) const = 0;
|
||||||
|
|
||||||
|
//- Calculate the grad of the given field into supplied field
|
||||||
|
virtual void calcGrad
|
||||||
|
(
|
||||||
|
GeometricField
|
||||||
|
<typename outerProduct<vector, Type>::type, fvPatchField, volMesh>& res,
|
||||||
|
const GeometricField<Type, fvPatchField, volMesh>&
|
||||||
|
) const;
|
||||||
|
|
||||||
//- Calculate and return the grad of the given field
|
//- Calculate and return the grad of the given field
|
||||||
//- which may have been cached
|
//- which may have been cached
|
||||||
tmp
|
tmp
|
||||||
|
|||||||
@ -62,40 +62,25 @@ void Foam::fv::cellLimitedGrad<Type, Limiter>::limitGradient
|
|||||||
|
|
||||||
|
|
||||||
template<class Type, class Limiter>
|
template<class Type, class Limiter>
|
||||||
Foam::tmp
|
void Foam::fv::cellLimitedGrad<Type, Limiter>::calcGrad
|
||||||
<
|
|
||||||
Foam::GeometricField
|
|
||||||
<
|
|
||||||
typename Foam::outerProduct<Foam::vector, Type>::type,
|
|
||||||
Foam::fvPatchField,
|
|
||||||
Foam::volMesh
|
|
||||||
>
|
|
||||||
>
|
|
||||||
Foam::fv::cellLimitedGrad<Type, Limiter>::calcGrad
|
|
||||||
(
|
(
|
||||||
const GeometricField<Type, fvPatchField, volMesh>& vsf,
|
|
||||||
const word& name
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
const fvMesh& mesh = vsf.mesh();
|
|
||||||
|
|
||||||
tmp
|
|
||||||
<
|
|
||||||
GeometricField
|
|
||||||
<typename outerProduct<vector, Type>::type, fvPatchField, volMesh>
|
|
||||||
> tGrad = basicGradScheme_().calcGrad(vsf, name);
|
|
||||||
|
|
||||||
if (k_ < SMALL)
|
|
||||||
{
|
|
||||||
return tGrad;
|
|
||||||
}
|
|
||||||
|
|
||||||
GeometricField
|
GeometricField
|
||||||
<
|
<
|
||||||
typename outerProduct<vector, Type>::type,
|
typename outerProduct<vector, Type>::type,
|
||||||
fvPatchField,
|
fvPatchField,
|
||||||
volMesh
|
volMesh
|
||||||
>& g = tGrad.ref();
|
>& g,
|
||||||
|
const GeometricField<Type, fvPatchField, volMesh>& vsf
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
const fvMesh& mesh = vsf.mesh();
|
||||||
|
|
||||||
|
basicGradScheme_().calcGrad(g, vsf);
|
||||||
|
|
||||||
|
if (k_ < SMALL)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const labelUList& owner = mesh.owner();
|
const labelUList& owner = mesh.owner();
|
||||||
const labelUList& neighbour = mesh.neighbour();
|
const labelUList& neighbour = mesh.neighbour();
|
||||||
@ -227,6 +212,49 @@ Foam::fv::cellLimitedGrad<Type, Limiter>::calcGrad
|
|||||||
limitGradient(limiter, g);
|
limitGradient(limiter, g);
|
||||||
g.correctBoundaryConditions();
|
g.correctBoundaryConditions();
|
||||||
gaussGrad<Type>::correctBoundaryConditions(vsf, g);
|
gaussGrad<Type>::correctBoundaryConditions(vsf, g);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class Type, class Limiter>
|
||||||
|
Foam::tmp
|
||||||
|
<
|
||||||
|
Foam::GeometricField
|
||||||
|
<
|
||||||
|
typename Foam::outerProduct<Foam::vector, Type>::type,
|
||||||
|
Foam::fvPatchField,
|
||||||
|
Foam::volMesh
|
||||||
|
>
|
||||||
|
>
|
||||||
|
Foam::fv::cellLimitedGrad<Type, Limiter>::calcGrad
|
||||||
|
(
|
||||||
|
const GeometricField<Type, fvPatchField, volMesh>& vsf,
|
||||||
|
const word& name
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
typedef typename outerProduct<vector, Type>::type GradType;
|
||||||
|
typedef GeometricField<GradType, fvPatchField, volMesh> GradFieldType;
|
||||||
|
|
||||||
|
const fvMesh& mesh = vsf.mesh();
|
||||||
|
|
||||||
|
tmp<GradFieldType> tGrad
|
||||||
|
(
|
||||||
|
new GradFieldType
|
||||||
|
(
|
||||||
|
IOobject
|
||||||
|
(
|
||||||
|
name,
|
||||||
|
vsf.instance(),
|
||||||
|
mesh,
|
||||||
|
IOobject::NO_READ,
|
||||||
|
IOobject::NO_WRITE
|
||||||
|
),
|
||||||
|
mesh,
|
||||||
|
vsf.dimensions()/dimLength,
|
||||||
|
fvPatchFieldBase::extrapolatedCalculatedType()
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
calcGrad(tGrad.ref(), vsf);
|
||||||
|
|
||||||
return tGrad;
|
return tGrad;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -150,6 +150,14 @@ public:
|
|||||||
const GeometricField<Type, fvPatchField, volMesh>& vsf,
|
const GeometricField<Type, fvPatchField, volMesh>& vsf,
|
||||||
const word& name
|
const word& name
|
||||||
) const;
|
) const;
|
||||||
|
|
||||||
|
//- Calculate the grad of the given field into supplied field
|
||||||
|
virtual void calcGrad
|
||||||
|
(
|
||||||
|
GeometricField
|
||||||
|
<typename outerProduct<vector, Type>::type, fvPatchField, volMesh>& res,
|
||||||
|
const GeometricField<Type, fvPatchField, volMesh>&
|
||||||
|
) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -2984,6 +2984,77 @@ Foam::Ostream& Foam::operator<<(Ostream& os, const fvMatrix<Type>& fvm)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * Expression Templates * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
template<class Type>
|
||||||
|
template<typename E>
|
||||||
|
Foam::fvMatrix<Type>::fvMatrix
|
||||||
|
(
|
||||||
|
const GeometricField<Type, fvPatchField, volMesh>& psi,
|
||||||
|
const Expression::fvMatrixExpression
|
||||||
|
<
|
||||||
|
E,
|
||||||
|
typename E::DiagExpr,
|
||||||
|
typename E::UpperExpr,
|
||||||
|
typename E::LowerExpr,
|
||||||
|
typename E::FaceFluxExpr,
|
||||||
|
typename E::SourceExpr
|
||||||
|
>& expr
|
||||||
|
)
|
||||||
|
:
|
||||||
|
lduMatrix(psi.mesh()),
|
||||||
|
psi_(psi),
|
||||||
|
useImplicit_(false),
|
||||||
|
lduAssemblyName_(),
|
||||||
|
nMatrix_(0),
|
||||||
|
dimensions_(expr.dimensions()),
|
||||||
|
source_(psi.size(), Zero),
|
||||||
|
internalCoeffs_(psi.mesh().boundary().size()),
|
||||||
|
boundaryCoeffs_(psi.mesh().boundary().size())
|
||||||
|
{
|
||||||
|
DebugInFunction
|
||||||
|
<< "Constructing fvMatrix<Type> from expression for field "
|
||||||
|
<< psi_.name() << endl;
|
||||||
|
|
||||||
|
checkImplicit();
|
||||||
|
|
||||||
|
// Fill in diag,upper,lower etc.
|
||||||
|
expr.evaluate(*this);
|
||||||
|
|
||||||
|
auto& psiRef = this->psi(0);
|
||||||
|
const label currentStatePsi = psiRef.eventNo();
|
||||||
|
psiRef.boundaryFieldRef().updateCoeffs();
|
||||||
|
psiRef.eventNo() = currentStatePsi;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class Type>
|
||||||
|
Foam::Expression::fvMatrixConstRefWrap<Foam::fvMatrix<Type>>
|
||||||
|
Foam::fvMatrix<Type>::expr() const
|
||||||
|
{
|
||||||
|
return Expression::fvMatrixConstRefWrap<Foam::fvMatrix<Type>>(*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class Type>
|
||||||
|
template<typename E>
|
||||||
|
void Foam::fvMatrix<Type>::operator=
|
||||||
|
(
|
||||||
|
const Expression::fvMatrixExpression
|
||||||
|
<
|
||||||
|
E,
|
||||||
|
typename E::DiagExpr,
|
||||||
|
typename E::UpperExpr,
|
||||||
|
typename E::LowerExpr,
|
||||||
|
typename E::FaceFluxExpr,
|
||||||
|
typename E::SourceExpr
|
||||||
|
>& expr
|
||||||
|
)
|
||||||
|
{
|
||||||
|
expr.evaluate(*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * Solvers * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * Solvers * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
#include "fvMatrixSolve.C"
|
#include "fvMatrixSolve.C"
|
||||||
|
|||||||
@ -53,6 +53,8 @@ SourceFiles
|
|||||||
#include "lduPrimitiveMeshAssembly.H"
|
#include "lduPrimitiveMeshAssembly.H"
|
||||||
#include "lduMesh.H"
|
#include "lduMesh.H"
|
||||||
|
|
||||||
|
#include "fvMatrixExpression.H"
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
namespace Foam
|
namespace Foam
|
||||||
@ -741,6 +743,47 @@ public:
|
|||||||
Ostream&,
|
Ostream&,
|
||||||
const fvMatrix<Type>&
|
const fvMatrix<Type>&
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
|
// Expression templates
|
||||||
|
|
||||||
|
//- Construct given a field to solve for and expressions for
|
||||||
|
//- all the components
|
||||||
|
template<typename E>
|
||||||
|
fvMatrix
|
||||||
|
(
|
||||||
|
const GeometricField<Type, fvPatchField, volMesh>& psi,
|
||||||
|
const Expression::fvMatrixExpression
|
||||||
|
<
|
||||||
|
E,
|
||||||
|
typename E::DiagExpr,
|
||||||
|
typename E::UpperExpr,
|
||||||
|
typename E::LowerExpr,
|
||||||
|
typename E::FaceFluxExpr,
|
||||||
|
typename E::SourceExpr
|
||||||
|
>& expr
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Wrap value as expression
|
||||||
|
typename Expression::fvMatrixConstRefWrap
|
||||||
|
<
|
||||||
|
fvMatrix<Type>
|
||||||
|
> expr() const;
|
||||||
|
|
||||||
|
//- Assign values from expression
|
||||||
|
template<typename E>
|
||||||
|
void operator=
|
||||||
|
(
|
||||||
|
const Expression::fvMatrixExpression
|
||||||
|
<
|
||||||
|
E,
|
||||||
|
typename E::DiagExpr,
|
||||||
|
typename E::UpperExpr,
|
||||||
|
typename E::LowerExpr,
|
||||||
|
typename E::FaceFluxExpr,
|
||||||
|
typename E::SourceExpr
|
||||||
|
>& expr
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -226,6 +226,94 @@ Foam::fv::fusedGaussGrad<Type>::calcGrad
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class Type>
|
||||||
|
void Foam::fv::fusedGaussGrad<Type>::calcGrad
|
||||||
|
(
|
||||||
|
GeometricField
|
||||||
|
<
|
||||||
|
typename outerProduct<vector, Type>::type,
|
||||||
|
fvPatchField,
|
||||||
|
volMesh
|
||||||
|
>& gGrad,
|
||||||
|
const GeometricField<Type, fvPatchField, volMesh>& vf
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
typedef typename outerProduct<vector, Type>::type GradType;
|
||||||
|
|
||||||
|
const fvMesh& mesh = vf.mesh();
|
||||||
|
|
||||||
|
DebugPout<< "fusedGaussGrad<Type>::calcGrad on " << vf.name()
|
||||||
|
<< " into " << gGrad.name() << endl;
|
||||||
|
|
||||||
|
gGrad = dimensioned<GradType>(vf.dimensions()/dimLength, Zero);
|
||||||
|
|
||||||
|
if (this->tinterpScheme_().corrected())
|
||||||
|
{
|
||||||
|
const auto tfaceCorr(this->tinterpScheme_().correction(vf));
|
||||||
|
auto& faceCorr = tfaceCorr();
|
||||||
|
|
||||||
|
DebugPout<< "fusedGaussGrad<Type>::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<Type>::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);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
template<class Type>
|
template<class Type>
|
||||||
template<class GradType>
|
template<class GradType>
|
||||||
void Foam::fv::fusedGaussGrad<Type>::correctBoundaryConditions
|
void Foam::fv::fusedGaussGrad<Type>::correctBoundaryConditions
|
||||||
|
|||||||
@ -145,6 +145,14 @@ public:
|
|||||||
const word& name
|
const word& name
|
||||||
) const;
|
) const;
|
||||||
|
|
||||||
|
//- Calculate the grad of the given field into supplied field
|
||||||
|
virtual void calcGrad
|
||||||
|
(
|
||||||
|
GeometricField
|
||||||
|
<typename outerProduct<vector, Type>::type, fvPatchField, volMesh>& res,
|
||||||
|
const GeometricField<Type, fvPatchField, volMesh>&
|
||||||
|
) const;
|
||||||
|
|
||||||
//- Correct the boundary values of the gradient using the patchField
|
//- Correct the boundary values of the gradient using the patchField
|
||||||
//- snGrad functions
|
//- snGrad functions
|
||||||
template<class GradType>
|
template<class GradType>
|
||||||
|
|||||||
@ -45,6 +45,87 @@ namespace fv
|
|||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
template<class Type, class GType>
|
||||||
|
template<class E1, class E2>
|
||||||
|
void fusedGaussLaplacianScheme<Type, GType>::fvmCorrection
|
||||||
|
(
|
||||||
|
fvMatrix<Type>& fvm,
|
||||||
|
const dimensionSet& gammaDim,
|
||||||
|
const E1& gammaMagSf,
|
||||||
|
const E2& corr
|
||||||
|
)
|
||||||
|
{
|
||||||
|
typedef GeometricField<Type, fvsPatchField, surfaceMesh> surfaceType;
|
||||||
|
|
||||||
|
const auto& vf = fvm.psi();
|
||||||
|
const fvMesh& mesh = vf.mesh();
|
||||||
|
const auto V = mesh.V().expr();
|
||||||
|
|
||||||
|
if (mesh.fluxRequired(vf.name()))
|
||||||
|
{
|
||||||
|
fvm.faceFluxCorrectionPtr() = std::make_unique<surfaceType>
|
||||||
|
(
|
||||||
|
IOobject
|
||||||
|
(
|
||||||
|
"faceFluxCorr",
|
||||||
|
mesh.time().timeName(),
|
||||||
|
mesh,
|
||||||
|
IOobject::NO_READ,
|
||||||
|
IOobject::NO_WRITE,
|
||||||
|
IOobject::NO_REGISTER
|
||||||
|
),
|
||||||
|
mesh,
|
||||||
|
gammaDim
|
||||||
|
*mesh.magSf().dimensions()
|
||||||
|
*corr.data().dimensions()
|
||||||
|
);
|
||||||
|
auto& faceFluxCorr = *fvm.faceFluxCorrectionPtr();
|
||||||
|
|
||||||
|
faceFluxCorr = corr*gammaMagSf;
|
||||||
|
|
||||||
|
fvm.source() =
|
||||||
|
fvm.source().expr()
|
||||||
|
- (
|
||||||
|
fvc::div
|
||||||
|
(
|
||||||
|
faceFluxCorr
|
||||||
|
)().primitiveField().expr()
|
||||||
|
*V
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
surfaceType faceFluxCorr
|
||||||
|
(
|
||||||
|
IOobject
|
||||||
|
(
|
||||||
|
"faceFluxCorr",
|
||||||
|
mesh.time().timeName(),
|
||||||
|
mesh,
|
||||||
|
IOobject::NO_READ,
|
||||||
|
IOobject::NO_WRITE,
|
||||||
|
IOobject::NO_REGISTER
|
||||||
|
),
|
||||||
|
mesh,
|
||||||
|
gammaDim
|
||||||
|
*mesh.magSf().dimensions()
|
||||||
|
*corr.data().dimensions()
|
||||||
|
);
|
||||||
|
faceFluxCorr = corr*gammaMagSf;
|
||||||
|
|
||||||
|
fvm.source() =
|
||||||
|
fvm.source().expr()
|
||||||
|
- (
|
||||||
|
fvc::div
|
||||||
|
(
|
||||||
|
faceFluxCorr
|
||||||
|
)().primitiveField().expr()
|
||||||
|
*V
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
template<class Type, class GType>
|
template<class Type, class GType>
|
||||||
tmp<fvMatrix<Type>>
|
tmp<fvMatrix<Type>>
|
||||||
fusedGaussLaplacianScheme<Type, GType>::fvmLaplacianUncorrected
|
fusedGaussLaplacianScheme<Type, GType>::fvmLaplacianUncorrected
|
||||||
|
|||||||
@ -65,6 +65,17 @@ class fusedGaussLaplacianScheme
|
|||||||
{
|
{
|
||||||
// Private Member Functions
|
// Private Member Functions
|
||||||
|
|
||||||
|
//- Helper for calculate source correction. Partially expression
|
||||||
|
// templated. Move to fvMatrixExpression.H?
|
||||||
|
template<class E1, class E2>
|
||||||
|
static void fvmCorrection
|
||||||
|
(
|
||||||
|
fvMatrix<Type>& fvm,
|
||||||
|
const dimensionSet& gammaDim,
|
||||||
|
const E1& gammaMagSf,
|
||||||
|
const E2& corr
|
||||||
|
);
|
||||||
|
|
||||||
//- See gaussLaplacianScheme
|
//- See gaussLaplacianScheme
|
||||||
tmp<GeometricField<Type, fvsPatchField, surfaceMesh>> gammaSnGradCorr
|
tmp<GeometricField<Type, fvsPatchField, surfaceMesh>> gammaSnGradCorr
|
||||||
(
|
(
|
||||||
@ -198,6 +209,8 @@ defineFvmLaplacianScalarGamma(sphericalTensor);
|
|||||||
defineFvmLaplacianScalarGamma(symmTensor);
|
defineFvmLaplacianScalarGamma(symmTensor);
|
||||||
defineFvmLaplacianScalarGamma(tensor);
|
defineFvmLaplacianScalarGamma(tensor);
|
||||||
|
|
||||||
|
#undef defineFvmLaplacianScalarGamma
|
||||||
|
|
||||||
// Unweighted laplacian
|
// Unweighted laplacian
|
||||||
template<>
|
template<>
|
||||||
tmp<GeometricField<scalar, fvPatchField, volMesh>>
|
tmp<GeometricField<scalar, fvPatchField, volMesh>>
|
||||||
@ -227,20 +240,6 @@ fusedGaussLaplacianScheme<vector, scalar>::fvcLaplacian
|
|||||||
const GeometricField<scalar, fvPatchField, volMesh>&,
|
const GeometricField<scalar, fvPatchField, volMesh>&,
|
||||||
const GeometricField<vector, fvPatchField, volMesh>&
|
const GeometricField<vector, fvPatchField, volMesh>&
|
||||||
);
|
);
|
||||||
template<>
|
|
||||||
tmp<fvMatrix<scalar>>
|
|
||||||
fusedGaussLaplacianScheme<scalar, scalar>::fvmLaplacian
|
|
||||||
(
|
|
||||||
const GeometricField<scalar, fvPatchField, volMesh>&,
|
|
||||||
const GeometricField<scalar, fvPatchField, volMesh>&
|
|
||||||
);
|
|
||||||
template<>
|
|
||||||
tmp<fvMatrix<vector>>
|
|
||||||
fusedGaussLaplacianScheme<vector, scalar>::fvmLaplacian
|
|
||||||
(
|
|
||||||
const GeometricField<scalar, fvPatchField, volMesh>&,
|
|
||||||
const GeometricField<vector, fvPatchField, volMesh>&
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|||||||
@ -28,6 +28,7 @@ License
|
|||||||
|
|
||||||
#include "fusedGaussLaplacianScheme.H"
|
#include "fusedGaussLaplacianScheme.H"
|
||||||
#include "fvMesh.H"
|
#include "fvMesh.H"
|
||||||
|
#include "fvMatrixExpression.H"
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
@ -40,61 +41,81 @@ Foam::tmp<Foam::fvMatrix<Foam::Type>> \
|
|||||||
Foam::fv::fusedGaussLaplacianScheme<Foam::Type, Foam::scalar>:: \
|
Foam::fv::fusedGaussLaplacianScheme<Foam::Type, Foam::scalar>:: \
|
||||||
fvmLaplacian \
|
fvmLaplacian \
|
||||||
( \
|
( \
|
||||||
const GeometricField<scalar, fvsPatchField, surfaceMesh>& gamma, \
|
const GeometricField<scalar, fvPatchField, volMesh>& gamma, \
|
||||||
const GeometricField<Type, fvPatchField, volMesh>& vf \
|
const GeometricField<Type, fvPatchField, volMesh>& vf \
|
||||||
) \
|
) \
|
||||||
{ \
|
{ \
|
||||||
DebugPout<< "fusedGaussLaplacianScheme::fvmLaplacian on " << vf.name() \
|
DebugPout<< "fusedGaussLaplacianScheme::fvmLaplacian on " << vf.name() \
|
||||||
<< " with scalar gamma " << gamma.name() << endl; \
|
<< " with scalar gamma " << gamma.name() << " and ET" << endl; \
|
||||||
\
|
\
|
||||||
const fvMesh& mesh = this->mesh(); \
|
const fvMesh& mesh = this->mesh(); \
|
||||||
\
|
\
|
||||||
GeometricField<scalar, fvsPatchField, surfaceMesh> gammaMagSf \
|
const auto weights = this->tinterpGammaScheme_().weights(gamma).expr(); \
|
||||||
( \
|
const auto gammaMagSf = \
|
||||||
gamma*mesh.magSf() \
|
Expression::interpolate(gamma.expr(), weights, mesh) \
|
||||||
); \
|
* mesh.magSf().expr(); \
|
||||||
|
/* For compatibility with linearInterpolate : avoid orientation. TBD. */ \
|
||||||
|
const_cast<orientedType&>(gammaMagSf.oriented()).setOriented(false); \
|
||||||
|
const auto deltaCoeffs = this->tsnGradScheme_().deltaCoeffs(vf).expr(); \
|
||||||
\
|
\
|
||||||
tmp<fvMatrix<Type>> tfvm = fvmLaplacianUncorrected \
|
tmp<fvMatrix<Type>> tfvm \
|
||||||
( \
|
( \
|
||||||
gammaMagSf, \
|
new fvMatrix<Type> \
|
||||||
this->tsnGradScheme_().deltaCoeffs(vf), \
|
( \
|
||||||
vf \
|
vf, \
|
||||||
|
gamma.dimensions()*mesh.magSf().dimensions()*vf.dimensions() \
|
||||||
|
) \
|
||||||
); \
|
); \
|
||||||
fvMatrix<Type>& fvm = tfvm.ref(); \
|
fvMatrix<Type>& fvm = tfvm.ref(); \
|
||||||
\
|
\
|
||||||
|
Expression::fvmLaplacianUncorrected(fvm, gammaMagSf, deltaCoeffs); \
|
||||||
|
\
|
||||||
if (this->tsnGradScheme_().corrected()) \
|
if (this->tsnGradScheme_().corrected()) \
|
||||||
{ \
|
{ \
|
||||||
if (mesh.fluxRequired(vf.name())) \
|
const auto corr(this->tsnGradScheme_().correction(vf).expr()); \
|
||||||
{ \
|
fvmCorrection(fvm, gamma.dimensions(), gammaMagSf, corr); \
|
||||||
fvm.faceFluxCorrectionPtr() = std::make_unique \
|
|
||||||
< \
|
|
||||||
GeometricField<Type, fvsPatchField, surfaceMesh> \
|
|
||||||
> \
|
|
||||||
( \
|
|
||||||
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; \
|
return tfvm; \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
|
template<> \
|
||||||
|
Foam::tmp<Foam::fvMatrix<Foam::Type>> \
|
||||||
|
Foam::fv::fusedGaussLaplacianScheme<Foam::Type, Foam::scalar>:: \
|
||||||
|
fvmLaplacian \
|
||||||
|
( \
|
||||||
|
const GeometricField<scalar, fvsPatchField, surfaceMesh>& gamma, \
|
||||||
|
const GeometricField<Type, fvPatchField, volMesh>& vf \
|
||||||
|
) \
|
||||||
|
{ \
|
||||||
|
DebugPout<< "fusedGaussLaplacianScheme::fvmLaplacian on " << vf.name() \
|
||||||
|
<< " with interpolated gamma " << gamma.name() << " and ET" << endl; \
|
||||||
|
\
|
||||||
|
const fvMesh& mesh = this->mesh(); \
|
||||||
|
\
|
||||||
|
const auto gammaMagSf = gamma.expr()* mesh.magSf().expr(); \
|
||||||
|
const auto deltaCoeffs = this->tsnGradScheme_().deltaCoeffs(vf).expr(); \
|
||||||
|
\
|
||||||
|
tmp<fvMatrix<Type>> tfvm \
|
||||||
|
( \
|
||||||
|
new fvMatrix<Type> \
|
||||||
|
( \
|
||||||
|
vf, \
|
||||||
|
gamma.dimensions()*mesh.magSf().dimensions()*vf.dimensions() \
|
||||||
|
) \
|
||||||
|
); \
|
||||||
|
fvMatrix<Type>& fvm = tfvm.ref(); \
|
||||||
|
\
|
||||||
|
Expression::fvmLaplacianUncorrected(fvm, gammaMagSf, deltaCoeffs); \
|
||||||
|
\
|
||||||
|
if (this->tsnGradScheme_().corrected()) \
|
||||||
|
{ \
|
||||||
|
const auto corr(this->tsnGradScheme_().correction(vf).expr()); \
|
||||||
|
fvmCorrection(fvm, gamma.dimensions(), gammaMagSf, corr); \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
return tfvm; \
|
||||||
|
} \
|
||||||
\
|
\
|
||||||
template<> \
|
template<> \
|
||||||
Foam::tmp<Foam::GeometricField<Foam::Type, Foam::fvPatchField, Foam::volMesh>> \
|
Foam::tmp<Foam::GeometricField<Foam::Type, Foam::fvPatchField, Foam::volMesh>> \
|
||||||
@ -500,38 +521,6 @@ Foam::fv::fusedGaussLaplacianScheme<Foam::vector, Foam::scalar>::fvcLaplacian
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template<>
|
|
||||||
Foam::tmp<Foam::fvMatrix<Foam::scalar>>
|
|
||||||
Foam::fv::fusedGaussLaplacianScheme<Foam::scalar, Foam::scalar>::fvmLaplacian
|
|
||||||
(
|
|
||||||
const GeometricField<scalar, fvPatchField, volMesh>& gamma,
|
|
||||||
const GeometricField<scalar, fvPatchField, volMesh>& vf
|
|
||||||
)
|
|
||||||
{
|
|
||||||
// TBD
|
|
||||||
DebugPout
|
|
||||||
<< "fusedGaussLaplacianScheme<scalar, scalar>::fvmLaplacian"
|
|
||||||
<< " on " << vf.name() << " with gamma " << gamma.name() << endl;
|
|
||||||
return fvmLaplacian(this->tinterpGammaScheme_().interpolate(gamma)(), vf);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template<>
|
|
||||||
Foam::tmp<Foam::fvMatrix<Foam::vector>>
|
|
||||||
Foam::fv::fusedGaussLaplacianScheme<Foam::vector, Foam::scalar>::fvmLaplacian
|
|
||||||
(
|
|
||||||
const GeometricField<scalar, fvPatchField, volMesh>& gamma,
|
|
||||||
const GeometricField<vector, fvPatchField, volMesh>& vf
|
|
||||||
)
|
|
||||||
{
|
|
||||||
// TBD
|
|
||||||
DebugPout
|
|
||||||
<< "fusedGaussLaplacianScheme<vector, scalar>::fvmLaplacian"
|
|
||||||
<< " on " << vf.name() << " with gamma " << gamma.name() << endl;
|
|
||||||
return fvmLaplacian(this->tinterpGammaScheme_().interpolate(gamma)(), vf);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
Foam::tmp
|
Foam::tmp
|
||||||
<
|
<
|
||||||
|
|||||||
@ -14,7 +14,7 @@ $(derivedSources)/buoyancyEnergy/buoyancyEnergy.C
|
|||||||
$(derivedSources)/buoyancyForce/buoyancyForce.C
|
$(derivedSources)/buoyancyForce/buoyancyForce.C
|
||||||
$(derivedSources)/directionalPressureGradientExplicitSource/directionalPressureGradientExplicitSource.C
|
$(derivedSources)/directionalPressureGradientExplicitSource/directionalPressureGradientExplicitSource.C
|
||||||
$(derivedSources)/explicitPorositySource/explicitPorositySource.C
|
$(derivedSources)/explicitPorositySource/explicitPorositySource.C
|
||||||
$(derivedSources)/jouleHeatingSource/jouleHeatingSource.cxx
|
$(derivedSources)/jouleHeatingSource/jouleHeatingSource.C
|
||||||
$(derivedSources)/meanVelocityForce/meanVelocityForce.C
|
$(derivedSources)/meanVelocityForce/meanVelocityForce.C
|
||||||
$(derivedSources)/meanVelocityForce/patchMeanVelocityForce/patchMeanVelocityForce.C
|
$(derivedSources)/meanVelocityForce/patchMeanVelocityForce/patchMeanVelocityForce.C
|
||||||
$(derivedSources)/multiphaseStabilizedTurbulence/multiphaseStabilizedTurbulence.C
|
$(derivedSources)/multiphaseStabilizedTurbulence/multiphaseStabilizedTurbulence.C
|
||||||
|
|||||||
@ -29,6 +29,7 @@ License
|
|||||||
#include "fvMatrices.H"
|
#include "fvMatrices.H"
|
||||||
#include "fvmLaplacian.H"
|
#include "fvmLaplacian.H"
|
||||||
#include "fvcGrad.H"
|
#include "fvcGrad.H"
|
||||||
|
#include "zeroGradientFvPatchField.H"
|
||||||
#include "basicThermo.H"
|
#include "basicThermo.H"
|
||||||
#include "addToRunTimeSelectionTable.H"
|
#include "addToRunTimeSelectionTable.H"
|
||||||
|
|
||||||
@ -44,12 +45,6 @@ namespace fv
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
// Implementation
|
|
||||||
#include "jouleHeatingSourceImpl.cxx"
|
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||||
|
|
||||||
Foam::tmp<Foam::volSymmTensorField>
|
Foam::tmp<Foam::volSymmTensorField>
|
||||||
@ -120,8 +115,11 @@ Foam::fv::jouleHeatingSource::jouleHeatingSource
|
|||||||
),
|
),
|
||||||
mesh
|
mesh
|
||||||
),
|
),
|
||||||
curTimeIndex_(-1),
|
anisotropicElectricalConductivity_(false),
|
||||||
anisotropicElectricalConductivity_(false)
|
scalarSigmaVsTPtr_(nullptr),
|
||||||
|
vectorSigmaVsTPtr_(nullptr),
|
||||||
|
csysPtr_(nullptr),
|
||||||
|
curTimeIndex_(-1)
|
||||||
{
|
{
|
||||||
// Set the field name to that of the energy
|
// Set the field name to that of the energy
|
||||||
// field from which the temperature is obtained
|
// field from which the temperature is obtained
|
||||||
@ -164,7 +162,7 @@ void Foam::fv::jouleHeatingSource::addSup
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Update sigma as a function of T if required
|
// Update sigma as a function of T if required
|
||||||
const auto& sigma = updateSigma(scalarSigmaVsTPtr_);
|
const volScalarField& sigma = updateSigma(scalarSigmaVsTPtr_);
|
||||||
|
|
||||||
// Solve the electrical potential equation
|
// Solve the electrical potential equation
|
||||||
fvScalarMatrix VEqn(fvm::laplacian(sigma, V_));
|
fvScalarMatrix VEqn(fvm::laplacian(sigma, V_));
|
||||||
@ -228,7 +226,7 @@ bool Foam::fv::jouleHeatingSource::read(const dictionary& dict)
|
|||||||
|
|
||||||
initialiseSigma(coeffs_, scalarSigmaVsTPtr_);
|
initialiseSigma(coeffs_, scalarSigmaVsTPtr_);
|
||||||
|
|
||||||
csysPtr_.reset(nullptr); // Do not need coordinate system
|
csysPtr_.clear(); // Do not need coordinate system
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@ -137,28 +137,25 @@ Note
|
|||||||
anisotropic (vectorial) electrical conductivity.
|
anisotropic (vectorial) electrical conductivity.
|
||||||
- \c anisotropicElectricalConductivity=false enables
|
- \c anisotropicElectricalConductivity=false enables
|
||||||
isotropic (scalar) electrical conductivity.
|
isotropic (scalar) electrical conductivity.
|
||||||
|
- The electrical conductivity can be specified using either:
|
||||||
The electrical conductivity can be specified using either:
|
|
||||||
- If the \c sigma entry is present the electrical conductivity is specified
|
- If the \c sigma entry is present the electrical conductivity is specified
|
||||||
as a function of temperature using a \c Function1 type.
|
as a function of temperature using a \c Function1 type.
|
||||||
- If not present the \c sigma field will be read from file.
|
- If not present the \c sigma field will be read from file.
|
||||||
- If the \c anisotropicElectricalConductivity flag is set to \c true,
|
- If the \c anisotropicElectricalConductivity flag is set to \c true,
|
||||||
\c sigma should be specified as a vector quantity.
|
\c sigma should be specified as a vector quantity.
|
||||||
.
|
|
||||||
|
|
||||||
See also
|
See also
|
||||||
- Foam::Function1
|
- Foam::Function1
|
||||||
- Foam::coordSystem
|
- Foam::coordSystem
|
||||||
- Foam::fa::jouleHeatingSource
|
|
||||||
|
|
||||||
SourceFiles
|
SourceFiles
|
||||||
jouleHeatingSource.cxx
|
jouleHeatingSource.C
|
||||||
jouleHeatingSourceImpl.cxx
|
jouleHeatingSourceTemplates.C
|
||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
#ifndef Foam_fv_jouleHeatingSource_H
|
#ifndef fv_jouleHeatingSource_H
|
||||||
#define Foam_fv_jouleHeatingSource_H
|
#define fv_jouleHeatingSource_H
|
||||||
|
|
||||||
#include "fvOption.H"
|
#include "fvOption.H"
|
||||||
#include "Function1.H"
|
#include "Function1.H"
|
||||||
@ -188,6 +185,9 @@ class jouleHeatingSource
|
|||||||
//- Electrical potential field / [V]
|
//- Electrical potential field / [V]
|
||||||
volScalarField V_;
|
volScalarField V_;
|
||||||
|
|
||||||
|
//- Flag to indicate that the electrical conductivity is anisotropic
|
||||||
|
bool anisotropicElectricalConductivity_;
|
||||||
|
|
||||||
//- Electrical conductivity as a scalar function of temperature
|
//- Electrical conductivity as a scalar function of temperature
|
||||||
autoPtr<Function1<scalar>> scalarSigmaVsTPtr_;
|
autoPtr<Function1<scalar>> scalarSigmaVsTPtr_;
|
||||||
|
|
||||||
@ -200,9 +200,6 @@ class jouleHeatingSource
|
|||||||
//- Current time index (used for updating)
|
//- Current time index (used for updating)
|
||||||
label curTimeIndex_;
|
label curTimeIndex_;
|
||||||
|
|
||||||
//- Flag to indicate that the electrical conductivity is anisotropic
|
|
||||||
bool anisotropicElectricalConductivity_;
|
|
||||||
|
|
||||||
|
|
||||||
// Private Member Functions
|
// Private Member Functions
|
||||||
|
|
||||||
@ -217,13 +214,13 @@ class jouleHeatingSource
|
|||||||
void initialiseSigma
|
void initialiseSigma
|
||||||
(
|
(
|
||||||
const dictionary& dict,
|
const dictionary& dict,
|
||||||
autoPtr<Function1<Type>>& sigmaFunctionPtr
|
autoPtr<Function1<Type>>& sigmaVsTPtr
|
||||||
);
|
);
|
||||||
|
|
||||||
//- Update the electrical conductivity field
|
//- Update the electrical conductivity field
|
||||||
template<class Type>
|
template<class Type>
|
||||||
const GeometricField<Type, fvPatchField, volMesh>&
|
const GeometricField<Type, fvPatchField, volMesh>&
|
||||||
updateSigma(const autoPtr<Function1<Type>>& sigmaFunctionPtr) const;
|
updateSigma(const autoPtr<Function1<Type>>& sigmaVsTPtr) const;
|
||||||
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@ -256,21 +253,21 @@ public:
|
|||||||
|
|
||||||
// Member Functions
|
// Member Functions
|
||||||
|
|
||||||
// Evaluation
|
// Evaluation
|
||||||
|
|
||||||
//- Add explicit contribution to energy equation
|
//- Add explicit contribution to compressible momentum equation
|
||||||
virtual void addSup
|
virtual void addSup
|
||||||
(
|
(
|
||||||
const volScalarField& rho,
|
const volScalarField& rho,
|
||||||
fvMatrix<scalar>& eqn,
|
fvMatrix<scalar>& eqn,
|
||||||
const label fieldi
|
const label fieldi
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
// IO
|
// IO
|
||||||
|
|
||||||
//- Read source dictionary
|
//- Read source dictionary
|
||||||
virtual bool read(const dictionary& dict);
|
virtual bool read(const dictionary& dict);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -281,6 +278,12 @@ public:
|
|||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
#ifdef NoRepository
|
||||||
|
#include "jouleHeatingSourceTemplates.C"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// ************************************************************************* //
|
// ************************************************************************* //
|
||||||
|
|||||||
@ -5,7 +5,7 @@
|
|||||||
\\ / A nd | www.openfoam.com
|
\\ / A nd | www.openfoam.com
|
||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Copyright (C) 2016-2025 OpenCFD Ltd.
|
Copyright (C) 2016-2024 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM.
|
This file is part of OpenFOAM.
|
||||||
@ -27,25 +27,18 @@ License
|
|||||||
|
|
||||||
#include "emptyFvPatchField.H"
|
#include "emptyFvPatchField.H"
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
template<class Type>
|
template<class Type>
|
||||||
void Foam::fv::jouleHeatingSource::initialiseSigma
|
void Foam::fv::jouleHeatingSource::initialiseSigma
|
||||||
(
|
(
|
||||||
const dictionary& dict,
|
const dictionary& dict,
|
||||||
autoPtr<Function1<Type>>& sigmaFunctionPtr
|
autoPtr<Function1<Type>>& sigmaVsTPtr
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
typedef GeometricField<Type, fvPatchField, volMesh> FieldType;
|
typedef GeometricField<Type, fvPatchField, volMesh> FieldType;
|
||||||
|
|
||||||
const word sigmaName
|
|
||||||
(
|
|
||||||
IOobject::scopedName(typeName, "sigma")
|
|
||||||
);
|
|
||||||
|
|
||||||
IOobject io
|
IOobject io
|
||||||
(
|
(
|
||||||
sigmaName,
|
IOobject::scopedName(typeName, "sigma"),
|
||||||
mesh_.time().timeName(),
|
mesh_.time().timeName(),
|
||||||
mesh_.thisDb(),
|
mesh_.thisDb(),
|
||||||
IOobject::NO_READ,
|
IOobject::NO_READ,
|
||||||
@ -55,11 +48,11 @@ void Foam::fv::jouleHeatingSource::initialiseSigma
|
|||||||
|
|
||||||
autoPtr<FieldType> tsigma;
|
autoPtr<FieldType> tsigma;
|
||||||
|
|
||||||
// Is sigma defined using a Function1 ?
|
if (dict.found("sigma"))
|
||||||
sigmaFunctionPtr = Function1<Type>::NewIfPresent("sigma", dict, &mesh_);
|
|
||||||
|
|
||||||
if (sigmaFunctionPtr)
|
|
||||||
{
|
{
|
||||||
|
// Sigma to be defined using a Function1 type
|
||||||
|
sigmaVsTPtr = Function1<Type>::New("sigma", dict, &mesh_);
|
||||||
|
|
||||||
tsigma.reset
|
tsigma.reset
|
||||||
(
|
(
|
||||||
new FieldType
|
new FieldType
|
||||||
@ -92,32 +85,28 @@ template<class Type>
|
|||||||
const Foam::GeometricField<Type, Foam::fvPatchField, Foam::volMesh>&
|
const Foam::GeometricField<Type, Foam::fvPatchField, Foam::volMesh>&
|
||||||
Foam::fv::jouleHeatingSource::updateSigma
|
Foam::fv::jouleHeatingSource::updateSigma
|
||||||
(
|
(
|
||||||
const autoPtr<Function1<Type>>& sigmaFunctionPtr
|
const autoPtr<Function1<Type>>& sigmaVsTPtr
|
||||||
) const
|
) const
|
||||||
{
|
{
|
||||||
typedef GeometricField<Type, fvPatchField, volMesh> FieldType;
|
typedef GeometricField<Type, fvPatchField, volMesh> FieldType;
|
||||||
|
|
||||||
const word sigmaName
|
auto& sigma = mesh_.lookupObjectRef<FieldType>
|
||||||
(
|
(
|
||||||
IOobject::scopedName(typeName, "sigma")
|
IOobject::scopedName(typeName, "sigma")
|
||||||
);
|
);
|
||||||
|
|
||||||
auto& sigma = mesh_.lookupObjectRef<FieldType>(sigmaName);
|
if (!sigmaVsTPtr)
|
||||||
|
|
||||||
if (!sigmaFunctionPtr)
|
|
||||||
{
|
{
|
||||||
// Electrical conductivity field, sigma, was specified by the user
|
// Electrical conductivity field, sigma, was specified by the user
|
||||||
return sigma;
|
return sigma;
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto& sigmaFunction = sigmaFunctionPtr();
|
|
||||||
|
|
||||||
const auto& T = mesh_.lookupObject<volScalarField>(TName_);
|
const auto& T = mesh_.lookupObject<volScalarField>(TName_);
|
||||||
|
|
||||||
// Internal field
|
// Internal field
|
||||||
forAll(sigma, i)
|
forAll(sigma, i)
|
||||||
{
|
{
|
||||||
sigma[i] = sigmaFunction.value(T[i]);
|
sigma[i] = sigmaVsTPtr->value(T[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -131,7 +120,7 @@ Foam::fv::jouleHeatingSource::updateSigma
|
|||||||
const scalarField& Tbf = T.boundaryField()[patchi];
|
const scalarField& Tbf = T.boundaryField()[patchi];
|
||||||
forAll(pf, facei)
|
forAll(pf, facei)
|
||||||
{
|
{
|
||||||
pf[facei] = sigmaFunction.value(Tbf[facei]);
|
pf[facei] = sigmaVsTPtr->value(Tbf[facei]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -480,7 +480,6 @@ void Foam::faMeshReconstructor::createMesh()
|
|||||||
(
|
(
|
||||||
new faMesh
|
new faMesh
|
||||||
(
|
(
|
||||||
procMesh_.name(),
|
|
||||||
*serialVolMesh_,
|
*serialVolMesh_,
|
||||||
identity(singlePatchFaces_.size()) // faceLabels
|
identity(singlePatchFaces_.size()) // faceLabels
|
||||||
)
|
)
|
||||||
|
|||||||
@ -5,7 +5,7 @@
|
|||||||
\\ / A nd | www.openfoam.com
|
\\ / A nd | www.openfoam.com
|
||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Copyright (C) 2019-2025 OpenCFD Ltd.
|
Copyright (C) 2019-2023 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM.
|
This file is part of OpenFOAM.
|
||||||
@ -144,23 +144,11 @@ KirchhoffShell::KirchhoffShell
|
|||||||
)
|
)
|
||||||
:
|
:
|
||||||
vibrationShellModel(modelType, mesh, dict),
|
vibrationShellModel(modelType, mesh, dict),
|
||||||
h_
|
|
||||||
(
|
|
||||||
IOobject
|
|
||||||
(
|
|
||||||
dict.getOrDefault<word>("h", suffixed("hs")),
|
|
||||||
regionMesh().time().timeName(),
|
|
||||||
regionMesh().thisDb(),
|
|
||||||
IOobject::MUST_READ,
|
|
||||||
IOobject::AUTO_WRITE
|
|
||||||
),
|
|
||||||
regionMesh()
|
|
||||||
),
|
|
||||||
ps_
|
ps_
|
||||||
(
|
(
|
||||||
IOobject
|
IOobject
|
||||||
(
|
(
|
||||||
dict.getOrDefault<word>("ps", suffixed("ps")),
|
"ps_" + regionName_,
|
||||||
regionMesh().time().timeName(),
|
regionMesh().time().timeName(),
|
||||||
regionMesh().thisDb(),
|
regionMesh().thisDb(),
|
||||||
IOobject::READ_IF_PRESENT,
|
IOobject::READ_IF_PRESENT,
|
||||||
@ -169,11 +157,23 @@ KirchhoffShell::KirchhoffShell
|
|||||||
regionMesh(),
|
regionMesh(),
|
||||||
dimensionedScalar(dimPressure, Zero)
|
dimensionedScalar(dimPressure, Zero)
|
||||||
),
|
),
|
||||||
|
h_
|
||||||
|
(
|
||||||
|
IOobject
|
||||||
|
(
|
||||||
|
"h_" + regionName_,
|
||||||
|
regionMesh().time().timeName(),
|
||||||
|
regionMesh().thisDb(),
|
||||||
|
IOobject::MUST_READ,
|
||||||
|
IOobject::AUTO_WRITE
|
||||||
|
),
|
||||||
|
regionMesh()
|
||||||
|
),
|
||||||
laplaceW_
|
laplaceW_
|
||||||
(
|
(
|
||||||
IOobject
|
IOobject
|
||||||
(
|
(
|
||||||
suffixed("laplaceW"),
|
"laplaceW_" + regionName_,
|
||||||
regionMesh().time().timeName(),
|
regionMesh().time().timeName(),
|
||||||
regionMesh().thisDb(),
|
regionMesh().thisDb(),
|
||||||
IOobject::NO_READ,
|
IOobject::NO_READ,
|
||||||
@ -186,7 +186,7 @@ KirchhoffShell::KirchhoffShell
|
|||||||
(
|
(
|
||||||
IOobject
|
IOobject
|
||||||
(
|
(
|
||||||
suffixed("laplace2W"),
|
"laplace2W_" + regionName_,
|
||||||
regionMesh().time().timeName(),
|
regionMesh().time().timeName(),
|
||||||
regionMesh().thisDb(),
|
regionMesh().thisDb(),
|
||||||
IOobject::NO_READ,
|
IOobject::NO_READ,
|
||||||
@ -199,7 +199,7 @@ KirchhoffShell::KirchhoffShell
|
|||||||
(
|
(
|
||||||
IOobject
|
IOobject
|
||||||
(
|
(
|
||||||
suffixed("w0"),
|
"w0_" + regionName_,
|
||||||
regionMesh().time().timeName(),
|
regionMesh().time().timeName(),
|
||||||
regionMesh().thisDb(),
|
regionMesh().thisDb(),
|
||||||
IOobject::NO_READ,
|
IOobject::NO_READ,
|
||||||
@ -212,7 +212,7 @@ KirchhoffShell::KirchhoffShell
|
|||||||
(
|
(
|
||||||
IOobject
|
IOobject
|
||||||
(
|
(
|
||||||
suffixed("w00"),
|
"w00_" + regionName_,
|
||||||
regionMesh().time().timeName(),
|
regionMesh().time().timeName(),
|
||||||
regionMesh().thisDb(),
|
regionMesh().thisDb(),
|
||||||
IOobject::NO_READ,
|
IOobject::NO_READ,
|
||||||
@ -225,7 +225,7 @@ KirchhoffShell::KirchhoffShell
|
|||||||
(
|
(
|
||||||
IOobject
|
IOobject
|
||||||
(
|
(
|
||||||
suffixed("laplaceW0"),
|
"laplaceW0_" + regionName_,
|
||||||
regionMesh().time().timeName(),
|
regionMesh().time().timeName(),
|
||||||
regionMesh().thisDb(),
|
regionMesh().thisDb(),
|
||||||
IOobject::NO_READ,
|
IOobject::NO_READ,
|
||||||
@ -238,7 +238,7 @@ KirchhoffShell::KirchhoffShell
|
|||||||
(
|
(
|
||||||
IOobject
|
IOobject
|
||||||
(
|
(
|
||||||
suffixed("laplace2W0"),
|
"laplace2W0_" + regionName_,
|
||||||
regionMesh().time().timeName(),
|
regionMesh().time().timeName(),
|
||||||
regionMesh().thisDb(),
|
regionMesh().thisDb(),
|
||||||
IOobject::NO_READ,
|
IOobject::NO_READ,
|
||||||
@ -256,7 +256,6 @@ KirchhoffShell::KirchhoffShell
|
|||||||
init(dict);
|
init(dict);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
void KirchhoffShell::preEvolveRegion()
|
void KirchhoffShell::preEvolveRegion()
|
||||||
|
|||||||
@ -24,7 +24,7 @@ License
|
|||||||
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
Class
|
Class
|
||||||
Foam::regionModels::KirchhoffShell (Foam::regionFaModels)
|
Foam::regionFaModels::KirchhoffShell
|
||||||
|
|
||||||
Description
|
Description
|
||||||
Vibration-shell finite-area model.
|
Vibration-shell finite-area model.
|
||||||
@ -51,25 +51,9 @@ Usage
|
|||||||
\table
|
\table
|
||||||
Property | Description | Type | Reqd | Deflt
|
Property | Description | Type | Reqd | Deflt
|
||||||
vibrationShellModel | Type name: KirchhoffShell | word | yes | -
|
vibrationShellModel | Type name: KirchhoffShell | word | yes | -
|
||||||
f0 | Damping coefficient [1/s] | scalar | yes | -
|
f0 | Damping coefficient [1/s] | scalar | yes | -
|
||||||
f1 | Damping coefficient [1/s] | scalar | yes | -
|
f1 | Damping coefficient [1/s] | scalar | yes | -
|
||||||
f2 | Damping coefficient [1/s] | scalar | yes | -
|
f2 | Damping coefficient [1/s] | scalar | yes | -
|
||||||
h | Name of thickness field | word | no | hs (suffix)
|
|
||||||
ps | Name of pressure field | word | no | ps (suffix)
|
|
||||||
\endtable
|
|
||||||
|
|
||||||
Fields/variables used:
|
|
||||||
\table
|
|
||||||
Property | Description | Type | Deflt
|
|
||||||
h | Thickness | shell | hs (suffix)
|
|
||||||
ps | Pressure on shell | shell | ps (suffix)
|
|
||||||
\endtable
|
|
||||||
|
|
||||||
Naming changes from 2056 and earlier:
|
|
||||||
\table
|
|
||||||
Keyword | Description | Keyword (old) | Deflt (old)
|
|
||||||
h | Thickness (shell) | - | "h_" + regionName
|
|
||||||
ps | Pressure (shell) | - | "ps_" + regionName
|
|
||||||
\endtable
|
\endtable
|
||||||
|
|
||||||
The inherited entries are elaborated in:
|
The inherited entries are elaborated in:
|
||||||
@ -106,12 +90,12 @@ class KirchhoffShell
|
|||||||
|
|
||||||
// Source term fields
|
// Source term fields
|
||||||
|
|
||||||
//- Shell thickness [m]
|
|
||||||
areaScalarField h_;
|
|
||||||
|
|
||||||
//- External surface source [Pa]
|
//- External surface source [Pa]
|
||||||
const areaScalarField ps_;
|
const areaScalarField ps_;
|
||||||
|
|
||||||
|
//- Thickness [m]
|
||||||
|
areaScalarField h_;
|
||||||
|
|
||||||
//- Laplace of the displacement
|
//- Laplace of the displacement
|
||||||
areaScalarField laplaceW_;
|
areaScalarField laplaceW_;
|
||||||
|
|
||||||
|
|||||||
@ -5,7 +5,7 @@
|
|||||||
\\ / A nd | www.openfoam.com
|
\\ / A nd | www.openfoam.com
|
||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Copyright (C) 2020-2023 OpenCFD Ltd.
|
Copyright (C) 2020-2025 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM.
|
This file is part of OpenFOAM.
|
||||||
@ -26,9 +26,9 @@ License
|
|||||||
\*---------------------------------------------------------------------------*/
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
#include "dynamicContactAngleForce.H"
|
#include "dynamicContactAngleForce.H"
|
||||||
#include "addToRunTimeSelectionTable.H"
|
|
||||||
#include "Function1.H"
|
#include "Function1.H"
|
||||||
#include "distributionModel.H"
|
#include "distributionModel.H"
|
||||||
|
#include "addToRunTimeSelectionTable.H"
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
@ -59,6 +59,7 @@ dynamicContactAngleForce::dynamicContactAngleForce
|
|||||||
)
|
)
|
||||||
:
|
:
|
||||||
contactAngleForce(typeName, film, dict),
|
contactAngleForce(typeName, film, dict),
|
||||||
|
thetaPtr_(nullptr),
|
||||||
U_vs_thetaPtr_
|
U_vs_thetaPtr_
|
||||||
(
|
(
|
||||||
Function1<scalar>::NewIfPresent
|
Function1<scalar>::NewIfPresent
|
||||||
@ -80,46 +81,56 @@ dynamicContactAngleForce::dynamicContactAngleForce
|
|||||||
)
|
)
|
||||||
),
|
),
|
||||||
rndGen_(label(0)),
|
rndGen_(label(0)),
|
||||||
distribution_
|
distributionPtr_(nullptr)
|
||||||
(
|
|
||||||
distributionModel::New
|
|
||||||
(
|
|
||||||
coeffDict_.subDict("distribution"),
|
|
||||||
rndGen_
|
|
||||||
)
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
if (U_vs_thetaPtr_ && T_vs_thetaPtr_)
|
if (U_vs_thetaPtr_ && T_vs_thetaPtr_)
|
||||||
{
|
{
|
||||||
FatalIOErrorInFunction(dict)
|
FatalIOErrorInFunction(dict)
|
||||||
<< "Entries Utheta and Ttheta could not be used together"
|
<< "Only one of Utheta or Ttheta should be provided; "
|
||||||
|
<< "both inputs cannot be used together."
|
||||||
<< abort(FatalIOError);
|
<< abort(FatalIOError);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
thetaPtr_.emplace
|
||||||
|
(
|
||||||
|
IOobject
|
||||||
|
(
|
||||||
|
IOobject::scopedName(typeName, "theta"),
|
||||||
|
film.regionMesh().time().timeName(),
|
||||||
|
film.regionMesh().thisDb(),
|
||||||
|
IOobject::READ_IF_PRESENT,
|
||||||
|
IOobject::AUTO_WRITE
|
||||||
|
),
|
||||||
|
film.regionMesh(),
|
||||||
|
dimensionedScalar(dimless, Zero)
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
if (coeffDict_.findEntry("distribution"))
|
||||||
|
{
|
||||||
|
distributionPtr_ = distributionModel::New
|
||||||
|
(
|
||||||
|
coeffDict_.subDict("distribution"),
|
||||||
|
rndGen_
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
dynamicContactAngleForce::~dynamicContactAngleForce()
|
||||||
|
{} // distributionModel was forward declared
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
tmp<areaScalarField> dynamicContactAngleForce::theta() const
|
tmp<areaScalarField> dynamicContactAngleForce::theta() const
|
||||||
{
|
{
|
||||||
auto ttheta = tmp<areaScalarField>::New
|
areaScalarField& theta = thetaPtr_.ref();
|
||||||
(
|
|
||||||
IOobject
|
|
||||||
(
|
|
||||||
IOobject::scopedName(typeName, "theta"),
|
|
||||||
film().regionMesh().time().timeName(),
|
|
||||||
film().regionMesh().thisDb(),
|
|
||||||
IOobject::NO_READ,
|
|
||||||
IOobject::NO_WRITE,
|
|
||||||
IOobject::NO_REGISTER
|
|
||||||
),
|
|
||||||
film().regionMesh(),
|
|
||||||
dimensionedScalar(dimless, Zero)
|
|
||||||
);
|
|
||||||
areaScalarField& theta = ttheta.ref();
|
|
||||||
scalarField& thetai = theta.ref();
|
scalarField& thetai = theta.ref();
|
||||||
|
|
||||||
|
|
||||||
if (U_vs_thetaPtr_)
|
if (U_vs_thetaPtr_)
|
||||||
{
|
{
|
||||||
// Initialize with the function of film speed
|
// Initialize with the function of film speed
|
||||||
@ -136,13 +147,16 @@ tmp<areaScalarField> dynamicContactAngleForce::theta() const
|
|||||||
thetai = T_vs_thetaPtr_->value(T());
|
thetai = T_vs_thetaPtr_->value(T());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add the stochastic perturbation
|
if (distributionPtr_)
|
||||||
forAll(thetai, facei)
|
|
||||||
{
|
{
|
||||||
thetai[facei] += distribution_->sample();
|
// Add the stochastic perturbation
|
||||||
|
forAll(thetai, facei)
|
||||||
|
{
|
||||||
|
thetai[facei] += distributionPtr_->sample();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return ttheta;
|
return thetaPtr_();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -5,7 +5,7 @@
|
|||||||
\\ / A nd | www.openfoam.com
|
\\ / A nd | www.openfoam.com
|
||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Copyright (C) 2020-2022 OpenCFD Ltd.
|
Copyright (C) 2020-2025 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM.
|
This file is part of OpenFOAM.
|
||||||
@ -112,6 +112,9 @@ class dynamicContactAngleForce
|
|||||||
{
|
{
|
||||||
// Private Data
|
// Private Data
|
||||||
|
|
||||||
|
//- Contact-angle field in degrees
|
||||||
|
mutable autoPtr<areaScalarField> thetaPtr_;
|
||||||
|
|
||||||
//- Contact angle as a function of film speed
|
//- Contact angle as a function of film speed
|
||||||
autoPtr<Function1<scalar>> U_vs_thetaPtr_;
|
autoPtr<Function1<scalar>> U_vs_thetaPtr_;
|
||||||
|
|
||||||
@ -121,17 +124,8 @@ class dynamicContactAngleForce
|
|||||||
//- Random number generator
|
//- Random number generator
|
||||||
Random rndGen_;
|
Random rndGen_;
|
||||||
|
|
||||||
//- Parcel size PDF model
|
//- Stochastic perturbation model for contact angle
|
||||||
const autoPtr<distributionModel> distribution_;
|
autoPtr<distributionModel> distributionPtr_;
|
||||||
|
|
||||||
|
|
||||||
// Private Member Functions
|
|
||||||
|
|
||||||
//- No copy construct
|
|
||||||
dynamicContactAngleForce(const dynamicContactAngleForce&) = delete;
|
|
||||||
|
|
||||||
//- No copy assignment
|
|
||||||
void operator=(const dynamicContactAngleForce&) = delete;
|
|
||||||
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
@ -148,7 +142,7 @@ public:
|
|||||||
|
|
||||||
// Constructors
|
// Constructors
|
||||||
|
|
||||||
//- Construct from surface film model
|
//- Construct from surface film model and dictionary
|
||||||
dynamicContactAngleForce
|
dynamicContactAngleForce
|
||||||
(
|
(
|
||||||
liquidFilmBase& film,
|
liquidFilmBase& film,
|
||||||
@ -157,7 +151,7 @@ public:
|
|||||||
|
|
||||||
|
|
||||||
//- Destructor
|
//- Destructor
|
||||||
virtual ~dynamicContactAngleForce() = default;
|
virtual ~dynamicContactAngleForce();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -27,6 +27,7 @@ License
|
|||||||
|
|
||||||
#include "regionFaModel.H"
|
#include "regionFaModel.H"
|
||||||
#include "faMesh.H"
|
#include "faMesh.H"
|
||||||
|
#include "faMeshesRegistry.H"
|
||||||
#include "Time.H"
|
#include "Time.H"
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||||
@ -73,7 +74,7 @@ Foam::IOobject createModelIOobject
|
|||||||
(
|
(
|
||||||
objName,
|
objName,
|
||||||
mesh.time().constant(),
|
mesh.time().constant(),
|
||||||
faMesh::Registry(mesh),
|
faMeshesRegistry::New(mesh).thisDb(),
|
||||||
IOobjectOption::NO_READ,
|
IOobjectOption::NO_READ,
|
||||||
IOobjectOption::NO_WRITE,
|
IOobjectOption::NO_WRITE,
|
||||||
IOobjectOption::REGISTER
|
IOobjectOption::REGISTER
|
||||||
@ -140,71 +141,12 @@ Foam::IOobject createPropertiesIOobject
|
|||||||
|
|
||||||
// * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * * //
|
// * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * * //
|
||||||
|
|
||||||
void Foam::regionModels::regionFaModel::constructMeshObjects
|
void Foam::regionModels::regionFaModel::constructMeshObjects()
|
||||||
(
|
|
||||||
// Just for error reference
|
|
||||||
const dictionary& dict
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
regionMeshPtr_.reset(nullptr);
|
|
||||||
|
|
||||||
#if 1
|
|
||||||
regionMeshPtr_.reset
|
regionMeshPtr_.reset
|
||||||
(
|
(
|
||||||
new faMesh(areaName_, primaryMesh_)
|
new faMesh(areaName_, primaryMesh_)
|
||||||
);
|
);
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
// With try/catch and error messages
|
|
||||||
|
|
||||||
// DIY
|
|
||||||
// regionMeshPtr_ = faMesh::TryNew(areaName_, primaryMesh_);
|
|
||||||
|
|
||||||
// More heavy handed, but gives a better chance of locating
|
|
||||||
// the source of the error.
|
|
||||||
{
|
|
||||||
const bool oldThrowingError = FatalError.throwing(true);
|
|
||||||
const bool oldThrowingIOerr = FatalIOError.throwing(true);
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
regionMeshPtr_.reset
|
|
||||||
(
|
|
||||||
new faMesh(areaName_, primaryMesh_)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
catch (const Foam::error& err)
|
|
||||||
{
|
|
||||||
Warning << err << nl << endl;
|
|
||||||
|
|
||||||
// Trickery to get original message
|
|
||||||
err.write(Warning, false);
|
|
||||||
}
|
|
||||||
catch (const Foam::IOerror& err)
|
|
||||||
{
|
|
||||||
Warning << err << nl << endl;
|
|
||||||
|
|
||||||
// Trickery to get original message
|
|
||||||
err.write(Warning, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
FatalError.throwing(oldThrowingError);
|
|
||||||
FatalIOError.throwing(oldThrowingIOerr);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!regionMeshPtr_)
|
|
||||||
{
|
|
||||||
FatalError
|
|
||||||
<< "Failed to create finite-area mesh [" << areaName_
|
|
||||||
<< "] for model: "<< modelName_ << nl
|
|
||||||
<< "A common cause is an incorrect or"
|
|
||||||
" missing 'area' entry in the setup" << nl
|
|
||||||
<< ">>>>" << nl
|
|
||||||
<< dict.relativeName() << dict << "<<<<" << endl
|
|
||||||
<< exit(FatalError);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -292,35 +234,7 @@ Foam::regionModels::regionFaModel::regionFaModel
|
|||||||
regionName_(dict.get<word>("region")),
|
regionName_(dict.get<word>("region")),
|
||||||
coeffs_(dict.subOrEmptyDict(modelName + "Coeffs"))
|
coeffs_(dict.subOrEmptyDict(modelName + "Coeffs"))
|
||||||
{
|
{
|
||||||
// Suffix hint for variable names
|
constructMeshObjects();
|
||||||
if
|
|
||||||
(
|
|
||||||
coeffs_.readIfPresent("suffixing", suffixHint_)
|
|
||||||
|| dict.readIfPresent("suffixing", suffixHint_)
|
|
||||||
)
|
|
||||||
{
|
|
||||||
Switch sw = Switch::find(suffixHint_);
|
|
||||||
|
|
||||||
if (sw.good())
|
|
||||||
{
|
|
||||||
if (!sw) // No suffix
|
|
||||||
{
|
|
||||||
suffixHint_.clear();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (suffixHint_ == "default")
|
|
||||||
{
|
|
||||||
// Use default suffix
|
|
||||||
sw = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sw) // Default suffix
|
|
||||||
{
|
|
||||||
suffixHint_ = '_' + regionName_;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
constructMeshObjects(dict);
|
|
||||||
initialise();
|
initialise();
|
||||||
|
|
||||||
if (readFields)
|
if (readFields)
|
||||||
@ -336,14 +250,9 @@ void Foam::regionModels::regionFaModel::evolve()
|
|||||||
{
|
{
|
||||||
if (active_)
|
if (active_)
|
||||||
{
|
{
|
||||||
Info<< "\nEvolving " << modelName_
|
Info<< "\nEvolving " << modelName_ << " for region "
|
||||||
<< " for region " << regionMesh().name();
|
<< regionMesh().name() << " : "
|
||||||
|
<< polyMesh::regionName(areaName_) << endl;
|
||||||
if (!polyMesh::regionName(areaName_).empty())
|
|
||||||
{
|
|
||||||
Info<< " [" << areaName_ << "]";
|
|
||||||
}
|
|
||||||
Info<< endl;
|
|
||||||
|
|
||||||
preEvolveRegion();
|
preEvolveRegion();
|
||||||
|
|
||||||
@ -356,7 +265,7 @@ void Foam::regionModels::regionFaModel::evolve()
|
|||||||
{
|
{
|
||||||
Info<< incrIndent;
|
Info<< incrIndent;
|
||||||
info();
|
info();
|
||||||
Info<< decrIndent << endl;
|
Info<< endl << decrIndent;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -57,20 +57,9 @@ Usage
|
|||||||
region | Name of operand region | word | yes | -
|
region | Name of operand region | word | yes | -
|
||||||
area | Name of the finite-area mesh | word | no | region0
|
area | Name of the finite-area mesh | word | no | region0
|
||||||
active | Flag to activate the model | bool | yes | -
|
active | Flag to activate the model | bool | yes | -
|
||||||
suffixing | Suffix hint for model variables | word | no | -
|
|
||||||
infoOutput | Flag to activate information output | bool | no | false
|
infoOutput | Flag to activate information output | bool | no | false
|
||||||
\endtable
|
\endtable
|
||||||
|
|
||||||
Note
|
|
||||||
The \c suffixing parameter is a hint that individual models may use
|
|
||||||
when automatically generating variable names internally. For example,
|
|
||||||
a model \em may provide ("T" + suffixing) and ("q" + suffixing)
|
|
||||||
as its default names temperature and flux fields, respectively.
|
|
||||||
If the user specifies \c suffixing = "_foo", those \em default names
|
|
||||||
would then become "T_foo" and "q_foo", respectively.
|
|
||||||
Suffixing (true|false|none|default|...) currently selects between
|
|
||||||
no suffix and ('_'+region).
|
|
||||||
|
|
||||||
SourceFiles
|
SourceFiles
|
||||||
regionFaModelI.H
|
regionFaModelI.H
|
||||||
regionFaModel.C
|
regionFaModel.C
|
||||||
@ -101,7 +90,7 @@ class regionFaModel
|
|||||||
// Private Member Functions
|
// Private Member Functions
|
||||||
|
|
||||||
//- Construct region mesh and fields
|
//- Construct region mesh and fields
|
||||||
void constructMeshObjects(const dictionary&);
|
void constructMeshObjects();
|
||||||
|
|
||||||
//- Initialise the region
|
//- Initialise the region
|
||||||
void initialise();
|
void initialise();
|
||||||
@ -129,21 +118,18 @@ protected:
|
|||||||
//- Model name
|
//- Model name
|
||||||
const word modelName_;
|
const word modelName_;
|
||||||
|
|
||||||
//- Suffix hint for automatic model variable names (default: "")
|
//- The finite-area mesh name
|
||||||
word suffixHint_;
|
|
||||||
|
|
||||||
//- The finite-area mesh name (default: region0)
|
|
||||||
word areaName_;
|
word areaName_;
|
||||||
|
|
||||||
//- Region name
|
//- Region name
|
||||||
word regionName_;
|
word regionName_;
|
||||||
|
|
||||||
//- Model coefficients dictionary
|
|
||||||
dictionary coeffs_;
|
|
||||||
|
|
||||||
//- Pointer to the region mesh database
|
//- Pointer to the region mesh database
|
||||||
autoPtr<faMesh> regionMeshPtr_;
|
autoPtr<faMesh> regionMeshPtr_;
|
||||||
|
|
||||||
|
//- Model coefficients dictionary
|
||||||
|
dictionary coeffs_;
|
||||||
|
|
||||||
//- Dictionary of output properties
|
//- Dictionary of output properties
|
||||||
autoPtr<IOdictionary> outputPropertiesPtr_;
|
autoPtr<IOdictionary> outputPropertiesPtr_;
|
||||||
|
|
||||||
@ -238,15 +224,6 @@ public:
|
|||||||
//- Return mapping between surface and volume fields
|
//- Return mapping between surface and volume fields
|
||||||
const volSurfaceMapping& vsm() const;
|
const volSurfaceMapping& vsm() const;
|
||||||
|
|
||||||
//- The suffix hint for automatic model variable names
|
|
||||||
const word& suffixHint() const noexcept { return suffixHint_; }
|
|
||||||
|
|
||||||
//- Return the concatenation of \p base and the suffix hint
|
|
||||||
inline word suffixed(const char* base) const;
|
|
||||||
|
|
||||||
//- Return the concatenation of \p base and the suffix hint
|
|
||||||
inline word suffixed(const std::string& base) const;
|
|
||||||
|
|
||||||
|
|
||||||
// Evolution
|
// Evolution
|
||||||
|
|
||||||
|
|||||||
@ -27,7 +27,7 @@ License
|
|||||||
|
|
||||||
#include "regionFaModel.H"
|
#include "regionFaModel.H"
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
inline const Foam::faMesh& Foam::regionModels::regionFaModel::regionMesh() const
|
inline const Foam::faMesh& Foam::regionModels::regionFaModel::regionMesh() const
|
||||||
{
|
{
|
||||||
@ -106,18 +106,4 @@ inline bool Foam::regionModels::regionFaModel::isRegionPatch
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
inline Foam::word
|
|
||||||
Foam::regionModels::regionFaModel::suffixed(const char* base) const
|
|
||||||
{
|
|
||||||
return word(base + suffixHint_);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline Foam::word
|
|
||||||
Foam::regionModels::regionFaModel::suffixed(const std::string& base) const
|
|
||||||
{
|
|
||||||
return word(base + suffixHint_);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
// ************************************************************************* //
|
||||||
|
|||||||
@ -123,29 +123,14 @@ thermalShell::thermalShell
|
|||||||
)
|
)
|
||||||
:
|
:
|
||||||
thermalShellModel(modelType, mesh, dict),
|
thermalShellModel(modelType, mesh, dict),
|
||||||
hName_(dict.getOrDefault<word>("h", suffixed("hs"))),
|
|
||||||
qsName_(dict.getOrDefault<word>("qs", suffixed("qs"))),
|
|
||||||
qrName_(dict.getOrDefault<word>("qr", "none")),
|
|
||||||
nNonOrthCorr_(1),
|
nNonOrthCorr_(1),
|
||||||
// Only need/want thermal solid properties
|
// Only need/want thermal solid properties
|
||||||
thermo_(dict.subDict("thermo"), solidProperties::THERMAL),
|
thermo_(dict.subDict("thermo"), solidProperties::THERMAL),
|
||||||
h_
|
|
||||||
(
|
|
||||||
IOobject
|
|
||||||
(
|
|
||||||
hName_,
|
|
||||||
regionMesh().time().timeName(),
|
|
||||||
regionMesh().thisDb(),
|
|
||||||
IOobject::MUST_READ,
|
|
||||||
IOobject::AUTO_WRITE
|
|
||||||
),
|
|
||||||
regionMesh()
|
|
||||||
),
|
|
||||||
qs_
|
qs_
|
||||||
(
|
(
|
||||||
IOobject
|
IOobject
|
||||||
(
|
(
|
||||||
qsName_,
|
"qs_" + regionName_,
|
||||||
regionMesh().time().timeName(),
|
regionMesh().time().timeName(),
|
||||||
regionMesh().thisDb(),
|
regionMesh().thisDb(),
|
||||||
IOobject::READ_IF_PRESENT,
|
IOobject::READ_IF_PRESENT,
|
||||||
@ -154,6 +139,19 @@ thermalShell::thermalShell
|
|||||||
regionMesh(),
|
regionMesh(),
|
||||||
dimensionedScalar(dimPower/dimArea, Zero)
|
dimensionedScalar(dimPower/dimArea, Zero)
|
||||||
),
|
),
|
||||||
|
h_
|
||||||
|
(
|
||||||
|
IOobject
|
||||||
|
(
|
||||||
|
"h_" + regionName_,
|
||||||
|
regionMesh().time().timeName(),
|
||||||
|
regionMesh().thisDb(),
|
||||||
|
IOobject::MUST_READ,
|
||||||
|
IOobject::AUTO_WRITE
|
||||||
|
),
|
||||||
|
regionMesh()
|
||||||
|
),
|
||||||
|
qrName_(dict.getOrDefault<word>("qr", "none")),
|
||||||
thickness_(dict.getOrDefault<scalar>("thickness", 0))
|
thickness_(dict.getOrDefault<scalar>("thickness", 0))
|
||||||
{
|
{
|
||||||
init(dict);
|
init(dict);
|
||||||
|
|||||||
@ -5,7 +5,7 @@
|
|||||||
\\ / A nd | www.openfoam.com
|
\\ / A nd | www.openfoam.com
|
||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Copyright (C) 2019-2025 OpenCFD Ltd.
|
Copyright (C) 2019-2020 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM.
|
This file is part of OpenFOAM.
|
||||||
@ -56,28 +56,11 @@ Usage
|
|||||||
|
|
||||||
where the entries mean:
|
where the entries mean:
|
||||||
\table
|
\table
|
||||||
Property | Description | Type | Reqd | Deflt
|
Property | Description | Type | Reqd | Deflt
|
||||||
thermalShellModel | Type name: thermalShell | word | yes | -
|
thermalShellModel | Type name: thermalShell | word | yes | -
|
||||||
h | Name of thickness field | word | no | hs (suffix)
|
thermo | Solid thermal properties | dictionary | yes | -
|
||||||
qs | Name of source field | word | no | qs (suffix)
|
qr | Name of radiative heat flux field | word | no | none
|
||||||
qr | Name of radiative heat flux field | word | no | none
|
thickness | Uniform film thickness [m] | scalar | choice | -
|
||||||
thermo | Solid thermal properties | dict | yes | -
|
|
||||||
thickness | Uniform shell thickness [m] | scalar | choice | -
|
|
||||||
\endtable
|
|
||||||
|
|
||||||
Fields/variables used:
|
|
||||||
\table
|
|
||||||
Property | Description | Type | Deflt
|
|
||||||
h | Thickness | shell | hs (suffix)
|
|
||||||
qs | Source field | shell | qs (suffix)
|
|
||||||
qr | Radiative heat flux field | volume | none
|
|
||||||
\endtable
|
|
||||||
|
|
||||||
Note the following naming changes from 2056 and earlier:
|
|
||||||
\table
|
|
||||||
Keyword | Description | Keyword (old) | Deflt (old)
|
|
||||||
h | Temperature (volume) | h | "h_" + regionName
|
|
||||||
qs | Temperature (shell) | qs | "qs_" + regionName
|
|
||||||
\endtable
|
\endtable
|
||||||
|
|
||||||
The inherited entries are elaborated in:
|
The inherited entries are elaborated in:
|
||||||
@ -85,6 +68,7 @@ Usage
|
|||||||
|
|
||||||
SourceFiles
|
SourceFiles
|
||||||
thermalShell.C
|
thermalShell.C
|
||||||
|
thermalShellI.H
|
||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
@ -124,38 +108,31 @@ protected:
|
|||||||
|
|
||||||
// Protected Data
|
// Protected Data
|
||||||
|
|
||||||
//- Name of shell thickness [height] field (default: "hs" + suffix)
|
// Solution parameters
|
||||||
const word hName_;
|
|
||||||
|
|
||||||
//- Name of surface energy source (default: "qs" + suffix)
|
//- Number of non orthogonal correctors
|
||||||
const word qsName_;
|
label nNonOrthCorr_;
|
||||||
|
|
||||||
//- Name of (volume) radiative flux field (default: none)
|
|
||||||
const word qrName_;
|
|
||||||
|
|
||||||
|
|
||||||
// Solution Parameters
|
// Thermo properties
|
||||||
|
|
||||||
//- Number of non orthogonal correctors
|
//- Solid properties
|
||||||
label nNonOrthCorr_;
|
solidProperties thermo_;
|
||||||
|
|
||||||
|
|
||||||
// Thermo properties
|
// Source term fields
|
||||||
|
|
||||||
//- Solid properties
|
//- External surface energy source [J/m2/s]
|
||||||
solidProperties thermo_;
|
areaScalarField qs_;
|
||||||
|
|
||||||
|
//- Film thickness [m]
|
||||||
|
areaScalarField h_;
|
||||||
|
|
||||||
// Source term fields
|
//- Name of the primary region radiative flux
|
||||||
|
const word qrName_;
|
||||||
|
|
||||||
//- Shell thickness field [m]
|
//- Uniform film thickness [m]
|
||||||
areaScalarField h_;
|
scalar thickness_;
|
||||||
|
|
||||||
//- External surface energy source [J/m2/s]
|
|
||||||
areaScalarField qs_;
|
|
||||||
|
|
||||||
//- Uniform shell thickness [m]
|
|
||||||
scalar thickness_;
|
|
||||||
|
|
||||||
|
|
||||||
// Protected Member Functions
|
// Protected Member Functions
|
||||||
@ -197,7 +174,7 @@ public:
|
|||||||
|
|
||||||
// Fields
|
// Fields
|
||||||
|
|
||||||
//- Return the shell specific heat capacity [J/kg/K]
|
//- Return the film specific heat capacity [J/kg/K]
|
||||||
const tmp<areaScalarField> Cp() const;
|
const tmp<areaScalarField> Cp() const;
|
||||||
|
|
||||||
//- Return density [kg/m3]
|
//- Return density [kg/m3]
|
||||||
|
|||||||
@ -50,14 +50,13 @@ thermalShellModel::thermalShellModel
|
|||||||
)
|
)
|
||||||
:
|
:
|
||||||
regionFaModel(mesh, "thermalShell", modelType, dict, true),
|
regionFaModel(mesh, "thermalShell", modelType, dict, true),
|
||||||
TName_(dict.getOrDefault<word>("T", suffixed("Ts"))),
|
TName_(dict.get<word>("T")),
|
||||||
TprimaryName_(dict.getOrDefault<word>("Tprimary", "T")),
|
Tp_(mesh.lookupObject<volScalarField>(TName_)),
|
||||||
Tp_(mesh.lookupObject<volScalarField>(TprimaryName_)),
|
|
||||||
T_
|
T_
|
||||||
(
|
(
|
||||||
IOobject
|
IOobject
|
||||||
(
|
(
|
||||||
TName_,
|
"Ts_" + regionName_,
|
||||||
regionMesh().time().timeName(),
|
regionMesh().time().timeName(),
|
||||||
regionMesh().thisDb(),
|
regionMesh().thisDb(),
|
||||||
IOobject::MUST_READ,
|
IOobject::MUST_READ,
|
||||||
@ -72,8 +71,8 @@ thermalShellModel::thermalShellModel
|
|||||||
{
|
{
|
||||||
if (faOptions_.optionList::empty())
|
if (faOptions_.optionList::empty())
|
||||||
{
|
{
|
||||||
Info<< "No finite-area options present for area:"
|
Info<< "No finite area options present for area : "
|
||||||
<< regionFaModel::areaName() << endl;
|
<< polyMesh::regionName(regionFaModel::areaName()) << endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -24,7 +24,7 @@ License
|
|||||||
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
Class
|
Class
|
||||||
Foam::regionModels::thermalShellModel
|
Foam::regionModels::thermalShellModels::thermalShellModel
|
||||||
|
|
||||||
Description
|
Description
|
||||||
Intermediate class for thermal-shell finite-area models.
|
Intermediate class for thermal-shell finite-area models.
|
||||||
@ -34,12 +34,12 @@ Usage
|
|||||||
\verbatim
|
\verbatim
|
||||||
<patchName>
|
<patchName>
|
||||||
{
|
{
|
||||||
|
// Mandatory entries
|
||||||
|
T <word>;
|
||||||
|
|
||||||
// Optional entries
|
// Optional entries
|
||||||
thermalShellModel <word>;
|
thermalShellModel <word>;
|
||||||
|
|
||||||
T <word>;
|
|
||||||
Tprimary <word>;
|
|
||||||
|
|
||||||
// Inherited entries
|
// Inherited entries
|
||||||
...
|
...
|
||||||
}
|
}
|
||||||
@ -47,27 +47,12 @@ Usage
|
|||||||
|
|
||||||
where the entries mean:
|
where the entries mean:
|
||||||
\table
|
\table
|
||||||
Property | Description | Type | Reqd | Deflt
|
Property | Description | Type | Reqd | Deflt
|
||||||
T | Name of operand temperature field | word | no | Ts (suffix)
|
T | Name of operand temperature field | word | yes | -
|
||||||
Tprimary | Name of primary temperature field | word | no | T
|
thermalShellModel | Name of thermal-shell model <!--
|
||||||
thermalShellModel | Name of thermalShellModel thermal-shell model <!--
|
|
||||||
--> | word | choice | -
|
--> | word | choice | -
|
||||||
\endtable
|
\endtable
|
||||||
|
|
||||||
Fields/variables used:
|
|
||||||
\table
|
|
||||||
Property | Description | Type | Deflt
|
|
||||||
T | Temperature | shell | Ts (suffix)
|
|
||||||
Tprimary | Temperature | volume | T
|
|
||||||
\endtable
|
|
||||||
|
|
||||||
\b BREAKING Naming changes from 2056 and earlier:
|
|
||||||
\table
|
|
||||||
Keyword | Description | Keyword (old) | Deflt (old)
|
|
||||||
T | Temperature (shell) | - | "Ts_" + regionName
|
|
||||||
Tprimary | Temperature (volume) | T | -
|
|
||||||
\endtable
|
|
||||||
|
|
||||||
The inherited entries are elaborated in:
|
The inherited entries are elaborated in:
|
||||||
- \link regionFaModel.H \endlink
|
- \link regionFaModel.H \endlink
|
||||||
|
|
||||||
@ -104,11 +89,8 @@ protected:
|
|||||||
|
|
||||||
// Protected Data
|
// Protected Data
|
||||||
|
|
||||||
//- Name of shell temperature field (default: "Ts" + suffix)
|
//- Name of the temperature field
|
||||||
const word TName_;
|
word TName_;
|
||||||
|
|
||||||
//- Name of volume temperature field (default: "T")
|
|
||||||
const word TprimaryName_;
|
|
||||||
|
|
||||||
//- Primary (volume) region temperature
|
//- Primary (volume) region temperature
|
||||||
const volScalarField& Tp_;
|
const volScalarField& Tp_;
|
||||||
|
|||||||
@ -53,7 +53,7 @@ vibrationShellModel::vibrationShellModel
|
|||||||
(
|
(
|
||||||
IOobject
|
IOobject
|
||||||
(
|
(
|
||||||
dict.getOrDefault<word>("ws", suffixed("ws")),
|
"ws_" + regionName_,
|
||||||
regionMesh().time().timeName(),
|
regionMesh().time().timeName(),
|
||||||
regionMesh().thisDb(),
|
regionMesh().thisDb(),
|
||||||
IOobject::MUST_READ,
|
IOobject::MUST_READ,
|
||||||
@ -65,7 +65,7 @@ vibrationShellModel::vibrationShellModel
|
|||||||
(
|
(
|
||||||
IOobject
|
IOobject
|
||||||
(
|
(
|
||||||
dict.getOrDefault<word>("as", suffixed("as")),
|
"as_" + regionName_,
|
||||||
regionMesh().time().timeName(),
|
regionMesh().time().timeName(),
|
||||||
regionMesh().thisDb(),
|
regionMesh().thisDb(),
|
||||||
IOobject::NO_READ,
|
IOobject::NO_READ,
|
||||||
|
|||||||
@ -24,7 +24,7 @@ License
|
|||||||
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
Class
|
Class
|
||||||
Foam::regionModels::vibrationShellModel
|
Foam::regionModels::thermalShellModels::vibrationShellModel
|
||||||
|
|
||||||
Description
|
Description
|
||||||
Intermediate class for vibration-shell finite-area models.
|
Intermediate class for vibration-shell finite-area models.
|
||||||
@ -52,19 +52,9 @@ Usage
|
|||||||
\table
|
\table
|
||||||
Property | Description | Type | Reqd | Deflt
|
Property | Description | Type | Reqd | Deflt
|
||||||
vibrationShellModel | Name of vibration-shell model | word | yes | -
|
vibrationShellModel | Name of vibration-shell model | word | yes | -
|
||||||
p | Name of primary pressure field | word | yes | -
|
p | Name of the coupled field in the primary <!--
|
||||||
solid | Solid properties | dict | yes | -
|
--> region | word | yes | -
|
||||||
as | Name of shell acceleration field | word | no | as (suffix)
|
solid | Solid properties | dictionary | yes | -
|
||||||
ps | Name of pressure (source) on shell | word | no | ps (suffix)
|
|
||||||
ws | Name of shell displacement field | word | no | ws (suffix)
|
|
||||||
\endtable
|
|
||||||
|
|
||||||
Naming changes from 2056 and earlier:
|
|
||||||
\table
|
|
||||||
Keyword | Description | Keyword (old) | Deflt (old)
|
|
||||||
as | Acceleration (shell) | - | "as_" + regionName
|
|
||||||
ps | Pressure on shell | - | "ps_" + regionName
|
|
||||||
ws | Displacement (shell) | - | "ws_" + regionName
|
|
||||||
\endtable
|
\endtable
|
||||||
|
|
||||||
The inherited entries are elaborated in:
|
The inherited entries are elaborated in:
|
||||||
@ -103,19 +93,19 @@ protected:
|
|||||||
|
|
||||||
// Protected Data
|
// Protected Data
|
||||||
|
|
||||||
//- Shell displacement [m]
|
//- Shell displacement
|
||||||
areaScalarField w_;
|
areaScalarField w_;
|
||||||
|
|
||||||
//- Shell acceleration [m/s2]
|
//- Shell acceleration
|
||||||
areaScalarField a_;
|
areaScalarField a_;
|
||||||
|
|
||||||
//- Solid properties
|
//- Solid properties
|
||||||
solidProperties solid_;
|
solidProperties solid_;
|
||||||
|
|
||||||
//- Name of primary region acoustic pressure field
|
//- Name of the coupled field in the primary region
|
||||||
word pName_;
|
word pName_;
|
||||||
|
|
||||||
//- Primary region acoustic pressure [Pa]
|
//- Primary region acoustic pressure
|
||||||
const volScalarField& pa_;
|
const volScalarField& pa_;
|
||||||
|
|
||||||
//- Reference to faOptions
|
//- Reference to faOptions
|
||||||
@ -177,26 +167,26 @@ public:
|
|||||||
|
|
||||||
// Member Functions
|
// Member Functions
|
||||||
|
|
||||||
//- Return the primary region presssure
|
//- Return primary region pa
|
||||||
const volScalarField& pa() const noexcept { return pa_; }
|
const volScalarField& pa() const noexcept { return pa_; }
|
||||||
|
|
||||||
//- Return the shell displacement
|
//- Return shell displacement
|
||||||
const areaScalarField& w() const noexcept { return w_; }
|
const areaScalarField& w() const noexcept { return w_; }
|
||||||
|
|
||||||
//- Return the shell acceleration
|
//- Return shell acceleration
|
||||||
const areaScalarField& a() const noexcept { return a_; }
|
const areaScalarField& a() const noexcept { return a_; }
|
||||||
|
|
||||||
//- Return faOptions
|
//- Return faOptions
|
||||||
Foam::fa::options& faOptions() noexcept { return faOptions_; }
|
Foam::fa::options& faOptions() noexcept { return faOptions_; }
|
||||||
|
|
||||||
//- Return solid properties
|
//- Return solid properties
|
||||||
const solidProperties& solid() const noexcept { return solid_; }
|
const solidProperties& solid() const noexcept { return solid_; }
|
||||||
|
|
||||||
|
|
||||||
// Evolution
|
// Evolution
|
||||||
|
|
||||||
//- Pre-evolve region
|
//- Pre-evolve region
|
||||||
virtual void preEvolveRegion();
|
virtual void preEvolveRegion();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -10,7 +10,7 @@ FoamFile
|
|||||||
version 2.0;
|
version 2.0;
|
||||||
format ascii;
|
format ascii;
|
||||||
class areaScalarField;
|
class areaScalarField;
|
||||||
object hs;
|
object h_ceilingShell;
|
||||||
}
|
}
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
@ -10,7 +10,7 @@ FoamFile
|
|||||||
version 2.0;
|
version 2.0;
|
||||||
format ascii;
|
format ascii;
|
||||||
class areaScalarField;
|
class areaScalarField;
|
||||||
object ws;
|
object wS;
|
||||||
}
|
}
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
@ -41,7 +41,7 @@ boundaryField
|
|||||||
nu 0.22;
|
nu 0.22;
|
||||||
}
|
}
|
||||||
|
|
||||||
region vibration;
|
region vibrationShell;
|
||||||
vibrationShellModel KirchhoffShell;
|
vibrationShellModel KirchhoffShell;
|
||||||
|
|
||||||
f0 0.04;
|
f0 0.04;
|
||||||
|
|||||||
@ -17,13 +17,12 @@ FoamFile
|
|||||||
pressure
|
pressure
|
||||||
{
|
{
|
||||||
type externalFileSource;
|
type externalFileSource;
|
||||||
//fieldName ws_shell;
|
fieldName ws_vibrationShell;
|
||||||
fieldName ws;
|
|
||||||
tableName p;
|
tableName p;
|
||||||
active true;
|
active true;
|
||||||
timeStart 0.001;
|
timeStart 0.001;
|
||||||
duration 0.03;
|
duration 0.03;
|
||||||
region vibration;
|
region vibrationShell;
|
||||||
selectionMode all;
|
selectionMode all;
|
||||||
|
|
||||||
sampleFormat ensight;
|
sampleFormat ensight;
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user