Add the OpenFOAM source tree

This commit is contained in:
Henry
2014-12-10 22:40:10 +00:00
parent ee487c860d
commit 446e5777f0
13379 changed files with 3983377 additions and 0 deletions

View File

@ -0,0 +1,3 @@
buoyantBoussinesqPimpleFoam.C
EXE = $(FOAM_APPBIN)/buoyantBoussinesqPimpleFoam

View File

@ -0,0 +1,21 @@
EXE_INC = \
-I../buoyantBoussinesqSimpleFoam \
-I$(LIB_SRC)/sampling/lnInclude \
-I$(LIB_SRC)/meshTools/lnInclude \
-I$(LIB_SRC)/fvOptions/lnInclude \
-I$(LIB_SRC)/finiteVolume/lnInclude \
-I$(LIB_SRC)/turbulenceModels \
-I$(LIB_SRC)/turbulenceModels/incompressible/RAS/lnInclude \
-I$(LIB_SRC)/transportModels \
-I$(LIB_SRC)/transportModels/incompressible/singlePhaseTransportModel \
-I$(LIB_SRC)/thermophysicalModels/radiationModels/lnInclude
EXE_LIBS = \
-lfiniteVolume \
-lfvOptions \
-lsampling \
-lmeshTools \
-lincompressibleTurbulenceModel \
-lincompressibleRASModels \
-lincompressibleTransportModels \
-lradiationModels

View File

@ -0,0 +1,28 @@
{
alphat = turbulence->nut()/Prt;
alphat.correctBoundaryConditions();
volScalarField alphaEff("alphaEff", turbulence->nu()/Pr + alphat);
fvScalarMatrix TEqn
(
fvm::ddt(T)
+ fvm::div(phi, T)
- fvm::laplacian(alphaEff, T)
==
radiation->ST(rhoCpRef, T)
+ fvOptions(T)
);
TEqn.relax();
fvOptions.constrain(TEqn);
TEqn.solve();
radiation->correct();
fvOptions.correct(T);
rhok = 1.0 - beta*(T - TRef);
}

View File

@ -0,0 +1,32 @@
// Solve the momentum equation
fvVectorMatrix UEqn
(
fvm::ddt(U)
+ fvm::div(phi, U)
+ turbulence->divDevReff(U)
==
fvOptions(U)
);
UEqn.relax();
fvOptions.constrain(UEqn);
if (pimple.momentumPredictor())
{
solve
(
UEqn
==
fvc::reconstruct
(
(
- ghf*fvc::snGrad(rhok)
- fvc::snGrad(p_rgh)
)*mesh.magSf()
)
);
fvOptions.correct(U);
}

View File

@ -0,0 +1,117 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
\\/ 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
buoyantBoussinesqPimpleFoam
Description
Transient solver for buoyant, turbulent flow of incompressible fluids
Uses the Boussinesq approximation:
\f[
rho_{k} = 1 - beta(T - T_{ref})
\f]
where:
\f$ rho_{k} \f$ = the effective (driving) kinematic density
beta = thermal expansion coefficient [1/K]
T = temperature [K]
\f$ T_{ref} \f$ = reference temperature [K]
Valid when:
\f[
\frac{beta(T - T_{ref})}{rho_{ref}} << 1
\f]
\*---------------------------------------------------------------------------*/
#include "fvCFD.H"
#include "singlePhaseTransportModel.H"
#include "RASModel.H"
#include "radiationModel.H"
#include "fvIOoptionList.H"
#include "pimpleControl.H"
#include "fixedFluxPressureFvPatchScalarField.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
int main(int argc, char *argv[])
{
#include "setRootCase.H"
#include "createTime.H"
#include "createMesh.H"
#include "readGravitationalAcceleration.H"
#include "createFields.H"
#include "createIncompressibleRadiationModel.H"
#include "createFvOptions.H"
#include "initContinuityErrs.H"
#include "readTimeControls.H"
#include "CourantNo.H"
#include "setInitialDeltaT.H"
pimpleControl pimple(mesh);
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
Info<< "\nStarting time loop\n" << endl;
while (runTime.loop())
{
Info<< "Time = " << runTime.timeName() << nl << endl;
#include "readTimeControls.H"
#include "CourantNo.H"
#include "setDeltaT.H"
// --- Pressure-velocity PIMPLE corrector loop
while (pimple.loop())
{
#include "UEqn.H"
#include "TEqn.H"
// --- Pressure corrector loop
while (pimple.correct())
{
#include "pEqn.H"
}
if (pimple.turbCorr())
{
turbulence->correct();
}
}
runTime.write();
Info<< "ExecutionTime = " << runTime.elapsedCpuTime() << " s"
<< " ClockTime = " << runTime.elapsedClockTime() << " s"
<< nl << endl;
}
Info<< "End\n" << endl;
return 0;
}
// ************************************************************************* //

View File

@ -0,0 +1,118 @@
Info<< "Reading thermophysical properties\n" << endl;
Info<< "Reading field T\n" << endl;
volScalarField T
(
IOobject
(
"T",
runTime.timeName(),
mesh,
IOobject::MUST_READ,
IOobject::AUTO_WRITE
),
mesh
);
Info<< "Reading field p_rgh\n" << endl;
volScalarField p_rgh
(
IOobject
(
"p_rgh",
runTime.timeName(),
mesh,
IOobject::MUST_READ,
IOobject::AUTO_WRITE
),
mesh
);
Info<< "Reading field U\n" << endl;
volVectorField U
(
IOobject
(
"U",
runTime.timeName(),
mesh,
IOobject::MUST_READ,
IOobject::AUTO_WRITE
),
mesh
);
#include "createPhi.H"
#include "readTransportProperties.H"
Info<< "Creating turbulence model\n" << endl;
autoPtr<incompressible::RASModel> turbulence
(
incompressible::RASModel::New(U, phi, laminarTransport)
);
// Kinematic density for buoyancy force
volScalarField rhok
(
IOobject
(
"rhok",
runTime.timeName(),
mesh
),
1.0 - beta*(T - TRef)
);
// kinematic turbulent thermal thermal conductivity m2/s
Info<< "Reading field alphat\n" << endl;
volScalarField alphat
(
IOobject
(
"alphat",
runTime.timeName(),
mesh,
IOobject::MUST_READ,
IOobject::AUTO_WRITE
),
mesh
);
Info<< "Calculating field g.h\n" << endl;
volScalarField gh("gh", g & mesh.C());
surfaceScalarField ghf("ghf", g & mesh.Cf());
volScalarField p
(
IOobject
(
"p",
runTime.timeName(),
mesh,
IOobject::NO_READ,
IOobject::AUTO_WRITE
),
p_rgh + rhok*gh
);
label pRefCell = 0;
scalar pRefValue = 0.0;
setRefCell
(
p,
p_rgh,
mesh.solutionDict().subDict("PIMPLE"),
pRefCell,
pRefValue
);
if (p_rgh.needReference())
{
p += dimensionedScalar
(
"p",
p.dimensions(),
pRefValue - getRefCellValue(p, pRefCell)
);
}

View File

@ -0,0 +1,71 @@
{
volScalarField rAU("rAU", 1.0/UEqn.A());
surfaceScalarField rAUf("rAUf", fvc::interpolate(rAU));
volVectorField HbyA("HbyA", U);
HbyA = rAU*UEqn.H();
surfaceScalarField phig(-rAUf*ghf*fvc::snGrad(rhok)*mesh.magSf());
surfaceScalarField phiHbyA
(
"phiHbyA",
(fvc::interpolate(HbyA) & mesh.Sf())
+ rAUf*fvc::ddtCorr(U, phi)
+ phig
);
fvOptions.makeRelative(phiHbyA);
// Update the fixedFluxPressure BCs to ensure flux consistency
setSnGrad<fixedFluxPressureFvPatchScalarField>
(
p_rgh.boundaryField(),
(
phiHbyA.boundaryField()
- fvOptions.relative(mesh.Sf().boundaryField() & U.boundaryField())
)/(mesh.magSf().boundaryField()*rAUf.boundaryField())
);
while (pimple.correctNonOrthogonal())
{
fvScalarMatrix p_rghEqn
(
fvm::laplacian(rAUf, p_rgh) == fvc::div(phiHbyA)
);
p_rghEqn.setReference(pRefCell, getRefCellValue(p_rgh, pRefCell));
p_rghEqn.solve(mesh.solver(p_rgh.select(pimple.finalInnerIter())));
if (pimple.finalNonOrthogonalIter())
{
// Calculate the conservative fluxes
phi = phiHbyA - p_rghEqn.flux();
// Explicitly relax pressure for momentum corrector
p_rgh.relax();
// Correct the momentum source with the pressure gradient flux
// calculated from the relaxed pressure
U = HbyA + rAU*fvc::reconstruct((phig - p_rghEqn.flux())/rAUf);
U.correctBoundaryConditions();
fvOptions.correct(U);
}
}
#include "continuityErrs.H"
p = p_rgh + rhok*gh;
if (p_rgh.needReference())
{
p += dimensionedScalar
(
"p",
p.dimensions(),
pRefValue - getRefCellValue(p, pRefCell)
);
p_rgh = p - rhok*gh;
}
}

View File

@ -0,0 +1,3 @@
buoyantBoussinesqSimpleFoam.C
EXE = $(FOAM_APPBIN)/buoyantBoussinesqSimpleFoam

View File

@ -0,0 +1,18 @@
EXE_INC = \
-I$(LIB_SRC)/finiteVolume/lnInclude \
-I$(LIB_SRC)/sampling/lnInclude \
-I$(LIB_SRC)/meshTools/lnInclude \
-I$(LIB_SRC)/fvOptions/lnInclude \
-I$(LIB_SRC)/turbulenceModels \
-I$(LIB_SRC)/turbulenceModels/incompressible/RAS/lnInclude \
-I$(LIB_SRC)/transportModels \
-I$(LIB_SRC)/transportModels/incompressible/singlePhaseTransportModel
EXE_LIBS = \
-lfiniteVolume \
-lsampling \
-lmeshTools \
-lfvOptions \
-lincompressibleTurbulenceModel \
-lincompressibleRASModels \
-lincompressibleTransportModels

View File

@ -0,0 +1,24 @@
{
alphat = turbulence->nut()/Prt;
alphat.correctBoundaryConditions();
volScalarField alphaEff("alphaEff", turbulence->nu()/Pr + alphat);
fvScalarMatrix TEqn
(
fvm::div(phi, T)
- fvm::laplacian(alphaEff, T)
==
fvOptions(T)
);
TEqn.relax();
fvOptions.constrain(TEqn);
TEqn.solve();
fvOptions.correct(T);
rhok = 1.0 - beta*(T - TRef);
}

View File

