OpenFOAM-2.4.x/applications/solvers/basic/potentialFoam/potentialFoam.C
Henry 1f28b87185 potentialFoam: Upgrade to version in OpenFOAM-dev:
commit e593fef659bcd71028e0e66a70510de2c34888e2
Author: Henry <Henry>
Date:   Thu Feb 19 19:05:17 2015 +0000

    potentialFoam: Added new method to estimate the static pressure field from the velocity
    Uses a form of the Euler equation in which only variation along the streamlines is considered

commit cdadf4865de4808d6fe5c2a7eb5f5deaefe83b66
Author: Henry <Henry>
Date:   Sat Feb 14 11:03:37 2015 +0000

    potentialFoam: Solve for velocity potential named Phi rather than using the pressure field for this purpose

    The Phi field is read if available otherwise created automatically with
    boundary conditions obtained automatically from the pressure field if
    available (with optional name) otherwise inferred from the velocity
    field.  Phi Laplacian scheme and solver specification are required.  See
    tutorials for examples.
2015-04-25 21:59:15 +01:00

196 lines
5.2 KiB
C

/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2015 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
potentialFoam
Description
Potential flow solver which solves for the velocity potential
from which the flux-field is obtained and velocity field by reconstructing
the flux.
This application is particularly useful to generate starting fields for
Navier-Stokes codes.
\*---------------------------------------------------------------------------*/
#include "fvCFD.H"
#include "fvIOoptionList.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
int main(int argc, char *argv[])
{
argList::addOption
(
"pName",
"pName",
"Name of the pressure field"
);
argList::addBoolOption
(
"initialiseUBCs",
"Initialise U boundary conditions"
);
argList::addBoolOption
(
"writePhi",
"Write the velocity potential field"
);
argList::addBoolOption
(
"writep",
"Calculate and write the pressure field"
);
argList::addBoolOption
(
"withFunctionObjects",
"execute functionObjects"
);
#include "setRootCase.H"
#include "createTime.H"
#include "createMesh.H"
#include "readControls.H"
#include "createFields.H"
#include "createFvOptions.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
Info<< nl << "Calculating potential flow" << endl;
// Since solver contains no time loop it would never execute
// function objects so do it ourselves
runTime.functionObjects().start();
fvOptions.makeRelative(phi);
adjustPhi(phi, U, p);
// Non-orthogonal velocity potential corrector loop
for (int nonOrth=0; nonOrth<=nNonOrthCorr; nonOrth++)
{
fvScalarMatrix PhiEqn
(
fvm::laplacian(dimensionedScalar("1", dimless, 1), Phi)
==
fvc::div(phi)
);
PhiEqn.setReference(PhiRefCell, PhiRefValue);
PhiEqn.solve();
if (nonOrth == nNonOrthCorr)
{
phi -= PhiEqn.flux();
}
}
fvOptions.makeAbsolute(phi);
Info<< "Continuity error = "
<< mag(fvc::div(phi))().weightedAverage(mesh.V()).value()
<< endl;
U = fvc::reconstruct(phi);
U.correctBoundaryConditions();
Info<< "Interpolated velocity error = "
<< (sqrt(sum(sqr((fvc::interpolate(U) & mesh.Sf()) - phi)))
/sum(mesh.magSf())).value()
<< endl;
// Write U and phi
U.write();
phi.write();
// Optionally write Phi
if (args.optionFound("writePhi"))
{
Phi.write();
}
// Calculate the pressure field
if (args.optionFound("writep"))
{
Info<< nl << "Calculating approximate pressure field" << endl;
label pRefCell = 0;
scalar pRefValue = 0.0;
setRefCell
(
p,
potentialFlow,
pRefCell,
pRefValue
);
// Calculate the flow-direction filter tensor
volScalarField magSqrU(magSqr(U));
volSymmTensorField F(sqr(U)/(magSqrU + SMALL*average(magSqrU)));
// Calculate the divergence of the flow-direction filtered div(U*U)
// Filtering with the flow-direction generates a more reasonable
// pressure distribution in regions of high velocity gradient in the
// direction of the flow
volScalarField divDivUU
(
fvc::div
(
F & fvc::div(phi, U),
"div(div(phi,U))"
)
);
// Solve a Poisson equation for the approximate pressure
for (int nonOrth=0; nonOrth<=nNonOrthCorr; nonOrth++)
{
fvScalarMatrix pEqn
(
fvm::laplacian(p) + divDivUU
);
pEqn.setReference(pRefCell, pRefValue);
pEqn.solve();
}
p.write();
}
runTime.functionObjects().end();
Info<< "ExecutionTime = " << runTime.elapsedCpuTime() << " s"
<< " ClockTime = " << runTime.elapsedClockTime() << " s"
<< nl << endl;
Info<< "End\n" << endl;
return 0;
}
// ************************************************************************* //