FEATURE: Immersed boundary solver. Authors: Zeljko Tukovic, Hrvoje Jasak. Merge: Dominik Christ.
This commit is contained in:
commit
d08127d5a9
405 changed files with 253902 additions and 0 deletions
49
applications/solvers/immersedBoundary/SOLVER_COOKBOOK
Normal file
49
applications/solvers/immersedBoundary/SOLVER_COOKBOOK
Normal file
|
@ -0,0 +1,49 @@
|
|||
Make/options: add
|
||||
|
||||
-I$(LIB_SRC)/triSurface/lnInclude \
|
||||
-I$(LIB_SRC)/meshTools/lnInclude \
|
||||
-I../immersedBoundary/lnInclude
|
||||
|
||||
|
||||
-ltriSurface \
|
||||
-lmeshTools \
|
||||
-L$(FOAM_USER_LIBBIN) -limmersedBoundary \
|
||||
|
||||
|
||||
createFields.H: add
|
||||
|
||||
# include "createIbMasks.H"
|
||||
|
||||
|
||||
solver:
|
||||
|
||||
1) add immersed boundary headers
|
||||
|
||||
#include "immersedBoundaryFvPatch.H"
|
||||
#include "immersedBoundaryAdjustPhi.H"
|
||||
|
||||
2) on calculation of face fluxes (or their components), mask with faceIbMask
|
||||
|
||||
3) before to adjustPhi, add:
|
||||
|
||||
// Adjust immersed boundary fluxes
|
||||
immersedBoundaryAdjustPhi(phi, U);
|
||||
|
||||
4) on explicit updates, add correctBoundaryConditions();
|
||||
|
||||
eg.
|
||||
|
||||
U = fvc::reconstruct(phi);
|
||||
U.correctBoundaryConditions();
|
||||
|
||||
5) On reports of continuity error, add masking:
|
||||
|
||||
Info<< "IB-masked continuity error = "
|
||||
<< mag(cellIbMask*fvc::div(phi))().weightedAverage(mesh.V()).value()
|
||||
<< endl;
|
||||
|
||||
or use immersedBoundaryContinuityErrs.H
|
||||
|
||||
5) Chenge Courant number check to be IB-sensitive, using
|
||||
|
||||
immersedBoundaryCourantNo.H
|
|
@ -0,0 +1,3 @@
|
|||
icoIbFoam.C
|
||||
|
||||
EXE = $(FOAM_APPBIN)/icoIbFoam
|
15
applications/solvers/immersedBoundary/icoIbFoam/Make/options
Normal file
15
applications/solvers/immersedBoundary/icoIbFoam/Make/options
Normal file
|
@ -0,0 +1,15 @@
|
|||
EXE_INC = \
|
||||
-I$(LIB_SRC)/finiteVolume/lnInclude \
|
||||
-I$(LIB_SRC)/triSurface/lnInclude \
|
||||
-I$(LIB_SRC)/meshTools/lnInclude \
|
||||
-I$(LIB_SRC)/immersedBoundary/immersedBoundary/lnInclude
|
||||
|
||||
EXE_LIBS = \
|
||||
-lfiniteVolume \
|
||||
-ltriSurface \
|
||||
-lmeshTools \
|
||||
-lsurfMesh \
|
||||
-lsampling \
|
||||
-ldynamicMesh \
|
||||
-limmersedBoundary \
|
||||
-llduSolvers
|
|
@ -0,0 +1,55 @@
|
|||
Info<< "Reading transportProperties\n" << endl;
|
||||
|
||||
IOdictionary transportProperties
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
"transportProperties",
|
||||
runTime.constant(),
|
||||
mesh,
|
||||
IOobject::MUST_READ,
|
||||
IOobject::NO_WRITE
|
||||
)
|
||||
);
|
||||
|
||||
dimensionedScalar nu
|
||||
(
|
||||
transportProperties.lookup("nu")
|
||||
);
|
||||
|
||||
Info<< "Reading field p\n" << endl;
|
||||
volScalarField p
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
"p",
|
||||
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"
|
||||
|
||||
|
||||
label pRefCell = 0;
|
||||
scalar pRefValue = 0.0;
|
||||
setRefCell(p, mesh.solutionDict().subDict("PIMPLE"), pRefCell, pRefValue);
|
128
applications/solvers/immersedBoundary/icoIbFoam/icoIbFoam.C
Normal file
128
applications/solvers/immersedBoundary/icoIbFoam/icoIbFoam.C
Normal file
|
@ -0,0 +1,128 @@
|
|||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright held by original author
|
||||
\\/ 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 2 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, write to the Free Software Foundation,
|
||||
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
Application
|
||||
icoIbFoam
|
||||
|
||||
Description
|
||||
Transient solver for incompressible, laminar flow of Newtonian fluids
|
||||
with immersed boundary support.
|
||||
|
||||
Author
|
||||
Hrvoje Jasak, Wikki Ltd. All rights reserved
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "fvCFD.H"
|
||||
#include "immersedBoundaryFvPatch.H"
|
||||
#include "immersedBoundaryAdjustPhi.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
# include "setRootCase.H"
|
||||
|
||||
# include "createTime.H"
|
||||
# include "createMesh.H"
|
||||
# include "createIbMasks.H"
|
||||
# include "createFields.H"
|
||||
# include "initContinuityErrs.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
Info<< "\nStarting time loop\n" << endl;
|
||||
|
||||
while (runTime.loop())
|
||||
{
|
||||
Info<< "Time = " << runTime.timeName() << nl << endl;
|
||||
|
||||
# include "readPIMPLEControls.H"
|
||||
# include "CourantNo.H"
|
||||
|
||||
// Pressure-velocity corrector
|
||||
int oCorr = 0;
|
||||
do
|
||||
{
|
||||
fvVectorMatrix UEqn
|
||||
(
|
||||
fvm::ddt(U)
|
||||
+ fvm::div(phi, U)
|
||||
- fvm::laplacian(nu, U)
|
||||
);
|
||||
|
||||
solve(UEqn == -fvc::grad(p));
|
||||
|
||||
// --- PISO loop
|
||||
for (int corr = 0; corr < nCorr; corr++)
|
||||
{
|
||||
volScalarField rUA = 1.0/UEqn.A();
|
||||
|
||||
U = rUA*UEqn.H();
|
||||
// Immersed boundary update
|
||||
U.correctBoundaryConditions();
|
||||
|
||||
phi = faceIbMask*(fvc::interpolate(U) & mesh.Sf());
|
||||
|
||||
// Adjust immersed boundary fluxes
|
||||
immersedBoundaryAdjustPhi(phi, U);
|
||||
adjustPhi(phi, U, p);
|
||||
|
||||
for (int nonOrth = 0; nonOrth <= nNonOrthCorr; nonOrth++)
|
||||
{
|
||||
fvScalarMatrix pEqn
|
||||
(
|
||||
fvm::laplacian(rUA, p) == fvc::div(phi)
|
||||
);
|
||||
|
||||
pEqn.setReference(pRefCell, pRefValue);
|
||||
pEqn.solve();
|
||||
|
||||
if (nonOrth == nNonOrthCorr)
|
||||
{
|
||||
phi -= pEqn.flux();
|
||||
}
|
||||
}
|
||||
|
||||
# include "immersedBoundaryContinuityErrs.H"
|
||||
|
||||
U -= rUA*fvc::grad(p);
|
||||
U.correctBoundaryConditions();
|
||||
}
|
||||
} while (++oCorr < nOuterCorr);
|
||||
|
||||
runTime.write();
|
||||
|
||||
Info<< "ExecutionTime = " << runTime.elapsedCpuTime() << " s"
|
||||
<< " ClockTime = " << runTime.elapsedClockTime() << " s"
|
||||
<< nl << endl;
|
||||
}
|
||||
|
||||
Info<< "End\n" << endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
|
@ -0,0 +1,3 @@
|
|||
interIbFoam.C
|
||||
|
||||
EXE = $(FOAM_APPBIN)/interIbFoam
|
|
@ -0,0 +1,24 @@
|
|||
EXE_INC = \
|
||||
-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 \
|
||||
-I$(LIB_SRC)/triSurface/lnInclude \
|
||||
-I$(LIB_SRC)/meshTools/lnInclude \
|
||||
-I$(LIB_SRC)/immersedBoundary/immersedBoundary/lnInclude
|
||||
|
||||
EXE_LIBS = \
|
||||
-linterfaceProperties \
|
||||
-lincompressibleTransportModels \
|
||||
-lincompressibleTurbulenceModel \
|
||||
-lincompressibleRASModels \
|
||||
-lincompressibleLESModels \
|
||||
-lfiniteVolume \
|
||||
-ltriSurface \
|
||||
-lmeshTools \
|
||||
-lsurfMesh \
|
||||
-lsampling \
|
||||
-ldynamicMesh \
|
||||
-limmersedBoundary \
|
||||
-llduSolvers
|
34
applications/solvers/immersedBoundary/interIbFoam/UEqn.H
Normal file
34
applications/solvers/immersedBoundary/interIbFoam/UEqn.H
Normal file
|
@ -0,0 +1,34 @@
|
|||
surfaceScalarField muEff
|
||||
(
|
||||
"muEff",
|
||||
twoPhaseProperties.muf()
|
||||
+ fvc::interpolate(rho*turbulence->nut())
|
||||
);
|
||||
|
||||
fvVectorMatrix UEqn
|
||||
(
|
||||
fvm::ddt(rho, U)
|
||||
+ fvm::div(rhoPhi, U)
|
||||
- fvm::laplacian(muEff, U)
|
||||
- (fvc::grad(U) & fvc::grad(muEff))
|
||||
//- fvc::div(muEff*(fvc::interpolate(dev(fvc::grad(U))) & mesh.Sf()))
|
||||
);
|
||||
|
||||
UEqn.relax();
|
||||
|
||||
if (momentumPredictor)
|
||||
{
|
||||
solve
|
||||
(
|
||||
UEqn
|
||||
==
|
||||
fvc::reconstruct
|
||||
(
|
||||
(
|
||||
fvc::interpolate(interface.sigmaK())*fvc::snGrad(alpha1)
|
||||
- ghf*fvc::snGrad(rho)
|
||||
- fvc::snGrad(pd)
|
||||
) * mesh.magSf()
|
||||
)
|
||||
);
|
||||
}
|
37
applications/solvers/immersedBoundary/interIbFoam/alphaEqn.H
Normal file
37
applications/solvers/immersedBoundary/interIbFoam/alphaEqn.H
Normal file
|
@ -0,0 +1,37 @@
|
|||
{
|
||||
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 = faceIbMask*phic*interface.nHatf();
|
||||
|
||||
fvScalarMatrix alpha1Eqn
|
||||
(
|
||||
fvm::ddt(alpha1)
|
||||
+ fvm::div(phi, alpha1, alphaScheme)
|
||||
+ fvm::div
|
||||
(
|
||||
-fvc::flux(-phir, scalar(1) - alpha1, alpharScheme),
|
||||
alpha1,
|
||||
alpharScheme
|
||||
)
|
||||
);
|
||||
|
||||
alpha1Eqn.solve();
|
||||
|
||||
Info<< "Liquid phase volume fraction = "
|
||||
<< alpha1.weightedAverage(mesh.V()).value()
|
||||
<< " Min(alpha1) = " << min(cellIbMask*alpha1).value()
|
||||
<< " Max(alpha1) = " << max(cellIbMask*alpha1).value()
|
||||
<< endl;
|
||||
|
||||
// Limit alpha to handle IB cells
|
||||
alpha1.max(0);
|
||||
alpha1.min(1);
|
||||
|
||||
// Update of interface and density
|
||||
interface.correct();
|
||||
|
||||
rho == alpha1*rho1 + (scalar(1) - alpha1)*rho2;
|
||||
}
|
|
@ -0,0 +1,56 @@
|
|||
{
|
||||
# include "continuityErrs.H"
|
||||
|
||||
wordList pcorrTypes
|
||||
(
|
||||
pd.boundaryField().size(),
|
||||
zeroGradientFvPatchScalarField::typeName
|
||||
);
|
||||
|
||||
for (label i=0; i<pd.boundaryField().size(); i++)
|
||||
{
|
||||
if (pd.boundaryField()[i].fixesValue())
|
||||
{
|
||||
pcorrTypes[i] = fixedValueFvPatchScalarField::typeName;
|
||||
}
|
||||
}
|
||||
|
||||
volScalarField pcorr
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
"pcorr",
|
||||
runTime.timeName(),
|
||||
mesh,
|
||||
IOobject::NO_READ,
|
||||
IOobject::NO_WRITE
|
||||
),
|
||||
mesh,
|
||||
dimensionedScalar("pcorr", pd.dimensions(), 0.0),
|
||||
pcorrTypes
|
||||
);
|
||||
|
||||
dimensionedScalar rUAf("(1|A(U))", dimTime/rho.dimensions(), 1.0);
|
||||
|
||||
// Adjust immersed boundary fluxes
|
||||
immersedBoundaryAdjustPhi(phi, U);
|
||||
adjustPhi(phi, U, pcorr);
|
||||
|
||||
for(int nonOrth=0; nonOrth<=nNonOrthCorr; nonOrth++)
|
||||
{
|
||||
fvScalarMatrix pcorrEqn
|
||||
(
|
||||
fvm::laplacian(rUAf, pcorr) == fvc::div(phi)
|
||||
);
|
||||
|
||||
pcorrEqn.setReference(pdRefCell, pdRefValue);
|
||||
pcorrEqn.solve();
|
||||
|
||||
if (nonOrth == nNonOrthCorr)
|
||||
{
|
||||
phi -= pcorrEqn.flux();
|
||||
}
|
||||
}
|
||||
|
||||
# include "immersedBoundaryContinuityErrs.H"
|
||||
}
|
138
applications/solvers/immersedBoundary/interIbFoam/createFields.H
Normal file
138
applications/solvers/immersedBoundary/interIbFoam/createFields.H
Normal file
|
@ -0,0 +1,138 @@
|
|||
Info<< "Reading field pd\n" << endl;
|
||||
volScalarField pd
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
"pd",
|
||||
runTime.timeName(),
|
||||
mesh,
|
||||
IOobject::MUST_READ,
|
||||
IOobject::AUTO_WRITE
|
||||
),
|
||||
mesh
|
||||
);
|
||||
|
||||
Info<< "Reading field alpha1\n" << endl;
|
||||
volScalarField alpha1
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
"alpha1",
|
||||
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"
|
||||
|
||||
|
||||
Info<< "Reading transportProperties\n" << endl;
|
||||
twoPhaseMixture twoPhaseProperties(U, phi, "alpha1");
|
||||
|
||||
const dimensionedScalar& rho1 = twoPhaseProperties.rho1();
|
||||
const dimensionedScalar& rho2 = twoPhaseProperties.rho2();
|
||||
|
||||
|
||||
// Need to store rho for ddt(rho, U)
|
||||
volScalarField rho
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
"rho",
|
||||
runTime.timeName(),
|
||||
mesh,
|
||||
IOobject::READ_IF_PRESENT
|
||||
),
|
||||
alpha1*rho1 + (scalar(1) - alpha1)*rho2,
|
||||
alpha1.boundaryField().types()
|
||||
);
|
||||
rho.oldTime();
|
||||
|
||||
|
||||
// Mass flux
|
||||
// Initialisation does not matter because rhoPhi is reset after the
|
||||
// alpha1 solution before it is used in the U equation.
|
||||
surfaceScalarField rhoPhi
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
"rho*phi",
|
||||
runTime.timeName(),
|
||||
mesh,
|
||||
IOobject::NO_READ,
|
||||
IOobject::NO_WRITE
|
||||
),
|
||||
rho1*phi
|
||||
);
|
||||
|
||||
|
||||
Info<< "Calculating field g.h\n" << endl;
|
||||
volScalarField gh("gh", g & mesh.C());
|
||||
surfaceScalarField ghf("gh", g & mesh.Cf());
|
||||
|
||||
volScalarField p
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
"p",
|
||||
runTime.timeName(),
|
||||
mesh,
|
||||
IOobject::NO_READ,
|
||||
IOobject::AUTO_WRITE
|
||||
),
|
||||
pd + rho*gh
|
||||
);
|
||||
|
||||
|
||||
label pdRefCell = 0;
|
||||
scalar pdRefValue = 0.0;
|
||||
setRefCell
|
||||
(
|
||||
pd,
|
||||
mesh.solutionDict().subDict("PIMPLE"),
|
||||
pdRefCell,
|
||||
pdRefValue
|
||||
);
|
||||
|
||||
scalar pRefValue = 0.0;
|
||||
|
||||
if (pd.needReference())
|
||||
{
|
||||
pRefValue = readScalar
|
||||
(
|
||||
mesh.solutionDict().subDict("PIMPLE").lookup("pRefValue")
|
||||
);
|
||||
|
||||
p += dimensionedScalar
|
||||
(
|
||||
"p",
|
||||
p.dimensions(),
|
||||
pRefValue - getRefCellValue(p, pdRefCell)
|
||||
);
|
||||
}
|
||||
|
||||
// Construct interface from alpha1 distribution
|
||||
interfaceProperties interface(alpha1, U, twoPhaseProperties);
|
||||
|
||||
// Construct incompressible turbulence model
|
||||
autoPtr<incompressible::turbulenceModel> turbulence
|
||||
(
|
||||
incompressible::turbulenceModel::New(U, phi, twoPhaseProperties)
|
||||
);
|
136
applications/solvers/immersedBoundary/interIbFoam/interIbFoam.C
Normal file
136
applications/solvers/immersedBoundary/interIbFoam/interIbFoam.C
Normal file
|
@ -0,0 +1,136 @@
|
|||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright held by original author
|
||||
\\/ 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 2 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, write to the Free Software Foundation,
|
||||
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
Application
|
||||
interIbFoam
|
||||
|
||||
Description
|
||||
Solver for 2 incompressible, isothermal immiscible fluids using a VOF
|
||||
(volume of fluid) phase-fraction based interface capturing approach,
|
||||
with immersed boundary support
|
||||
|
||||
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.
|
||||
|
||||
Author
|
||||
Hrvoje Jasak, Wikki Ltd. All rights reserved
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "fvCFD.H"
|
||||
#include "interfaceProperties.H"
|
||||
#include "twoPhaseMixture.H"
|
||||
#include "turbulenceModel.H"
|
||||
|
||||
#include "immersedBoundaryFvPatch.H"
|
||||
#include "immersedBoundaryAdjustPhi.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
# include "setRootCase.H"
|
||||
# include "createTime.H"
|
||||
# include "createMesh.H"
|
||||
# include "readGravitationalAcceleration.H"
|
||||
# include "readPIMPLEControls.H"
|
||||
# include "initContinuityErrs.H"
|
||||
# include "createFields.H"
|
||||
# include "createIbMasks.H"
|
||||
# include "readTimeControls.H"
|
||||
# include "correctPhi.H"
|
||||
# include "CourantNo.H"
|
||||
# include "setInitialDeltaT.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
Info<< "\nStarting time loop\n" << endl;
|
||||
|
||||
while (runTime.run())
|
||||
{
|
||||
# include "readPIMPLEControls.H"
|
||||
# include "readTimeControls.H"
|
||||
# include "immersedBoundaryCourantNo.H"
|
||||
# include "setDeltaT.H"
|
||||
|
||||
runTime++;
|
||||
|
||||
Info<< "Time = " << runTime.timeName() << nl << endl;
|
||||
|
||||
// Pressure-velocity corrector
|
||||
int oCorr = 0;
|
||||
do
|
||||
{
|
||||
twoPhaseProperties.correct();
|
||||
|
||||
# include "alphaEqn.H"
|
||||
|
||||
# include "UEqn.H"
|
||||
|
||||
// --- PISO loop
|
||||
for (int corr = 0; corr < nCorr; corr++)
|
||||
{
|
||||
# include "pEqn.H"
|
||||
}
|
||||
|
||||
# include "immersedBoundaryContinuityErrs.H"
|
||||
|
||||
# include "limitU.H"
|
||||
|
||||
// Recalculate the mass fluxes
|
||||
rhoPhi = phi*fvc::interpolate(rho);
|
||||
|
||||
p = pd + cellIbMask*rho*gh;
|
||||
|
||||
if (pd.needReference())
|
||||
{
|
||||
p += dimensionedScalar
|
||||
(
|
||||
"p",
|
||||
p.dimensions(),
|
||||
pRefValue - getRefCellValue(p, pdRefCell)
|
||||
);
|
||||
}
|
||||
|
||||
turbulence->correct();
|
||||
} while (++oCorr < nOuterCorr);
|
||||
|
||||
runTime.write();
|
||||
|
||||
Info<< "ExecutionTime = " << runTime.elapsedCpuTime() << " s"
|
||||
<< " ClockTime = " << runTime.elapsedClockTime() << " s"
|
||||
<< nl << endl;
|
||||
}
|
||||
|
||||
Info<< "End\n" << endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
24
applications/solvers/immersedBoundary/interIbFoam/limitU.H
Normal file
24
applications/solvers/immersedBoundary/interIbFoam/limitU.H
Normal file
|
@ -0,0 +1,24 @@
|
|||
{
|
||||
scalar limitMagU = readScalar(pimple.lookup("limitMagU"));
|
||||
|
||||
volScalarField magU(mag(U));
|
||||
|
||||
scalar maxMagU = max(magU).value();
|
||||
|
||||
Info<< "mag(U): max: " << maxMagU
|
||||
<< " avg: " << magU.weightedAverage(mesh.V()).value();
|
||||
|
||||
if (maxMagU > limitMagU)
|
||||
{
|
||||
U.internalField() *=
|
||||
neg(magU.internalField() - limitMagU)
|
||||
+ pos(magU.internalField() - limitMagU)*
|
||||
limitMagU/(magU.internalField() + SMALL);
|
||||
U.correctBoundaryConditions();
|
||||
Info << " ...limiting" << endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
Info << endl;
|
||||
}
|
||||
}
|
64
applications/solvers/immersedBoundary/interIbFoam/pEqn.H
Normal file
64
applications/solvers/immersedBoundary/interIbFoam/pEqn.H
Normal file
|
@ -0,0 +1,64 @@
|
|||
{
|
||||
if (nOuterCorr != 1)
|
||||
{
|
||||
pd.storePrevIter();
|
||||
}
|
||||
|
||||
volScalarField rUA = 1.0/UEqn.A();
|
||||
surfaceScalarField rUAf = fvc::interpolate(rUA);
|
||||
|
||||
U = rUA*UEqn.H();
|
||||
// Immersed boundary update
|
||||
U.correctBoundaryConditions();
|
||||
|
||||
surfaceScalarField phiU
|
||||
(
|
||||
"phiU",
|
||||
faceIbMask*(fvc::interpolate(U) & mesh.Sf())
|
||||
);
|
||||
|
||||
// Adjust immersed boundary fluxes
|
||||
immersedBoundaryAdjustPhi(phiU, U);
|
||||
adjustPhi(phiU, U, pd);
|
||||
|
||||
phi = phiU
|
||||
+ faceIbMask*
|
||||
(
|
||||
fvc::interpolate(interface.sigmaK())*fvc::snGrad(alpha1)
|
||||
- ghf*fvc::snGrad(rho)
|
||||
)*rUAf*mesh.magSf();
|
||||
|
||||
|
||||
for(int nonOrth = 0; nonOrth <= nNonOrthCorr; nonOrth++)
|
||||
{
|
||||
fvScalarMatrix pdEqn
|
||||
(
|
||||
fvm::laplacian(rUAf, pd) == fvc::div(phi)
|
||||
);
|
||||
|
||||
pdEqn.setReference(pdRefCell, pdRefValue);
|
||||
|
||||
if (corr == nCorr - 1 && nonOrth == nNonOrthCorr)
|
||||
{
|
||||
pdEqn.solve(mesh.solutionDict().solver(pd.name() + "Final"));
|
||||
}
|
||||
else
|
||||
{
|
||||
pdEqn.solve(mesh.solutionDict().solver(pd.name()));
|
||||
}
|
||||
|
||||
if (nonOrth == nNonOrthCorr)
|
||||
{
|
||||
phi -= pdEqn.flux();
|
||||
}
|
||||
}
|
||||
|
||||
// Explicitly relax pressure except for last corrector
|
||||
if (oCorr != nOuterCorr - 1)
|
||||
{
|
||||
pd.relax();
|
||||
}
|
||||
|
||||
U += rUA*fvc::reconstruct((phi - phiU)/rUAf);
|
||||
U.correctBoundaryConditions();
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
porousSimpleIbFoam.C
|
||||
|
||||
EXE = $(FOAM_APPBIN)/porousSimpleIbFoam
|
|
@ -0,0 +1,22 @@
|
|||
EXE_INC = \
|
||||
-I$(LIB_SRC)/turbulenceModels \
|
||||
-I$(LIB_SRC)/turbulenceModels/incompressible/RAS/RASModel \
|
||||
-I$(LIB_SRC)/transportModels \
|
||||
-I$(LIB_SRC)/transportModels/incompressible/singlePhaseTransportModel \
|
||||
-I$(LIB_SRC)/finiteVolume/lnInclude \
|
||||
-I$(LIB_SRC)/triSurface/lnInclude \
|
||||
-I$(LIB_SRC)/meshTools/lnInclude \
|
||||
-I$(LIB_SRC)/immersedBoundary/immersedBoundary/lnInclude
|
||||
|
||||
EXE_LIBS = \
|
||||
-lincompressibleRASModels \
|
||||
-lincompressibleTransportModels \
|
||||
-lfiniteVolume \
|
||||
-ltriSurface \
|
||||
-lmeshTools \
|
||||
-lsurfMesh \
|
||||
-lsampling \
|
||||
-ldynamicMesh \
|
||||
-limmersedBoundary \
|
||||
-limmersedBoundaryTurbulence \
|
||||
-llduSolvers
|
|
@ -0,0 +1,17 @@
|
|||
// Solve the Momentum equation
|
||||
tmp<fvVectorMatrix> UEqn
|
||||
(
|
||||
fvm::div(phi, U)
|
||||
+ turbulence->divDevReff(U)
|
||||
);
|
||||
|
||||
UEqn().relax();
|
||||
|
||||
pZones.addResistance(UEqn());
|
||||
|
||||
eqnResidual = solve
|
||||
(
|
||||
UEqn() == -fvc::grad(p)
|
||||
).initialResidual();
|
||||
|
||||
maxResidual = max(eqnResidual, maxResidual);
|
|
@ -0,0 +1,9 @@
|
|||
// check convergence
|
||||
|
||||
if (maxResidual < convergenceCriterion)
|
||||
{
|
||||
Info<< "reached convergence criterion: " << convergenceCriterion << endl;
|
||||
runTime.writeAndEnd();
|
||||
Info<< "latestTime = " << runTime.timeName() << endl;
|
||||
}
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
Info << "Reading field p\n" << endl;
|
||||
volScalarField p
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
"p",
|
||||
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"
|
||||
|
||||
|
||||
label pRefCell = 0;
|
||||
scalar pRefValue = 0.0;
|
||||
setRefCell(p, mesh.solutionDict().subDict("SIMPLE"), pRefCell, pRefValue);
|
||||
|
||||
|
||||
singlePhaseTransportModel laminarTransport(U, phi);
|
||||
|
||||
autoPtr<incompressible::RASModel> turbulence
|
||||
(
|
||||
incompressible::RASModel::New(U, phi, laminarTransport)
|
||||
);
|
||||
|
||||
porousZones pZones(mesh);
|
|
@ -0,0 +1,7 @@
|
|||
// initialize values for convergence checks
|
||||
|
||||
scalar eqnResidual = 1, maxResidual = 0;
|
||||
scalar convergenceCriterion = 0;
|
||||
|
||||
simple.readIfPresent("convergence", convergenceCriterion);
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
p.boundaryField().updateCoeffs();
|
||||
|
||||
volScalarField AU = UEqn().A();
|
||||
|
||||
U = UEqn().H()/AU;
|
||||
// Immersed boundary update
|
||||
U.correctBoundaryConditions();
|
||||
|
||||
UEqn.clear();
|
||||
phi = faceIbMask*(fvc::interpolate(U) & mesh.Sf());
|
||||
|
||||
// Adjust immersed boundary fluxes
|
||||
immersedBoundaryAdjustPhi(phi, U);
|
||||
adjustPhi(phi, U, p);
|
||||
|
||||
// Non-orthogonal pressure corrector loop
|
||||
for (int nonOrth=0; nonOrth<=nNonOrthCorr; nonOrth++)
|
||||
{
|
||||
fvScalarMatrix pEqn
|
||||
(
|
||||
fvm::laplacian(1.0/AU, p) == fvc::div(phi)
|
||||
);
|
||||
|
||||
pEqn.setReference(pRefCell, pRefValue);
|
||||
|
||||
// Retain the residual from the first iteration
|
||||
if (nonOrth == 0)
|
||||
{
|
||||
eqnResidual = pEqn.solve().initialResidual();
|
||||
maxResidual = max(eqnResidual, maxResidual);
|
||||
}
|
||||
else
|
||||
{
|
||||
pEqn.solve();
|
||||
}
|
||||
|
||||
if (nonOrth == nNonOrthCorr)
|
||||
{
|
||||
phi -= pEqn.flux();
|
||||
}
|
||||
}
|
||||
|
||||
# include "immersedBoundaryContinuityErrs.H"
|
||||
|
||||
// Explicitly relax pressure for momentum corrector
|
||||
p.relax();
|
||||
|
||||
// Momentum corrector
|
||||
U -= fvc::grad(p)/AU;
|
||||
U.correctBoundaryConditions();
|
||||
|
|
@ -0,0 +1,92 @@
|
|||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright held by original author
|
||||
\\/ 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 2 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, write to the Free Software Foundation,
|
||||
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
Application
|
||||
simpleIbFoam
|
||||
|
||||
Description
|
||||
Steady-state solver for incompressible, turbulent flow
|
||||
with porous zones and immersed boundary support.
|
||||
|
||||
Author
|
||||
Hrvoje Jasak, Wikki Ltd. All rights reserved
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "fvCFD.H"
|
||||
#include "singlePhaseTransportModel.H"
|
||||
#include "RASModel.H"
|
||||
#include "porousZones.H"
|
||||
|
||||
#include "immersedBoundaryFvPatch.H"
|
||||
#include "immersedBoundaryAdjustPhi.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
# include "setRootCase.H"
|
||||
# include "createTime.H"
|
||||
# include "createMesh.H"
|
||||
# include "createIbMasks.H"
|
||||
# include "createFields.H"
|
||||
# include "initContinuityErrs.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
Info<< "\nStarting time loop\n" << endl;
|
||||
|
||||
while (runTime.loop())
|
||||
{
|
||||
Info<< "Time = " << runTime.timeName() << nl << endl;
|
||||
|
||||
# include "readSIMPLEControls.H"
|
||||
# include "initConvergenceCheck.H"
|
||||
|
||||
p.storePrevIter();
|
||||
|
||||
// Pressure-velocity SIMPLE corrector
|
||||
{
|
||||
# include "UEqn.H"
|
||||
# include "pEqn.H"
|
||||
}
|
||||
|
||||
turbulence->correct();
|
||||
|
||||
runTime.write();
|
||||
|
||||
Info<< "ExecutionTime = " << runTime.elapsedCpuTime() << " s"
|
||||
<< " ClockTime = " << runTime.elapsedClockTime() << " s"
|
||||
<< nl << endl;
|
||||
|
||||
# include "convergenceCheck.H"
|
||||
}
|
||||
|
||||
Info<< "End\n" << endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
|
@ -0,0 +1,3 @@
|
|||
potentialIbFoam.C
|
||||
|
||||
EXE = $(FOAM_APPBIN)/potentialIbFoam
|
|
@ -0,0 +1,15 @@
|
|||
EXE_INC = \
|
||||
-I$(LIB_SRC)/finiteVolume/lnInclude \
|
||||
-I$(LIB_SRC)/triSurface/lnInclude \
|
||||
-I$(LIB_SRC)/meshTools/lnInclude \
|
||||
-I$(LIB_SRC)/immersedBoundary/immersedBoundary/lnInclude
|
||||
|
||||
EXE_LIBS = \
|
||||
-lfiniteVolume \
|
||||
-ltriSurface \
|
||||
-lmeshTools \
|
||||
-lsurfMesh \
|
||||
-lsampling \
|
||||
-ldynamicMesh \
|
||||
-limmersedBoundary \
|
||||
-llduSolvers
|
|
@ -0,0 +1,49 @@
|
|||
Info<< "Reading field p\n" << endl;
|
||||
volScalarField p
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
"p",
|
||||
runTime.timeName(),
|
||||
mesh,
|
||||
IOobject::MUST_READ,
|
||||
IOobject::NO_WRITE
|
||||
),
|
||||
mesh
|
||||
);
|
||||
|
||||
// Do not reset p
|
||||
|
||||
Info<< "Reading field U\n" << endl;
|
||||
volVectorField U
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
"U",
|
||||
runTime.timeName(),
|
||||
mesh,
|
||||
IOobject::MUST_READ,
|
||||
IOobject::AUTO_WRITE
|
||||
),
|
||||
mesh
|
||||
);
|
||||
|
||||
// Do not reset U
|
||||
|
||||
surfaceScalarField phi
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
"phi",
|
||||
runTime.timeName(),
|
||||
mesh,
|
||||
IOobject::NO_READ,
|
||||
IOobject::AUTO_WRITE
|
||||
),
|
||||
fvc::interpolate(U) & mesh.Sf()
|
||||
);
|
||||
|
||||
|
||||
label pRefCell = 0;
|
||||
scalar pRefValue = 0.0;
|
||||
setRefCell(p, mesh.solutionDict().subDict("SIMPLE"), pRefCell, pRefValue);
|
|
@ -0,0 +1,229 @@
|
|||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright held by original author
|
||||
\\/ 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 2 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, write to the Free Software Foundation,
|
||||
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
Application
|
||||
potentialIbFoam
|
||||
|
||||
Description
|
||||
Potential flow solver with immersed boundary support.
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "fvCFD.H"
|
||||
#include "immersedBoundaryFvPatch.H"
|
||||
#include "immersedBoundaryAdjustPhi.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
argList::validOptions.insert("writep", "");
|
||||
|
||||
# include "setRootCase.H"
|
||||
|
||||
# include "createTime.H"
|
||||
# include "createMesh.H"
|
||||
# include "createIbMasks.H"
|
||||
# include "createFields.H"
|
||||
# include "readSIMPLEControls.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
Info<< nl << "Calculating potential flow" << endl;
|
||||
|
||||
// Do correctors over the complete set
|
||||
for (int nonOrth=0; nonOrth<=nNonOrthCorr; nonOrth++)
|
||||
{
|
||||
phi = faceIbMask*(linearInterpolate(U) & mesh.Sf());
|
||||
|
||||
// Adjust immersed boundary fluxes
|
||||
immersedBoundaryAdjustPhi(phi, U);
|
||||
|
||||
// Adjust fluxes
|
||||
adjustPhi(phi, U, p);
|
||||
|
||||
p.storePrevIter();
|
||||
|
||||
fvScalarMatrix pEqn
|
||||
(
|
||||
fvm::laplacian
|
||||
(
|
||||
dimensionedScalar
|
||||
(
|
||||
"1",
|
||||
dimTime/p.dimensions()*dimensionSet(0, 2, -2, 0, 0),
|
||||
1
|
||||
),
|
||||
p
|
||||
)
|
||||
==
|
||||
fvc::div(phi)
|
||||
);
|
||||
|
||||
pEqn.setReference(pRefCell, pRefValue);
|
||||
pEqn.solve();
|
||||
|
||||
// Correct the flux
|
||||
phi -= pEqn.flux();
|
||||
|
||||
if (nonOrth != nNonOrthCorr)
|
||||
{
|
||||
p.relax();
|
||||
}
|
||||
|
||||
Info<< "p min " << gMin(p.internalField())
|
||||
<< " max " << gMax(p.internalField())
|
||||
<< " masked min "
|
||||
<< gMin(cellIbMask.internalField()*p.internalField())
|
||||
<< " max "
|
||||
<< gMax(cellIbMask.internalField()*p.internalField())
|
||||
<< endl;
|
||||
|
||||
Info<< "continuity error = "
|
||||
<< mag
|
||||
(
|
||||
fvc::div(faceIbMask*phi)
|
||||
)().weightedAverage(mesh.V()).value()
|
||||
<< endl;
|
||||
|
||||
Info<< "Contour continuity error = "
|
||||
<< mag(sum(phi.boundaryField()))
|
||||
<< endl;
|
||||
|
||||
U = fvc::reconstruct(phi);
|
||||
U.correctBoundaryConditions();
|
||||
|
||||
Info<< "Interpolated U error = "
|
||||
<< (
|
||||
sqrt
|
||||
(
|
||||
sum
|
||||
(
|
||||
sqr
|
||||
(
|
||||
faceIbMask*
|
||||
(
|
||||
fvc::interpolate(U) & mesh.Sf()
|
||||
)
|
||||
- phi
|
||||
)
|
||||
)
|
||||
)/sum(mesh.magSf())
|
||||
).value()
|
||||
<< endl;
|
||||
}
|
||||
|
||||
// Calculate velocity magnitude
|
||||
{
|
||||
volScalarField magU = cellIbMask*mag(U);
|
||||
|
||||
Info << "IB-masked mag(U): max: " << gMax(magU.internalField())
|
||||
<< " min: " << gMin(magU.internalField()) << endl;
|
||||
}
|
||||
|
||||
// Force the write
|
||||
U.write();
|
||||
phi.write();
|
||||
|
||||
cellIbMask.write();
|
||||
cellIbMaskExt.write();
|
||||
|
||||
if (args.optionFound("writep"))
|
||||
{
|
||||
// Find reference patch
|
||||
label refPatch = -1;
|
||||
scalar maxMagU = 0;
|
||||
|
||||
// Go through all velocity patches and find the one that fixes
|
||||
// velocity to the largest value
|
||||
|
||||
forAll (U.boundaryField(), patchI)
|
||||
{
|
||||
const fvPatchVectorField& Upatch = U.boundaryField()[patchI];
|
||||
|
||||
if (Upatch.fixesValue())
|
||||
{
|
||||
// Calculate mean velocity
|
||||
scalar u = sum(mag(Upatch));
|
||||
label patchSize = Upatch.size();
|
||||
|
||||
reduce(u, sumOp<scalar>());
|
||||
reduce(patchSize, sumOp<label>());
|
||||
|
||||
if (patchSize > 0)
|
||||
{
|
||||
scalar curMag = u/patchSize;
|
||||
|
||||
if (curMag > maxMagU)
|
||||
{
|
||||
refPatch = patchI;
|
||||
|
||||
maxMagU = curMag;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (refPatch > -1)
|
||||
{
|
||||
// Calculate reference pressure
|
||||
const fvPatchVectorField& Upatch = U.boundaryField()[refPatch];
|
||||
const fvPatchScalarField& pPatch = p.boundaryField()[refPatch];
|
||||
|
||||
scalar patchE = sum(mag(pPatch + 0.5*magSqr(Upatch)));
|
||||
label patchSize = Upatch.size();
|
||||
|
||||
reduce(patchE, sumOp<scalar>());
|
||||
reduce(patchSize, sumOp<label>());
|
||||
|
||||
scalar e = patchE/patchSize;
|
||||
|
||||
|
||||
Info<< "Using reference patch " << refPatch
|
||||
<< " with mag(U) = " << maxMagU
|
||||
<< " p + 0.5*U^2 = " << e << endl;
|
||||
|
||||
p.internalField() = e - 0.5*magSqr(U.internalField());
|
||||
p.correctBoundaryConditions();
|
||||
}
|
||||
else
|
||||
{
|
||||
Info<< "No reference patch found. Writing potential function"
|
||||
<< endl;
|
||||
}
|
||||
|
||||
p.write();
|
||||
}
|
||||
|
||||
Info<< "ExecutionTime = " << runTime.elapsedCpuTime() << " s"
|
||||
<< " ClockTime = " << runTime.elapsedClockTime() << " s"
|
||||
<< nl << endl;
|
||||
|
||||
Info<< "End\n" << endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
|
@ -0,0 +1,3 @@
|
|||
simpleIbFoam.C
|
||||
|
||||
EXE = $(FOAM_APPBIN)/simpleIbFoam
|
|
@ -0,0 +1,22 @@
|
|||
EXE_INC = \
|
||||
-I$(LIB_SRC)/turbulenceModels \
|
||||
-I$(LIB_SRC)/turbulenceModels/incompressible/RAS/RASModel \
|
||||
-I$(LIB_SRC)/transportModels \
|
||||
-I$(LIB_SRC)/transportModels/incompressible/singlePhaseTransportModel \
|
||||
-I$(LIB_SRC)/finiteVolume/lnInclude \
|
||||
-I$(LIB_SRC)/triSurface/lnInclude \
|
||||
-I$(LIB_SRC)/meshTools/lnInclude \
|
||||
-I$(LIB_SRC)/immersedBoundary/immersedBoundary/lnInclude
|
||||
|
||||
EXE_LIBS = \
|
||||
-lincompressibleRASModels \
|
||||
-lincompressibleTransportModels \
|
||||
-lfiniteVolume \
|
||||
-ltriSurface \
|
||||
-lmeshTools \
|
||||
-lsurfMesh \
|
||||
-lsampling \
|
||||
-ldynamicMesh \
|
||||
-limmersedBoundary \
|
||||
-limmersedBoundaryTurbulence \
|
||||
-llduSolvers
|
15
applications/solvers/immersedBoundary/simpleIbFoam/UEqn.H
Normal file
15
applications/solvers/immersedBoundary/simpleIbFoam/UEqn.H
Normal file
|
@ -0,0 +1,15 @@
|
|||
// Solve the Momentum equation
|
||||
tmp<fvVectorMatrix> UEqn
|
||||
(
|
||||
fvm::div(phi, U)
|
||||
+ turbulence->divDevReff(U)
|
||||
);
|
||||
|
||||
UEqn().relax();
|
||||
|
||||
eqnResidual = solve
|
||||
(
|
||||
UEqn() == -fvc::grad(p)
|
||||
).initialResidual();
|
||||
|
||||
maxResidual = max(eqnResidual, maxResidual);
|
|
@ -0,0 +1,9 @@
|
|||
// check convergence
|
||||
|
||||
if (maxResidual < convergenceCriterion)
|
||||
{
|
||||
Info<< "reached convergence criterion: " << convergenceCriterion << endl;
|
||||
runTime.writeAndEnd();
|
||||
Info<< "latestTime = " << runTime.timeName() << endl;
|
||||
}
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
Info<< "Reading field p\n" << endl;
|
||||
volScalarField p
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
"p",
|
||||
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"
|
||||
|
||||
|
||||
label pRefCell = 0;
|
||||
scalar pRefValue = 0.0;
|
||||
setRefCell(p, mesh.solutionDict().subDict("SIMPLE"), pRefCell, pRefValue);
|
||||
|
||||
|
||||
singlePhaseTransportModel laminarTransport(U, phi);
|
||||
|
||||
autoPtr<incompressible::RASModel> turbulence
|
||||
(
|
||||
incompressible::RASModel::New(U, phi, laminarTransport)
|
||||
);
|
|
@ -0,0 +1,7 @@
|
|||
// initialize values for convergence checks
|
||||
|
||||
scalar eqnResidual = 1, maxResidual = 0;
|
||||
scalar convergenceCriterion = 0;
|
||||
|
||||
simple.readIfPresent("convergence", convergenceCriterion);
|
||||
|
51
applications/solvers/immersedBoundary/simpleIbFoam/pEqn.H
Normal file
51
applications/solvers/immersedBoundary/simpleIbFoam/pEqn.H
Normal file
|
@ -0,0 +1,51 @@
|
|||
p.boundaryField().updateCoeffs();
|
||||
|
||||
volScalarField AU = UEqn().A();
|
||||
|
||||
U = UEqn().H()/AU;
|
||||
// Immersed boundary update
|
||||
U.correctBoundaryConditions();
|
||||
|
||||
UEqn.clear();
|
||||
phi = faceIbMask*(fvc::interpolate(U) & mesh.Sf());
|
||||
|
||||
// Adjust immersed boundary fluxes
|
||||
immersedBoundaryAdjustPhi(phi, U);
|
||||
adjustPhi(phi, U, p);
|
||||
|
||||
// Non-orthogonal pressure corrector loop
|
||||
for (int nonOrth = 0; nonOrth <= nNonOrthCorr; nonOrth++)
|
||||
{
|
||||
fvScalarMatrix pEqn
|
||||
(
|
||||
fvm::laplacian(1.0/AU, p) == fvc::div(phi)
|
||||
);
|
||||
|
||||
pEqn.setReference(pRefCell, pRefValue);
|
||||
|
||||
// Retain the residual from the first iteration
|
||||
if (nonOrth == 0)
|
||||
{
|
||||
eqnResidual = pEqn.solve().initialResidual();
|
||||
maxResidual = max(eqnResidual, maxResidual);
|
||||
}
|
||||
else
|
||||
{
|
||||
pEqn.solve();
|
||||
}
|
||||
|
||||
if (nonOrth == nNonOrthCorr)
|
||||
{
|
||||
phi -= pEqn.flux();
|
||||
}
|
||||
}
|
||||
|
||||
# include "immersedBoundaryContinuityErrs.H"
|
||||
|
||||
// Explicitly relax pressure for momentum corrector
|
||||
p.relax();
|
||||
|
||||
// Momentum corrector
|
||||
U -= fvc::grad(p)/AU;
|
||||
U.correctBoundaryConditions();
|
||||
|
|
@ -0,0 +1,91 @@
|
|||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright held by original author
|
||||
\\/ 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 2 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, write to the Free Software Foundation,
|
||||
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
Application
|
||||
simpleIbFoam
|
||||
|
||||
Description
|
||||
Steady-state solver for incompressible, turbulent flow
|
||||
with immersed boundary support.
|
||||
|
||||
Author
|
||||
Hrvoje Jasak, Wikki Ltd. All rights reserved
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "fvCFD.H"
|
||||
#include "singlePhaseTransportModel.H"
|
||||
#include "RASModel.H"
|
||||
|
||||
#include "immersedBoundaryFvPatch.H"
|
||||
#include "immersedBoundaryAdjustPhi.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
# include "setRootCase.H"
|
||||
# include "createTime.H"
|
||||
# include "createMesh.H"
|
||||
# include "createIbMasks.H"
|
||||
# include "createFields.H"
|
||||
# include "initContinuityErrs.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
Info<< "\nStarting time loop\n" << endl;
|
||||
|
||||
while (runTime.loop())
|
||||
{
|
||||
Info<< "Time = " << runTime.timeName() << nl << endl;
|
||||
|
||||
# include "readSIMPLEControls.H"
|
||||
# include "initConvergenceCheck.H"
|
||||
|
||||
p.storePrevIter();
|
||||
|
||||
// Pressure-velocity SIMPLE corrector
|
||||
{
|
||||
# include "UEqn.H"
|
||||
# include "pEqn.H"
|
||||
}
|
||||
|
||||
turbulence->correct();
|
||||
|
||||
runTime.write();
|
||||
|
||||
Info<< "ExecutionTime = " << runTime.elapsedCpuTime() << " s"
|
||||
<< " ClockTime = " << runTime.elapsedClockTime() << " s"
|
||||
<< nl << endl;
|
||||
|
||||
# include "convergenceCheck.H"
|
||||
}
|
||||
|
||||
Info<< "End\n" << endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
|
@ -0,0 +1,3 @@
|
|||
ibContinuityError.C
|
||||
|
||||
EXE = $(FOAM_APPBIN)/ibContinuityError
|
|
@ -0,0 +1,14 @@
|
|||
EXE_INC = \
|
||||
-I$(LIB_SRC)/postProcessing/postCalc \
|
||||
-I$(LIB_SRC)/finiteVolume/lnInclude \
|
||||
-I$(LIB_SRC)/immersedBoundary/lnInclude
|
||||
|
||||
EXE_LIBS = \
|
||||
$(FOAM_LIBBIN)/postCalc.o \
|
||||
-lfiniteVolume \
|
||||
-ltriSurface \
|
||||
-lmeshTools \
|
||||
-lsurfMesh \
|
||||
-lsampling \
|
||||
-ldynamicMesh \
|
||||
-limmersedBoundary
|
|
@ -0,0 +1,93 @@
|
|||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright held by original author
|
||||
\\/ 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 2 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, write to the Free Software Foundation,
|
||||
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
Application
|
||||
shapeDerivative
|
||||
|
||||
Description
|
||||
Calculate continuity error on immersed boundary mesh
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "calc.H"
|
||||
#include "fvc.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
void Foam::calc(const argList& args, const Time& runTime, const fvMesh& mesh)
|
||||
{
|
||||
IOobject phiHeader
|
||||
(
|
||||
"phi",
|
||||
runTime.timeName(),
|
||||
mesh,
|
||||
IOobject::MUST_READ
|
||||
);
|
||||
|
||||
IOobject faceIbMaskHeader
|
||||
(
|
||||
"faceIbMask",
|
||||
runTime.timeName(),
|
||||
mesh,
|
||||
IOobject::MUST_READ
|
||||
);
|
||||
|
||||
if (phiHeader.headerOk() && faceIbMaskHeader.headerOk())
|
||||
{
|
||||
Info<< " Reading phi" << endl;
|
||||
surfaceScalarField phi(phiHeader, mesh);
|
||||
|
||||
Info<< " Reading faceIbMask" << endl;
|
||||
surfaceScalarField faceIbMask(faceIbMaskHeader, mesh);
|
||||
|
||||
volScalarField contErr = fvc::div(faceIbMask*phi);
|
||||
|
||||
scalar sumLocalContErr = runTime.deltaT().value()*
|
||||
mag(contErr)().weightedAverage(mesh.V()).value();
|
||||
|
||||
scalar globalContErr = runTime.deltaT().value()*
|
||||
contErr.weightedAverage(mesh.V()).value();
|
||||
|
||||
Info<< "IB time step continuity errors : sum local = "
|
||||
<< sumLocalContErr
|
||||
<< ", global = " << globalContErr
|
||||
<< endl;
|
||||
|
||||
volScalarField magContErr
|
||||
(
|
||||
"magContErr",
|
||||
mag(contErr)
|
||||
);
|
||||
magContErr.write();
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
Info<< " No phi or faceIbMask" << endl;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
|
@ -0,0 +1,3 @@
|
|||
makeTriSurfaceMesh.C
|
||||
|
||||
EXE = $(FOAM_APPBIN)/makeTriSurfaceMesh
|
|
@ -0,0 +1,10 @@
|
|||
EXE_INC = \
|
||||
-I$(LIB_SRC)/finiteVolume/lnInclude \
|
||||
-I$(LIB_SRC)/cfdTools/general/lnInclude \
|
||||
-I$(LIB_SRC)/triSurface/lnInclude \
|
||||
-I$(LIB_SRC)/meshTools/lnInclude
|
||||
|
||||
EXE_LIBS = \
|
||||
-lfiniteVolume \
|
||||
-ltriSurface \
|
||||
-lmeshTools
|
|
@ -0,0 +1,76 @@
|
|||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright held by original author
|
||||
\\/ 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 2 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, write to the Free Software Foundation,
|
||||
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
Application
|
||||
makeTriSurfaceMesh
|
||||
|
||||
Description
|
||||
Generate a triSurface mesh from fvMesh patches
|
||||
|
||||
Author
|
||||
Zeljko Tukovic
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "fvCFD.H"
|
||||
#include "triSurface.H"
|
||||
#include "triSurfaceTools.H"
|
||||
// #include "labelHashSet.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
# include "setRootCase.H"
|
||||
# include "createTime.H"
|
||||
# include "createMesh.H"
|
||||
|
||||
labelHashSet includedPatches;
|
||||
|
||||
forAll (mesh.boundaryMesh(), patchI)
|
||||
{
|
||||
includedPatches.insert(patchI);
|
||||
}
|
||||
|
||||
triSurface triSurf =
|
||||
triSurfaceTools::triangulate
|
||||
(
|
||||
mesh.boundaryMesh(),
|
||||
includedPatches
|
||||
);
|
||||
|
||||
|
||||
// Writing triSurface mesh
|
||||
Info << "Write triSurface mesh ... ";
|
||||
|
||||
triSurf.write(runTime.caseName() + ".stl");
|
||||
triSurf.write(runTime.caseName() + ".ftr");
|
||||
|
||||
Info << "done" << endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
|
@ -0,0 +1,3 @@
|
|||
refineImmersedBoundaryMesh.C
|
||||
|
||||
EXE = $(FOAM_APPBIN)/refineImmersedBoundaryMesh
|
|
@ -0,0 +1,15 @@
|
|||
EXE_INC = \
|
||||
-I$(LIB_SRC)/immersedBoundary/immersedBoundary/lnInclude \
|
||||
-I$(LIB_SRC)/dynamicMesh/dynamicMesh/lnInclude \
|
||||
-I$(LIB_SRC)/finiteVolume/lnInclude \
|
||||
-I$(LIB_SRC)/triSurface/lnInclude \
|
||||
-I$(LIB_SRC)/meshTools/lnInclude
|
||||
|
||||
EXE_LIBS = \
|
||||
-lfiniteVolume \
|
||||
-ltriSurface \
|
||||
-lmeshTools \
|
||||
-lsurfMesh \
|
||||
-lsampling \
|
||||
-ldynamicMesh \
|
||||
-limmersedBoundary
|
|
@ -0,0 +1,93 @@
|
|||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright held by original author
|
||||
\\/ 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 2 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, write to the Free Software Foundation,
|
||||
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
Application
|
||||
refineImmersedBoundaryMesh
|
||||
|
||||
Description
|
||||
Refine the background mesh around the immersed surface
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "fvCFD.H"
|
||||
#include "refineImmersedBoundaryMesh.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
argList::validOptions.insert("ibCells", "");
|
||||
argList::validOptions.insert("ibCellCells", "");
|
||||
argList::validOptions.insert("ibCellCellFaces", "");
|
||||
|
||||
# include "setRootCase.H"
|
||||
|
||||
# include "createTime.H"
|
||||
# include "createMesh.H"
|
||||
|
||||
refineImmersedBoundaryMesh rib(mesh);
|
||||
|
||||
labelList rc;
|
||||
|
||||
if (args.optionFound("ibCells"))
|
||||
{
|
||||
rc = rib.refinementCells
|
||||
(
|
||||
refineImmersedBoundaryMesh::IB_CELLS
|
||||
);
|
||||
}
|
||||
else if (args.optionFound("ibCellCells"))
|
||||
{
|
||||
rc = rib.refinementCells
|
||||
(
|
||||
refineImmersedBoundaryMesh::IB_CELL_CELLS
|
||||
);
|
||||
}
|
||||
else if (args.optionFound("ibCellCellFaces"))
|
||||
{
|
||||
rc = rib.refinementCells
|
||||
(
|
||||
refineImmersedBoundaryMesh::IB_CELL_CELL_FACES
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
FatalErrorIn(args.executable())
|
||||
<< "Specify one of the available options for cell selection: "
|
||||
<< "[-ibCells] [-ibCellCells] [-ibCellCellFaces]" << nl
|
||||
<< exit(FatalError);
|
||||
}
|
||||
|
||||
Info<< "Number of refinement cells = " << rc.size() << endl;
|
||||
|
||||
rib.refineMesh(rc);
|
||||
mesh.write();
|
||||
|
||||
Info<< "End\n" << endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
|
@ -0,0 +1,3 @@
|
|||
surfaceInvertNormal.C
|
||||
|
||||
EXE = $(FOAM_APPBIN)/surfaceInvertNormal
|
|
@ -0,0 +1,7 @@
|
|||
EXE_INC = \
|
||||
-I$(LIB_SRC)/triSurface/lnInclude \
|
||||
-I$(LIB_SRC)/meshTools/lnInclude
|
||||
|
||||
EXE_LIBS = \
|
||||
-ltriSurface \
|
||||
-lmeshTools
|
|
@ -0,0 +1,79 @@
|
|||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright held by original author
|
||||
\\/ 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 2 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, write to the Free Software Foundation,
|
||||
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
Description
|
||||
Write surface and normal vector
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "argList.H"
|
||||
#include "triSurface.H"
|
||||
#include "IFstream.H"
|
||||
|
||||
using namespace Foam;
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
// Main program:
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
argList::noParallel();
|
||||
argList::validArgs.clear();
|
||||
|
||||
argList::validArgs.append("surface file");
|
||||
argList::validArgs.append("output surface file");
|
||||
argList args(argc, argv);
|
||||
|
||||
fileName surfFileName(args.additionalArgs()[0]);
|
||||
|
||||
Info<< "Reading surf from " << surfFileName << " ..." << endl;
|
||||
|
||||
fileName outFileName(args.additionalArgs()[1]);
|
||||
|
||||
Info<< "Writing surf to " << outFileName << " ..." << endl;
|
||||
|
||||
triSurface ts(surfFileName);
|
||||
|
||||
triFaceList invertedFaces(ts.size());
|
||||
|
||||
forAll (ts, tsI)
|
||||
{
|
||||
invertedFaces[tsI] = ts[tsI].reverseFace();
|
||||
}
|
||||
|
||||
triSurface invertedTs
|
||||
(
|
||||
invertedFaces,
|
||||
ts.points()
|
||||
);
|
||||
|
||||
invertedTs.write(outFileName);
|
||||
|
||||
Info << "End\n" << endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
|
@ -0,0 +1,3 @@
|
|||
surfaceNormal.C
|
||||
|
||||
EXE = $(FOAM_APPBIN)/surfaceNormal
|
|
@ -0,0 +1,7 @@
|
|||
EXE_INC = \
|
||||
-I$(LIB_SRC)/triSurface/lnInclude \
|
||||
-I$(LIB_SRC)/meshTools/lnInclude
|
||||
|
||||
EXE_LIBS = \
|
||||
-ltriSurface \
|
||||
-lmeshTools
|
|
@ -0,0 +1,69 @@
|
|||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright held by original author
|
||||
\\/ 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 2 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, write to the Free Software Foundation,
|
||||
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
Description
|
||||
Write surface and normal vector
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "argList.H"
|
||||
#include "triSurface.H"
|
||||
#include "IFstream.H"
|
||||
|
||||
using namespace Foam;
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
// Main program:
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
argList::noParallel();
|
||||
argList::validArgs.clear();
|
||||
|
||||
argList::validArgs.append("surface file");
|
||||
argList args(argc, argv);
|
||||
|
||||
fileName surfFileName(args.additionalArgs()[0]);
|
||||
|
||||
Info<< "Reading surf from " << surfFileName << " ..." << endl;
|
||||
|
||||
triSurface ts(surfFileName);
|
||||
|
||||
fileName normalFileName(surfFileName.lessExt() + "Normals");
|
||||
|
||||
Info<< "Writing normals to file " << normalFileName << endl;
|
||||
triSurface::writeVTKNormals
|
||||
(
|
||||
normalFileName,
|
||||
ts,
|
||||
ts.points()
|
||||
);
|
||||
|
||||
Info << "End\n" << endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
|
@ -0,0 +1,3 @@
|
|||
writeIbMasks.C
|
||||
|
||||
EXE = $(FOAM_APPBIN)/writeIbMasks
|
|
@ -0,0 +1,15 @@
|
|||
EXE_INC = \
|
||||
-I$(LIB_SRC)/finiteVolume/lnInclude \
|
||||
-I$(LIB_SRC)/triSurface/lnInclude \
|
||||
-I$(LIB_SRC)/meshTools/lnInclude \
|
||||
-I$(LIB_SRC)/immersedBoundary/immersedBoundary/lnInclude
|
||||
|
||||
EXE_LIBS = \
|
||||
-lfiniteVolume \
|
||||
-ltriSurface \
|
||||
-lmeshTools \
|
||||
-lsurfMesh \
|
||||
-lsampling \
|
||||
-ldynamicMesh \
|
||||
-limmersedBoundary \
|
||||
-llduSolvers
|
|
@ -0,0 +1,62 @@
|
|||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright held by original author
|
||||
\\/ 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 2 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, write to the Free Software Foundation,
|
||||
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
Application
|
||||
writeIbMasks
|
||||
|
||||
Description
|
||||
Calculate and write immersed boundary masks
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "fvCFD.H"
|
||||
#include "immersedBoundaryFvPatch.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
# include "setRootCase.H"
|
||||
# include "createTime.H"
|
||||
# include "createMesh.H"
|
||||
# include "createIbMasks.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
Info<< "Time = " << runTime.timeName() << nl << endl;
|
||||
|
||||
cellIbMask.write();
|
||||
cellIbMaskExt.write();
|
||||
|
||||
Info<< "ExecutionTime = " << runTime.elapsedCpuTime() << " s"
|
||||
<< " ClockTime = " << runTime.elapsedClockTime() << " s"
|
||||
<< nl << endl;
|
||||
|
||||
Info<< "End\n" << endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
|
@ -71,6 +71,10 @@ wmake libso multiSolver
|
|||
wmake libso solidModels
|
||||
wmake libso dbns
|
||||
|
||||
wmake libso immersedBoundary
|
||||
wmake libso immersedBoundaryForce
|
||||
wmake libso immersedBoundaryTurbulence
|
||||
|
||||
( cd cudaSolvers ; ./Allwmake )
|
||||
|
||||
# ----------------------------------------------------------------- end-of-file
|
||||
|
|
17
src/immersedBoundary/immersedBoundary/Make/files
Normal file
17
src/immersedBoundary/immersedBoundary/Make/files
Normal file
|
@ -0,0 +1,17 @@
|
|||
immersedBoundaryPolyPatch/immersedBoundaryPolyPatch.C
|
||||
immersedBoundaryPointPatch/immersedBoundaryPointPatch.C
|
||||
immersedBoundaryFvPatch/immersedBoundaryFvPatch.C
|
||||
immersedBoundaryFvPatch/immersedBoundaryFvPatchLeastSquaresFit.C
|
||||
immersedBoundaryFvPatch/immersedBoundaryFvPatchSamplingWeights.C
|
||||
immersedBoundaryFvPatch/immersedBoundaryFvPatchTriAddressing.C
|
||||
|
||||
immersedBoundaryFvPatchField/immersedBoundaryFvPatchFields.C
|
||||
immersedBoundaryFvsPatchField/immersedBoundaryFvsPatchFields.C
|
||||
|
||||
immersedBoundaryAdjustPhi/immersedBoundaryAdjustPhi.C
|
||||
|
||||
refineImmersedBoundaryMesh/refineImmersedBoundaryMesh.C
|
||||
|
||||
ibSwirlFlowRateInletVelocity/ibSwirlFlowRateInletVelocityFvPatchVectorField.C
|
||||
|
||||
LIB = $(FOAM_LIBBIN)/libimmersedBoundary
|
15
src/immersedBoundary/immersedBoundary/Make/options
Normal file
15
src/immersedBoundary/immersedBoundary/Make/options
Normal file
|
@ -0,0 +1,15 @@
|
|||
EXE_INC = \
|
||||
-I$(LIB_SRC)/finiteVolume/lnInclude \
|
||||
-I$(LIB_SRC)/triSurface/lnInclude \
|
||||
-I$(LIB_SRC)/meshTools/lnInclude \
|
||||
-I$(LIB_SRC)/surfMesh/lnInclude \
|
||||
-I$(LIB_SRC)/sampling/lnInclude \
|
||||
-I$(LIB_SRC)/dynamicMesh/dynamicMesh/lnInclude
|
||||
|
||||
EXE_LIBS = \
|
||||
-lfiniteVolume \
|
||||
-ltriSurface \
|
||||
-lmeshTools \
|
||||
-lsurfMesh \
|
||||
-lsampling \
|
||||
-ldynamicMesh
|
|
@ -0,0 +1,225 @@
|
|||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / 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 "ibSwirlFlowRateInletVelocityFvPatchVectorField.H"
|
||||
#include "volFields.H"
|
||||
#include "addToRunTimeSelectionTable.H"
|
||||
#include "fvPatchFieldMapper.H"
|
||||
#include "surfaceFields.H"
|
||||
#include "mathematicalConstants.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
Foam::
|
||||
ibSwirlFlowRateInletVelocityFvPatchVectorField::
|
||||
ibSwirlFlowRateInletVelocityFvPatchVectorField
|
||||
(
|
||||
const fvPatch& p,
|
||||
const DimensionedField<vector, volMesh>& iF
|
||||
)
|
||||
:
|
||||
fixedValueFvPatchField<vector>(p, iF),
|
||||
flowRate_(0),
|
||||
phiName_("phi"),
|
||||
rhoName_("rho"),
|
||||
rpm_(0)
|
||||
{
|
||||
calcGeom();
|
||||
}
|
||||
|
||||
|
||||
Foam::
|
||||
ibSwirlFlowRateInletVelocityFvPatchVectorField::
|
||||
ibSwirlFlowRateInletVelocityFvPatchVectorField
|
||||
(
|
||||
const ibSwirlFlowRateInletVelocityFvPatchVectorField& ptf,
|
||||
const fvPatch& p,
|
||||
const DimensionedField<vector, volMesh>& iF,
|
||||
const fvPatchFieldMapper& mapper
|
||||
)
|
||||
:
|
||||
fixedValueFvPatchField<vector>(ptf, p, iF, mapper),
|
||||
flowRate_(ptf.flowRate_),
|
||||
phiName_(ptf.phiName_),
|
||||
rhoName_(ptf.rhoName_),
|
||||
rpm_(ptf.rpm_)
|
||||
{
|
||||
calcGeom();
|
||||
}
|
||||
|
||||
|
||||
Foam::
|
||||
ibSwirlFlowRateInletVelocityFvPatchVectorField::
|
||||
ibSwirlFlowRateInletVelocityFvPatchVectorField
|
||||
(
|
||||
const fvPatch& p,
|
||||
const DimensionedField<vector, volMesh>& iF,
|
||||
const dictionary& dict
|
||||
)
|
||||
:
|
||||
fixedValueFvPatchField<vector>(p, iF, dict),
|
||||
flowRate_(readScalar(dict.lookup("flowRate"))),
|
||||
phiName_(dict.lookupOrDefault<word>("phi", "phi")),
|
||||
rhoName_(dict.lookupOrDefault<word>("rho", "rho")),
|
||||
rpm_(readScalar(dict.lookup("rpm")))
|
||||
{
|
||||
calcGeom();
|
||||
}
|
||||
|
||||
|
||||
Foam::
|
||||
ibSwirlFlowRateInletVelocityFvPatchVectorField::
|
||||
ibSwirlFlowRateInletVelocityFvPatchVectorField
|
||||
(
|
||||
const ibSwirlFlowRateInletVelocityFvPatchVectorField& ptf
|
||||
)
|
||||
:
|
||||
fixedValueFvPatchField<vector>(ptf),
|
||||
flowRate_(ptf.flowRate_),
|
||||
phiName_(ptf.phiName_),
|
||||
rhoName_(ptf.rhoName_),
|
||||
rpm_(ptf.rpm_)
|
||||
{
|
||||
calcGeom();
|
||||
}
|
||||
|
||||
|
||||
Foam::
|
||||
ibSwirlFlowRateInletVelocityFvPatchVectorField::
|
||||
ibSwirlFlowRateInletVelocityFvPatchVectorField
|
||||
(
|
||||
const ibSwirlFlowRateInletVelocityFvPatchVectorField& ptf,
|
||||
const DimensionedField<vector, volMesh>& iF
|
||||
)
|
||||
:
|
||||
fixedValueFvPatchField<vector>(ptf, iF),
|
||||
flowRate_(ptf.flowRate_),
|
||||
phiName_(ptf.phiName_),
|
||||
rhoName_(ptf.rhoName_),
|
||||
rpm_(ptf.rpm_)
|
||||
{
|
||||
calcGeom();
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
void Foam::ibSwirlFlowRateInletVelocityFvPatchVectorField::calcGeom()
|
||||
{
|
||||
// Lookup cellIbMask
|
||||
const fvPatchScalarField& patchCellIbMask =
|
||||
lookupPatchField<volScalarField, scalar>("cellIbMask");
|
||||
|
||||
scalarField faceMask = patchCellIbMask.patchInternalField();
|
||||
|
||||
totArea_ = gSum(faceMask*patch().magSf());
|
||||
avgCenter_ = gSum(faceMask*patch().Cf()*patch().magSf())/totArea_;
|
||||
avgNormal_ = gSum(faceMask*patch().Sf())/totArea_;
|
||||
}
|
||||
|
||||
|
||||
void Foam::ibSwirlFlowRateInletVelocityFvPatchVectorField::updateCoeffs()
|
||||
{
|
||||
if (updated())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const scalar avgU = -flowRate_/totArea_;
|
||||
|
||||
// Update angular velocity - convert [rpm] to [rad/s]
|
||||
vectorField tangentialVelocity =
|
||||
(rpm_*mathematicalConstant::pi/30.0)
|
||||
* ((patch().Cf() - avgCenter_) ^ avgNormal_);
|
||||
|
||||
vectorField n = patch().nf();
|
||||
|
||||
vectorField& U = *this;
|
||||
|
||||
const surfaceScalarField& phi =
|
||||
db().lookupObject<surfaceScalarField>(phiName_);
|
||||
|
||||
// Lookup cellIbMask
|
||||
const fvPatchScalarField& patchCellIbMask =
|
||||
lookupPatchField<volScalarField, scalar>("cellIbMask");
|
||||
|
||||
scalarField faceMask = patchCellIbMask.patchInternalField();
|
||||
|
||||
if (phi.dimensions() == dimVelocity*dimArea)
|
||||
{
|
||||
// Volumetric flow-rate
|
||||
U = faceMask*(tangentialVelocity + n*avgU);
|
||||
}
|
||||
else if (phi.dimensions() == dimDensity*dimVelocity*dimArea)
|
||||
{
|
||||
const fvPatchField<scalar>& rhop =
|
||||
patch().lookupPatchField<volScalarField, scalar>(rhoName_);
|
||||
|
||||
// Mass flow-rate
|
||||
U = faceMask*(tangentialVelocity + n*avgU/rhop);
|
||||
}
|
||||
else
|
||||
{
|
||||
FatalErrorIn
|
||||
(
|
||||
"ibSwirlFlowRateInletVelocityFvPatchVectorField::updateCoeffs()"
|
||||
) << "dimensions of " << phiName_ << " are incorrect" << nl
|
||||
<< " on patch " << this->patch().name()
|
||||
<< " of field " << this->dimensionedInternalField().name()
|
||||
<< " in file " << this->dimensionedInternalField().objectPath()
|
||||
<< nl << exit(FatalError);
|
||||
}
|
||||
|
||||
fixedValueFvPatchField<vector>::updateCoeffs();
|
||||
}
|
||||
|
||||
|
||||
void Foam::ibSwirlFlowRateInletVelocityFvPatchVectorField::write
|
||||
(
|
||||
Ostream& os
|
||||
) const
|
||||
{
|
||||
fvPatchField<vector>::write(os);
|
||||
os.writeKeyword("flowRate") << flowRate_ << token::END_STATEMENT << nl;
|
||||
writeEntryIfDifferent<word>(os, "phi", "phi", phiName_);
|
||||
writeEntryIfDifferent<word>(os, "rho", "rho", rhoName_);
|
||||
os.writeKeyword("rpm") << rpm_ << token::END_STATEMENT << nl;
|
||||
writeEntry("value", os);
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
makePatchTypeField
|
||||
(
|
||||
fvPatchVectorField,
|
||||
ibSwirlFlowRateInletVelocityFvPatchVectorField
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
|
@ -0,0 +1,202 @@
|
|||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / 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/>.
|
||||
|
||||
Class
|
||||
Foam::ibSwirlFlowRateInletVelocityFvPatchVectorField
|
||||
|
||||
Description
|
||||
Describes a volumetric/mass flow normal vector boundary condition by its
|
||||
magnitude as an integral over its area with a swirl component determined
|
||||
by the RPM
|
||||
|
||||
The basis of the patch (volumetric or mass) is determined by the
|
||||
dimensions of the flux, phi.
|
||||
The current density is used to correct the velocity when applying the
|
||||
mass basis.
|
||||
|
||||
The boundary condition is sensitised to work only on live IB cells
|
||||
|
||||
Example of the boundary condition specification:
|
||||
\verbatim
|
||||
inlet
|
||||
{
|
||||
type ibSwirlFlowRateInletVelocity;
|
||||
flowRate 0.2; // Volumetric/mass flow rate [m3/s or kg/s]
|
||||
rpm 100;
|
||||
}
|
||||
\endverbatim
|
||||
|
||||
Note
|
||||
- The value is positive inwards
|
||||
|
||||
SourceFiles
|
||||
ibSwirlFlowRateInletVelocityFvPatchVectorField.C
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef ibSwirlFlowRateInletVelocityFvPatchVectorField_H
|
||||
#define ibSwirlFlowRateInletVelocityFvPatchVectorField_H
|
||||
|
||||
#include "fixedValueFvPatchFields.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class ibSwirlFlowRateInletVelocityFvPatchVectorField Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
class ibSwirlFlowRateInletVelocityFvPatchVectorField
|
||||
:
|
||||
public fixedValueFvPatchVectorField
|
||||
{
|
||||
// Private data
|
||||
|
||||
//- Inlet integral flow rate
|
||||
const scalar flowRate_;
|
||||
|
||||
//- Name of the flux transporting the field
|
||||
const word phiName_;
|
||||
|
||||
//- Name of the density field used to normalize the mass flux
|
||||
const word rhoName_;
|
||||
|
||||
//- RPM
|
||||
const scalar rpm_;
|
||||
|
||||
// Derived parameters
|
||||
|
||||
//- Total area of inlet patch
|
||||
scalar totArea_;
|
||||
|
||||
//- Average centre
|
||||
vector avgCenter_;
|
||||
|
||||
//- Average normal
|
||||
vector avgNormal_;
|
||||
|
||||
|
||||
// Private member functions
|
||||
|
||||
//- Calculate geometrical characteristics of the patch
|
||||
void calcGeom();
|
||||
|
||||
|
||||
public:
|
||||
|
||||
//- Runtime type information
|
||||
TypeName("ibSwirlFlowRateInletVelocity");
|
||||
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Construct from patch and internal field
|
||||
ibSwirlFlowRateInletVelocityFvPatchVectorField
|
||||
(
|
||||
const fvPatch&,
|
||||
const DimensionedField<vector, volMesh>&
|
||||
);
|
||||
|
||||
//- Construct from patch, internal field and dictionary
|
||||
ibSwirlFlowRateInletVelocityFvPatchVectorField
|
||||
(
|
||||
const fvPatch&,
|
||||
const DimensionedField<vector, volMesh>&,
|
||||
const dictionary&
|
||||
);
|
||||
|
||||
//- Construct by mapping given
|
||||
// flowRateInletVelocityFvPatchVectorField
|
||||
// onto a new patch
|
||||
ibSwirlFlowRateInletVelocityFvPatchVectorField
|
||||
(
|
||||
const ibSwirlFlowRateInletVelocityFvPatchVectorField&,
|
||||
const fvPatch&,
|
||||
const DimensionedField<vector, volMesh>&,
|
||||
const fvPatchFieldMapper&
|
||||
);
|
||||
|
||||
//- Construct as copy
|
||||
ibSwirlFlowRateInletVelocityFvPatchVectorField
|
||||
(
|
||||
const ibSwirlFlowRateInletVelocityFvPatchVectorField&
|
||||
);
|
||||
|
||||
//- Construct and return a clone
|
||||
virtual tmp<fvPatchVectorField> clone() const
|
||||
{
|
||||
return tmp<fvPatchVectorField>
|
||||
(
|
||||
new ibSwirlFlowRateInletVelocityFvPatchVectorField(*this)
|
||||
);
|
||||
}
|
||||
|
||||
//- Construct as copy setting internal field reference
|
||||
ibSwirlFlowRateInletVelocityFvPatchVectorField
|
||||
(
|
||||
const ibSwirlFlowRateInletVelocityFvPatchVectorField&,
|
||||
const DimensionedField<vector, volMesh>&
|
||||
);
|
||||
|
||||
//- Construct and return a clone setting internal field reference
|
||||
virtual tmp<fvPatchVectorField> clone
|
||||
(
|
||||
const DimensionedField<vector, volMesh>& iF
|
||||
) const
|
||||
{
|
||||
return tmp<fvPatchVectorField>
|
||||
(
|
||||
new ibSwirlFlowRateInletVelocityFvPatchVectorField(*this, iF)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
// Member functions
|
||||
|
||||
// Access
|
||||
|
||||
//- Return the flux
|
||||
scalar flowRate() const
|
||||
{
|
||||
return flowRate_;
|
||||
}
|
||||
|
||||
|
||||
//- Update the coefficients associated with the patch field
|
||||
virtual void updateCoeffs();
|
||||
|
||||
//- Write
|
||||
virtual void write(Ostream&) const;
|
||||
};
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
|
@ -0,0 +1,281 @@
|
|||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright held by original author
|
||||
\\/ 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 2 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, write to the Free Software Foundation,
|
||||
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "immersedBoundaryAdjustPhi.H"
|
||||
#include "volFields.H"
|
||||
#include "surfaceFields.H"
|
||||
#include "immersedBoundaryFvPatchFields.H"
|
||||
#include "immersedBoundaryFvsPatchFields.H"
|
||||
#include "inletOutletFvPatchFields.H"
|
||||
#include "fvc.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * Global Functions * * * * * * * * * * * * * //
|
||||
|
||||
void Foam::immersedBoundaryAdjustPhi
|
||||
(
|
||||
surfaceScalarField& phi,
|
||||
volVectorField& U
|
||||
)
|
||||
{
|
||||
const fvMesh& mesh = phi.mesh();
|
||||
|
||||
// If the mesh is moving, adjustment needs to be calculated on
|
||||
// relative fluxes. HJ, 13/Feb/2009
|
||||
if (mesh.moving())
|
||||
{
|
||||
fvc::makeRelative(phi, U);
|
||||
}
|
||||
|
||||
forAll (phi.boundaryField(), patchI)
|
||||
{
|
||||
const fvPatchVectorField& Up = U.boundaryField()[patchI];
|
||||
|
||||
if (isA<immersedBoundaryFvPatchVectorField>(Up))
|
||||
{
|
||||
if (Up.fixesValue())
|
||||
{
|
||||
// Found immersed boundary path which fixes value.
|
||||
// Correction is necessary
|
||||
|
||||
// Cast into immersedBoundary types
|
||||
const immersedBoundaryFvPatchVectorField& ibU =
|
||||
refCast<const immersedBoundaryFvPatchVectorField>(Up);
|
||||
|
||||
const immersedBoundaryFvPatch& ibPatch = ibU.ibPatch();
|
||||
|
||||
// Complete immersed boundary triangular surface is present
|
||||
// on all processors: no need for parallel reduction
|
||||
|
||||
// Sum the flux through the immersed boundary
|
||||
const scalar triFlux = sum(ibU.refValue() & ibPatch.triSf());
|
||||
|
||||
scalarField& phiInternal = phi.internalField();
|
||||
|
||||
scalar fluxIn = 0;
|
||||
scalar fluxOut = 0;
|
||||
scalar fixedFlux = 0;
|
||||
|
||||
// Get all IB faces
|
||||
const labelList& ibFaces = ibPatch.ibFaces();
|
||||
const boolList& ibFaceFlips = ibPatch.ibFaceFlips();
|
||||
|
||||
forAll (ibFaces, faceI)
|
||||
{
|
||||
const label curFace = ibFaces[faceI];
|
||||
const bool curFlip = ibFaceFlips[faceI];
|
||||
|
||||
if (mesh.isInternalFace(curFace))
|
||||
{
|
||||
const scalar curFlux = phiInternal[curFace];
|
||||
|
||||
if (!curFlip)
|
||||
{
|
||||
// Face points out of the live cell
|
||||
if (curFlux >= 0)
|
||||
{
|
||||
// Flux out of the live cell
|
||||
fluxOut += curFlux;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Flux into the live cell
|
||||
fluxIn -= curFlux;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Face points into the live cell: flip it
|
||||
if (curFlux >= 0)
|
||||
{
|
||||
// Flux into of the live cell
|
||||
fluxIn += curFlux;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Flux out the live cell
|
||||
fluxOut -= curFlux;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
const label patchID =
|
||||
mesh.boundaryMesh().whichPatch(curFace);
|
||||
const label faceID =
|
||||
mesh.boundaryMesh()[patchID].whichFace(curFace);
|
||||
|
||||
const scalar curFlux =
|
||||
phi.boundaryField()[patchID][faceID];
|
||||
|
||||
// Note: only coupled patches may carry flux
|
||||
// In order to avoid double summation and
|
||||
// inconsistencies in the correction,
|
||||
// coupled face fluxes will NOT be corrected,
|
||||
// but only accounted for in the summation.
|
||||
if (mesh.boundaryMesh()[patchID].coupled())
|
||||
{
|
||||
// Only do the master side; slave will
|
||||
// be handled on the other side of the couple
|
||||
if (!curFlip)
|
||||
{
|
||||
fixedFlux += curFlux;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
reduce(fluxIn, sumOp<scalar>());
|
||||
reduce(fluxOut, sumOp<scalar>());
|
||||
reduce(fixedFlux, sumOp<scalar>());
|
||||
|
||||
scalar imbalance = (fluxIn - fluxOut + fixedFlux) - triFlux;
|
||||
|
||||
if (fvMesh::debug)
|
||||
{
|
||||
Info<< "triFlux = " << triFlux
|
||||
<< " fluxIn = " << fluxIn << " fluxOut = " << fluxOut
|
||||
<< " fixedFlux = " << fixedFlux
|
||||
<< " imbalance = " << imbalance
|
||||
<< endl;
|
||||
}
|
||||
|
||||
scalar massCorr = 1.0;
|
||||
|
||||
if (mag(imbalance) > SMALL)
|
||||
{
|
||||
// Scaling required: scale to match the smaller of two
|
||||
// fluxes
|
||||
if (fluxIn > fluxOut)
|
||||
{
|
||||
// Scale down incoming flux
|
||||
// Note change of sign: imbalance is negative
|
||||
massCorr = 1 - imbalance/(fluxIn + SMALL);
|
||||
|
||||
if (fvMesh::debug)
|
||||
{
|
||||
Info<< "Scaling down incoming flux with factor = "
|
||||
<< massCorr << endl;
|
||||
}
|
||||
|
||||
scalar newFluxIn = 0;
|
||||
|
||||
// Visit all incoming flux faces and re-scale the flux
|
||||
forAll (ibFaces, faceI)
|
||||
{
|
||||
const label curFace = ibFaces[faceI];
|
||||
const bool curFlip = ibFaceFlips[faceI];
|
||||
|
||||
if (mesh.isInternalFace(curFace))
|
||||
{
|
||||
// Take reference to current flux
|
||||
scalar& curFlux = phiInternal[curFace];
|
||||
|
||||
if (!curFlip)
|
||||
{
|
||||
// Face points out of the live cell
|
||||
if (curFlux < 0)
|
||||
{
|
||||
// Flux out of the live cell
|
||||
curFlux *= massCorr;
|
||||
newFluxIn -= curFlux;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Face points into the live cell: flip it
|
||||
if (curFlux >= 0)
|
||||
{
|
||||
// Flux out the live cell
|
||||
curFlux *= massCorr;
|
||||
newFluxIn += curFlux;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Scale down outgoing flux
|
||||
massCorr = 1 + imbalance/(fluxOut + SMALL);
|
||||
|
||||
if (fvMesh::debug)
|
||||
{
|
||||
Info<< "Scaling down outgoing flux with factor = "
|
||||
<< massCorr << endl;
|
||||
}
|
||||
|
||||
scalar newFluxOut = 0;
|
||||
|
||||
// Visit all outgoing flux faces and re-scale the flux
|
||||
forAll (ibFaces, faceI)
|
||||
{
|
||||
const label curFace = ibFaces[faceI];
|
||||
const bool curFlip = ibFaceFlips[faceI];
|
||||
|
||||
if (mesh.isInternalFace(curFace))
|
||||
{
|
||||
// Take reference to current flux
|
||||
scalar& curFlux = phiInternal[curFace];
|
||||
|
||||
if (!curFlip)
|
||||
{
|
||||
// Face points out of the live cell
|
||||
if (curFlux >= 0)
|
||||
{
|
||||
// Flux out of the live cell
|
||||
curFlux *= massCorr;
|
||||
newFluxOut += curFlux;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Face points into the live cell: flip it
|
||||
if (curFlux < 0)
|
||||
{
|
||||
// Flux out the live cell
|
||||
curFlux *= massCorr;
|
||||
newFluxOut -= curFlux;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// If the mesh is moving, adjustment needs to be calculated on
|
||||
// relative fluxes. Now reverting to absolute fluxes. HJ, 13/Feb/2009
|
||||
if (mesh.moving())
|
||||
{
|
||||
fvc::makeAbsolute(phi, U);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
|
@ -0,0 +1,60 @@
|
|||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright held by original author
|
||||
\\/ 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 2 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, write to the Free Software Foundation,
|
||||
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
InNamespace
|
||||
Foam
|
||||
|
||||
Description
|
||||
Adjust immersed boundary fluxes to obey continuity
|
||||
|
||||
SourceFiles
|
||||
immersedBoundaryAdjustPhi.C
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef immersedBoundaryAdjustPhi_H
|
||||
#define immersedBoundaryAdjustPhi_H
|
||||
|
||||
#include "volFieldsFwd.H"
|
||||
#include "surfaceFieldsFwd.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
//- Adjust the fluxes on immersed boundary to obey continuity.
|
||||
void immersedBoundaryAdjustPhi
|
||||
(
|
||||
surfaceScalarField& phi,
|
||||
volVectorField& U
|
||||
);
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,572 @@
|
|||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright held by original author
|
||||
\\/ 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 2 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, write to the Free Software Foundation,
|
||||
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
Class
|
||||
Foam::immersedBoundaryFvPatch
|
||||
|
||||
Description
|
||||
Immersed boundary FV patch
|
||||
|
||||
Author
|
||||
Zeljko Tukovic
|
||||
Reorganisation by Hrvoje Jasak
|
||||
|
||||
SourceFiles
|
||||
immersedBoundaryFvPatch.C
|
||||
immersedBoundaryFvPatchLeastSquaresFit.C
|
||||
immersedBoundaryFvPatchTriAddressing.C
|
||||
immersedBoundaryFvPatchSamplingWeights.C
|
||||
immersedBoundaryFvPatchTemplates.C
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef immersedBoundaryFvPatch_H
|
||||
#define immersedBoundaryFvPatch_H
|
||||
|
||||
#include "fvPatch.H"
|
||||
#include "immersedBoundaryPolyPatch.H"
|
||||
#include "volFieldsFwd.H"
|
||||
#include "surfaceFieldsFwd.H"
|
||||
|
||||
#include "labelPair.H"
|
||||
#include "FieldFields.H"
|
||||
#include "scalarMatrices.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
// Forward declaration of classes
|
||||
class fvMesh;
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class immersedBoundaryFvPatch Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
class immersedBoundaryFvPatch
|
||||
:
|
||||
public fvPatch
|
||||
{
|
||||
// Private data
|
||||
|
||||
//- Reference to processor patch
|
||||
const immersedBoundaryPolyPatch& ibPolyPatch_;
|
||||
|
||||
//- Finite volume mesh reference
|
||||
const fvMesh& mesh_;
|
||||
|
||||
|
||||
// Static data
|
||||
|
||||
//- Fitting angle rejection factor (deg)
|
||||
// Cells within the the radius will be used for the fitting function
|
||||
static scalar angleFactor_;
|
||||
|
||||
//- Fitting radius factor
|
||||
// Cells within the the radius will be used for the fitting function
|
||||
static scalar radiusFactor_;
|
||||
|
||||
//- Maximum number of rows in cell-cell search
|
||||
static label maxCellCellRows_;
|
||||
|
||||
//- Sampling point distance factor
|
||||
// Sampling point is located distFactor further away from the wall
|
||||
// from the immersed boundary cell centre
|
||||
static scalar distFactor_;
|
||||
|
||||
|
||||
// Demand-driven data
|
||||
|
||||
// Immersed boundary data
|
||||
|
||||
//- Fluid cells indicator, marking only live fluid cells
|
||||
mutable volScalarField* gammaPtr_;
|
||||
|
||||
//- Fluid cells indicator, marking live and IB cells
|
||||
mutable volScalarField* gammaExtPtr_;
|
||||
|
||||
//- Fluid faces indicator, marking faces between live cells
|
||||
mutable surfaceScalarField* sGammaPtr_;
|
||||
|
||||
//- List of fluid cells next to immersed boundary (IB cells)
|
||||
mutable labelList* ibCellsPtr_;
|
||||
|
||||
//- List of faces for which one neighbour is an IB cell
|
||||
// and another neighbour is a live fluid cell (IB faces)
|
||||
mutable labelList* ibFacesPtr_;
|
||||
|
||||
//- List of IB cell index for each ibFace
|
||||
mutable labelList* ibFaceCellsPtr_;
|
||||
|
||||
//- List of IB face flip:
|
||||
// false if IB face points into IB cell (out of the live cell)
|
||||
// true if IB face points into a live cell
|
||||
mutable boolList* ibFaceFlipsPtr_;
|
||||
|
||||
//- List of fluid faces for which one neighbour is an IB cell
|
||||
// and another neighbour is a dead cell (inside IB faces)
|
||||
mutable labelList* ibInsideFacesPtr_;
|
||||
|
||||
//- List of internal faces in the region bounded by IB faces
|
||||
mutable labelList* ibInternalFacesPtr_;
|
||||
|
||||
//- Points at the immersed boundary (IB points)
|
||||
// nearest to the IB cell centres
|
||||
mutable vectorField* ibPointsPtr_;
|
||||
|
||||
//- Normals at IB points
|
||||
mutable vectorField* ibNormalsPtr_;
|
||||
|
||||
//- List of faces (triangles) which are part of IB mesh
|
||||
// nearest to the IB cell centres
|
||||
mutable labelList* hitFacesPtr_;
|
||||
|
||||
//- Sampling points for IB cells
|
||||
mutable vectorField* ibSamplingPointsPtr_;
|
||||
|
||||
//- Interpolation weights for sampling weights
|
||||
mutable scalarListList* ibSamplingWeightsPtr_;
|
||||
|
||||
//- Interpolation weights for sampling processor weights
|
||||
mutable scalarListList* ibSamplingProcWeightsPtr_;
|
||||
|
||||
//- Interpolation addressing from IB points to tri faces
|
||||
mutable labelListList* cellsToTriAddrPtr_;
|
||||
|
||||
//- Interpolation weights from IB points to tri faces
|
||||
mutable scalarListList* cellsToTriWeightsPtr_;
|
||||
|
||||
//- Neighbour cells for immersed boundary cells
|
||||
// (extended stencil)
|
||||
mutable labelListList* ibCellCellsPtr_;
|
||||
|
||||
//- List of cells needed by neighbour processors
|
||||
mutable labelListList* ibProcCellsPtr_;
|
||||
|
||||
//- Centres of cells from neighbour processors
|
||||
mutable FieldField<Field, vector>* ibProcCentresPtr_;
|
||||
|
||||
//- Gamma of cells from neighbour processors
|
||||
mutable FieldField<Field, scalar>* ibProcGammaPtr_;
|
||||
|
||||
//- Cell-proc-cell addressing
|
||||
mutable List<List<labelPair> >* ibCellProcCellsPtr_;
|
||||
|
||||
//- Dead cells list
|
||||
mutable labelList* deadCellsPtr_;
|
||||
|
||||
//- Extended dead cells list (dead cells + IB cells)
|
||||
mutable labelList* deadCellsExtPtr_;
|
||||
|
||||
//- Dead faces list
|
||||
mutable labelList* deadFacesPtr_;
|
||||
|
||||
//- List of live cells
|
||||
mutable labelList* liveCellsPtr_;
|
||||
|
||||
//- Average IB cell sizes
|
||||
mutable scalarField* ibCellSizesPtr_;
|
||||
|
||||
//- Inverse interpolation matrices for Dirichlet BC at the IB
|
||||
mutable PtrList<scalarRectangularMatrix>* invDirichletMatricesPtr_;
|
||||
|
||||
//- Inverse interpolation matrices for Neumann BC at the IB
|
||||
mutable PtrList<scalarRectangularMatrix>* invNeumannMatricesPtr_;
|
||||
|
||||
//- IB face area vectors
|
||||
mutable vectorField* ibSfPtr_;
|
||||
|
||||
//- IB face area vector magnitudess
|
||||
mutable scalarField* ibMagSfPtr_;
|
||||
|
||||
//- IB cell centre distances to IB
|
||||
mutable scalarField* ibDeltaPtr_;
|
||||
|
||||
//- IB cell centre distances to IB
|
||||
mutable scalarField* ibSamplingPointDeltaPtr_;
|
||||
|
||||
|
||||
// Tri surface data
|
||||
|
||||
//- Tri surface face area vectors
|
||||
mutable vectorField* triSfPtr_;
|
||||
|
||||
|
||||
// Private Member Functions
|
||||
|
||||
|
||||
// Storage management
|
||||
|
||||
//- Clear all demand-driven data
|
||||
void clearOut();
|
||||
|
||||
|
||||
// Make demand-driven data
|
||||
|
||||
//- Make fluid cells indicator, marking only live fluid cells
|
||||
void makeGamma() const;
|
||||
|
||||
//- Make extended fluid cells indicator, marking live and IB cells
|
||||
void makeGammaExt() const;
|
||||
|
||||
//- Make fluid faces indicator
|
||||
void makeSGamma() const;
|
||||
|
||||
//- Make list of cells next to immersed boundary
|
||||
void makeIbCells() const;
|
||||
|
||||
//- Add corner points to IB cells list
|
||||
void addIbCornerCells() const;
|
||||
|
||||
//- Make IB faces
|
||||
void makeIbFaces() const;
|
||||
|
||||
//- Make tri addressing
|
||||
void makeTriAddressing() const;
|
||||
|
||||
//- Make inside IB faces
|
||||
void makeIbInsideFaces() const;
|
||||
|
||||
//- Make internal IB faces
|
||||
void makeIbInternalFaces() const;
|
||||
|
||||
//- Make immersed boundary points and normals
|
||||
void makeIbPointsAndNormals() const;
|
||||
|
||||
//- Make sampling point weights
|
||||
void makeIbSamplingWeights() const;
|
||||
|
||||
//- Make extended IB cells stencils
|
||||
void makeIbCellCells() const;
|
||||
|
||||
//- Make list of dead cells
|
||||
void makeDeadCells() const;
|
||||
|
||||
//- Make extended list of dead cells
|
||||
void makeDeadCellsExt() const;
|
||||
|
||||
//- Make list of dead faces
|
||||
void makeDeadFaces() const;
|
||||
|
||||
//- Make list of live cells
|
||||
void makeLiveCells() const;
|
||||
|
||||
//- Make immersed boundary cell sizes
|
||||
void makeIbCellSizes() const;
|
||||
|
||||
//- Make face area vectors and magnitudes
|
||||
void makeIbSf() const;
|
||||
|
||||
//- Make distance between IB cell centres
|
||||
// and corresponding IB points
|
||||
void makeIbDelta() const;
|
||||
|
||||
//- Make distance between IB cell centres
|
||||
// and corresponding sample IB points
|
||||
void makeIbSamplingPointDelta() const;
|
||||
|
||||
//- Make triangular surface face area vectors
|
||||
void makeTriSf() const;
|
||||
|
||||
//- Find nearest cell
|
||||
label findNearestCell(const point& location) const;
|
||||
|
||||
//- Return extended cell-cell addressing
|
||||
void findCellCells
|
||||
(
|
||||
const vector& pt,
|
||||
const label cellID,
|
||||
labelList& cellCells
|
||||
) const;
|
||||
|
||||
//- Calc cell size
|
||||
scalar cellSize(label cellID) const;
|
||||
|
||||
//- Calc cell projection area
|
||||
scalar cellProjection(label cellID, const vector& dir) const;
|
||||
|
||||
|
||||
// Boundary evaluation matrices
|
||||
|
||||
//- Make inverse Dirichlet interpolation matrices
|
||||
void makeInvDirichletMatrices() const;
|
||||
|
||||
//- Make inverse Neumann interpolation matrices
|
||||
void makeInvNeumannMatrices() const;
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
// Protected Member Functions
|
||||
|
||||
//- Initialise the patches for moving points
|
||||
virtual void initMovePoints();
|
||||
|
||||
//- Correct patches after moving points
|
||||
virtual void movePoints();
|
||||
|
||||
|
||||
public:
|
||||
|
||||
//- Runtime type information
|
||||
TypeName(immersedBoundaryPolyPatch::typeName_());
|
||||
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Construct from polyPatch
|
||||
immersedBoundaryFvPatch
|
||||
(
|
||||
const polyPatch& patch,
|
||||
const fvBoundaryMesh& bm
|
||||
);
|
||||
|
||||
|
||||
//- Destructor
|
||||
virtual ~immersedBoundaryFvPatch()
|
||||
{}
|
||||
|
||||
|
||||
// Member Functions
|
||||
|
||||
// Access to immersed boundary components
|
||||
|
||||
//- Return reference to immersed boundary polyPatch
|
||||
const immersedBoundaryPolyPatch& ibPolyPatch() const
|
||||
{
|
||||
return ibPolyPatch_;
|
||||
}
|
||||
|
||||
//- Return immersed boundary surface mesh
|
||||
const triSurfaceMesh& ibMesh() const
|
||||
{
|
||||
return ibPolyPatch_.ibMesh();
|
||||
}
|
||||
|
||||
bool internalFlow() const
|
||||
{
|
||||
return ibPolyPatch_.internalFlow();
|
||||
}
|
||||
|
||||
//- Is the immersed boundary patch moving?
|
||||
bool movingIb() const
|
||||
{
|
||||
return ibPolyPatch_.movingIb();
|
||||
}
|
||||
|
||||
|
||||
// Immersed boundary data access
|
||||
|
||||
//- Get fluid cells indicator, marking only live fluid cells
|
||||
const volScalarField& gamma() const;
|
||||
|
||||
//- Get extended flud cells indicator, including live and IB cells
|
||||
const volScalarField& gammaExt() const;
|
||||
|
||||
//- Get fluid faces indicator, marking faces between live cells
|
||||
const surfaceScalarField& sGamma() const;
|
||||
|
||||
|
||||
//- Return list of fluid cells next to immersed boundary (IB cells)
|
||||
const labelList& ibCells() const;
|
||||
|
||||
//- Return list of faces for which one neighbour is an IB cell
|
||||
// and another neighbour is a live fluid cell (IB faces)
|
||||
const labelList& ibFaces() const;
|
||||
|
||||
//- Return list of IB cell index for each ibFace
|
||||
const labelList& ibFaceCells() const;
|
||||
|
||||
//- Return list of IB face flip:
|
||||
// false if IB face points into IB cell (out of the live cell)
|
||||
// true if IB face points into a live cell
|
||||
const boolList& ibFaceFlips() const;
|
||||
|
||||
//- Return list of fluid faces for which one neighbour is an
|
||||
// IB cell and another neighbour is a dead cell (inside IB faces)
|
||||
const labelList& ibInsideFaces() const;
|
||||
|
||||
//- Return list of internal faces in the region bounded by IB faces
|
||||
const labelList& ibInternalFaces() const;
|
||||
|
||||
//- Return IB points
|
||||
const vectorField& ibPoints() const;
|
||||
|
||||
//- Return IB normals
|
||||
const vectorField& ibNormals() const;
|
||||
|
||||
//- Return list of triangles in IB mesh nearest
|
||||
// nearest to IB cell centres
|
||||
const labelList& hitFaces() const;
|
||||
|
||||
//- Return IB sampling points
|
||||
const vectorField& ibSamplingPoints() const;
|
||||
|
||||
//- Interpolation weights for sampling points
|
||||
const scalarListList& ibSamplingWeights() const;
|
||||
|
||||
//- Processor interpolation weights for sampling points
|
||||
const scalarListList& ibSamplingProcWeights() const;
|
||||
|
||||
//- Interpolation addressing from IB points to tri faces
|
||||
const labelListList& cellsToTriAddr() const;
|
||||
|
||||
//- Interpolation weights from IB points to tri faces
|
||||
const scalarListList& cellsToTriWeights() const;
|
||||
|
||||
//- Return IB cell extended stencil
|
||||
const labelListList& ibCellCells() const;
|
||||
|
||||
//- Return neighbour proc centres
|
||||
// These are centres from neighbouring processors the
|
||||
// local processor needs to receive
|
||||
const FieldField<Field, vector>& ibProcCentres() const;
|
||||
|
||||
//- Return neighbour proc gamma
|
||||
// These are gamma values from neighbouring processors the
|
||||
// local processor needs to receive
|
||||
const FieldField<Field, scalar>& ibProcGamma() const;
|
||||
|
||||
//- Return neighbour cell addressing
|
||||
const List<List<labelPair> >& ibCellProcCells() const;
|
||||
|
||||
//- Return neighbour proc cells
|
||||
// These are cell data that other processors need from
|
||||
// local processor
|
||||
const labelListList& ibProcCells() const;
|
||||
|
||||
//- Return dead cells
|
||||
const labelList& deadCells() const;
|
||||
|
||||
//- Return extended dead cells
|
||||
const labelList& deadCellsExt() const;
|
||||
|
||||
//- Return dead faces
|
||||
const labelList& deadFaces() const;
|
||||
|
||||
//- Return live cells
|
||||
const labelList& liveCells() const;
|
||||
|
||||
//- Return immersed boundary cell sizes
|
||||
const scalarField& ibCellSizes() const;
|
||||
|
||||
//- Get inverse Dirichlet interpolation matrix
|
||||
const PtrList<scalarRectangularMatrix>&
|
||||
invDirichletMatrices() const;
|
||||
|
||||
//- Get inverse Neumann interpolation matrix
|
||||
const PtrList<scalarRectangularMatrix>&
|
||||
invNeumannMatrices() const;
|
||||
|
||||
|
||||
//- Return IB face area vectors
|
||||
const vectorField& ibSf() const;
|
||||
|
||||
//- Return IB face area vector magnitudes
|
||||
const scalarField& ibMagSf() const;
|
||||
|
||||
//- Return distance to IB
|
||||
const scalarField& ibDelta() const;
|
||||
|
||||
//- Return distance to IB
|
||||
const scalarField& ibSamplingPointDelta() const;
|
||||
|
||||
//- Return triangular surface face area vectors
|
||||
const vectorField& triSf() const;
|
||||
|
||||
//- Return triangular surface face centres
|
||||
const vectorField& triCf() const;
|
||||
|
||||
|
||||
// Parallel communication
|
||||
|
||||
//- Send and receive
|
||||
template<class Type>
|
||||
tmp<FieldField<Field, Type> > sendAndReceive
|
||||
(
|
||||
const Field<Type>& psi
|
||||
) const;
|
||||
|
||||
|
||||
// Interpolation functions to and from triangular surface
|
||||
|
||||
//- Collect ibPoint values: from tri face fields onto intersection
|
||||
// points on the IB surface
|
||||
template<class Type>
|
||||
tmp<Field<Type> > toIbPoints
|
||||
(
|
||||
const Field<Type>& triValues
|
||||
) const;
|
||||
|
||||
//- Collect ibPoint values: from tri face fields onto intersection
|
||||
// points on the IB surface with tmp
|
||||
template<class Type>
|
||||
tmp<Field<Type> > toIbPoints
|
||||
(
|
||||
const tmp<Field<Type> >& ttriValues
|
||||
) const;
|
||||
|
||||
//- triFace values: collect data from IB fields onto intersection
|
||||
// points on the IB surface
|
||||
template<class Type>
|
||||
tmp<Field<Type> > toTriFaces
|
||||
(
|
||||
const Field<Type>& ibValues
|
||||
) const;
|
||||
|
||||
//- triFace values: collect data from IB fields onto intersection
|
||||
// points on the IB surface with tmp
|
||||
template<class Type>
|
||||
tmp<Field<Type> > toTriFaces
|
||||
(
|
||||
const tmp<Field<Type> >& tibValues
|
||||
) const;
|
||||
|
||||
|
||||
//- Interpolation functions to sampling points from mesh cell centres
|
||||
template<class Type>
|
||||
tmp<Field<Type> > toSamplingPoints
|
||||
(
|
||||
const Field<Type>& cellValues
|
||||
) const;
|
||||
|
||||
};
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#ifdef NoRepository
|
||||
# include "immersedBoundaryFvPatchTemplates.C"
|
||||
#endif
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
|
@ -0,0 +1,594 @@
|
|||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright held by original author
|
||||
\\/ 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 2 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, write to the Free Software Foundation,
|
||||
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "immersedBoundaryFvPatch.H"
|
||||
#include "fvMesh.H"
|
||||
#include "volFields.H"
|
||||
|
||||
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||
|
||||
void Foam::immersedBoundaryFvPatch::makeInvDirichletMatrices() const
|
||||
{
|
||||
if (debug)
|
||||
{
|
||||
Info<< "immersedBoundaryFvPatch::makeInvDirichletMatrices() : "
|
||||
<< "making immersed boundary inverse matrices"
|
||||
<< endl;
|
||||
}
|
||||
|
||||
// It is an error to attempt to recalculate
|
||||
// if the pointer is already set
|
||||
if (invDirichletMatricesPtr_)
|
||||
{
|
||||
FatalErrorIn
|
||||
(
|
||||
"void immersedBoundaryFvPatch::makeInvDirichletMatrices()"
|
||||
) << "immersed boundary inverse least squares matrices already exist"
|
||||
<< abort(FatalError);
|
||||
}
|
||||
|
||||
// Get addressing
|
||||
const labelList& ibc = ibCells();
|
||||
const labelListList& ibcc = ibCellCells();
|
||||
const List<List<labelPair> >& ibcProcC = ibCellProcCells();
|
||||
const vectorField& ibp = ibPoints();
|
||||
|
||||
invDirichletMatricesPtr_ =
|
||||
new PtrList<scalarRectangularMatrix>(ibc.size());
|
||||
PtrList<scalarRectangularMatrix>& idm = *invDirichletMatricesPtr_;
|
||||
|
||||
const vectorField& C = mesh_.C().internalField();
|
||||
|
||||
scalarField conditionNumber(ibc.size(), 0.0);
|
||||
|
||||
// Initialize maxRowSum for debug
|
||||
scalar maxRowSum = 0.0;
|
||||
|
||||
const FieldField<Field, vector>& procC = ibProcCentres();
|
||||
|
||||
label nCoeffs = 5;
|
||||
|
||||
if (mesh_.nGeometricD() == 3)
|
||||
{
|
||||
nCoeffs += 4;
|
||||
}
|
||||
|
||||
forAll (idm, cellI)
|
||||
{
|
||||
const labelList& interpCells = ibcc[cellI];
|
||||
const List<labelPair>& interpProcCells = ibcProcC[cellI];
|
||||
|
||||
vectorField allPoints
|
||||
(
|
||||
interpCells.size()
|
||||
+ interpProcCells.size(),
|
||||
vector::zero
|
||||
);
|
||||
|
||||
if (allPoints.size() < nCoeffs)
|
||||
{
|
||||
FatalErrorIn
|
||||
(
|
||||
"void immersedBoundaryFvPatch::makeInvDirichletMatrices()"
|
||||
) << "allPoints.size() < " << nCoeffs << " : "
|
||||
<< allPoints.size() << abort(FatalError);
|
||||
}
|
||||
|
||||
label pointID = 0;
|
||||
|
||||
// Cells
|
||||
for (label i = 0; i < interpCells.size(); i++)
|
||||
{
|
||||
allPoints[pointID++] = C[interpCells[i]];
|
||||
}
|
||||
|
||||
// Processor cells
|
||||
for (label i = 0; i < interpProcCells.size(); i++)
|
||||
{
|
||||
allPoints[pointID++] =
|
||||
procC
|
||||
[
|
||||
interpProcCells[i].first()
|
||||
]
|
||||
[
|
||||
interpProcCells[i].second()
|
||||
];
|
||||
}
|
||||
|
||||
// Weights calculation
|
||||
|
||||
vector origin = C[ibc[cellI]];
|
||||
|
||||
scalarField curDist = mag(allPoints - origin);
|
||||
|
||||
// Calculate weights
|
||||
scalarField W =
|
||||
0.5*
|
||||
(
|
||||
1
|
||||
+ cos(mathematicalConstant::pi*curDist/(1.1*max(curDist)))
|
||||
);
|
||||
|
||||
idm.set
|
||||
(
|
||||
cellI,
|
||||
new scalarRectangularMatrix
|
||||
(
|
||||
nCoeffs,
|
||||
allPoints.size(),
|
||||
0.0
|
||||
)
|
||||
);
|
||||
scalarRectangularMatrix& curMatrix = idm[cellI];
|
||||
|
||||
scalarRectangularMatrix M
|
||||
(
|
||||
allPoints.size(),
|
||||
nCoeffs,
|
||||
0.0
|
||||
);
|
||||
|
||||
origin = ibp[cellI];
|
||||
|
||||
for(label i = 0; i < allPoints.size(); i++)
|
||||
{
|
||||
scalar X = allPoints[i].x() - origin.x();
|
||||
scalar Y = allPoints[i].y() - origin.y();
|
||||
|
||||
label coeff = 0;
|
||||
M[i][coeff++] = X;
|
||||
M[i][coeff++] = Y;
|
||||
M[i][coeff++] = X*Y;
|
||||
M[i][coeff++] = sqr(X);
|
||||
M[i][coeff++] = sqr(Y);
|
||||
|
||||
if (mesh_.nGeometricD() == 3)
|
||||
{
|
||||
scalar Z = allPoints[i].z() - origin.z();
|
||||
M[i][coeff++] = Z;
|
||||
M[i][coeff++] = X*Z;
|
||||
M[i][coeff++] = Y*Z;
|
||||
M[i][coeff++] = sqr(Z);
|
||||
}
|
||||
}
|
||||
|
||||
for (label i = 0; i < M.n(); i++)
|
||||
{
|
||||
for (label j = 0; j < M.m(); j++)
|
||||
{
|
||||
M[i][j] *= W[i];
|
||||
}
|
||||
}
|
||||
|
||||
scalarSquareMatrix lsM(nCoeffs, 0.0);
|
||||
|
||||
for (label i = 0; i < lsM.n(); i++)
|
||||
{
|
||||
for (label j = 0; j < lsM.m(); j++)
|
||||
{
|
||||
for (label k=0; k<M.n(); k++)
|
||||
{
|
||||
lsM[i][j] += M[k][i]*M[k][j];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (debug)
|
||||
{
|
||||
// Calculate matrix norm
|
||||
maxRowSum = 0.0;
|
||||
|
||||
for (label i = 0; i < lsM.n(); i++)
|
||||
{
|
||||
scalar curRowSum = 0.0;
|
||||
|
||||
for (label j = 0; j < lsM.m(); j++)
|
||||
{
|
||||
curRowSum += lsM[i][j];
|
||||
}
|
||||
|
||||
if (curRowSum > maxRowSum)
|
||||
{
|
||||
maxRowSum = curRowSum;
|
||||
}
|
||||
}
|
||||
|
||||
conditionNumber[cellI] = maxRowSum;
|
||||
}
|
||||
|
||||
// Calculate inverse
|
||||
scalarSquareMatrix invLsM = lsM.LUinvert();
|
||||
|
||||
for (label i = 0; i < lsM.n(); i++)
|
||||
{
|
||||
for (label j = 0; j < M.n(); j++)
|
||||
{
|
||||
for (label k = 0; k < lsM.n(); k++)
|
||||
{
|
||||
curMatrix[i][j] += invLsM[i][k]*M[j][k]*W[j];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (debug)
|
||||
{
|
||||
// Calculate condition number
|
||||
maxRowSum = 0.0;
|
||||
|
||||
for (label i = 0; i < lsM.n(); i++)
|
||||
{
|
||||
scalar curRowSum = 0.0;
|
||||
|
||||
for (label j = 0; j < lsM.m(); j++)
|
||||
{
|
||||
curRowSum += invLsM[i][j];
|
||||
}
|
||||
|
||||
if (curRowSum > maxRowSum)
|
||||
{
|
||||
maxRowSum = curRowSum;
|
||||
}
|
||||
}
|
||||
|
||||
conditionNumber[cellI] *= maxRowSum;
|
||||
|
||||
InfoIn
|
||||
(
|
||||
"void immersedBoundaryFvPatch::"
|
||||
"makeInvDirichletMatrices() const"
|
||||
) << "Max Dirichlet matrix condition number: "
|
||||
<< gMax(conditionNumber) << endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Foam::immersedBoundaryFvPatch::makeInvNeumannMatrices() const
|
||||
{
|
||||
if (debug)
|
||||
{
|
||||
Info<< "immersedBoundaryFvPatch::makeInvNeumannMatrices() : "
|
||||
<< "making immersed boundary inverse least sqares matrices"
|
||||
<< endl;
|
||||
}
|
||||
|
||||
// It is an error to attempt to recalculate
|
||||
// if the pointer is already set
|
||||
if (invNeumannMatricesPtr_)
|
||||
{
|
||||
FatalErrorIn("immersedBoundaryFvPatch::makeInvNeumannMatrices()")
|
||||
<< "immersed boundary inverse least squares matrices already exist"
|
||||
<< abort(FatalError);
|
||||
}
|
||||
|
||||
// Get addressing
|
||||
const labelList& ibc = ibCells();
|
||||
const labelListList& ibcc = ibCellCells();
|
||||
const List<List<labelPair> >& ibcProcC = ibCellProcCells();
|
||||
const vectorField& ibp = ibPoints();
|
||||
|
||||
// Note: the algorithm is originally written with inward-facing normals
|
||||
// and subsequently changed: IB surface normals point outwards
|
||||
// HJ, 21/May/2012
|
||||
const vectorField& ibn = ibNormals();
|
||||
|
||||
invNeumannMatricesPtr_ =
|
||||
new PtrList<scalarRectangularMatrix>(ibc.size());
|
||||
PtrList<scalarRectangularMatrix>& inm = *invNeumannMatricesPtr_;
|
||||
|
||||
const vectorField& C = mesh_.C().internalField();
|
||||
|
||||
scalarField conditionNumber(ibc.size(), 0);
|
||||
|
||||
// Initialize maxRowSum for debug
|
||||
scalar maxRowSum = 0.0;
|
||||
|
||||
const FieldField<Field, vector>& procC = ibProcCentres();
|
||||
|
||||
label nCoeffs = 6;
|
||||
|
||||
if (mesh_.nGeometricD() == 3)
|
||||
{
|
||||
nCoeffs += 4;
|
||||
}
|
||||
|
||||
forAll (inm, cellI)
|
||||
{
|
||||
const labelList& interpCells = ibcc[cellI];
|
||||
const List<labelPair>& interpProcCells = ibcProcC[cellI];
|
||||
|
||||
vectorField allPoints
|
||||
(
|
||||
interpCells.size() + 1
|
||||
+ interpProcCells.size(),
|
||||
vector::zero
|
||||
);
|
||||
|
||||
label pointID = 0;
|
||||
|
||||
// Cells
|
||||
for (label i = 0; i < interpCells.size(); i++)
|
||||
{
|
||||
allPoints[pointID++] = C[interpCells[i]];
|
||||
}
|
||||
|
||||
// IB point
|
||||
allPoints[pointID++] = ibp[cellI];
|
||||
|
||||
// Processor cells
|
||||
for (label i = 0; i < interpProcCells.size(); i++)
|
||||
{
|
||||
allPoints[pointID++] =
|
||||
procC
|
||||
[
|
||||
interpProcCells[i].first()
|
||||
]
|
||||
[
|
||||
interpProcCells[i].second()
|
||||
];
|
||||
}
|
||||
|
||||
// Weights calculation
|
||||
|
||||
vector origin = C[ibc[cellI]];
|
||||
|
||||
scalarField curR = mag(allPoints - origin);
|
||||
|
||||
// Calculate weights
|
||||
scalarField W = 1 - curR/(1.1*max(curR));
|
||||
|
||||
|
||||
inm.set
|
||||
(
|
||||
cellI,
|
||||
new scalarRectangularMatrix
|
||||
(
|
||||
nCoeffs,
|
||||
allPoints.size(),
|
||||
0.0
|
||||
)
|
||||
);
|
||||
scalarRectangularMatrix& curMatrix = inm[cellI];
|
||||
|
||||
scalarRectangularMatrix M
|
||||
(
|
||||
allPoints.size(),
|
||||
nCoeffs,
|
||||
0.0
|
||||
);
|
||||
|
||||
pointID = 0;
|
||||
origin = ibp[cellI];
|
||||
for (label i = 0; i < interpCells.size(); i++)
|
||||
{
|
||||
scalar X = allPoints[pointID].x() - origin.x();
|
||||
scalar Y = allPoints[pointID].y() - origin.y();
|
||||
|
||||
M[pointID][0] = 1.0;
|
||||
M[pointID][1] = X;
|
||||
M[pointID][2] = Y;
|
||||
M[pointID][3] = X*Y;
|
||||
M[pointID][4] = sqr(X);
|
||||
M[pointID][5] = sqr(Y);
|
||||
|
||||
if (mesh_.nGeometricD() == 3)
|
||||
{
|
||||
scalar Z = allPoints[pointID].z() - origin.z();
|
||||
|
||||
M[pointID][6] = Z;
|
||||
M[pointID][7] = X*Z;
|
||||
M[pointID][8] = Y*Z;
|
||||
M[pointID][9] = sqr(Z);
|
||||
}
|
||||
|
||||
pointID++;
|
||||
}
|
||||
|
||||
scalar X = allPoints[pointID].x() - origin.x();
|
||||
scalar Y = allPoints[pointID].y() - origin.y();
|
||||
|
||||
M[pointID][0] = 0;
|
||||
M[pointID][1] = -ibn[cellI].x();
|
||||
M[pointID][2] = -ibn[cellI].y();
|
||||
M[pointID][3] =
|
||||
(
|
||||
-ibn[cellI].x()*Y
|
||||
- ibn[cellI].y()*X
|
||||
);
|
||||
M[pointID][4] = -2*ibn[cellI].x()*X;
|
||||
M[pointID][5] = -2*ibn[cellI].y()*Y;
|
||||
|
||||
if (mesh_.nGeometricD() == 3)
|
||||
{
|
||||
scalar Z = allPoints[pointID].z() - origin.z();
|
||||
|
||||
M[pointID][6] = -ibn[cellI].z();
|
||||
M[pointID][7] =
|
||||
(
|
||||
-ibn[cellI].x()*Z
|
||||
- ibn[cellI].z()*X
|
||||
);
|
||||
M[pointID][8] =
|
||||
(
|
||||
-ibn[cellI].y()*Z
|
||||
- ibn[cellI].z()*Y
|
||||
);
|
||||
M[pointID][9] = -2*ibn[cellI].z()*Z;
|
||||
}
|
||||
|
||||
pointID++;
|
||||
|
||||
for(label i = 0; i < interpProcCells.size(); i++)
|
||||
{
|
||||
scalar X = allPoints[pointID].x() - origin.x();
|
||||
scalar Y = allPoints[pointID].y() - origin.y();
|
||||
|
||||
M[pointID][0] = 1.0;
|
||||
M[pointID][1] = X;
|
||||
M[pointID][2] = Y;
|
||||
M[pointID][3] = X*Y;
|
||||
M[pointID][4] = sqr(X);
|
||||
M[pointID][5] = sqr(Y);
|
||||
|
||||
if (mesh_.nGeometricD() == 3)
|
||||
{
|
||||
scalar Z = allPoints[pointID].z() - origin.z();
|
||||
|
||||
M[pointID][6] = Z;
|
||||
M[pointID][7] = X*Z;
|
||||
M[pointID][8] = Y*Z;
|
||||
M[pointID][9] = sqr(Z);
|
||||
}
|
||||
|
||||
pointID++;
|
||||
}
|
||||
|
||||
for (label i = 0; i < M.n(); i++)
|
||||
{
|
||||
for (label j = 0; j < M.m(); j++)
|
||||
{
|
||||
M[i][j] *= W[i];
|
||||
}
|
||||
}
|
||||
|
||||
scalarSquareMatrix lsM(nCoeffs, 0.0);
|
||||
|
||||
for (label i = 0; i < lsM.n(); i++)
|
||||
{
|
||||
for (label j = 0; j < lsM.m(); j++)
|
||||
{
|
||||
for (label k = 0; k < M.n(); k++)
|
||||
{
|
||||
lsM[i][j] += M[k][i]*M[k][j];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Calculate matrix norm
|
||||
if (debug)
|
||||
{
|
||||
maxRowSum = 0.0;
|
||||
|
||||
for (label i = 0; i < lsM.n(); i++)
|
||||
{
|
||||
scalar curRowSum = 0.0;
|
||||
|
||||
for (label j = 0; j < lsM.m(); j++)
|
||||
{
|
||||
curRowSum += lsM[i][j];
|
||||
}
|
||||
|
||||
if (curRowSum > maxRowSum)
|
||||
{
|
||||
maxRowSum = curRowSum;
|
||||
}
|
||||
}
|
||||
|
||||
conditionNumber[cellI] = maxRowSum;
|
||||
}
|
||||
|
||||
// Calculate inverse
|
||||
scalarSquareMatrix invLsM = lsM.LUinvert();
|
||||
|
||||
for (label i = 0; i < lsM.n(); i++)
|
||||
{
|
||||
for (label j = 0; j < M.n(); j++)
|
||||
{
|
||||
for (label k = 0; k < lsM.n(); k++)
|
||||
{
|
||||
curMatrix[i][j] += invLsM[i][k]*M[j][k]*W[j];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Calculate condition number
|
||||
if (debug)
|
||||
{
|
||||
maxRowSum = 0.0;
|
||||
|
||||
for (label i = 0; i < lsM.n(); i++)
|
||||
{
|
||||
scalar curRowSum = 0.0;
|
||||
|
||||
for (label j = 0; j < lsM.m(); j++)
|
||||
{
|
||||
curRowSum += invLsM[i][j];
|
||||
}
|
||||
|
||||
if (curRowSum > maxRowSum)
|
||||
{
|
||||
maxRowSum = curRowSum;
|
||||
}
|
||||
}
|
||||
|
||||
conditionNumber[cellI] *= maxRowSum;
|
||||
|
||||
if (conditionNumber[cellI] > 1e6)
|
||||
{
|
||||
labelList CC = interpCells;
|
||||
sort(CC);
|
||||
|
||||
Info<< "Condition = " << conditionNumber[cellI] << nl
|
||||
<< "cell cells: " << CC
|
||||
<< "M = " << lsM
|
||||
<< endl;
|
||||
}
|
||||
|
||||
InfoIn
|
||||
(
|
||||
"void immersedBoundaryFvPatch::makeInvNeumannMatrices() const"
|
||||
) << "Max Neumann matrix condition number: "
|
||||
<< gMax(conditionNumber) << endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const Foam::PtrList<Foam::scalarRectangularMatrix>&
|
||||
Foam::immersedBoundaryFvPatch::invDirichletMatrices() const
|
||||
{
|
||||
if (!invDirichletMatricesPtr_)
|
||||
{
|
||||
makeInvDirichletMatrices();
|
||||
}
|
||||
|
||||
return *invDirichletMatricesPtr_;
|
||||
}
|
||||
|
||||
|
||||
const Foam::PtrList<Foam::scalarRectangularMatrix>&
|
||||
Foam::immersedBoundaryFvPatch::invNeumannMatrices() const
|
||||
{
|
||||
if (!invNeumannMatricesPtr_)
|
||||
{
|
||||
makeInvNeumannMatrices();
|
||||
}
|
||||
|
||||
return *invNeumannMatricesPtr_;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
|
@ -0,0 +1,208 @@
|
|||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright held by original author
|
||||
\\/ 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 2 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, write to the Free Software Foundation,
|
||||
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "immersedBoundaryFvPatch.H"
|
||||
#include "fvMesh.H"
|
||||
#include "volFields.H"
|
||||
|
||||
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||
|
||||
void Foam::immersedBoundaryFvPatch::makeIbSamplingWeights() const
|
||||
{
|
||||
if (debug)
|
||||
{
|
||||
Info<< "immersedBoundaryFvPatch::makeIbSamplingWeights() : "
|
||||
<< "making sampling point weights"
|
||||
<< endl;
|
||||
}
|
||||
|
||||
// It is an error to attempt to recalculate
|
||||
// if the pointer is already set
|
||||
if (ibSamplingWeightsPtr_ || ibSamplingProcWeightsPtr_)
|
||||
{
|
||||
FatalErrorIn("void immersedBoundaryFvPatch::makeIbSamplingWeights()")
|
||||
<< "sampling point weights already exist"
|
||||
<< abort(FatalError);
|
||||
}
|
||||
|
||||
// Get addressing
|
||||
const labelList& ibc = ibCells();
|
||||
const labelListList& ibcc = ibCellCells();
|
||||
const List<List<labelPair> >& ibcProcC = ibCellProcCells();
|
||||
|
||||
// Initialise the weights
|
||||
ibSamplingWeightsPtr_ = new scalarListList(ibc.size());
|
||||
scalarListList& cellWeights = *ibSamplingWeightsPtr_;
|
||||
|
||||
forAll (cellWeights, cellI)
|
||||
{
|
||||
cellWeights[cellI].setSize(ibcc[cellI].size(), 0);
|
||||
}
|
||||
|
||||
ibSamplingProcWeightsPtr_ = new scalarListList(ibc.size());
|
||||
scalarListList& cellProcWeights = *ibSamplingProcWeightsPtr_;
|
||||
|
||||
forAll (cellProcWeights, cellI)
|
||||
{
|
||||
cellProcWeights[cellI].setSize(ibcProcC[cellI].size(), 0);
|
||||
}
|
||||
|
||||
// Get sampling point locations
|
||||
const vectorField& samplingPoints = ibSamplingPoints();
|
||||
const scalarField& gammaIn = gamma().internalField();
|
||||
const vectorField& CIn = mesh_.C().internalField();
|
||||
|
||||
const FieldField<Field, scalar>& gammaProc = ibProcGamma();
|
||||
const FieldField<Field, vector>& CProc = ibProcCentres();
|
||||
|
||||
// Go through all cellCells and calculate inverse distance for
|
||||
// all live points
|
||||
forAll (samplingPoints, cellI)
|
||||
{
|
||||
const vector& curP = samplingPoints[cellI];
|
||||
|
||||
scalar sumW = 0;
|
||||
|
||||
// Local weights
|
||||
scalarList& curCW = cellWeights[cellI];
|
||||
|
||||
const labelList& curCells = ibcc[cellI];
|
||||
|
||||
forAll (curCells, ccI)
|
||||
{
|
||||
// Only pick live cells
|
||||
if (gammaIn[curCells[ccI]] > SMALL)
|
||||
{
|
||||
curCW[ccI] = 1/mag(CIn[curCells[ccI]] - curP);
|
||||
sumW += curCW[ccI];
|
||||
}
|
||||
else
|
||||
{
|
||||
curCW[ccI] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Processor weights
|
||||
const List<labelPair>& interpProcCells = ibcProcC[cellI];
|
||||
|
||||
scalarList& curProcCW = cellProcWeights[cellI];
|
||||
|
||||
forAll (interpProcCells, cProcI)
|
||||
{
|
||||
if
|
||||
(
|
||||
gammaProc
|
||||
[
|
||||
interpProcCells[cProcI].first()
|
||||
]
|
||||
[
|
||||
interpProcCells[cProcI].second()
|
||||
] > SMALL
|
||||
)
|
||||
{
|
||||
curProcCW[cProcI] =
|
||||
1/mag
|
||||
(
|
||||
CProc
|
||||
[
|
||||
interpProcCells[cProcI].first()
|
||||
]
|
||||
[
|
||||
interpProcCells[cProcI].second()
|
||||
] - curP
|
||||
);
|
||||
|
||||
sumW += curProcCW[cProcI];
|
||||
}
|
||||
else
|
||||
{
|
||||
curProcCW[cProcI] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Divide through by the sum
|
||||
if (sumW < SMALL)
|
||||
{
|
||||
InfoIn
|
||||
(
|
||||
"void immersedBoundaryFvPatch::makeIbSamplingWeights()"
|
||||
) << "Insufficient live neighbourhood for IB cell "
|
||||
<< ibc[cellI] << "." << nl
|
||||
<< "Please adjust radiusFactor, angleFactor or "
|
||||
<< "immersedBoundaryMaxCellCellRows "
|
||||
<< "in immersedBoundaryFvPatch."
|
||||
<< endl;
|
||||
|
||||
// Reset sum and weights and use all points
|
||||
sumW = 0;
|
||||
curCW = 0;
|
||||
|
||||
forAll (curCells, ccI)
|
||||
{
|
||||
// Use all cells
|
||||
curCW[ccI] = 1/mag(CIn[curCells[ccI]] - curP);
|
||||
sumW += curCW[ccI];
|
||||
}
|
||||
}
|
||||
|
||||
forAll (curCells, ccI)
|
||||
{
|
||||
curCW[ccI] /= sumW;
|
||||
}
|
||||
|
||||
forAll (curProcCW, cProcI)
|
||||
{
|
||||
curProcCW[cProcI] /= sumW;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const Foam::scalarListList&
|
||||
Foam::immersedBoundaryFvPatch::ibSamplingWeights() const
|
||||
{
|
||||
if (!ibSamplingWeightsPtr_)
|
||||
{
|
||||
makeIbSamplingWeights();
|
||||
}
|
||||
|
||||
return *ibSamplingWeightsPtr_;
|
||||
}
|
||||
|
||||
|
||||
const Foam::scalarListList&
|
||||
Foam::immersedBoundaryFvPatch::ibSamplingProcWeights() const
|
||||
{
|
||||
if (!ibSamplingProcWeightsPtr_)
|
||||
{
|
||||
makeIbSamplingWeights();
|
||||
}
|
||||
|
||||
return *ibSamplingProcWeightsPtr_;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
|
@ -0,0 +1,324 @@
|
|||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright held by original author
|
||||
\\/ 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 2 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, write to the Free Software Foundation,
|
||||
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "immersedBoundaryFvPatch.H"
|
||||
#include "fvMesh.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
template<class Type>
|
||||
Foam::tmp<Foam::FieldField<Foam::Field, Type> >
|
||||
Foam::immersedBoundaryFvPatch::sendAndReceive
|
||||
(
|
||||
const Field<Type>& psi
|
||||
) const
|
||||
{
|
||||
tmp<FieldField<Field, Type> > tprocPsi
|
||||
(
|
||||
new FieldField<Field, Type>(Pstream::nProcs())
|
||||
);
|
||||
FieldField<Field, Type>& procPsi = tprocPsi();
|
||||
|
||||
forAll (procPsi, procI)
|
||||
{
|
||||
procPsi.set
|
||||
(
|
||||
procI,
|
||||
new Field<Type>
|
||||
(
|
||||
ibProcCentres()[procI].size(),
|
||||
pTraits<Type>::zero
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
if (Pstream::parRun())
|
||||
{
|
||||
// Send
|
||||
for (label procI = 0; procI < Pstream::nProcs(); procI++)
|
||||
{
|
||||
if (procI != Pstream::myProcNo())
|
||||
{
|
||||
// Do not send empty lists
|
||||
if (!ibProcCells()[procI].empty())
|
||||
{
|
||||
Field<Type> curPsi(psi, ibProcCells()[procI]);
|
||||
|
||||
// Parallel data exchange
|
||||
OPstream toProc
|
||||
(
|
||||
Pstream::blocking,
|
||||
procI,
|
||||
curPsi.size()*sizeof(Type)
|
||||
);
|
||||
|
||||
toProc << curPsi;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Receive
|
||||
for (label procI = 0; procI < Pstream::nProcs(); procI++)
|
||||
{
|
||||
if (procI != Pstream::myProcNo())
|
||||
{
|
||||
// Do not receive empty lists
|
||||
if (!procPsi[procI].empty())
|
||||
{
|
||||
// Parallel data exchange
|
||||
IPstream fromProc
|
||||
(
|
||||
Pstream::blocking,
|
||||
procI,
|
||||
procPsi[procI].size()*sizeof(Type)
|
||||
);
|
||||
|
||||
fromProc >> procPsi[procI];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return tprocPsi;
|
||||
}
|
||||
|
||||
|
||||
template<class Type>
|
||||
Foam::tmp<Foam::Field<Type> >
|
||||
Foam::immersedBoundaryFvPatch::toIbPoints
|
||||
(
|
||||
const Field<Type>& triValues
|
||||
) const
|
||||
{
|
||||
if (triValues.size() != ibMesh().size())
|
||||
{
|
||||
FatalErrorIn
|
||||
(
|
||||
"template<class Type>\n"
|
||||
"Foam::tmp<Foam::Field<Type> >\n"
|
||||
"immersedBoundaryFvPatch::toIbPoints\n"
|
||||
"(\n"
|
||||
" const Field<Type>& triValues\n"
|
||||
") const"
|
||||
) << "Field size does not correspond to size of immersed boundary "
|
||||
<< "triangulated surface for patch " << name() << nl
|
||||
<< "Field size = " << triValues.size()
|
||||
<< " surface size = " << ibMesh().size()
|
||||
<< abort(FatalError);
|
||||
}
|
||||
|
||||
const labelList& ibc = ibCells();
|
||||
|
||||
tmp<Field<Type> > tIbPsi
|
||||
(
|
||||
new Field<Type>(ibc.size(), pTraits<Type>::zero)
|
||||
);
|
||||
Field<Type>& ibPsi = tIbPsi();
|
||||
|
||||
const labelList& hf = hitFaces();
|
||||
|
||||
// Assuming triSurface data is on triangles
|
||||
forAll (ibPsi, cellI)
|
||||
{
|
||||
ibPsi[cellI] = triValues[hf[cellI]];
|
||||
}
|
||||
|
||||
// const vectorField& p = ibPoints();
|
||||
// const List<labelledTri>& faces = ibMesh();
|
||||
// const vectorField& triPoints = ibMesh().points();
|
||||
|
||||
// // Assuming triSurface data is on vertices
|
||||
// forAll (ibPsi, cellI)
|
||||
// {
|
||||
// const labelledTri& tri = faces[hf[cellI]];
|
||||
// triPointRef triPt = faces[hf[cellI]].tri(triPoints);
|
||||
|
||||
// ibPsi[cellI] =
|
||||
// triValues[tri[0]]*triPt.Ni(0, p[cellI])
|
||||
// + triValues[tri[1]]*triPt.Ni(1, p[cellI])
|
||||
// + triValues[tri[2]]*triPt.Ni(2, p[cellI]);
|
||||
// }
|
||||
|
||||
return tIbPsi;
|
||||
}
|
||||
|
||||
|
||||
template<class Type>
|
||||
Foam::tmp<Foam::Field<Type> >
|
||||
Foam::immersedBoundaryFvPatch::toIbPoints
|
||||
(
|
||||
const tmp<Field<Type> >& ttriValues
|
||||
) const
|
||||
{
|
||||
tmp<Field<Type> > tint = toIbPoints(ttriValues());
|
||||
ttriValues.clear();
|
||||
return tint;
|
||||
|
||||
}
|
||||
|
||||
|
||||
template<class Type>
|
||||
Foam::tmp<Foam::Field<Type> >
|
||||
Foam::immersedBoundaryFvPatch::toTriFaces
|
||||
(
|
||||
const Field<Type>& ibValues
|
||||
) const
|
||||
{
|
||||
if (ibValues.size() != ibCells().size())
|
||||
{
|
||||
FatalErrorIn
|
||||
(
|
||||
"template<class Type>\n"
|
||||
"Foam::tmp<Foam::Field<Type> >\n"
|
||||
"immersedBoundaryFvPatch::toTriFaces\n"
|
||||
"(\n"
|
||||
" const Field<Type>& ibValues\n"
|
||||
") const"
|
||||
) << "Field size does not correspond to size of IB points "
|
||||
<< "triangulated surface for patch " << name() << nl
|
||||
<< "Field size = " << ibValues.size()
|
||||
<< " IB points size = " << ibCells().size()
|
||||
<< abort(FatalError);
|
||||
}
|
||||
|
||||
const labelListList& ctfAddr = cellsToTriAddr();
|
||||
const scalarListList& ctfWeights = cellsToTriWeights();
|
||||
|
||||
tmp<Field<Type> > tIbPsi
|
||||
(
|
||||
new Field<Type>(ctfAddr.size(), pTraits<Type>::zero)
|
||||
);
|
||||
Field<Type>& ibPsi = tIbPsi();
|
||||
|
||||
// Do interpolation
|
||||
forAll (ctfAddr, triI)
|
||||
{
|
||||
const labelList& curAddr = ctfAddr[triI];
|
||||
const scalarList& curWeights = ctfWeights[triI];
|
||||
|
||||
forAll (curAddr, cellI)
|
||||
{
|
||||
ibPsi[triI] += curWeights[cellI]*ibValues[curAddr[cellI]];
|
||||
}
|
||||
}
|
||||
|
||||
return tIbPsi;
|
||||
}
|
||||
|
||||
|
||||
template<class Type>
|
||||
Foam::tmp<Foam::Field<Type> >
|
||||
Foam::immersedBoundaryFvPatch::toTriFaces
|
||||
(
|
||||
const tmp<Field<Type> >& tibValues
|
||||
) const
|
||||
{
|
||||
tmp<Field<Type> > tint = toTriFaces(tibValues());
|
||||
tibValues.clear();
|
||||
return tint;
|
||||
|
||||
}
|
||||
|
||||
|
||||
template<class Type>
|
||||
Foam::tmp<Foam::Field<Type> >
|
||||
Foam::immersedBoundaryFvPatch::toSamplingPoints
|
||||
(
|
||||
const Field<Type>& cellValues
|
||||
) const
|
||||
{
|
||||
if (cellValues.size() != mesh_.nCells())
|
||||
{
|
||||
FatalErrorIn
|
||||
(
|
||||
"template<class Type>\n"
|
||||
"Foam::tmp<Foam::Field<Type> >\n"
|
||||
"immersedBoundaryFvPatch::toSamplingPoints\n"
|
||||
"(\n"
|
||||
" const Field<Type>& cellValues\n"
|
||||
") const"
|
||||
) << "Field size does not correspond to cell centres "
|
||||
<< "for patch " << name() << nl
|
||||
<< "Field size = " << cellValues.size()
|
||||
<< " nCells = " << mesh_.nCells()
|
||||
<< abort(FatalError);
|
||||
}
|
||||
|
||||
// Get addressing
|
||||
const labelList& ibc = ibCells();
|
||||
const labelListList& ibcc = ibCellCells();
|
||||
const List<List<labelPair> >& ibcProcC = ibCellProcCells();
|
||||
|
||||
// Get weights
|
||||
const scalarListList& cellWeights = ibSamplingWeights();
|
||||
const scalarListList& cellProcWeights = ibSamplingProcWeights();
|
||||
|
||||
tmp<Field<Type> > tIbPsi
|
||||
(
|
||||
new Field<Type>(ibc.size(), pTraits<Type>::zero)
|
||||
);
|
||||
Field<Type>& ibPsi = tIbPsi();
|
||||
|
||||
// Do interpolation, local cell data
|
||||
forAll (ibc, cellI)
|
||||
{
|
||||
const labelList& curAddr = ibcc[cellI];
|
||||
const scalarList& curWeights = cellWeights[cellI];
|
||||
|
||||
forAll (curAddr, ccI)
|
||||
{
|
||||
ibPsi[cellI] += curWeights[ccI]*cellValues[curAddr[ccI]];
|
||||
}
|
||||
}
|
||||
|
||||
// Parallel communication for psi
|
||||
FieldField<Field, Type> procCellValues = sendAndReceive(cellValues);
|
||||
|
||||
// Do interpolation, cell data from other processors
|
||||
forAll (ibc, cellI)
|
||||
{
|
||||
const List<labelPair>& curProcCells = ibcProcC[cellI];
|
||||
const scalarList& curProcWeights = cellProcWeights[cellI];
|
||||
|
||||
forAll (curProcCells, cpcI)
|
||||
{
|
||||
ibPsi[cellI] +=
|
||||
curProcWeights[cpcI]*
|
||||
procCellValues
|
||||
[
|
||||
curProcCells[cpcI].first()
|
||||
]
|
||||
[
|
||||
curProcCells[cpcI].second()
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
return tIbPsi;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************ //
|
|
@ -0,0 +1,201 @@
|
|||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright held by original author
|
||||
\\/ 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 2 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, write to the Free Software Foundation,
|
||||
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "immersedBoundaryFvPatch.H"
|
||||
|
||||
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||
|
||||
void Foam::immersedBoundaryFvPatch::makeTriAddressing() const
|
||||
{
|
||||
if (debug)
|
||||
{
|
||||
InfoIn("void immersedBoundaryFvPatch::makeTriAddressing() const")
|
||||
<< "creating tri addressing for immersed boundary " << name()
|
||||
<< endl;
|
||||
}
|
||||
|
||||
// It is an error to attempt to recalculate
|
||||
// if the pointer is already set
|
||||
if (cellsToTriAddrPtr_ || cellsToTriWeightsPtr_)
|
||||
{
|
||||
FatalErrorIn("immersedBoundaryFvPatch::makeTriAddressing() const")
|
||||
<< "tri addressing already exist"
|
||||
<< "for immersed boundary" << name()
|
||||
<< abort(FatalError);
|
||||
}
|
||||
|
||||
// Get reference to tri patch and hit faces
|
||||
const triSurface& triPatch = ibPolyPatch_.ibMesh();
|
||||
const vectorField& triCentres = triPatch.faceCentres();
|
||||
|
||||
const labelList& hf = hitFaces();
|
||||
const vectorField& ibp = ibPoints();
|
||||
|
||||
// Create a markup field and mark all tris containing an ib point with its
|
||||
// index
|
||||
labelList hitTris(triPatch.size(), -1);
|
||||
|
||||
forAll (hf, hfI)
|
||||
{
|
||||
hitTris[hf[hfI]] = hfI;
|
||||
}
|
||||
|
||||
// Allocate storage
|
||||
cellsToTriAddrPtr_ = new labelListList(triPatch.size());
|
||||
labelListList& addr = *cellsToTriAddrPtr_;
|
||||
|
||||
cellsToTriWeightsPtr_ = new scalarListList(triPatch.size());
|
||||
scalarListList& w = *cellsToTriWeightsPtr_;
|
||||
|
||||
// Algorithm:
|
||||
// For each tri face, check if it contains an IB point
|
||||
// - if so, set the addressing to the index of IB point and weight to 1
|
||||
// - if not, search the neighbouring faces of the visited faces until
|
||||
// at least 3 IB points are found, or the neighbourhood is exhausted.
|
||||
// When a sufficient number of points is found, calculate the weights
|
||||
// using inverse distance weighting
|
||||
|
||||
// Get addressing from the triangular patch
|
||||
const labelListList& pf = triPatch.pointFaces();
|
||||
|
||||
forAll (triPatch, triI)
|
||||
{
|
||||
if (hitTris[triI] > -1)
|
||||
{
|
||||
// Triangle contains IB point
|
||||
addr[triI].setSize(1);
|
||||
w[triI].setSize(1);
|
||||
|
||||
addr[triI] = hitTris[triI];
|
||||
w[triI] = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
// No direct hit. Start a neighbourhood search
|
||||
|
||||
// Record already visited faces
|
||||
labelHashSet visited;
|
||||
|
||||
// Collect new faces to visit
|
||||
SLList<label> nextToVisit;
|
||||
|
||||
// Collect IB points for interpolation
|
||||
labelHashSet ibPointsToUse;
|
||||
|
||||
// Initialise with the original tri
|
||||
nextToVisit.insert(triI);
|
||||
|
||||
do
|
||||
{
|
||||
const label curTri = nextToVisit.removeHead();
|
||||
|
||||
// Discard tri if already visited
|
||||
if (visited[curTri]) continue;
|
||||
|
||||
visited.insert(curTri);
|
||||
|
||||
const triFace& curTriPoints = triPatch[curTri];
|
||||
|
||||
// For all current points of face, pick up neighbouring faces
|
||||
forAll (curTriPoints, tpI)
|
||||
{
|
||||
const labelList curNbrs = pf[curTriPoints[tpI]];
|
||||
|
||||
forAll (curNbrs, nbrI)
|
||||
{
|
||||
if (!visited.found(curNbrs[nbrI]))
|
||||
{
|
||||
// Found a face which is not visited. Add it to
|
||||
// the list of faces to visit
|
||||
nextToVisit.append(curNbrs[nbrI]);
|
||||
|
||||
if (hitTris[curNbrs[nbrI]] > -1)
|
||||
{
|
||||
// Found a neighbour with a hit: use this
|
||||
// IB point
|
||||
ibPointsToUse.insert(hitTris[curNbrs[nbrI]]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} while
|
||||
(
|
||||
ibPointsToUse.size() < 3
|
||||
&& !nextToVisit.empty()
|
||||
);
|
||||
|
||||
// Found neighbourhood: collect addressing and weights
|
||||
addr[triI] = ibPointsToUse.toc();
|
||||
w[triI].setSize(addr[triI].size());
|
||||
|
||||
labelList& curAddr = addr[triI];
|
||||
scalarList& curW = w[triI];
|
||||
|
||||
vector curTriCentre = triCentres[triI];
|
||||
|
||||
scalar sumW = 0;
|
||||
|
||||
forAll (curAddr, ibI)
|
||||
{
|
||||
curW[ibI] = 1/mag(curTriCentre - ibp[curAddr[ibI]]);
|
||||
sumW += curW[ibI];
|
||||
}
|
||||
|
||||
// Divide weights by sum distance
|
||||
forAll (curW, ibI)
|
||||
{
|
||||
curW[ibI] /= sumW;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const Foam::labelListList&
|
||||
Foam::immersedBoundaryFvPatch::cellsToTriAddr() const
|
||||
{
|
||||
if (!cellsToTriAddrPtr_)
|
||||
{
|
||||
makeTriAddressing();
|
||||
}
|
||||
|
||||
return *cellsToTriAddrPtr_;
|
||||
}
|
||||
|
||||
|
||||
const Foam::scalarListList&
|
||||
Foam::immersedBoundaryFvPatch::cellsToTriWeights() const
|
||||
{
|
||||
if (!cellsToTriWeightsPtr_)
|
||||
{
|
||||
makeTriAddressing();
|
||||
}
|
||||
|
||||
return *cellsToTriWeightsPtr_;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,402 @@
|
|||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright held by original author
|
||||
\\/ 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 2 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, write to the Free Software Foundation,
|
||||
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
Class
|
||||
Foam::immersedBoundaryFvPatchField
|
||||
|
||||
Description
|
||||
Foam::immersedBoundaryFvPatchField
|
||||
|
||||
Author
|
||||
Hrvoje Jasak
|
||||
|
||||
SourceFiles
|
||||
immersedBoundaryFvPatchField.C
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef immersedBoundaryFvPatchField_H
|
||||
#define immersedBoundaryFvPatchField_H
|
||||
|
||||
#include "fvPatchField.H"
|
||||
#include "immersedBoundaryFvPatch.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class immersedBoundaryFvPatchField Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
template<class Type>
|
||||
class immersedBoundaryFvPatchField
|
||||
:
|
||||
public fvPatchField<Type>
|
||||
{
|
||||
// Private data
|
||||
|
||||
//- Local reference cast into the processor patch
|
||||
const immersedBoundaryFvPatch& ibPatch_;
|
||||
|
||||
//- Local reference to fvMesh
|
||||
const fvMesh& mesh_;
|
||||
|
||||
// Defining fields
|
||||
// Note: defining fields carry values on faces of the IB patch
|
||||
// represented as a triangulated surface
|
||||
|
||||
//- Defining value field
|
||||
Field<Type> refValue_;
|
||||
|
||||
//- Defining normal gradient field
|
||||
Field<Type> refGrad_;
|
||||
|
||||
|
||||
//- Does the boundary condition fix the value
|
||||
Switch fixesValue_;
|
||||
|
||||
|
||||
// Dead cell controls
|
||||
|
||||
//- Set dead cell value
|
||||
Switch setDeadCellValue_;
|
||||
|
||||
//- Dead cell value
|
||||
Type deadCellValue_;
|
||||
|
||||
|
||||
// Fields on the IB intersection points
|
||||
// Field size equals the number of cells intesected with the IB
|
||||
|
||||
//- Time index for last update of mesh or moving boundary
|
||||
mutable label ibUpdateTimeIndex_;
|
||||
|
||||
//- Value field
|
||||
mutable Field<Type> ibValue_;
|
||||
|
||||
//- Normal gradient field
|
||||
mutable Field<Type> ibGrad_;
|
||||
|
||||
|
||||
// Private Member Functions
|
||||
|
||||
//- Update IB value and gradient
|
||||
void updateIbValues() const;
|
||||
|
||||
//- Impose Dirichlet BC at IB cells and return corrected cells values
|
||||
// Calculate value and gradient on IB intersection points
|
||||
tmp<Field<Type> > imposeDirichletCondition() const;
|
||||
|
||||
//- Impose Neumann BC at IB cells and return corrected cells values
|
||||
// Calculate value and gradient on IB intersection points
|
||||
tmp<Field<Type> > imposeNeumannCondition() const;
|
||||
|
||||
//- Impose condition in dead cells
|
||||
void imposeDeadCondition();
|
||||
|
||||
|
||||
// Manipulate matrix
|
||||
|
||||
//- Check and correct zero diagonal in dead cells
|
||||
void correctDiag
|
||||
(
|
||||
fvMatrix<Type>& eqn
|
||||
) const;
|
||||
|
||||
//- Impose fixed gradient condition by manipulating matrix
|
||||
// Note: reconsider pre-factor for diffusivity
|
||||
// HJ, 16/Apr/2012
|
||||
void correctOffDiag
|
||||
(
|
||||
fvMatrix<Type>& eqn
|
||||
) const;
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
// Protected Member Functions
|
||||
|
||||
//- Does immersed boundary patch field need motion update?
|
||||
bool motionUpdateRequired() const;
|
||||
|
||||
//- Execute immersed boundary patch field motion update
|
||||
virtual void motionUpdate() const;
|
||||
|
||||
//- Set IB cell values
|
||||
virtual void setIbCellValues(const Field<Type>&) const;
|
||||
|
||||
|
||||
public:
|
||||
|
||||
//- Runtime type information
|
||||
TypeName(immersedBoundaryFvPatch::typeName_());
|
||||
|
||||
|
||||
// Static algorithm control data
|
||||
|
||||
//- Number of boundary condition update iterations
|
||||
static label nBcIter_;
|
||||
|
||||
//- Boundary condition update tolerance
|
||||
static scalar bcTolerance_;
|
||||
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Construct from patch and internal field
|
||||
immersedBoundaryFvPatchField
|
||||
(
|
||||
const fvPatch&,
|
||||
const DimensionedField<Type, volMesh>&
|
||||
);
|
||||
|
||||
//- Construct from patch, internal field and dictionary
|
||||
immersedBoundaryFvPatchField
|
||||
(
|
||||
const fvPatch&,
|
||||
const DimensionedField<Type, volMesh>&,
|
||||
const dictionary&
|
||||
);
|
||||
|
||||
//- Construct by mapping given immersedBoundaryFvPatchField
|
||||
// onto a new patch
|
||||
immersedBoundaryFvPatchField
|
||||
(
|
||||
const immersedBoundaryFvPatchField<Type>&,
|
||||
const fvPatch&,
|
||||
const DimensionedField<Type, volMesh>&,
|
||||
const fvPatchFieldMapper&
|
||||
);
|
||||
|
||||
//- Construct as copy
|
||||
immersedBoundaryFvPatchField
|
||||
(
|
||||
const immersedBoundaryFvPatchField<Type>&
|
||||
);
|
||||
|
||||
//- Construct and return a clone
|
||||
virtual tmp<fvPatchField<Type> > clone() const
|
||||
{
|
||||
return tmp<fvPatchField<Type> >
|
||||
(
|
||||
new immersedBoundaryFvPatchField<Type>(*this)
|
||||
);
|
||||
}
|
||||
|
||||
//- Construct as copy setting internal field reference
|
||||
immersedBoundaryFvPatchField
|
||||
(
|
||||
const immersedBoundaryFvPatchField<Type>&,
|
||||
const DimensionedField<Type, volMesh>&
|
||||
);
|
||||
|
||||
//- Construct and return a clone setting internal field reference
|
||||
virtual tmp<fvPatchField<Type> > clone
|
||||
(
|
||||
const DimensionedField<Type, volMesh>& iF
|
||||
) const
|
||||
{
|
||||
return tmp<fvPatchField<Type> >
|
||||
(
|
||||
new immersedBoundaryFvPatchField<Type>(*this, iF)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
//- Destructor
|
||||
virtual ~immersedBoundaryFvPatchField()
|
||||
{}
|
||||
|
||||
|
||||
// Member functions
|
||||
|
||||
//- Return reference to immersed boundary patch
|
||||
const immersedBoundaryFvPatch& ibPatch() const
|
||||
{
|
||||
return ibPatch_;
|
||||
}
|
||||
|
||||
|
||||
// Return defining fields
|
||||
// Note: defining fields carry values on faces of the IB patch
|
||||
// represented as a triangulated surface
|
||||
|
||||
//- Return access to reference value
|
||||
virtual Field<Type>& refValue()
|
||||
{
|
||||
return refValue_;
|
||||
}
|
||||
|
||||
//- Return reference value
|
||||
virtual const Field<Type>& refValue() const
|
||||
{
|
||||
return refValue_;
|
||||
}
|
||||
|
||||
//- Return access to reference gradient
|
||||
virtual Field<Type>& refGrad()
|
||||
{
|
||||
return refGrad_;
|
||||
}
|
||||
|
||||
//- Return reference gradient
|
||||
virtual const Field<Type>& refGrad() const
|
||||
{
|
||||
return refGrad_;
|
||||
}
|
||||
|
||||
//- Return true if this patch field fixes a value
|
||||
virtual bool fixesValue() const
|
||||
{
|
||||
return fixesValue_;
|
||||
}
|
||||
|
||||
//- Return access to fixes value switch
|
||||
Switch& fixesValue()
|
||||
{
|
||||
return fixesValue_;
|
||||
}
|
||||
|
||||
|
||||
//- Return fields on intersection points interacting with the IB
|
||||
|
||||
//- Return IB field
|
||||
const Field<Type>& ibValue() const;
|
||||
|
||||
//- Return IB surface-normal gradient
|
||||
const Field<Type>& ibGrad() const;
|
||||
|
||||
//- Return IB cell field
|
||||
tmp<Field<Type> > ibCellValue() const;
|
||||
|
||||
//- Return IB sample point field
|
||||
tmp<Field<Type> > ibSamplingPointValue() const;
|
||||
|
||||
|
||||
//- Return fields on triangular faces
|
||||
|
||||
//- Return IB field
|
||||
tmp<Field<Type> > triValue() const;
|
||||
|
||||
//- Return IB surface-normal gradient
|
||||
tmp<Field<Type> > triGrad() const;
|
||||
|
||||
|
||||
// Mapping functions
|
||||
|
||||
//- Map (and resize as needed) from self given a mapping object
|
||||
virtual void autoMap
|
||||
(
|
||||
const fvPatchFieldMapper&
|
||||
)
|
||||
{}
|
||||
|
||||
//- Reverse map the given fvPatchField onto this fvPatchField
|
||||
virtual void rmap
|
||||
(
|
||||
const fvPatchField<Type>&,
|
||||
const labelList&
|
||||
)
|
||||
{}
|
||||
|
||||
|
||||
// Evaluation functions
|
||||
|
||||
//- Update the coefficients associated with the patch field
|
||||
void updateCoeffs();
|
||||
|
||||
//- Initialise the evaluation of the patch field
|
||||
virtual void initEvaluate
|
||||
(
|
||||
const Pstream::commsTypes commsType = Pstream::blocking
|
||||
);
|
||||
|
||||
//- Evaluate the patch field
|
||||
virtual void evaluate
|
||||
(
|
||||
const Pstream::commsTypes commsType = Pstream::blocking
|
||||
);
|
||||
|
||||
//- Return the matrix diagonal coefficients corresponding to the
|
||||
// evaluation of the value of this patchField with given weights
|
||||
virtual tmp<Field<Type> > valueInternalCoeffs
|
||||
(
|
||||
const tmp<scalarField>&
|
||||
) const
|
||||
{
|
||||
return tmp<Field<Type> >(new Field<Type>(0));
|
||||
}
|
||||
|
||||
//- Return the matrix source coefficients corresponding to the
|
||||
// evaluation of the value of this patchField with given weights
|
||||
virtual tmp<Field<Type> > valueBoundaryCoeffs
|
||||
(
|
||||
const tmp<scalarField>&
|
||||
) const
|
||||
{
|
||||
return tmp<Field<Type> >(new Field<Type>(0));
|
||||
}
|
||||
|
||||
//- Return the matrix diagonal coefficients corresponding to the
|
||||
// evaluation of the gradient of this patchField
|
||||
tmp<Field<Type> > gradientInternalCoeffs() const
|
||||
{
|
||||
return tmp<Field<Type> >(new Field<Type>(0));
|
||||
}
|
||||
|
||||
//- Return the matrix source coefficients corresponding to the
|
||||
// evaluation of the gradient of this patchField
|
||||
tmp<Field<Type> > gradientBoundaryCoeffs() const
|
||||
{
|
||||
return tmp<Field<Type> >(new Field<Type>(0));
|
||||
}
|
||||
|
||||
//- Manipulate matrix
|
||||
virtual void manipulateMatrix(fvMatrix<Type>& matrix);
|
||||
|
||||
|
||||
// I-O
|
||||
|
||||
//- Write
|
||||
virtual void write(Ostream&) const;
|
||||
};
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#ifdef NoRepository
|
||||
# include "immersedBoundaryFvPatchField.C"
|
||||
#endif
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
|
@ -0,0 +1,45 @@
|
|||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright held by original author
|
||||
\\/ 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 2 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, write to the Free Software Foundation,
|
||||
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "volFields.H"
|
||||
#include "surfaceFields.H"
|
||||
#include "immersedBoundaryFvPatchFields.H"
|
||||
#include "addToRunTimeSelectionTable.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||
|
||||
makePatchFields(immersedBoundary);
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
// ************************************************************************* //
|
|
@ -0,0 +1,50 @@
|
|||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright held by original author
|
||||
\\/ 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 2 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, write to the Free Software Foundation,
|
||||
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef immersedBoundaryFvPatchFields_H
|
||||
#define immersedBoundaryFvPatchFields_H
|
||||
|
||||
#include "immersedBoundaryFvPatchField.H"
|
||||
#include "fieldTypes.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
makePatchTypeFieldTypedefs(immersedBoundary)
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
|
@ -0,0 +1,52 @@
|
|||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright held by original author
|
||||
\\/ 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 2 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, write to the Free Software Foundation,
|
||||
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef immersedBoundaryFvPatchFieldsFwd_H
|
||||
#define immersedBoundaryFvPatchFieldsFwd_H
|
||||
|
||||
#include "fvPatchField.H"
|
||||
#include "fieldTypes.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
template<class Type> class immersedBoundaryFvPatchField;
|
||||
|
||||
makePatchTypeFieldTypedefs(immersedBoundary)
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
|
@ -0,0 +1,129 @@
|
|||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright held by original author
|
||||
\\/ 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 2 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, write to the Free Software Foundation,
|
||||
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "immersedBoundaryFvsPatchField.H"
|
||||
#include "fvPatchFieldMapper.H"
|
||||
#include "surfaceMesh.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
template<class Type>
|
||||
immersedBoundaryFvsPatchField<Type>::immersedBoundaryFvsPatchField
|
||||
(
|
||||
const fvPatch& p,
|
||||
const DimensionedField<Type, surfaceMesh>& iF
|
||||
)
|
||||
:
|
||||
fvsPatchField<Type>(p, iF),
|
||||
ibPatch_(refCast<const immersedBoundaryFvPatch>(p))
|
||||
{}
|
||||
|
||||
|
||||
template<class Type>
|
||||
immersedBoundaryFvsPatchField<Type>::immersedBoundaryFvsPatchField
|
||||
(
|
||||
const fvPatch& p,
|
||||
const DimensionedField<Type, surfaceMesh>& iF,
|
||||
const dictionary& dict
|
||||
)
|
||||
:
|
||||
fvsPatchField<Type>(p, iF, dict),
|
||||
ibPatch_(refCast<const immersedBoundaryFvPatch>(p))
|
||||
{}
|
||||
|
||||
|
||||
template<class Type>
|
||||
immersedBoundaryFvsPatchField<Type>::immersedBoundaryFvsPatchField
|
||||
(
|
||||
const immersedBoundaryFvsPatchField<Type>& ptf,
|
||||
const fvPatch& p,
|
||||
const DimensionedField<Type, surfaceMesh>& iF,
|
||||
const fvPatchFieldMapper& mapper
|
||||
)
|
||||
:
|
||||
fvsPatchField<Type>(ptf, p, iF, mapper),
|
||||
ibPatch_(refCast<const immersedBoundaryFvPatch>(p))
|
||||
{}
|
||||
|
||||
|
||||
template<class Type>
|
||||
immersedBoundaryFvsPatchField<Type>::immersedBoundaryFvsPatchField
|
||||
(
|
||||
const immersedBoundaryFvsPatchField<Type>& ptf
|
||||
)
|
||||
:
|
||||
fvsPatchField<Type>(ptf),
|
||||
ibPatch_(ptf.ibPatch())
|
||||
{}
|
||||
|
||||
|
||||
template<class Type>
|
||||
immersedBoundaryFvsPatchField<Type>::immersedBoundaryFvsPatchField
|
||||
(
|
||||
const immersedBoundaryFvsPatchField<Type>& ptf,
|
||||
const DimensionedField<Type, surfaceMesh>& iF
|
||||
)
|
||||
:
|
||||
fvsPatchField<Type>(ptf, iF),
|
||||
ibPatch_(ptf.ibPatch())
|
||||
{}
|
||||
|
||||
|
||||
// template<class Type>
|
||||
// void immersedBoundaryFvsPatchField<Type>::operator=
|
||||
// (
|
||||
// const fvPatchField<Type>& ptf
|
||||
// )
|
||||
// {
|
||||
// const immersedBoundaryFvPatchField<Type>& ibf =
|
||||
// refCast<const immersedBoundaryFvPatchField<Type> > (ptf);
|
||||
|
||||
// this->check(ptf);
|
||||
// fvsPatchField<Type>::operator=(ptf);
|
||||
// }
|
||||
|
||||
|
||||
template<class Type>
|
||||
void immersedBoundaryFvsPatchField<Type>::write(Ostream& os) const
|
||||
{
|
||||
fvsPatchField<Type>::write(os);
|
||||
this->writeEntry("value", os);
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
// ************************************************************************* //
|
|
@ -0,0 +1,195 @@
|
|||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright held by original author
|
||||
\\/ 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 2 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, write to the Free Software Foundation,
|
||||
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
Class
|
||||
Foam::immersedBoundaryFvsPatchField
|
||||
|
||||
Description
|
||||
Foam::immersedBoundaryFvsPatchField
|
||||
|
||||
Author
|
||||
Hrvoje Jasak
|
||||
|
||||
SourceFiles
|
||||
immersedBoundaryFvsPatchField.C
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef immersedBoundaryFvsPatchField_H
|
||||
#define immersedBoundaryFvsPatchField_H
|
||||
|
||||
#include "fvsPatchField.H"
|
||||
#include "immersedBoundaryFvPatch.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
// Forward declaration of classes
|
||||
|
||||
template<class Type>
|
||||
class immersedBoundaryFvPatchField;
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class immersedBoundaryFvsPatch Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
template<class Type>
|
||||
class immersedBoundaryFvsPatchField
|
||||
:
|
||||
public fvsPatchField<Type>
|
||||
{
|
||||
// Private data
|
||||
|
||||
//- Local reference cast into the processor patch
|
||||
const immersedBoundaryFvPatch& ibPatch_;
|
||||
|
||||
|
||||
public:
|
||||
|
||||
//- Runtime type information
|
||||
TypeName(immersedBoundaryFvPatch::typeName_());
|
||||
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Construct from patch and internal field
|
||||
immersedBoundaryFvsPatchField
|
||||
(
|
||||
const fvPatch&,
|
||||
const DimensionedField<Type, surfaceMesh>&
|
||||
);
|
||||
|
||||
//- Construct from patch, internal field and dictionary
|
||||
immersedBoundaryFvsPatchField
|
||||
(
|
||||
const fvPatch&,
|
||||
const DimensionedField<Type, surfaceMesh>&,
|
||||
const dictionary&
|
||||
);
|
||||
|
||||
//- Construct by mapping given immersedBoundaryFvsPatchField
|
||||
// onto a new patch
|
||||
immersedBoundaryFvsPatchField
|
||||
(
|
||||
const immersedBoundaryFvsPatchField<Type>&,
|
||||
const fvPatch&,
|
||||
const DimensionedField<Type, surfaceMesh>&,
|
||||
const fvPatchFieldMapper&
|
||||
);
|
||||
|
||||
//- Construct as copy
|
||||
immersedBoundaryFvsPatchField
|
||||
(
|
||||
const immersedBoundaryFvsPatchField<Type>&
|
||||
);
|
||||
|
||||
//- Construct and return a clone
|
||||
virtual tmp<fvsPatchField<Type> > clone() const
|
||||
{
|
||||
return tmp<fvsPatchField<Type> >
|
||||
(
|
||||
new immersedBoundaryFvsPatchField<Type>(*this)
|
||||
);
|
||||
}
|
||||
|
||||
//- Construct as copy setting internal field reference
|
||||
immersedBoundaryFvsPatchField
|
||||
(
|
||||
const immersedBoundaryFvsPatchField<Type>&,
|
||||
const DimensionedField<Type, surfaceMesh>&
|
||||
);
|
||||
|
||||
//- Construct and return a clone setting internal field reference
|
||||
virtual tmp<fvsPatchField<Type> > clone
|
||||
(
|
||||
const DimensionedField<Type, surfaceMesh>& iF
|
||||
) const
|
||||
{
|
||||
return tmp<fvsPatchField<Type> >
|
||||
(
|
||||
new immersedBoundaryFvsPatchField<Type>(*this, iF)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
//- Destructor
|
||||
virtual ~immersedBoundaryFvsPatchField()
|
||||
{}
|
||||
|
||||
|
||||
// Member functions
|
||||
|
||||
// Mapping functions
|
||||
|
||||
//- Map (and resize as needed) from self given a mapping object
|
||||
virtual void autoMap
|
||||
(
|
||||
const fvPatchFieldMapper&
|
||||
)
|
||||
{}
|
||||
|
||||
//- Reverse map the given fvsPatchField onto this fvsPatchField
|
||||
virtual void rmap
|
||||
(
|
||||
const fvPatchField<Type>&,
|
||||
const labelList&
|
||||
)
|
||||
{}
|
||||
|
||||
|
||||
// Member functions
|
||||
|
||||
//- Return reference to immersed boundary patch
|
||||
const immersedBoundaryFvPatch& ibPatch() const
|
||||
{
|
||||
return ibPatch_;
|
||||
}
|
||||
|
||||
//- Write
|
||||
virtual void write(Ostream&) const;
|
||||
|
||||
|
||||
// Member operators
|
||||
|
||||
// virtual void operator=(const fvPatchField<Type>&);
|
||||
};
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#ifdef NoRepository
|
||||
# include "immersedBoundaryFvsPatchField.C"
|
||||
#endif
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
|
@ -0,0 +1,47 @@
|
|||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright held by original author
|
||||
\\/ 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 2 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, write to the Free Software Foundation,
|
||||
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "immersedBoundaryFvsPatchFields.H"
|
||||
#include "fvsPatchFields.H"
|
||||
#include "volFields.H"
|
||||
#include "surfaceFields.H"
|
||||
#include "immersedBoundaryFvPatchFields.H"
|
||||
#include "addToRunTimeSelectionTable.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||
|
||||
makeFvsPatchFields(immersedBoundary);
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
// ************************************************************************* //
|
|
@ -0,0 +1,50 @@
|
|||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright held by original author
|
||||
\\/ 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 2 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, write to the Free Software Foundation,
|
||||
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef immersedBoundaryFvsPatchFields_H
|
||||
#define immersedBoundaryFvsPatchFields_H
|
||||
|
||||
#include "immersedBoundaryFvsPatchField.H"
|
||||
#include "fieldTypes.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
makeFvsPatchTypeFieldTypedefs(immersedBoundary)
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
|
@ -0,0 +1,52 @@
|
|||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright held by original author
|
||||
\\/ 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 2 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, write to the Free Software Foundation,
|
||||
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef immersedBoundaryFvsPatchFieldsFwd_H
|
||||
#define immersedBoundaryFvsPatchFieldsFwd_H
|
||||
|
||||
#include "fvsPatchField.H"
|
||||
#include "fieldTypes.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
template<class Type> class immersedBoundaryFvsPatchField;
|
||||
|
||||
makeFvsPatchTypeFieldTypedefs(immersedBoundary)
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
|
@ -0,0 +1,47 @@
|
|||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright held by original author
|
||||
\\/ 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 2 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, write to the Free Software Foundation,
|
||||
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "immersedBoundaryPointPatch.H"
|
||||
#include "pointConstraint.H"
|
||||
#include "addToRunTimeSelectionTable.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
defineTypeNameAndDebug(immersedBoundaryPointPatch, 0);
|
||||
|
||||
addToRunTimeSelectionTable
|
||||
(
|
||||
facePointPatch,
|
||||
immersedBoundaryPointPatch,
|
||||
polyPatch
|
||||
);
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
// ************************************************************************* //
|
|
@ -0,0 +1,93 @@
|
|||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright held by original author
|
||||
\\/ 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 2 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, write to the Free Software Foundation,
|
||||
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
Class
|
||||
Foam::immersedBoundaryPointPatch
|
||||
|
||||
Description
|
||||
Immersed boundary point patch.
|
||||
|
||||
Author
|
||||
Hrvoje Jasak
|
||||
|
||||
SourceFiles
|
||||
immersedBoundaryPointPatch.C
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef immersedBoundaryPointPatch_H
|
||||
#define immersedBoundaryPointPatch_H
|
||||
|
||||
#include "facePointPatch.H"
|
||||
#include "immersedBoundaryPolyPatch.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class immersedBoundaryPointPatch Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
class immersedBoundaryPointPatch
|
||||
:
|
||||
public facePointPatch
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
//- Runtime type information
|
||||
TypeName(immersedBoundaryPolyPatch::typeName_());
|
||||
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Construct from polyPatch
|
||||
immersedBoundaryPointPatch
|
||||
(
|
||||
const polyPatch& patch,
|
||||
const pointBoundaryMesh& bm
|
||||
)
|
||||
:
|
||||
facePointPatch(patch, bm)
|
||||
{}
|
||||
|
||||
|
||||
// Destructor
|
||||
|
||||
virtual ~immersedBoundaryPointPatch()
|
||||
{}
|
||||
};
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
|
@ -0,0 +1,296 @@
|
|||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright held by original author
|
||||
\\/ 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 2 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, write to the Free Software Foundation,
|
||||
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "immersedBoundaryPolyPatch.H"
|
||||
#include "polyBoundaryMesh.H"
|
||||
#include "polyMesh.H"
|
||||
#include "Time.H"
|
||||
#include "addToRunTimeSelectionTable.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
defineTypeNameAndDebug(immersedBoundaryPolyPatch, 0);
|
||||
|
||||
addToRunTimeSelectionTable(polyPatch, immersedBoundaryPolyPatch, word);
|
||||
addToRunTimeSelectionTable
|
||||
(
|
||||
polyPatch,
|
||||
immersedBoundaryPolyPatch,
|
||||
dictionary
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||
|
||||
void Foam::immersedBoundaryPolyPatch::makeTriSurfSearch() const
|
||||
{
|
||||
if (debug)
|
||||
{
|
||||
Info<< "void immersedBoundaryPolyPatch::makeTriSurfSearch() const : "
|
||||
<< "creating triSurface search algorithm"
|
||||
<< endl;
|
||||
}
|
||||
|
||||
// It is an error to attempt to recalculate
|
||||
// if the pointer is already
|
||||
if (triSurfSearchPtr_)
|
||||
{
|
||||
FatalErrorIn("immersedBoundaryPolyPatch::makeTriSurfSearch() const")
|
||||
<< "triSurface search algorithm already exist"
|
||||
<< abort(FatalError);
|
||||
}
|
||||
|
||||
triSurfSearchPtr_ = new triSurfaceSearch(ibMesh_);
|
||||
}
|
||||
|
||||
|
||||
void Foam::immersedBoundaryPolyPatch::clearOut()
|
||||
{
|
||||
deleteDemandDrivenData(triSurfSearchPtr_);
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
|
||||
|
||||
void Foam::immersedBoundaryPolyPatch::movePoints(const pointField& p)
|
||||
{
|
||||
// Handle motion of immersed boundary
|
||||
clearOut();
|
||||
|
||||
primitivePatch::movePoints(p);
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
Foam::immersedBoundaryPolyPatch::immersedBoundaryPolyPatch
|
||||
(
|
||||
const word& name,
|
||||
const label size,
|
||||
const label start,
|
||||
const label index,
|
||||
const polyBoundaryMesh& bm
|
||||
)
|
||||
:
|
||||
polyPatch(name, size, start, index, bm),
|
||||
ibMesh_
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
name + ".ftr",
|
||||
bm.mesh().time().constant(), // instance
|
||||
"triSurface", // local
|
||||
bm.mesh(), // registry
|
||||
IOobject::MUST_READ,
|
||||
IOobject::NO_WRITE
|
||||
)
|
||||
),
|
||||
internalFlow_(false),
|
||||
triSurfSearchPtr_(NULL),
|
||||
movingIb_(false)
|
||||
{}
|
||||
|
||||
|
||||
Foam::immersedBoundaryPolyPatch::immersedBoundaryPolyPatch
|
||||
(
|
||||
const word& name,
|
||||
const dictionary& dict,
|
||||
const label index,
|
||||
const polyBoundaryMesh& bm
|
||||
)
|
||||
:
|
||||
polyPatch(name, dict, index, bm),
|
||||
ibMesh_
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
name + ".ftr",
|
||||
bm.mesh().time().constant(), // instance
|
||||
"triSurface", // local
|
||||
bm.mesh(), // registry
|
||||
IOobject::MUST_READ,
|
||||
IOobject::NO_WRITE
|
||||
)
|
||||
),
|
||||
internalFlow_(dict.lookup("internalFlow")),
|
||||
triSurfSearchPtr_(NULL),
|
||||
movingIb_(false)
|
||||
{
|
||||
if (size() > 0)
|
||||
{
|
||||
FatalIOErrorIn
|
||||
(
|
||||
"immersedBoundaryPolyPatch::immersedBoundaryPolyPatch\n"
|
||||
"(\n"
|
||||
" const word& name,\n"
|
||||
" const dictionary& dict,\n"
|
||||
" const label index,\n"
|
||||
" const polyBoundaryMesh& bm\n"
|
||||
")",
|
||||
dict
|
||||
) << "Faces detected in the immersedBoundaryPolyPatch. "
|
||||
<< "This is not allowed: please make sure that the patch size "
|
||||
<< "equals zero."
|
||||
<< abort(FatalIOError);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Foam::immersedBoundaryPolyPatch::immersedBoundaryPolyPatch
|
||||
(
|
||||
const immersedBoundaryPolyPatch& pp,
|
||||
const polyBoundaryMesh& bm
|
||||
)
|
||||
:
|
||||
polyPatch(pp, bm),
|
||||
ibMesh_
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
pp.name() + ".ftr",
|
||||
bm.mesh().time().constant(), // instance
|
||||
"triSurface", // local
|
||||
bm.mesh(), // registry
|
||||
IOobject::MUST_READ,
|
||||
IOobject::NO_WRITE
|
||||
)
|
||||
),
|
||||
internalFlow_(pp.internalFlow_),
|
||||
triSurfSearchPtr_(NULL),
|
||||
movingIb_(false)
|
||||
{}
|
||||
|
||||
|
||||
Foam::immersedBoundaryPolyPatch::immersedBoundaryPolyPatch
|
||||
(
|
||||
const immersedBoundaryPolyPatch& pp,
|
||||
const polyBoundaryMesh& bm,
|
||||
const label index,
|
||||
const label newSize,
|
||||
const label newStart
|
||||
)
|
||||
:
|
||||
polyPatch(pp, bm, index, newSize, newStart),
|
||||
ibMesh_
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
pp.name() + ".ftr",
|
||||
bm.mesh().time().constant(), // instance
|
||||
"triSurface", // local
|
||||
bm.mesh(), // registry
|
||||
IOobject::MUST_READ,
|
||||
IOobject::NO_WRITE
|
||||
)
|
||||
),
|
||||
internalFlow_(pp.internalFlow_),
|
||||
triSurfSearchPtr_(NULL),
|
||||
movingIb_(false)
|
||||
{}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * * //
|
||||
|
||||
Foam::immersedBoundaryPolyPatch::~immersedBoundaryPolyPatch()
|
||||
{
|
||||
clearOut();
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
|
||||
|
||||
const Foam::triSurfaceSearch&
|
||||
Foam::immersedBoundaryPolyPatch::triSurfSearch() const
|
||||
{
|
||||
if (!triSurfSearchPtr_)
|
||||
{
|
||||
makeTriSurfSearch();
|
||||
}
|
||||
|
||||
return *triSurfSearchPtr_;
|
||||
}
|
||||
|
||||
|
||||
void Foam::immersedBoundaryPolyPatch::moveTriSurfacePoints
|
||||
(
|
||||
const pointField& p
|
||||
)
|
||||
{
|
||||
// Record the motion of the patch
|
||||
movingIb_ = true;
|
||||
|
||||
// Move points of the triSurface
|
||||
const pointField& oldPoints = ibMesh_.points();
|
||||
|
||||
if (oldPoints.size() != p.size())
|
||||
{
|
||||
FatalErrorIn
|
||||
(
|
||||
"void immersedBoundaryPolyPatch::moveTriSurfacePoints\n"
|
||||
"(\n"
|
||||
" const pointField& p\n"
|
||||
")"
|
||||
) << "Incorrect size of motion points for patch " << name()
|
||||
<< ". oldPoints = "
|
||||
<< oldPoints.size() << " p = " << p.size()
|
||||
<< abort(FatalError);
|
||||
}
|
||||
|
||||
Info<< "Moving immersed boundary points for patch " << name()
|
||||
<< endl;
|
||||
|
||||
ibMesh_.movePoints(p);
|
||||
|
||||
fileName path(boundaryMesh().mesh().time().path()/"VTK");
|
||||
|
||||
mkDir(path);
|
||||
ibMesh_.triSurface::write
|
||||
(
|
||||
path/
|
||||
word
|
||||
(
|
||||
name() + "_"
|
||||
+ Foam::name(boundaryMesh().mesh().time().timeIndex())
|
||||
+ ".stl"
|
||||
)
|
||||
);
|
||||
|
||||
clearOut();
|
||||
}
|
||||
|
||||
|
||||
void Foam::immersedBoundaryPolyPatch::write(Ostream& os) const
|
||||
{
|
||||
polyPatch::write(os);
|
||||
os.writeKeyword("internalFlow") << internalFlow_
|
||||
<< token::END_STATEMENT << nl;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
|
@ -0,0 +1,235 @@
|
|||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright held by original author
|
||||
\\/ 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 2 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, write to the Free Software Foundation,
|
||||
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
Class
|
||||
Foam::immersedBoundaryPolyPatch
|
||||
|
||||
Description
|
||||
Immersed boundary patch
|
||||
|
||||
Author
|
||||
Zeljko Tukovic
|
||||
Reorganisation by Hrvoje Jasak
|
||||
|
||||
SourceFiles
|
||||
immersedBoundaryPolyPatch.C
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef immersedBoundaryPolyPatch_H
|
||||
#define immersedBoundaryPolyPatch_H
|
||||
|
||||
#include "polyPatch.H"
|
||||
#include "triSurfaceMesh.H"
|
||||
#include "triSurfaceTools.H"
|
||||
#include "triSurfaceSearch.H"
|
||||
#include "Switch.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class immersedBoundaryPolyPatch Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
class immersedBoundaryPolyPatch
|
||||
:
|
||||
public polyPatch
|
||||
{
|
||||
// Private data
|
||||
|
||||
//- Triangular surface representing immersed boundary.
|
||||
// Name of tri surface will be identical to the name of the patch
|
||||
triSurfaceMesh ibMesh_;
|
||||
|
||||
//- Internal or external flow calculation
|
||||
Switch internalFlow_;
|
||||
|
||||
|
||||
// Demand-driven data
|
||||
|
||||
//- Triangular surface search algorithm
|
||||
mutable triSurfaceSearch* triSurfSearchPtr_;
|
||||
|
||||
//- Moving immersed boundary
|
||||
bool movingIb_;
|
||||
|
||||
|
||||
// Private Member Functions
|
||||
|
||||
// Storage management
|
||||
|
||||
//- Clear all demand-driven data
|
||||
void clearOut();
|
||||
|
||||
|
||||
// Make demand-driven data
|
||||
|
||||
//- Make triSurface search algorithm
|
||||
void makeTriSurfSearch() const;
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
// Protected Member Functions
|
||||
|
||||
//- Initialise the patches for moving points
|
||||
virtual void initMovePoints(const pointField&)
|
||||
{}
|
||||
|
||||
//- Correct patches after moving points
|
||||
virtual void movePoints(const pointField& p);
|
||||
|
||||
|
||||
public:
|
||||
|
||||
//- Runtime type information
|
||||
TypeName("immersedBoundary");
|
||||
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Construct from components
|
||||
immersedBoundaryPolyPatch
|
||||
(
|
||||
const word& name,
|
||||
const label size,
|
||||
const label start,
|
||||
const label index,
|
||||
const polyBoundaryMesh& bm
|
||||
);
|
||||
|
||||
//- Construct from dictionary
|
||||
immersedBoundaryPolyPatch
|
||||
(
|
||||
const word& name,
|
||||
const dictionary& dict,
|
||||
const label index,
|
||||
const polyBoundaryMesh& bm
|
||||
);
|
||||
|
||||
//- Construct as copy, resetting the boundary mesh
|
||||
immersedBoundaryPolyPatch
|
||||
(
|
||||
const immersedBoundaryPolyPatch&,
|
||||
const polyBoundaryMesh&
|
||||
);
|
||||
|
||||
//- Construct given the original patch and resetting the
|
||||
// face list and boundary mesh information
|
||||
immersedBoundaryPolyPatch
|
||||
(
|
||||
const immersedBoundaryPolyPatch& pp,
|
||||
const polyBoundaryMesh& bm,
|
||||
const label index,
|
||||
const label newSize,
|
||||
const label newStart
|
||||
);
|
||||
|
||||
//- Construct and return a clone, resetting the boundary mesh
|
||||
virtual autoPtr<polyPatch> clone(const polyBoundaryMesh& bm) const
|
||||
{
|
||||
return autoPtr<polyPatch>
|
||||
(
|
||||
new immersedBoundaryPolyPatch(*this, bm)
|
||||
);
|
||||
}
|
||||
|
||||
//- Construct and return a clone, resetting the face list
|
||||
// and boundary mesh
|
||||
virtual autoPtr<polyPatch> clone
|
||||
(
|
||||
const polyBoundaryMesh& bm,
|
||||
const label index,
|
||||
const label newSize,
|
||||
const label newStart
|
||||
) const
|
||||
{
|
||||
return autoPtr<polyPatch>
|
||||
(
|
||||
new immersedBoundaryPolyPatch
|
||||
(
|
||||
*this,
|
||||
bm,
|
||||
index,
|
||||
newSize,
|
||||
newStart
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
//- Destructor
|
||||
virtual ~immersedBoundaryPolyPatch();
|
||||
|
||||
|
||||
// Member Functions
|
||||
|
||||
// Access
|
||||
|
||||
//- Return immersed boundary surface mesh
|
||||
const triSurfaceMesh& ibMesh() const
|
||||
{
|
||||
return ibMesh_;
|
||||
}
|
||||
|
||||
//- Return true if solving for flow inside the immersed boundary
|
||||
bool internalFlow() const
|
||||
{
|
||||
return internalFlow_;
|
||||
}
|
||||
|
||||
//- Return triSurface search object
|
||||
const triSurfaceSearch& triSurfSearch() const;
|
||||
|
||||
//- Return true if immersed boundary is moving
|
||||
bool movingIb() const
|
||||
{
|
||||
return movingIb_;
|
||||
}
|
||||
|
||||
|
||||
// Edit
|
||||
|
||||
//- Correct patches after moving points
|
||||
void moveTriSurfacePoints(const pointField& p);
|
||||
|
||||
|
||||
|
||||
//- Write
|
||||
virtual void write(Ostream&) const;
|
||||
};
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
|
@ -0,0 +1,72 @@
|
|||
//
|
||||
// createIbMask.H
|
||||
// ~~~~~~~~~~~~
|
||||
|
||||
Info<< "Create immersed boundary cell mask" << endl;
|
||||
|
||||
volScalarField cellIbMask
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
"cellIbMask",
|
||||
runTime.timeName(),
|
||||
mesh,
|
||||
IOobject::NO_READ,
|
||||
IOobject::AUTO_WRITE
|
||||
),
|
||||
mesh,
|
||||
dimensionedScalar("one", dimless, 1)
|
||||
);
|
||||
|
||||
volScalarField cellIbMaskExt
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
"cellIbMaskExt",
|
||||
runTime.timeName(),
|
||||
mesh,
|
||||
IOobject::NO_READ,
|
||||
IOobject::AUTO_WRITE
|
||||
),
|
||||
mesh,
|
||||
dimensionedScalar("one", dimless, 1)
|
||||
);
|
||||
|
||||
Info<< "Create immersed boundary face mask" << endl;
|
||||
surfaceScalarField faceIbMask
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
"faceIbMask",
|
||||
runTime.timeName(),
|
||||
mesh,
|
||||
IOobject::NO_READ,
|
||||
IOobject::AUTO_WRITE
|
||||
),
|
||||
mesh,
|
||||
dimensionedScalar("one", dimless, 1)
|
||||
);
|
||||
|
||||
forAll (mesh.boundary(), patchI)
|
||||
{
|
||||
if (isA<immersedBoundaryFvPatch>(mesh.boundary()[patchI]))
|
||||
{
|
||||
Info<< "Found immersed boundary patch " << patchI
|
||||
<< " named " << mesh.boundary()[patchI].name()
|
||||
<< endl;
|
||||
|
||||
const immersedBoundaryFvPatch& ibPatch =
|
||||
refCast<const immersedBoundaryFvPatch>
|
||||
(
|
||||
mesh.boundary()[patchI]
|
||||
);
|
||||
|
||||
cellIbMask *= ibPatch.gamma();
|
||||
cellIbMaskExt *= ibPatch.gammaExt();
|
||||
faceIbMask *= ibPatch.sGamma();
|
||||
}
|
||||
}
|
||||
|
||||
// Evaluate boundary conditions for IB masks
|
||||
cellIbMask.boundaryField().evaluateCoupled();
|
||||
cellIbMaskExt.boundaryField().evaluateCoupled();
|
|
@ -0,0 +1,52 @@
|
|||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright held by original author
|
||||
\\/ 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 2 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, write to the Free Software Foundation,
|
||||
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
Global
|
||||
immersedBoundaryContinuityErrs
|
||||
|
||||
Description
|
||||
Calculates and prints the continuity errors with
|
||||
immersed boundary correction.
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
{
|
||||
volScalarField contErr = fvc::div(faceIbMask*phi);
|
||||
// volScalarField contErr = cellIbMask*fvc::div(phi);
|
||||
|
||||
sumLocalContErr = runTime.deltaT().value()*
|
||||
mag(contErr)().weightedAverage(mesh.V()).value();
|
||||
|
||||
globalContErr = runTime.deltaT().value()*
|
||||
contErr.weightedAverage(mesh.V()).value();
|
||||
|
||||
cumulativeContErr += globalContErr;
|
||||
|
||||
Info<< "IB time step continuity errors : sum local = " << sumLocalContErr
|
||||
<< ", global = " << globalContErr
|
||||
<< ", cumulative = " << cumulativeContErr
|
||||
<< endl;
|
||||
}
|
||||
|
||||
// ************************************************************************* //
|
|
@ -0,0 +1,59 @@
|
|||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright held by original author
|
||||
\\/ 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 2 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, write to the Free Software Foundation,
|
||||
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
Global
|
||||
CourantNo
|
||||
|
||||
Description
|
||||
Calculates and outputs the mean and maximum Courant Numbers with
|
||||
immersed boundary correction.
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
scalar CoNum = 0.0;
|
||||
scalar meanCoNum = 0.0;
|
||||
scalar velMag = 0.0;
|
||||
|
||||
if (mesh.nInternalFaces())
|
||||
{
|
||||
surfaceScalarField magPhi = mag(faceIbMask*phi);
|
||||
|
||||
surfaceScalarField SfUfbyDelta =
|
||||
mesh.surfaceInterpolation::deltaCoeffs()*magPhi;
|
||||
|
||||
CoNum = max(SfUfbyDelta/mesh.magSf())
|
||||
.value()*runTime.deltaT().value();
|
||||
|
||||
meanCoNum = (sum(SfUfbyDelta)/sum(mesh.magSf()))
|
||||
.value()*runTime.deltaT().value();
|
||||
|
||||
velMag = max(magPhi/mesh.magSf()).value();
|
||||
}
|
||||
|
||||
Info<< "Courant Number mean: " << meanCoNum
|
||||
<< " max: " << CoNum
|
||||
<< " velocity magnitude: " << velMag
|
||||
<< endl;
|
||||
|
||||
// ************************************************************************* //
|
|
@ -0,0 +1,475 @@
|
|||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright held by original author
|
||||
\\/ 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 2 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, write to the Free Software Foundation,
|
||||
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "refineImmersedBoundaryMesh.H"
|
||||
#include "immersedBoundaryFvPatch.H"
|
||||
#include "volFields.H"
|
||||
#include "surfaceFields.H"
|
||||
#include "plane.H"
|
||||
#include "wedgePolyPatch.H"
|
||||
#include "multiDirRefinement.H"
|
||||
|
||||
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||
|
||||
template<>
|
||||
const char*
|
||||
Foam::NamedEnum<Foam::refineImmersedBoundaryMesh::ibCellCollection, 4>
|
||||
::names[] =
|
||||
{
|
||||
"undefined",
|
||||
"ibCells",
|
||||
"ibCellCells",
|
||||
"ibCellCellFaces"
|
||||
};
|
||||
|
||||
|
||||
const Foam::NamedEnum<Foam::refineImmersedBoundaryMesh::ibCellCollection, 4>
|
||||
Foam::refineImmersedBoundaryMesh::ibCellCollectionNames_;
|
||||
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||
|
||||
void Foam::refineImmersedBoundaryMesh::addIbCells
|
||||
(
|
||||
labelHashSet& refCellSet
|
||||
) const
|
||||
{
|
||||
Info<< "Adding ibCells for refinement" << endl;
|
||||
|
||||
// Insert immersed boundary cells from all immersed boundary patches
|
||||
forAll (mesh_.boundary(), patchI)
|
||||
{
|
||||
if (isA<immersedBoundaryFvPatch>(mesh_.boundary()[patchI]))
|
||||
{
|
||||
Info<< "Found immersed boundary patch " << patchI
|
||||
<< " named " << mesh_.boundary()[patchI].name()
|
||||
<< endl;
|
||||
|
||||
const immersedBoundaryFvPatch& ibPatch =
|
||||
refCast<const immersedBoundaryFvPatch>
|
||||
(
|
||||
mesh_.boundary()[patchI]
|
||||
);
|
||||
|
||||
const labelList& c = ibPatch.ibCells();
|
||||
|
||||
forAll (c, cI)
|
||||
{
|
||||
if (!refCellSet.found(c[cI]))
|
||||
{
|
||||
refCellSet.insert(c[cI]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Foam::refineImmersedBoundaryMesh::addIbCellCells
|
||||
(
|
||||
labelHashSet& refCellSet
|
||||
) const
|
||||
{
|
||||
Info<< "Adding ibCellCells for refinement" << endl;
|
||||
|
||||
// Insert immersed boundary cells from all immersed boundary patches
|
||||
forAll (mesh_.boundary(), patchI)
|
||||
{
|
||||
if (isA<immersedBoundaryFvPatch>(mesh_.boundary()[patchI]))
|
||||
{
|
||||
const immersedBoundaryFvPatch& ibPatch =
|
||||
refCast<const immersedBoundaryFvPatch>
|
||||
(
|
||||
mesh_.boundary()[patchI]
|
||||
);
|
||||
|
||||
const labelListList& cc = ibPatch.ibCellCells();
|
||||
|
||||
forAll (cc, cellI)
|
||||
{
|
||||
const labelList& curCells = cc[cellI];
|
||||
|
||||
forAll (curCells, cI)
|
||||
{
|
||||
if (!refCellSet.found(curCells[cI]))
|
||||
{
|
||||
refCellSet.insert(curCells[cI]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Foam::refineImmersedBoundaryMesh::addIbCellCellFaces
|
||||
(
|
||||
labelHashSet& refCellSet
|
||||
) const
|
||||
{
|
||||
Info<< "Adding ibCellCellFaces for refinement" << endl;
|
||||
|
||||
const unallocLabelList& owner = mesh_.owner();
|
||||
const unallocLabelList& neighbour = mesh_.neighbour();
|
||||
|
||||
// Insert immersed boundary cells from all immersed boundary patches
|
||||
forAll (mesh_.boundary(), patchI)
|
||||
{
|
||||
if (isA<immersedBoundaryFvPatch>(mesh_.boundary()[patchI]))
|
||||
{
|
||||
const immersedBoundaryFvPatch& ibPatch =
|
||||
refCast<const immersedBoundaryFvPatch>
|
||||
(
|
||||
mesh_.boundary()[patchI]
|
||||
);
|
||||
|
||||
const scalarField& gammaExtI = ibPatch.gammaExt().internalField();
|
||||
|
||||
const labelList& ibInsideFaces = ibPatch.ibInsideFaces();
|
||||
|
||||
forAll (ibInsideFaces, faceI)
|
||||
{
|
||||
const label ownCell = owner[ibInsideFaces[faceI]];
|
||||
const label ngbCell = neighbour[ibInsideFaces[faceI]];
|
||||
|
||||
if (gammaExtI[ownCell] < SMALL)
|
||||
{
|
||||
if (!refCellSet.found(ownCell))
|
||||
{
|
||||
refCellSet.insert(ownCell);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!refCellSet.found(ngbCell))
|
||||
{
|
||||
refCellSet.insert(ngbCell);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Return index of coordinate axis.
|
||||
Foam::label Foam::refineImmersedBoundaryMesh::axis(const vector& normal) const
|
||||
{
|
||||
const scalar edgeTol = 1e-3;
|
||||
|
||||
label axisIndex = -1;
|
||||
|
||||
if (mag(normal & vector(1, 0, 0)) > (1 - edgeTol))
|
||||
{
|
||||
axisIndex = 0;
|
||||
}
|
||||
else if (mag(normal & vector(0, 1, 0)) > (1 - edgeTol))
|
||||
{
|
||||
axisIndex = 1;
|
||||
}
|
||||
else if (mag(normal & vector(0, 0, 1)) > (1 - edgeTol))
|
||||
{
|
||||
axisIndex = 2;
|
||||
}
|
||||
|
||||
return axisIndex;
|
||||
}
|
||||
|
||||
|
||||
//- Returns -1 or cartesian coordinate component (0=x, 1=y, 2=z) of normal
|
||||
// in case of 2D mesh
|
||||
Foam::label Foam::refineImmersedBoundaryMesh::twoDNess() const
|
||||
{
|
||||
const pointField& ctrs = mesh_.cellCentres();
|
||||
|
||||
if (ctrs.size() < 2)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
//
|
||||
// 1. All cell centres on single plane aligned with x, y or z
|
||||
//
|
||||
|
||||
// Determine 3 points to base plane on.
|
||||
vector vec10 = ctrs[1] - ctrs[0];
|
||||
vec10 /= mag(vec10);
|
||||
|
||||
label otherCellI = -1;
|
||||
|
||||
for (label cellI = 2; cellI < ctrs.size(); cellI++)
|
||||
{
|
||||
vector vec(ctrs[cellI] - ctrs[0]);
|
||||
vec /= mag(vec);
|
||||
|
||||
if (mag(vec & vec10) < 0.9)
|
||||
{
|
||||
// ctrs[cellI] not in line with n
|
||||
otherCellI = cellI;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (otherCellI == -1)
|
||||
{
|
||||
// Cannot find cell to make decent angle with cell0-cell1 vector.
|
||||
// Note: what to do here? All cells (almost) in one line.
|
||||
// Maybe 1D case?
|
||||
return -1;
|
||||
}
|
||||
|
||||
plane cellPlane(ctrs[0], ctrs[1], ctrs[otherCellI]);
|
||||
|
||||
|
||||
forAll (ctrs, cellI)
|
||||
{
|
||||
const labelList& cEdges = mesh_.cellEdges()[cellI];
|
||||
|
||||
scalar minLen = GREAT;
|
||||
|
||||
forAll (cEdges, i)
|
||||
{
|
||||
minLen = min(minLen, mesh_.edges()[cEdges[i]].mag(mesh_.points()));
|
||||
}
|
||||
|
||||
if (cellPlane.distance(ctrs[cellI]) > 1e-6*minLen)
|
||||
{
|
||||
// Centres not in plane
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
label axisIndex = axis(cellPlane.normal());
|
||||
|
||||
if (axisIndex == -1)
|
||||
{
|
||||
return axisIndex;
|
||||
}
|
||||
|
||||
|
||||
const polyBoundaryMesh& patches = mesh_.boundaryMesh();
|
||||
|
||||
|
||||
//
|
||||
// 2. No edges without points on boundary
|
||||
//
|
||||
|
||||
// Mark boundary points
|
||||
boolList boundaryPoint(mesh_.allPoints().size(), false);
|
||||
|
||||
forAll (patches, patchI)
|
||||
{
|
||||
const polyPatch& patch = patches[patchI];
|
||||
|
||||
forAll (patch, patchFaceI)
|
||||
{
|
||||
const face& f = patch[patchFaceI];
|
||||
|
||||
forAll (f, fp)
|
||||
{
|
||||
boundaryPoint[f[fp]] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const edgeList& edges = mesh_.edges();
|
||||
|
||||
forAll (edges, edgeI)
|
||||
{
|
||||
const edge& e = edges[edgeI];
|
||||
|
||||
if (!boundaryPoint[e.start()] && !boundaryPoint[e.end()])
|
||||
{
|
||||
// Edge has no point on boundary.
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 3. For all non-wedge patches: all faces either perp or aligned with
|
||||
// cell-plane normal. (wedge patches already checked upon construction)
|
||||
|
||||
forAll (patches, patchI)
|
||||
{
|
||||
const polyPatch& patch = patches[patchI];
|
||||
|
||||
if (!isA<wedgePolyPatch>(patch))
|
||||
{
|
||||
const vectorField& n = patch.faceAreas();
|
||||
|
||||
scalarField cosAngle = mag(n/mag(n) & cellPlane.normal());
|
||||
|
||||
if (mag(min(cosAngle) - max(cosAngle)) > 1e-6)
|
||||
{
|
||||
// cosAngle should be either ~1 over all faces (2D front and
|
||||
// back) or ~0 (all other patches perp to 2D)
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return axisIndex;
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
Foam::refineImmersedBoundaryMesh::refineImmersedBoundaryMesh
|
||||
(
|
||||
fvMesh& mesh
|
||||
)
|
||||
:
|
||||
mesh_(mesh)
|
||||
{}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
|
||||
|
||||
Foam::refineImmersedBoundaryMesh::~refineImmersedBoundaryMesh()
|
||||
{}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
|
||||
|
||||
Foam::labelList
|
||||
Foam::refineImmersedBoundaryMesh::refinementCells
|
||||
(
|
||||
const ibCellCollection& collectionType
|
||||
) const
|
||||
{
|
||||
labelHashSet refCellSet;
|
||||
|
||||
switch (collectionType)
|
||||
{
|
||||
// Note: fall-through is intentional. HJ, 25/Oct/2012
|
||||
case IB_CELL_CELL_FACES:
|
||||
{
|
||||
addIbCellCellFaces(refCellSet);
|
||||
}
|
||||
|
||||
case IB_CELL_CELLS:
|
||||
{
|
||||
addIbCellCells(refCellSet);
|
||||
}
|
||||
|
||||
case IB_CELLS:
|
||||
{
|
||||
addIbCells(refCellSet);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
{
|
||||
FatalErrorIn
|
||||
(
|
||||
"labelList refineImmersedBoundaryMesh::refinementCells\n"
|
||||
"(\n"
|
||||
" const ibCellCollection& collectionType\n"
|
||||
") const"
|
||||
) << "Collection type undefined: "
|
||||
<< ibCellCollectionNames_[collectionType]
|
||||
<< abort(FatalError);
|
||||
}
|
||||
}
|
||||
|
||||
return refCellSet.toc();
|
||||
}
|
||||
|
||||
|
||||
void Foam::refineImmersedBoundaryMesh::refineMesh
|
||||
(
|
||||
const labelList& refCells
|
||||
) const
|
||||
{
|
||||
Info << "nRefCells = " << refCells.size() << "\n" << endl;
|
||||
|
||||
// Dictionary to control refinement
|
||||
dictionary refineDict;
|
||||
|
||||
// Set refinement directions based on 2D/3D
|
||||
label axisIndex = twoDNess();
|
||||
|
||||
if (axisIndex == -1)
|
||||
{
|
||||
Info<< "3D case; refining all directions" << nl << endl;
|
||||
|
||||
wordList directions(3);
|
||||
directions[0] = "tan1";
|
||||
directions[1] = "tan2";
|
||||
directions[2] = "normal";
|
||||
refineDict.add("directions", directions);
|
||||
|
||||
// Use hex cutter
|
||||
refineDict.add("useHexTopology", "true");
|
||||
}
|
||||
else
|
||||
{
|
||||
wordList directions(2);
|
||||
|
||||
if (axisIndex == 0)
|
||||
{
|
||||
Info<< "2D case; refining in directions y,z\n" << endl;
|
||||
directions[0] = "tan2";
|
||||
directions[1] = "normal";
|
||||
}
|
||||
else if (axisIndex == 1)
|
||||
{
|
||||
Info<< "2D case; refining in directions x,z\n" << endl;
|
||||
directions[0] = "tan1";
|
||||
directions[1] = "normal";
|
||||
}
|
||||
else
|
||||
{
|
||||
Info<< "2D case; refining in directions x,y\n" << endl;
|
||||
directions[0] = "tan1";
|
||||
directions[1] = "tan2";
|
||||
}
|
||||
|
||||
refineDict.add("directions", directions);
|
||||
|
||||
// Use standard cutter
|
||||
refineDict.add("useHexTopology", "false");
|
||||
}
|
||||
|
||||
refineDict.add("coordinateSystem", "global");
|
||||
|
||||
dictionary coeffsDict;
|
||||
coeffsDict.add("tan1", vector(1, 0, 0));
|
||||
coeffsDict.add("tan2", vector(0, 1, 0));
|
||||
refineDict.add("globalCoeffs", coeffsDict);
|
||||
|
||||
refineDict.add("geometricCut", "false");
|
||||
refineDict.add("writeMesh", "false");
|
||||
|
||||
// Multi-directional refinement (does multiple iterations)
|
||||
multiDirRefinement multiRef(mesh_, refCells, refineDict);
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
|
@ -0,0 +1,139 @@
|
|||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright held by original author
|
||||
\\/ 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 2 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, write to the Free Software Foundation,
|
||||
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
Class
|
||||
Foam::refineImmersedBoundaryMesh
|
||||
|
||||
Description
|
||||
Refine a mesh with immersed boundary
|
||||
|
||||
SourceFiles
|
||||
refineImmersedBoundaryMesh.C
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef refineImmersedBoundaryMesh_H
|
||||
#define refineImmersedBoundaryMesh_H
|
||||
|
||||
#include "fvMesh.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class refineImmersedBoundaryMesh Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
class refineImmersedBoundaryMesh
|
||||
{
|
||||
public:
|
||||
|
||||
// Public enumerations
|
||||
|
||||
//- Cell collection method
|
||||
enum ibCellCollection
|
||||
{
|
||||
UNDEFINED_COLLECTION = 0,
|
||||
IB_CELLS,
|
||||
IB_CELL_CELLS,
|
||||
IB_CELL_CELL_FACES
|
||||
};
|
||||
|
||||
//- Projection method names
|
||||
static const NamedEnum<ibCellCollection, 4> ibCellCollectionNames_;
|
||||
|
||||
|
||||
private:
|
||||
|
||||
// Private data
|
||||
|
||||
//- Reference to mesh
|
||||
fvMesh& mesh_;
|
||||
|
||||
|
||||
// Private Member Functions
|
||||
|
||||
//- Disallow default bitwise copy construct
|
||||
refineImmersedBoundaryMesh(const refineImmersedBoundaryMesh&);
|
||||
|
||||
//- Disallow default bitwise assignment
|
||||
void operator=(const refineImmersedBoundaryMesh&);
|
||||
|
||||
|
||||
// Mesh refinement
|
||||
|
||||
//- Add ibCells for refinement
|
||||
void addIbCells(labelHashSet& refCellSet) const;
|
||||
|
||||
//- Add ibCellCells for refinement
|
||||
void addIbCellCells(labelHashSet& refCellSet) const;
|
||||
|
||||
//- Add ibCellCellFaces for refinement
|
||||
void addIbCellCellFaces(labelHashSet& refCellSet) const;
|
||||
|
||||
|
||||
//- From refineMesh application
|
||||
label axis(const vector& normal) const;
|
||||
|
||||
//- From refineMesh application
|
||||
label twoDNess() const;
|
||||
|
||||
|
||||
public:
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Construct from mesh
|
||||
refineImmersedBoundaryMesh(fvMesh& mesh);
|
||||
|
||||
|
||||
//- Destructor
|
||||
~refineImmersedBoundaryMesh();
|
||||
|
||||
|
||||
// Member Functions
|
||||
|
||||
//- Return list of cells for refinement based on specifie collection
|
||||
// type (see enumeration)
|
||||
labelList refinementCells
|
||||
(
|
||||
const ibCellCollection& collectionType
|
||||
) const;
|
||||
|
||||
// Refine mesh given a list of cells for refinement
|
||||
void refineMesh(const labelList& refCells) const;
|
||||
};
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
|
@ -0,0 +1,50 @@
|
|||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright held by original author
|
||||
\\/ 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 2 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, write to the Free Software Foundation,
|
||||
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
Typedef
|
||||
Foam::IOimmersedBoundaryForces
|
||||
|
||||
Description
|
||||
Instance of the generic IOOutputFilter for immersedBoundaryForces.
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef IOimmersedBoundaryForces_H
|
||||
#define IOimmersedBoundaryForces_H
|
||||
|
||||
#include "immersedBoundaryForces.H"
|
||||
#include "IOOutputFilter.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
typedef IOOutputFilter<immersedBoundaryForces> IOimmersedBoundaryForces;
|
||||
}
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
4
src/immersedBoundary/immersedBoundaryForce/Make/files
Normal file
4
src/immersedBoundary/immersedBoundaryForce/Make/files
Normal file
|
@ -0,0 +1,4 @@
|
|||
immersedBoundaryForces.C
|
||||
immersedBoundaryForcesFunctionObject.C
|
||||
|
||||
LIB = $(FOAM_LIBBIN)/libimmersedBoundaryForceFunctionObject
|
28
src/immersedBoundary/immersedBoundaryForce/Make/options
Normal file
28
src/immersedBoundary/immersedBoundaryForce/Make/options
Normal file
|
@ -0,0 +1,28 @@
|
|||
EXE_INC = \
|
||||
-I$(LIB_SRC)/finiteVolume/lnInclude \
|
||||
-I$(LIB_SRC)/postProcessing/functionObjects/forces/lnInclude \
|
||||
-I$(LIB_SRC)/surfMesh/lnInclude \
|
||||
-I$(LIB_SRC)/triSurface/lnInclude \
|
||||
-I$(LIB_SRC)/meshTools/lnInclude \
|
||||
-I$(LIB_SRC)/sampling/lnInclude \
|
||||
-I../immersedBoundary/lnInclude \
|
||||
-I../immersedBoundaryTurbulence/lnInclude
|
||||
|
||||
LIB_LIBS = \
|
||||
-lforces \
|
||||
-lincompressibleTransportModels \
|
||||
-lincompressibleRASModels \
|
||||
-lincompressibleLESModels \
|
||||
-lbasicThermophysicalModels \
|
||||
-lspecie \
|
||||
-lcompressibleRASModels \
|
||||
-lcompressibleLESModels \
|
||||
-lfiniteVolume \
|
||||
-ltriSurface \
|
||||
-lmeshTools \
|
||||
-lsurfMesh \
|
||||
-lsampling \
|
||||
-ldynamicMesh \
|
||||
-L$(FOAM_USER_LIBBIN) \
|
||||
-limmersedBoundary \
|
||||
-limmersedBoundaryTurbulence
|
|
@ -0,0 +1,249 @@
|
|||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright held by original author
|
||||
\\/ 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 2 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, write to the Free Software Foundation,
|
||||
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "immersedBoundaryForces.H"
|
||||
#include "immersedBoundaryFvPatch.H"
|
||||
#include "immersedBoundaryFvPatchFields.H"
|
||||
#include "immersedBoundaryVelocityWallFunctionFvPatchVectorField.H"
|
||||
#include "volFields.H"
|
||||
#include "surfaceFields.H"
|
||||
#include "dictionary.H"
|
||||
#include "Time.H"
|
||||
|
||||
using namespace Foam::incompressible::RASModels;
|
||||
|
||||
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
defineTypeNameAndDebug(immersedBoundaryForces, 0);
|
||||
}
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
Foam::immersedBoundaryForces::immersedBoundaryForces
|
||||
(
|
||||
const word& name,
|
||||
const objectRegistry& obr,
|
||||
const dictionary& dict,
|
||||
const bool loadFromFiles
|
||||
)
|
||||
:
|
||||
forces
|
||||
(
|
||||
name,
|
||||
obr,
|
||||
dict,
|
||||
loadFromFiles
|
||||
)
|
||||
{}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
|
||||
|
||||
Foam::immersedBoundaryForces::~immersedBoundaryForces()
|
||||
{}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
Foam::immersedBoundaryForces::forcesMoments
|
||||
Foam::immersedBoundaryForces::calcForcesMoment() const
|
||||
{
|
||||
forcesMoments fm
|
||||
(
|
||||
pressureViscous(vector::zero, vector::zero),
|
||||
pressureViscous(vector::zero, vector::zero)
|
||||
);
|
||||
|
||||
if (directForceDensity_)
|
||||
{
|
||||
const volVectorField& fD = obr_.lookupObject<volVectorField>(fDName_);
|
||||
|
||||
const fvMesh& mesh = fD.mesh();
|
||||
|
||||
forAllConstIter(labelHashSet, patchSet_, iter)
|
||||
{
|
||||
label patchI = iter.key();
|
||||
|
||||
// Check and cast into immersed boundary type
|
||||
if
|
||||
(
|
||||
isA<immersedBoundaryFvPatchVectorField>
|
||||
(
|
||||
fD.boundaryField()[patchI]
|
||||
)
|
||||
)
|
||||
{
|
||||
// Found immersed boundary patch and field.
|
||||
// Cast into immersed boundary type
|
||||
const immersedBoundaryFvPatch& ibPatch =
|
||||
refCast<const immersedBoundaryFvPatch>
|
||||
(
|
||||
mesh.boundary()[patchI]
|
||||
);
|
||||
|
||||
const immersedBoundaryFvPatchVectorField& fDpatch =
|
||||
refCast<const immersedBoundaryFvPatchVectorField>
|
||||
(
|
||||
fD.boundaryField()[patchI]
|
||||
);
|
||||
|
||||
// Get face area vectors for triangles
|
||||
const vectorField& Sfb = ibPatch.triSf();
|
||||
scalarField sA = mag(Sfb);
|
||||
|
||||
// Calculate distance for triangles
|
||||
vectorField Md = ibPatch.triCf() - CofR_;
|
||||
|
||||
// Old treatment:
|
||||
// Normal force =
|
||||
// surfaceNormal*(surfaceUnitNormal & forceDensity)
|
||||
// The first operation will be done on ibPoints, the data will
|
||||
// then be distributed onto the ib surface
|
||||
// for surface integration
|
||||
// vectorField fN =
|
||||
// Sfb*
|
||||
// ibPatch.toTriFaces
|
||||
// (
|
||||
// ibPatch.ibNormals() & fDpatch.ibValue()
|
||||
// );
|
||||
|
||||
// New treatment: normal force calculated on triangles
|
||||
// Damir Rigler, 30/Apr/2014
|
||||
vectorField fN = Sfb/sA*(Sfb & fDpatch.triValue());
|
||||
|
||||
fm.first().first() += sum(fN);
|
||||
fm.second().first() += sum(Md ^ fN);
|
||||
|
||||
// Tangential force (total force minus normal fN)
|
||||
vectorField fT = sA*fDpatch.triValue() - fN;
|
||||
|
||||
fm.first().second() += sum(fT);
|
||||
fm.second().second() += sum(Md ^ fT);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
const volVectorField& U = obr_.lookupObject<volVectorField>(UName_);
|
||||
const volScalarField& p = obr_.lookupObject<volScalarField>(pName_);
|
||||
|
||||
const fvMesh& mesh = U.mesh();
|
||||
|
||||
// Stress from turbulence model. Note: this does not account
|
||||
// for wall functions on the Immersed Boundary: use wallShearStress
|
||||
// from Immersed Boundary U wall patch instead.
|
||||
// HJ, 11/Aug/2014
|
||||
// volSymmTensorField stress = devRhoReff();
|
||||
|
||||
// Scale pRef by density for incompressible simulations
|
||||
scalar pRef = pRef_/rho(p);
|
||||
|
||||
forAllConstIter(labelHashSet, patchSet_, iter)
|
||||
{
|
||||
label patchI = iter.key();
|
||||
|
||||
// Check and cast into immersed boundary type
|
||||
if
|
||||
(
|
||||
isA<immersedBoundaryFvPatchVectorField>
|
||||
(
|
||||
U.boundaryField()[patchI]
|
||||
)
|
||||
)
|
||||
{
|
||||
// Found immersed boundary patch and field.
|
||||
// Cast into immersed boundary type
|
||||
const immersedBoundaryFvPatch& ibPatch =
|
||||
refCast<const immersedBoundaryFvPatch>
|
||||
(
|
||||
mesh.boundary()[patchI]
|
||||
);
|
||||
|
||||
// Get immersed boundary velocity. Used to access wall
|
||||
// shear stress
|
||||
const immersedBoundaryVelocityWallFunctionFvPatchVectorField&
|
||||
UPatch =
|
||||
refCast
|
||||
<
|
||||
const
|
||||
immersedBoundaryVelocityWallFunctionFvPatchVectorField
|
||||
>
|
||||
(
|
||||
U.boundaryField()[patchI]
|
||||
);
|
||||
|
||||
// const immersedBoundaryFvPatchSymmTensorField stressPatch =
|
||||
// refCast<const immersedBoundaryFvPatchSymmTensorField>
|
||||
// (
|
||||
// stress.boundaryField()[patchI]
|
||||
// );
|
||||
|
||||
const immersedBoundaryFvPatchScalarField pPatch =
|
||||
refCast<const immersedBoundaryFvPatchScalarField>
|
||||
(
|
||||
p.boundaryField()[patchI]
|
||||
);
|
||||
|
||||
// Get face area vectors for triangles
|
||||
const vectorField& Sfb = ibPatch.triSf();
|
||||
scalarField sA = mag(Sfb);
|
||||
|
||||
// Calculate distance for triangles
|
||||
vectorField Md = ibPatch.triCf() - CofR_;
|
||||
|
||||
// Pressure force is an integral of interpolated pressure
|
||||
// on triangular faces
|
||||
vectorField pf = Sfb*(pPatch.triValue() - pRef);
|
||||
|
||||
fm.first().first() += rho(p)*sum(pf);
|
||||
fm.second().first() += rho(p)*sum(Md ^ pf);
|
||||
|
||||
// Old treatment:
|
||||
// Shear force is obtained from velocity wall functions
|
||||
// and integrated on triangular faces
|
||||
vectorField vf =
|
||||
sA*ibPatch.toTriFaces(UPatch.wallShearStress());
|
||||
|
||||
// New treatment: normal force calculated on triangles
|
||||
// Damir Rigler, 30/Apr/2014
|
||||
// vectorField vfOld = (Sfb & stressPatch.triValue());
|
||||
// Info<< "Force difference " << sumMag(vf - vfOld) << endl;
|
||||
|
||||
fm.first().second() += sum(vf);
|
||||
fm.second().second() += sum(Md ^ vf);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
reduce(fm, sumOp());
|
||||
|
||||
return fm;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
|
@ -0,0 +1,107 @@
|
|||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright held by original author
|
||||
\\/ 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 2 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, write to the Free Software Foundation,
|
||||
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
Class
|
||||
Foam::immersedBoundaryForces
|
||||
|
||||
Description
|
||||
Calculates the forces and moments by integrating the pressure and
|
||||
skin-friction forces over a given list of immersed boundary patches.
|
||||
|
||||
Member function calcForcesMoment() calculates and returns the forces and
|
||||
moments on immersed boundary patches.
|
||||
|
||||
Author
|
||||
Hrvoje Jasak. All rights reserved.
|
||||
|
||||
SourceFiles
|
||||
immersedBoundaryForces.C
|
||||
IOimmersedBoundaryForces.H
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef immersedBoundaryForces_H
|
||||
#define immersedBoundaryForces_H
|
||||
|
||||
#include "forces.H"
|
||||
#include "fvPatchFields.H"
|
||||
#include "volFieldsFwd.H"
|
||||
#include "HashSet.H"
|
||||
#include "Tuple2.H"
|
||||
#include "OFstream.H"
|
||||
#include "Switch.H"
|
||||
#include "pointFieldFwd.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class immersedBoundaryForces Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
class immersedBoundaryForces
|
||||
:
|
||||
public forces
|
||||
{
|
||||
public:
|
||||
|
||||
//- Runtime type information
|
||||
TypeName("immersedBoundaryForces");
|
||||
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Construct for given objectRegistry and dictionary.
|
||||
// Allow the possibility to load fields from files
|
||||
immersedBoundaryForces
|
||||
(
|
||||
const word& name,
|
||||
const objectRegistry&,
|
||||
const dictionary&,
|
||||
const bool loadFromFiles = false
|
||||
);
|
||||
|
||||
|
||||
//- Destructor
|
||||
virtual ~immersedBoundaryForces();
|
||||
|
||||
|
||||
// Member Functions
|
||||
|
||||
//- Calculate and return forces and moment
|
||||
virtual forcesMoments calcForcesMoment() const;
|
||||
};
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
|
@ -0,0 +1,47 @@
|
|||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright held by original author
|
||||
\\/ 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 2 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, write to the Free Software Foundation,
|
||||
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "immersedBoundaryForcesFunctionObject.H"
|
||||
|
||||
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
defineNamedTemplateTypeNameAndDebug
|
||||
(
|
||||
immersedBoundaryForcesFunctionObject,
|
||||
0
|
||||
);
|
||||
|
||||
addToRunTimeSelectionTable
|
||||
(
|
||||
functionObject,
|
||||
immersedBoundaryForcesFunctionObject,
|
||||
dictionary
|
||||
);
|
||||
}
|
||||
|
||||
// ************************************************************************* //
|
|
@ -0,0 +1,55 @@
|
|||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright held by original author
|
||||
\\/ 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 2 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, write to the Free Software Foundation,
|
||||
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
Typedef
|
||||
Foam::immersedBoundaryForcesFunctionObject
|
||||
|
||||
Description
|
||||
FunctionObject wrapper around immersedBoundaryForces to allow them to be
|
||||
created via the functions entry within controlDict.
|
||||
|
||||
SourceFiles
|
||||
immersedBoundaryForcesFunctionObject.C
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef immersedBoundaryForcesFunctionObject_H
|
||||
#define immersedBoundaryForcesFunctionObject_H
|
||||
|
||||
#include "immersedBoundaryForces.H"
|
||||
#include "OutputFilterFunctionObject.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
typedef OutputFilterFunctionObject<immersedBoundaryForces>
|
||||
immersedBoundaryForcesFunctionObject;
|
||||
}
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
|
@ -0,0 +1,6 @@
|
|||
wallFunctions/immersedBoundaryWallFunctions/immersedBoundaryWallFunctionFvPatchFields.C
|
||||
wallFunctions/immersedBoundaryEpsilonWallFunctions/immersedBoundaryEpsilonWallFunctionFvPatchScalarField.C
|
||||
wallFunctions/immersedBoundaryOmegaWallFunctions/immersedBoundaryOmegaWallFunctionFvPatchScalarField.C
|
||||
wallFunctions/immersedBoundaryVelocityWallFunctions/immersedBoundaryVelocityWallFunctionFvPatchVectorField.C
|
||||
|
||||
LIB = $(FOAM_LIBBIN)/libimmersedBoundaryTurbulence
|
26
src/immersedBoundary/immersedBoundaryTurbulence/Make/options
Normal file
26
src/immersedBoundary/immersedBoundaryTurbulence/Make/options
Normal file
|
@ -0,0 +1,26 @@
|
|||
EXE_INC = \
|
||||
-IlnInclude \
|
||||
-I../immersedBoundary/lnInclude \
|
||||
-I$(LIB_SRC)/finiteVolume/lnInclude \
|
||||
-I$(LIB_SRC)/turbulenceModels \
|
||||
-I$(LIB_SRC)/turbulenceModels/incompressible/RAS/RASModel \
|
||||
-I$(LIB_SRC)/transportModels \
|
||||
-I$(LIB_SRC)/transportModels/incompressible/singlePhaseTransportModel \
|
||||
-I$(LIB_SRC)/triSurface/lnInclude \
|
||||
-I$(LIB_SRC)/meshTools/lnInclude \
|
||||
-I$(LIB_SRC)/surfMesh/lnInclude \
|
||||
-I$(LIB_SRC)/sampling/lnInclude \
|
||||
-I$(LIB_SRC)/dynamicMesh/dynamicMesh/lnInclude
|
||||
|
||||
EXE_LIBS = \
|
||||
-limmersedBoundary \
|
||||
-lfiniteVolume \
|
||||
-lincompressibleTurbulenceModel \
|
||||
-lincompressibleRASModels \
|
||||
-lincompressibleLESModels \
|
||||
-lincompressibleTransportModels \
|
||||
-ltriSurface \
|
||||
-lmeshTools \
|
||||
-lsurfMesh \
|
||||
-lsampling \
|
||||
-ldynamicMesh
|
|
@ -0,0 +1,394 @@
|
|||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright held by original author
|
||||
\\/ 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 2 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, write to the Free Software Foundation,
|
||||
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "immersedBoundaryEpsilonWallFunctionFvPatchScalarField.H"
|
||||
#include "immersedBoundaryVelocityWallFunctionFvPatchVectorField.H"
|
||||
#include "RASModel.H"
|
||||
#include "fvPatchFieldMapper.H"
|
||||
#include "volFields.H"
|
||||
#include "addToRunTimeSelectionTable.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
namespace incompressible
|
||||
{
|
||||
namespace RASModels
|
||||
{
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
immersedBoundaryEpsilonWallFunctionFvPatchScalarField::
|
||||
immersedBoundaryEpsilonWallFunctionFvPatchScalarField
|
||||
(
|
||||
const fvPatch& p,
|
||||
const DimensionedField<scalar, volMesh>& iF
|
||||
)
|
||||
:
|
||||
immersedBoundaryWallFunctionFvPatchScalarField(p, iF),
|
||||
UName_("U"),
|
||||
kName_("k"),
|
||||
GName_("RASModel::G"),
|
||||
nuName_("nu"),
|
||||
nutName_("nut"),
|
||||
Cmu_(0.09),
|
||||
kappa_(0.41),
|
||||
E_(9.8)
|
||||
{}
|
||||
|
||||
|
||||
immersedBoundaryEpsilonWallFunctionFvPatchScalarField::
|
||||
immersedBoundaryEpsilonWallFunctionFvPatchScalarField
|
||||
(
|
||||
const fvPatch& p,
|
||||
const DimensionedField<scalar, volMesh>& iF,
|
||||
const dictionary& dict
|
||||
)
|
||||
:
|
||||
immersedBoundaryWallFunctionFvPatchScalarField(p, iF, dict),
|
||||
UName_(dict.lookupOrDefault<word>("U", "U")),
|
||||
kName_(dict.lookupOrDefault<word>("k", "k")),
|
||||
GName_(dict.lookupOrDefault<word>("G", "RASModel::G")),
|
||||
nuName_(dict.lookupOrDefault<word>("nu", "nu")),
|
||||
nutName_(dict.lookupOrDefault<word>("nut", "nut")),
|
||||
Cmu_(dict.lookupOrDefault<scalar>("Cmu", 0.09)),
|
||||
kappa_(dict.lookupOrDefault<scalar>("kappa", 0.41)),
|
||||
E_(dict.lookupOrDefault<scalar>("E", 9.8))
|
||||
{}
|
||||
|
||||
|
||||
immersedBoundaryEpsilonWallFunctionFvPatchScalarField::
|
||||
immersedBoundaryEpsilonWallFunctionFvPatchScalarField
|
||||
(
|
||||
const immersedBoundaryEpsilonWallFunctionFvPatchScalarField& ptf,
|
||||
const fvPatch& p,
|
||||
const DimensionedField<scalar, volMesh>& iF,
|
||||
const fvPatchFieldMapper& mapper
|
||||
)
|
||||
:
|
||||
immersedBoundaryWallFunctionFvPatchScalarField(ptf, p, iF, mapper),
|
||||
UName_(ptf.UName_),
|
||||
kName_(ptf.kName_),
|
||||
GName_(ptf.GName_),
|
||||
nuName_(ptf.nuName_),
|
||||
nutName_(ptf.nutName_),
|
||||
Cmu_(ptf.Cmu_),
|
||||
kappa_(ptf.kappa_),
|
||||
E_(ptf.E_)
|
||||
{}
|
||||
|
||||
|
||||
immersedBoundaryEpsilonWallFunctionFvPatchScalarField::
|
||||
immersedBoundaryEpsilonWallFunctionFvPatchScalarField
|
||||
(
|
||||
const immersedBoundaryEpsilonWallFunctionFvPatchScalarField& ewfpsf
|
||||
)
|
||||
:
|
||||
immersedBoundaryWallFunctionFvPatchScalarField(ewfpsf),
|
||||
UName_(ewfpsf.UName_),
|
||||
kName_(ewfpsf.kName_),
|
||||
GName_(ewfpsf.GName_),
|
||||
nuName_(ewfpsf.nuName_),
|
||||
nutName_(ewfpsf.nutName_),
|
||||
Cmu_(ewfpsf.Cmu_),
|
||||
kappa_(ewfpsf.kappa_),
|
||||
E_(ewfpsf.E_)
|
||||
{}
|
||||
|
||||
|
||||
immersedBoundaryEpsilonWallFunctionFvPatchScalarField::
|
||||
immersedBoundaryEpsilonWallFunctionFvPatchScalarField
|
||||
(
|
||||
const immersedBoundaryEpsilonWallFunctionFvPatchScalarField& ewfpsf,
|
||||
const DimensionedField<scalar, volMesh>& iF
|
||||
)
|
||||
:
|
||||
immersedBoundaryWallFunctionFvPatchScalarField(ewfpsf, iF),
|
||||
UName_(ewfpsf.UName_),
|
||||
kName_(ewfpsf.kName_),
|
||||
GName_(ewfpsf.GName_),
|
||||
nuName_(ewfpsf.nuName_),
|
||||
nutName_(ewfpsf.nutName_),
|
||||
Cmu_(ewfpsf.Cmu_),
|
||||
kappa_(ewfpsf.kappa_),
|
||||
E_(ewfpsf.E_)
|
||||
{}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
void immersedBoundaryEpsilonWallFunctionFvPatchScalarField::updateCoeffs()
|
||||
{
|
||||
if (updated())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// If G field is not present, execute zero gradient evaluation
|
||||
// HJ, 20/Mar/2011
|
||||
if (!db().foundObject<volScalarField>(GName_))
|
||||
{
|
||||
InfoIn
|
||||
(
|
||||
"void immersedBoundaryEpsilonWallFunctionFvPatchScalarField::"
|
||||
"updateCoeffs()"
|
||||
) << "Cannot access " << GName_ << " field. for patch "
|
||||
<< patch().name() << ". Evaluating as regular immersed boundary"
|
||||
<< endl;
|
||||
|
||||
immersedBoundaryWallFunctionFvPatchScalarField::evaluate();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
const vectorField& n = ibPatch().ibNormals();
|
||||
|
||||
const RASModel& rasModel = db().lookupObject<RASModel>("RASProperties");
|
||||
const scalar yPlusLam = rasModel.yPlusLam(kappa_, E_);
|
||||
|
||||
const scalar Cmu25 = pow(Cmu_, 0.25);
|
||||
const scalar Cmu50 = sqrt(Cmu_);
|
||||
const scalar Cmu75 = pow(Cmu_, 0.75);
|
||||
|
||||
volScalarField& G = const_cast<volScalarField&>
|
||||
(db().lookupObject<volScalarField>(GName_));
|
||||
|
||||
// Grab values of other fields required for wall functions
|
||||
|
||||
// Velocity
|
||||
const fvPatchVectorField& Uwg =
|
||||
patch().lookupPatchField<volVectorField, vector>(UName_);
|
||||
const immersedBoundaryVelocityWallFunctionFvPatchVectorField& Uw =
|
||||
refCast<const immersedBoundaryVelocityWallFunctionFvPatchVectorField>
|
||||
(
|
||||
Uwg
|
||||
);
|
||||
|
||||
// Calculate tangential component, taking into account wall velocity
|
||||
const vectorField UtanOld =
|
||||
(I - sqr(n)) & (Uw.ibSamplingPointValue() - Uw.ibValue());
|
||||
const scalarField magUtanOld = mag(UtanOld);
|
||||
|
||||
// Tangential velocity component
|
||||
scalarField& UTangentialNew = Uw.wallTangentialValue();
|
||||
|
||||
// Wall shear stress
|
||||
vectorField& tauWall = Uw.tauWall();
|
||||
|
||||
// Turbulence kinetic energy
|
||||
const fvPatchScalarField& kg =
|
||||
patch().lookupPatchField<volScalarField, scalar>(kName_);
|
||||
const immersedBoundaryWallFunctionFvPatchScalarField& kw =
|
||||
refCast<const immersedBoundaryWallFunctionFvPatchScalarField>(kg);
|
||||
|
||||
// Current and new values of k at sampling point
|
||||
scalarField k = kw.ibSamplingPointValue();
|
||||
scalarField& kNew = kw.wallValue();
|
||||
|
||||
// Laminar viscosity
|
||||
const fvPatchScalarField& nuwg =
|
||||
patch().lookupPatchField<volScalarField, scalar>(nuName_);
|
||||
const immersedBoundaryFvPatchScalarField& nuw =
|
||||
refCast<const immersedBoundaryFvPatchScalarField>(nuwg);
|
||||
scalarField nu = nuw.ibCellValue();
|
||||
|
||||
// Turbulent viscosity
|
||||
const fvPatchScalarField& nutwg =
|
||||
patch().lookupPatchField<volScalarField, scalar>(nutName_);
|
||||
const immersedBoundaryWallFunctionFvPatchScalarField& nutw =
|
||||
refCast<const immersedBoundaryWallFunctionFvPatchScalarField>(nutwg);
|
||||
|
||||
// New values of nut
|
||||
scalarField nutOld = nutw.ibCellValue();
|
||||
scalarField& nutNew = nutw.wallValue();
|
||||
|
||||
const scalarField magGradUw = mag(Uw.ibGrad());
|
||||
|
||||
// Get the IB addressing and distance
|
||||
const labelList& ibc = ibPatch().ibCells();
|
||||
|
||||
// Distance to sampling point
|
||||
const scalarField& ySample = ibPatch().ibSamplingPointDelta();
|
||||
|
||||
// Distance from wall to IB point
|
||||
const scalarField& y = ibPatch().ibDelta();
|
||||
|
||||
// Epsilon: store IB cell values for direct insertion
|
||||
scalarField epsilonSample = this->ibSamplingPointValue();
|
||||
|
||||
scalarField& epsilonNew = this->wallValue();
|
||||
|
||||
// Mark values to be fixed
|
||||
boolList wf(ibc.size(), false);
|
||||
|
||||
// Calculate yPlus for sample points
|
||||
scalarField ypd = Cmu25*ySample*sqrt(k)/nu;
|
||||
|
||||
// Calculate wall function conditions
|
||||
forAll (ibc, ibCellI)
|
||||
{
|
||||
const scalar nuLam = nu[ibCellI];
|
||||
|
||||
// Calculate yPlus from k and laminar viscosity for the IB point
|
||||
const scalar yPlusSample = ypd[ibCellI];
|
||||
|
||||
scalar uTau;
|
||||
|
||||
if (yPlusSample > yPlusLam)
|
||||
{
|
||||
// Calculate uTau from log-law, knowing sampled k and U
|
||||
uTau = magUtanOld[ibCellI]*kappa_/log(E_*yPlusSample);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Sampling point is in laminar sublayer
|
||||
// Bug fix: HJ, 11/Aug/2014
|
||||
uTau = yPlusSample;
|
||||
|
||||
}
|
||||
|
||||
// Set wall shear stress
|
||||
tauWall[ibCellI] = sqr(uTau)*UtanOld[ibCellI]/(magUtanOld[ibCellI] + SMALL);
|
||||
|
||||
// Calculate yPlus for IB point
|
||||
// scalar yPlusIB = uTau*y[ibCellI]/nuLam;
|
||||
scalar yPlusIB = yPlusSample*y[ibCellI]/ySample[ibCellI];
|
||||
|
||||
// Calculate wall function data in the immersed boundary point
|
||||
if (yPlusIB > yPlusLam)
|
||||
{
|
||||
// Logarithmic region
|
||||
wf[ibCellI] = true;
|
||||
|
||||
scalar nutw = nuLam*(yPlusIB*kappa_/log(E_*yPlusIB) - 1);
|
||||
|
||||
// Fix generation even though it if is not used
|
||||
G[ibc[ibCellI]] =
|
||||
sqr((nutw + nuLam)*magGradUw[ibCellI])/
|
||||
(Cmu25*sqrt(k[ibCellI])*kappa_*y[ibCellI]);
|
||||
|
||||
// Log-Law for tangential velocity
|
||||
UTangentialNew[ibCellI] =
|
||||
min
|
||||
(
|
||||
magUtanOld[ibCellI],
|
||||
uTau/kappa_*log(E_*yPlusIB)
|
||||
);
|
||||
|
||||
// Calculate turbulent viscosity
|
||||
nutNew[ibCellI] = nutw;
|
||||
|
||||
// Calculate k in the IB cell from G = epsilon
|
||||
kNew[ibCellI] = (nutw + nuLam)*magGradUw[ibCellI]/Cmu50;
|
||||
|
||||
// Calculate epsilon from yPlus and set it
|
||||
epsilonNew[ibCellI] =
|
||||
Cmu75*pow(kNew[ibCellI], 1.5)/(kappa_*y[ibCellI]);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Laminar sub-layer
|
||||
wf[ibCellI] = false;
|
||||
|
||||
// G is zero
|
||||
G[ibc[ibCellI]] = 0;
|
||||
|
||||
// Laminar sub-layer for tangential velocity: uPlus = yPlus
|
||||
UTangentialNew[ibCellI] = min(magUtanOld[ibCellI], uTau*yPlusIB);
|
||||
|
||||
// Turbulent viscosity is zero
|
||||
nutNew[ibCellI] = SMALL;
|
||||
|
||||
// k is zero gradient: use the sampled value
|
||||
kNew[ibCellI] = k[ibCellI];
|
||||
|
||||
// Calculate epsilon from yPlus and set it.
|
||||
// Note: calculating equilibrium epsilon in the sub-layer creates
|
||||
// an unrealistic oscillation: use sampled value
|
||||
// HJ, 27/Jul/2012
|
||||
epsilonNew[ibCellI] = epsilonSample[ibCellI];
|
||||
}
|
||||
}
|
||||
|
||||
// Info<< "UTangentialNew " << min(UTangentialNew) << " " << max(UTangentialNew) << endl;
|
||||
// Info<< "nutNew " << min(nutNew) << " " << max(nutNew) << endl;
|
||||
// Info<< "kNew " << min(kNew) << " " << max(kNew) << endl;
|
||||
// Info<< "epsilonNew " << min(epsilonNew) << " " << max(epsilonNew) << endl;
|
||||
|
||||
// Set the fields to calculated wall function values
|
||||
Uw.wallMask() = true;
|
||||
kw.wallMask() = wf;
|
||||
nutw.wallMask() = true;
|
||||
this->wallMask() = true;
|
||||
|
||||
// Insert epsilon values into the internal field
|
||||
immersedBoundaryWallFunctionFvPatchScalarField::updateCoeffs();
|
||||
}
|
||||
|
||||
|
||||
void immersedBoundaryEpsilonWallFunctionFvPatchScalarField::evaluate
|
||||
(
|
||||
const Pstream::commsTypes commsType
|
||||
)
|
||||
{
|
||||
// Insert epsilon values into the internal field
|
||||
this->setIbCellValues(this->wallValue());
|
||||
|
||||
fvPatchScalarField::evaluate(commsType);
|
||||
}
|
||||
|
||||
|
||||
void immersedBoundaryEpsilonWallFunctionFvPatchScalarField::
|
||||
write(Ostream& os) const
|
||||
{
|
||||
immersedBoundaryWallFunctionFvPatchScalarField::write(os);
|
||||
writeEntryIfDifferent<word>(os, "U", "U", UName_);
|
||||
writeEntryIfDifferent<word>(os, "k", "k", kName_);
|
||||
writeEntryIfDifferent<word>(os, "G", "RASModel::G", GName_);
|
||||
writeEntryIfDifferent<word>(os, "nu", "nu", nuName_);
|
||||
writeEntryIfDifferent<word>(os, "nut", "nut", nutName_);
|
||||
os.writeKeyword("Cmu") << Cmu_ << token::END_STATEMENT << nl;
|
||||
os.writeKeyword("kappa") << kappa_ << token::END_STATEMENT << nl;
|
||||
os.writeKeyword("E") << E_ << token::END_STATEMENT << nl;
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
makePatchTypeField
|
||||
(
|
||||
fvPatchScalarField,
|
||||
immersedBoundaryEpsilonWallFunctionFvPatchScalarField
|
||||
);
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace RASModels
|
||||
} // End namespace incompressible
|
||||
} // End namespace Foam
|
||||
|
||||
// ************************************************************************* //
|
|
@ -0,0 +1,202 @@
|
|||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright held by original author
|
||||
\\/ 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 2 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, write to the Free Software Foundation,
|
||||
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
Class
|
||||
Foam::incompressible::RASModels::
|
||||
immersedBoundaryEpsilonWallFunctionFvPatchScalarField
|
||||
|
||||
Description
|
||||
Boundary condition for epsilon when using wall functions
|
||||
- calculates y+, G, tangential velocity, nut and k
|
||||
- each of calculated values is handled separately by the appropriate
|
||||
boundary condition
|
||||
- epsilon values added directly into the field to act as a constraint
|
||||
|
||||
SourceFiles
|
||||
immersedBoundaryEpsilonWallFunctionFvPatchScalarField.C
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef immersedBoundaryEpsilonWallFunctionFvPatchScalarField_H
|
||||
#define immersedBoundaryEpsilonWallFunctionFvPatchScalarField_H
|
||||
|
||||
#include "immersedBoundaryWallFunctionFvPatchFields.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
namespace incompressible
|
||||
{
|
||||
namespace RASModels
|
||||
{
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class immersedBoundaryEpsilonWallFunctionFvPatchScalarField Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
class immersedBoundaryEpsilonWallFunctionFvPatchScalarField
|
||||
:
|
||||
public immersedBoundaryWallFunctionFvPatchScalarField
|
||||
{
|
||||
// Private data
|
||||
|
||||
//- Name of velocity field
|
||||
word UName_;
|
||||
|
||||
//- Name of turbulence kinetic energy field
|
||||
word kName_;
|
||||
|
||||
//- Name of turbulence generation field
|
||||
word GName_;
|
||||
|
||||
//- Name of laminar viscosity field
|
||||
word nuName_;
|
||||
|
||||
//- Name of turbulent viscosity field
|
||||
word nutName_;
|
||||
|
||||
//- Cmu coefficient
|
||||
scalar Cmu_;
|
||||
|
||||
//- Von Karman constant
|
||||
scalar kappa_;
|
||||
|
||||
//- E coefficient
|
||||
scalar E_;
|
||||
|
||||
|
||||
public:
|
||||
|
||||
//- Runtime type information
|
||||
TypeName("immersedBoundaryEpsilonWallFunction");
|
||||
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Construct from patch and internal field
|
||||
immersedBoundaryEpsilonWallFunctionFvPatchScalarField
|
||||
(
|
||||
const fvPatch&,
|
||||
const DimensionedField<scalar, volMesh>&
|
||||
);
|
||||
|
||||
//- Construct from patch, internal field and dictionary
|
||||
immersedBoundaryEpsilonWallFunctionFvPatchScalarField
|
||||
(
|
||||
const fvPatch&,
|
||||
const DimensionedField<scalar, volMesh>&,
|
||||
const dictionary&
|
||||
);
|
||||
|
||||
//- Construct by mapping given
|
||||
// immersedBoundaryEpsilonWallFunctionFvPatchScalarField
|
||||
// onto a new patch
|
||||
immersedBoundaryEpsilonWallFunctionFvPatchScalarField
|
||||
(
|
||||
const immersedBoundaryEpsilonWallFunctionFvPatchScalarField&,
|
||||
const fvPatch&,
|
||||
const DimensionedField<scalar, volMesh>&,
|
||||
const fvPatchFieldMapper&
|
||||
);
|
||||
|
||||
//- Construct as copy
|
||||
immersedBoundaryEpsilonWallFunctionFvPatchScalarField
|
||||
(
|
||||
const immersedBoundaryEpsilonWallFunctionFvPatchScalarField&
|
||||
);
|
||||
|
||||
//- Construct and return a clone
|
||||
virtual tmp<fvPatchScalarField> clone() const
|
||||
{
|
||||
return tmp<fvPatchScalarField>
|
||||
(
|
||||
new immersedBoundaryEpsilonWallFunctionFvPatchScalarField
|
||||
(
|
||||
*this
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
//- Construct as copy setting internal field reference
|
||||
immersedBoundaryEpsilonWallFunctionFvPatchScalarField
|
||||
(
|
||||
const immersedBoundaryEpsilonWallFunctionFvPatchScalarField&,
|
||||
const DimensionedField<scalar, volMesh>&
|
||||
);
|
||||
|
||||
//- Construct and return a clone setting internal field reference
|
||||
virtual tmp<fvPatchScalarField> clone
|
||||
(
|
||||
const DimensionedField<scalar, volMesh>& iF
|
||||
) const
|
||||
{
|
||||
return tmp<fvPatchScalarField>
|
||||
(
|
||||
new immersedBoundaryEpsilonWallFunctionFvPatchScalarField
|
||||
(
|
||||
*this,
|
||||
iF
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
//- Destructor
|
||||
virtual ~immersedBoundaryEpsilonWallFunctionFvPatchScalarField()
|
||||
{}
|
||||
|
||||
|
||||
// Member functions
|
||||
|
||||
// Evaluation functions
|
||||
|
||||
//- Update the coefficients associated with the patch field
|
||||
virtual void updateCoeffs();
|
||||
|
||||
//- Evaluate the patchField
|
||||
virtual void evaluate
|
||||
(
|
||||
const Pstream::commsTypes = Pstream::blocking
|
||||
);
|
||||
|
||||
|
||||
// I-O
|
||||
|
||||
//- Write
|
||||
void write(Ostream&) const;
|
||||
};
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace RASModels
|
||||
} // End namespace incompressible
|
||||
} // End namespace Foam
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
|
@ -0,0 +1,386 @@
|
|||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright held by original author
|
||||
\\/ 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 2 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, write to the Free Software Foundation,
|
||||
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "immersedBoundaryOmegaWallFunctionFvPatchScalarField.H"
|
||||
#include "immersedBoundaryVelocityWallFunctionFvPatchVectorField.H"
|
||||
#include "RASModel.H"
|
||||
#include "fvPatchFieldMapper.H"
|
||||
#include "volFields.H"
|
||||
#include "addToRunTimeSelectionTable.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
namespace incompressible
|
||||
{
|
||||
namespace RASModels
|
||||
{
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
immersedBoundaryOmegaWallFunctionFvPatchScalarField::
|
||||
immersedBoundaryOmegaWallFunctionFvPatchScalarField
|
||||
(
|
||||
const fvPatch& p,
|
||||
const DimensionedField<scalar, volMesh>& iF
|
||||
)
|
||||
:
|
||||
immersedBoundaryWallFunctionFvPatchScalarField(p, iF),
|
||||
UName_("U"),
|
||||
kName_("k"),
|
||||
GName_("RASModel::G"),
|
||||
nuName_("nu"),
|
||||
nutName_("nut"),
|
||||
Cmu_(0.09),
|
||||
kappa_(0.41),
|
||||
E_(9.8),
|
||||
beta1_(0.075)
|
||||
{}
|
||||
|
||||
|
||||
immersedBoundaryOmegaWallFunctionFvPatchScalarField::
|
||||
immersedBoundaryOmegaWallFunctionFvPatchScalarField
|
||||
(
|
||||
const fvPatch& p,
|
||||
const DimensionedField<scalar, volMesh>& iF,
|
||||
const dictionary& dict
|
||||
)
|
||||
:
|
||||
immersedBoundaryWallFunctionFvPatchScalarField(p, iF, dict),
|
||||
UName_(dict.lookupOrDefault<word>("U", "U")),
|
||||
kName_(dict.lookupOrDefault<word>("k", "k")),
|
||||
GName_(dict.lookupOrDefault<word>("G", "RASModel::G")),
|
||||
nuName_(dict.lookupOrDefault<word>("nu", "nu")),
|
||||
nutName_(dict.lookupOrDefault<word>("nut", "nut")),
|
||||
Cmu_(dict.lookupOrDefault<scalar>("Cmu", 0.09)),
|
||||
kappa_(dict.lookupOrDefault<scalar>("kappa", 0.41)),
|
||||
E_(dict.lookupOrDefault<scalar>("E", 9.8)),
|
||||
beta1_(dict.lookupOrDefault<scalar>("beta1", 0.075))
|
||||
{}
|
||||
|
||||
|
||||
immersedBoundaryOmegaWallFunctionFvPatchScalarField::
|
||||
immersedBoundaryOmegaWallFunctionFvPatchScalarField
|
||||
(
|
||||
const immersedBoundaryOmegaWallFunctionFvPatchScalarField& ptf,
|
||||
const fvPatch& p,
|
||||
const DimensionedField<scalar, volMesh>& iF,
|
||||
const fvPatchFieldMapper& mapper
|
||||
)
|
||||
:
|
||||
immersedBoundaryWallFunctionFvPatchScalarField(ptf, p, iF, mapper),
|
||||
UName_(ptf.UName_),
|
||||
kName_(ptf.kName_),
|
||||
GName_(ptf.GName_),
|
||||
nuName_(ptf.nuName_),
|
||||
nutName_(ptf.nutName_),
|
||||
Cmu_(ptf.Cmu_),
|
||||
kappa_(ptf.kappa_),
|
||||
E_(ptf.E_),
|
||||
beta1_(ptf.beta1_)
|
||||
{}
|
||||
|
||||
|
||||
immersedBoundaryOmegaWallFunctionFvPatchScalarField::
|
||||
immersedBoundaryOmegaWallFunctionFvPatchScalarField
|
||||
(
|
||||
const immersedBoundaryOmegaWallFunctionFvPatchScalarField& owfpsf
|
||||
)
|
||||
:
|
||||
immersedBoundaryWallFunctionFvPatchScalarField(owfpsf),
|
||||
UName_(owfpsf.UName_),
|
||||
kName_(owfpsf.kName_),
|
||||
GName_(owfpsf.GName_),
|
||||
nuName_(owfpsf.nuName_),
|
||||
nutName_(owfpsf.nutName_),
|
||||
Cmu_(owfpsf.Cmu_),
|
||||
kappa_(owfpsf.kappa_),
|
||||
E_(owfpsf.E_)
|
||||
{}
|
||||
|
||||
|
||||
immersedBoundaryOmegaWallFunctionFvPatchScalarField::
|
||||
immersedBoundaryOmegaWallFunctionFvPatchScalarField
|
||||
(
|
||||
const immersedBoundaryOmegaWallFunctionFvPatchScalarField& owfpsf,
|
||||
const DimensionedField<scalar, volMesh>& iF
|
||||
)
|
||||
:
|
||||
immersedBoundaryWallFunctionFvPatchScalarField(owfpsf, iF),
|
||||
UName_(owfpsf.UName_),
|
||||
kName_(owfpsf.kName_),
|
||||
GName_(owfpsf.GName_),
|
||||
nuName_(owfpsf.nuName_),
|
||||
nutName_(owfpsf.nutName_),
|
||||
Cmu_(owfpsf.Cmu_),
|
||||
kappa_(owfpsf.kappa_),
|
||||
E_(owfpsf.E_)
|
||||
{}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
void immersedBoundaryOmegaWallFunctionFvPatchScalarField::updateCoeffs()
|
||||
{
|
||||
if (updated())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// If G field is not present, execute zero gradient evaluation
|
||||
// HJ, 20/Mar/2011
|
||||
if (!db().foundObject<volScalarField>(GName_))
|
||||
{
|
||||
InfoIn
|
||||
(
|
||||
"void immersedBoundaryOmegaWallFunctionFvPatchScalarField::"
|
||||
"updateCoeffs()"
|
||||
) << "Cannot access " << GName_ << " field. for patch "
|
||||
<< patch().name() << ". Evaluating as regular immersed boundary"
|
||||
<< endl;
|
||||
|
||||
immersedBoundaryWallFunctionFvPatchScalarField::evaluate();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
const vectorField& n = ibPatch().ibNormals();
|
||||
|
||||
const RASModel& rasModel = db().lookupObject<RASModel>("RASProperties");
|
||||
const scalar yPlusLam = rasModel.yPlusLam(kappa_, E_);
|
||||
|
||||
const scalar Cmu25 = pow(Cmu_, 0.25);
|
||||
const scalar Cmu50 = sqrt(Cmu_);
|
||||
|
||||
volScalarField& G = const_cast<volScalarField&>
|
||||
(db().lookupObject<volScalarField>(GName_));
|
||||
|
||||
// Grab values of other fields required for wall functions
|
||||
|
||||
// Velocity
|
||||
const fvPatchVectorField& Uwg =
|
||||
patch().lookupPatchField<volVectorField, vector>(UName_);
|
||||
const immersedBoundaryVelocityWallFunctionFvPatchVectorField& Uw =
|
||||
refCast<const immersedBoundaryVelocityWallFunctionFvPatchVectorField>
|
||||
(
|
||||
Uwg
|
||||
);
|
||||
|
||||
// Calculate tangential component, taking into account wall velocity
|
||||
const scalarField UtanOld =
|
||||
mag((I - sqr(n)) & (Uw.ibSamplingPointValue() - Uw.ibValue()));
|
||||
|
||||
scalarField& UTangentialNew = Uw.wallTangentialValue();
|
||||
|
||||
// Turbulence kinetic energy
|
||||
const fvPatchScalarField& kg =
|
||||
patch().lookupPatchField<volScalarField, scalar>(kName_);
|
||||
const immersedBoundaryWallFunctionFvPatchScalarField& kw =
|
||||
refCast<const immersedBoundaryWallFunctionFvPatchScalarField>(kg);
|
||||
|
||||
// Current and new values of k at sampling point
|
||||
scalarField k = kw.ibSamplingPointValue();
|
||||
scalarField& kNew = kw.wallValue();
|
||||
|
||||
// Laminar viscosity
|
||||
const fvPatchScalarField& nuwg =
|
||||
patch().lookupPatchField<volScalarField, scalar>(nuName_);
|
||||
const immersedBoundaryFvPatchScalarField& nuw =
|
||||
refCast<const immersedBoundaryFvPatchScalarField>(nuwg);
|
||||
scalarField nu = nuw.ibCellValue();
|
||||
|
||||
// Turbulent viscosity
|
||||
const fvPatchScalarField& nutwg =
|
||||
patch().lookupPatchField<volScalarField, scalar>(nutName_);
|
||||
const immersedBoundaryWallFunctionFvPatchScalarField& nutw =
|
||||
refCast<const immersedBoundaryWallFunctionFvPatchScalarField>(nutwg);
|
||||
|
||||
// New values of nut
|
||||
scalarField nutOld = nutw.ibCellValue();
|
||||
scalarField& nutNew = nutw.wallValue();
|
||||
|
||||
const scalarField magGradUw = mag(Uw.ibGrad());
|
||||
|
||||
// Get the IB addressing and distance
|
||||
const labelList& ibc = ibPatch().ibCells();
|
||||
|
||||
// Distance to sampling point
|
||||
const scalarField& ySample = ibPatch().ibSamplingPointDelta();
|
||||
|
||||
// Distance from wall to IB point
|
||||
const scalarField& y = ibPatch().ibDelta();
|
||||
|
||||
// Omega: store IB cell values for direct insertion
|
||||
scalarField omegaSample = this->ibSamplingPointValue();
|
||||
|
||||
scalarField& omegaNew = this->wallValue();
|
||||
|
||||
// Mark values to be fixed
|
||||
boolList wf(ibc.size(), false);
|
||||
|
||||
// Calculate yPlus for sample points
|
||||
scalarField ypd = Cmu25*ySample*sqrt(k)/nu;
|
||||
|
||||
// Calculate wall function conditions
|
||||
forAll (ibc, ibCellI)
|
||||
{
|
||||
const scalar nuLam = nu[ibCellI];
|
||||
|
||||
// Calculate yPlus from k and laminar viscosity for the IB point
|
||||
const scalar yPlusSample = ypd[ibCellI];
|
||||
|
||||
scalar tauW, uTau; // wall-shear and friction velocity from LOW
|
||||
|
||||
if (yPlusSample > yPlusLam)
|
||||
{
|
||||
// Calculate tauW from log-law using k and U at sampling point
|
||||
|
||||
tauW = UtanOld[ibCellI]*Cmu25*sqrt(k[ibCellI])*kappa_
|
||||
/log(E_*yPlusSample);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Sampling point is in laminar sublayer
|
||||
tauW = UtanOld[ibCellI]*Cmu25*sqrt(k[ibCellI])/yPlusSample;
|
||||
}
|
||||
|
||||
// friction velocity computed from k and U at sampling point
|
||||
uTau = sqrt(tauW);
|
||||
|
||||
// Calculate yPlus for IB point
|
||||
|
||||
scalar yPlusIB = yPlusSample*y[ibCellI]/ySample[ibCellI];
|
||||
|
||||
// Calculate wall function data in the immersed boundary point
|
||||
if (yPlusIB > yPlusLam)
|
||||
{
|
||||
// Logarithmic region
|
||||
wf[ibCellI] = true;
|
||||
|
||||
// turbulent viscosity at IB cell and at wall
|
||||
scalar nutw = nuLam*(yPlusIB*kappa_/log(E_*yPlusIB) - 1);
|
||||
|
||||
// Fix generation even though it if is not used
|
||||
G[ibc[ibCellI]] =
|
||||
sqr((nutw + nuLam)*magGradUw[ibCellI])/
|
||||
(Cmu25*sqrt(k[ibCellI])*kappa_*y[ibCellI]);
|
||||
|
||||
// Compute k at the IB cell
|
||||
kNew[ibCellI] = tauW/Cmu50; // equilibrium boundary layer
|
||||
// kNew[ibCellI] = k[ibCellI]; // zero-Gradient (less stable)
|
||||
|
||||
// Compute omega at the IB cell
|
||||
omegaNew[ibCellI] = sqrt(kNew[ibCellI])/(Cmu25*kappa_*y[ibCellI]);
|
||||
|
||||
// Log-Law for tangential velocity - uTau = Cmu25*sqrt(kNew)
|
||||
UTangentialNew[ibCellI] = uTau/kappa_*log(E_*yPlusIB);
|
||||
|
||||
// Calculate turbulent viscosity
|
||||
nutNew[ibCellI] = nutw;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Laminar sub-layer
|
||||
wf[ibCellI] = false;
|
||||
|
||||
// G is zero - immaterial!
|
||||
// G[ibc[ibCellI]] = 0;
|
||||
|
||||
// quadratic fit
|
||||
kNew[ibCellI] = k[ibCellI]*sqr(yPlusIB/yPlusLam);
|
||||
|
||||
// Compute omega at the IB cell
|
||||
omegaNew[ibCellI] = 6.0*nu[ibCellI]/(beta1_*sqr(y[ibCellI]));
|
||||
|
||||
// Laminar sub-layer for tangential velocity: uPlus = yPlus
|
||||
UTangentialNew[ibCellI] = uTau*yPlusIB;
|
||||
|
||||
// Turbulent viscosity is zero
|
||||
nutNew[ibCellI] = SMALL;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// Info<< "UTangentialNew " << min(UTangentialNew) << " " << max(UTangentialNew) << endl;
|
||||
// Info<< "nutNew " << min(nutNew) << " " << max(nutNew) << endl;
|
||||
// Info<< "kNew " << min(kNew) << " " << max(kNew) << endl;
|
||||
// Info<< "epsilonNew " << min(epsilonNew) << " " << max(epsilonNew) << endl;
|
||||
|
||||
// Set the fields to calculated wall function values
|
||||
Uw.wallMask() = true;
|
||||
kw.wallMask() = wf;
|
||||
nutw.wallMask() = true;
|
||||
this->wallMask() = true;
|
||||
|
||||
// Insert epsilon values into the internal field
|
||||
immersedBoundaryWallFunctionFvPatchScalarField::updateCoeffs();
|
||||
}
|
||||
|
||||
|
||||
void immersedBoundaryOmegaWallFunctionFvPatchScalarField::evaluate
|
||||
(
|
||||
const Pstream::commsTypes commsType
|
||||
)
|
||||
{
|
||||
// Insert epsilon values into the internal field
|
||||
this->setIbCellValues(this->wallValue());
|
||||
|
||||
fvPatchScalarField::evaluate(commsType);
|
||||
}
|
||||
|
||||
|
||||
void immersedBoundaryOmegaWallFunctionFvPatchScalarField::
|
||||
write(Ostream& os) const
|
||||
{
|
||||
immersedBoundaryWallFunctionFvPatchScalarField::write(os);
|
||||
writeEntryIfDifferent<word>(os, "U", "U", UName_);
|
||||
writeEntryIfDifferent<word>(os, "k", "k", kName_);
|
||||
writeEntryIfDifferent<word>(os, "G", "RASModel::G", GName_);
|
||||
writeEntryIfDifferent<word>(os, "nu", "nu", nuName_);
|
||||
writeEntryIfDifferent<word>(os, "nut", "nut", nutName_);
|
||||
os.writeKeyword("Cmu") << Cmu_ << token::END_STATEMENT << nl;
|
||||
os.writeKeyword("kappa") << kappa_ << token::END_STATEMENT << nl;
|
||||
os.writeKeyword("E") << E_ << token::END_STATEMENT << nl;
|
||||
os.writeKeyword("beta1") << beta1_ << token::END_STATEMENT << nl;
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
makePatchTypeField
|
||||
(
|
||||
fvPatchScalarField,
|
||||
immersedBoundaryOmegaWallFunctionFvPatchScalarField
|
||||
);
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace RASModels
|
||||
} // End namespace incompressible
|
||||
} // End namespace Foam
|
||||
|
||||
// ************************************************************************* //
|
|
@ -0,0 +1,217 @@
|
|||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright held by original author
|
||||
\\/ 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 2 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, write to the Free Software Foundation,
|
||||
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
Class
|
||||
Foam::incompressible::RASModels::
|
||||
immersedBoundaryOmegaWallFunctionFvPatchScalarField
|
||||
|
||||
Description
|
||||
Provides a wall function boundary condition/constraint on omega
|
||||
|
||||
Computed value is:
|
||||
|
||||
omega = sqrt(omega_vis^2 + omega_log^2)
|
||||
|
||||
where
|
||||
omega_vis = omega in viscous region
|
||||
omega_log = omega in logarithmic region
|
||||
|
||||
Model described by Eq.(15) of:
|
||||
@verbatim
|
||||
Menter, F., Esch, T.
|
||||
"Elements of Industrial Heat Transfer Prediction"
|
||||
16th Brazilian Congress of Mechanical Engineering (COBEM),
|
||||
Nov. 2001
|
||||
@endverbatim
|
||||
|
||||
SourceFiles
|
||||
immersedBoundaryOmegaWallFunctionFvPatchScalarField.C
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef immersedBoundaryOmegaWallFunctionFvPatchScalarField_H
|
||||
#define immersedBoundaryOmegaWallFunctionFvPatchScalarField_H
|
||||
|
||||
#include "immersedBoundaryWallFunctionFvPatchFields.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
namespace incompressible
|
||||
{
|
||||
namespace RASModels
|
||||
{
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class immersedBoundaryOmegaWallFunctionFvPatchScalarField Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
class immersedBoundaryOmegaWallFunctionFvPatchScalarField
|
||||
:
|
||||
public immersedBoundaryWallFunctionFvPatchScalarField
|
||||
{
|
||||
// Private data
|
||||
|
||||
//- Name of velocity field
|
||||
word UName_;
|
||||
|
||||
//- Name of turbulence kinetic energy field
|
||||
word kName_;
|
||||
|
||||
//- Name of turbulence generation field
|
||||
word GName_;
|
||||
|
||||
//- Name of laminar viscosity field
|
||||
word nuName_;
|
||||
|
||||
//- Name of turbulent viscosity field
|
||||
word nutName_;
|
||||
|
||||
//- Cmu coefficient
|
||||
scalar Cmu_;
|
||||
|
||||
//- Von Karman constant
|
||||
scalar kappa_;
|
||||
|
||||
//- E coefficient
|
||||
scalar E_;
|
||||
|
||||
//- beta1 coefficient
|
||||
scalar beta1_;
|
||||
|
||||
|
||||
public:
|
||||
|
||||
//- Runtime type information
|
||||
TypeName("immersedBoundaryOmegaWallFunction");
|
||||
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Construct from patch and internal field
|
||||
immersedBoundaryOmegaWallFunctionFvPatchScalarField
|
||||
(
|
||||
const fvPatch&,
|
||||
const DimensionedField<scalar, volMesh>&
|
||||
);
|
||||
|
||||
//- Construct from patch, internal field and dictionary
|
||||
immersedBoundaryOmegaWallFunctionFvPatchScalarField
|
||||
(
|
||||
const fvPatch&,
|
||||
const DimensionedField<scalar, volMesh>&,
|
||||
const dictionary&
|
||||
);
|
||||
|
||||
//- Construct by mapping given
|
||||
// immersedBoundaryOmegaWallFunctionFvPatchScalarField
|
||||
// onto a new patch
|
||||
immersedBoundaryOmegaWallFunctionFvPatchScalarField
|
||||
(
|
||||
const immersedBoundaryOmegaWallFunctionFvPatchScalarField&,
|
||||
const fvPatch&,
|
||||
const DimensionedField<scalar, volMesh>&,
|
||||
const fvPatchFieldMapper&
|
||||
);
|
||||
|
||||
//- Construct as copy
|
||||
immersedBoundaryOmegaWallFunctionFvPatchScalarField
|
||||
(
|
||||
const immersedBoundaryOmegaWallFunctionFvPatchScalarField&
|
||||
);
|
||||
|
||||
//- Construct and return a clone
|
||||
virtual tmp<fvPatchScalarField> clone() const
|
||||
{
|
||||
return tmp<fvPatchScalarField>
|
||||
(
|
||||
new immersedBoundaryOmegaWallFunctionFvPatchScalarField
|
||||
(
|
||||
*this
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
//- Construct as copy setting internal field reference
|
||||
immersedBoundaryOmegaWallFunctionFvPatchScalarField
|
||||
(
|
||||
const immersedBoundaryOmegaWallFunctionFvPatchScalarField&,
|
||||
const DimensionedField<scalar, volMesh>&
|
||||
);
|
||||
|
||||
//- Construct and return a clone setting internal field reference
|
||||
virtual tmp<fvPatchScalarField> clone
|
||||
(
|
||||
const DimensionedField<scalar, volMesh>& iF
|
||||
) const
|
||||
{
|
||||
return tmp<fvPatchScalarField>
|
||||
(
|
||||
new immersedBoundaryOmegaWallFunctionFvPatchScalarField
|
||||
(
|
||||
*this,
|
||||
iF
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
//- Destructor
|
||||
virtual ~immersedBoundaryOmegaWallFunctionFvPatchScalarField()
|
||||
{}
|
||||
|
||||
|
||||
// Member functions
|
||||
|
||||
// Evaluation functions
|
||||
|
||||
//- Update the coefficients associated with the patch field
|
||||
virtual void updateCoeffs();
|
||||
|
||||
//- Evaluate the patchField
|
||||
virtual void evaluate
|
||||
(
|
||||
const Pstream::commsTypes = Pstream::blocking
|
||||
);
|
||||
|
||||
|
||||
// I-O
|
||||
|
||||
//- Write
|
||||
void write(Ostream&) const;
|
||||
};
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace RASModels
|
||||
} // End namespace incompressible
|
||||
} // End namespace Foam
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
|
@ -0,0 +1,224 @@
|
|||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright held by original author
|
||||
\\/ 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 2 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, write to the Free Software Foundation,
|
||||
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "immersedBoundaryVelocityWallFunctionFvPatchVectorField.H"
|
||||
#include "immersedBoundaryWallFunctionFvPatchFields.H"
|
||||
#include "RASModel.H"
|
||||
#include "fvPatchFieldMapper.H"
|
||||
#include "volFields.H"
|
||||
#include "addToRunTimeSelectionTable.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
namespace incompressible
|
||||
{
|
||||
namespace RASModels
|
||||
{
|
||||
|
||||
void immersedBoundaryVelocityWallFunctionFvPatchVectorField::setIbCellValues
|
||||
(
|
||||
const vectorField& ibcValues
|
||||
) const
|
||||
{
|
||||
const labelList& ibc = ibPatch().ibCells();
|
||||
|
||||
if (ibcValues.size() != ibc.size())
|
||||
{
|
||||
FatalErrorIn
|
||||
(
|
||||
"void immersedBoundaryVelocityWallFunctionFvPatchVectorField::"
|
||||
"setIbCellValues\n"
|
||||
"(\n"
|
||||
" const vectorField& ibcValues\n"
|
||||
") const"
|
||||
) << "Size of ibcValues field not equal to the number of IB cells."
|
||||
<< nl << "ibcValues: " << ibcValues.size()
|
||||
<< " ibc: " << ibc.size()
|
||||
<< abort(FatalError);
|
||||
}
|
||||
|
||||
// Get non-const access to internal field
|
||||
vectorField& psiI = const_cast<vectorField&>(this->internalField());
|
||||
|
||||
immersedBoundaryFvPatchVectorField::setIbCellValues(ibcValues);
|
||||
|
||||
if (wallTangentialValue_.empty() || wallMask_.empty())
|
||||
{
|
||||
immersedBoundaryFvPatchVectorField::setIbCellValues(ibcValues);
|
||||
}
|
||||
else
|
||||
{
|
||||
const vectorField& n = ibPatch().ibNormals();
|
||||
|
||||
// Calculate tangential component taking into account wall velocity
|
||||
scalarField UtanOld = mag((I - sqr(n)) & this->ibCellValue());
|
||||
|
||||
vectorField Uwall = this->ibValue();
|
||||
|
||||
forAll (ibcValues, cellI)
|
||||
{
|
||||
// If mask is set, correct the velocity for the
|
||||
// tangential wall value, otherwise use the fitted value
|
||||
if (wallMask_[cellI])
|
||||
{
|
||||
// Decompose fitted velocity into the normal and
|
||||
// tangential components
|
||||
const vector& curN = n[cellI];
|
||||
const vector curU = psiI[ibc[cellI]];
|
||||
|
||||
scalar ibcNormal = curN & ibcValues[cellI];
|
||||
|
||||
// Get tangential velocity and direction
|
||||
vector ibcTangential = (I - sqr(curN)) & curU;
|
||||
ibcTangential /= mag(ibcTangential) + SMALL;
|
||||
|
||||
// Reconstruct the velocity, imposing the magnitude of
|
||||
// tangential value and add wall velocity
|
||||
psiI[ibc[cellI]] = curN*ibcNormal
|
||||
+ ibcTangential*wallTangentialValue_[cellI]
|
||||
+ Uwall[cellI];
|
||||
}
|
||||
else
|
||||
{
|
||||
psiI[ibc[cellI]] = ibcValues[cellI];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
immersedBoundaryVelocityWallFunctionFvPatchVectorField::
|
||||
immersedBoundaryVelocityWallFunctionFvPatchVectorField
|
||||
(
|
||||
const fvPatch& p,
|
||||
const DimensionedField<vector, volMesh>& iF
|
||||
)
|
||||
:
|
||||
immersedBoundaryFvPatchVectorField(p, iF),
|
||||
wallTangentialValue_(),
|
||||
tauWall_(),
|
||||
wallMask_()
|
||||
{}
|
||||
|
||||
|
||||
immersedBoundaryVelocityWallFunctionFvPatchVectorField::
|
||||
immersedBoundaryVelocityWallFunctionFvPatchVectorField
|
||||
(
|
||||
const fvPatch& p,
|
||||
const DimensionedField<vector, volMesh>& iF,
|
||||
const dictionary& dict
|
||||
)
|
||||
:
|
||||
immersedBoundaryFvPatchVectorField(p, iF, dict),
|
||||
wallTangentialValue_(),
|
||||
tauWall_(),
|
||||
wallMask_()
|
||||
{}
|
||||
|
||||
|
||||
immersedBoundaryVelocityWallFunctionFvPatchVectorField::
|
||||
immersedBoundaryVelocityWallFunctionFvPatchVectorField
|
||||
(
|
||||
const immersedBoundaryVelocityWallFunctionFvPatchVectorField& ptf,
|
||||
const fvPatch& p,
|
||||
const DimensionedField<vector, volMesh>& iF,
|
||||
const fvPatchFieldMapper& mapper
|
||||
)
|
||||
:
|
||||
immersedBoundaryFvPatchVectorField(ptf, p, iF, mapper),
|
||||
wallTangentialValue_(),
|
||||
tauWall_(),
|
||||
wallMask_()
|
||||
{}
|
||||
|
||||
|
||||
immersedBoundaryVelocityWallFunctionFvPatchVectorField::
|
||||
immersedBoundaryVelocityWallFunctionFvPatchVectorField
|
||||
(
|
||||
const immersedBoundaryVelocityWallFunctionFvPatchVectorField& ewfpsf
|
||||
)
|
||||
:
|
||||
immersedBoundaryFvPatchVectorField(ewfpsf),
|
||||
wallTangentialValue_(),
|
||||
tauWall_(),
|
||||
wallMask_()
|
||||
{}
|
||||
|
||||
|
||||
immersedBoundaryVelocityWallFunctionFvPatchVectorField::
|
||||
immersedBoundaryVelocityWallFunctionFvPatchVectorField
|
||||
(
|
||||
const immersedBoundaryVelocityWallFunctionFvPatchVectorField& ewfpsf,
|
||||
const DimensionedField<vector, volMesh>& iF
|
||||
)
|
||||
:
|
||||
immersedBoundaryFvPatchVectorField(ewfpsf, iF),
|
||||
wallTangentialValue_(),
|
||||
tauWall_(),
|
||||
wallMask_()
|
||||
{}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
const vectorField&
|
||||
immersedBoundaryVelocityWallFunctionFvPatchVectorField::wallShearStress() const
|
||||
{
|
||||
if (tauWall_.empty())
|
||||
{
|
||||
FatalErrorIn
|
||||
(
|
||||
"const vectorField& "
|
||||
"immersedBoundaryVelocityWallFunctionFvPatchVectorField::"
|
||||
"wallShearStress() const"
|
||||
) << "tauWall not set for IB patch " << patch().name()
|
||||
<< " for field " << dimensionedInternalField().name()
|
||||
<< abort(FatalError);
|
||||
}
|
||||
|
||||
return tauWall_;
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
makePatchTypeField
|
||||
(
|
||||
fvPatchVectorField,
|
||||
immersedBoundaryVelocityWallFunctionFvPatchVectorField
|
||||
);
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace RASModels
|
||||
} // End namespace incompressible
|
||||
} // End namespace Foam
|
||||
|
||||
// ************************************************************************* //
|
|
@ -0,0 +1,229 @@
|
|||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright held by original author
|
||||
\\/ 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 2 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, write to the Free Software Foundation,
|
||||
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
Class
|
||||
Foam::incompressible::RASModels::
|
||||
immersedBoundaryVelocityWallFunctionFvPatchVectorField
|
||||
|
||||
Description
|
||||
Boundary condition for velocity when using wall functions
|
||||
- uses tangential velocity as prescribed by the epsilon boundary condition
|
||||
to enforce into the fit
|
||||
|
||||
SourceFiles
|
||||
immersedBoundaryVelocityWallFunctionFvPatchVectorField.C
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef immersedBoundaryVelocityWallFunctionFvPatchVectorField_H
|
||||
#define immersedBoundaryVelocityWallFunctionFvPatchVectorField_H
|
||||
|
||||
#include "fvPatchFields.H"
|
||||
#include "immersedBoundaryFvPatchFields.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
namespace incompressible
|
||||
{
|
||||
namespace RASModels
|
||||
{
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class immersedBoundaryVelocityWallFunctionFvPatchVectorField Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
class immersedBoundaryVelocityWallFunctionFvPatchVectorField
|
||||
:
|
||||
public immersedBoundaryFvPatchVectorField
|
||||
{
|
||||
// Private data
|
||||
|
||||
//- Tangential velocity value to fix in IB cell
|
||||
mutable scalarField wallTangentialValue_;
|
||||
|
||||
//- Wall shear stress
|
||||
mutable vectorField tauWall_;
|
||||
|
||||
//- Indicator on values to fix
|
||||
mutable boolList wallMask_;
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
// Protected Member Functions
|
||||
|
||||
//- Set IB cell values: contains data manipulation
|
||||
virtual void setIbCellValues(const vectorField&) const;
|
||||
|
||||
|
||||
public:
|
||||
|
||||
//- Runtime type information
|
||||
TypeName("immersedBoundaryVelocityWallFunction");
|
||||
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Construct from patch and internal field
|
||||
immersedBoundaryVelocityWallFunctionFvPatchVectorField
|
||||
(
|
||||
const fvPatch&,
|
||||
const DimensionedField<vector, volMesh>&
|
||||
);
|
||||
|
||||
//- Construct from patch, internal field and dictionary
|
||||
immersedBoundaryVelocityWallFunctionFvPatchVectorField
|
||||
(
|
||||
const fvPatch&,
|
||||
const DimensionedField<vector, volMesh>&,
|
||||
const dictionary&
|
||||
);
|
||||
|
||||
//- Construct by mapping given
|
||||
// immersedBoundaryVelocityWallFunctionFvPatchVectorField
|
||||
// onto a new patch
|
||||
immersedBoundaryVelocityWallFunctionFvPatchVectorField
|
||||
(
|
||||
const immersedBoundaryVelocityWallFunctionFvPatchVectorField&,
|
||||
const fvPatch&,
|
||||
const DimensionedField<vector, volMesh>&,
|
||||
const fvPatchFieldMapper&
|
||||
);
|
||||
|
||||
//- Construct as copy
|
||||
immersedBoundaryVelocityWallFunctionFvPatchVectorField
|
||||
(
|
||||
const immersedBoundaryVelocityWallFunctionFvPatchVectorField&
|
||||
);
|
||||
|
||||
//- Construct and return a clone
|
||||
virtual tmp<fvPatchVectorField> clone() const
|
||||
{
|
||||
return tmp<fvPatchVectorField>
|
||||
(
|
||||
new immersedBoundaryVelocityWallFunctionFvPatchVectorField
|
||||
(
|
||||
*this
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
//- Construct as copy setting internal field reference
|
||||
immersedBoundaryVelocityWallFunctionFvPatchVectorField
|
||||
(
|
||||
const immersedBoundaryVelocityWallFunctionFvPatchVectorField&,
|
||||
const DimensionedField<vector, volMesh>&
|
||||
);
|
||||
|
||||
//- Construct and return a clone setting internal field reference
|
||||
virtual tmp<fvPatchVectorField> clone
|
||||
(
|
||||
const DimensionedField<vector, volMesh>& iF
|
||||
) const
|
||||
{
|
||||
return tmp<fvPatchVectorField>
|
||||
(
|
||||
new immersedBoundaryVelocityWallFunctionFvPatchVectorField
|
||||
(
|
||||
*this,
|
||||
iF
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
//- Destructor
|
||||
virtual ~immersedBoundaryVelocityWallFunctionFvPatchVectorField()
|
||||
{}
|
||||
|
||||
|
||||
// Member functions
|
||||
|
||||
// Access
|
||||
|
||||
//- Access to tangential velocity value to fix in IB cell
|
||||
// Note non-const access
|
||||
scalarField& wallTangentialValue() const
|
||||
{
|
||||
if (wallTangentialValue_.empty())
|
||||
{
|
||||
wallTangentialValue_.setSize
|
||||
(
|
||||
this->ibPatch().ibCells().size(),
|
||||
0
|
||||
);
|
||||
}
|
||||
|
||||
return wallTangentialValue_;
|
||||
}
|
||||
|
||||
//- Return wall shear stress
|
||||
const vectorField& wallShearStress() const;
|
||||
|
||||
//- Access to wall shear stress in IB cell
|
||||
// Note non-const access
|
||||
vectorField& tauWall() const
|
||||
{
|
||||
if (tauWall_.empty())
|
||||
{
|
||||
tauWall_.setSize
|
||||
(
|
||||
this->ibPatch().ibCells().size(),
|
||||
vector::zero
|
||||
);
|
||||
}
|
||||
|
||||
return tauWall_;
|
||||
}
|
||||
|
||||
//- Access to indicator on fixed values. Note non-const access
|
||||
boolList& wallMask() const
|
||||
{
|
||||
if (wallMask_.empty())
|
||||
{
|
||||
wallMask_.setSize
|
||||
(
|
||||
this->ibPatch().ibCells().size(),
|
||||
false
|
||||
);
|
||||
}
|
||||
|
||||
return wallMask_;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace RASModels
|
||||
} // End namespace incompressible
|
||||
} // End namespace Foam
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
|
@ -0,0 +1,183 @@
|
|||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright held by original author
|
||||
\\/ 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 2 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, write to the Free Software Foundation,
|
||||
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "immersedBoundaryWallFunctionFvPatchField.H"
|
||||
#include "fvPatchFieldMapper.H"
|
||||
#include "addToRunTimeSelectionTable.H"
|
||||
#include "wallFvPatch.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
namespace incompressible
|
||||
{
|
||||
namespace RASModels
|
||||
{
|
||||
|
||||
// * * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * //
|
||||
|
||||
template<class Type>
|
||||
void immersedBoundaryWallFunctionFvPatchField<Type>::motionUpdate() const
|
||||
{
|
||||
wallValue_.clear();
|
||||
wallMask_.clear();
|
||||
|
||||
immersedBoundaryFvPatchField<Type>::motionUpdate();
|
||||
}
|
||||
|
||||
|
||||
template<class Type>
|
||||
void immersedBoundaryWallFunctionFvPatchField<Type>::setIbCellValues
|
||||
(
|
||||
const Field<Type>& ibcValues
|
||||
) const
|
||||
{
|
||||
const labelList& ibc = this->ibPatch().ibCells();
|
||||
|
||||
if (ibcValues.size() != ibc.size())
|
||||
{
|
||||
FatalErrorIn
|
||||
(
|
||||
"template<class Type>\n"
|
||||
"void immersedBoundaryWallFunctionFvPatchField<Type>::"
|
||||
"setIbCellValues\n"
|
||||
"(\n"
|
||||
" const Field<Type>& ibcValues\n"
|
||||
") const"
|
||||
) << "Size of ibcValues field not equal to the number of IB cells."
|
||||
<< nl << "ibcValues: " << ibcValues.size()
|
||||
<< " ibc: " << ibc.size()
|
||||
<< abort(FatalError);
|
||||
}
|
||||
|
||||
// Get non-const access to internal field
|
||||
Field<Type>& psiI = const_cast<Field<Type>&>(this->internalField());
|
||||
|
||||
if (wallValue_.empty() || wallMask_.empty())
|
||||
{
|
||||
immersedBoundaryFvPatchField<Type>::setIbCellValues(ibcValues);
|
||||
}
|
||||
else
|
||||
{
|
||||
forAll (ibcValues, cellI)
|
||||
{
|
||||
// If mask is set use the wall value, otherwise use the
|
||||
// fitted value
|
||||
if (wallMask_[cellI])
|
||||
{
|
||||
psiI[ibc[cellI]] = wallValue_[cellI];
|
||||
}
|
||||
else
|
||||
{
|
||||
psiI[ibc[cellI]] = ibcValues[cellI];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
template<class Type>
|
||||
immersedBoundaryWallFunctionFvPatchField<Type>::
|
||||
immersedBoundaryWallFunctionFvPatchField
|
||||
(
|
||||
const fvPatch& p,
|
||||
const DimensionedField<Type, volMesh>& iF
|
||||
)
|
||||
:
|
||||
immersedBoundaryFvPatchField<Type>(p, iF),
|
||||
wallValue_(),
|
||||
wallMask_()
|
||||
{}
|
||||
|
||||
|
||||
template<class Type>
|
||||
immersedBoundaryWallFunctionFvPatchField<Type>::
|
||||
immersedBoundaryWallFunctionFvPatchField
|
||||
(
|
||||
const fvPatch& p,
|
||||
const DimensionedField<Type, volMesh>& iF,
|
||||
const dictionary& dict
|
||||
)
|
||||
:
|
||||
immersedBoundaryFvPatchField<Type>(p, iF, dict),
|
||||
wallValue_(),
|
||||
wallMask_()
|
||||
{}
|
||||
|
||||
|
||||
template<class Type>
|
||||
immersedBoundaryWallFunctionFvPatchField<Type>::
|
||||
immersedBoundaryWallFunctionFvPatchField
|
||||
(
|
||||
const immersedBoundaryWallFunctionFvPatchField& ptf,
|
||||
const fvPatch& p,
|
||||
const DimensionedField<Type, volMesh>& iF,
|
||||
const fvPatchFieldMapper& mapper
|
||||
)
|
||||
:
|
||||
immersedBoundaryFvPatchField<Type>(ptf, p, iF, mapper),
|
||||
wallValue_(),
|
||||
wallMask_()
|
||||
{}
|
||||
|
||||
|
||||
template<class Type>
|
||||
immersedBoundaryWallFunctionFvPatchField<Type>::
|
||||
immersedBoundaryWallFunctionFvPatchField
|
||||
(
|
||||
const immersedBoundaryWallFunctionFvPatchField& tkqrwfpf
|
||||
)
|
||||
:
|
||||
immersedBoundaryFvPatchField<Type>(tkqrwfpf),
|
||||
wallValue_(),
|
||||
wallMask_()
|
||||
{}
|
||||
|
||||
|
||||
template<class Type>
|
||||
immersedBoundaryWallFunctionFvPatchField<Type>::
|
||||
immersedBoundaryWallFunctionFvPatchField
|
||||
(
|
||||
const immersedBoundaryWallFunctionFvPatchField& tkqrwfpf,
|
||||
const DimensionedField<Type, volMesh>& iF
|
||||
)
|
||||
:
|
||||
immersedBoundaryFvPatchField<Type>(tkqrwfpf, iF),
|
||||
wallValue_(),
|
||||
wallMask_()
|
||||
{}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace RASModels
|
||||
} // End namespace incompressible
|
||||
} // End namespace Foam
|
||||
|
||||
// ************************************************************************* //
|
Some files were not shown because too many files have changed in this diff Show more
Reference in a new issue