@ -0,0 +1,31 @@
// Solve the momentum equation
tmp<fvVectorMatrix> UEqn
(
fvm::div(phi, U)
+ turbulence->divDevReff(U)
==
fvOptions(U)
);
UEqn().relax();
fvOptions.constrain(UEqn());
if (simple.momentumPredictor())
{
solve
(
UEqn()
==
fvc::reconstruct
(
(
- ghf*fvc::snGrad(rhok)
- fvc::snGrad(p_rgh)
)*mesh.magSf()
)
);
fvOptions.correct(U);
}

View File

@ -0,0 +1,99 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
\\/ 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
buoyantBoussinesqSimpleFoam
Description
Steady-state solver for buoyant, turbulent flow of incompressible fluids
Uses the Boussinesq approximation:
\f[
rho_{k} = 1 - beta(T - T_{ref})
\f]
where:
\f$ rho_{k} \f$ = the effective (driving) density
beta = thermal expansion coefficient [1/K]
T = temperature [K]
\f$ T_{ref} \f$ = reference temperature [K]
Valid when:
\f[
\frac{beta(T - T_{ref})}{rho_{ref}} << 1
\f]
\*---------------------------------------------------------------------------*/
#include "fvCFD.H"
#include "singlePhaseTransportModel.H"
#include "RASModel.H"
#include "fvIOoptionList.H"
#include "simpleControl.H"
#include "fixedFluxPressureFvPatchScalarField.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
int main(int argc, char *argv[])
{
#include "setRootCase.H"
#include "createTime.H"
#include "createMesh.H"
#include "readGravitationalAcceleration.H"
#include "createFields.H"
#include "createFvOptions.H"
#include "initContinuityErrs.H"
simpleControl simple(mesh);
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
Info<< "\nStarting time loop\n" << endl;
while (simple.loop())
{
Info<< "Time = " << runTime.timeName() << nl << endl;
// Pressure-velocity SIMPLE corrector
{
#include "UEqn.H"
#include "TEqn.H"
#include "pEqn.H"
}
turbulence->correct();
runTime.write();
Info<< "ExecutionTime = " << runTime.elapsedCpuTime() << " s"
<< " ClockTime = " << runTime.elapsedClockTime() << " s"
<< nl << endl;
}
Info<< "End\n" << endl;
return 0;
}
// ************************************************************************* //

View File

@ -0,0 +1,118 @@
Info<< "Reading thermophysical properties\n" << endl;
Info<< "Reading field T\n" << endl;
volScalarField T
(
IOobject
(
"T",
runTime.timeName(),
mesh,
IOobject::MUST_READ,
IOobject::AUTO_WRITE
),
mesh
);
Info<< "Reading field p_rgh\n" << endl;
volScalarField p_rgh
(
IOobject
(
"p_rgh",
runTime.timeName(),
mesh,
IOobject::MUST_READ,
IOobject::AUTO_WRITE
),
mesh
);
Info<< "Reading field U\n" << endl;
volVectorField U
(
IOobject
(
"U",
runTime.timeName(),
mesh,
IOobject::MUST_READ,
IOobject::AUTO_WRITE
),
mesh
);
#include "createPhi.H"
#include "readTransportProperties.H"
Info<< "Creating turbulence model\n" << endl;
autoPtr<incompressible::RASModel> turbulence
(
incompressible::RASModel::New(U, phi, laminarTransport)
);
// Kinematic density for buoyancy force
volScalarField rhok
(
IOobject
(
"rhok",
runTime.timeName(),
mesh
),
1.0 - beta*(T - TRef)
);
// kinematic turbulent thermal thermal conductivity m2/s
Info<< "Reading field alphat\n" << endl;
volScalarField alphat
(
IOobject
(
"alphat",
runTime.timeName(),
mesh,
IOobject::MUST_READ,
IOobject::AUTO_WRITE
),
mesh
);
Info<< "Calculating field g.h\n" << endl;
volScalarField gh("gh", g & mesh.C());
surfaceScalarField ghf("ghf", g & mesh.Cf());
volScalarField p
(
IOobject
(
"p",
runTime.timeName(),
mesh,
IOobject::NO_READ,
IOobject::AUTO_WRITE
),
p_rgh + rhok*gh
);
label pRefCell = 0;
scalar pRefValue = 0.0;
setRefCell
(
p,
p_rgh,
mesh.solutionDict().subDict("SIMPLE"),
pRefCell,
pRefValue
);
if (p_rgh.needReference())
{
p += dimensionedScalar
(
"p",
p.dimensions(),
pRefValue - getRefCellValue(p, pRefCell)
);
}

View File

@ -0,0 +1,74 @@
{
volScalarField rAU("rAU", 1.0/UEqn().A());
surfaceScalarField rAUf("rAUf", fvc::interpolate(rAU));
volVectorField HbyA("HbyA", U);
HbyA = rAU*UEqn().H();
UEqn.clear();
surfaceScalarField phig(-rAUf*ghf*fvc::snGrad(rhok)*mesh.magSf());
surfaceScalarField phiHbyA
(
"phiHbyA",
(fvc::interpolate(HbyA) & mesh.Sf())
);
fvOptions.makeRelative(phiHbyA);
adjustPhi(phiHbyA, U, p_rgh);
phiHbyA += phig;
// Update the fixedFluxPressure BCs to ensure flux consistency
setSnGrad<fixedFluxPressureFvPatchScalarField>
(
p_rgh.boundaryField(),
(
phiHbyA.boundaryField()
- fvOptions.relative(mesh.Sf().boundaryField() & U.boundaryField())
)/(mesh.magSf().boundaryField()*rAUf.boundaryField())
);
while (simple.correctNonOrthogonal())
{
fvScalarMatrix p_rghEqn
(
fvm::laplacian(rAUf, p_rgh) == fvc::div(phiHbyA)
);
p_rghEqn.setReference(pRefCell, getRefCellValue(p_rgh, pRefCell));
p_rghEqn.solve();
if (simple.finalNonOrthogonalIter())
{
// Calculate the conservative fluxes
phi = phiHbyA - p_rghEqn.flux();
// Explicitly relax pressure for momentum corrector
p_rgh.relax();
// Correct the momentum source with the pressure gradient flux
// calculated from the relaxed pressure
U = HbyA + rAU*fvc::reconstruct((phig - p_rghEqn.flux())/rAUf);
U.correctBoundaryConditions();
fvOptions.correct(U);
}
}
#include "continuityErrs.H"
p = p_rgh + rhok*gh;
if (p_rgh.needReference())
{
p += dimensionedScalar
(
"p",
p.dimensions(),
pRefValue - getRefCellValue(p, pRefCell)
);
p_rgh = p - rhok*gh;
}
}

View File

@ -0,0 +1,13 @@
singlePhaseTransportModel laminarTransport(U, phi);
// Thermal expansion coefficient [1/K]
dimensionedScalar beta(laminarTransport.lookup("beta"));
// Reference temperature [K]
dimensionedScalar TRef(laminarTransport.lookup("TRef"));
// Laminar Prandtl number
dimensionedScalar Pr(laminarTransport.lookup("Pr"));
// Turbulent Prandtl number
dimensionedScalar Prt(laminarTransport.lookup("Prt"));

View File

@ -0,0 +1,34 @@
{
volScalarField& he = thermo.he();
fvScalarMatrix EEqn
(
fvm::ddt(rho, he) + fvm::div(phi, he)
+ fvc::ddt(rho, K) + fvc::div(phi, K)
+ (
he.name() == "e"
? fvc::div
(
fvc::absolute(phi/fvc::interpolate(rho), U),
p,
"div(phiv,p)"
)
: -dpdt
)
- fvm::laplacian(turbulence->alphaEff(), he)
==
radiation->Sh(thermo)
+ fvOptions(rho, he)
);
EEqn.relax();
fvOptions.constrain(EEqn);
EEqn.solve();
fvOptions.correct(he);
thermo.correct();
radiation->correct();
}

View File

@ -0,0 +1,3 @@
buoyantPimpleFoam.C
EXE = $(FOAM_APPBIN)/buoyantPimpleFoam

View File

@ -0,0 +1,21 @@
EXE_INC = \
-I$(LIB_SRC)/finiteVolume/lnInclude \
-I$(LIB_SRC)/sampling/lnInclude \
-I$(LIB_SRC)/meshTools/lnInclude \
-I$(LIB_SRC)/fvOptions/lnInclude \
-I$(LIB_SRC)/thermophysicalModels/basic/lnInclude \
-I$(LIB_SRC)/thermophysicalModels/radiationModels/lnInclude \
-I$(LIB_SRC)/turbulenceModels/compressible/turbulenceModel
EXE_LIBS = \
-lfiniteVolume \
-lsampling \
-lmeshTools \
-lfvOptions \
-lfluidThermophysicalModels \
-lradiationModels \
-lspecie \
-lcompressibleTurbulenceModel \
-lcompressibleRASModels \
-lcompressibleLESModels

View File

@ -0,0 +1,33 @@
// Solve the Momentum equation
fvVectorMatrix UEqn
(
fvm::ddt(rho, U)
+ fvm::div(phi, U)
+ turbulence->divDevRhoReff(U)
==
fvOptions(rho, U)
);
UEqn.relax();
fvOptions.constrain(UEqn);
if (pimple.momentumPredictor())
{
solve
(
UEqn
==
fvc::reconstruct
(
(
- ghf*fvc::snGrad(rho)
- fvc::snGrad(p_rgh)
)*mesh.magSf()
)
);
fvOptions.correct(U);
K = 0.5*magSqr(U);
}

View File

@ -0,0 +1,111 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
\\/ 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
buoyantPimpleFoam
Description
Transient solver for buoyant, turbulent flow of compressible fluids for
ventilation and heat-transfer.
Turbulence is modelled using a run-time selectable compressible RAS or
LES model.
\*---------------------------------------------------------------------------*/
#include "fvCFD.H"
#include "rhoThermo.H"
#include "turbulenceModel.H"
#include "radiationModel.H"
#include "fvIOoptionList.H"
#include "pimpleControl.H"
#include "fixedFluxPressureFvPatchScalarField.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
int main(int argc, char *argv[])
{
#include "setRootCase.H"
#include "createTime.H"
#include "createMesh.H"
#include "readGravitationalAcceleration.H"
#include "createFields.H"
#include "createFvOptions.H"
#include "createRadiationModel.H"
#include "initContinuityErrs.H"
#include "readTimeControls.H"
#include "compressibleCourantNo.H"
#include "setInitialDeltaT.H"
pimpleControl pimple(mesh);
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
Info<< "\nStarting time loop\n" << endl;
while (runTime.run())
{
#include "readTimeControls.H"
#include "compressibleCourantNo.H"
#include "setDeltaT.H"
runTime++;
Info<< "Time = " << runTime.timeName() << nl << endl;
#include "rhoEqn.H"
// --- Pressure-velocity PIMPLE corrector loop
while (pimple.loop())
{
#include "UEqn.H"
#include "EEqn.H"
// --- Pressure corrector loop
while (pimple.correct())
{
#include "pEqn.H"
}
if (pimple.turbCorr())
{
turbulence->correct();
}
}
rho = thermo.rho();
runTime.write();
Info<< "ExecutionTime = " << runTime.elapsedCpuTime() << " s"
<< " ClockTime = " << runTime.elapsedClockTime() << " s"
<< nl << endl;
}
Info<< "End\n" << endl;
return 0;
}
// ************************************************************************* //

