mirror of
https://develop.openfoam.com/Development/openfoam.git
synced 2025-11-28 03:28:01 +00:00
Merge branch 'master' into cvm
This commit is contained in:
@ -66,6 +66,11 @@
|
|||||||
-doc display application documentation in browser
|
-doc display application documentation in browser
|
||||||
-help print the usage
|
-help print the usage
|
||||||
|
|
||||||
|
*** *New* basicSolidThermo solids thermophysical library
|
||||||
|
+ Used in all conjugate heat transfer solvers
|
||||||
|
+ constant properties
|
||||||
|
+ temperature dependent properties
|
||||||
|
+ temperature and direction (in local coordinate system) dependent properties
|
||||||
*** *New* Surface film library
|
*** *New* Surface film library
|
||||||
+ Creation of films by particle addition, or initial film distribution
|
+ Creation of films by particle addition, or initial film distribution
|
||||||
+ Coupled with the lagrangian/intermediate cloud hierarchy library
|
+ Coupled with the lagrangian/intermediate cloud hierarchy library
|
||||||
@ -86,7 +91,14 @@
|
|||||||
*** *New* ptscotch decomposition method
|
*** *New* ptscotch decomposition method
|
||||||
*** *Updated* particle tracking algorithm
|
*** *Updated* particle tracking algorithm
|
||||||
*** *Updated* split cyclics into two separate patches. See doc/changed/splitCyclics.txt
|
*** *Updated* split cyclics into two separate patches. See doc/changed/splitCyclics.txt
|
||||||
|
* *Updated* interpolation (volPointInterpolation) now works without the
|
||||||
|
globalPointPatch. Moving mesh cases can now be run non-parallel and
|
||||||
|
continued in parallel and reconstructed without any limitation.
|
||||||
*** *New* compact binary I/O for faces and cells. This speeds up reading/writing meshes in binary.
|
*** *New* compact binary I/O for faces and cells. This speeds up reading/writing meshes in binary.
|
||||||
|
*** *Updated* runTimeModifiable
|
||||||
|
+ on linux uses inotify instead of time stamps - more efficient for large
|
||||||
|
numbers of monitored files. No more fileModificationSkew needed.
|
||||||
|
+ single integer reduction instead of one reduction per monitored file.
|
||||||
* Solvers
|
* Solvers
|
||||||
A number of new solvers have been developed for a range of engineering
|
A number of new solvers have been developed for a range of engineering
|
||||||
applications. There has been a set of improvements to certain classes of
|
applications. There has been a set of improvements to certain classes of
|
||||||
@ -125,6 +137,8 @@
|
|||||||
(nonuniformTransform)cyclic <zoneA>_<zoneB>
|
(nonuniformTransform)cyclic <zoneA>_<zoneB>
|
||||||
+ extrudes into master direction (i.e. away from the owner cell
|
+ extrudes into master direction (i.e. away from the owner cell
|
||||||
if flipMap is false)
|
if flipMap is false)
|
||||||
|
+ =topoSet=: replacement of cellSet,faceSet,pointSet utilities.
|
||||||
|
Comparable to a dictionary driven =setSet= utility.
|
||||||
*** Updated utilities
|
*** Updated utilities
|
||||||
+ =setFields=: optionally use faceSets to set patch values (see e.g. hotRoom tutorial).
|
+ =setFields=: optionally use faceSets to set patch values (see e.g. hotRoom tutorial).
|
||||||
+ =blockMesh=: specify patches via dictionary instead of type only. This
|
+ =blockMesh=: specify patches via dictionary instead of type only. This
|
||||||
@ -133,6 +147,8 @@
|
|||||||
* Post-processing
|
* Post-processing
|
||||||
+ =foamToEnsight=: parallel continuous data. new =-nodeValues= option to generate and output nodal
|
+ =foamToEnsight=: parallel continuous data. new =-nodeValues= option to generate and output nodal
|
||||||
field data.
|
field data.
|
||||||
|
+ =singleCellMesh=: new utility to convert mesh and fields to a single cell
|
||||||
|
mesh. Great for postprocessing.
|
||||||
+ Function objects:
|
+ Function objects:
|
||||||
+ =residualControl=: new function object to allow users to terminate steady
|
+ =residualControl=: new function object to allow users to terminate steady
|
||||||
state calculations when the defined residual levels are achieved
|
state calculations when the defined residual levels are achieved
|
||||||
@ -144,7 +160,9 @@
|
|||||||
+ =streamLine=: generate streamlines; ouputs both trajectory and field data
|
+ =streamLine=: generate streamlines; ouputs both trajectory and field data
|
||||||
|
|
||||||
* New tutorials
|
* New tutorials
|
||||||
There is a large number of new tutorials to support the new solvers in the
|
There is a large number of new tutorials for existing and new solvers in the
|
||||||
release.
|
release.
|
||||||
+ =reactingParcelFilmFoam= tutorials:
|
+ =reactingParcelFilmFoam= tutorials:
|
||||||
+ multipleBoxes, hotBoxes, panel, evaporationTest
|
+ multipleBoxes, hotBoxes, panel, evaporationTest
|
||||||
|
+ =interDyMFoam= tutorials:
|
||||||
|
+ testTubeMixer: showcases =solidBodyMotionFunction=
|
||||||
|
|||||||
@ -34,7 +34,6 @@ Description
|
|||||||
#include "turbulenceModel.H"
|
#include "turbulenceModel.H"
|
||||||
#include "fixedGradientFvPatchFields.H"
|
#include "fixedGradientFvPatchFields.H"
|
||||||
#include "regionProperties.H"
|
#include "regionProperties.H"
|
||||||
#include "compressibleCourantNo.H"
|
|
||||||
#include "basicSolidThermo.H"
|
#include "basicSolidThermo.H"
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|||||||
@ -37,20 +37,14 @@ Foam::scalar Foam::compressibleCourantNo
|
|||||||
scalar CoNum = 0.0;
|
scalar CoNum = 0.0;
|
||||||
scalar meanCoNum = 0.0;
|
scalar meanCoNum = 0.0;
|
||||||
|
|
||||||
//- Can have fluid domains with 0 cells so do not test.
|
scalarField sumPhi =
|
||||||
//if (mesh.nInternalFaces())
|
fvc::surfaceSum(mag(phi))().internalField()
|
||||||
{
|
/rho.internalField();
|
||||||
surfaceScalarField SfUfbyDelta =
|
|
||||||
mesh.surfaceInterpolation::deltaCoeffs()
|
|
||||||
* mag(phi)
|
|
||||||
/ fvc::interpolate(rho);
|
|
||||||
|
|
||||||
CoNum = max(SfUfbyDelta/mesh.magSf())
|
CoNum = 0.5*gMax(sumPhi/mesh.V().field())*runTime.deltaTValue();
|
||||||
.value()*runTime.deltaT().value();
|
|
||||||
|
|
||||||
meanCoNum = (sum(SfUfbyDelta)/sum(mesh.magSf()))
|
meanCoNum =
|
||||||
.value()*runTime.deltaT().value();
|
0.5*(gSum(sumPhi)/gSum(mesh.V().field()))*runTime.deltaTValue();
|
||||||
}
|
|
||||||
|
|
||||||
Info<< "Region: " << mesh.name() << " Courant Number mean: " << meanCoNum
|
Info<< "Region: " << mesh.name() << " Courant Number mean: " << meanCoNum
|
||||||
<< " max: " << CoNum << endl;
|
<< " max: " << CoNum << endl;
|
||||||
|
|||||||
@ -37,18 +37,16 @@ Foam::scalar Foam::solidRegionDiffNo
|
|||||||
scalar DiNum = 0.0;
|
scalar DiNum = 0.0;
|
||||||
scalar meanDiNum = 0.0;
|
scalar meanDiNum = 0.0;
|
||||||
|
|
||||||
//- Can have fluid domains with 0 cells so do not test.
|
//- Take care: can have fluid domains with 0 cells so do not test for
|
||||||
if (mesh.nInternalFaces())
|
// zero internal faces.
|
||||||
{
|
|
||||||
surfaceScalarField KrhoCpbyDelta =
|
surfaceScalarField KrhoCpbyDelta =
|
||||||
mesh.surfaceInterpolation::deltaCoeffs()
|
mesh.surfaceInterpolation::deltaCoeffs()
|
||||||
* fvc::interpolate(K)
|
* fvc::interpolate(K)
|
||||||
/ fvc::interpolate(Cprho);
|
/ fvc::interpolate(Cprho);
|
||||||
|
|
||||||
DiNum = max(KrhoCpbyDelta.internalField())*runTime.deltaT().value();
|
DiNum = gMax(KrhoCpbyDelta.internalField())*runTime.deltaT().value();
|
||||||
|
|
||||||
meanDiNum = (average(KrhoCpbyDelta)).value()*runTime.deltaT().value();
|
meanDiNum = (average(KrhoCpbyDelta)).value()*runTime.deltaT().value();
|
||||||
}
|
|
||||||
|
|
||||||
Info<< "Region: " << mesh.name() << " Diffusion Number mean: " << meanDiNum
|
Info<< "Region: " << mesh.name() << " Diffusion Number mean: " << meanDiNum
|
||||||
<< " max: " << DiNum << endl;
|
<< " max: " << DiNum << endl;
|
||||||
|
|||||||
@ -55,7 +55,7 @@
|
|||||||
(
|
(
|
||||||
dimensionedScalar::lookupOrAddToDict
|
dimensionedScalar::lookupOrAddToDict
|
||||||
(
|
(
|
||||||
"alphaEps",
|
"alphak",
|
||||||
kEpsilonDict,
|
kEpsilonDict,
|
||||||
1.0
|
1.0
|
||||||
)
|
)
|
||||||
|
|||||||
@ -6,5 +6,6 @@ wclean
|
|||||||
wclean interDyMFoam
|
wclean interDyMFoam
|
||||||
wclean MRFInterFoam
|
wclean MRFInterFoam
|
||||||
wclean porousInterFoam
|
wclean porousInterFoam
|
||||||
|
wclean LTSInterFoam
|
||||||
|
|
||||||
# ----------------------------------------------------------------- end-of-file
|
# ----------------------------------------------------------------- end-of-file
|
||||||
|
|||||||
@ -6,5 +6,6 @@ wmake
|
|||||||
wmake interDyMFoam
|
wmake interDyMFoam
|
||||||
wmake MRFInterFoam
|
wmake MRFInterFoam
|
||||||
wmake porousInterFoam
|
wmake porousInterFoam
|
||||||
|
wmake LTSInterFoam
|
||||||
|
|
||||||
# ----------------------------------------------------------------- end-of-file
|
# ----------------------------------------------------------------- end-of-file
|
||||||
|
|||||||
@ -0,0 +1,101 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | Copyright (C) 1991-2010 OpenCFD Ltd.
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
License
|
||||||
|
This file is part of OpenFOAM.
|
||||||
|
|
||||||
|
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 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
|
||||||
|
interFoam
|
||||||
|
|
||||||
|
Description
|
||||||
|
Solver for 2 incompressible, isothermal immiscible fluids using a VOF
|
||||||
|
(volume of fluid) phase-fraction based interface capturing approach.
|
||||||
|
|
||||||
|
The momentum and other fluid properties are of the "mixture" and a single
|
||||||
|
momentum equation is solved.
|
||||||
|
|
||||||
|
Turbulence modelling is generic, i.e. laminar, RAS or LES may be selected.
|
||||||
|
|
||||||
|
For a two-fluid approach see twoPhaseEulerFoam.
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#include "fvCFD.H"
|
||||||
|
#include "MULES.H"
|
||||||
|
#include "subCycle.H"
|
||||||
|
#include "interfaceProperties.H"
|
||||||
|
#include "twoPhaseMixture.H"
|
||||||
|
#include "turbulenceModel.H"
|
||||||
|
#include "fvcSmooth.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
#include "setRootCase.H"
|
||||||
|
#include "createTime.H"
|
||||||
|
#include "createMesh.H"
|
||||||
|
#include "readPISOControls.H"
|
||||||
|
#include "initContinuityErrs.H"
|
||||||
|
#include "createFields.H"
|
||||||
|
#include "correctPhi.H"
|
||||||
|
#include "CourantNo.H"
|
||||||
|
#include "setInitialrDeltaT.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Info<< "\nStarting time loop\n" << endl;
|
||||||
|
|
||||||
|
while (runTime.run())
|
||||||
|
{
|
||||||
|
#include "readPISOControls.H"
|
||||||
|
|
||||||
|
runTime++;
|
||||||
|
|
||||||
|
Info<< "Time = " << runTime.timeName() << nl << endl;
|
||||||
|
|
||||||
|
#include "setrDeltaT.H"
|
||||||
|
|
||||||
|
twoPhaseProperties.correct();
|
||||||
|
|
||||||
|
#include "alphaEqnSubCycle.H"
|
||||||
|
turbulence->correct();
|
||||||
|
#include "UEqn.H"
|
||||||
|
|
||||||
|
// --- PISO loop
|
||||||
|
for (int corr=0; corr<nCorr; corr++)
|
||||||
|
{
|
||||||
|
#include "pEqn.H"
|
||||||
|
}
|
||||||
|
|
||||||
|
runTime.write();
|
||||||
|
|
||||||
|
Info<< "ExecutionTime = " << runTime.elapsedCpuTime() << " s"
|
||||||
|
<< " ClockTime = " << runTime.elapsedClockTime() << " s"
|
||||||
|
<< nl << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
Info<< "End\n" << endl;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -23,39 +23,60 @@ License
|
|||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
#include "compressibleCourantNo.H"
|
#include "MULES.H"
|
||||||
#include "fvc.H"
|
#include "upwind.H"
|
||||||
|
#include "uncorrectedSnGrad.H"
|
||||||
|
#include "gaussConvectionScheme.H"
|
||||||
|
#include "gaussLaplacianScheme.H"
|
||||||
|
#include "uncorrectedSnGrad.H"
|
||||||
|
#include "surfaceInterpolate.H"
|
||||||
|
#include "fvcSurfaceIntegrate.H"
|
||||||
|
#include "slicedSurfaceFields.H"
|
||||||
|
#include "syncTools.H"
|
||||||
|
|
||||||
Foam::scalar Foam::compressibleCourantNo
|
#include "fvCFD.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
void Foam::MULES::explicitLTSSolve
|
||||||
(
|
(
|
||||||
const fvMesh& mesh,
|
volScalarField& psi,
|
||||||
const Time& runTime,
|
const surfaceScalarField& phi,
|
||||||
const volScalarField& rho,
|
surfaceScalarField& phiPsi,
|
||||||
const surfaceScalarField& phi
|
const scalar psiMax,
|
||||||
|
const scalar psiMin
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
scalar CoNum = 0.0;
|
explicitLTSSolve
|
||||||
scalar meanCoNum = 0.0;
|
(
|
||||||
|
geometricOneField(),
|
||||||
//- Can have fluid domains with 0 cells so do not test.
|
psi,
|
||||||
//if (mesh.nInternalFaces())
|
phi,
|
||||||
{
|
phiPsi,
|
||||||
surfaceScalarField SfUfbyDelta =
|
zeroField(), zeroField(),
|
||||||
mesh.surfaceInterpolation::deltaCoeffs()
|
psiMax, psiMin
|
||||||
* mag(phi)
|
);
|
||||||
/ fvc::interpolate(rho);
|
|
||||||
|
|
||||||
CoNum = max(SfUfbyDelta/mesh.magSf())
|
|
||||||
.value()*runTime.deltaT().value();
|
|
||||||
|
|
||||||
meanCoNum = (sum(SfUfbyDelta)/sum(mesh.magSf()))
|
|
||||||
.value()*runTime.deltaT().value();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Info<< "Region: " << mesh.name() << " Courant Number mean: " << meanCoNum
|
|
||||||
<< " max: " << CoNum << endl;
|
|
||||||
|
|
||||||
return CoNum;
|
void Foam::MULES::implicitSolve
|
||||||
|
(
|
||||||
|
volScalarField& psi,
|
||||||
|
const surfaceScalarField& phi,
|
||||||
|
surfaceScalarField& phiPsi,
|
||||||
|
const scalar psiMax,
|
||||||
|
const scalar psiMin
|
||||||
|
)
|
||||||
|
{
|
||||||
|
implicitSolve
|
||||||
|
(
|
||||||
|
geometricOneField(),
|
||||||
|
psi,
|
||||||
|
phi,
|
||||||
|
phiPsi,
|
||||||
|
zeroField(), zeroField(),
|
||||||
|
psiMax, psiMin
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
136
applications/solvers/multiphase/interFoam/LTSInterFoam/MULES.H
Normal file
136
applications/solvers/multiphase/interFoam/LTSInterFoam/MULES.H
Normal file
@ -0,0 +1,136 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | Copyright (C) 1991-2010 OpenCFD Ltd.
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
License
|
||||||
|
This file is part of OpenFOAM.
|
||||||
|
|
||||||
|
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 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/>.
|
||||||
|
|
||||||
|
Global
|
||||||
|
MULES
|
||||||
|
|
||||||
|
Description
|
||||||
|
MULES: Multidimensional universal limiter with explicit solution.
|
||||||
|
|
||||||
|
Solve a convective-only transport equation using an explicit universal
|
||||||
|
multi-dimensional limiter.
|
||||||
|
|
||||||
|
Parameters are the variable to solve, the normal convective flux and the
|
||||||
|
actual explicit flux of the variable which is also used to return limited
|
||||||
|
flux used in the bounded-solution.
|
||||||
|
|
||||||
|
SourceFiles
|
||||||
|
MULES.C
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef MULES_H
|
||||||
|
#define MULES_H
|
||||||
|
|
||||||
|
#include "volFields.H"
|
||||||
|
#include "surfaceFieldsFwd.H"
|
||||||
|
#include "primitiveFieldsFwd.H"
|
||||||
|
#include "zeroField.H"
|
||||||
|
#include "geometricOneField.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace MULES
|
||||||
|
{
|
||||||
|
|
||||||
|
template<class RhoType, class SpType, class SuType>
|
||||||
|
void explicitLTSSolve
|
||||||
|
(
|
||||||
|
const RhoType& rho,
|
||||||
|
volScalarField& psi,
|
||||||
|
const surfaceScalarField& phiBD,
|
||||||
|
surfaceScalarField& phiPsi,
|
||||||
|
const SpType& Sp,
|
||||||
|
const SuType& Su,
|
||||||
|
const scalar psiMax,
|
||||||
|
const scalar psiMin
|
||||||
|
);
|
||||||
|
|
||||||
|
void explicitLTSSolve
|
||||||
|
(
|
||||||
|
volScalarField& psi,
|
||||||
|
const surfaceScalarField& phiBD,
|
||||||
|
surfaceScalarField& phiPsi,
|
||||||
|
const scalar psiMax,
|
||||||
|
const scalar psiMin
|
||||||
|
);
|
||||||
|
|
||||||
|
template<class RhoType, class SpType, class SuType>
|
||||||
|
void implicitSolve
|
||||||
|
(
|
||||||
|
const RhoType& rho,
|
||||||
|
volScalarField& gamma,
|
||||||
|
const surfaceScalarField& phi,
|
||||||
|
surfaceScalarField& phiCorr,
|
||||||
|
const SpType& Sp,
|
||||||
|
const SuType& Su,
|
||||||
|
const scalar psiMax,
|
||||||
|
const scalar psiMin
|
||||||
|
);
|
||||||
|
|
||||||
|
void implicitSolve
|
||||||
|
(
|
||||||
|
volScalarField& gamma,
|
||||||
|
const surfaceScalarField& phi,
|
||||||
|
surfaceScalarField& phiCorr,
|
||||||
|
const scalar psiMax,
|
||||||
|
const scalar psiMin
|
||||||
|
);
|
||||||
|
|
||||||
|
template<class RhoType, class SpType, class SuType>
|
||||||
|
void limiter
|
||||||
|
(
|
||||||
|
scalarField& allLambda,
|
||||||
|
const RhoType& rho,
|
||||||
|
const volScalarField& psi,
|
||||||
|
const surfaceScalarField& phiBD,
|
||||||
|
const surfaceScalarField& phiCorr,
|
||||||
|
const SpType& Sp,
|
||||||
|
const SuType& Su,
|
||||||
|
const scalar psiMax,
|
||||||
|
const scalar psiMin,
|
||||||
|
const label nLimiterIter
|
||||||
|
);
|
||||||
|
|
||||||
|
} // End namespace MULES
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
} // End namespace Foam
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
#ifdef NoRepository
|
||||||
|
# include "MULESTemplates.C"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -0,0 +1,602 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | Copyright (C) 1991-2010 OpenCFD Ltd.
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
License
|
||||||
|
This file is part of OpenFOAM.
|
||||||
|
|
||||||
|
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 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/>.
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#include "MULES.H"
|
||||||
|
#include "upwind.H"
|
||||||
|
#include "uncorrectedSnGrad.H"
|
||||||
|
#include "gaussConvectionScheme.H"
|
||||||
|
#include "gaussLaplacianScheme.H"
|
||||||
|
#include "uncorrectedSnGrad.H"
|
||||||
|
#include "surfaceInterpolate.H"
|
||||||
|
#include "fvcSurfaceIntegrate.H"
|
||||||
|
#include "slicedSurfaceFields.H"
|
||||||
|
#include "syncTools.H"
|
||||||
|
|
||||||
|
#include "fvCFD.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
template<class RhoType, class SpType, class SuType>
|
||||||
|
void Foam::MULES::explicitLTSSolve
|
||||||
|
(
|
||||||
|
const RhoType& rho,
|
||||||
|
volScalarField& psi,
|
||||||
|
const surfaceScalarField& phi,
|
||||||
|
surfaceScalarField& phiPsi,
|
||||||
|
const SpType& Sp,
|
||||||
|
const SuType& Su,
|
||||||
|
const scalar psiMax,
|
||||||
|
const scalar psiMin
|
||||||
|
)
|
||||||
|
{
|
||||||
|
Info<< "MULES: Solving for " << psi.name() << endl;
|
||||||
|
|
||||||
|
const fvMesh& mesh = psi.mesh();
|
||||||
|
psi.correctBoundaryConditions();
|
||||||
|
|
||||||
|
surfaceScalarField phiBD = upwind<scalar>(psi.mesh(), phi).flux(psi);
|
||||||
|
|
||||||
|
surfaceScalarField& phiCorr = phiPsi;
|
||||||
|
phiCorr -= phiBD;
|
||||||
|
|
||||||
|
scalarField allLambda(mesh.nFaces(), 1.0);
|
||||||
|
|
||||||
|
slicedSurfaceScalarField lambda
|
||||||
|
(
|
||||||
|
IOobject
|
||||||
|
(
|
||||||
|
"lambda",
|
||||||
|
mesh.time().timeName(),
|
||||||
|
mesh,
|
||||||
|
IOobject::NO_READ,
|
||||||
|
IOobject::NO_WRITE,
|
||||||
|
false
|
||||||
|
),
|
||||||
|
mesh,
|
||||||
|
dimless,
|
||||||
|
allLambda,
|
||||||
|
false // Use slices for the couples
|
||||||
|
);
|
||||||
|
|
||||||
|
limiter
|
||||||
|
(
|
||||||
|
allLambda,
|
||||||
|
rho,
|
||||||
|
psi,
|
||||||
|
phiBD,
|
||||||
|
phiCorr,
|
||||||
|
Sp.field(),
|
||||||
|
Su.field(),
|
||||||
|
psiMax,
|
||||||
|
psiMin,
|
||||||
|
3
|
||||||
|
);
|
||||||
|
|
||||||
|
phiPsi = phiBD + lambda*phiCorr;
|
||||||
|
|
||||||
|
scalarField& psiIf = psi;
|
||||||
|
const scalarField& psi0 = psi.oldTime();
|
||||||
|
|
||||||
|
const volScalarField& rDeltaT =
|
||||||
|
mesh.objectRegistry::lookupObject<volScalarField>("rSubDeltaT");
|
||||||
|
|
||||||
|
psiIf = 0.0;
|
||||||
|
fvc::surfaceIntegrate(psiIf, phiPsi);
|
||||||
|
|
||||||
|
if (mesh.moving())
|
||||||
|
{
|
||||||
|
psiIf =
|
||||||
|
(
|
||||||
|
mesh.Vsc0()*rho.oldTime()*psi0*rDeltaT/mesh.Vsc()
|
||||||
|
+ Su.field()
|
||||||
|
- psiIf
|
||||||
|
)/(rho*rDeltaT - Sp.field());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
psiIf =
|
||||||
|
(
|
||||||
|
rho.oldTime()*psi0*rDeltaT
|
||||||
|
+ Su.field()
|
||||||
|
- psiIf
|
||||||
|
)/(rho*rDeltaT - Sp.field());
|
||||||
|
}
|
||||||
|
|
||||||
|
psi.correctBoundaryConditions();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class RhoType, class SpType, class SuType>
|
||||||
|
void Foam::MULES::implicitSolve
|
||||||
|
(
|
||||||
|
const RhoType& rho,
|
||||||
|
volScalarField& psi,
|
||||||
|
const surfaceScalarField& phi,
|
||||||
|
surfaceScalarField& phiPsi,
|
||||||
|
const SpType& Sp,
|
||||||
|
const SuType& Su,
|
||||||
|
const scalar psiMax,
|
||||||
|
const scalar psiMin
|
||||||
|
)
|
||||||
|
{
|
||||||
|
const fvMesh& mesh = psi.mesh();
|
||||||
|
|
||||||
|
const dictionary& MULEScontrols = mesh.solverDict(psi.name());
|
||||||
|
|
||||||
|
label maxIter
|
||||||
|
(
|
||||||
|
readLabel(MULEScontrols.lookup("maxIter"))
|
||||||
|
);
|
||||||
|
|
||||||
|
label nLimiterIter
|
||||||
|
(
|
||||||
|
readLabel(MULEScontrols.lookup("nLimiterIter"))
|
||||||
|
);
|
||||||
|
|
||||||
|
scalar maxUnboundedness
|
||||||
|
(
|
||||||
|
readScalar(MULEScontrols.lookup("maxUnboundedness"))
|
||||||
|
);
|
||||||
|
|
||||||
|
scalar CoCoeff
|
||||||
|
(
|
||||||
|
readScalar(MULEScontrols.lookup("CoCoeff"))
|
||||||
|
);
|
||||||
|
|
||||||
|
scalarField allCoLambda(mesh.nFaces());
|
||||||
|
|
||||||
|
{
|
||||||
|
surfaceScalarField Cof =
|
||||||
|
mesh.time().deltaT()*mesh.surfaceInterpolation::deltaCoeffs()
|
||||||
|
*mag(phi)/mesh.magSf();
|
||||||
|
|
||||||
|
slicedSurfaceScalarField CoLambda
|
||||||
|
(
|
||||||
|
IOobject
|
||||||
|
(
|
||||||
|
"CoLambda",
|
||||||
|
mesh.time().timeName(),
|
||||||
|
mesh,
|
||||||
|
IOobject::NO_READ,
|
||||||
|
IOobject::NO_WRITE,
|
||||||
|
false
|
||||||
|
),
|
||||||
|
mesh,
|
||||||
|
dimless,
|
||||||
|
allCoLambda,
|
||||||
|
false // Use slices for the couples
|
||||||
|
);
|
||||||
|
|
||||||
|
CoLambda == 1.0/max(CoCoeff*Cof, scalar(1));
|
||||||
|
}
|
||||||
|
|
||||||
|
scalarField allLambda(allCoLambda);
|
||||||
|
//scalarField allLambda(mesh.nFaces(), 1.0);
|
||||||
|
|
||||||
|
slicedSurfaceScalarField lambda
|
||||||
|
(
|
||||||
|
IOobject
|
||||||
|
(
|
||||||
|
"lambda",
|
||||||
|
mesh.time().timeName(),
|
||||||
|
mesh,
|
||||||
|
IOobject::NO_READ,
|
||||||
|
IOobject::NO_WRITE,
|
||||||
|
false
|
||||||
|
),
|
||||||
|
mesh,
|
||||||
|
dimless,
|
||||||
|
allLambda,
|
||||||
|
false // Use slices for the couples
|
||||||
|
);
|
||||||
|
|
||||||
|
linear<scalar> CDs(mesh);
|
||||||
|
upwind<scalar> UDs(mesh, phi);
|
||||||
|
//fv::uncorrectedSnGrad<scalar> snGrads(mesh);
|
||||||
|
|
||||||
|
fvScalarMatrix psiConvectionDiffusion
|
||||||
|
(
|
||||||
|
fvm::ddt(rho, psi)
|
||||||
|
+ fv::gaussConvectionScheme<scalar>(mesh, phi, UDs).fvmDiv(phi, psi)
|
||||||
|
//- fv::gaussLaplacianScheme<scalar, scalar>(mesh, CDs, snGrads)
|
||||||
|
//.fvmLaplacian(Dpsif, psi)
|
||||||
|
- fvm::Sp(Sp, psi)
|
||||||
|
- Su
|
||||||
|
);
|
||||||
|
|
||||||
|
surfaceScalarField phiBD = psiConvectionDiffusion.flux();
|
||||||
|
|
||||||
|
surfaceScalarField& phiCorr = phiPsi;
|
||||||
|
phiCorr -= phiBD;
|
||||||
|
|
||||||
|
for (label i=0; i<maxIter; i++)
|
||||||
|
{
|
||||||
|
if (i != 0 && i < 4)
|
||||||
|
{
|
||||||
|
allLambda = allCoLambda;
|
||||||
|
}
|
||||||
|
|
||||||
|
limiter
|
||||||
|
(
|
||||||
|
allLambda,
|
||||||
|
rho,
|
||||||
|
psi,
|
||||||
|
phiBD,
|
||||||
|
phiCorr,
|
||||||
|
Sp.field(),
|
||||||
|
Su.field(),
|
||||||
|
psiMax,
|
||||||
|
psiMin,
|
||||||
|
nLimiterIter
|
||||||
|
);
|
||||||
|
|
||||||
|
solve
|
||||||
|
(
|
||||||
|
psiConvectionDiffusion + fvc::div(lambda*phiCorr),
|
||||||
|
MULEScontrols
|
||||||
|
);
|
||||||
|
|
||||||
|
scalar maxPsiM1 = gMax(psi.internalField()) - 1.0;
|
||||||
|
scalar minPsi = gMin(psi.internalField());
|
||||||
|
|
||||||
|
scalar unboundedness = max(max(maxPsiM1, 0.0), -min(minPsi, 0.0));
|
||||||
|
|
||||||
|
if (unboundedness < maxUnboundedness)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Info<< "MULES: max(" << psi.name() << " - 1) = " << maxPsiM1
|
||||||
|
<< " min(" << psi.name() << ") = " << minPsi << endl;
|
||||||
|
|
||||||
|
phiBD = psiConvectionDiffusion.flux();
|
||||||
|
|
||||||
|
/*
|
||||||
|
word gammaScheme("div(phi,gamma)");
|
||||||
|
word gammarScheme("div(phirb,gamma)");
|
||||||
|
|
||||||
|
const surfaceScalarField& phir =
|
||||||
|
mesh.lookupObject<surfaceScalarField>("phir");
|
||||||
|
|
||||||
|
phiCorr =
|
||||||
|
fvc::flux
|
||||||
|
(
|
||||||
|
phi,
|
||||||
|
psi,
|
||||||
|
gammaScheme
|
||||||
|
)
|
||||||
|
+ fvc::flux
|
||||||
|
(
|
||||||
|
-fvc::flux(-phir, scalar(1) - psi, gammarScheme),
|
||||||
|
psi,
|
||||||
|
gammarScheme
|
||||||
|
)
|
||||||
|
- phiBD;
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
phiPsi = psiConvectionDiffusion.flux() + lambda*phiCorr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class RhoType, class SpType, class SuType>
|
||||||
|
void Foam::MULES::limiter
|
||||||
|
(
|
||||||
|
scalarField& allLambda,
|
||||||
|
const RhoType& rho,
|
||||||
|
const volScalarField& psi,
|
||||||
|
const surfaceScalarField& phiBD,
|
||||||
|
const surfaceScalarField& phiCorr,
|
||||||
|
const SpType& Sp,
|
||||||
|
const SuType& Su,
|
||||||
|
const scalar psiMax,
|
||||||
|
const scalar psiMin,
|
||||||
|
const label nLimiterIter
|
||||||
|
)
|
||||||
|
{
|
||||||
|
const scalarField& psiIf = psi;
|
||||||
|
const volScalarField::GeometricBoundaryField& psiBf = psi.boundaryField();
|
||||||
|
|
||||||
|
const scalarField& psi0 = psi.oldTime();
|
||||||
|
|
||||||
|
const fvMesh& mesh = psi.mesh();
|
||||||
|
|
||||||
|
const unallocLabelList& owner = mesh.owner();
|
||||||
|
const unallocLabelList& neighb = mesh.neighbour();
|
||||||
|
tmp<volScalarField::DimensionedInternalField> tVsc = mesh.Vsc();
|
||||||
|
const scalarField& V = tVsc();
|
||||||
|
|
||||||
|
const volScalarField& rDeltaT =
|
||||||
|
mesh.objectRegistry::lookupObject<volScalarField>("rSubDeltaT");
|
||||||
|
|
||||||
|
const scalarField& phiBDIf = phiBD;
|
||||||
|
const surfaceScalarField::GeometricBoundaryField& phiBDBf =
|
||||||
|
phiBD.boundaryField();
|
||||||
|
|
||||||
|
const scalarField& phiCorrIf = phiCorr;
|
||||||
|
const surfaceScalarField::GeometricBoundaryField& phiCorrBf =
|
||||||
|
phiCorr.boundaryField();
|
||||||
|
|
||||||
|
slicedSurfaceScalarField lambda
|
||||||
|
(
|
||||||
|
IOobject
|
||||||
|
(
|
||||||
|
"lambda",
|
||||||
|
mesh.time().timeName(),
|
||||||
|
mesh,
|
||||||
|
IOobject::NO_READ,
|
||||||
|
IOobject::NO_WRITE,
|
||||||
|
false
|
||||||
|
),
|
||||||
|
mesh,
|
||||||
|
dimless,
|
||||||
|
allLambda,
|
||||||
|
false // Use slices for the couples
|
||||||
|
);
|
||||||
|
|
||||||
|
scalarField& lambdaIf = lambda;
|
||||||
|
surfaceScalarField::GeometricBoundaryField& lambdaBf =
|
||||||
|
lambda.boundaryField();
|
||||||
|
|
||||||
|
scalarField psiMaxn(psiIf.size(), psiMin);
|
||||||
|
scalarField psiMinn(psiIf.size(), psiMax);
|
||||||
|
|
||||||
|
scalarField sumPhiBD(psiIf.size(), 0.0);
|
||||||
|
|
||||||
|
scalarField sumPhip(psiIf.size(), VSMALL);
|
||||||
|
scalarField mSumPhim(psiIf.size(), VSMALL);
|
||||||
|
|
||||||
|
forAll(phiCorrIf, facei)
|
||||||
|
{
|
||||||
|
label own = owner[facei];
|
||||||
|
label nei = neighb[facei];
|
||||||
|
|
||||||
|
psiMaxn[own] = max(psiMaxn[own], psiIf[nei]);
|
||||||
|
psiMinn[own] = min(psiMinn[own], psiIf[nei]);
|
||||||
|
|
||||||
|
psiMaxn[nei] = max(psiMaxn[nei], psiIf[own]);
|
||||||
|
psiMinn[nei] = min(psiMinn[nei], psiIf[own]);
|
||||||
|
|
||||||
|
sumPhiBD[own] += phiBDIf[facei];
|
||||||
|
sumPhiBD[nei] -= phiBDIf[facei];
|
||||||
|
|
||||||
|
scalar phiCorrf = phiCorrIf[facei];
|
||||||
|
|
||||||
|
if (phiCorrf > 0.0)
|
||||||
|
{
|
||||||
|
sumPhip[own] += phiCorrf;
|
||||||
|
mSumPhim[nei] += phiCorrf;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mSumPhim[own] -= phiCorrf;
|
||||||
|
sumPhip[nei] -= phiCorrf;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
forAll(phiCorrBf, patchi)
|
||||||
|
{
|
||||||
|
const fvPatchScalarField& psiPf = psiBf[patchi];
|
||||||
|
const scalarField& phiBDPf = phiBDBf[patchi];
|
||||||
|
const scalarField& phiCorrPf = phiCorrBf[patchi];
|
||||||
|
|
||||||
|
const labelList& pFaceCells = mesh.boundary()[patchi].faceCells();
|
||||||
|
|
||||||
|
if (psiPf.coupled())
|
||||||
|
{
|
||||||
|
scalarField psiPNf = psiPf.patchNeighbourField();
|
||||||
|
|
||||||
|
forAll(phiCorrPf, pFacei)
|
||||||
|
{
|
||||||
|
label pfCelli = pFaceCells[pFacei];
|
||||||
|
|
||||||
|
psiMaxn[pfCelli] = max(psiMaxn[pfCelli], psiPNf[pFacei]);
|
||||||
|
psiMinn[pfCelli] = min(psiMinn[pfCelli], psiPNf[pFacei]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
forAll(phiCorrPf, pFacei)
|
||||||
|
{
|
||||||
|
label pfCelli = pFaceCells[pFacei];
|
||||||
|
|
||||||
|
psiMaxn[pfCelli] = max(psiMaxn[pfCelli], psiPf[pFacei]);
|
||||||
|
psiMinn[pfCelli] = min(psiMinn[pfCelli], psiPf[pFacei]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
forAll(phiCorrPf, pFacei)
|
||||||
|
{
|
||||||
|
label pfCelli = pFaceCells[pFacei];
|
||||||
|
|
||||||
|
sumPhiBD[pfCelli] += phiBDPf[pFacei];
|
||||||
|
|
||||||
|
scalar phiCorrf = phiCorrPf[pFacei];
|
||||||
|
|
||||||
|
if (phiCorrf > 0.0)
|
||||||
|
{
|
||||||
|
sumPhip[pfCelli] += phiCorrf;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mSumPhim[pfCelli] -= phiCorrf;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
psiMaxn = min(psiMaxn, psiMax);
|
||||||
|
psiMinn = max(psiMinn, psiMin);
|
||||||
|
|
||||||
|
//scalar smooth = 0.5;
|
||||||
|
//psiMaxn = min((1.0 - smooth)*psiIf + smooth*psiMaxn, psiMax);
|
||||||
|
//psiMinn = max((1.0 - smooth)*psiIf + smooth*psiMinn, psiMin);
|
||||||
|
|
||||||
|
if (mesh.moving())
|
||||||
|
{
|
||||||
|
tmp<volScalarField::DimensionedInternalField> V0 = mesh.Vsc0();
|
||||||
|
|
||||||
|
psiMaxn =
|
||||||
|
V*((rho*rDeltaT - Sp)*psiMaxn - Su)
|
||||||
|
- (V0()*rDeltaT)*rho.oldTime()*psi0
|
||||||
|
+ sumPhiBD;
|
||||||
|
|
||||||
|
psiMinn =
|
||||||
|
V*(Su - (rho*rDeltaT - Sp)*psiMinn)
|
||||||
|
+ (V0*rDeltaT)*rho.oldTime()*psi0
|
||||||
|
- sumPhiBD;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
psiMaxn =
|
||||||
|
V*((rho*rDeltaT - Sp)*psiMaxn - (rho.oldTime()*rDeltaT)*psi0 - Su)
|
||||||
|
+ sumPhiBD;
|
||||||
|
|
||||||
|
psiMinn =
|
||||||
|
V*((rho*rDeltaT)*psi0 - (rho.oldTime()*rDeltaT - Sp)*psiMinn + Su)
|
||||||
|
- sumPhiBD;
|
||||||
|
}
|
||||||
|
|
||||||
|
scalarField sumlPhip(psiIf.size());
|
||||||
|
scalarField mSumlPhim(psiIf.size());
|
||||||
|
|
||||||
|
for(int j=0; j<nLimiterIter; j++)
|
||||||
|
{
|
||||||
|
sumlPhip = 0.0;
|
||||||
|
mSumlPhim = 0.0;
|
||||||
|
|
||||||
|
forAll(lambdaIf, facei)
|
||||||
|
{
|
||||||
|
label own = owner[facei];
|
||||||
|
label nei = neighb[facei];
|
||||||
|
|
||||||
|
scalar lambdaPhiCorrf = lambdaIf[facei]*phiCorrIf[facei];
|
||||||
|
|
||||||
|
if (lambdaPhiCorrf > 0.0)
|
||||||
|
{
|
||||||
|
sumlPhip[own] += lambdaPhiCorrf;
|
||||||
|
mSumlPhim[nei] += lambdaPhiCorrf;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mSumlPhim[own] -= lambdaPhiCorrf;
|
||||||
|
sumlPhip[nei] -= lambdaPhiCorrf;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
forAll(lambdaBf, patchi)
|
||||||
|
{
|
||||||
|
scalarField& lambdaPf = lambdaBf[patchi];
|
||||||
|
const scalarField& phiCorrfPf = phiCorrBf[patchi];
|
||||||
|
|
||||||
|
const labelList& pFaceCells = mesh.boundary()[patchi].faceCells();
|
||||||
|
|
||||||
|
forAll(lambdaPf, pFacei)
|
||||||
|
{
|
||||||
|
label pfCelli = pFaceCells[pFacei];
|
||||||
|
|
||||||
|
scalar lambdaPhiCorrf = lambdaPf[pFacei]*phiCorrfPf[pFacei];
|
||||||
|
|
||||||
|
if (lambdaPhiCorrf > 0.0)
|
||||||
|
{
|
||||||
|
sumlPhip[pfCelli] += lambdaPhiCorrf;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mSumlPhim[pfCelli] -= lambdaPhiCorrf;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
forAll (sumlPhip, celli)
|
||||||
|
{
|
||||||
|
sumlPhip[celli] =
|
||||||
|
max(min
|
||||||
|
(
|
||||||
|
(sumlPhip[celli] + psiMaxn[celli])/mSumPhim[celli],
|
||||||
|
1.0), 0.0
|
||||||
|
);
|
||||||
|
|
||||||
|
mSumlPhim[celli] =
|
||||||
|
max(min
|
||||||
|
(
|
||||||
|
(mSumlPhim[celli] + psiMinn[celli])/sumPhip[celli],
|
||||||
|
1.0), 0.0
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const scalarField& lambdam = sumlPhip;
|
||||||
|
const scalarField& lambdap = mSumlPhim;
|
||||||
|
|
||||||
|
forAll(lambdaIf, facei)
|
||||||
|
{
|
||||||
|
if (phiCorrIf[facei] > 0.0)
|
||||||
|
{
|
||||||
|
lambdaIf[facei] = min
|
||||||
|
(
|
||||||
|
lambdaIf[facei],
|
||||||
|
min(lambdap[owner[facei]], lambdam[neighb[facei]])
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
lambdaIf[facei] = min
|
||||||
|
(
|
||||||
|
lambdaIf[facei],
|
||||||
|
min(lambdam[owner[facei]], lambdap[neighb[facei]])
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
forAll(lambdaBf, patchi)
|
||||||
|
{
|
||||||
|
fvsPatchScalarField& lambdaPf = lambdaBf[patchi];
|
||||||
|
const scalarField& phiCorrfPf = phiCorrBf[patchi];
|
||||||
|
|
||||||
|
const labelList& pFaceCells = mesh.boundary()[patchi].faceCells();
|
||||||
|
|
||||||
|
forAll(lambdaPf, pFacei)
|
||||||
|
{
|
||||||
|
label pfCelli = pFaceCells[pFacei];
|
||||||
|
|
||||||
|
if (phiCorrfPf[pFacei] > 0.0)
|
||||||
|
{
|
||||||
|
lambdaPf[pFacei] = min(lambdaPf[pFacei], lambdap[pfCelli]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
lambdaPf[pFacei] = min(lambdaPf[pFacei], lambdam[pfCelli]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
syncTools::syncFaceList(mesh, allLambda, minEqOp<scalar>());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -0,0 +1,4 @@
|
|||||||
|
LTSInterFoam.C
|
||||||
|
MULES.C
|
||||||
|
|
||||||
|
EXE = $(FOAM_APPBIN)/LTSInterFoam
|
||||||
@ -0,0 +1,15 @@
|
|||||||
|
EXE_INC = \
|
||||||
|
-I.. \
|
||||||
|
-I$(LIB_SRC)/transportModels \
|
||||||
|
-I$(LIB_SRC)/transportModels/incompressible/lnInclude \
|
||||||
|
-I$(LIB_SRC)/transportModels/interfaceProperties/lnInclude \
|
||||||
|
-I$(LIB_SRC)/turbulenceModels/incompressible/turbulenceModel \
|
||||||
|
-I$(LIB_SRC)/finiteVolume/lnInclude
|
||||||
|
|
||||||
|
EXE_LIBS = \
|
||||||
|
-ltwoPhaseInterfaceProperties \
|
||||||
|
-lincompressibleTransportModels \
|
||||||
|
-lincompressibleTurbulenceModel \
|
||||||
|
-lincompressibleRASModels \
|
||||||
|
-lincompressibleLESModels \
|
||||||
|
-lfiniteVolume
|
||||||
@ -0,0 +1,36 @@
|
|||||||
|
{
|
||||||
|
word alphaScheme("div(phi,alpha)");
|
||||||
|
word alpharScheme("div(phirb,alpha)");
|
||||||
|
|
||||||
|
surfaceScalarField phic = mag(phi/mesh.magSf());
|
||||||
|
phic = min(interface.cAlpha()*phic, max(phic));
|
||||||
|
surfaceScalarField phir = phic*interface.nHatf();
|
||||||
|
|
||||||
|
for (int aCorr=0; aCorr<nAlphaCorr; aCorr++)
|
||||||
|
{
|
||||||
|
surfaceScalarField phiAlpha =
|
||||||
|
fvc::flux
|
||||||
|
(
|
||||||
|
phi,
|
||||||
|
alpha1,
|
||||||
|
alphaScheme
|
||||||
|
)
|
||||||
|
+ fvc::flux
|
||||||
|
(
|
||||||
|
-fvc::flux(-phir, scalar(1) - alpha1, alpharScheme),
|
||||||
|
alpha1,
|
||||||
|
alpharScheme
|
||||||
|
);
|
||||||
|
|
||||||
|
MULES::explicitLTSSolve(alpha1, phi, phiAlpha, 1, 0);
|
||||||
|
//MULES::explicitSolve(alpha1, phi, phiAlpha, 1, 0);
|
||||||
|
|
||||||
|
rhoPhi = phiAlpha*(rho1 - rho2) + phi*rho2;
|
||||||
|
}
|
||||||
|
|
||||||
|
Info<< "Liquid phase volume fraction = "
|
||||||
|
<< alpha1.weightedAverage(mesh.V()).value()
|
||||||
|
<< " Min(alpha1) = " << min(alpha1).value()
|
||||||
|
<< " Max(alpha1) = " << max(alpha1).value()
|
||||||
|
<< endl;
|
||||||
|
}
|
||||||
@ -0,0 +1,35 @@
|
|||||||
|
label nAlphaCorr
|
||||||
|
(
|
||||||
|
readLabel(piso.lookup("nAlphaCorr"))
|
||||||
|
);
|
||||||
|
|
||||||
|
label nAlphaSubCycles
|
||||||
|
(
|
||||||
|
readLabel(piso.lookup("nAlphaSubCycles"))
|
||||||
|
);
|
||||||
|
|
||||||
|
if (nAlphaSubCycles > 1)
|
||||||
|
{
|
||||||
|
dimensionedScalar totalDeltaT = runTime.deltaT();
|
||||||
|
surfaceScalarField rhoPhiSum = 0.0*rhoPhi;
|
||||||
|
|
||||||
|
for
|
||||||
|
(
|
||||||
|
subCycle<volScalarField> alphaSubCycle(alpha1, nAlphaSubCycles);
|
||||||
|
!(++alphaSubCycle).end();
|
||||||
|
)
|
||||||
|
{
|
||||||
|
# include "alphaEqn.H"
|
||||||
|
rhoPhiSum += (runTime.deltaT()/totalDeltaT)*rhoPhi;
|
||||||
|
}
|
||||||
|
|
||||||
|
rhoPhi = rhoPhiSum;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
# include "alphaEqn.H"
|
||||||
|
}
|
||||||
|
|
||||||
|
interface.correct();
|
||||||
|
|
||||||
|
rho == alpha1*rho1 + (scalar(1) - alpha1)*rho2;
|
||||||
@ -0,0 +1,31 @@
|
|||||||
|
scalar maxDeltaT
|
||||||
|
(
|
||||||
|
piso.lookupOrDefault<scalar>("maxDeltaT", GREAT)
|
||||||
|
);
|
||||||
|
|
||||||
|
volScalarField rDeltaT
|
||||||
|
(
|
||||||
|
IOobject
|
||||||
|
(
|
||||||
|
"rDeltaT",
|
||||||
|
runTime.timeName(),
|
||||||
|
mesh,
|
||||||
|
IOobject::NO_READ,
|
||||||
|
IOobject::AUTO_WRITE
|
||||||
|
),
|
||||||
|
mesh,
|
||||||
|
1/dimensionedScalar("maxDeltaT", dimTime, maxDeltaT),
|
||||||
|
zeroGradientFvPatchScalarField::typeName
|
||||||
|
);
|
||||||
|
|
||||||
|
volScalarField rSubDeltaT
|
||||||
|
(
|
||||||
|
IOobject
|
||||||
|
(
|
||||||
|
"rSubDeltaT",
|
||||||
|
runTime.timeName(),
|
||||||
|
mesh
|
||||||
|
),
|
||||||
|
mesh,
|
||||||
|
1/dimensionedScalar("maxDeltaT", dimTime, maxDeltaT)
|
||||||
|
);
|
||||||
@ -0,0 +1,133 @@
|
|||||||
|
{
|
||||||
|
scalar maxCo
|
||||||
|
(
|
||||||
|
piso.lookupOrDefault<scalar>("maxCo", 0.9)
|
||||||
|
);
|
||||||
|
|
||||||
|
scalar maxAlphaCo
|
||||||
|
(
|
||||||
|
piso.lookupOrDefault<scalar>("maxAlphaCo", 0.2)
|
||||||
|
);
|
||||||
|
|
||||||
|
scalar rDeltaTSmoothingCoeff
|
||||||
|
(
|
||||||
|
piso.lookupOrDefault<scalar>("rDeltaTSmoothingCoeff", 0.1)
|
||||||
|
);
|
||||||
|
|
||||||
|
label nAlphaSpreadIter
|
||||||
|
(
|
||||||
|
piso.lookupOrDefault<label>("nAlphaSpreadIter", 1)
|
||||||
|
);
|
||||||
|
|
||||||
|
scalar alphaSpreadDiff
|
||||||
|
(
|
||||||
|
piso.lookupOrDefault<label>("alphaSpreadDiff", 0.2)
|
||||||
|
);
|
||||||
|
|
||||||
|
scalar alphaSpreadMax
|
||||||
|
(
|
||||||
|
piso.lookupOrDefault<label>("alphaSpreadMax", 0.99)
|
||||||
|
);
|
||||||
|
|
||||||
|
scalar alphaSpreadMin
|
||||||
|
(
|
||||||
|
piso.lookupOrDefault<label>("alphaSpreadMin", 0.01)
|
||||||
|
);
|
||||||
|
|
||||||
|
label nAlphaSweepIter
|
||||||
|
(
|
||||||
|
piso.lookupOrDefault<label>("nAlphaSweepIter", 5)
|
||||||
|
);
|
||||||
|
|
||||||
|
scalar rDeltaTDampingCoeff
|
||||||
|
(
|
||||||
|
piso.lookupOrDefault<scalar>("rDeltaTDampingCoeff", 1.0)
|
||||||
|
);
|
||||||
|
|
||||||
|
scalar maxDeltaT
|
||||||
|
(
|
||||||
|
piso.lookupOrDefault<scalar>("maxDeltaT", GREAT)
|
||||||
|
);
|
||||||
|
|
||||||
|
volScalarField rDeltaT0 = rDeltaT;
|
||||||
|
|
||||||
|
// Set the reciprocal time-step from the local Courant number
|
||||||
|
rDeltaT.dimensionedInternalField() = max
|
||||||
|
(
|
||||||
|
1/dimensionedScalar("maxDeltaT", dimTime, maxDeltaT),
|
||||||
|
fvc::surfaceSum(mag(rhoPhi))().dimensionedInternalField()
|
||||||
|
/((2*maxCo)*mesh.V()*rho.dimensionedInternalField())
|
||||||
|
);
|
||||||
|
|
||||||
|
if (maxAlphaCo < maxCo)
|
||||||
|
{
|
||||||
|
// Further limit the reciprocal time-step
|
||||||
|
// in the vicinity of the interface
|
||||||
|
rDeltaT.dimensionedInternalField() = max
|
||||||
|
(
|
||||||
|
rDeltaT.dimensionedInternalField(),
|
||||||
|
pos(alpha1.dimensionedInternalField() - 0.01)
|
||||||
|
*pos(0.99 - alpha1.dimensionedInternalField())
|
||||||
|
*fvc::surfaceSum(mag(phi))().dimensionedInternalField()
|
||||||
|
/((2*maxAlphaCo)*mesh.V())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update tho boundary values of the reciprocal time-step
|
||||||
|
rDeltaT.correctBoundaryConditions();
|
||||||
|
|
||||||
|
Info<< "Flow time scale min/max = "
|
||||||
|
<< gMin(1/rDeltaT.internalField())
|
||||||
|
<< ", " << gMax(1/rDeltaT.internalField()) << endl;
|
||||||
|
|
||||||
|
if (rDeltaTSmoothingCoeff < 1.0)
|
||||||
|
{
|
||||||
|
fvc::smooth(rDeltaT, rDeltaTSmoothingCoeff);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nAlphaSpreadIter > 0)
|
||||||
|
{
|
||||||
|
fvc::spread
|
||||||
|
(
|
||||||
|
rDeltaT,
|
||||||
|
alpha1,
|
||||||
|
nAlphaSpreadIter,
|
||||||
|
alphaSpreadDiff,
|
||||||
|
alphaSpreadMax,
|
||||||
|
alphaSpreadMin
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nAlphaSweepIter > 0)
|
||||||
|
{
|
||||||
|
fvc::sweep(rDeltaT, alpha1, nAlphaSweepIter, alphaSpreadDiff);
|
||||||
|
}
|
||||||
|
|
||||||
|
Info<< "Flow time scale min/max = "
|
||||||
|
<< gMin(1/rDeltaT.internalField())
|
||||||
|
<< ", " << gMax(1/rDeltaT.internalField()) << endl;
|
||||||
|
|
||||||
|
// Limit rate of change of time scale
|
||||||
|
// - reduce as much as required
|
||||||
|
// - only increase at a fraction of old time scale
|
||||||
|
if
|
||||||
|
(
|
||||||
|
rDeltaTDampingCoeff < 1.0
|
||||||
|
&& runTime.timeIndex() > runTime.startTimeIndex() + 1
|
||||||
|
)
|
||||||
|
{
|
||||||
|
Info<< "Damping rDeltaT" << endl;
|
||||||
|
rDeltaT = rDeltaT0*max(rDeltaT/rDeltaT0, 1.0 - rDeltaTDampingCoeff);
|
||||||
|
}
|
||||||
|
|
||||||
|
Info<< "Flow time scale min/max = "
|
||||||
|
<< gMin(1/rDeltaT.internalField())
|
||||||
|
<< ", " << gMax(1/rDeltaT.internalField()) << endl;
|
||||||
|
|
||||||
|
label nAlphaSubCycles
|
||||||
|
(
|
||||||
|
readLabel(piso.lookup("nAlphaSubCycles"))
|
||||||
|
);
|
||||||
|
|
||||||
|
rSubDeltaT = rDeltaT*nAlphaSubCycles;
|
||||||
|
}
|
||||||
@ -5,7 +5,7 @@ EXE_INC = \
|
|||||||
-I$(LIB_SRC)/transportModels/interfaceProperties/lnInclude \
|
-I$(LIB_SRC)/transportModels/interfaceProperties/lnInclude \
|
||||||
-I$(LIB_SRC)/finiteVolume/lnInclude
|
-I$(LIB_SRC)/finiteVolume/lnInclude
|
||||||
|
|
||||||
EXE_LIBS = \
|
LIB_LIBS = \
|
||||||
-linterfaceProperties \
|
-linterfaceProperties \
|
||||||
-lincompressibleTransportModels \
|
-lincompressibleTransportModels \
|
||||||
-lfiniteVolume
|
-lfiniteVolume
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
========= |
|
========= |
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
\\ / O peration |
|
\\ / O peration |
|
||||||
\\ / A nd | Copyright (C) 1991-2010 OpenCFD Ltd.
|
\\ / A nd | Copyright (C) 2009-2010 OpenCFD Ltd.
|
||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
@ -25,9 +25,9 @@ Description
|
|||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#include "point.H"
|
||||||
#include "DynamicField.H"
|
#include "DynamicField.H"
|
||||||
#include "IOstreams.H"
|
#include "IOstreams.H"
|
||||||
#include "labelField.H"
|
|
||||||
|
|
||||||
using namespace Foam;
|
using namespace Foam;
|
||||||
|
|
||||||
@ -36,44 +36,62 @@ using namespace Foam;
|
|||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
{
|
DynamicField<point, 0, 10, 11> testField;
|
||||||
DynamicField<label> dl(10);
|
DynamicField<point, 0, 10, 11> testField2;
|
||||||
Pout<< "null construct dl:" << dl << endl;
|
|
||||||
dl.append(3);
|
|
||||||
dl.append(2);
|
|
||||||
dl.append(1);
|
|
||||||
Pout<< "appending : dl:" << dl << endl;
|
|
||||||
|
|
||||||
dl[2] *= 10;
|
testField.setSize(5);
|
||||||
Pout<< "assigning : dl:" << dl << endl;
|
testField2.setSize(5);
|
||||||
}
|
|
||||||
|
|
||||||
{
|
testField[0] = testField2[0] = vector(1.0, 4.5, 6.3);
|
||||||
DynamicField<label> dl(IStringStream("(1 2 3)")());
|
testField[1] = testField2[1] = vector(5.2, 2.3, 3.5);
|
||||||
Pout<< "reading : dl:" << dl << endl;
|
testField[2] = testField2[2] = vector(7.5, 4.7, 7.7);
|
||||||
}
|
testField[3] = testField2[3] = vector(2.8, 8.2, 2.3);
|
||||||
|
testField[4] = testField2[4] = vector(6.1, 1.7, 8.8);
|
||||||
|
|
||||||
{
|
Info << "testField:" << testField << endl;
|
||||||
labelField lf(3);
|
|
||||||
lf[0] = 1;
|
|
||||||
lf[1] = 2;
|
|
||||||
lf[2] = 3;
|
|
||||||
DynamicField<label> dl;
|
|
||||||
dl = lf;
|
|
||||||
Pout<< "assigning from labelField : dl:" << dl << endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
testField.append(vector(0.5, 4.8, 6.2));
|
||||||
labelField lf(3);
|
|
||||||
lf[0] = 1;
|
|
||||||
lf[1] = 2;
|
|
||||||
lf[2] = 3;
|
|
||||||
DynamicField<label> dl(lf);
|
|
||||||
Pout<< "constructing from labelField dl:" << dl << endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
Info << "testField after appending:" << testField << endl;
|
||||||
|
|
||||||
Info<< "\nEnd\n";
|
testField.append(vector(2.7, 2.3, 6.1));
|
||||||
|
|
||||||
|
Info << "testField after appending:" << testField << endl;
|
||||||
|
|
||||||
|
vector elem = testField.remove();
|
||||||
|
|
||||||
|
Info << "removed element:" << elem << endl;
|
||||||
|
Info << "testField:" << testField << endl;
|
||||||
|
|
||||||
|
testField.append(vector(3.0, 1.3, 9.2));
|
||||||
|
|
||||||
|
Info << "testField:" << testField << endl;
|
||||||
|
|
||||||
|
testField.setSize(10, vector(1.5, 0.6, -1.0));
|
||||||
|
|
||||||
|
Info << "testField after setSize:" << testField << endl;
|
||||||
|
|
||||||
|
testField.append(testField2);
|
||||||
|
|
||||||
|
Info << "testField after appending testField2:" << testField << endl;
|
||||||
|
|
||||||
|
testField = testField2;
|
||||||
|
|
||||||
|
Info << "testField after assignment:" << testField << endl;
|
||||||
|
|
||||||
|
testField += testField2;
|
||||||
|
|
||||||
|
Info << "testField after field algebra:" << testField << endl;
|
||||||
|
|
||||||
|
testField.clear();
|
||||||
|
|
||||||
|
testField.append(vector(3.0, 1.3, 9.2));
|
||||||
|
|
||||||
|
Info << "testField after clear and append:" << testField << endl;
|
||||||
|
|
||||||
|
testField.clearStorage();
|
||||||
|
|
||||||
|
Info << "testField after clearStorage:" << testField << endl;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -934,6 +934,8 @@ int main(int argc, char *argv[])
|
|||||||
{
|
{
|
||||||
char* linePtr = readline("readline>");
|
char* linePtr = readline("readline>");
|
||||||
|
|
||||||
|
if (linePtr)
|
||||||
|
{
|
||||||
rawLine = string(linePtr);
|
rawLine = string(linePtr);
|
||||||
|
|
||||||
if (*linePtr)
|
if (*linePtr)
|
||||||
@ -944,8 +946,19 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
free(linePtr); // readline uses malloc, not new.
|
free(linePtr); // readline uses malloc, not new.
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
# else
|
# else
|
||||||
{
|
{
|
||||||
|
if (!std::cin.good())
|
||||||
|
{
|
||||||
|
Info<< "End of cin" << endl;
|
||||||
|
// No error.
|
||||||
|
break;
|
||||||
|
}
|
||||||
Info<< "Command>" << flush;
|
Info<< "Command>" << flush;
|
||||||
std::getline(std::cin, rawLine);
|
std::getline(std::cin, rawLine);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -34,8 +34,12 @@ Description
|
|||||||
- any face inbetween differing cellZones (-cellZones)
|
- any face inbetween differing cellZones (-cellZones)
|
||||||
|
|
||||||
Output is:
|
Output is:
|
||||||
- volScalarField with regions as different scalars (-detectOnly) or
|
- volScalarField with regions as different scalars (-detectOnly)
|
||||||
- mesh with multiple regions or
|
or
|
||||||
|
- mesh with multiple regions and directMapped patches. These patches
|
||||||
|
either cover the whole interface between two region (default) or
|
||||||
|
only part according to faceZones (-useFaceZones)
|
||||||
|
or
|
||||||
- mesh with cells put into cellZones (-makeCellZones)
|
- mesh with cells put into cellZones (-makeCellZones)
|
||||||
|
|
||||||
Note:
|
Note:
|
||||||
@ -495,18 +499,70 @@ labelList getNonRegionCells(const labelList& cellRegion, const label regionI)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Get per region-region interface the sizes. If sumParallel sums sizes.
|
void addToInterface
|
||||||
|
(
|
||||||
|
const polyMesh& mesh,
|
||||||
|
const label zoneID,
|
||||||
|
const label ownRegion,
|
||||||
|
const label neiRegion,
|
||||||
|
EdgeMap<Map<label> >& regionsToSize
|
||||||
|
)
|
||||||
|
{
|
||||||
|
edge interface
|
||||||
|
(
|
||||||
|
min(ownRegion, neiRegion),
|
||||||
|
max(ownRegion, neiRegion)
|
||||||
|
);
|
||||||
|
|
||||||
|
EdgeMap<Map<label> >::iterator iter = regionsToSize.find
|
||||||
|
(
|
||||||
|
interface
|
||||||
|
);
|
||||||
|
|
||||||
|
if (iter != regionsToSize.end())
|
||||||
|
{
|
||||||
|
// Check if zone present
|
||||||
|
Map<label>::iterator zoneFnd = iter().find(zoneID);
|
||||||
|
if (zoneFnd != iter().end())
|
||||||
|
{
|
||||||
|
// Found zone. Increment count.
|
||||||
|
zoneFnd()++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// New or no zone. Insert with count 1.
|
||||||
|
iter().insert(zoneID, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Create new interface of size 1.
|
||||||
|
Map<label> zoneToSize;
|
||||||
|
zoneToSize.insert(zoneID, 1);
|
||||||
|
regionsToSize.insert(interface, zoneToSize);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Get region-region interface name and sizes.
|
||||||
// Returns interfaces as straight list for looping in identical order.
|
// Returns interfaces as straight list for looping in identical order.
|
||||||
void getInterfaceSizes
|
void getInterfaceSizes
|
||||||
(
|
(
|
||||||
const polyMesh& mesh,
|
const polyMesh& mesh,
|
||||||
|
const bool useFaceZones,
|
||||||
const labelList& cellRegion,
|
const labelList& cellRegion,
|
||||||
const bool sumParallel,
|
const wordList& regionNames,
|
||||||
|
|
||||||
edgeList& interfaces,
|
edgeList& interfaces,
|
||||||
EdgeMap<label>& interfaceSizes
|
List<Pair<word> >& interfaceNames,
|
||||||
|
labelList& interfaceSizes,
|
||||||
|
labelList& faceToInterface
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
// From region-region to faceZone (or -1) to number of faces.
|
||||||
|
|
||||||
|
EdgeMap<Map<label> > regionsToSize;
|
||||||
|
|
||||||
|
|
||||||
// Internal faces
|
// Internal faces
|
||||||
// ~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~
|
||||||
@ -518,22 +574,14 @@ void getInterfaceSizes
|
|||||||
|
|
||||||
if (ownRegion != neiRegion)
|
if (ownRegion != neiRegion)
|
||||||
{
|
{
|
||||||
edge interface
|
addToInterface
|
||||||
(
|
(
|
||||||
min(ownRegion, neiRegion),
|
mesh,
|
||||||
max(ownRegion, neiRegion)
|
(useFaceZones ? mesh.faceZones().whichZone(faceI) : -1),
|
||||||
|
ownRegion,
|
||||||
|
neiRegion,
|
||||||
|
regionsToSize
|
||||||
);
|
);
|
||||||
|
|
||||||
EdgeMap<label>::iterator iter = interfaceSizes.find(interface);
|
|
||||||
|
|
||||||
if (iter != interfaceSizes.end())
|
|
||||||
{
|
|
||||||
iter()++;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
interfaceSizes.insert(interface, 1);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -558,27 +606,19 @@ void getInterfaceSizes
|
|||||||
|
|
||||||
if (ownRegion != neiRegion)
|
if (ownRegion != neiRegion)
|
||||||
{
|
{
|
||||||
edge interface
|
addToInterface
|
||||||
(
|
(
|
||||||
min(ownRegion, neiRegion),
|
mesh,
|
||||||
max(ownRegion, neiRegion)
|
(useFaceZones ? mesh.faceZones().whichZone(faceI) : -1),
|
||||||
|
ownRegion,
|
||||||
|
neiRegion,
|
||||||
|
regionsToSize
|
||||||
);
|
);
|
||||||
|
|
||||||
EdgeMap<label>::iterator iter = interfaceSizes.find(interface);
|
|
||||||
|
|
||||||
if (iter != interfaceSizes.end())
|
|
||||||
{
|
|
||||||
iter()++;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
interfaceSizes.insert(interface, 1);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (sumParallel && Pstream::parRun())
|
if (Pstream::parRun())
|
||||||
{
|
{
|
||||||
if (Pstream::master())
|
if (Pstream::master())
|
||||||
{
|
{
|
||||||
@ -592,35 +632,43 @@ void getInterfaceSizes
|
|||||||
{
|
{
|
||||||
IPstream fromSlave(Pstream::blocking, slave);
|
IPstream fromSlave(Pstream::blocking, slave);
|
||||||
|
|
||||||
EdgeMap<label> slaveSizes(fromSlave);
|
EdgeMap<Map<label> > slaveSizes(fromSlave);
|
||||||
|
|
||||||
forAllConstIter(EdgeMap<label>, slaveSizes, slaveIter)
|
forAllConstIter(EdgeMap<Map<label> >, slaveSizes, slaveIter)
|
||||||
{
|
{
|
||||||
EdgeMap<label>::iterator masterIter =
|
EdgeMap<Map<label> >::iterator masterIter =
|
||||||
interfaceSizes.find(slaveIter.key());
|
regionsToSize.find(slaveIter.key());
|
||||||
|
|
||||||
if (masterIter != interfaceSizes.end())
|
if (masterIter != regionsToSize.end())
|
||||||
{
|
{
|
||||||
masterIter() += slaveIter();
|
// Same inter-region
|
||||||
|
const Map<label>& slaveInfo = slaveIter();
|
||||||
|
Map<label>& masterInfo = masterIter();
|
||||||
|
|
||||||
|
forAllConstIter(Map<label>, slaveInfo, iter)
|
||||||
|
{
|
||||||
|
label zoneID = iter.key();
|
||||||
|
label slaveSize = iter();
|
||||||
|
|
||||||
|
Map<label>::iterator zoneFnd = masterInfo.find
|
||||||
|
(
|
||||||
|
zoneID
|
||||||
|
);
|
||||||
|
if (zoneFnd != masterInfo.end())
|
||||||
|
{
|
||||||
|
zoneFnd() += slaveSize;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
interfaceSizes.insert(slaveIter.key(), slaveIter());
|
masterInfo.insert(zoneID, slaveSize);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
// Distribute
|
|
||||||
for
|
|
||||||
(
|
|
||||||
int slave=Pstream::firstSlave();
|
|
||||||
slave<=Pstream::lastSlave();
|
|
||||||
slave++
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
// Receive the edges using shared points from the slave.
|
regionsToSize.insert(slaveIter.key(), slaveIter());
|
||||||
OPstream toSlave(Pstream::blocking, slave);
|
}
|
||||||
toSlave << interfaceSizes;
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -628,21 +676,125 @@ void getInterfaceSizes
|
|||||||
// Send to master
|
// Send to master
|
||||||
{
|
{
|
||||||
OPstream toMaster(Pstream::blocking, Pstream::masterNo());
|
OPstream toMaster(Pstream::blocking, Pstream::masterNo());
|
||||||
toMaster << interfaceSizes;
|
toMaster << regionsToSize;
|
||||||
}
|
|
||||||
// Receive from master
|
|
||||||
{
|
|
||||||
IPstream fromMaster(Pstream::blocking, Pstream::masterNo());
|
|
||||||
fromMaster >> interfaceSizes;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make sure all processors have interfaces in same order
|
// Rework
|
||||||
interfaces = interfaceSizes.toc();
|
|
||||||
if (sumParallel)
|
Pstream::scatter(regionsToSize);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Now we have the global sizes of all inter-regions.
|
||||||
|
// Invert this on master and distribute.
|
||||||
|
label nInterfaces = 0;
|
||||||
|
forAllConstIter(EdgeMap<Map<label> >, regionsToSize, iter)
|
||||||
{
|
{
|
||||||
|
const Map<label>& info = iter();
|
||||||
|
nInterfaces += info.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
interfaces.setSize(nInterfaces);
|
||||||
|
interfaceNames.setSize(nInterfaces);
|
||||||
|
interfaceSizes.setSize(nInterfaces);
|
||||||
|
EdgeMap<Map<label> > regionsToInterface(nInterfaces);
|
||||||
|
|
||||||
|
nInterfaces = 0;
|
||||||
|
forAllConstIter(EdgeMap<Map<label> >, regionsToSize, iter)
|
||||||
|
{
|
||||||
|
const edge& e = iter.key();
|
||||||
|
const word& name0 = regionNames[e[0]];
|
||||||
|
const word& name1 = regionNames[e[1]];
|
||||||
|
|
||||||
|
const Map<label>& info = iter();
|
||||||
|
forAllConstIter(Map<label>, info, infoIter)
|
||||||
|
{
|
||||||
|
interfaces[nInterfaces] = iter.key();
|
||||||
|
label zoneID = infoIter.key();
|
||||||
|
if (zoneID == -1)
|
||||||
|
{
|
||||||
|
interfaceNames[nInterfaces] = Pair<word>
|
||||||
|
(
|
||||||
|
name0 + "_to_" + name1,
|
||||||
|
name1 + "_to_" + name0
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
const word& zoneName = mesh.faceZones()[zoneID].name();
|
||||||
|
interfaceNames[nInterfaces] = Pair<word>
|
||||||
|
(
|
||||||
|
zoneName + "_" + name0 + "_to_" + name1,
|
||||||
|
zoneName + "_" + name1 + "_to_" + name0
|
||||||
|
);
|
||||||
|
}
|
||||||
|
interfaceSizes[nInterfaces] = infoIter();
|
||||||
|
|
||||||
|
Map<label> zoneAndInterface;
|
||||||
|
zoneAndInterface.insert(zoneID, nInterfaces);
|
||||||
|
regionsToInterface.insert(e, zoneAndInterface);
|
||||||
|
|
||||||
|
nInterfaces++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Now all processor have consistent interface information
|
||||||
|
|
||||||
Pstream::scatter(interfaces);
|
Pstream::scatter(interfaces);
|
||||||
|
Pstream::scatter(interfaceNames);
|
||||||
|
Pstream::scatter(interfaceSizes);
|
||||||
|
Pstream::scatter(regionsToInterface);
|
||||||
|
|
||||||
|
// Mark all inter-region faces.
|
||||||
|
faceToInterface.setSize(mesh.nFaces(), -1);
|
||||||
|
|
||||||
|
forAll(mesh.faceNeighbour(), faceI)
|
||||||
|
{
|
||||||
|
label ownRegion = cellRegion[mesh.faceOwner()[faceI]];
|
||||||
|
label neiRegion = cellRegion[mesh.faceNeighbour()[faceI]];
|
||||||
|
|
||||||
|
if (ownRegion != neiRegion)
|
||||||
|
{
|
||||||
|
label zoneID = -1;
|
||||||
|
if (useFaceZones)
|
||||||
|
{
|
||||||
|
zoneID = mesh.faceZones().whichZone(faceI);
|
||||||
|
}
|
||||||
|
|
||||||
|
edge interface
|
||||||
|
(
|
||||||
|
min(ownRegion, neiRegion),
|
||||||
|
max(ownRegion, neiRegion)
|
||||||
|
);
|
||||||
|
|
||||||
|
faceToInterface[faceI] = regionsToInterface[interface][zoneID];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
forAll(coupledRegion, i)
|
||||||
|
{
|
||||||
|
label faceI = i+mesh.nInternalFaces();
|
||||||
|
label ownRegion = cellRegion[mesh.faceOwner()[faceI]];
|
||||||
|
label neiRegion = coupledRegion[i];
|
||||||
|
|
||||||
|
if (ownRegion != neiRegion)
|
||||||
|
{
|
||||||
|
label zoneID = -1;
|
||||||
|
if (useFaceZones)
|
||||||
|
{
|
||||||
|
zoneID = mesh.faceZones().whichZone(faceI);
|
||||||
|
}
|
||||||
|
|
||||||
|
edge interface
|
||||||
|
(
|
||||||
|
min(ownRegion, neiRegion),
|
||||||
|
max(ownRegion, neiRegion)
|
||||||
|
);
|
||||||
|
|
||||||
|
faceToInterface[faceI] = regionsToInterface[interface][zoneID];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -650,11 +802,15 @@ void getInterfaceSizes
|
|||||||
// Create mesh for region.
|
// Create mesh for region.
|
||||||
autoPtr<mapPolyMesh> createRegionMesh
|
autoPtr<mapPolyMesh> createRegionMesh
|
||||||
(
|
(
|
||||||
const labelList& cellRegion,
|
|
||||||
const EdgeMap<label>& interfaceToPatch,
|
|
||||||
const fvMesh& mesh,
|
const fvMesh& mesh,
|
||||||
|
// Region info
|
||||||
|
const labelList& cellRegion,
|
||||||
const label regionI,
|
const label regionI,
|
||||||
const word& regionName,
|
const word& regionName,
|
||||||
|
// Interface info
|
||||||
|
const labelList& interfacePatches,
|
||||||
|
const labelList& faceToInterface,
|
||||||
|
|
||||||
autoPtr<fvMesh>& newMesh
|
autoPtr<fvMesh>& newMesh
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
@ -739,6 +895,7 @@ autoPtr<mapPolyMesh> createRegionMesh
|
|||||||
forAll(exposedFaces, i)
|
forAll(exposedFaces, i)
|
||||||
{
|
{
|
||||||
label faceI = exposedFaces[i];
|
label faceI = exposedFaces[i];
|
||||||
|
label interfaceI = faceToInterface[faceI];
|
||||||
|
|
||||||
label ownRegion = cellRegion[mesh.faceOwner()[faceI]];
|
label ownRegion = cellRegion[mesh.faceOwner()[faceI]];
|
||||||
label neiRegion = -1;
|
label neiRegion = -1;
|
||||||
@ -752,6 +909,10 @@ autoPtr<mapPolyMesh> createRegionMesh
|
|||||||
neiRegion = coupledRegion[faceI-mesh.nInternalFaces()];
|
neiRegion = coupledRegion[faceI-mesh.nInternalFaces()];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Check which side is being kept - determines which of the two
|
||||||
|
// patches will be used.
|
||||||
|
|
||||||
label otherRegion = -1;
|
label otherRegion = -1;
|
||||||
|
|
||||||
if (ownRegion == regionI && neiRegion != regionI)
|
if (ownRegion == regionI && neiRegion != regionI)
|
||||||
@ -773,19 +934,14 @@ autoPtr<mapPolyMesh> createRegionMesh
|
|||||||
<< exit(FatalError);
|
<< exit(FatalError);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (otherRegion != -1)
|
|
||||||
{
|
|
||||||
edge interface(regionI, otherRegion);
|
|
||||||
|
|
||||||
// Find the patch.
|
// Find the patch.
|
||||||
if (regionI < otherRegion)
|
if (regionI < otherRegion)
|
||||||
{
|
{
|
||||||
exposedPatchIDs[i] = interfaceToPatch[interface];
|
exposedPatchIDs[i] = interfacePatches[interfaceI];
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
exposedPatchIDs[i] = interfaceToPatch[interface]+1;
|
exposedPatchIDs[i] = interfacePatches[interfaceI]+1;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -821,7 +977,8 @@ void createAndWriteRegion
|
|||||||
const fvMesh& mesh,
|
const fvMesh& mesh,
|
||||||
const labelList& cellRegion,
|
const labelList& cellRegion,
|
||||||
const wordList& regionNames,
|
const wordList& regionNames,
|
||||||
const EdgeMap<label>& interfaceToPatch,
|
const labelList& faceToInterface,
|
||||||
|
const labelList& interfacePatches,
|
||||||
const label regionI,
|
const label regionI,
|
||||||
const word& newMeshInstance
|
const word& newMeshInstance
|
||||||
)
|
)
|
||||||
@ -832,21 +989,22 @@ void createAndWriteRegion
|
|||||||
autoPtr<fvMesh> newMesh;
|
autoPtr<fvMesh> newMesh;
|
||||||
autoPtr<mapPolyMesh> map = createRegionMesh
|
autoPtr<mapPolyMesh> map = createRegionMesh
|
||||||
(
|
(
|
||||||
cellRegion,
|
|
||||||
interfaceToPatch,
|
|
||||||
mesh,
|
mesh,
|
||||||
|
cellRegion,
|
||||||
regionI,
|
regionI,
|
||||||
regionNames[regionI],
|
regionNames[regionI],
|
||||||
|
interfacePatches,
|
||||||
|
faceToInterface,
|
||||||
newMesh
|
newMesh
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
// Make map of all added patches
|
// Make map of all added patches
|
||||||
labelHashSet addedPatches(2*interfaceToPatch.size());
|
labelHashSet addedPatches(2*interfacePatches.size());
|
||||||
forAllConstIter(EdgeMap<label>, interfaceToPatch, iter)
|
forAll(interfacePatches, interfaceI)
|
||||||
{
|
{
|
||||||
addedPatches.insert(iter());
|
addedPatches.insert(interfacePatches[interfaceI]);
|
||||||
addedPatches.insert(iter()+1);
|
addedPatches.insert(interfacePatches[interfaceI]+1);
|
||||||
}
|
}
|
||||||
|
|
||||||
Info<< "Mapping fields" << endl;
|
Info<< "Mapping fields" << endl;
|
||||||
@ -1074,70 +1232,67 @@ void createAndWriteRegion
|
|||||||
// First one is for minimumregion to maximumregion.
|
// First one is for minimumregion to maximumregion.
|
||||||
// Note that patches get created in same order on all processors (if parallel)
|
// Note that patches get created in same order on all processors (if parallel)
|
||||||
// since looping over synchronised 'interfaces'.
|
// since looping over synchronised 'interfaces'.
|
||||||
EdgeMap<label> addRegionPatches
|
labelList addRegionPatches
|
||||||
(
|
(
|
||||||
fvMesh& mesh,
|
fvMesh& mesh,
|
||||||
const labelList& cellRegion,
|
const wordList& regionNames,
|
||||||
const label nCellRegions,
|
|
||||||
const edgeList& interfaces,
|
const edgeList& interfaces,
|
||||||
const EdgeMap<label>& interfaceSizes,
|
const List<Pair<word> >& interfaceNames
|
||||||
const wordList& regionNames
|
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
// Check that all patches are present in same order.
|
|
||||||
mesh.boundaryMesh().checkParallelSync(true);
|
|
||||||
|
|
||||||
Info<< nl << "Adding patches" << nl << endl;
|
Info<< nl << "Adding patches" << nl << endl;
|
||||||
|
|
||||||
EdgeMap<label> interfaceToPatch(nCellRegions);
|
labelList interfacePatches(interfaces.size());
|
||||||
|
|
||||||
forAll(interfaces, interI)
|
forAll(interfaces, interI)
|
||||||
{
|
{
|
||||||
const edge& e = interfaces[interI];
|
const edge& e = interfaces[interI];
|
||||||
|
const Pair<word>& names = interfaceNames[interI];
|
||||||
|
|
||||||
|
//Info<< "For interface " << interI
|
||||||
|
// << " between regions " << e
|
||||||
|
// << " trying to add patches " << names << endl;
|
||||||
|
|
||||||
if (interfaceSizes[e] > 0)
|
|
||||||
{
|
|
||||||
const word inter1 = regionNames[e[0]] + "_to_" + regionNames[e[1]];
|
|
||||||
const word inter2 = regionNames[e[1]] + "_to_" + regionNames[e[0]];
|
|
||||||
|
|
||||||
directMappedWallPolyPatch patch1
|
directMappedWallPolyPatch patch1
|
||||||
(
|
(
|
||||||
inter1,
|
names[0],
|
||||||
0, // overridden
|
0, // overridden
|
||||||
0, // overridden
|
0, // overridden
|
||||||
0, // overridden
|
0, // overridden
|
||||||
regionNames[e[1]], // sampleRegion
|
regionNames[e[1]], // sampleRegion
|
||||||
directMappedPatchBase::NEARESTPATCHFACE,
|
directMappedPatchBase::NEARESTPATCHFACE,
|
||||||
inter2, // samplePatch
|
names[1], // samplePatch
|
||||||
point::zero, // offset
|
point::zero, // offset
|
||||||
mesh.boundaryMesh()
|
mesh.boundaryMesh()
|
||||||
);
|
);
|
||||||
|
|
||||||
label patchI = addPatch(mesh, patch1);
|
interfacePatches[interI] = addPatch(mesh, patch1);
|
||||||
|
|
||||||
directMappedWallPolyPatch patch2
|
directMappedWallPolyPatch patch2
|
||||||
(
|
(
|
||||||
inter2,
|
names[1],
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
regionNames[e[0]], // sampleRegion
|
regionNames[e[0]], // sampleRegion
|
||||||
directMappedPatchBase::NEARESTPATCHFACE,
|
directMappedPatchBase::NEARESTPATCHFACE,
|
||||||
inter1,
|
names[0],
|
||||||
point::zero, // offset
|
point::zero, // offset
|
||||||
mesh.boundaryMesh()
|
mesh.boundaryMesh()
|
||||||
);
|
);
|
||||||
addPatch(mesh, patch2);
|
addPatch(mesh, patch2);
|
||||||
|
|
||||||
Info<< "For interface between region " << e[0]
|
Info<< "For interface between region " << regionNames[e[0]]
|
||||||
<< " and " << e[1] << " added patch " << patchI
|
<< " and " << regionNames[e[1]] << " added patches" << endl
|
||||||
<< " " << mesh.boundaryMesh()[patchI].name()
|
<< " " << interfacePatches[interI]
|
||||||
|
<< "\t" << mesh.boundaryMesh()[interfacePatches[interI]].name()
|
||||||
|
<< endl
|
||||||
|
<< " " << interfacePatches[interI]+1
|
||||||
|
<< "\t" << mesh.boundaryMesh()[interfacePatches[interI]+1].name()
|
||||||
<< endl;
|
<< endl;
|
||||||
|
|
||||||
interfaceToPatch.insert(e, patchI);
|
|
||||||
}
|
}
|
||||||
}
|
return interfacePatches;
|
||||||
return interfaceToPatch;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1195,76 +1350,6 @@ label findCorrespondingRegion
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//// Checks if cellZone has corresponding cellRegion.
|
|
||||||
//label findCorrespondingRegion
|
|
||||||
//(
|
|
||||||
// const cellZoneMesh& cellZones,
|
|
||||||
// const labelList& existingZoneID, // per cell the (unique) zoneID
|
|
||||||
// const labelList& cellRegion,
|
|
||||||
// const label nCellRegions,
|
|
||||||
// const label zoneI
|
|
||||||
//)
|
|
||||||
//{
|
|
||||||
// // Region corresponding to zone. Start off with special value: no
|
|
||||||
// // corresponding region.
|
|
||||||
// label regionI = labelMax;
|
|
||||||
//
|
|
||||||
// const cellZone& cz = cellZones[zoneI];
|
|
||||||
//
|
|
||||||
// if (cz.empty())
|
|
||||||
// {
|
|
||||||
// // My local portion is empty. Maps to any empty cellZone. Mark with
|
|
||||||
// // special value which can get overwritten by other processors.
|
|
||||||
// regionI = -1;
|
|
||||||
// }
|
|
||||||
// else
|
|
||||||
// {
|
|
||||||
// regionI = cellRegion[cz[0]];
|
|
||||||
//
|
|
||||||
// forAll(cz, i)
|
|
||||||
// {
|
|
||||||
// if (cellRegion[cz[i]] != regionI)
|
|
||||||
// {
|
|
||||||
// regionI = labelMax;
|
|
||||||
// break;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// // Determine same zone over all processors.
|
|
||||||
// reduce(regionI, maxOp<label>());
|
|
||||||
//
|
|
||||||
//
|
|
||||||
// // 2. All of region present?
|
|
||||||
//
|
|
||||||
// if (regionI == labelMax)
|
|
||||||
// {
|
|
||||||
// regionI = -1;
|
|
||||||
// }
|
|
||||||
// else if (regionI != -1)
|
|
||||||
// {
|
|
||||||
// forAll(cellRegion, cellI)
|
|
||||||
// {
|
|
||||||
// if
|
|
||||||
// (
|
|
||||||
// cellRegion[cellI] == regionI
|
|
||||||
// && existingZoneID[cellI] != zoneI
|
|
||||||
// )
|
|
||||||
// {
|
|
||||||
// // cellI in regionI but not in zoneI
|
|
||||||
// regionI = -1;
|
|
||||||
// break;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// // If one in error, all should be in error. Note that branch
|
|
||||||
// // gets taken on all procs.
|
|
||||||
// reduce(regionI, minOp<label>());
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// return regionI;
|
|
||||||
//}
|
|
||||||
|
|
||||||
|
|
||||||
// Get zone per cell
|
// Get zone per cell
|
||||||
// - non-unique zoning
|
// - non-unique zoning
|
||||||
// - coupled zones
|
// - coupled zones
|
||||||
@ -1484,6 +1569,7 @@ void writeCellToRegion(const fvMesh& mesh, const labelList& cellRegion)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Main program:
|
// Main program:
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
@ -1541,6 +1627,11 @@ int main(int argc, char *argv[])
|
|||||||
"sloppyCellZones",
|
"sloppyCellZones",
|
||||||
"try to match heuristically regions to existing cell zones"
|
"try to match heuristically regions to existing cell zones"
|
||||||
);
|
);
|
||||||
|
argList::addBoolOption
|
||||||
|
(
|
||||||
|
"useFaceZones",
|
||||||
|
"use faceZones to patch inter-region faces instead of single patch"
|
||||||
|
);
|
||||||
|
|
||||||
#include "setRootCase.H"
|
#include "setRootCase.H"
|
||||||
#include "createTime.H"
|
#include "createTime.H"
|
||||||
@ -1564,6 +1655,8 @@ int main(int argc, char *argv[])
|
|||||||
const bool overwrite = args.optionFound("overwrite");
|
const bool overwrite = args.optionFound("overwrite");
|
||||||
const bool detectOnly = args.optionFound("detectOnly");
|
const bool detectOnly = args.optionFound("detectOnly");
|
||||||
const bool sloppyCellZones = args.optionFound("sloppyCellZones");
|
const bool sloppyCellZones = args.optionFound("sloppyCellZones");
|
||||||
|
const bool useFaceZones = args.optionFound("useFaceZones");
|
||||||
|
|
||||||
if
|
if
|
||||||
(
|
(
|
||||||
(useCellZonesOnly || useCellZonesFile)
|
(useCellZonesOnly || useCellZonesFile)
|
||||||
@ -1579,6 +1672,20 @@ int main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (useFaceZones)
|
||||||
|
{
|
||||||
|
Info<< "Using current faceZones to divide inter-region interfaces"
|
||||||
|
<< " into multiple patches."
|
||||||
|
<< nl << endl;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Info<< "Creating single patch per inter-region interface."
|
||||||
|
<< nl << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (insidePoint && largestOnly)
|
if (insidePoint && largestOnly)
|
||||||
{
|
{
|
||||||
FatalErrorIn(args.executable())
|
FatalErrorIn(args.executable())
|
||||||
@ -1768,6 +1875,7 @@ int main(int argc, char *argv[])
|
|||||||
writeCellToRegion(mesh, cellRegion);
|
writeCellToRegion(mesh, cellRegion);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Sizes per region
|
// Sizes per region
|
||||||
// ~~~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
@ -1805,34 +1913,48 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Since we're going to mess with patches make sure all non-processor ones
|
// Since we're going to mess with patches and zones make sure all
|
||||||
// are on all processors.
|
// is synchronised
|
||||||
mesh.boundaryMesh().checkParallelSync(true);
|
mesh.boundaryMesh().checkParallelSync(true);
|
||||||
|
mesh.faceZones().checkParallelSync(true);
|
||||||
|
|
||||||
|
|
||||||
// Sizes of interface between regions. From pair of regions to number of
|
// Interfaces
|
||||||
// faces.
|
// ----------
|
||||||
|
// per interface:
|
||||||
|
// - the two regions on either side
|
||||||
|
// - the name
|
||||||
|
// - the (global) size
|
||||||
edgeList interfaces;
|
edgeList interfaces;
|
||||||
EdgeMap<label> interfaceSizes;
|
List<Pair<word> > interfaceNames;
|
||||||
|
labelList interfaceSizes;
|
||||||
|
// per face the interface
|
||||||
|
labelList faceToInterface;
|
||||||
|
|
||||||
getInterfaceSizes
|
getInterfaceSizes
|
||||||
(
|
(
|
||||||
mesh,
|
mesh,
|
||||||
|
useFaceZones,
|
||||||
cellRegion,
|
cellRegion,
|
||||||
true, // sum in parallel?
|
regionNames,
|
||||||
|
|
||||||
interfaces,
|
interfaces,
|
||||||
interfaceSizes
|
interfaceNames,
|
||||||
|
interfaceSizes,
|
||||||
|
faceToInterface
|
||||||
);
|
);
|
||||||
|
|
||||||
Info<< "Sizes inbetween regions:" << nl << nl
|
Info<< "Sizes of interfaces between regions:" << nl << nl
|
||||||
<< "Region\tRegion\tFaces" << nl
|
<< "Interface\tRegion\tRegion\tFaces" << nl
|
||||||
<< "------\t------\t-----" << endl;
|
<< "---------\t------\t------\t-----" << endl;
|
||||||
|
|
||||||
forAll(interfaces, interI)
|
forAll(interfaces, interI)
|
||||||
{
|
{
|
||||||
const edge& e = interfaces[interI];
|
const edge& e = interfaces[interI];
|
||||||
|
|
||||||
Info<< e[0] << '\t' << e[1] << '\t' << interfaceSizes[e] << nl;
|
Info<< interI
|
||||||
|
<< "\t\t" << e[0] << '\t' << e[1]
|
||||||
|
<< '\t' << interfaceSizes[interI] << nl;
|
||||||
}
|
}
|
||||||
Info<< endl;
|
Info<< endl;
|
||||||
|
|
||||||
@ -1982,16 +2104,14 @@ int main(int argc, char *argv[])
|
|||||||
// Add all possible patches. Empty ones get filtered later on.
|
// Add all possible patches. Empty ones get filtered later on.
|
||||||
Info<< nl << "Adding patches" << nl << endl;
|
Info<< nl << "Adding patches" << nl << endl;
|
||||||
|
|
||||||
EdgeMap<label> interfaceToPatch
|
labelList interfacePatches
|
||||||
(
|
(
|
||||||
addRegionPatches
|
addRegionPatches
|
||||||
(
|
(
|
||||||
mesh,
|
mesh,
|
||||||
cellRegion,
|
regionNames,
|
||||||
nCellRegions,
|
|
||||||
interfaces,
|
interfaces,
|
||||||
interfaceSizes,
|
interfaceNames
|
||||||
regionNames
|
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -2041,7 +2161,8 @@ int main(int argc, char *argv[])
|
|||||||
mesh,
|
mesh,
|
||||||
cellRegion,
|
cellRegion,
|
||||||
regionNames,
|
regionNames,
|
||||||
interfaceToPatch,
|
faceToInterface,
|
||||||
|
interfacePatches,
|
||||||
regionI,
|
regionI,
|
||||||
(overwrite ? oldInstance : runTime.timeName())
|
(overwrite ? oldInstance : runTime.timeName())
|
||||||
);
|
);
|
||||||
@ -2059,7 +2180,8 @@ int main(int argc, char *argv[])
|
|||||||
mesh,
|
mesh,
|
||||||
cellRegion,
|
cellRegion,
|
||||||
regionNames,
|
regionNames,
|
||||||
interfaceToPatch,
|
faceToInterface,
|
||||||
|
interfacePatches,
|
||||||
regionI,
|
regionI,
|
||||||
(overwrite ? oldInstance : runTime.timeName())
|
(overwrite ? oldInstance : runTime.timeName())
|
||||||
);
|
);
|
||||||
@ -2078,7 +2200,8 @@ int main(int argc, char *argv[])
|
|||||||
mesh,
|
mesh,
|
||||||
cellRegion,
|
cellRegion,
|
||||||
regionNames,
|
regionNames,
|
||||||
interfaceToPatch,
|
faceToInterface,
|
||||||
|
interfacePatches,
|
||||||
regionI,
|
regionI,
|
||||||
(overwrite ? oldInstance : runTime.timeName())
|
(overwrite ? oldInstance : runTime.timeName())
|
||||||
);
|
);
|
||||||
|
|||||||
@ -68,13 +68,13 @@ namespace Foam
|
|||||||
|
|
||||||
functionObjectList fol(runTime, dict);
|
functionObjectList fol(runTime, dict);
|
||||||
fol.start();
|
fol.start();
|
||||||
fol.execute();
|
fol.execute(true); // override outputControl - force writing
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
functionObjectList fol(runTime);
|
functionObjectList fol(runTime);
|
||||||
fol.start();
|
fol.start();
|
||||||
fol.execute();
|
fol.execute(true); // override outputControl - force writing
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -162,12 +162,14 @@ do
|
|||||||
procCmdFile="$PWD/processor${proc}.sh"
|
procCmdFile="$PWD/processor${proc}.sh"
|
||||||
procLog="processor${proc}.log"
|
procLog="processor${proc}.log"
|
||||||
geom="-geometry 120x20+$xpos+$ypos"
|
geom="-geometry 120x20+$xpos+$ypos"
|
||||||
node=""
|
|
||||||
|
|
||||||
if [ "$WM_MPLIB" = OPENMPI ]
|
case "$WM_MPLIB" in
|
||||||
then
|
*OPENMPI)
|
||||||
node="-np 1 "
|
node="-np 1 "
|
||||||
fi
|
;;
|
||||||
|
*)
|
||||||
|
node=""
|
||||||
|
esac
|
||||||
|
|
||||||
echo "#!/bin/sh" > $procCmdFile
|
echo "#!/bin/sh" > $procCmdFile
|
||||||
case "$method" in
|
case "$method" in
|
||||||
|
|||||||
@ -65,6 +65,7 @@ cleanCase()
|
|||||||
rm -rf processor* > /dev/null 2>&1
|
rm -rf processor* > /dev/null 2>&1
|
||||||
rm -rf probes* > /dev/null 2>&1
|
rm -rf probes* > /dev/null 2>&1
|
||||||
rm -rf forces* > /dev/null 2>&1
|
rm -rf forces* > /dev/null 2>&1
|
||||||
|
rm -rf sets > /dev/null 2>&1
|
||||||
rm -rf system/machines > /dev/null 2>&1
|
rm -rf system/machines > /dev/null 2>&1
|
||||||
(cd constant/polyMesh && \
|
(cd constant/polyMesh && \
|
||||||
rm -rf \
|
rm -rf \
|
||||||
|
|||||||
@ -59,6 +59,14 @@ It will check if anything needs to be converted, backup the current file to .old
|
|||||||
and split any cyclic patchFields into two entries.
|
and split any cyclic patchFields into two entries.
|
||||||
|
|
||||||
|
|
||||||
|
Mesh converters
|
||||||
|
---------------
|
||||||
|
Most mesh formats use cyclics in a single patch (i.e. the old way).
|
||||||
|
The converters have been adapted to use the patch 'oldCyclic' instead of
|
||||||
|
'cyclic'. oldCyclic uses the 17x automatic ordering but writes 'type cyclic'
|
||||||
|
so afterwards foamUpgradeCyclics can be run to upgrade.
|
||||||
|
|
||||||
|
|
||||||
decomposePar
|
decomposePar
|
||||||
------------
|
------------
|
||||||
Decomposes cyclics into processorCyclic:
|
Decomposes cyclics into processorCyclic:
|
||||||
|
|||||||
@ -37,8 +37,11 @@ namespace Foam
|
|||||||
const label SIBS::nSeq_[iMaxX_] = {2, 6, 10, 14, 22, 34, 50, 70};
|
const label SIBS::nSeq_[iMaxX_] = {2, 6, 10, 14, 22, 34, 50, 70};
|
||||||
|
|
||||||
const scalar
|
const scalar
|
||||||
SIBS::safe1 = 0.25, SIBS::safe2 = 0.7,
|
SIBS::safe1 = 0.25,
|
||||||
SIBS::redMax = 1.0e-5, SIBS::redMin = 0.0, SIBS::scaleMX = 0.1;
|
SIBS::safe2 = 0.7,
|
||||||
|
SIBS::redMax = 1.0e-5,
|
||||||
|
SIBS::redMin = 0.7,
|
||||||
|
SIBS::scaleMX = 0.1;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -170,7 +170,9 @@ namespace Foam
|
|||||||
<< "inotify instances" << endl
|
<< "inotify instances" << endl
|
||||||
<< " (/proc/sys/fs/inotify/max_user_instances"
|
<< " (/proc/sys/fs/inotify/max_user_instances"
|
||||||
<< " on Linux)" << endl
|
<< " on Linux)" << endl
|
||||||
<< " or switch off runTimeModifiable." << endl
|
<< " , switch off runTimeModifiable." << endl
|
||||||
|
<< " or compile this file with FOAM_USE_STAT to use"
|
||||||
|
<< " time stamps instead of inotify." << endl
|
||||||
<< " Continuing without additional file monitoring."
|
<< " Continuing without additional file monitoring."
|
||||||
<< endl;
|
<< endl;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -28,8 +28,8 @@ License
|
|||||||
template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
|
template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
|
||||||
inline Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::DynamicList()
|
inline Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::DynamicList()
|
||||||
:
|
:
|
||||||
List<T>(SizeInc),
|
List<T>(0),
|
||||||
capacity_(SizeInc)
|
capacity_(0)
|
||||||
{
|
{
|
||||||
List<T>::size(0);
|
List<T>::size(0);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -128,7 +128,10 @@ bool Foam::OutputFilterFunctionObject<OutputFilter>::start()
|
|||||||
|
|
||||||
|
|
||||||
template<class OutputFilter>
|
template<class OutputFilter>
|
||||||
bool Foam::OutputFilterFunctionObject<OutputFilter>::execute()
|
bool Foam::OutputFilterFunctionObject<OutputFilter>::execute
|
||||||
|
(
|
||||||
|
const bool forceWrite
|
||||||
|
)
|
||||||
{
|
{
|
||||||
if (enabled_)
|
if (enabled_)
|
||||||
{
|
{
|
||||||
@ -139,7 +142,7 @@ bool Foam::OutputFilterFunctionObject<OutputFilter>::execute()
|
|||||||
|
|
||||||
ptr_->execute();
|
ptr_->execute();
|
||||||
|
|
||||||
if (outputControl_.output())
|
if (forceWrite || outputControl_.output())
|
||||||
{
|
{
|
||||||
ptr_->write();
|
ptr_->write();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -183,7 +183,7 @@ public:
|
|||||||
virtual bool start();
|
virtual bool start();
|
||||||
|
|
||||||
//- Called at each ++ or += of the time-loop
|
//- Called at each ++ or += of the time-loop
|
||||||
virtual bool execute();
|
virtual bool execute(const bool forceWrite);
|
||||||
|
|
||||||
//- Called when Time::run() determines that the time-loop exits
|
//- Called when Time::run() determines that the time-loop exits
|
||||||
virtual bool end();
|
virtual bool end();
|
||||||
|
|||||||
@ -112,7 +112,7 @@ const Foam::word& Foam::functionObject::name() const
|
|||||||
|
|
||||||
bool Foam::functionObject::end()
|
bool Foam::functionObject::end()
|
||||||
{
|
{
|
||||||
return execute();
|
return execute(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -147,8 +147,9 @@ public:
|
|||||||
//- Called at the start of the time-loop
|
//- Called at the start of the time-loop
|
||||||
virtual bool start() = 0;
|
virtual bool start() = 0;
|
||||||
|
|
||||||
//- Called at each ++ or += of the time-loop
|
//- Called at each ++ or += of the time-loop. forceWrite overrides the
|
||||||
virtual bool execute() = 0;
|
// outputControl behaviour.
|
||||||
|
virtual bool execute(const bool forceWrite) = 0;
|
||||||
|
|
||||||
//- Called when Time::run() determines that the time-loop exits.
|
//- Called when Time::run() determines that the time-loop exits.
|
||||||
// By default it simply calls execute().
|
// By default it simply calls execute().
|
||||||
|
|||||||
@ -144,7 +144,7 @@ bool Foam::functionObjectList::start()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool Foam::functionObjectList::execute()
|
bool Foam::functionObjectList::execute(const bool forceWrite)
|
||||||
{
|
{
|
||||||
bool ok = true;
|
bool ok = true;
|
||||||
|
|
||||||
@ -157,7 +157,7 @@ bool Foam::functionObjectList::execute()
|
|||||||
|
|
||||||
forAll(*this, objectI)
|
forAll(*this, objectI)
|
||||||
{
|
{
|
||||||
ok = operator[](objectI).execute() && ok;
|
ok = operator[](objectI).execute(forceWrite) && ok;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -153,8 +153,10 @@ public:
|
|||||||
//- Called at the start of the time-loop
|
//- Called at the start of the time-loop
|
||||||
virtual bool start();
|
virtual bool start();
|
||||||
|
|
||||||
//- Called at each ++ or += of the time-loop
|
//- Called at each ++ or += of the time-loop. forceWrite overrides
|
||||||
virtual bool execute();
|
// the usual outputControl behaviour and forces writing always
|
||||||
|
// (used in postprocessing mode)
|
||||||
|
virtual bool execute(const bool forceWrite = false);
|
||||||
|
|
||||||
//- Called when Time::run() determines that the time-loop exits
|
//- Called when Time::run() determines that the time-loop exits
|
||||||
virtual bool end();
|
virtual bool end();
|
||||||
|
|||||||
@ -25,87 +25,53 @@ License
|
|||||||
|
|
||||||
#include "DynamicField.H"
|
#include "DynamicField.H"
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * IOstream Operators * * * * * * * * * * * * //
|
||||||
|
|
||||||
namespace Foam
|
template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
|
||||||
{
|
Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>::DynamicField(Istream& is)
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * Static Members * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
template<class Type>
|
|
||||||
const char* const DynamicField<Type>::typeName("DynamicField");
|
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
template<class Type>
|
|
||||||
DynamicField<Type>::DynamicField(Istream& is)
|
|
||||||
:
|
:
|
||||||
Field<Type>(is),
|
Field<T>(is),
|
||||||
capacity_(Field<Type>::size())
|
capacity_(Field<T>::size())
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
|
||||||
template<class Type>
|
template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
|
||||||
tmp<DynamicField<Type> > DynamicField<Type>::clone() const
|
Foam::tmp<Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv> >
|
||||||
|
Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>::clone() const
|
||||||
{
|
{
|
||||||
return tmp<DynamicField<Type> >(new DynamicField<Type>(*this));
|
return tmp<DynamicField<T, SizeInc, SizeMult, SizeDiv> >
|
||||||
|
(
|
||||||
|
new DynamicField<T, SizeInc, SizeMult, SizeDiv>(*this)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
template<class Type>
|
|
||||||
void DynamicField<Type>::setSize(const label nElem)
|
|
||||||
{
|
|
||||||
// allocate more capacity?
|
|
||||||
if (nElem > capacity_)
|
|
||||||
{
|
|
||||||
capacity_ = max(nElem, label(1 + capacity_*2));
|
|
||||||
|
|
||||||
Field<Type>::setSize(capacity_);
|
|
||||||
}
|
|
||||||
|
|
||||||
// adjust addressed size
|
|
||||||
Field<Type>::size(nElem);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * IOstream Operator * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * IOstream Operator * * * * * * * * * * * * * //
|
||||||
|
|
||||||
template<class Type>
|
template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
|
||||||
Ostream& operator<<(Ostream& os, const DynamicField<Type>& f)
|
Foam::Ostream& Foam::operator<<
|
||||||
|
(
|
||||||
|
Ostream& os,
|
||||||
|
const DynamicField<T, SizeInc, SizeMult, SizeDiv>& lst
|
||||||
|
)
|
||||||
{
|
{
|
||||||
os << static_cast<const Field<Type>&>(f);
|
os << static_cast<const Field<T>&>(lst);
|
||||||
return os;
|
return os;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template<class Type>
|
template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
|
||||||
Ostream& operator<<(Ostream& os, const tmp<DynamicField<Type> >& tf)
|
Foam::Istream& Foam::operator>>
|
||||||
|
(
|
||||||
|
Istream& is,
|
||||||
|
DynamicField<T, SizeInc, SizeMult, SizeDiv>& lst
|
||||||
|
)
|
||||||
{
|
{
|
||||||
os << tf();
|
is >> static_cast<Field<T>&>(lst);
|
||||||
tf.clear();
|
lst.capacity_ = lst.Field<T>::size();
|
||||||
return os;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template<class Type>
|
|
||||||
Istream& operator>>(Istream& is, DynamicField<Type>& lst)
|
|
||||||
{
|
|
||||||
is >> static_cast<Field<Type>&>(lst);
|
|
||||||
lst.capacity_ = lst.Field<Type>::size();
|
|
||||||
|
|
||||||
return is;
|
return is;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
} // End namespace Foam
|
|
||||||
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
// ************************************************************************* //
|
||||||
|
|||||||
@ -25,9 +25,10 @@ Class
|
|||||||
Foam::DynamicField
|
Foam::DynamicField
|
||||||
|
|
||||||
Description
|
Description
|
||||||
Dynamically sized Field. WIP.
|
Dynamically sized Field.
|
||||||
|
|
||||||
SourceFiles
|
SourceFiles
|
||||||
|
DynamicFieldI.H
|
||||||
DynamicField.C
|
DynamicField.C
|
||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
\*---------------------------------------------------------------------------*/
|
||||||
@ -44,89 +45,78 @@ namespace Foam
|
|||||||
|
|
||||||
// Forward declaration of friend functions and operators
|
// Forward declaration of friend functions and operators
|
||||||
|
|
||||||
template<class Type>
|
template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
|
||||||
class DynamicField;
|
class DynamicField;
|
||||||
|
|
||||||
template<class Type>
|
template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
|
||||||
Ostream& operator<<(Ostream&, const DynamicField<Type>&);
|
Ostream& operator<<
|
||||||
|
(
|
||||||
template<class Type>
|
Ostream&,
|
||||||
Ostream& operator<<(Ostream&, const tmp<DynamicField<Type> >&);
|
const DynamicField<T, SizeInc, SizeMult, SizeDiv>&
|
||||||
|
);
|
||||||
template<class Type>
|
template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
|
||||||
Istream& operator>>(Istream&, DynamicField<Type>&);
|
Istream& operator>>
|
||||||
|
(
|
||||||
|
Istream&,
|
||||||
|
DynamicField<T, SizeInc, SizeMult, SizeDiv>&
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*\
|
/*---------------------------------------------------------------------------*\
|
||||||
Class DynamicField Declaration
|
Class DynamicField Declaration
|
||||||
\*---------------------------------------------------------------------------*/
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
template<class Type>
|
template<class T, unsigned SizeInc=0, unsigned SizeMult=2, unsigned SizeDiv=1>
|
||||||
class DynamicField
|
class DynamicField
|
||||||
:
|
:
|
||||||
public Field<Type>
|
public Field<T>
|
||||||
{
|
{
|
||||||
|
|
||||||
// Private data
|
// Private data
|
||||||
|
|
||||||
//- The capacity (allocated size) of the underlying field.
|
//- The capacity (allocated size) of the underlying field.
|
||||||
label capacity_;
|
label capacity_;
|
||||||
|
|
||||||
|
|
||||||
//- Construct given size and initial value
|
|
||||||
DynamicField(const label, const Type&);
|
|
||||||
|
|
||||||
//- Construct as copy of tmp<DynamicField>
|
|
||||||
# ifdef ConstructFromTmp
|
|
||||||
DynamicField(const tmp<DynamicField<Type> >&);
|
|
||||||
# endif
|
|
||||||
|
|
||||||
//- Construct from a dictionary entry
|
|
||||||
DynamicField(const word&, const dictionary&, const label);
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
// Static data members
|
|
||||||
|
|
||||||
static const char* const typeName;
|
|
||||||
|
|
||||||
|
|
||||||
// Static Member Functions
|
// Static Member Functions
|
||||||
|
|
||||||
//- Return a null field
|
//- Return a null field
|
||||||
inline static const DynamicField<Type>& null()
|
inline static const DynamicField<T, SizeInc, SizeMult, SizeDiv>& null()
|
||||||
{
|
{
|
||||||
return *reinterpret_cast< DynamicField<Type>* >(0);
|
return *reinterpret_cast
|
||||||
|
<
|
||||||
|
DynamicField<T, SizeInc, SizeMult, SizeDiv>*
|
||||||
|
>(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Constructors
|
// Constructors
|
||||||
|
|
||||||
//- Construct null
|
//- Construct null
|
||||||
// Used for temporary fields which are initialised after construction
|
inline DynamicField();
|
||||||
DynamicField();
|
|
||||||
|
|
||||||
//- Construct given size
|
//- Construct given size.
|
||||||
// Used for temporary fields which are initialised after construction
|
|
||||||
explicit inline DynamicField(const label);
|
explicit inline DynamicField(const label);
|
||||||
|
|
||||||
//- Construct as copy of a UList\<Type\>
|
//- Construct from UList. Size set to UList size.
|
||||||
explicit inline DynamicField(const UList<Type>&);
|
// Also constructs from DynamicField with different sizing parameters.
|
||||||
|
explicit inline DynamicField(const UList<T>&);
|
||||||
|
|
||||||
//- Construct by transferring the List contents
|
//- Construct by transferring the parameter contents
|
||||||
explicit inline DynamicField(const Xfer<List<Type> >&);
|
explicit inline DynamicField(const Xfer<List<T> >&);
|
||||||
|
|
||||||
//- Construct by 1 to 1 mapping from the given field
|
//- Construct by 1 to 1 mapping from the given field
|
||||||
inline DynamicField
|
inline DynamicField
|
||||||
(
|
(
|
||||||
const UList<Type>& mapF,
|
const UList<T>& mapF,
|
||||||
const labelList& mapAddressing
|
const labelList& mapAddressing
|
||||||
);
|
);
|
||||||
|
|
||||||
//- Construct by interpolative mapping from the given field
|
//- Construct by interpolative mapping from the given field
|
||||||
inline DynamicField
|
inline DynamicField
|
||||||
(
|
(
|
||||||
const UList<Type>& mapF,
|
const UList<T>& mapF,
|
||||||
const labelListList& mapAddressing,
|
const labelListList& mapAddressing,
|
||||||
const scalarListList& weights
|
const scalarListList& weights
|
||||||
);
|
);
|
||||||
@ -134,59 +124,129 @@ public:
|
|||||||
//- Construct by mapping from the given field
|
//- Construct by mapping from the given field
|
||||||
inline DynamicField
|
inline DynamicField
|
||||||
(
|
(
|
||||||
const UList<Type>& mapF,
|
const UList<T>& mapF,
|
||||||
const FieldMapper& map
|
const FieldMapper& map
|
||||||
);
|
);
|
||||||
|
|
||||||
//- Construct as copy
|
//- Construct copy
|
||||||
inline DynamicField(const DynamicField<Type>&);
|
inline DynamicField(const DynamicField<T, SizeInc, SizeMult, SizeDiv>&);
|
||||||
|
|
||||||
//- Construct as copy or re-use as specified.
|
|
||||||
inline DynamicField(DynamicField<Type>&, bool reUse);
|
|
||||||
|
|
||||||
//- Construct by transferring the Field contents
|
//- Construct by transferring the Field contents
|
||||||
inline DynamicField(const Xfer<DynamicField<Type> >&);
|
inline DynamicField
|
||||||
|
(
|
||||||
|
const Xfer<DynamicField<T, SizeInc, SizeMult, SizeDiv> >&
|
||||||
|
);
|
||||||
|
|
||||||
//- Construct from Istream
|
//- Construct from Istream. Size set to size of list read.
|
||||||
inline DynamicField(Istream&);
|
explicit DynamicField(Istream&);
|
||||||
|
|
||||||
//- Clone
|
//- Clone
|
||||||
tmp<DynamicField<Type> > clone() const;
|
tmp<DynamicField<T, SizeInc, SizeMult, SizeDiv> > clone() const;
|
||||||
|
|
||||||
|
|
||||||
// Member Functions
|
// Member Functions
|
||||||
|
|
||||||
|
// Access
|
||||||
|
|
||||||
//- Size of the underlying storage.
|
//- Size of the underlying storage.
|
||||||
inline label capacity() const;
|
inline label capacity() const;
|
||||||
|
|
||||||
//- Append an element at the end of the list
|
// Edit
|
||||||
inline void append(const Type&);
|
|
||||||
|
//- Alter the size of the underlying storage.
|
||||||
|
// The addressed size will be truncated if needed to fit, but will
|
||||||
|
// remain otherwise untouched.
|
||||||
|
// Use this or reserve() in combination with append().
|
||||||
|
inline void setCapacity(const label);
|
||||||
|
|
||||||
//- Alter the addressed list size.
|
//- Alter the addressed list size.
|
||||||
// New space will be allocated if required.
|
// New space will be allocated if required.
|
||||||
// Use this to resize the list prior to using the operator[] for
|
// Use this to resize the list prior to using the operator[] for
|
||||||
// setting values (as per List usage).
|
// setting values (as per List usage).
|
||||||
void setSize(const label nElem);
|
inline void setSize(const label);
|
||||||
|
|
||||||
// Member operators
|
//- Alter the addressed list size and fill new space with a
|
||||||
|
// constant.
|
||||||
|
inline void setSize(const label, const T&);
|
||||||
|
|
||||||
inline void operator=(const DynamicField<Type>&);
|
//- Alter the addressed list size.
|
||||||
inline void operator=(const UList<Type>&);
|
// New space will be allocated if required.
|
||||||
inline void operator=(const tmp<DynamicField<Type> >&);
|
// Use this to resize the list prior to using the operator[] for
|
||||||
|
// setting values (as per List usage).
|
||||||
|
inline void resize(const label);
|
||||||
|
|
||||||
|
//- Alter the addressed list size and fill new space with a
|
||||||
|
// constant.
|
||||||
|
inline void resize(const label, const T&);
|
||||||
|
|
||||||
|
//- Reserve allocation space for at least this size.
|
||||||
|
// Never shrinks the allocated size, use setCapacity() for that.
|
||||||
|
inline void reserve(const label);
|
||||||
|
|
||||||
|
//- Clear the addressed list, i.e. set the size to zero.
|
||||||
|
// Allocated size does not change
|
||||||
|
inline void clear();
|
||||||
|
|
||||||
|
//- Clear the list and delete storage.
|
||||||
|
inline void clearStorage();
|
||||||
|
|
||||||
|
//- Shrink the allocated space to the number of elements used.
|
||||||
|
// Returns a reference to the DynamicField.
|
||||||
|
inline DynamicField<T, SizeInc, SizeMult, SizeDiv>& shrink();
|
||||||
|
|
||||||
|
//- Transfer contents to the Xfer container as a plain List
|
||||||
|
inline Xfer<List<T> > xfer();
|
||||||
|
|
||||||
|
|
||||||
|
// Member Operators
|
||||||
|
|
||||||
|
//- Append an element at the end of the list
|
||||||
|
inline DynamicField<T, SizeInc, SizeMult, SizeDiv>& append
|
||||||
|
(
|
||||||
|
const T&
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Append a List at the end of this list
|
||||||
|
inline DynamicField<T, SizeInc, SizeMult, SizeDiv>& append
|
||||||
|
(
|
||||||
|
const UList<T>&
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Remove and return the top element
|
||||||
|
inline T remove();
|
||||||
|
|
||||||
|
//- Return non-const access to an element, resizing list if
|
||||||
|
// necessary
|
||||||
|
inline T& operator()(const label);
|
||||||
|
|
||||||
|
//- Assignment of all addressed entries to the given value
|
||||||
|
inline void operator=(const T&);
|
||||||
|
|
||||||
|
//- Assignment from DynamicField
|
||||||
|
inline void operator=
|
||||||
|
(
|
||||||
|
const DynamicField<T, SizeInc, SizeMult, SizeDiv>&
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Assignment from UList
|
||||||
|
inline void operator=(const UList<T>&);
|
||||||
|
|
||||||
//- Return element of Field.
|
|
||||||
using Field<Type>::operator[];
|
|
||||||
|
|
||||||
// IOstream operators
|
// IOstream operators
|
||||||
|
|
||||||
friend Ostream& operator<< <Type>
|
// Write DynamicField to Ostream.
|
||||||
(Ostream&, const DynamicField<Type>&);
|
friend Ostream& operator<< <T, SizeInc, SizeMult, SizeDiv>
|
||||||
|
(
|
||||||
|
Ostream&,
|
||||||
|
const DynamicField<T, SizeInc, SizeMult, SizeDiv>&
|
||||||
|
);
|
||||||
|
|
||||||
friend Ostream& operator<< <Type>
|
//- Read from Istream, discarding contents of existing DynamicField.
|
||||||
(Ostream&, const tmp<DynamicField<Type> >&);
|
friend Istream& operator>> <T, SizeInc, SizeMult, SizeDiv>
|
||||||
|
(
|
||||||
friend Istream& operator>> <Type>
|
Istream&,
|
||||||
(Istream&, DynamicField<Type>&);
|
DynamicField<T, SizeInc, SizeMult, SizeDiv>&
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -23,175 +23,441 @@ License
|
|||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
#include "DynamicField.H"
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
template<class Type>
|
template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
|
||||||
Foam::DynamicField<Type>::DynamicField()
|
inline Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>::DynamicField()
|
||||||
:
|
:
|
||||||
Field<Type>(),
|
Field<T>(0),
|
||||||
capacity_(0)
|
capacity_(Field<T>::size())
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
|
||||||
template<class Type>
|
template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
|
||||||
Foam::DynamicField<Type>::DynamicField(const label size)
|
inline Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>::DynamicField
|
||||||
|
(
|
||||||
|
const label nElem
|
||||||
|
)
|
||||||
:
|
:
|
||||||
Field<Type>(size),
|
Field<T>(nElem),
|
||||||
capacity_(Field<Type>::size())
|
capacity_(Field<T>::size())
|
||||||
{
|
{
|
||||||
Field<Type>::size(0);
|
// we could also enforce SizeInc granularity when (!SizeMult || !SizeDiv)
|
||||||
|
Field<T>::size(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template<class Type>
|
template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
|
||||||
inline Foam::DynamicField<Type>::DynamicField
|
inline Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>::DynamicField
|
||||||
(
|
(
|
||||||
const UList<Type>& lst
|
const UList<T>& lst
|
||||||
)
|
)
|
||||||
:
|
:
|
||||||
Field<Type>(lst),
|
Field<T>(lst),
|
||||||
capacity_(Field<Type>::size())
|
capacity_(Field<T>::size())
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
|
||||||
template<class Type>
|
template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
|
||||||
inline Foam::DynamicField<Type>::DynamicField
|
inline Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>::DynamicField
|
||||||
(
|
(
|
||||||
const Xfer<List<Type> >& lst
|
const Xfer<List<T> >& lst
|
||||||
)
|
)
|
||||||
:
|
:
|
||||||
Field<Type>(lst),
|
Field<T>(lst),
|
||||||
capacity_(Field<Type>::size())
|
capacity_(Field<T>::size())
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
|
||||||
template<class Type>
|
template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
|
||||||
Foam::DynamicField<Type>::DynamicField
|
inline Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>::DynamicField
|
||||||
(
|
(
|
||||||
const UList<Type>& mapF,
|
const UList<T>& mapF,
|
||||||
const labelList& mapAddressing
|
const labelList& mapAddressing
|
||||||
)
|
)
|
||||||
:
|
:
|
||||||
Field<Type>(mapF, mapAddressing),
|
Field<T>(mapF, mapAddressing),
|
||||||
capacity_(Field<Type>::size())
|
capacity_(Field<T>::size())
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
|
||||||
template<class Type>
|
template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
|
||||||
Foam::DynamicField<Type>::DynamicField
|
inline Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>::DynamicField
|
||||||
(
|
(
|
||||||
const UList<Type>& mapF,
|
const UList<T>& mapF,
|
||||||
const labelListList& mapAddressing,
|
const labelListList& mapAddressing,
|
||||||
const scalarListList& weights
|
const scalarListList& weights
|
||||||
)
|
)
|
||||||
:
|
:
|
||||||
Field<Type>(mapF, mapAddressing, weights),
|
Field<T>(mapF, mapAddressing, weights),
|
||||||
capacity_(Field<Type>::size())
|
capacity_(Field<T>::size())
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
|
||||||
//- Construct by mapping from the given field
|
//- Construct by mapping from the given field
|
||||||
template<class Type>
|
template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
|
||||||
Foam::DynamicField<Type>::DynamicField
|
inline Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>::DynamicField
|
||||||
(
|
(
|
||||||
const UList<Type>& mapF,
|
const UList<T>& mapF,
|
||||||
const FieldMapper& map
|
const FieldMapper& map
|
||||||
)
|
)
|
||||||
:
|
:
|
||||||
DynamicField<Type>(mapF, map),
|
Field<T>(mapF, map),
|
||||||
capacity_(Field<Type>::size())
|
capacity_(Field<T>::size())
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
|
||||||
template<class Type>
|
template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
|
||||||
Foam::DynamicField<Type>::DynamicField(const DynamicField<Type>& f)
|
inline Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>::DynamicField
|
||||||
|
(
|
||||||
|
const DynamicField<T, SizeInc, SizeMult, SizeDiv>& lst
|
||||||
|
)
|
||||||
:
|
:
|
||||||
Field<Type>(f),
|
Field<T>(lst),
|
||||||
capacity_(Field<Type>::size())
|
capacity_(lst.capacity())
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
|
||||||
template<class Type>
|
template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
|
||||||
Foam::DynamicField<Type>::DynamicField(DynamicField<Type>& f, bool reUse)
|
inline Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>::DynamicField
|
||||||
|
(
|
||||||
|
const Xfer<DynamicField<T, SizeInc, SizeMult, SizeDiv> >& lst
|
||||||
|
)
|
||||||
:
|
:
|
||||||
Field<Type>(f, reUse),
|
Field<T>(lst),
|
||||||
capacity_(Field<Type>::size())
|
capacity_(Field<T>::size())
|
||||||
{}
|
|
||||||
|
|
||||||
|
|
||||||
template<class Type>
|
|
||||||
Foam::DynamicField<Type>::DynamicField(const Xfer<DynamicField<Type> >& f)
|
|
||||||
:
|
|
||||||
Field<Type>(f),
|
|
||||||
capacity_(Field<Type>::size())
|
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||||
|
|
||||||
template<class Type>
|
template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
|
||||||
Foam::label Foam::DynamicField<Type>::capacity() const
|
inline Foam::label Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>::capacity()
|
||||||
|
const
|
||||||
{
|
{
|
||||||
return capacity_;
|
return capacity_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template<class Type>
|
template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
|
||||||
void Foam::DynamicField<Type>::append(const Type& t)
|
inline void Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>::setCapacity
|
||||||
|
(
|
||||||
|
const label nElem
|
||||||
|
)
|
||||||
{
|
{
|
||||||
label elemI = Field<Type>::size();
|
label nextFree = Field<T>::size();
|
||||||
|
capacity_ = nElem;
|
||||||
|
|
||||||
|
if (nextFree > capacity_)
|
||||||
|
{
|
||||||
|
// truncate addressed sizes too
|
||||||
|
nextFree = capacity_;
|
||||||
|
}
|
||||||
|
// we could also enforce SizeInc granularity when (!SizeMult || !SizeDiv)
|
||||||
|
|
||||||
|
Field<T>::setSize(capacity_);
|
||||||
|
Field<T>::size(nextFree);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
|
||||||
|
inline void Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>::reserve
|
||||||
|
(
|
||||||
|
const label nElem
|
||||||
|
)
|
||||||
|
{
|
||||||
|
// allocate more capacity?
|
||||||
|
if (nElem > capacity_)
|
||||||
|
{
|
||||||
|
// TODO: convince the compiler that division by zero does not occur
|
||||||
|
// if (SizeInc && (!SizeMult || !SizeDiv))
|
||||||
|
// {
|
||||||
|
// // resize with SizeInc as the granularity
|
||||||
|
// capacity_ = nElem;
|
||||||
|
// unsigned pad = SizeInc - (capacity_ % SizeInc);
|
||||||
|
// if (pad != SizeInc)
|
||||||
|
// {
|
||||||
|
// capacity_ += pad;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// else
|
||||||
|
{
|
||||||
|
capacity_ = max
|
||||||
|
(
|
||||||
|
nElem,
|
||||||
|
label(SizeInc + capacity_ * SizeMult / SizeDiv)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// adjust allocated size, leave addressed size untouched
|
||||||
|
label nextFree = Field<T>::size();
|
||||||
|
Field<T>::setSize(capacity_);
|
||||||
|
Field<T>::size(nextFree);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
|
||||||
|
inline void Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>::setSize
|
||||||
|
(
|
||||||
|
const label nElem
|
||||||
|
)
|
||||||
|
{
|
||||||
|
// allocate more capacity?
|
||||||
|
if (nElem > capacity_)
|
||||||
|
{
|
||||||
|
// TODO: convince the compiler that division by zero does not occur
|
||||||
|
// if (SizeInc && (!SizeMult || !SizeDiv))
|
||||||
|
// {
|
||||||
|
// // resize with SizeInc as the granularity
|
||||||
|
// capacity_ = nElem;
|
||||||
|
// unsigned pad = SizeInc - (capacity_ % SizeInc);
|
||||||
|
// if (pad != SizeInc)
|
||||||
|
// {
|
||||||
|
// capacity_ += pad;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// else
|
||||||
|
{
|
||||||
|
capacity_ = max
|
||||||
|
(
|
||||||
|
nElem,
|
||||||
|
label(SizeInc + capacity_ * SizeMult / SizeDiv)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Field<T>::setSize(capacity_);
|
||||||
|
}
|
||||||
|
|
||||||
|
// adjust addressed size
|
||||||
|
Field<T>::size(nElem);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
|
||||||
|
inline void Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>::setSize
|
||||||
|
(
|
||||||
|
const label nElem,
|
||||||
|
const T& t
|
||||||
|
)
|
||||||
|
{
|
||||||
|
label nextFree = Field<T>::size();
|
||||||
|
setSize(nElem);
|
||||||
|
|
||||||
|
// set new elements to constant value
|
||||||
|
while (nextFree < nElem)
|
||||||
|
{
|
||||||
|
this->operator[](nextFree++) = t;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
|
||||||
|
inline void Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>::resize
|
||||||
|
(
|
||||||
|
const label nElem
|
||||||
|
)
|
||||||
|
{
|
||||||
|
this->setSize(nElem);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
|
||||||
|
inline void Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>::resize
|
||||||
|
(
|
||||||
|
const label nElem,
|
||||||
|
const T& t
|
||||||
|
)
|
||||||
|
{
|
||||||
|
this->setSize(nElem, t);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
|
||||||
|
inline void Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>::clear()
|
||||||
|
{
|
||||||
|
Field<T>::size(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
|
||||||
|
inline void Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>::clearStorage()
|
||||||
|
{
|
||||||
|
Field<T>::clear();
|
||||||
|
capacity_ = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
|
||||||
|
inline Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>&
|
||||||
|
Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>::shrink()
|
||||||
|
{
|
||||||
|
label nextFree = Field<T>::size();
|
||||||
|
if (capacity_ > nextFree)
|
||||||
|
{
|
||||||
|
// use the full list when resizing
|
||||||
|
Field<T>::size(capacity_);
|
||||||
|
|
||||||
|
// the new size
|
||||||
|
capacity_ = nextFree;
|
||||||
|
Field<T>::setSize(capacity_);
|
||||||
|
Field<T>::size(nextFree);
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
|
||||||
|
inline Foam::Xfer<Foam::List<T> >
|
||||||
|
Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>::xfer()
|
||||||
|
{
|
||||||
|
return xferMoveTo< List<T> >(*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
|
||||||
|
inline Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>&
|
||||||
|
Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>::append
|
||||||
|
(
|
||||||
|
const T& t
|
||||||
|
)
|
||||||
|
{
|
||||||
|
const label elemI = List<T>::size();
|
||||||
setSize(elemI + 1);
|
setSize(elemI + 1);
|
||||||
|
|
||||||
this->operator[](elemI) = t;
|
this->operator[](elemI) = t;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
|
||||||
|
inline Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>&
|
||||||
|
Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>::append
|
||||||
|
(
|
||||||
|
const UList<T>& lst
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (this == &lst)
|
||||||
|
{
|
||||||
|
FatalErrorIn
|
||||||
|
(
|
||||||
|
"DynamicField<T, SizeInc, SizeMult, SizeDiv>::append"
|
||||||
|
"(const UList<T>&)"
|
||||||
|
) << "attempted appending to self" << abort(FatalError);
|
||||||
|
}
|
||||||
|
|
||||||
|
label nextFree = List<T>::size();
|
||||||
|
setSize(nextFree + lst.size());
|
||||||
|
|
||||||
|
forAll(lst, elemI)
|
||||||
|
{
|
||||||
|
this->operator[](nextFree++) = lst[elemI];
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
|
||||||
|
inline T Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>::remove()
|
||||||
|
{
|
||||||
|
const label elemI = List<T>::size() - 1;
|
||||||
|
|
||||||
|
if (elemI < 0)
|
||||||
|
{
|
||||||
|
FatalErrorIn
|
||||||
|
(
|
||||||
|
"Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>::remove()"
|
||||||
|
) << "List is empty" << abort(FatalError);
|
||||||
|
}
|
||||||
|
|
||||||
|
const T& val = List<T>::operator[](elemI);
|
||||||
|
|
||||||
|
List<T>::size(elemI);
|
||||||
|
|
||||||
|
return val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
|
||||||
|
|
||||||
template<class Type>
|
template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
|
||||||
void Foam::DynamicField<Type>::operator=(const DynamicField<Type>& rhs)
|
inline T& Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>::operator()
|
||||||
|
(
|
||||||
|
const label elemI
|
||||||
|
)
|
||||||
{
|
{
|
||||||
if (this == &rhs)
|
if (elemI >= Field<T>::size())
|
||||||
{
|
{
|
||||||
FatalErrorIn("DynamicField<Type>::operator=(const DynamicField<Type>&)")
|
setSize(elemI + 1);
|
||||||
<< "attempted assignment to self"
|
|
||||||
<< abort(FatalError);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Field<Type>::operator=(rhs);
|
return this->operator[](elemI);
|
||||||
capacity_ = Field<Type>::size();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template<class Type>
|
template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
|
||||||
void Foam::DynamicField<Type>::operator=(const UList<Type>& rhs)
|
inline void Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>::operator=
|
||||||
|
(
|
||||||
|
const T& t
|
||||||
|
)
|
||||||
{
|
{
|
||||||
Field<Type>::operator=(rhs);
|
UList<T>::operator=(t);
|
||||||
capacity_ = Field<Type>::size();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template<class Type>
|
template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
|
||||||
void Foam::DynamicField<Type>::operator=(const tmp<DynamicField>& rhs)
|
inline void Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>::operator=
|
||||||
|
(
|
||||||
|
const DynamicField<T, SizeInc, SizeMult, SizeDiv>& lst
|
||||||
|
)
|
||||||
{
|
{
|
||||||
if (this == &(rhs()))
|
if (this == &lst)
|
||||||
{
|
{
|
||||||
FatalErrorIn("DynamicField<Type>::operator=(const tmp<DynamicField>&)")
|
FatalErrorIn
|
||||||
<< "attempted assignment to self"
|
(
|
||||||
<< abort(FatalError);
|
"DynamicField<T, SizeInc, SizeMult, SizeDiv>::operator="
|
||||||
|
"(const DynamicField<T, SizeInc, SizeMult, SizeDiv>&)"
|
||||||
|
) << "attempted assignment to self" << abort(FatalError);
|
||||||
}
|
}
|
||||||
|
|
||||||
// This is dodgy stuff, don't try it at home.
|
if (capacity_ >= lst.size())
|
||||||
DynamicField* fieldPtr = rhs.ptr();
|
{
|
||||||
List<Type>::transfer(*fieldPtr);
|
// can copy w/o reallocating, match initial size to avoid reallocation
|
||||||
delete fieldPtr;
|
Field<T>::size(lst.size());
|
||||||
capacity_ = Field<Type>::size();
|
Field<T>::operator=(lst);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// make everything available for the copy operation
|
||||||
|
Field<T>::size(capacity_);
|
||||||
|
|
||||||
|
Field<T>::operator=(lst);
|
||||||
|
capacity_ = Field<T>::size();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * IOstream Operator * * * * * * * * * * * * * //
|
template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
|
||||||
|
inline void Foam::DynamicField<T, SizeInc, SizeMult, SizeDiv>::operator=
|
||||||
|
(
|
||||||
|
const UList<T>& lst
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (capacity_ >= lst.size())
|
||||||
|
{
|
||||||
|
// can copy w/o reallocating, match initial size to avoid reallocation
|
||||||
|
Field<T>::size(lst.size());
|
||||||
|
Field<T>::operator=(lst);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// make everything available for the copy operation
|
||||||
|
Field<T>::size(capacity_);
|
||||||
|
|
||||||
|
Field<T>::operator=(lst);
|
||||||
|
capacity_ = Field<T>::size();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
// ************************************************************************* //
|
||||||
|
|||||||
@ -287,6 +287,7 @@ $(ddtSchemes)/steadyStateDdtScheme/steadyStateDdtSchemes.C
|
|||||||
$(ddtSchemes)/EulerDdtScheme/EulerDdtSchemes.C
|
$(ddtSchemes)/EulerDdtScheme/EulerDdtSchemes.C
|
||||||
$(ddtSchemes)/CoEulerDdtScheme/CoEulerDdtSchemes.C
|
$(ddtSchemes)/CoEulerDdtScheme/CoEulerDdtSchemes.C
|
||||||
$(ddtSchemes)/SLTSDdtScheme/SLTSDdtSchemes.C
|
$(ddtSchemes)/SLTSDdtScheme/SLTSDdtSchemes.C
|
||||||
|
$(ddtSchemes)/localEulerDdtScheme/localEulerDdtSchemes.C
|
||||||
$(ddtSchemes)/backwardDdtScheme/backwardDdtSchemes.C
|
$(ddtSchemes)/backwardDdtScheme/backwardDdtSchemes.C
|
||||||
$(ddtSchemes)/boundedBackwardDdtScheme/boundedBackwardDdtScheme.C
|
$(ddtSchemes)/boundedBackwardDdtScheme/boundedBackwardDdtScheme.C
|
||||||
$(ddtSchemes)/boundedBackwardDdtScheme/boundedBackwardDdtSchemes.C
|
$(ddtSchemes)/boundedBackwardDdtScheme/boundedBackwardDdtSchemes.C
|
||||||
@ -337,6 +338,7 @@ $(laplacianSchemes)/laplacianScheme/laplacianSchemes.C
|
|||||||
$(laplacianSchemes)/gaussLaplacianScheme/gaussLaplacianSchemes.C
|
$(laplacianSchemes)/gaussLaplacianScheme/gaussLaplacianSchemes.C
|
||||||
|
|
||||||
finiteVolume/fvc/fvcMeshPhi.C
|
finiteVolume/fvc/fvcMeshPhi.C
|
||||||
|
finiteVolume/fvc/fvcSmooth/fvcSmooth.C
|
||||||
|
|
||||||
general = cfdTools/general
|
general = cfdTools/general
|
||||||
$(general)/findRefCell/findRefCell.C
|
$(general)/findRefCell/findRefCell.C
|
||||||
|
|||||||
@ -0,0 +1,584 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | Copyright (C) 1991-2010 OpenCFD Ltd.
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
License
|
||||||
|
This file is part of OpenFOAM.
|
||||||
|
|
||||||
|
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 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/>.
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#include "localEulerDdtScheme.H"
|
||||||
|
#include "surfaceInterpolate.H"
|
||||||
|
#include "fvMatrices.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace fv
|
||||||
|
{
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
template<class Type>
|
||||||
|
const volScalarField& localEulerDdtScheme<Type>::localRDeltaT() const
|
||||||
|
{
|
||||||
|
return mesh().objectRegistry::lookupObject<volScalarField>(rDeltaTName_);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class Type>
|
||||||
|
tmp<GeometricField<Type, fvPatchField, volMesh> >
|
||||||
|
localEulerDdtScheme<Type>::fvcDdt
|
||||||
|
(
|
||||||
|
const dimensioned<Type>& dt
|
||||||
|
)
|
||||||
|
{
|
||||||
|
const volScalarField& rDeltaT = localRDeltaT();
|
||||||
|
|
||||||
|
IOobject ddtIOobject
|
||||||
|
(
|
||||||
|
"ddt(" + dt.name() + ')',
|
||||||
|
mesh().time().timeName(),
|
||||||
|
mesh()
|
||||||
|
);
|
||||||
|
|
||||||
|
if (mesh().moving())
|
||||||
|
{
|
||||||
|
tmp<GeometricField<Type, fvPatchField, volMesh> > tdtdt
|
||||||
|
(
|
||||||
|
new GeometricField<Type, fvPatchField, volMesh>
|
||||||
|
(
|
||||||
|
ddtIOobject,
|
||||||
|
mesh(),
|
||||||
|
dimensioned<Type>
|
||||||
|
(
|
||||||
|
"0",
|
||||||
|
dt.dimensions()/dimTime,
|
||||||
|
pTraits<Type>::zero
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
tdtdt().internalField() =
|
||||||
|
rDeltaT.internalField()*dt.value()*(1.0 - mesh().V0()/mesh().V());
|
||||||
|
|
||||||
|
return tdtdt;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return tmp<GeometricField<Type, fvPatchField, volMesh> >
|
||||||
|
(
|
||||||
|
new GeometricField<Type, fvPatchField, volMesh>
|
||||||
|
(
|
||||||
|
ddtIOobject,
|
||||||
|
mesh(),
|
||||||
|
dimensioned<Type>
|
||||||
|
(
|
||||||
|
"0",
|
||||||
|
dt.dimensions()/dimTime,
|
||||||
|
pTraits<Type>::zero
|
||||||
|
),
|
||||||
|
calculatedFvPatchField<Type>::typeName
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class Type>
|
||||||
|
tmp<GeometricField<Type, fvPatchField, volMesh> >
|
||||||
|
localEulerDdtScheme<Type>::fvcDdt
|
||||||
|
(
|
||||||
|
const GeometricField<Type, fvPatchField, volMesh>& vf
|
||||||
|
)
|
||||||
|
{
|
||||||
|
const volScalarField& rDeltaT = localRDeltaT();
|
||||||
|
|
||||||
|
IOobject ddtIOobject
|
||||||
|
(
|
||||||
|
"ddt(" + vf.name() + ')',
|
||||||
|
mesh().time().timeName(),
|
||||||
|
mesh()
|
||||||
|
);
|
||||||
|
|
||||||
|
if (mesh().moving())
|
||||||
|
{
|
||||||
|
return tmp<GeometricField<Type, fvPatchField, volMesh> >
|
||||||
|
(
|
||||||
|
new GeometricField<Type, fvPatchField, volMesh>
|
||||||
|
(
|
||||||
|
ddtIOobject,
|
||||||
|
mesh(),
|
||||||
|
rDeltaT.dimensions()*vf.dimensions(),
|
||||||
|
rDeltaT.internalField()*
|
||||||
|
(
|
||||||
|
vf.internalField()
|
||||||
|
- vf.oldTime().internalField()*mesh().V0()/mesh().V()
|
||||||
|
),
|
||||||
|
rDeltaT.boundaryField()*
|
||||||
|
(
|
||||||
|
vf.boundaryField() - vf.oldTime().boundaryField()
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return tmp<GeometricField<Type, fvPatchField, volMesh> >
|
||||||
|
(
|
||||||
|
new GeometricField<Type, fvPatchField, volMesh>
|
||||||
|
(
|
||||||
|
ddtIOobject,
|
||||||
|
rDeltaT*(vf - vf.oldTime())
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class Type>
|
||||||
|
tmp<GeometricField<Type, fvPatchField, volMesh> >
|
||||||
|
localEulerDdtScheme<Type>::fvcDdt
|
||||||
|
(
|
||||||
|
const dimensionedScalar& rho,
|
||||||
|
const GeometricField<Type, fvPatchField, volMesh>& vf
|
||||||
|
)
|
||||||
|
{
|
||||||
|
const volScalarField& rDeltaT = localRDeltaT();
|
||||||
|
|
||||||
|
IOobject ddtIOobject
|
||||||
|
(
|
||||||
|
"ddt(" + rho.name() + ',' + vf.name() + ')',
|
||||||
|
mesh().time().timeName(),
|
||||||
|
mesh()
|
||||||
|
);
|
||||||
|
|
||||||
|
if (mesh().moving())
|
||||||
|
{
|
||||||
|
return tmp<GeometricField<Type, fvPatchField, volMesh> >
|
||||||
|
(
|
||||||
|
new GeometricField<Type, fvPatchField, volMesh>
|
||||||
|
(
|
||||||
|
ddtIOobject,
|
||||||
|
mesh(),
|
||||||
|
rDeltaT.dimensions()*rho.dimensions()*vf.dimensions(),
|
||||||
|
rDeltaT.internalField()*rho.value()*
|
||||||
|
(
|
||||||
|
vf.internalField()
|
||||||
|
- vf.oldTime().internalField()*mesh().V0()/mesh().V()
|
||||||
|
),
|
||||||
|
rDeltaT.boundaryField()*rho.value()*
|
||||||
|
(
|
||||||
|
vf.boundaryField() - vf.oldTime().boundaryField()
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return tmp<GeometricField<Type, fvPatchField, volMesh> >
|
||||||
|
(
|
||||||
|
new GeometricField<Type, fvPatchField, volMesh>
|
||||||
|
(
|
||||||
|
ddtIOobject,
|
||||||
|
rDeltaT*rho*(vf - vf.oldTime())
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class Type>
|
||||||
|
tmp<GeometricField<Type, fvPatchField, volMesh> >
|
||||||
|
localEulerDdtScheme<Type>::fvcDdt
|
||||||
|
(
|
||||||
|
const volScalarField& rho,
|
||||||
|
const GeometricField<Type, fvPatchField, volMesh>& vf
|
||||||
|
)
|
||||||
|
{
|
||||||
|
const volScalarField& rDeltaT = localRDeltaT();
|
||||||
|
|
||||||
|
IOobject ddtIOobject
|
||||||
|
(
|
||||||
|
"ddt(" + rho.name() + ',' + vf.name() + ')',
|
||||||
|
mesh().time().timeName(),
|
||||||
|
mesh()
|
||||||
|
);
|
||||||
|
|
||||||
|
if (mesh().moving())
|
||||||
|
{
|
||||||
|
return tmp<GeometricField<Type, fvPatchField, volMesh> >
|
||||||
|
(
|
||||||
|
new GeometricField<Type, fvPatchField, volMesh>
|
||||||
|
(
|
||||||
|
ddtIOobject,
|
||||||
|
mesh(),
|
||||||
|
rDeltaT.dimensions()*rho.dimensions()*vf.dimensions(),
|
||||||
|
rDeltaT.internalField()*
|
||||||
|
(
|
||||||
|
rho.internalField()*vf.internalField()
|
||||||
|
- rho.oldTime().internalField()
|
||||||
|
*vf.oldTime().internalField()*mesh().V0()/mesh().V()
|
||||||
|
),
|
||||||
|
rDeltaT.boundaryField()*
|
||||||
|
(
|
||||||
|
rho.boundaryField()*vf.boundaryField()
|
||||||
|
- rho.oldTime().boundaryField()
|
||||||
|
*vf.oldTime().boundaryField()
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return tmp<GeometricField<Type, fvPatchField, volMesh> >
|
||||||
|
(
|
||||||
|
new GeometricField<Type, fvPatchField, volMesh>
|
||||||
|
(
|
||||||
|
ddtIOobject,
|
||||||
|
rDeltaT*(rho*vf - rho.oldTime()*vf.oldTime())
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class Type>
|
||||||
|
tmp<fvMatrix<Type> >
|
||||||
|
localEulerDdtScheme<Type>::fvmDdt
|
||||||
|
(
|
||||||
|
const GeometricField<Type, fvPatchField, volMesh>& vf
|
||||||
|
)
|
||||||
|
{
|
||||||
|
tmp<fvMatrix<Type> > tfvm
|
||||||
|
(
|
||||||
|
new fvMatrix<Type>
|
||||||
|
(
|
||||||
|
vf,
|
||||||
|
vf.dimensions()*dimVol/dimTime
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
fvMatrix<Type>& fvm = tfvm();
|
||||||
|
|
||||||
|
const scalarField& rDeltaT = localRDeltaT().internalField();
|
||||||
|
|
||||||
|
fvm.diag() = rDeltaT*mesh().V();
|
||||||
|
|
||||||
|
if (mesh().moving())
|
||||||
|
{
|
||||||
|
fvm.source() = rDeltaT*vf.oldTime().internalField()*mesh().V0();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fvm.source() = rDeltaT*vf.oldTime().internalField()*mesh().V();
|
||||||
|
}
|
||||||
|
|
||||||
|
return tfvm;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class Type>
|
||||||
|
tmp<fvMatrix<Type> >
|
||||||
|
localEulerDdtScheme<Type>::fvmDdt
|
||||||
|
(
|
||||||
|
const dimensionedScalar& rho,
|
||||||
|
const GeometricField<Type, fvPatchField, volMesh>& vf
|
||||||
|
)
|
||||||
|
{
|
||||||
|
tmp<fvMatrix<Type> > tfvm
|
||||||
|
(
|
||||||
|
new fvMatrix<Type>
|
||||||
|
(
|
||||||
|
vf,
|
||||||
|
rho.dimensions()*vf.dimensions()*dimVol/dimTime
|
||||||
|
)
|
||||||
|
);
|
||||||
|
fvMatrix<Type>& fvm = tfvm();
|
||||||
|
|
||||||
|
const scalarField& rDeltaT = localRDeltaT().internalField();
|
||||||
|
|
||||||
|
fvm.diag() = rDeltaT*rho.value()*mesh().V();
|
||||||
|
|
||||||
|
if (mesh().moving())
|
||||||
|
{
|
||||||
|
fvm.source() = rDeltaT
|
||||||
|
*rho.value()*vf.oldTime().internalField()*mesh().V0();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fvm.source() = rDeltaT
|
||||||
|
*rho.value()*vf.oldTime().internalField()*mesh().V();
|
||||||
|
}
|
||||||
|
|
||||||
|
return tfvm;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class Type>
|
||||||
|
tmp<fvMatrix<Type> >
|
||||||
|
localEulerDdtScheme<Type>::fvmDdt
|
||||||
|
(
|
||||||
|
const volScalarField& rho,
|
||||||
|
const GeometricField<Type, fvPatchField, volMesh>& vf
|
||||||
|
)
|
||||||
|
{
|
||||||
|
tmp<fvMatrix<Type> > tfvm
|
||||||
|
(
|
||||||
|
new fvMatrix<Type>
|
||||||
|
(
|
||||||
|
vf,
|
||||||
|
rho.dimensions()*vf.dimensions()*dimVol/dimTime
|
||||||
|
)
|
||||||
|
);
|
||||||
|
fvMatrix<Type>& fvm = tfvm();
|
||||||
|
|
||||||
|
const scalarField& rDeltaT = localRDeltaT().internalField();
|
||||||
|
|
||||||
|
fvm.diag() = rDeltaT*rho.internalField()*mesh().V();
|
||||||
|
|
||||||
|
if (mesh().moving())
|
||||||
|
{
|
||||||
|
fvm.source() = rDeltaT
|
||||||
|
*rho.oldTime().internalField()
|
||||||
|
*vf.oldTime().internalField()*mesh().V0();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fvm.source() = rDeltaT
|
||||||
|
*rho.oldTime().internalField()
|
||||||
|
*vf.oldTime().internalField()*mesh().V();
|
||||||
|
}
|
||||||
|
|
||||||
|
return tfvm;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class Type>
|
||||||
|
tmp<typename localEulerDdtScheme<Type>::fluxFieldType>
|
||||||
|
localEulerDdtScheme<Type>::fvcDdtPhiCorr
|
||||||
|
(
|
||||||
|
const volScalarField& rA,
|
||||||
|
const GeometricField<Type, fvPatchField, volMesh>& U,
|
||||||
|
const fluxFieldType& phi
|
||||||
|
)
|
||||||
|
{
|
||||||
|
IOobject ddtIOobject
|
||||||
|
(
|
||||||
|
"ddtPhiCorr(" + rA.name() + ',' + U.name() + ',' + phi.name() + ')',
|
||||||
|
mesh().time().timeName(),
|
||||||
|
mesh()
|
||||||
|
);
|
||||||
|
|
||||||
|
if (mesh().moving())
|
||||||
|
{
|
||||||
|
return tmp<fluxFieldType>
|
||||||
|
(
|
||||||
|
new fluxFieldType
|
||||||
|
(
|
||||||
|
ddtIOobject,
|
||||||
|
mesh(),
|
||||||
|
dimensioned<typename flux<Type>::type>
|
||||||
|
(
|
||||||
|
"0",
|
||||||
|
rA.dimensions()*phi.dimensions()/dimTime,
|
||||||
|
pTraits<typename flux<Type>::type>::zero
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
const volScalarField& rDeltaT = localRDeltaT();
|
||||||
|
|
||||||
|
return tmp<fluxFieldType>
|
||||||
|
(
|
||||||
|
new fluxFieldType
|
||||||
|
(
|
||||||
|
ddtIOobject,
|
||||||
|
fvcDdtPhiCoeff(U.oldTime(), phi.oldTime())*
|
||||||
|
(
|
||||||
|
fvc::interpolate(rDeltaT*rA)*phi.oldTime()
|
||||||
|
- (fvc::interpolate(rDeltaT*rA*U.oldTime()) & mesh().Sf())
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class Type>
|
||||||
|
tmp<typename localEulerDdtScheme<Type>::fluxFieldType>
|
||||||
|
localEulerDdtScheme<Type>::fvcDdtPhiCorr
|
||||||
|
(
|
||||||
|
const volScalarField& rA,
|
||||||
|
const volScalarField& rho,
|
||||||
|
const GeometricField<Type, fvPatchField, volMesh>& U,
|
||||||
|
const fluxFieldType& phi
|
||||||
|
)
|
||||||
|
{
|
||||||
|
IOobject ddtIOobject
|
||||||
|
(
|
||||||
|
"ddtPhiCorr("
|
||||||
|
+ rA.name() + ',' + rho.name() + ',' + U.name() + ',' + phi.name() + ')',
|
||||||
|
mesh().time().timeName(),
|
||||||
|
mesh()
|
||||||
|
);
|
||||||
|
|
||||||
|
if (mesh().moving())
|
||||||
|
{
|
||||||
|
return tmp<fluxFieldType>
|
||||||
|
(
|
||||||
|
new fluxFieldType
|
||||||
|
(
|
||||||
|
ddtIOobject,
|
||||||
|
mesh(),
|
||||||
|
dimensioned<typename flux<Type>::type>
|
||||||
|
(
|
||||||
|
"0",
|
||||||
|
rA.dimensions()*rho.dimensions()*phi.dimensions()/dimTime,
|
||||||
|
pTraits<typename flux<Type>::type>::zero
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
const volScalarField& rDeltaT = localRDeltaT();
|
||||||
|
|
||||||
|
if
|
||||||
|
(
|
||||||
|
U.dimensions() == dimVelocity
|
||||||
|
&& phi.dimensions() == dimVelocity*dimArea
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return tmp<fluxFieldType>
|
||||||
|
(
|
||||||
|
new fluxFieldType
|
||||||
|
(
|
||||||
|
ddtIOobject,
|
||||||
|
fvcDdtPhiCoeff(U.oldTime(), phi.oldTime())
|
||||||
|
*(
|
||||||
|
fvc::interpolate(rDeltaT*rA*rho.oldTime())*phi.oldTime()
|
||||||
|
- (fvc::interpolate(rDeltaT*rA*rho.oldTime()*U.oldTime())
|
||||||
|
& mesh().Sf())
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else if
|
||||||
|
(
|
||||||
|
U.dimensions() == dimVelocity
|
||||||
|
&& phi.dimensions() == dimDensity*dimVelocity*dimArea
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return tmp<fluxFieldType>
|
||||||
|
(
|
||||||
|
new fluxFieldType
|
||||||
|
(
|
||||||
|
ddtIOobject,
|
||||||
|
fvcDdtPhiCoeff
|
||||||
|
(
|
||||||
|
U.oldTime(),
|
||||||
|
phi.oldTime()/fvc::interpolate(rho.oldTime())
|
||||||
|
)
|
||||||
|
*(
|
||||||
|
fvc::interpolate(rDeltaT*rA*rho.oldTime())
|
||||||
|
*phi.oldTime()/fvc::interpolate(rho.oldTime())
|
||||||
|
- (
|
||||||
|
fvc::interpolate
|
||||||
|
(
|
||||||
|
rDeltaT*rA*rho.oldTime()*U.oldTime()
|
||||||
|
) & mesh().Sf()
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else if
|
||||||
|
(
|
||||||
|
U.dimensions() == dimDensity*dimVelocity
|
||||||
|
&& phi.dimensions() == dimDensity*dimVelocity*dimArea
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return tmp<fluxFieldType>
|
||||||
|
(
|
||||||
|
new fluxFieldType
|
||||||
|
(
|
||||||
|
ddtIOobject,
|
||||||
|
fvcDdtPhiCoeff(rho.oldTime(), U.oldTime(), phi.oldTime())
|
||||||
|
*(
|
||||||
|
fvc::interpolate(rDeltaT*rA)*phi.oldTime()
|
||||||
|
- (
|
||||||
|
fvc::interpolate(rDeltaT*rA*U.oldTime())&mesh().Sf()
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
FatalErrorIn
|
||||||
|
(
|
||||||
|
"localEulerDdtScheme<Type>::fvcDdtPhiCorr"
|
||||||
|
) << "dimensions of phi are not correct"
|
||||||
|
<< abort(FatalError);
|
||||||
|
|
||||||
|
return fluxFieldType::null();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class Type>
|
||||||
|
tmp<surfaceScalarField> localEulerDdtScheme<Type>::meshPhi
|
||||||
|
(
|
||||||
|
const GeometricField<Type, fvPatchField, volMesh>&
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return tmp<surfaceScalarField>
|
||||||
|
(
|
||||||
|
new surfaceScalarField
|
||||||
|
(
|
||||||
|
IOobject
|
||||||
|
(
|
||||||
|
"meshPhi",
|
||||||
|
mesh().time().timeName(),
|
||||||
|
mesh()
|
||||||
|
),
|
||||||
|
mesh(),
|
||||||
|
dimensionedScalar("0", dimVolume/dimTime, 0.0)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
} // End namespace fv
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
} // End namespace Foam
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -0,0 +1,210 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | Copyright (C) 1991-2010 OpenCFD Ltd.
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
License
|
||||||
|
This file is part of OpenFOAM.
|
||||||
|
|
||||||
|
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 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/>.
|
||||||
|
|
||||||
|
Class
|
||||||
|
Foam::fv::localEulerDdtScheme
|
||||||
|
|
||||||
|
Description
|
||||||
|
Local time-step first-order Euler implicit/explicit ddt.
|
||||||
|
The reciprocal of the local time-step field is looked-up from the
|
||||||
|
database with the name provided.
|
||||||
|
|
||||||
|
This scheme should only be used for steady-state computations
|
||||||
|
using transient codes where local time-stepping is preferably to
|
||||||
|
under-relaxation for transport consistency reasons.
|
||||||
|
|
||||||
|
See also CoEulerDdtScheme.
|
||||||
|
|
||||||
|
SourceFiles
|
||||||
|
localEulerDdtScheme.C
|
||||||
|
localEulerDdtSchemes.C
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef localEulerDdtScheme_H
|
||||||
|
#define localEulerDdtScheme_H
|
||||||
|
|
||||||
|
#include "ddtScheme.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace fv
|
||||||
|
{
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
Class localEulerDdtScheme Declaration
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
template<class Type>
|
||||||
|
class localEulerDdtScheme
|
||||||
|
:
|
||||||
|
public fv::ddtScheme<Type>
|
||||||
|
{
|
||||||
|
// Private Data
|
||||||
|
|
||||||
|
//- Name of the reciprocal local time-step field
|
||||||
|
word rDeltaTName_;
|
||||||
|
|
||||||
|
|
||||||
|
// Private Member Functions
|
||||||
|
|
||||||
|
//- Disallow default bitwise copy construct
|
||||||
|
localEulerDdtScheme(const localEulerDdtScheme&);
|
||||||
|
|
||||||
|
//- Disallow default bitwise assignment
|
||||||
|
void operator=(const localEulerDdtScheme&);
|
||||||
|
|
||||||
|
//- Return the reciprocal of the local time-step
|
||||||
|
const volScalarField& localRDeltaT() const;
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
//- Runtime type information
|
||||||
|
TypeName("localEuler");
|
||||||
|
|
||||||
|
|
||||||
|
// Constructors
|
||||||
|
|
||||||
|
//- Construct from mesh and Istream
|
||||||
|
localEulerDdtScheme(const fvMesh& mesh, Istream& is)
|
||||||
|
:
|
||||||
|
ddtScheme<Type>(mesh, is),
|
||||||
|
rDeltaTName_(is)
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
// Member Functions
|
||||||
|
|
||||||
|
//- Return mesh reference
|
||||||
|
const fvMesh& mesh() const
|
||||||
|
{
|
||||||
|
return fv::ddtScheme<Type>::mesh();
|
||||||
|
}
|
||||||
|
|
||||||
|
tmp<GeometricField<Type, fvPatchField, volMesh> > fvcDdt
|
||||||
|
(
|
||||||
|
const dimensioned<Type>&
|
||||||
|
);
|
||||||
|
|
||||||
|
tmp<GeometricField<Type, fvPatchField, volMesh> > fvcDdt
|
||||||
|
(
|
||||||
|
const GeometricField<Type, fvPatchField, volMesh>&
|
||||||
|
);
|
||||||
|
|
||||||
|
tmp<GeometricField<Type, fvPatchField, volMesh> > fvcDdt
|
||||||
|
(
|
||||||
|
const dimensionedScalar&,
|
||||||
|
const GeometricField<Type, fvPatchField, volMesh>&
|
||||||
|
);
|
||||||
|
|
||||||
|
tmp<GeometricField<Type, fvPatchField, volMesh> > fvcDdt
|
||||||
|
(
|
||||||
|
const volScalarField&,
|
||||||
|
const GeometricField<Type, fvPatchField, volMesh>&
|
||||||
|
);
|
||||||
|
|
||||||
|
tmp<fvMatrix<Type> > fvmDdt
|
||||||
|
(
|
||||||
|
const GeometricField<Type, fvPatchField, volMesh>&
|
||||||
|
);
|
||||||
|
|
||||||
|
tmp<fvMatrix<Type> > fvmDdt
|
||||||
|
(
|
||||||
|
const dimensionedScalar&,
|
||||||
|
const GeometricField<Type, fvPatchField, volMesh>&
|
||||||
|
);
|
||||||
|
|
||||||
|
tmp<fvMatrix<Type> > fvmDdt
|
||||||
|
(
|
||||||
|
const volScalarField&,
|
||||||
|
const GeometricField<Type, fvPatchField, volMesh>&
|
||||||
|
);
|
||||||
|
|
||||||
|
typedef typename ddtScheme<Type>::fluxFieldType fluxFieldType;
|
||||||
|
|
||||||
|
tmp<fluxFieldType> fvcDdtPhiCorr
|
||||||
|
(
|
||||||
|
const volScalarField& rA,
|
||||||
|
const GeometricField<Type, fvPatchField, volMesh>& U,
|
||||||
|
const fluxFieldType& phi
|
||||||
|
);
|
||||||
|
|
||||||
|
tmp<fluxFieldType> fvcDdtPhiCorr
|
||||||
|
(
|
||||||
|
const volScalarField& rA,
|
||||||
|
const volScalarField& rho,
|
||||||
|
const GeometricField<Type, fvPatchField, volMesh>& U,
|
||||||
|
const fluxFieldType& phi
|
||||||
|
);
|
||||||
|
|
||||||
|
tmp<surfaceScalarField> meshPhi
|
||||||
|
(
|
||||||
|
const GeometricField<Type, fvPatchField, volMesh>&
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
template<>
|
||||||
|
tmp<surfaceScalarField> localEulerDdtScheme<scalar>::fvcDdtPhiCorr
|
||||||
|
(
|
||||||
|
const volScalarField& rA,
|
||||||
|
const volScalarField& U,
|
||||||
|
const surfaceScalarField& phi
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
template<>
|
||||||
|
tmp<surfaceScalarField> localEulerDdtScheme<scalar>::fvcDdtPhiCorr
|
||||||
|
(
|
||||||
|
const volScalarField& rA,
|
||||||
|
const volScalarField& rho,
|
||||||
|
const volScalarField& U,
|
||||||
|
const surfaceScalarField& phi
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
} // End namespace fv
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
} // End namespace Foam
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
#ifdef NoRepository
|
||||||
|
# include "localEulerDdtScheme.C"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -21,28 +21,19 @@ License
|
|||||||
You should have received a copy of the GNU General Public License
|
You should have received a copy of the GNU General Public License
|
||||||
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
Description
|
|
||||||
Calculates and outputs the mean and maximum Courant Numbers for the fluid
|
|
||||||
regions
|
|
||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
#ifndef compressibleCourantNo_H
|
#include "localEulerDdtScheme.H"
|
||||||
#define compressibleCourantNo_H
|
|
||||||
|
|
||||||
#include "fvMesh.H"
|
#include "fvMesh.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
namespace Foam
|
namespace Foam
|
||||||
{
|
{
|
||||||
scalar compressibleCourantNo
|
namespace fv
|
||||||
(
|
{
|
||||||
const fvMesh& mesh,
|
makeFvDdtScheme(localEulerDdtScheme)
|
||||||
const Time& runTime,
|
}
|
||||||
const volScalarField& rho,
|
|
||||||
const surfaceScalarField& phi
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
// ************************************************************************* //
|
||||||
324
src/finiteVolume/finiteVolume/fvc/fvcSmooth/fvcSmooth.C
Normal file
324
src/finiteVolume/finiteVolume/fvc/fvcSmooth/fvcSmooth.C
Normal file
@ -0,0 +1,324 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | Copyright (C) 2010-2010 OpenCFD Ltd.
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
License
|
||||||
|
This file is part of OpenFOAM.
|
||||||
|
|
||||||
|
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 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/>.
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#include "fvcSmooth.H"
|
||||||
|
#include "volFields.H"
|
||||||
|
#include "FaceCellWave.H"
|
||||||
|
#include "smoothData.H"
|
||||||
|
#include "sweepData.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Foam::scalar Foam::smoothData::maxRatio = 1.0;
|
||||||
|
|
||||||
|
void Foam::fvc::smooth
|
||||||
|
(
|
||||||
|
volScalarField& field,
|
||||||
|
const scalar coeff
|
||||||
|
)
|
||||||
|
{
|
||||||
|
const fvMesh& mesh = field.mesh();
|
||||||
|
smoothData::maxRatio = 1 + coeff;
|
||||||
|
|
||||||
|
DynamicList<label> changedFaces(mesh.nFaces()/100 + 100);
|
||||||
|
DynamicList<smoothData> changedFacesInfo(changedFaces.size());
|
||||||
|
|
||||||
|
const unallocLabelList& owner = mesh.owner();
|
||||||
|
const unallocLabelList& neighbour = mesh.neighbour();
|
||||||
|
|
||||||
|
forAll(owner, facei)
|
||||||
|
{
|
||||||
|
const label own = owner[facei];
|
||||||
|
const label nbr = neighbour[facei];
|
||||||
|
|
||||||
|
// Check if owner value much larger than neighbour value or vice versa
|
||||||
|
if (field[own] > smoothData::maxRatio*field[nbr])
|
||||||
|
{
|
||||||
|
changedFaces.append(facei);
|
||||||
|
changedFacesInfo.append(smoothData(field[own]));
|
||||||
|
}
|
||||||
|
else if (field[nbr] > smoothData::maxRatio*field[own])
|
||||||
|
{
|
||||||
|
changedFaces.append(facei);
|
||||||
|
changedFacesInfo.append(smoothData(field[nbr]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Insert all faces of coupled patches - FaceCellWave will correct them
|
||||||
|
forAll(mesh.boundaryMesh(), patchi)
|
||||||
|
{
|
||||||
|
const polyPatch& patch = mesh.boundaryMesh()[patchi];
|
||||||
|
|
||||||
|
if (patch.coupled())
|
||||||
|
{
|
||||||
|
forAll(patch, patchFacei)
|
||||||
|
{
|
||||||
|
label facei = patch.start() + patchFacei;
|
||||||
|
label own = mesh.faceOwner()[facei];
|
||||||
|
|
||||||
|
changedFaces.append(facei);
|
||||||
|
changedFacesInfo.append(smoothData(field[own]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
changedFaces.shrink();
|
||||||
|
changedFacesInfo.shrink();
|
||||||
|
|
||||||
|
// Set initial field on cells
|
||||||
|
List<smoothData> cellData(mesh.nCells());
|
||||||
|
|
||||||
|
forAll(field, celli)
|
||||||
|
{
|
||||||
|
cellData[celli] = field[celli];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set initial field on faces
|
||||||
|
List<smoothData> faceData(mesh.nFaces());
|
||||||
|
|
||||||
|
|
||||||
|
// Propagate information over whole domain
|
||||||
|
FaceCellWave<smoothData > smoothData
|
||||||
|
(
|
||||||
|
mesh,
|
||||||
|
changedFaces,
|
||||||
|
changedFacesInfo,
|
||||||
|
faceData,
|
||||||
|
cellData,
|
||||||
|
mesh.globalData().nTotalCells() // max iterations
|
||||||
|
);
|
||||||
|
|
||||||
|
forAll(field, celli)
|
||||||
|
{
|
||||||
|
field[celli] = cellData[celli].value();
|
||||||
|
}
|
||||||
|
|
||||||
|
field.correctBoundaryConditions();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::fvc::spread
|
||||||
|
(
|
||||||
|
volScalarField& field,
|
||||||
|
const volScalarField& alpha,
|
||||||
|
const label nLayers,
|
||||||
|
const scalar alphaDiff,
|
||||||
|
const scalar alphaMax,
|
||||||
|
const scalar alphaMin
|
||||||
|
)
|
||||||
|
{
|
||||||
|
const fvMesh& mesh = field.mesh();
|
||||||
|
smoothData::maxRatio = 1;
|
||||||
|
|
||||||
|
DynamicList<label> changedFaces(mesh.nFaces()/100 + 100);
|
||||||
|
DynamicList<smoothData> changedFacesInfo(changedFaces.size());
|
||||||
|
|
||||||
|
// Set initial field on cells
|
||||||
|
List<smoothData> cellData(mesh.nCells());
|
||||||
|
|
||||||
|
forAll(field, celli)
|
||||||
|
{
|
||||||
|
cellData[celli] = field[celli];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set initial field on faces
|
||||||
|
List<smoothData> faceData(mesh.nFaces());
|
||||||
|
|
||||||
|
const unallocLabelList& owner = mesh.owner();
|
||||||
|
const unallocLabelList& neighbour = mesh.neighbour();
|
||||||
|
|
||||||
|
forAll(owner, facei)
|
||||||
|
{
|
||||||
|
const label own = owner[facei];
|
||||||
|
const label nbr = neighbour[facei];
|
||||||
|
|
||||||
|
if
|
||||||
|
(
|
||||||
|
(alpha[own] > alphaMin && alpha[own] < alphaMax)
|
||||||
|
|| (alpha[nbr] > alphaMin && alpha[nbr] < alphaMax)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (mag(alpha[own] - alpha[nbr]) > alphaDiff)
|
||||||
|
{
|
||||||
|
changedFaces.append(facei);
|
||||||
|
changedFacesInfo.append
|
||||||
|
(
|
||||||
|
smoothData(max(field[own], field[nbr]))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Insert all faces of coupled patches - FaceCellWave will correct them
|
||||||
|
forAll(mesh.boundaryMesh(), patchi)
|
||||||
|
{
|
||||||
|
const polyPatch& patch = mesh.boundaryMesh()[patchi];
|
||||||
|
|
||||||
|
if (patch.coupled())
|
||||||
|
{
|
||||||
|
forAll(patch, patchFacei)
|
||||||
|
{
|
||||||
|
label facei = patch.start() + patchFacei;
|
||||||
|
label own = mesh.faceOwner()[facei];
|
||||||
|
|
||||||
|
scalarField alphapn =
|
||||||
|
alpha.boundaryField()[patchi].patchNeighbourField();
|
||||||
|
|
||||||
|
if
|
||||||
|
(
|
||||||
|
(alpha[own] > alphaMin && alpha[own] < alphaMax)
|
||||||
|
|| (
|
||||||
|
alphapn[patchFacei] > alphaMin
|
||||||
|
&& alphapn[patchFacei] < alphaMax
|
||||||
|
)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (mag(alpha[own] - alphapn[patchFacei]) > alphaDiff)
|
||||||
|
{
|
||||||
|
changedFaces.append(facei);
|
||||||
|
changedFacesInfo.append(smoothData(field[own]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
changedFaces.shrink();
|
||||||
|
changedFacesInfo.shrink();
|
||||||
|
|
||||||
|
// Propagate information over whole domain
|
||||||
|
FaceCellWave<smoothData> smoothData
|
||||||
|
(
|
||||||
|
mesh,
|
||||||
|
faceData,
|
||||||
|
cellData
|
||||||
|
);
|
||||||
|
|
||||||
|
smoothData.setFaceInfo(changedFaces, changedFacesInfo);
|
||||||
|
|
||||||
|
smoothData.iterate(nLayers);
|
||||||
|
|
||||||
|
forAll(field, celli)
|
||||||
|
{
|
||||||
|
field[celli] = cellData[celli].value();
|
||||||
|
}
|
||||||
|
|
||||||
|
field.correctBoundaryConditions();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::fvc::sweep
|
||||||
|
(
|
||||||
|
volScalarField& field,
|
||||||
|
const volScalarField& alpha,
|
||||||
|
const label nLayers,
|
||||||
|
const scalar alphaDiff
|
||||||
|
)
|
||||||
|
{
|
||||||
|
const fvMesh& mesh = field.mesh();
|
||||||
|
|
||||||
|
DynamicList<label> changedFaces(mesh.nFaces()/100 + 100);
|
||||||
|
DynamicList<sweepData> changedFacesInfo(changedFaces.size());
|
||||||
|
|
||||||
|
// Set initial field on cells
|
||||||
|
List<sweepData> cellData(mesh.nCells());
|
||||||
|
|
||||||
|
// Set initial field on faces
|
||||||
|
List<sweepData> faceData(mesh.nFaces());
|
||||||
|
|
||||||
|
const unallocLabelList& owner = mesh.owner();
|
||||||
|
const unallocLabelList& neighbour = mesh.neighbour();
|
||||||
|
const vectorField& Cf = mesh.faceCentres();
|
||||||
|
|
||||||
|
forAll(owner, facei)
|
||||||
|
{
|
||||||
|
const label own = owner[facei];
|
||||||
|
const label nbr = neighbour[facei];
|
||||||
|
|
||||||
|
if (mag(alpha[own] - alpha[nbr]) > alphaDiff)
|
||||||
|
{
|
||||||
|
changedFaces.append(facei);
|
||||||
|
changedFacesInfo.append
|
||||||
|
(
|
||||||
|
sweepData(max(field[own], field[nbr]), Cf[facei])
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Insert all faces of coupled patches - FaceCellWave will correct them
|
||||||
|
forAll(mesh.boundaryMesh(), patchi)
|
||||||
|
{
|
||||||
|
const polyPatch& patch = mesh.boundaryMesh()[patchi];
|
||||||
|
|
||||||
|
if (patch.coupled())
|
||||||
|
{
|
||||||
|
forAll(patch, patchFacei)
|
||||||
|
{
|
||||||
|
label facei = patch.start() + patchFacei;
|
||||||
|
label own = mesh.faceOwner()[facei];
|
||||||
|
|
||||||
|
scalarField alphapn =
|
||||||
|
alpha.boundaryField()[patchi].patchNeighbourField();
|
||||||
|
|
||||||
|
if (mag(alpha[own] - alphapn[patchFacei]) > alphaDiff)
|
||||||
|
{
|
||||||
|
changedFaces.append(facei);
|
||||||
|
changedFacesInfo.append
|
||||||
|
(
|
||||||
|
sweepData(field[own], Cf[facei])
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
changedFaces.shrink();
|
||||||
|
changedFacesInfo.shrink();
|
||||||
|
|
||||||
|
// Propagate information over whole domain
|
||||||
|
FaceCellWave<sweepData> sweepData
|
||||||
|
(
|
||||||
|
mesh,
|
||||||
|
faceData,
|
||||||
|
cellData
|
||||||
|
);
|
||||||
|
|
||||||
|
sweepData.setFaceInfo(changedFaces, changedFacesInfo);
|
||||||
|
|
||||||
|
sweepData.iterate(nLayers);
|
||||||
|
|
||||||
|
forAll(field, celli)
|
||||||
|
{
|
||||||
|
if (cellData[celli].valid())
|
||||||
|
{
|
||||||
|
field[celli] = max(field[celli], cellData[celli].value());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
field.correctBoundaryConditions();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
90
src/finiteVolume/finiteVolume/fvc/fvcSmooth/fvcSmooth.H
Normal file
90
src/finiteVolume/finiteVolume/fvc/fvcSmooth/fvcSmooth.H
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | Copyright (C) 2010-2010 OpenCFD Ltd.
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
License
|
||||||
|
This file is part of OpenFOAM.
|
||||||
|
|
||||||
|
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 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/>.
|
||||||
|
|
||||||
|
InNamespace
|
||||||
|
Foam::fvc
|
||||||
|
|
||||||
|
Description
|
||||||
|
Provides functions smooth spread and sweep which use the FaceCellWave
|
||||||
|
algorithm to smooth and redistribute the first field argument.
|
||||||
|
|
||||||
|
smooth: smooths the field by ensuring the values in neighbouring cells are
|
||||||
|
at least coeff* the cell value.
|
||||||
|
|
||||||
|
spread: redistributes the field by spreading the maximum value within the
|
||||||
|
region defined by the value (being between alphaMax and alphaMin)
|
||||||
|
and gradient of alpha (where the difference between the values in
|
||||||
|
neighbouring cells is larger than alphaDiff).
|
||||||
|
|
||||||
|
sweep: redistributes the field by sweeping the maximum value where the
|
||||||
|
gradient of alpha is large (where the difference between the values
|
||||||
|
in neighbouring cells is larger than alphaDiff) away from that
|
||||||
|
starting point of the sweep.
|
||||||
|
|
||||||
|
SourceFiles
|
||||||
|
fvcSmooth.C
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef fvcSmooth_H
|
||||||
|
#define fvcSmooth_H
|
||||||
|
|
||||||
|
#include "volFieldsFwd.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
namespace fvc
|
||||||
|
{
|
||||||
|
void smooth
|
||||||
|
(
|
||||||
|
volScalarField& field,
|
||||||
|
const scalar coeff
|
||||||
|
);
|
||||||
|
|
||||||
|
void spread
|
||||||
|
(
|
||||||
|
volScalarField& field,
|
||||||
|
const volScalarField& alpha,
|
||||||
|
const label nLayers,
|
||||||
|
const scalar alphaDiff = 0.2,
|
||||||
|
const scalar alphaMax = 0.99,
|
||||||
|
const scalar alphaMin = 0.01
|
||||||
|
);
|
||||||
|
|
||||||
|
void sweep
|
||||||
|
(
|
||||||
|
volScalarField& field,
|
||||||
|
const volScalarField& alpha,
|
||||||
|
const label nLayers,
|
||||||
|
const scalar alphaDiff = 0.2
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
204
src/finiteVolume/finiteVolume/fvc/fvcSmooth/smoothData.H
Normal file
204
src/finiteVolume/finiteVolume/fvc/fvcSmooth/smoothData.H
Normal file
@ -0,0 +1,204 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | Copyright (C) 2010-2010 OpenCFD Ltd.
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
License
|
||||||
|
This file is part of OpenFOAM.
|
||||||
|
|
||||||
|
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 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/>.
|
||||||
|
|
||||||
|
Class
|
||||||
|
Foam::smoothData
|
||||||
|
|
||||||
|
Description
|
||||||
|
Helper class used by the fvc::smooth and fvc::spread functions.
|
||||||
|
|
||||||
|
SourceFiles
|
||||||
|
smoothData.H
|
||||||
|
smoothDataI.H
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef smoothData_H
|
||||||
|
#define smoothData_H
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
Class smoothData Declaration
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
class smoothData
|
||||||
|
{
|
||||||
|
scalar value_;
|
||||||
|
|
||||||
|
// Private Member Functions
|
||||||
|
|
||||||
|
//- Update - gets information from neighbouring face/cell and
|
||||||
|
// uses this to update itself (if necessary) and return true
|
||||||
|
inline bool update
|
||||||
|
(
|
||||||
|
const smoothData& svf,
|
||||||
|
const scalar scale,
|
||||||
|
const scalar tol
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
// Static data members
|
||||||
|
|
||||||
|
//- Field fraction
|
||||||
|
static scalar maxRatio;
|
||||||
|
|
||||||
|
|
||||||
|
// Constructors
|
||||||
|
|
||||||
|
//- Construct null
|
||||||
|
inline smoothData();
|
||||||
|
|
||||||
|
//- Construct from inverse field value
|
||||||
|
inline smoothData(const scalar value);
|
||||||
|
|
||||||
|
|
||||||
|
// Member Functions
|
||||||
|
|
||||||
|
// Access
|
||||||
|
|
||||||
|
//- Return value
|
||||||
|
scalar value() const
|
||||||
|
{
|
||||||
|
return value_;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Needed by FaceCellWave
|
||||||
|
|
||||||
|
//- Check whether origin has been changed at all or
|
||||||
|
// still contains original (invalid) value
|
||||||
|
inline bool valid() const;
|
||||||
|
|
||||||
|
//- Check for identical geometrical data
|
||||||
|
// Used for cyclics checking
|
||||||
|
inline bool sameGeometry
|
||||||
|
(
|
||||||
|
const polyMesh&,
|
||||||
|
const smoothData&,
|
||||||
|
const scalar
|
||||||
|
) const;
|
||||||
|
|
||||||
|
//- Convert any absolute coordinates into relative to
|
||||||
|
// (patch)face centre
|
||||||
|
inline void leaveDomain
|
||||||
|
(
|
||||||
|
const polyMesh&,
|
||||||
|
const polyPatch&,
|
||||||
|
const label patchFaceI,
|
||||||
|
const point& faceCentre
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Reverse of leaveDomain
|
||||||
|
inline void enterDomain
|
||||||
|
(
|
||||||
|
const polyMesh&,
|
||||||
|
const polyPatch&,
|
||||||
|
const label patchFaceI,
|
||||||
|
const point& faceCentre
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Apply rotation matrix to any coordinates
|
||||||
|
inline void transform
|
||||||
|
(
|
||||||
|
const polyMesh&,
|
||||||
|
const tensor&
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Influence of neighbouring face
|
||||||
|
inline bool updateCell
|
||||||
|
(
|
||||||
|
const polyMesh&,
|
||||||
|
const label thisCellI,
|
||||||
|
const label neighbourFaceI,
|
||||||
|
const smoothData& svf,
|
||||||
|
const scalar tol
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Influence of neighbouring cell
|
||||||
|
inline bool updateFace
|
||||||
|
(
|
||||||
|
const polyMesh&,
|
||||||
|
const label thisFaceI,
|
||||||
|
const label neighbourCellI,
|
||||||
|
const smoothData& svf,
|
||||||
|
const scalar tol
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Influence of different value on same face
|
||||||
|
inline bool updateFace
|
||||||
|
(
|
||||||
|
const polyMesh&,
|
||||||
|
const label thisFaceI,
|
||||||
|
const smoothData& svf,
|
||||||
|
const scalar tol
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
// Member Operators
|
||||||
|
|
||||||
|
inline void operator=(const scalar value);
|
||||||
|
|
||||||
|
// Needed for List IO
|
||||||
|
inline bool operator==(const smoothData&) const;
|
||||||
|
|
||||||
|
inline bool operator!=(const smoothData&) const;
|
||||||
|
|
||||||
|
|
||||||
|
// IOstream Operators
|
||||||
|
|
||||||
|
friend Ostream& operator<<
|
||||||
|
(
|
||||||
|
Ostream& os,
|
||||||
|
const smoothData& svf
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return os << svf.value_;
|
||||||
|
}
|
||||||
|
|
||||||
|
friend Istream& operator>>(Istream& is, smoothData& svf)
|
||||||
|
{
|
||||||
|
return is >> svf.value_;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
} // End namespace Foam
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
#include "smoothDataI.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
192
src/finiteVolume/finiteVolume/fvc/fvcSmooth/smoothDataI.H
Normal file
192
src/finiteVolume/finiteVolume/fvc/fvcSmooth/smoothDataI.H
Normal file
@ -0,0 +1,192 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | Copyright (C) 2010-2010 OpenCFD Ltd.
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
License
|
||||||
|
This file is part of OpenFOAM.
|
||||||
|
|
||||||
|
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 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/>.
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||||
|
|
||||||
|
inline bool Foam::smoothData::update
|
||||||
|
(
|
||||||
|
const smoothData& svf,
|
||||||
|
const scalar scale,
|
||||||
|
const scalar tol
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (!valid() || (value_ < VSMALL))
|
||||||
|
{
|
||||||
|
// My value not set - take over neighbour
|
||||||
|
value_ = svf.value()/scale;
|
||||||
|
|
||||||
|
// Something changed - let caller know
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else if (svf.value() > (1 + tol)*scale*value_)
|
||||||
|
{
|
||||||
|
// Neighbour is too big for me - Up my value
|
||||||
|
value_ = svf.value()/scale;
|
||||||
|
|
||||||
|
// Something changed - let caller know
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Neighbour is not too big for me or change is too small
|
||||||
|
// Nothing changed
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
inline Foam::smoothData::smoothData()
|
||||||
|
:
|
||||||
|
value_(-GREAT)
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
inline Foam::smoothData::smoothData(const scalar value)
|
||||||
|
:
|
||||||
|
value_(value)
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
inline bool Foam::smoothData::valid() const
|
||||||
|
{
|
||||||
|
return value_ > -SMALL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline bool Foam::smoothData::sameGeometry
|
||||||
|
(
|
||||||
|
const polyMesh&,
|
||||||
|
const smoothData&,
|
||||||
|
const scalar
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline void Foam::smoothData::leaveDomain
|
||||||
|
(
|
||||||
|
const polyMesh&,
|
||||||
|
const polyPatch&,
|
||||||
|
const label,
|
||||||
|
const point&
|
||||||
|
)
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
inline void Foam::smoothData::transform
|
||||||
|
(
|
||||||
|
const polyMesh&,
|
||||||
|
const tensor&
|
||||||
|
)
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
inline void Foam::smoothData::enterDomain
|
||||||
|
(
|
||||||
|
const polyMesh&,
|
||||||
|
const polyPatch&,
|
||||||
|
const label,
|
||||||
|
const point&
|
||||||
|
)
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
inline bool Foam::smoothData::updateCell
|
||||||
|
(
|
||||||
|
const polyMesh&,
|
||||||
|
const label,
|
||||||
|
const label,
|
||||||
|
const smoothData& svf,
|
||||||
|
const scalar tol
|
||||||
|
)
|
||||||
|
{
|
||||||
|
// Take over info from face if more than deltaRatio larger
|
||||||
|
return update(svf, maxRatio, tol);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline bool Foam::smoothData::updateFace
|
||||||
|
(
|
||||||
|
const polyMesh&,
|
||||||
|
const label,
|
||||||
|
const label,
|
||||||
|
const smoothData& svf,
|
||||||
|
const scalar tol
|
||||||
|
)
|
||||||
|
{
|
||||||
|
// Take over information from cell without any scaling (scale = 1.0)
|
||||||
|
return update(svf, 1.0, tol);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Update this (face) with coupled face information.
|
||||||
|
inline bool Foam::smoothData::updateFace
|
||||||
|
(
|
||||||
|
const polyMesh&,
|
||||||
|
const label,
|
||||||
|
const smoothData& svf,
|
||||||
|
const scalar tol
|
||||||
|
)
|
||||||
|
{
|
||||||
|
// Take over information from coupled face without any scaling (scale = 1.0)
|
||||||
|
return update(svf, 1.0, tol);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
inline void Foam::smoothData::operator=
|
||||||
|
(
|
||||||
|
const scalar value
|
||||||
|
)
|
||||||
|
{
|
||||||
|
value_ = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline bool Foam::smoothData::operator==
|
||||||
|
(
|
||||||
|
const smoothData& rhs
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
return value_ == rhs.value();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline bool Foam::smoothData::operator!=
|
||||||
|
(
|
||||||
|
const smoothData& rhs
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
return !(*this == rhs);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
205
src/finiteVolume/finiteVolume/fvc/fvcSmooth/sweepData.H
Normal file
205
src/finiteVolume/finiteVolume/fvc/fvcSmooth/sweepData.H
Normal file
@ -0,0 +1,205 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | Copyright (C) 2010-2010 OpenCFD Ltd.
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
License
|
||||||
|
This file is part of OpenFOAM.
|
||||||
|
|
||||||
|
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 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/>.
|
||||||
|
|
||||||
|
Class
|
||||||
|
Foam::sweepData
|
||||||
|
|
||||||
|
Description
|
||||||
|
Helper class used by fvc::sweep function.
|
||||||
|
|
||||||
|
SourceFiles
|
||||||
|
sweepData.H
|
||||||
|
sweepDataI.H
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef sweepData_H
|
||||||
|
#define sweepData_H
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
Class sweepData Declaration
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
class sweepData
|
||||||
|
{
|
||||||
|
scalar value_;
|
||||||
|
point origin_;
|
||||||
|
|
||||||
|
// Private Member Functions
|
||||||
|
|
||||||
|
//- Update - gets information from neighbouring face/cell and
|
||||||
|
// uses this to update itself (if necessary) and return true
|
||||||
|
inline bool update
|
||||||
|
(
|
||||||
|
const sweepData& svf,
|
||||||
|
const point& position,
|
||||||
|
const scalar tol
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
// Constructors
|
||||||
|
|
||||||
|
//- Construct null
|
||||||
|
inline sweepData();
|
||||||
|
|
||||||
|
//- Construct from component
|
||||||
|
inline sweepData(const scalar value, const point& origin);
|
||||||
|
|
||||||
|
|
||||||
|
// Member Functions
|
||||||
|
|
||||||
|
// Access
|
||||||
|
|
||||||
|
//- Return value
|
||||||
|
scalar value() const
|
||||||
|
{
|
||||||
|
return value_;
|
||||||
|
}
|
||||||
|
|
||||||
|
//- Return origin
|
||||||
|
const point& origin() const
|
||||||
|
{
|
||||||
|
return origin_;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Needed by FaceCellWave
|
||||||
|
|
||||||
|
//- Check whether origin has been changed at all or
|
||||||
|
// still contains original (invalid) value
|
||||||
|
inline bool valid() const;
|
||||||
|
|
||||||
|
//- Check for identical geometrical data
|
||||||
|
// Used for cyclics checking
|
||||||
|
inline bool sameGeometry
|
||||||
|
(
|
||||||
|
const polyMesh&,
|
||||||
|
const sweepData&,
|
||||||
|
const scalar
|
||||||
|
) const;
|
||||||
|
|
||||||
|
//- Convert any absolute coordinates into relative to
|
||||||
|
// (patch)face centre
|
||||||
|
inline void leaveDomain
|
||||||
|
(
|
||||||
|
const polyMesh&,
|
||||||
|
const polyPatch&,
|
||||||
|
const label patchFaceI,
|
||||||
|
const point& faceCentre
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Reverse of leaveDomain
|
||||||
|
inline void enterDomain
|
||||||
|
(
|
||||||
|
const polyMesh&,
|
||||||
|
const polyPatch&,
|
||||||
|
const label patchFaceI,
|
||||||
|
const point& faceCentre
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Apply rotation matrix to any coordinates
|
||||||
|
inline void transform
|
||||||
|
(
|
||||||
|
const polyMesh&,
|
||||||
|
const tensor&
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Influence of neighbouring face
|
||||||
|
inline bool updateCell
|
||||||
|
(
|
||||||
|
const polyMesh&,
|
||||||
|
const label thisCellI,
|
||||||
|
const label neighbourFaceI,
|
||||||
|
const sweepData& svf,
|
||||||
|
const scalar tol
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Influence of neighbouring cell
|
||||||
|
inline bool updateFace
|
||||||
|
(
|
||||||
|
const polyMesh&,
|
||||||
|
const label thisFaceI,
|
||||||
|
const label neighbourCellI,
|
||||||
|
const sweepData& svf,
|
||||||
|
const scalar tol
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Influence of different value on same face
|
||||||
|
inline bool updateFace
|
||||||
|
(
|
||||||
|
const polyMesh&,
|
||||||
|
const label thisFaceI,
|
||||||
|
const sweepData& svf,
|
||||||
|
const scalar tol
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
// Member Operators
|
||||||
|
|
||||||
|
inline void operator=(const scalar value);
|
||||||
|
|
||||||
|
// Needed for List IO
|
||||||
|
inline bool operator==(const sweepData&) const;
|
||||||
|
|
||||||
|
inline bool operator!=(const sweepData&) const;
|
||||||
|
|
||||||
|
|
||||||
|
// IOstream Operators
|
||||||
|
|
||||||
|
friend Ostream& operator<<
|
||||||
|
(
|
||||||
|
Ostream& os,
|
||||||
|
const sweepData& svf
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return os << svf.value_ << svf.origin_;
|
||||||
|
}
|
||||||
|
|
||||||
|
friend Istream& operator>>(Istream& is, sweepData& svf)
|
||||||
|
{
|
||||||
|
return is >> svf.value_ >> svf.origin_;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
} // End namespace Foam
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
#include "sweepDataI.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
208
src/finiteVolume/finiteVolume/fvc/fvcSmooth/sweepDataI.H
Normal file
208
src/finiteVolume/finiteVolume/fvc/fvcSmooth/sweepDataI.H
Normal file
@ -0,0 +1,208 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | Copyright (C) 2010-2010 OpenCFD Ltd.
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
License
|
||||||
|
This file is part of OpenFOAM.
|
||||||
|
|
||||||
|
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 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/>.
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#include "transform.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||||
|
|
||||||
|
inline bool Foam::sweepData::update
|
||||||
|
(
|
||||||
|
const sweepData& svf,
|
||||||
|
const point& position,
|
||||||
|
const scalar tol
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (!valid())
|
||||||
|
{
|
||||||
|
operator=(svf);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
scalar myDist2 = magSqr(position - origin());
|
||||||
|
|
||||||
|
if (myDist2 < SMALL)
|
||||||
|
{
|
||||||
|
if (svf.value() > value())
|
||||||
|
{
|
||||||
|
operator=(svf);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
scalar dist2 = magSqr(position - svf.origin());
|
||||||
|
|
||||||
|
if (dist2 < myDist2)
|
||||||
|
{
|
||||||
|
operator=(svf);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
inline Foam::sweepData::sweepData()
|
||||||
|
:
|
||||||
|
value_(-GREAT),
|
||||||
|
origin_(vector::max)
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
inline Foam::sweepData::sweepData(const scalar value, const point& origin)
|
||||||
|
:
|
||||||
|
value_(value),
|
||||||
|
origin_(origin)
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
inline bool Foam::sweepData::valid() const
|
||||||
|
{
|
||||||
|
return value_ > -SMALL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline bool Foam::sweepData::sameGeometry
|
||||||
|
(
|
||||||
|
const polyMesh&,
|
||||||
|
const sweepData&,
|
||||||
|
const scalar
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline void Foam::sweepData::leaveDomain
|
||||||
|
(
|
||||||
|
const polyMesh&,
|
||||||
|
const polyPatch&,
|
||||||
|
const label,
|
||||||
|
const point& faceCentre
|
||||||
|
)
|
||||||
|
{
|
||||||
|
origin_ -= faceCentre;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline void Foam::sweepData::transform
|
||||||
|
(
|
||||||
|
const polyMesh&,
|
||||||
|
const tensor& rotTensor
|
||||||
|
)
|
||||||
|
{
|
||||||
|
origin_ = Foam::transform(rotTensor, origin_);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline void Foam::sweepData::enterDomain
|
||||||
|
(
|
||||||
|
const polyMesh&,
|
||||||
|
const polyPatch&,
|
||||||
|
const label,
|
||||||
|
const point& faceCentre
|
||||||
|
)
|
||||||
|
{
|
||||||
|
// back to absolute form
|
||||||
|
origin_ += faceCentre;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline bool Foam::sweepData::updateCell
|
||||||
|
(
|
||||||
|
const polyMesh& mesh,
|
||||||
|
const label thisCellI,
|
||||||
|
const label,
|
||||||
|
const sweepData& svf,
|
||||||
|
const scalar tol
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return update(svf, mesh.cellCentres()[thisCellI], tol);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline bool Foam::sweepData::updateFace
|
||||||
|
(
|
||||||
|
const polyMesh& mesh,
|
||||||
|
const label thisFaceI,
|
||||||
|
const label,
|
||||||
|
const sweepData& svf,
|
||||||
|
const scalar tol
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return update(svf, mesh.faceCentres()[thisFaceI], tol);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Update this (face) with coupled face information.
|
||||||
|
inline bool Foam::sweepData::updateFace
|
||||||
|
(
|
||||||
|
const polyMesh& mesh,
|
||||||
|
const label thisFaceI,
|
||||||
|
const sweepData& svf,
|
||||||
|
const scalar tol
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return update(svf, mesh.faceCentres()[thisFaceI], tol);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
inline void Foam::sweepData::operator=
|
||||||
|
(
|
||||||
|
const scalar value
|
||||||
|
)
|
||||||
|
{
|
||||||
|
value_ = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline bool Foam::sweepData::operator==
|
||||||
|
(
|
||||||
|
const sweepData& rhs
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
return origin() == rhs.origin();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline bool Foam::sweepData::operator!=
|
||||||
|
(
|
||||||
|
const sweepData& rhs
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
return !(*this == rhs);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -617,11 +617,7 @@ bool Foam::meshSearch::pointInCell(const point& p, label cellI) const
|
|||||||
{
|
{
|
||||||
label faceI = cFaces[i];
|
label faceI = cFaces[i];
|
||||||
|
|
||||||
const face& f = mesh_.faces()[faceI];
|
pointHit inter = mesh_.faces()[faceI].ray
|
||||||
|
|
||||||
forAll(f, fp)
|
|
||||||
{
|
|
||||||
pointHit inter = f.ray
|
|
||||||
(
|
(
|
||||||
ctr,
|
ctr,
|
||||||
dir,
|
dir,
|
||||||
@ -643,7 +639,6 @@ bool Foam::meshSearch::pointInCell(const point& p, label cellI) const
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
intersection::setPlanarTol(oldTol);
|
intersection::setPlanarTol(oldTol);
|
||||||
|
|
||||||
|
|||||||
@ -53,16 +53,10 @@ void Foam::streamLine::track()
|
|||||||
initialParticles
|
initialParticles
|
||||||
);
|
);
|
||||||
|
|
||||||
//Pout<< "Seeding particles." << endl;
|
|
||||||
|
|
||||||
const sampledSet& seedPoints = sampledSetPtr_();
|
const sampledSet& seedPoints = sampledSetPtr_();
|
||||||
|
|
||||||
forAll(seedPoints, i)
|
forAll(seedPoints, i)
|
||||||
{
|
{
|
||||||
//Pout<< "Seeded particle at " << seedPoints[i]
|
|
||||||
// << " at cell:" << seedPoints.cells()[i]
|
|
||||||
// << endl;
|
|
||||||
|
|
||||||
particles.addParticle
|
particles.addParticle
|
||||||
(
|
(
|
||||||
new streamLineParticle
|
new streamLineParticle
|
||||||
@ -228,15 +222,14 @@ void Foam::streamLine::track()
|
|||||||
vvInterp,
|
vvInterp,
|
||||||
UIndex, // index of U in vvInterp
|
UIndex, // index of U in vvInterp
|
||||||
trackForward_, // track in +u direction
|
trackForward_, // track in +u direction
|
||||||
|
nSubCycle_, // step through cells in steps?
|
||||||
allTracks_,
|
allTracks_,
|
||||||
allScalars_,
|
allScalars_,
|
||||||
allVectors_
|
allVectors_
|
||||||
);
|
);
|
||||||
|
|
||||||
// Track
|
// Track
|
||||||
//Pout<< "Tracking particles." << endl;
|
|
||||||
particles.move(td);
|
particles.move(td);
|
||||||
//Pout<< "Finished tracking particles." << endl;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -296,6 +289,19 @@ void Foam::streamLine::read(const dictionary& dict)
|
|||||||
UName_ = dict.lookupOrDefault<word>("U", "U");
|
UName_ = dict.lookupOrDefault<word>("U", "U");
|
||||||
dict.lookup("trackForward") >> trackForward_;
|
dict.lookup("trackForward") >> trackForward_;
|
||||||
dict.lookup("lifeTime") >> lifeTime_;
|
dict.lookup("lifeTime") >> lifeTime_;
|
||||||
|
if (lifeTime_ < 1)
|
||||||
|
{
|
||||||
|
FatalErrorIn(":streamLine::read(const dictionary&)")
|
||||||
|
<< "Illegal value " << lifeTime_ << " for lifeTime"
|
||||||
|
<< exit(FatalError);
|
||||||
|
}
|
||||||
|
|
||||||
|
dict.lookup("nSubCycle") >> nSubCycle_;
|
||||||
|
if (nSubCycle_ < 1)
|
||||||
|
{
|
||||||
|
nSubCycle_ = 1;
|
||||||
|
}
|
||||||
|
|
||||||
cloudName_ = dict.lookupOrDefault<word>("cloudName", "streamLine");
|
cloudName_ = dict.lookupOrDefault<word>("cloudName", "streamLine");
|
||||||
dict.lookup("seedSampleSet") >> seedSet_;
|
dict.lookup("seedSampleSet") >> seedSet_;
|
||||||
|
|
||||||
@ -323,7 +329,6 @@ void Foam::streamLine::execute()
|
|||||||
{
|
{
|
||||||
// const Time& runTime = const_cast<Time&>(obr_.time());
|
// const Time& runTime = const_cast<Time&>(obr_.time());
|
||||||
// Pout<< "**streamLine::execute : time:" << runTime.timeName() << endl;
|
// Pout<< "**streamLine::execute : time:" << runTime.timeName() << endl;
|
||||||
// Pout<< "**streamLine::execute : time:" << runTime.timeIndex() << endl;
|
|
||||||
//
|
//
|
||||||
// bool isOutputTime = false;
|
// bool isOutputTime = false;
|
||||||
//
|
//
|
||||||
|
|||||||
@ -92,6 +92,9 @@ class streamLine
|
|||||||
//- Maximum lifetime (= number of cells) of particle
|
//- Maximum lifetime (= number of cells) of particle
|
||||||
label lifeTime_;
|
label lifeTime_;
|
||||||
|
|
||||||
|
//- Number of subcycling steps
|
||||||
|
label nSubCycle_;
|
||||||
|
|
||||||
//- Optional specified name of particles
|
//- Optional specified name of particles
|
||||||
word cloudName_;
|
word cloudName_;
|
||||||
|
|
||||||
|
|||||||
@ -36,6 +36,25 @@ namespace Foam
|
|||||||
|
|
||||||
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||||
|
|
||||||
|
// Estimate dt to cross cell in a few steps
|
||||||
|
Foam::scalar Foam::streamLineParticle::calcSubCycleDeltaT
|
||||||
|
(
|
||||||
|
streamLineParticle::trackData& td,
|
||||||
|
const scalar dt,
|
||||||
|
const vector& U
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
streamLineParticle testParticle(*this);
|
||||||
|
bool oldKeepParticle = td.keepParticle;
|
||||||
|
bool oldSwitchProcessor = td.switchProcessor;
|
||||||
|
scalar fraction = testParticle.trackToFace(position()+dt*U, td);
|
||||||
|
td.keepParticle = oldKeepParticle;
|
||||||
|
td.switchProcessor = oldSwitchProcessor;
|
||||||
|
// Adapt the dt to subdivide the trajectory into 4 substeps.
|
||||||
|
return dt*fraction/td.nSubCycle_;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
Foam::vector Foam::streamLineParticle::interpolateFields
|
Foam::vector Foam::streamLineParticle::interpolateFields
|
||||||
(
|
(
|
||||||
const streamLineParticle::trackData& td,
|
const streamLineParticle::trackData& td,
|
||||||
@ -170,14 +189,19 @@ bool Foam::streamLineParticle::move(streamLineParticle::trackData& td)
|
|||||||
&& lifeTime_ > 0
|
&& lifeTime_ > 0
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
// TBD: implement subcycling so step through cells in more than
|
|
||||||
// one step.
|
|
||||||
|
|
||||||
// set the lagrangian time-step
|
// set the lagrangian time-step
|
||||||
scalar dt = min(dtMax, tEnd);
|
scalar dt = min(dtMax, tEnd);
|
||||||
|
|
||||||
// Store current position and sampled velocity.
|
// Cross cell in steps:
|
||||||
|
// - at subiter 0 calculate dt to cross cell in nSubCycle steps
|
||||||
|
// - at the last subiter do all of the remaining track
|
||||||
|
// - do a few more subiters than nSubCycle since velocity might
|
||||||
|
// be decreasing
|
||||||
|
for (label subIter = 0; subIter < 2*td.nSubCycle_; subIter++)
|
||||||
|
{
|
||||||
--lifeTime_;
|
--lifeTime_;
|
||||||
|
|
||||||
|
// Store current position and sampled velocity.
|
||||||
sampledPositions_.append(position());
|
sampledPositions_.append(position());
|
||||||
vector U = interpolateFields(td, position(), cell());
|
vector U = interpolateFields(td, position(), cell());
|
||||||
|
|
||||||
@ -186,7 +210,21 @@ bool Foam::streamLineParticle::move(streamLineParticle::trackData& td)
|
|||||||
U = -U;
|
U = -U;
|
||||||
}
|
}
|
||||||
|
|
||||||
dt *= trackToFace(position()+dt*U, td);
|
|
||||||
|
if (subIter == 0 && td.nSubCycle_ > 1)
|
||||||
|
{
|
||||||
|
// Adapt dt to cross cell in a few steps
|
||||||
|
dt = calcSubCycleDeltaT(td, dt, U);
|
||||||
|
}
|
||||||
|
else if (subIter == td.nSubCycle_-1)
|
||||||
|
{
|
||||||
|
// Do full step on last subcycle
|
||||||
|
dt = min(dtMax, tEnd);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
scalar fraction = trackToFace(position()+dt*U, td);
|
||||||
|
dt *= fraction;
|
||||||
|
|
||||||
tEnd -= dt;
|
tEnd -= dt;
|
||||||
stepFraction() = 1.0 - tEnd/deltaT;
|
stepFraction() = 1.0 - tEnd/deltaT;
|
||||||
@ -196,7 +234,14 @@ bool Foam::streamLineParticle::move(streamLineParticle::trackData& td)
|
|||||||
// Force removal
|
// Force removal
|
||||||
lifeTime_ = 0;
|
lifeTime_ = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!td.keepParticle || td.switchProcessor || lifeTime_ == 0)
|
||||||
|
{
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
if (!td.keepParticle || lifeTime_ == 0)
|
if (!td.keepParticle || lifeTime_ == 0)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -72,6 +72,7 @@ public:
|
|||||||
const PtrList<interpolationCellPoint<vector> >& vvInterp_;
|
const PtrList<interpolationCellPoint<vector> >& vvInterp_;
|
||||||
const label UIndex_;
|
const label UIndex_;
|
||||||
const bool trackForward_;
|
const bool trackForward_;
|
||||||
|
const label nSubCycle_;
|
||||||
|
|
||||||
DynamicList<vectorList>& allPositions_;
|
DynamicList<vectorList>& allPositions_;
|
||||||
List<DynamicList<scalarList> >& allScalars_;
|
List<DynamicList<scalarList> >& allScalars_;
|
||||||
@ -87,6 +88,7 @@ public:
|
|||||||
const PtrList<interpolationCellPoint<vector> >& vvInterp,
|
const PtrList<interpolationCellPoint<vector> >& vvInterp,
|
||||||
const label UIndex,
|
const label UIndex,
|
||||||
const bool trackForward,
|
const bool trackForward,
|
||||||
|
const label nSubCycle,
|
||||||
DynamicList<List<point> >& allPositions,
|
DynamicList<List<point> >& allPositions,
|
||||||
List<DynamicList<scalarList> >& allScalars,
|
List<DynamicList<scalarList> >& allScalars,
|
||||||
List<DynamicList<vectorList> >& allVectors
|
List<DynamicList<vectorList> >& allVectors
|
||||||
@ -97,6 +99,7 @@ public:
|
|||||||
vvInterp_(vvInterp),
|
vvInterp_(vvInterp),
|
||||||
UIndex_(UIndex),
|
UIndex_(UIndex),
|
||||||
trackForward_(trackForward),
|
trackForward_(trackForward),
|
||||||
|
nSubCycle_(nSubCycle),
|
||||||
allPositions_(allPositions),
|
allPositions_(allPositions),
|
||||||
allScalars_(allScalars),
|
allScalars_(allScalars),
|
||||||
allVectors_(allVectors)
|
allVectors_(allVectors)
|
||||||
@ -123,6 +126,15 @@ private:
|
|||||||
|
|
||||||
// Private Member Functions
|
// Private Member Functions
|
||||||
|
|
||||||
|
//- Estimate dt to cross from current face to next one in nSubCycle
|
||||||
|
// steps.
|
||||||
|
scalar calcSubCycleDeltaT
|
||||||
|
(
|
||||||
|
streamLineParticle::trackData& td,
|
||||||
|
const scalar dt,
|
||||||
|
const vector& U
|
||||||
|
) const;
|
||||||
|
|
||||||
//- Interpolate all quantities; return interpolated velocity.
|
//- Interpolate all quantities; return interpolated velocity.
|
||||||
vector interpolateFields
|
vector interpolateFields
|
||||||
(
|
(
|
||||||
|
|||||||
@ -82,8 +82,11 @@ functions
|
|||||||
// Names of fields to sample. Should contain above velocity field!
|
// Names of fields to sample. Should contain above velocity field!
|
||||||
fields (p U k);
|
fields (p U k);
|
||||||
|
|
||||||
// Cells particles can travel before being removed
|
// Steps particles can travel before being removed
|
||||||
lifeTime 1000;
|
lifeTime 10000;
|
||||||
|
|
||||||
|
// Number of steps per cell (estimate). Set to 1 to disable subcycling.
|
||||||
|
nSubCycle 5;
|
||||||
|
|
||||||
// Cloud name to use
|
// Cloud name to use
|
||||||
cloudName particleTracks;
|
cloudName particleTracks;
|
||||||
|
|||||||
@ -84,8 +84,11 @@ functions
|
|||||||
// Names of fields to sample. Should contain above velocity field!
|
// Names of fields to sample. Should contain above velocity field!
|
||||||
fields (p k U);
|
fields (p k U);
|
||||||
|
|
||||||
// Cells particles can travel before being removed
|
// Steps particles can travel before being removed
|
||||||
lifeTime 1000;
|
lifeTime 10000;
|
||||||
|
|
||||||
|
// Number of steps per cell (estimate). Set to 1 to disable subcycling.
|
||||||
|
nSubCycle 5;
|
||||||
|
|
||||||
// Cloud name to use
|
// Cloud name to use
|
||||||
cloudName particleTracks;
|
cloudName particleTracks;
|
||||||
|
|||||||
Reference in New Issue
Block a user