View File

@ -0,0 +1,88 @@
Info<< "Reading thermophysical properties\n" << endl;
autoPtr<rhoThermo> pThermo(rhoThermo::New(mesh));
rhoThermo& thermo = pThermo();
thermo.validate(args.executable(), "h", "e");
volScalarField rho
(
IOobject
(
"rho",
runTime.timeName(),
mesh,
IOobject::NO_READ,
IOobject::NO_WRITE
),
thermo.rho()
);
volScalarField& p = thermo.p();
const volScalarField& psi = thermo.psi();
Info<< "Reading field U\n" << endl;
volVectorField U
(
IOobject
(
"U",
runTime.timeName(),
mesh,
IOobject::MUST_READ,
IOobject::AUTO_WRITE
),
mesh
);
#include "compressibleCreatePhi.H"
Info<< "Creating turbulence model\n" << endl;
autoPtr<compressible::turbulenceModel> turbulence
(
compressible::turbulenceModel::New
(
rho,
U,
phi,
thermo
)
);
Info<< "Calculating field g.h\n" << endl;
volScalarField gh("gh", g & mesh.C());
surfaceScalarField ghf("ghf", g & mesh.Cf());
Info<< "Reading field p_rgh\n" << endl;
volScalarField p_rgh
(
IOobject
(
"p_rgh",
runTime.timeName(),
mesh,
IOobject::MUST_READ,
IOobject::AUTO_WRITE
),
mesh
);
// Force p_rgh to be consistent with p
p_rgh = p - rho*gh;
Info<< "Creating field dpdt\n" << endl;
volScalarField dpdt
(
IOobject
(
"dpdt",
runTime.timeName(),
mesh
),
mesh,
dimensionedScalar("dpdt", p.dimensions()/dimTime, 0)
);
Info<< "Creating field kinetic energy K\n" << endl;
volScalarField K("K", 0.5*magSqr(U));

View File

@ -0,0 +1,88 @@
{
rho = thermo.rho();
// Thermodynamic density needs to be updated by psi*d(p) after the
// pressure solution - done in 2 parts. Part 1:
thermo.rho() -= psi*p_rgh;
volScalarField rAU(1.0/UEqn.A());
surfaceScalarField rAUf("rAUf", fvc::interpolate(rho*rAU));
volVectorField HbyA("HbyA", U);
HbyA = rAU*UEqn.H();
surfaceScalarField phig(-rAUf*ghf*fvc::snGrad(rho)*mesh.magSf());
surfaceScalarField phiHbyA
(
"phiHbyA",
(
(fvc::interpolate(rho*HbyA) & mesh.Sf())
+ rAUf*fvc::ddtCorr(rho, U, phi)
)
+ phig
);
fvOptions.makeRelative(fvc::interpolate(rho), phiHbyA);
// Update the fixedFluxPressure BCs to ensure flux consistency
setSnGrad<fixedFluxPressureFvPatchScalarField>
(
p_rgh.boundaryField(),
(
phiHbyA.boundaryField()
- fvOptions.relative(mesh.Sf().boundaryField() & U.boundaryField())
*rho.boundaryField()
)/(mesh.magSf().boundaryField()*rAUf.boundaryField())
);
fvScalarMatrix p_rghDDtEqn
(
fvc::ddt(rho) + psi*correction(fvm::ddt(p_rgh))
+ fvc::div(phiHbyA)
==
fvOptions(psi, p_rgh, rho.name())
);
while (pimple.correctNonOrthogonal())
{
fvScalarMatrix p_rghEqn
(
p_rghDDtEqn
- fvm::laplacian(rAUf, p_rgh)
);
fvOptions.constrain(p_rghEqn);
p_rghEqn.solve(mesh.solver(p_rgh.select(pimple.finalInnerIter())));
if (pimple.finalNonOrthogonalIter())
{
// Calculate the conservative fluxes
phi = phiHbyA + p_rghEqn.flux();
// Explicitly relax pressure for momentum corrector
p_rgh.relax();
// Correct the momentum source with the pressure gradient flux
// calculated from the relaxed pressure
U = HbyA + rAU*fvc::reconstruct((phig + p_rghEqn.flux())/rAUf);
U.correctBoundaryConditions();
fvOptions.correct(U);
K = 0.5*magSqr(U);
}
}
p = p_rgh + rho*gh;
// Second part of thermodynamic density update
thermo.rho() += psi*p_rgh;
if (thermo.dpdt())
{
dpdt = fvc::ddt(p);
}
#include "rhoEqn.H"
#include "compressibleContinuityErrs.H"
}

View File

@ -0,0 +1,28 @@
{
volScalarField& he = thermo.he();
fvScalarMatrix EEqn
(
fvm::div(phi, he)
+ (
he.name() == "e"
? fvc::div(phi, volScalarField("Ekp", 0.5*magSqr(U) + p/rho))
: fvc::div(phi, volScalarField("K", 0.5*magSqr(U)))
)
- fvm::laplacian(turbulence->alphaEff(), he)
==
radiation->Sh(thermo)
+ fvOptions(rho, he)
);
EEqn.relax();
fvOptions.constrain(EEqn);
EEqn.solve();
fvOptions.correct(he);
thermo.correct();
radiation->correct();
}

View File

@ -0,0 +1,3 @@
buoyantSimpleFoam.C
EXE = $(FOAM_APPBIN)/buoyantSimpleFoam

View File

@ -0,0 +1,22 @@
EXE_INC = \
-I$(LIB_SRC)/finiteVolume/lnInclude \
-I$(LIB_SRC)/fvOptions/lnInclude \
-I$(LIB_SRC)/sampling/lnInclude \
-I$(LIB_SRC)/meshTools/lnInclude \
-I$(LIB_SRC)/thermophysicalModels/basic/lnInclude \
-I$(LIB_SRC)/thermophysicalModels/radiationModels/lnInclude \
-I$(LIB_SRC)/turbulenceModels \
-I$(LIB_SRC)/turbulenceModels/compressible/RAS/lnInclude \
-I$(LIB_SRC)/turbulenceModels/RAS \
EXE_LIBS = \
-lfiniteVolume \
-lfvOptions \
-lsampling \
-lmeshTools \
-lfluidThermophysicalModels \
-lspecie \
-lradiationModels \
-lcompressibleTurbulenceModel \
-lcompressibleRASModels \
-lmeshTools

View File

@ -0,0 +1,31 @@
// Solve the Momentum equation
tmp<fvVectorMatrix> UEqn
(
fvm::div(phi, U)
+ turbulence->divDevRhoReff(U)
==
fvOptions(rho, U)
);
UEqn().relax();
fvOptions.constrain(UEqn());
if (simple.momentumPredictor())
{
solve
(
UEqn()
==
fvc::reconstruct
(
(
- ghf*fvc::snGrad(rho)
- fvc::snGrad(p_rgh)
)*mesh.magSf()
)
);
fvOptions.correct(U);
}

View File

@ -0,0 +1,86 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
\\/ 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
buoyantSimpleFoam
Description
Steady-state solver for buoyant, turbulent flow of compressible fluids,
including radiation, for ventilation and heat-transfer.
\*---------------------------------------------------------------------------*/
#include "fvCFD.H"
#include "rhoThermo.H"
#include "RASModel.H"
#include "radiationModel.H"
#include "simpleControl.H"
#include "fvIOoptionList.H"
#include "fixedFluxPressureFvPatchScalarField.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
int main(int argc, char *argv[])
{
#include "setRootCase.H"
#include "createTime.H"
#include "createMesh.H"
#include "readGravitationalAcceleration.H"
#include "createFields.H"
#include "createFvOptions.H"
#include "createRadiationModel.H"
#include "initContinuityErrs.H"
simpleControl simple(mesh);
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
Info<< "\nStarting time loop\n" << endl;
while (simple.loop())
{
Info<< "Time = " << runTime.timeName() << nl << endl;
// Pressure-velocity SIMPLE corrector
{
#include "UEqn.H"
#include "EEqn.H"
#include "pEqn.H"
}
turbulence->correct();
runTime.write();
Info<< "ExecutionTime = " << runTime.elapsedCpuTime() << " s"
<< " ClockTime = " << runTime.elapsedClockTime() << " s"
<< nl << endl;
}
Info<< "End\n" << endl;
return 0;
}
// ************************************************************************* //

View File

@ -0,0 +1,86 @@
Info<< "Reading thermophysical properties\n" << endl;
autoPtr<rhoThermo> pThermo(rhoThermo::New(mesh));
rhoThermo& thermo = pThermo();
thermo.validate(args.executable(), "h", "e");
volScalarField rho
(
IOobject
(
"rho",
runTime.timeName(),
mesh,
IOobject::NO_READ,
IOobject::NO_WRITE
),
thermo.rho()
);
volScalarField& p = thermo.p();
const volScalarField& psi = thermo.psi();
Info<< "Reading field U\n" << endl;
volVectorField U
(
IOobject
(
"U",
runTime.timeName(),
mesh,
IOobject::MUST_READ,
IOobject::AUTO_WRITE
),
mesh
);
#include "compressibleCreatePhi.H"
Info<< "Creating turbulence model\n" << endl;
autoPtr<compressible::RASModel> turbulence
(
compressible::RASModel::New
(
rho,
U,
phi,
thermo
)
);
Info<< "Calculating field g.h\n" << endl;
volScalarField gh("gh", g & mesh.C());
surfaceScalarField ghf("ghf", g & mesh.Cf());
Info<< "Reading field p_rgh\n" << endl;
volScalarField p_rgh
(
IOobject
(
"p_rgh",
runTime.timeName(),
mesh,
IOobject::MUST_READ,
IOobject::AUTO_WRITE
),
mesh
);
// Force p_rgh to be consistent with p
p_rgh = p - rho*gh;
label pRefCell = 0;
scalar pRefValue = 0.0;
setRefCell
(
p,
p_rgh,
mesh.solutionDict().subDict("SIMPLE"),
pRefCell,
pRefValue
);
dimensionedScalar initialMass = fvc::domainIntegrate(rho);
dimensionedScalar totalVolume = sum(mesh.V());

View File

@ -0,0 +1,80 @@
{
rho = thermo.rho();
rho.relax();
volScalarField rAU("rAU", 1.0/UEqn().A());
surfaceScalarField rhorAUf("rhorAUf", fvc::interpolate(rho*rAU));
volVectorField HbyA("HbyA", U);
HbyA = rAU*UEqn().H();
UEqn.clear();
surfaceScalarField phig(-rhorAUf*ghf*fvc::snGrad(rho)*mesh.magSf());
surfaceScalarField phiHbyA
(
"phiHbyA",
(fvc::interpolate(rho*HbyA) & mesh.Sf())
);
fvOptions.makeRelative(fvc::interpolate(rho), phiHbyA);
bool closedVolume = adjustPhi(phiHbyA, U, p_rgh);
phiHbyA += phig;
// Update the fixedFluxPressure BCs to ensure flux consistency
setSnGrad<fixedFluxPressureFvPatchScalarField>
(
p_rgh.boundaryField(),
(
phiHbyA.boundaryField()
- fvOptions.relative(mesh.Sf().boundaryField() & U.boundaryField())
*rho.boundaryField()
)/(mesh.magSf().boundaryField()*rhorAUf.boundaryField())
);
while (simple.correctNonOrthogonal())
{
fvScalarMatrix p_rghEqn
(
fvm::laplacian(rhorAUf, p_rgh) == fvc::div(phiHbyA)
);
p_rghEqn.setReference(pRefCell, getRefCellValue(p_rgh, pRefCell));
p_rghEqn.solve();
if (simple.finalNonOrthogonalIter())
{
// Calculate the conservative fluxes
phi = phiHbyA - p_rghEqn.flux();
// Explicitly relax pressure for momentum corrector
p_rgh.relax();
// Correct the momentum source with the pressure gradient flux
// calculated from the relaxed pressure
U = HbyA + rAU*fvc::reconstruct((phig - p_rghEqn.flux())/rhorAUf);
U.correctBoundaryConditions();
fvOptions.correct(U);
}
}
#include "continuityErrs.H"
p = p_rgh + rho*gh;
// For closed-volume cases adjust the pressure level
// to obey overall mass continuity
if (closedVolume)
{
p += (initialMass - fvc::domainIntegrate(psi*p))
/fvc::domainIntegrate(psi);
p_rgh = p - rho*gh;
}
rho = thermo.rho();
rho.relax();
Info<< "rho max/min : " << max(rho).value() << " " << min(rho).value()
<< endl;
}

View File

@ -0,0 +1,8 @@
#!/bin/sh
cd ${0%/*} || exit 1 # run from this directory
set -x
wclean
wclean chtMultiRegionSimpleFoam
# ----------------------------------------------------------------- end-of-file

View File

@ -0,0 +1,8 @@
#!/bin/sh
cd ${0%/*} || exit 1 # run from this directory
set -x
wmake
wmake chtMultiRegionSimpleFoam
# ----------------------------------------------------------------- end-of-file

View File

@ -0,0 +1,5 @@
fluid/compressibleCourantNo.C
solid/solidRegionDiffNo.C
chtMultiRegionFoam.C
EXE = $(FOAM_APPBIN)/chtMultiRegionFoam

View File

@ -0,0 +1,32 @@
EXE_INC = \
-I./fluid \
-I./solid \
-I./porousFluid \
-I./porousSolid \
-I./include \
-I$(LIB_SRC)/meshTools/lnInclude \
-I$(LIB_SRC)/sampling/lnInclude \
-I$(LIB_SRC)/finiteVolume/lnInclude \
-I$(LIB_SRC)/thermophysicalModels/basic/lnInclude \
-I$(LIB_SRC)/thermophysicalModels/specie/lnInclude \
-I$(LIB_SRC)/thermophysicalModels/solidThermo/lnInclude \
-I$(LIB_SRC)/turbulenceModels/compressible/turbulenceModel/lnInclude \
-I$(LIB_SRC)/thermophysicalModels/radiationModels/lnInclude \
-I$(LIB_SRC)/fvOptions/lnInclude \
-I$(LIB_SRC)/regionModels/regionModel/lnInclude
EXE_LIBS = \
-lfluidThermophysicalModels \
-lsolidThermo \
-lspecie \
-lcompressibleTurbulenceModel \
-lcompressibleRASModels \
-lcompressibleLESModels \
-lmeshTools \
-lfiniteVolume \
-lradiationModels \
-lfvOptions \
-lregionModels \
-lsampling

View File

@ -0,0 +1,136 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
\\/ 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
chtMultiRegionFoam
Description
Combination of heatConductionFoam and buoyantFoam for conjugate heat
transfer between solid regions and fluid regions. Both regions include
the fvOptions framework.
It handles secondary fluid or solid circuits which can be coupled
thermally with the main fluid region. i.e radiators, etc.
\*---------------------------------------------------------------------------*/
#include "fvCFD.H"
#include "rhoThermo.H"
#include "turbulenceModel.H"
#include "fixedGradientFvPatchFields.H"
#include "regionProperties.H"
#include "compressibleCourantNo.H"
#include "solidRegionDiffNo.H"
#include "solidThermo.H"
#include "radiationModel.H"
#include "fvIOoptionList.H"
#include "coordinateSystem.H"
#include "fixedFluxPressureFvPatchScalarField.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
int main(int argc, char *argv[])
{
#include "setRootCase.H"
#include "createTime.H"
regionProperties rp(runTime);
#include "createFluidMeshes.H"
#include "createSolidMeshes.H"
#include "createFluidFields.H"
#include "createSolidFields.H"
#include "initContinuityErrs.H"
#include "readTimeControls.H"
#include "readSolidTimeControls.H"
#include "compressibleMultiRegionCourantNo.H"
#include "solidRegionDiffusionNo.H"
#include "setInitialMultiRegionDeltaT.H"
while (runTime.run())
{
#include "readTimeControls.H"
#include "readSolidTimeControls.H"
#include "readPIMPLEControls.H"
#include "compressibleMultiRegionCourantNo.H"
#include "solidRegionDiffusionNo.H"
#include "setMultiRegionDeltaT.H"
runTime++;
Info<< "Time = " << runTime.timeName() << nl << endl;
if (nOuterCorr != 1)
{
forAll(fluidRegions, i)
{
#include "setRegionFluidFields.H"
#include "storeOldFluidFields.H"
}
}
// --- PIMPLE loop
for (int oCorr=0; oCorr<nOuterCorr; oCorr++)
{
bool finalIter = oCorr == nOuterCorr-1;
forAll(fluidRegions, i)
{
Info<< "\nSolving for fluid region "
<< fluidRegions[i].name() << endl;
#include "setRegionFluidFields.H"
#include "readFluidMultiRegionPIMPLEControls.H"
#include "solveFluid.H"
}
forAll(solidRegions, i)
{
Info<< "\nSolving for solid region "
<< solidRegions[i].name() << endl;
#include "setRegionSolidFields.H"
#include "readSolidMultiRegionPIMPLEControls.H"
#include "solveSolid.H"
}
}
runTime.write();
Info<< "ExecutionTime = " << runTime.elapsedCpuTime() << " s"
<< " ClockTime = " << runTime.elapsedClockTime() << " s"
<< nl << endl;
}
Info<< "End\n" << endl;
return 0;
}
// ************************************************************************* //

View File

@ -0,0 +1,4 @@
chtMultiRegionSimpleFoam.C
EXE = $(FOAM_APPBIN)/chtMultiRegionSimpleFoam

View File

@ -0,0 +1,30 @@
EXE_INC = \
-Ifluid \
-Isolid \
-I../solid \
-I$(LIB_SRC)/finiteVolume/lnInclude \
-I$(LIB_SRC)/meshTools/lnInclude \
-I$(LIB_SRC)/finiteVolume/cfdTools \
-I$(LIB_SRC)/thermophysicalModels/basic/lnInclude \
-I$(LIB_SRC)/thermophysicalModels/specie/lnInclude \
-I$(LIB_SRC)/thermophysicalModels/solidThermo/lnInclude \
-I$(LIB_SRC)/thermophysicalModels/radiationModels/lnInclude \
-I$(LIB_SRC)/turbulenceModels \
-I$(LIB_SRC)/turbulenceModels/compressible/turbulenceModel/lnInclude \
-I$(LIB_SRC)/turbulenceModels/compressible/RAS/lnInclude \
-I$(LIB_SRC)/fvOptions/lnInclude \
-I$(LIB_SRC)/sampling/lnInclude \
-I$(LIB_SRC)/regionModels/regionModel/lnInclude
EXE_LIBS = \
-lfiniteVolume \
-lfluidThermophysicalModels \
-lsolidThermo \
-lspecie \
-lcompressibleTurbulenceModel \
-lcompressibleRASModels \
-lcompressibleLESModels \
-lradiationModels \
-lfvOptions \
-lregionModels \
-lsampling

View File

@ -0,0 +1,96 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
\\/ 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
chtMultiRegionSimpleFoam
Description
Steady-state version of chtMultiRegionFoam
\*---------------------------------------------------------------------------*/
#include "fvCFD.H"
#include "rhoThermo.H"
#include "turbulenceModel.H"
#include "fixedGradientFvPatchFields.H"
#include "regionProperties.H"
#include "solidThermo.H"
#include "radiationModel.H"
#include "fvIOoptionList.H"
#include "coordinateSystem.H"
#include "fixedFluxPressureFvPatchScalarField.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
int main(int argc, char *argv[])
{
#include "setRootCase.H"
#include "createTime.H"
regionProperties rp(runTime);
#include "createFluidMeshes.H"
#include "createSolidMeshes.H"
#include "createFluidFields.H"
#include "createSolidFields.H"
#include "initContinuityErrs.H"
while (runTime.loop())
{
Info<< "Time = " << runTime.timeName() << nl << endl;
forAll(fluidRegions, i)
{
Info<< "\nSolving for fluid region "
<< fluidRegions[i].name() << endl;
#include "setRegionFluidFields.H"
#include "readFluidMultiRegionSIMPLEControls.H"
#include "solveFluid.H"
}
forAll(solidRegions, i)
{
Info<< "\nSolving for solid region "
<< solidRegions[i].name() << endl;
#include "setRegionSolidFields.H"
#include "readSolidMultiRegionSIMPLEControls.H"
#include "solveSolid.H"
}
runTime.write();
Info<< "ExecutionTime = " << runTime.elapsedCpuTime() << " s"
<< " ClockTime = " << runTime.elapsedClockTime() << " s"
<< nl << endl;
}
Info<< "End\n" << endl;
return 0;
}
// ************************************************************************* //

View File

@ -0,0 +1,31 @@
{
volScalarField& he = thermo.he();
fvScalarMatrix EEqn
(
fvm::div(phi, he)
+ (
he.name() == "e"
? fvc::div(phi, volScalarField("Ekp", 0.5*magSqr(U) + p/rho))
: fvc::div(phi, volScalarField("K", 0.5*magSqr(U)))
)
- fvm::laplacian(turb.alphaEff(), he)
==
rad.Sh(thermo)
+ fvOptions(rho, he)
);
EEqn.relax();
fvOptions.constrain(EEqn);
EEqn.solve();
fvOptions.correct(he);
thermo.correct();
rad.correct();
Info<< "Min/max T:" << min(thermo.T()).value() << ' '
<< max(thermo.T()).value() << endl;
}

View File

@ -0,0 +1,27 @@
// Solve the Momentum equation
tmp<fvVectorMatrix> UEqn
(
fvm::div(phi, U)
+ turb.divDevRhoReff(U)
==
fvOptions(rho, U)
);
UEqn().relax();
fvOptions.constrain(UEqn());
solve
(
UEqn()
==
fvc::reconstruct
(
(
- ghf*fvc::snGrad(rho)
- fvc::snGrad(p_rgh)
)*mesh.magSf()
)
);
fvOptions.correct(U);

View File

@ -0,0 +1,21 @@
{
dimensionedScalar totalMass = fvc::domainIntegrate(rho);
scalar sumLocalContErr =
(
fvc::domainIntegrate(mag(rho - thermo.rho()))/totalMass
).value();
scalar globalContErr =
(
fvc::domainIntegrate(rho - thermo.rho())/totalMass
).value();
cumulativeContErr[i] += globalContErr;
Info<< "time step continuity errors (" << mesh.name() << ")"
<< ": sum local = " << sumLocalContErr
<< ", global = " << globalContErr
<< ", cumulative = " << cumulativeContErr[i]
<< endl;
}

View File

@ -0,0 +1,15 @@
scalar CoNum = -GREAT;
forAll(fluidRegions, regionI)
{
CoNum = max
(
compressibleCourantNo
(
fluidRegions[regionI],
runTime,
rhoFluid[regionI],
phiFluid[regionI]
),
CoNum
);
}

View File

@ -0,0 +1,189 @@
// Initialise fluid field pointer lists
PtrList<rhoThermo> thermoFluid(fluidRegions.size());
PtrList<volScalarField> rhoFluid(fluidRegions.size());
PtrList<volVectorField> UFluid(fluidRegions.size());
PtrList<surfaceScalarField> phiFluid(fluidRegions.size());
PtrList<uniformDimensionedVectorField> gFluid(fluidRegions.size());
PtrList<compressible::turbulenceModel> turbulence(fluidRegions.size());
PtrList<volScalarField> p_rghFluid(fluidRegions.size());
PtrList<volScalarField> ghFluid(fluidRegions.size());
PtrList<surfaceScalarField> ghfFluid(fluidRegions.size());
PtrList<radiation::radiationModel> radiation(fluidRegions.size());
List<scalar> initialMassFluid(fluidRegions.size());
List<label> pRefCellFluid(fluidRegions.size(), 0);
List<scalar> pRefValueFluid(fluidRegions.size(), 0.0);
List<bool> frozenFlowFluid(fluidRegions.size(), false);
PtrList<dimensionedScalar> rhoMax(fluidRegions.size());
PtrList<dimensionedScalar> rhoMin(fluidRegions.size());
PtrList<fv::IOoptionList> fluidFvOptions(fluidRegions.size());
// Populate fluid field pointer lists
forAll(fluidRegions, i)
{
Info<< "*** Reading fluid mesh thermophysical properties for region "
<< fluidRegions[i].name() << nl << endl;
Info<< " Adding to thermoFluid\n" << endl;
thermoFluid.set
(
i,
rhoThermo::New(fluidRegions[i]).ptr()
);
Info<< " Adding to rhoFluid\n" << endl;
rhoFluid.set
(
i,
new volScalarField
(
IOobject
(
"rho",
runTime.timeName(),
fluidRegions[i],
IOobject::NO_READ,
IOobject::AUTO_WRITE
),
thermoFluid[i].rho()
)
);
Info<< " Adding to UFluid\n" << endl;
UFluid.set
(
i,
new volVectorField
(
IOobject
(
"U",
runTime.timeName(),
fluidRegions[i],
IOobject::MUST_READ,
IOobject::AUTO_WRITE
),
fluidRegions[i]
)
);
Info<< " Adding to phiFluid\n" << endl;
phiFluid.set
(
i,
new surfaceScalarField
(
IOobject
(
"phi",
runTime.timeName(),
fluidRegions[i],
IOobject::READ_IF_PRESENT,
IOobject::AUTO_WRITE
),
linearInterpolate(rhoFluid[i]*UFluid[i])
& fluidRegions[i].Sf()
)
);
Info<< " Adding to gFluid\n" << endl;
gFluid.set
(
i,
new uniformDimensionedVectorField
(
IOobject
(
"g",
runTime.constant(),
fluidRegions[i],
IOobject::MUST_READ,
IOobject::NO_WRITE
)
)
);
Info<< " Adding to turbulence\n" << endl;
turbulence.set
(
i,
compressible::turbulenceModel::New
(
rhoFluid[i],
UFluid[i],
phiFluid[i],
thermoFluid[i]
).ptr()
);
Info<< " Adding to ghFluid\n" << endl;
ghFluid.set
(
i,
new volScalarField("gh", gFluid[i] & fluidRegions[i].C())
);
Info<< " Adding to ghfFluid\n" << endl;
ghfFluid.set
(
i,
new surfaceScalarField("ghf", gFluid[i] & fluidRegions[i].Cf())
);
p_rghFluid.set
(
i,
new volScalarField
(
IOobject
(
"p_rgh",
runTime.timeName(),
fluidRegions[i],
IOobject::MUST_READ,
IOobject::AUTO_WRITE
),
fluidRegions[i]
)
);
// Force p_rgh to be consistent with p
p_rghFluid[i] = thermoFluid[i].p() - rhoFluid[i]*ghFluid[i];
radiation.set
(
i,
radiation::radiationModel::New(thermoFluid[i].T())
);
initialMassFluid[i] = fvc::domainIntegrate(rhoFluid[i]).value();
const dictionary& simpleDict =
fluidRegions[i].solutionDict().subDict("SIMPLE");
setRefCell
(
thermoFluid[i].p(),
p_rghFluid[i],
simpleDict,
pRefCellFluid[i],
pRefValueFluid[i]
);
simpleDict.readIfPresent("frozenFlow", frozenFlowFluid[i]);
rhoMax.set(i, new dimensionedScalar(simpleDict.lookup("rhoMax")));
rhoMin.set(i, new dimensionedScalar(simpleDict.lookup("rhoMin")));
Info<< " Adding fvOptions\n" << endl;
fluidFvOptions.set
(
i,
new fv::IOoptionList(fluidRegions[i])
);
}

View File

@ -0,0 +1,24 @@
const wordList fluidNames(rp["fluid"]);
PtrList<fvMesh> fluidRegions(fluidNames.size());
forAll(fluidNames, i)
{
Info<< "Create fluid mesh for region " << fluidNames[i]
<< " for time = " << runTime.timeName() << nl << endl;
fluidRegions.set
(
i,
new fvMesh
(
IOobject
(
fluidNames[i],
runTime.timeName(),
runTime,
IOobject::MUST_READ
)
)
);
}

View File

@ -0,0 +1,94 @@
{
rho = thermo.rho();
rho = max(rho, rhoMin[i]);
rho = min(rho, rhoMax[i]);
rho.relax();
volScalarField rAU("rAU", 1.0/UEqn().A());
surfaceScalarField rhorAUf("rhorAUf", fvc::interpolate(rho*rAU));
volVectorField HbyA("HbyA", U);
HbyA = rAU*UEqn().H();
UEqn.clear();
surfaceScalarField phig(-rhorAUf*ghf*fvc::snGrad(rho)*mesh.magSf());
surfaceScalarField phiHbyA
(
"phiHbyA",
(fvc::interpolate(rho*HbyA) & mesh.Sf())
);
fvOptions.makeRelative(fvc::interpolate(rho), phiHbyA);
bool closedVolume = adjustPhi(phiHbyA, U, p_rgh);
phiHbyA += phig;
// Update the fixedFluxPressure BCs to ensure flux consistency
setSnGrad<fixedFluxPressureFvPatchScalarField>
(
p_rgh.boundaryField(),
(
phiHbyA.boundaryField()
- fvOptions.relative(mesh.Sf().boundaryField() & U.boundaryField())
*rho.boundaryField()
)/(mesh.magSf().boundaryField()*rhorAUf.boundaryField())
);
dimensionedScalar compressibility = fvc::domainIntegrate(psi);
bool compressible = (compressibility.value() > SMALL);
// Solve pressure
for (int nonOrth=0; nonOrth<=nNonOrthCorr; nonOrth++)
{
fvScalarMatrix p_rghEqn
(
fvm::laplacian(rhorAUf, p_rgh) == fvc::div(phiHbyA)
);
p_rghEqn.setReference
(
pRefCell,
compressible ? getRefCellValue(p_rgh, pRefCell) : pRefValue
);
p_rghEqn.solve();
if (nonOrth == nNonOrthCorr)
{
// Calculate the conservative fluxes
phi = phiHbyA - p_rghEqn.flux();
// Explicitly relax pressure for momentum corrector
p_rgh.relax();
// Correct the momentum source with the pressure gradient flux
// calculated from the relaxed pressure
U = HbyA + rAU*fvc::reconstruct((phig - p_rghEqn.flux())/rhorAUf);
U.correctBoundaryConditions();
fvOptions.correct(U);
}
}
p = p_rgh + rho*gh;
#include "continuityErrs.H"
// For closed-volume cases adjust the pressure level
// to obey overall mass continuity
if (closedVolume && compressible)
{
p += (initialMass - fvc::domainIntegrate(thermo.rho()))
/compressibility;
p_rgh = p - rho*gh;
}
rho = thermo.rho();
rho = max(rho, rhoMin[i]);
rho = min(rho, rhoMax[i]);
rho.relax();
Info<< "Min/max rho:" << min(rho).value() << ' '
<< max(rho).value() << endl;
}

View File

@ -0,0 +1,5 @@
const dictionary& simple = fluidRegions[i].solutionDict().subDict("SIMPLE");
const int nNonOrthCorr =
simple.lookupOrDefault<int>("nNonOrthogonalCorrectors", 0);

View File

@ -0,0 +1,32 @@
const fvMesh& mesh = fluidRegions[i];
rhoThermo& thermo = thermoFluid[i];
thermo.validate(args.executable(), "h", "e");
volScalarField& rho = rhoFluid[i];
volVectorField& U = UFluid[i];
surfaceScalarField& phi = phiFluid[i];
compressible::turbulenceModel& turb = turbulence[i];
volScalarField& p = thermo.p();
const volScalarField& psi = thermo.psi();
fv::IOoptionList& fvOptions = fluidFvOptions[i];
const dimensionedScalar initialMass
(
"initialMass",
dimMass,
initialMassFluid[i]
);
radiation::radiationModel& rad = radiation[i];
const label pRefCell = pRefCellFluid[i];
const scalar pRefValue = pRefValueFluid[i];
const bool frozenFlow = frozenFlowFluid[i];
volScalarField& p_rgh = p_rghFluid[i];
const volScalarField& gh = ghFluid[i];
const surfaceScalarField& ghf = ghfFluid[i];

View File

@ -0,0 +1,19 @@
// Pressure-velocity SIMPLE corrector
{
if (frozenFlow)
{
#include "EEqn.H"
}
else
{
p_rgh.storePrevIter();
rho.storePrevIter();
#include "UEqn.H"
#include "EEqn.H"
#include "pEqn.H"
turb.correct();
}
}

View File

@ -0,0 +1,5 @@
const dictionary& simple = solidRegions[i].solutionDict().subDict("SIMPLE");
const int nNonOrthCorr =
simple.lookupOrDefault<int>("nNonOrthogonalCorrectors", 0);

View File

@ -0,0 +1,27 @@
{
for (int nonOrth=0; nonOrth<=nNonOrthCorr; nonOrth++)
{
fvScalarMatrix hEqn
(
(
thermo.isotropic()
? -fvm::laplacian(betav*thermo.alpha(), h, "laplacian(alpha,h)")
: -fvm::laplacian(betav*taniAlpha(), h, "laplacian(alpha,h)")
)
==
fvOptions(rho, h)
);
hEqn.relax();
fvOptions.constrain(hEqn);
hEqn.solve();
fvOptions.correct(h);
}
}
thermo.correct();
Info<< "Min/max T:" << min(thermo.T()) << ' ' << max(thermo.T()) << endl;

View File

@ -0,0 +1,37 @@
{
volScalarField& he = thermo.he();
fvScalarMatrix EEqn
(
fvm::ddt(rho, he) + fvm::div(phi, he)
+ fvc::ddt(rho, K) + fvc::div(phi, K)
+ (
he.name() == "e"
? fvc::div
(
fvc::absolute(phi/fvc::interpolate(rho), U),
p,
"div(phiv,p)"
)
: -dpdt
)
- fvm::laplacian(turb.alphaEff(), he)
==
rad.Sh(thermo)
+ fvOptions(rho, he)
);
EEqn.relax();
fvOptions.constrain(EEqn);
EEqn.solve(mesh.solver(he.select(finalIter)));
fvOptions.correct(he);
thermo.correct();
rad.correct();
Info<< "Min/max T:" << min(thermo.T()).value() << ' '
<< max(thermo.T()).value() << endl;
}

View File

@ -0,0 +1,33 @@
// Solve the Momentum equation
tmp<fvVectorMatrix> UEqn
(
fvm::ddt(rho, U)
+ fvm::div(phi, U)
+ turb.divDevRhoReff(U)
==
fvOptions(rho, U)
);
UEqn().relax();
fvOptions.constrain(UEqn());
if (momentumPredictor)
{
solve
(
UEqn()
==
fvc::reconstruct
(
(
- ghf*fvc::snGrad(rho)
- fvc::snGrad(p_rgh)
)*mesh.magSf()
),
mesh.solver(U.select(finalIter))
);
fvOptions.correct(U);
K = 0.5*magSqr(U);
}

View File

@ -0,0 +1,21 @@
{
dimensionedScalar totalMass = fvc::domainIntegrate(rho);
scalar sumLocalContErr =
(
fvc::domainIntegrate(mag(rho - thermo.rho()))/totalMass
).value();
scalar globalContErr =
(
fvc::domainIntegrate(rho - thermo.rho())/totalMass
).value();
cumulativeContErr[i] += globalContErr;
Info<< "time step continuity errors (" << mesh.name() << ")"
<< ": sum local = " << sumLocalContErr
<< ", global = " << globalContErr
<< ", cumulative = " << cumulativeContErr[i]
<< endl;
}

View File

@ -0,0 +1,55 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
\\/ 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 "compressibleCourantNo.H"
#include "fvc.H"
Foam::scalar Foam::compressibleCourantNo
(
const fvMesh& mesh,
const Time& runTime,
const volScalarField& rho,
const surfaceScalarField& phi
)
{
scalarField sumPhi
(
fvc::surfaceSum(mag(phi))().internalField()
/ rho.internalField()
);
scalar CoNum = 0.5*gMax(sumPhi/mesh.V().field())*runTime.deltaTValue();
scalar meanCoNum =
0.5*(gSum(sumPhi)/gSum(mesh.V().field()))*runTime.deltaTValue();
Info<< "Region: " << mesh.name() << " Courant Number mean: " << meanCoNum
<< " max: " << CoNum << endl;
return CoNum;
}
// ************************************************************************* //

View File

@ -0,0 +1,48 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
\\/ 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/>.
Description
Calculates and outputs the mean and maximum Courant Numbers for the fluid
regions
\*---------------------------------------------------------------------------*/
#ifndef compressibleCourantNo_H
#define compressibleCourantNo_H
#include "fvMesh.H"
namespace Foam
{
scalar compressibleCourantNo
(
const fvMesh& mesh,
const Time& runTime,
const volScalarField& rho,
const surfaceScalarField& phi
);
}
#endif
// ************************************************************************* //

View File

@ -0,0 +1,32 @@
scalar CoNum = -GREAT;
forAll(fluidRegions, regionI)
{
CoNum = max
(
compressibleCourantNo
(
fluidRegions[regionI],
runTime,
rhoFluid[regionI],
phiFluid[regionI]
),
CoNum
);
}
/*
forAll (porousFluidRegions, porousI)
{
CoNum = max
(
compressibleCourantNo
(
porousFluidRegions[porousI],
runTime,
rhoPorous[porousI],
phiPorous[porousI]
),
CoNum
);
}
*/

View File

@ -0,0 +1,204 @@
// Initialise fluid field pointer lists
PtrList<rhoThermo> thermoFluid(fluidRegions.size());
PtrList<volScalarField> rhoFluid(fluidRegions.size());
PtrList<volVectorField> UFluid(fluidRegions.size());
PtrList<surfaceScalarField> phiFluid(fluidRegions.size());
PtrList<uniformDimensionedVectorField> gFluid(fluidRegions.size());
PtrList<compressible::turbulenceModel> turbulence(fluidRegions.size());
PtrList<volScalarField> p_rghFluid(fluidRegions.size());
PtrList<volScalarField> ghFluid(fluidRegions.size());
PtrList<surfaceScalarField> ghfFluid(fluidRegions.size());
PtrList<radiation::radiationModel> radiation(fluidRegions.size());
PtrList<volScalarField> KFluid(fluidRegions.size());
PtrList<volScalarField> dpdtFluid(fluidRegions.size());
List<scalar> initialMassFluid(fluidRegions.size());
List<bool> frozenFlowFluid(fluidRegions.size(), false);
PtrList<fv::IOoptionList> fluidFvOptions(fluidRegions.size());
// Populate fluid field pointer lists
forAll(fluidRegions, i)
{
Info<< "*** Reading fluid mesh thermophysical properties for region "
<< fluidRegions[i].name() << nl << endl;
Info<< " Adding to thermoFluid\n" << endl;
thermoFluid.set
(
i,
rhoThermo::New(fluidRegions[i]).ptr()
);
Info<< " Adding to rhoFluid\n" << endl;
rhoFluid.set
(
i,
new volScalarField
(
IOobject
(
"rho",
runTime.timeName(),
fluidRegions[i],
IOobject::NO_READ,
IOobject::AUTO_WRITE
),
thermoFluid[i].rho()
)
);
Info<< " Adding to UFluid\n" << endl;
UFluid.set
(
i,
new volVectorField
(
IOobject
(
"U",
runTime.timeName(),
fluidRegions[i],
IOobject::MUST_READ,
IOobject::AUTO_WRITE
),
fluidRegions[i]
)
);
Info<< " Adding to phiFluid\n" << endl;
phiFluid.set
(
i,
new surfaceScalarField
(
IOobject
(
"phi",
runTime.timeName(),
fluidRegions[i],
IOobject::READ_IF_PRESENT,
IOobject::AUTO_WRITE
),
linearInterpolate(rhoFluid[i]*UFluid[i])
& fluidRegions[i].Sf()
)
);
Info<< " Adding to gFluid\n" << endl;
gFluid.set
(
i,
new uniformDimensionedVectorField
(
IOobject
(
"g",
runTime.constant(),
fluidRegions[i],
IOobject::MUST_READ,
IOobject::NO_WRITE
)
)
);
Info<< " Adding to turbulence\n" << endl;
turbulence.set
(
i,
compressible::turbulenceModel::New
(
rhoFluid[i],
UFluid[i],
phiFluid[i],
thermoFluid[i]
).ptr()
);
Info<< " Adding to ghFluid\n" << endl;
ghFluid.set
(
i,
new volScalarField("gh", gFluid[i] & fluidRegions[i].C())
);
Info<< " Adding to ghfFluid\n" << endl;
ghfFluid.set
(
i,
new surfaceScalarField("ghf", gFluid[i] & fluidRegions[i].Cf())
);
p_rghFluid.set
(
i,
new volScalarField
(
IOobject
(
"p_rgh",
runTime.timeName(),
fluidRegions[i],
IOobject::MUST_READ,
IOobject::AUTO_WRITE
),
fluidRegions[i]
)
);
// Force p_rgh to be consistent with p
p_rghFluid[i] = thermoFluid[i].p() - rhoFluid[i]*ghFluid[i];
radiation.set
(
i,
radiation::radiationModel::New(thermoFluid[i].T())
);
initialMassFluid[i] = fvc::domainIntegrate(rhoFluid[i]).value();
Info<< " Adding to KFluid\n" << endl;
KFluid.set
(
i,
new volScalarField
(
"K",
0.5*magSqr(UFluid[i])
)
);
Info<< " Adding to dpdtFluid\n" << endl;
dpdtFluid.set
(
i,
new volScalarField
(
IOobject
(
"dpdt",
runTime.timeName(),
fluidRegions[i]
),
fluidRegions[i],
dimensionedScalar
(
"dpdt",
thermoFluid[i].p().dimensions()/dimTime,
0
)
)
);
const dictionary& pimpleDict =
fluidRegions[i].solutionDict().subDict("PIMPLE");
pimpleDict.readIfPresent("frozenFlow", frozenFlowFluid[i]);
Info<< " Adding fvOptions\n" << endl;
fluidFvOptions.set
(
i,
new fv::IOoptionList(fluidRegions[i])
);
}

View File

@ -0,0 +1,24 @@
const wordList fluidNames(rp["fluid"]);
PtrList<fvMesh> fluidRegions(fluidNames.size());
forAll(fluidNames, i)
{
Info<< "Create fluid mesh for region " << fluidNames[i]
<< " for time = " << runTime.timeName() << nl << endl;
fluidRegions.set
(
i,
new fvMesh
(
IOobject
(
fluidNames[i],
runTime.timeName(),
runTime,
IOobject::MUST_READ
)
)
);
}

View File

@ -0,0 +1 @@
List<scalar> cumulativeContErr(fluidRegions.size(), 0.0);

View File

@ -0,0 +1,111 @@
{
bool closedVolume = p_rgh.needReference();
dimensionedScalar compressibility = fvc::domainIntegrate(psi);
bool compressible = (compressibility.value() > SMALL);
rho = thermo.rho();
volScalarField rAU("rAU", 1.0/UEqn().A());
surfaceScalarField rhorAUf("rhorAUf", fvc::interpolate(rho*rAU));
volVectorField HbyA("HbyA", U);
HbyA = rAU*UEqn().H();
surfaceScalarField phig(-rhorAUf*ghf*fvc::snGrad(rho)*mesh.magSf());
surfaceScalarField phiHbyA
(
"phiHbyA",
(
(fvc::interpolate(rho*HbyA) & mesh.Sf())
+ rhorAUf*fvc::ddtCorr(rho, U, phi)
)
+ phig
);
fvOptions.makeRelative(fvc::interpolate(rho), phiHbyA);
// Update the fixedFluxPressure BCs to ensure flux consistency
setSnGrad<fixedFluxPressureFvPatchScalarField>
(
p_rgh.boundaryField(),
(
phiHbyA.boundaryField()
- fvOptions.relative(mesh.Sf().boundaryField() & U.boundaryField())
*rho.boundaryField()
)/(mesh.magSf().boundaryField()*rhorAUf.boundaryField())
);
{
fvScalarMatrix p_rghDDtEqn
(
fvc::ddt(rho) + psi*correction(fvm::ddt(p_rgh))
+ fvc::div(phiHbyA)
);
// Thermodynamic density needs to be updated by psi*d(p) after the
// pressure solution - done in 2 parts. Part 1:
thermo.rho() -= psi*p_rgh;
for (int nonOrth=0; nonOrth<=nNonOrthCorr; nonOrth++)
{
fvScalarMatrix p_rghEqn
(
p_rghDDtEqn
- fvm::laplacian(rhorAUf, p_rgh)
);
p_rghEqn.solve
(
mesh.solver
(
p_rgh.select
(
(
oCorr == nOuterCorr-1
&& corr == nCorr-1
&& nonOrth == nNonOrthCorr
)
)
)
);
if (nonOrth == nNonOrthCorr)
{
phi = phiHbyA + p_rghEqn.flux();
U = HbyA
+ rAU*fvc::reconstruct((phig + p_rghEqn.flux())/rhorAUf);
U.correctBoundaryConditions();
fvOptions.correct(U);
K = 0.5*magSqr(U);
}
}
// Second part of thermodynamic density update
thermo.rho() += psi*p_rgh;
}
p = p_rgh + rho*gh;
// Update pressure time derivative if needed
if (thermo.dpdt())
{
dpdt = fvc::ddt(p);
}
// Solve continuity
#include "rhoEqn.H"
// Update continuity errors
#include "compressibleContinuityErrors.H"
// For closed-volume cases adjust the pressure and density levels
// to obey overall mass continuity
if (closedVolume && compressible)
{
p += (initialMass - fvc::domainIntegrate(thermo.rho()))
/compressibility;
rho = thermo.rho();
p_rgh = p - rho*gh;
}
}

View File

@ -0,0 +1,10 @@
const dictionary& pimple = mesh.solutionDict().subDict("PIMPLE");
const int nCorr =
pimple.lookupOrDefault<int>("nCorrectors", 1);
const int nNonOrthCorr =
pimple.lookupOrDefault<int>("nNonOrthogonalCorrectors", 0);
const bool momentumPredictor =
pimple.lookupOrDefault("momentumPredictor", true);

View File

@ -0,0 +1,32 @@
fvMesh& mesh = fluidRegions[i];
rhoThermo& thermo = thermoFluid[i];
thermo.validate(args.executable(), "h", "e");
volScalarField& rho = rhoFluid[i];
volVectorField& U = UFluid[i];
surfaceScalarField& phi = phiFluid[i];
compressible::turbulenceModel& turb = turbulence[i];
volScalarField& K = KFluid[i];
volScalarField& dpdt = dpdtFluid[i];
volScalarField& p = thermo.p();
const volScalarField& psi = thermo.psi();
volScalarField& p_rgh = p_rghFluid[i];
const volScalarField& gh = ghFluid[i];
const surfaceScalarField& ghf = ghfFluid[i];
radiation::radiationModel& rad = radiation[i];
fv::IOoptionList& fvOptions = fluidFvOptions[i];
const dimensionedScalar initialMass
(
"initialMass",
dimMass,
initialMassFluid[i]
);
const bool frozenFlow = frozenFlowFluid[i];

View File

@ -0,0 +1,34 @@
if (finalIter)
{
mesh.data::add("finalIteration", true);
}
if (frozenFlow)
{
#include "EEqn.H"
}
else
{
if (oCorr == 0)
{
#include "rhoEqn.H"
}
#include "UEqn.H"
#include "EEqn.H"
// --- PISO loop
for (int corr=0; corr<nCorr; corr++)
{
#include "pEqn.H"
}
turb.correct();
rho = thermo.rho();
}
if (finalIter)
{
mesh.data::remove("finalIteration");
}

View File

@ -0,0 +1,2 @@
p_rgh.storePrevIter();
rho.storePrevIter();

View File

@ -0,0 +1,58 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
\\/ 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
setInitialDeltaT
Description
Set the initial timestep for the CHT MultiRegion solver.
\*---------------------------------------------------------------------------*/
if (adjustTimeStep)
{
if ((runTime.timeIndex() == 0) && ((CoNum > SMALL) || (DiNum > SMALL)))
{
if (CoNum < SMALL)
{
CoNum = SMALL;
}
if (DiNum < SMALL)
{
DiNum = SMALL;
}
runTime.setDeltaT
(
min
(
min(maxCo/CoNum, maxDi/DiNum)*runTime.deltaT().value(),
maxDeltaT
)
);
Info<< "deltaT = " << runTime.deltaT().value() << endl;
}
}
// ************************************************************************* //

View File

@ -0,0 +1,68 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
\\/ 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
setMultiRegionDeltaT
Description
Reset the timestep to maintain a constant maximum courant and
diffusion Numbers. Reduction of time-step is immediate, but
increase is damped to avoid unstable oscillations.
\*---------------------------------------------------------------------------*/
if (adjustTimeStep)
{
if (CoNum == -GREAT)
{
CoNum = SMALL;
}
if (DiNum == -GREAT)
{
DiNum = SMALL;
}
scalar maxDeltaTFluid = maxCo/(CoNum + SMALL);
scalar maxDeltaTSolid = maxDi/(DiNum + SMALL);
scalar deltaTFluid =
min
(
min(maxDeltaTFluid, 1.0 + 0.1*maxDeltaTFluid),
1.2
);
runTime.setDeltaT
(
min
(
min(deltaTFluid, maxDeltaTSolid)*runTime.deltaT().value(),
maxDeltaT
)
);
Info<< "deltaT = " << runTime.deltaT().value() << endl;
}
// ************************************************************************* //

View File

@ -0,0 +1,8 @@
// We do not have a top-level mesh. Construct the fvSolution for
// the runTime instead.
fvSolution solutionDict(runTime);
const dictionary& pimple = solutionDict.subDict("PIMPLE");
const int nOuterCorr =
pimple.lookupOrDefault<int>("nOuterCorrectors", 1);

View File

@ -0,0 +1,107 @@
// Initialise solid field pointer lists
PtrList<coordinateSystem> coordinates(solidRegions.size());
PtrList<solidThermo> thermos(solidRegions.size());
PtrList<radiation::radiationModel> radiations(solidRegions.size());
PtrList<fv::IOoptionList> solidHeatSources(solidRegions.size());
PtrList<volScalarField> betavSolid(solidRegions.size());
PtrList<volSymmTensorField> aniAlphas(solidRegions.size());
// Populate solid field pointer lists
forAll(solidRegions, i)
{
Info<< "*** Reading solid mesh thermophysical properties for region "
<< solidRegions[i].name() << nl << endl;
Info<< " Adding to thermos\n" << endl;
thermos.set(i, solidThermo::New(solidRegions[i]));
Info<< " Adding to radiations\n" << endl;
radiations.set(i, radiation::radiationModel::New(thermos[i].T()));
Info<< " Adding fvOptions\n" << endl;
solidHeatSources.set
(
i,
new fv::IOoptionList(solidRegions[i])
);
if (!thermos[i].isotropic())
{
Info<< " Adding coordinateSystems\n" << endl;
coordinates.set
(
i,
coordinateSystem::New(solidRegions[i], thermos[i])
);
tmp<volVectorField> tkappaByCp =
thermos[i].Kappa()/thermos[i].Cp();
aniAlphas.set
(
i,
new volSymmTensorField
(
IOobject
(
"Anialpha",
runTime.timeName(),
solidRegions[i],
IOobject::NO_READ,
IOobject::NO_WRITE
),
solidRegions[i],
dimensionedSymmTensor
(
"zero",
tkappaByCp().dimensions(),
symmTensor::zero
),
zeroGradientFvPatchSymmTensorField::typeName
)
);
aniAlphas[i].internalField() =
coordinates[i].R().transformVector(tkappaByCp());
aniAlphas[i].correctBoundaryConditions();
}
IOobject betavSolidIO
(
"betavSolid",
runTime.timeName(),
solidRegions[i],
IOobject::MUST_READ,
IOobject::AUTO_WRITE
);
if (betavSolidIO.headerOk())
{
betavSolid.set
(
i,
new volScalarField(betavSolidIO, solidRegions[i])
);
}
else
{
betavSolid.set
(
i,
new volScalarField
(
IOobject
(
"betavSolid",
runTime.timeName(),
solidRegions[i],
IOobject::NO_READ,
IOobject::NO_WRITE
),
solidRegions[i],
dimensionedScalar("1", dimless, scalar(1.0))
)
);
}
}

View File

@ -0,0 +1,29 @@
const wordList solidsNames(rp["solid"]);
PtrList<fvMesh> solidRegions(solidsNames.size());
forAll(solidsNames, i)
{
Info<< "Create solid mesh for region " << solidsNames[i]
<< " for time = " << runTime.timeName() << nl << endl;
solidRegions.set
(
i,
new fvMesh
(
IOobject
(
solidsNames[i],
runTime.timeName(),
runTime,
IOobject::MUST_READ
)
)
);
// Force calculation of geometric properties to prevent it being done
// later in e.g. some boundary evaluation
//(void)solidRegions[i].weights();
//(void)solidRegions[i].deltaCoeffs();
}

View File

@ -0,0 +1,4 @@
const dictionary& pimple = mesh.solutionDict().subDict("PIMPLE");
int nNonOrthCorr =
pimple.lookupOrDefault<int>("nNonOrthogonalCorrectors", 0);

View File

@ -0,0 +1,34 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
\\/ 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
readSolidTimeControls
Description
Read the control parameters used in the solid
\*---------------------------------------------------------------------------*/
scalar maxDi = runTime.controlDict().lookupOrDefault<scalar>("maxDi", 10.0);
// ************************************************************************* //

View File

@ -0,0 +1,33 @@
fvMesh& mesh = solidRegions[i];
solidThermo& thermo = thermos[i];
const radiation::radiationModel& radiation = radiations[i];
tmp<volScalarField> trho = thermo.rho();
const volScalarField& rho = trho();
tmp<volScalarField> tcp = thermo.Cp();
const volScalarField& cp = tcp();
tmp<volSymmTensorField> taniAlpha;
if (!thermo.isotropic())
{
volSymmTensorField& aniAlpha = aniAlphas[i];
tmp<volVectorField> tkappaByCp = thermo.Kappa()/cp;
const coordinateSystem& coodSys = coordinates[i];
aniAlpha.internalField() =
coodSys.R().transformVector(tkappaByCp());
aniAlpha.correctBoundaryConditions();
taniAlpha = tmp<volSymmTensorField>
(
new volSymmTensorField(aniAlpha)
);
}
volScalarField& h = thermo.he();
const volScalarField& betav = betavSolid[i];
fv::IOoptionList& fvOptions = solidHeatSources[i];

View File

@ -0,0 +1,59 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
\\/ 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 "solidRegionDiffNo.H"
#include "fvc.H"
Foam::scalar Foam::solidRegionDiffNo
(
const fvMesh& mesh,
const Time& runTime,
const volScalarField& Cprho,
const volScalarField& kappa
)
{
scalar DiNum = 0.0;
scalar meanDiNum = 0.0;
//- Take care: can have fluid domains with 0 cells so do not test for
// zero internal faces.
surfaceScalarField kapparhoCpbyDelta
(
mesh.surfaceInterpolation::deltaCoeffs()
* fvc::interpolate(kappa)
/ fvc::interpolate(Cprho)
);
DiNum = gMax(kapparhoCpbyDelta.internalField())*runTime.deltaT().value();
meanDiNum = (average(kapparhoCpbyDelta)).value()*runTime.deltaT().value();
Info<< "Region: " << mesh.name() << " Diffusion Number mean: " << meanDiNum
<< " max: " << DiNum << endl;
return DiNum;
}
// ************************************************************************* //

View File

@ -0,0 +1,48 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
\\/ 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/>.
Description
Calculates and outputs the mean and maximum Diffusion Numbers for the solid
regions
\*---------------------------------------------------------------------------*/
#ifndef solidRegionDiff_H
#define solidRegionDiff_H
#include "fvMesh.H"
namespace Foam
{
scalar solidRegionDiffNo
(
const fvMesh& mesh,
const Time& runTime,
const volScalarField& Cprho,
const volScalarField& kappa
);
}
#endif
// ************************************************************************* //

View File

@ -0,0 +1,37 @@
scalar DiNum = -GREAT;
forAll(solidRegions, i)
{
//- Note: do not use setRegionSolidFields.H to avoid double registering Cp
//#include "setRegionSolidFields.H"
const solidThermo& thermo = thermos[i];
tmp<volScalarField> magKappa;
if (thermo.isotropic())
{
magKappa = thermo.kappa();
}
else
{
magKappa = mag(thermo.Kappa());
}
tmp<volScalarField> tcp = thermo.Cp();
const volScalarField& cp = tcp();
tmp<volScalarField> trho = thermo.rho();
const volScalarField& rho = trho();
DiNum = max
(
solidRegionDiffNo
(
solidRegions[i],
runTime,
rho*cp,
magKappa()
),
DiNum
);
}

View File

@ -0,0 +1,38 @@
if (finalIter)
{
mesh.data::add("finalIteration", true);
}
{
for (int nonOrth=0; nonOrth<=nNonOrthCorr; nonOrth++)
{
tmp<fvScalarMatrix> hEqn
(
fvm::ddt(betav*rho, h)
- (
thermo.isotropic()
? fvm::laplacian(betav*thermo.alpha(), h, "laplacian(alpha,h)")
: fvm::laplacian(betav*taniAlpha(), h, "laplacian(alpha,h)")
)
==
fvOptions(rho, h)
);
hEqn().relax();
fvOptions.constrain(hEqn());
hEqn().solve(mesh.solver(h.select(finalIter)));
fvOptions.correct(h);
}
}
thermo.correct();
Info<< "Min/max T:" << min(thermo.T()) << ' ' << max(thermo.T()) << endl;
if (finalIter)
{
mesh.data::remove("finalIteration");
}

View File

@ -0,0 +1,34 @@
{
volScalarField& he = thermo.he();
fvScalarMatrix EEqn
(
fvm::ddt(rho, he) + fvm::div(phi, he)
+ fvc::ddt(rho, K) + fvc::div(phi, K)
+ (
he.name() == "e"
? fvc::div
(
fvc::absolute(phi/fvc::interpolate(rho), U),
p,
"div(phiv,p)"
)
: -dpdt
)
- fvm::laplacian(alphaEff, he)
==
radiation->Sh(thermo)
+ fvOptions(rho, he)
);
EEqn.relax();
fvOptions.constrain(EEqn);
EEqn.solve();
fvOptions.correct(he);
thermo.correct();
radiation->correct();
}

View File

@ -0,0 +1,3 @@
thermoFoam.C
EXE = $(FOAM_APPBIN)/thermoFoam

View File

@ -0,0 +1,24 @@
EXE_INC = \
-I$(LIB_SRC)/finiteVolume/lnInclude \
-I$(LIB_SRC)/sampling/lnInclude \
-I$(LIB_SRC)/meshTools/lnInclude \
-I$(LIB_SRC)/fvOptions/lnInclude \
-I$(LIB_SRC)/thermophysicalModels/basic/lnInclude \
-I$(LIB_SRC)/thermophysicalModels/radiationModels/lnInclude \
-I$(LIB_SRC)/turbulenceModels \
-I$(LIB_SRC)/turbulenceModels/compressible/turbulenceModel/lnInclude \
-I$(LIB_SRC)/turbulenceModels/compressible/RAS/lnInclude \
-I$(LIB_SRC)/turbulenceModels/compressible/LES/lnInclude \
-I$(LIB_SRC)/turbulenceModels/LES/LESdeltas/lnInclude
EXE_LIBS = \
-lfiniteVolume \
-lsampling \
-lmeshTools \
-lfvOptions \
-lfluidThermophysicalModels \
-lradiationModels \
-lspecie \
-lcompressibleTurbulenceModel \
-lcompressibleRASModels \
-lcompressibleLESModels

View File

@ -0,0 +1,54 @@
Info<< "Reading thermophysical properties\n" << endl;
autoPtr<rhoThermo> pThermo(rhoThermo::New(mesh));
rhoThermo& thermo = pThermo();
thermo.validate(args.executable(), "h", "e");
volScalarField rho
(
IOobject
(
"rho",
runTime.timeName(),
mesh,
IOobject::NO_READ,
IOobject::NO_WRITE
),
thermo.rho()
);
volScalarField& p = thermo.p();
Info<< "Reading field U\n" << endl;
volVectorField U
(
IOobject
(
"U",
runTime.timeName(),
mesh,
IOobject::MUST_READ,
IOobject::AUTO_WRITE
),
mesh
);
#include "compressibleCreatePhi.H"
#include "setAlphaEff.H"
Info<< "Creating field dpdt\n" << endl;
volScalarField dpdt
(
IOobject
(
"dpdt",
runTime.timeName(),
mesh
),
mesh,
dimensionedScalar("dpdt", p.dimensions()/dimTime, 0)
);
Info<< "Creating field kinetic energy K\n" << endl;
volScalarField K("K", 0.5*magSqr(U));

View File

@ -0,0 +1,93 @@
Info<< "Creating turbulence model\n" << endl;
tmp<volScalarField> talphaEff;
IOobject turbulenceHeader
(
"turbulenceProperties",
runTime.constant(),
mesh,
IOobject::MUST_READ
);
IOobject RASHeader
(
"RASProperties",
runTime.constant(),
mesh,
IOobject::MUST_READ
);
IOobject LESHeader
(
"LESProperties",
runTime.constant(),
mesh,
IOobject::MUST_READ
);
if (turbulenceHeader.headerOk())
{
autoPtr<compressible::turbulenceModel> turbulence
(
compressible::turbulenceModel::New
(
rho,
U,
phi,
thermo
)
);
talphaEff = turbulence->alphaEff();
}
else if (RASHeader.headerOk())
{
autoPtr<compressible::RASModel> turbulence
(
compressible::RASModel::New
(
rho,
U,
phi,
thermo
)
);
talphaEff = turbulence->alphaEff();
}
else if (LESHeader.headerOk())
{
autoPtr<compressible::LESModel> turbulence
(
compressible::LESModel::New
(
rho,
U,
phi,
thermo
)
);
talphaEff = turbulence->alphaEff();
}
else
{
talphaEff = tmp<volScalarField>
(
new volScalarField
(
IOobject
(
"alphaEff",
runTime.timeName(),
mesh,
IOobject::NO_READ,
IOobject::NO_WRITE
),
mesh,
dimensionedScalar("0", dimMass/dimLength/dimTime, 0.0)
)
);
}
const volScalarField& alphaEff = talphaEff();

View File

@ -0,0 +1,107 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2013 OpenFOAM Foundation
\\/ 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
thermoFoam
Description
Evolves the thermodynamics on a frozen flow field
\*---------------------------------------------------------------------------*/
#include "fvCFD.H"
#include "rhoThermo.H"
#include "turbulenceModel.H"
#include "RASModel.H"
#include "LESModel.H"
#include "radiationModel.H"
#include "fvIOoptionList.H"
#include "simpleControl.H"
#include "pimpleControl.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
int main(int argc, char *argv[])
{
#include "setRootCase.H"
#include "createTime.H"
#include "createMesh.H"
#include "createFields.H"
#include "createFvOptions.H"
#include "createRadiationModel.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
Info<< "\nEvolving thermodynamics\n" << endl;
if (mesh.solutionDict().found("SIMPLE"))
{
simpleControl simple(mesh);
while (simple.loop())
{
Info<< "Time = " << runTime.timeName() << nl << endl;
while (simple.correctNonOrthogonal())
{
#include "EEqn.H"
}
Info<< "ExecutionTime = " << runTime.elapsedCpuTime() << " s"
<< " ClockTime = " << runTime.elapsedClockTime() << " s"
<< nl << endl;
runTime.write();
}
}
else
{
pimpleControl pimple(mesh);
while (runTime.run())
{
runTime++;
Info<< "Time = " << runTime.timeName() << nl << endl;
while (pimple.correctNonOrthogonal())
{
#include "EEqn.H"
}
Info<< "ExecutionTime = " << runTime.elapsedCpuTime() << " s"
<< " ClockTime = " << runTime.elapsedClockTime() << " s"
<< nl << endl;
runTime.write();
}
}
Info<< "End\n" << endl;
return 0;
}
// ************************************************************************* //