INT: Integration of isoAdvector and supporting material

Community contribution from Johan Roenby, DHI

IsoAdvector is a geometric Volume-of-Fluid method for advection of a
sharp interface between two incompressible fluids. It works on both
structured and unstructured meshes with no requirements on cell shapes.
IsoAdvector is as an alternative choice for the interface compression
treatment with the MULES limiter implemented in the interFoam family
of solvers.

The isoAdvector concept and code was developed at DHI and was funded
by a Sapere Aude postdoc grant to Johan Roenby from The Danish Council
for Independent Research | Technology and Production Sciences (Grant-ID:
DFF - 1337-00118B - FTP).
Co-funding is also provided by the GTS grant to DHI from the Danish
Agency for Science, Technology and Innovation.

The ideas behind and performance of the isoAdvector scheme is
documented in:

    Roenby J, Bredmose H, Jasak H. 2016 A computational method for sharp
    interface  advection. R. Soc. open sci. 3: 160405.
    [http://dx.doi.org/10.1098/rsos.160405](http://dx.doi.org/10.1098/rsos.160405)

Videos showing isoAdvector's performance with a number of standard
test cases can be found in this youtube channel:

    https://www.youtube.com/channel/UCt6Idpv4C8TTgz1iUX0prAA

Project contributors:

* Johan Roenby <jro@dhigroup.com> (Inventor and main developer)
* Hrvoje Jasak <hrvoje.jasak@fsb.hr> (Consistent treatment of
  boundary faces including processor boundaries, parallelisation,
  code clean up
* Henrik Bredmose <hbre@dtu.dk> (Assisted in the conceptual
  development)
* Vuko Vukcevic <vuko.vukcevic@fsb.hr> (Code review, profiling,
  porting to foam-extend, bug fixing, testing)
* Tomislav Maric <tomislav@sourceflux.de> (Source file
  rearrangement)
* Andy Heather <a.heather@opencfd.co.uk> (Integration into OpenFOAM
  for v1706 release)

See the integration repository below to see the full set of changes
implemented for release into OpenFOAM v1706

    https://develop.openfoam.com/Community/Integration-isoAdvector
This commit is contained in:
Andrew Heather
2017-06-20 14:36:15 +01:00
parent 614b33f3e1
commit a6ef8b9027
121 changed files with 8643 additions and 0 deletions

View File

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

View File

@ -0,0 +1,20 @@
EXE_INC = \
-I$(LIB_SRC)/transportModels/twoPhaseMixture/lnInclude \
-I$(LIB_SRC)/transportModels \
-I$(LIB_SRC)/transportModels/incompressible/lnInclude \
-I$(LIB_SRC)/transportModels/interfaceProperties/lnInclude \
-I$(LIB_SRC)/TurbulenceModels/turbulenceModels/lnInclude \
-I$(LIB_SRC)/TurbulenceModels/incompressible/lnInclude \
-I$(LIB_SRC)/transportModels/immiscibleIncompressibleTwoPhaseMixture/lnInclude \
-I$(LIB_SRC)/finiteVolume/lnInclude \
-I$(LIB_SRC)/meshTools/lnInclude \
-I$(LIB_SRC)/sampling/lnInclude
EXE_LIBS = \
-limmiscibleIncompressibleTwoPhaseMixture \
-lturbulenceModels \
-lincompressibleTurbulenceModels \
-lfiniteVolume \
-lfvOptions \
-lmeshTools \
-lsampling

View File

@ -0,0 +1,33 @@
MRF.correctBoundaryVelocity(U);
fvVectorMatrix UEqn
(
fvm::ddt(rho, U) + fvm::div(rhoPhi, U)
+ MRF.DDt(rho, U)
+ turbulence->divDevRhoReff(rho, U)
==
fvOptions(rho, U)
);
UEqn.relax();
fvOptions.constrain(UEqn);
if (pimple.momentumPredictor())
{
solve
(
UEqn
==
fvc::reconstruct
(
(
mixture.surfaceTensionForce()
- ghf*fvc::snGrad(rho)
- fvc::snGrad(p_rgh)
) * mesh.magSf()
)
);
fvOptions.correct(U);
}

View File

@ -0,0 +1,4 @@
const dictionary& alphaControls = mesh.solverDict(alpha1.name());
label nAlphaSubCycles(readLabel(alphaControls.lookup("nAlphaSubCycles")));

View File

@ -0,0 +1,57 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Global
alphaCourantNo
Description
Calculates and outputs the mean and maximum Courant Numbers.
\*---------------------------------------------------------------------------*/
scalar maxAlphaCo
(
readScalar(runTime.controlDict().lookup("maxAlphaCo"))
);
scalar alphaCoNum = 0.0;
scalar meanAlphaCoNum = 0.0;
if (mesh.nInternalFaces())
{
scalarField sumPhi
(
mixture.nearInterface()().primitiveField()
*fvc::surfaceSum(mag(phi))().primitiveField()
);
alphaCoNum = 0.5*gMax(sumPhi/mesh.V().field())*runTime.deltaTValue();
meanAlphaCoNum =
0.5*(gSum(sumPhi)/gSum(mesh.V().field()))*runTime.deltaTValue();
}
Info<< "Interface Courant Number mean: " << meanAlphaCoNum
<< " max: " << alphaCoNum << endl;
// ************************************************************************* //

View File

@ -0,0 +1,35 @@
// If there are more than one outer corrector, we use a mixture of old and
// new U and phi for propagating alpha1 in all but the first outer iteration
if (!pimple.firstIter())
{
// We are recalculating alpha1 from the its old time value
alpha1 = alpha1.oldTime();
// Temporarily storing new U and phi values in prevIter storage
U.storePrevIter();
phi.storePrevIter();
// Overwriting new U and phi values with mixture of old and new values
phi = 0.5*(phi + phi.oldTime());
U = 0.5*(U + U.oldTime());
}
// Update alpha1
advector.advect();
// Update rhoPhi
rhoPhi = advector.getRhoPhi(rho1, rho2);
alpha2 = 1.0 - alpha1;
if (!pimple.firstIter())
{
// Restoring new U and phi values temporarily saved in prevIter() above
U = U.prevIter();
phi = phi.prevIter();
}
Info<< "Phase-1 volume fraction = "
<< alpha1.weightedAverage(mesh.Vsc()).value()
<< " Min(" << alpha1.name() << ") = " << min(alpha1).value()
<< " Max(" << alpha1.name() << ") - 1 = " << max(alpha1).value() - 1
<< endl;

View File

@ -0,0 +1,35 @@
if (nAlphaSubCycles > 1)
{
dimensionedScalar totalDeltaT = runTime.deltaT();
surfaceScalarField rhoPhiSum
(
IOobject
(
"rhoPhiSum",
runTime.timeName(),
mesh
),
mesh,
dimensionedScalar("0", rhoPhi.dimensions(), 0)
);
tmp<volScalarField> trSubDeltaT;
for
(
subCycle<volScalarField> alphaSubCycle(alpha1, nAlphaSubCycles);
!(++alphaSubCycle).end();
)
{
#include "alphaEqn.H"
rhoPhiSum += (runTime.deltaT()/totalDeltaT)*rhoPhi;
}
rhoPhi = rhoPhiSum;
}
else
{
#include "alphaEqn.H"
}
rho == alpha1*rho1 + alpha2*rho2;

View File

@ -0,0 +1,11 @@
CorrectPhi
(
U,
phi,
p_rgh,
dimensionedScalar("rAUf", dimTime/rho.dimensions(), 1),
geometricZeroField(),
pimple
);
#include "continuityErrs.H"

View File

@ -0,0 +1,123 @@
Info<< "Reading field p_rgh\n" << endl;
volScalarField p_rgh
(
IOobject
(
"p_rgh",
runTime.timeName(),
mesh,
IOobject::MUST_READ,
IOobject::AUTO_WRITE
),
mesh
);
Info<< "Reading field U\n" << endl;
volVectorField U
(
IOobject
(
"U",
runTime.timeName(),
mesh,
IOobject::MUST_READ,
IOobject::AUTO_WRITE
),
mesh
);
#include "createPhi.H"
Info<< "Reading transportProperties\n" << endl;
immiscibleIncompressibleTwoPhaseMixture mixture(U, phi);
volScalarField& alpha1(mixture.alpha1());
volScalarField& alpha2(mixture.alpha2());
const dimensionedScalar& rho1 = mixture.rho1();
const dimensionedScalar& rho2 = mixture.rho2();
// Need to store rho for ddt(rho, U)
volScalarField rho
(
IOobject
(
"rho",
runTime.timeName(),
mesh,
IOobject::READ_IF_PRESENT
),
alpha1*rho1 + alpha2*rho2
);
rho.oldTime();
// Mass flux
surfaceScalarField rhoPhi
(
IOobject
(
"rhoPhi",
runTime.timeName(),
mesh,
IOobject::NO_READ,
IOobject::NO_WRITE
),
fvc::interpolate(rho)*phi
);
// Construct incompressible turbulence model
autoPtr<incompressible::turbulenceModel> turbulence
(
incompressible::turbulenceModel::New(U, phi, mixture)
);
#include "readGravitationalAcceleration.H"
#include "readhRef.H"
#include "gh.H"
volScalarField p
(
IOobject
(
"p",
runTime.timeName(),
mesh,
IOobject::NO_READ,
IOobject::AUTO_WRITE
),
p_rgh + rho*gh
);
label pRefCell = 0;
scalar pRefValue = 0.0;
setRefCell
(
p,
p_rgh,
pimple.dict(),
pRefCell,
pRefValue
);
if (p_rgh.needReference())
{
p += dimensionedScalar
(
"p",
p.dimensions(),
pRefValue - getRefCellValue(p, pRefCell)
);
p_rgh = p - rho*gh;
}
mesh.setFluxRequired(p_rgh.name());
mesh.setFluxRequired(alpha1.name());
#include "createMRF.H"
#include "createIsoAdvection.H"

View File

@ -0,0 +1,10 @@
// Defining isoAdvection
isoAdvection advector(alpha1, phi, U);
bool frozenFlow = pimple.dict().lookupOrDefault<bool>("frozenFlow", false);
if (frozenFlow)
{
Info<< "Employing frozen-flow assumption: "
<< "pressure-velocity system will not be updated"
<< endl;
}

View File

@ -0,0 +1,143 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2017 OpenFOAM Foundation
\\/ M anipulation | Copyright (C) 2017 OpenCFD Ltd.
-------------------------------------------------------------------------------
isoAdvector | Copyright (C) 2016 DHI
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Application
interIsoFoam
Group
grpMultiphaseSolvers
Description
Solver derived from interFoam for 2 incompressible, isothermal immiscible
fluids using the iso-advector phase-fraction based interface capturing
approach.
The momentum and other fluid properties are of the "mixture" and a single
momentum equation is solved.
Turbulence modelling is generic, i.e. laminar, RAS or LES may be selected.
For a two-fluid approach see twoPhaseEulerFoam.
Reference:
\verbatim
Roenby, J., Bredmose, H. and Jasak, H. (2016).
A computational method for sharp interface advection
Royal Society Open Science, 3
doi 10.1098/rsos.160405
\endverbatim
isoAdvector code supplied by Johan Roenby, DHI (2016)
\*---------------------------------------------------------------------------*/
#include "isoAdvection.H"
#include "fvCFD.H"
#include "subCycle.H"
#include "immiscibleIncompressibleTwoPhaseMixture.H"
#include "turbulentTransportModel.H"
#include "pimpleControl.H"
#include "fvOptions.H"
#include "CorrectPhi.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
int main(int argc, char *argv[])
{
#include "postProcess.H"
#include "setRootCase.H"
#include "createTime.H"
#include "createMesh.H"
#include "createControl.H"
#include "createTimeControls.H"
#include "initContinuityErrs.H"
#include "createFields.H"
#include "createFvOptions.H"
#include "correctPhi.H"
turbulence->validate();
#include "readTimeControls.H"
#include "CourantNo.H"
#include "setInitialDeltaT.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
Info<< "\nStarting time loop\n" << endl;
while (runTime.run())
{
#include "readTimeControls.H"
#include "CourantNo.H"
#include "alphaCourantNo.H"
#include "setDeltaT.H"
runTime++;
Info<< "Time = " << runTime.timeName() << nl << endl;
// --- Pressure-velocity PIMPLE corrector loop
while (pimple.loop())
{
#include "alphaControls.H"
#include "alphaEqnSubCycle.H"
mixture.correct();
if (frozenFlow)
{
continue;
}
#include "UEqn.H"
// --- Pressure corrector loop
while (pimple.correct())
{
#include "pEqn.H"
}
if (pimple.turbCorr())
{
turbulence->correct();
}
}
runTime.write();
Info<< "ExecutionTime = " << runTime.elapsedCpuTime() << " s"
<< " ClockTime = " << runTime.elapsedClockTime() << " s"
<< nl << endl;
}
Info<< "End\n" << endl;
return 0;
}
// ************************************************************************* //

View File

@ -0,0 +1,67 @@
{
volScalarField rAU("rAU", 1.0/UEqn.A());
surfaceScalarField rAUf("rAUf", fvc::interpolate(rAU));
volVectorField HbyA(constrainHbyA(rAU*UEqn.H(), U, p_rgh));
surfaceScalarField phiHbyA
(
"phiHbyA",
fvc::flux(HbyA)
+ fvc::interpolate(rho*rAU)*fvc::ddtCorr(U, phi)
);
MRF.makeRelative(phiHbyA);
adjustPhi(phiHbyA, U, p_rgh);
surfaceScalarField phig
(
(
mixture.surfaceTensionForce()
- ghf*fvc::snGrad(rho)
)*rAUf*mesh.magSf()
// - ghf*(fvc::grad(rho) & mesh.Sf())*rAUf
);
phiHbyA += phig;
// Update the pressure BCs to ensure flux consistency
constrainPressure(p_rgh, U, phiHbyA, rAUf, MRF);
while (pimple.correctNonOrthogonal())
{
fvScalarMatrix p_rghEqn
(
fvm::laplacian(rAUf, p_rgh) == fvc::div(phiHbyA)
);
p_rghEqn.setReference(pRefCell, getRefCellValue(p_rgh, pRefCell));
p_rghEqn.solve(mesh.solver(p_rgh.select(pimple.finalInnerIter())));
if (pimple.finalNonOrthogonalIter())
{
phi = phiHbyA - p_rghEqn.flux();
p_rgh.relax();
U = HbyA + rAU*fvc::reconstruct((phig - p_rghEqn.flux())/rAUf);
U.correctBoundaryConditions();
fvOptions.correct(U);
}
}
#include "continuityErrs.H"
p == p_rgh + rho*gh;
if (p_rgh.needReference())
{
p += dimensionedScalar
(
"p",
p.dimensions(),
pRefValue - getRefCellValue(p, pRefCell)
);
p_rgh = p - rho*gh;
}
}

View File

@ -0,0 +1,53 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Global
setDeltaT
Description
Reset the timestep to maintain a constant maximum courant Number.
Reduction of time-step is immediate, but increase is damped to avoid
unstable oscillations.
\*---------------------------------------------------------------------------*/
if (adjustTimeStep)
{
scalar maxDeltaTFact =
min(maxCo/(CoNum + SMALL), maxAlphaCo/(alphaCoNum + SMALL));
scalar deltaTFact = min(min(maxDeltaTFact, 1.0 + 0.1*maxDeltaTFact), 1.2);
runTime.setDeltaT
(
min
(
deltaTFact*runTime.deltaTValue(),
maxDeltaT
)
);
Info<< "deltaT = " << runTime.deltaTValue() << endl;
}
// ************************************************************************* //

View File

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

View File

@ -0,0 +1,9 @@
EXE_INC = \
-I$(LIB_SRC)/finiteVolume/lnInclude \
-I$(LIB_SRC)/meshTools/lnInclude \
-I$(LIB_SRC)/sampling/lnInclude
EXE_LIBS = \
-lfiniteVolume \
-lmeshTools \
-lsampling

View File

@ -0,0 +1,191 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2017 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
isoAdvector | Copyright (C) 2016-2017 DHI
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Application
setAlphaField
Description
Uses isoCutCell to create a volume fraction field from either a cylinder,
a sphere or a plane.
Original code supplied by Johan Roenby, DHI (2016)
\*---------------------------------------------------------------------------*/
#include "fvCFD.H"
#include "isoCutFace.H"
#include "isoCutCell.H"
#include "Enum.H"
#include "mathematicalConstants.H"
using namespace Foam::constant;
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
class shapeSelector
{
public:
enum class shapeType
{
PLANE,
SPHERE,
CYLINDER,
SIN
};
static const Foam::Enum<shapeType> shapeTypeNames;
};
const Foam::Enum<shapeSelector::shapeType> shapeSelector::shapeTypeNames
{
{ shapeSelector::shapeType::PLANE, "plane" },
{ shapeSelector::shapeType::SPHERE, "sphere" },
{ shapeSelector::shapeType::CYLINDER, "cylinder" },
{ shapeSelector::shapeType::SIN, "sin" },
};
int main(int argc, char *argv[])
{
#include "setRootCase.H"
#include "createTime.H"
#include "createMesh.H"
Info<< "Reading setAlphaFieldDict\n" << endl;
IOdictionary dict
(
IOobject
(
"setAlphaFieldDict",
runTime.system(),
mesh,
IOobject::MUST_READ,
IOobject::NO_WRITE
)
);
const shapeSelector::shapeType surfType
(
shapeSelector::shapeTypeNames.read(dict.lookup("type"))
);
const vector centre(dict.lookup("centre"));
const word fieldName(dict.lookup("field"));
Info<< "Reading field " << fieldName << "\n" << endl;
volScalarField alpha1
(
IOobject
(
fieldName,
runTime.timeName(),
mesh,
IOobject::MUST_READ,
IOobject::AUTO_WRITE
),
mesh
);
scalar f0 = 0.0;
scalarField f(mesh.points().size());
Info<< "Processing type '" << shapeSelector::shapeTypeNames[surfType]
<< "'" << endl;
switch (surfType)
{
case shapeSelector::shapeType::PLANE:
{
const vector direction(dict.lookup("direction"));
f = -(mesh.points() - centre) & (direction/mag(direction));
f0 = 0.0;
break;
}
case shapeSelector::shapeType::SPHERE:
{
const scalar radius(readScalar(dict.lookup("radius")));
f = -mag(mesh.points() - centre);
f0 = -radius;
break;
}
case shapeSelector::shapeType::CYLINDER:
{
const scalar radius(readScalar(dict.lookup("radius")));
const vector direction(dict.lookup("direction"));
f = -sqrt
(
sqr(mag(mesh.points() - centre))
- sqr(mag((mesh.points() - centre) & direction))
);
f0 = -radius;
break;
}
case shapeSelector::shapeType::SIN:
{
const scalar period(readScalar(dict.lookup("period")));
const scalar amplitude(readScalar(dict.lookup("amplitude")));
const vector up(dict.lookup("up"));
const vector direction(dict.lookup("direction"));
const scalarField xx
(
(mesh.points() - centre) & direction/mag(direction)
);
const scalarField zz((mesh.points() - centre) & up/mag(up));
f = amplitude*Foam::sin(2*mathematical::pi*xx/period) - zz;
f0 = 0;
break;
}
}
// Define function on mesh points and isovalue
// Calculating alpha1 volScalarField from f = f0 isosurface
isoCutCell icc(mesh, f);
icc.volumeOfFluid(alpha1, f0);
// Writing volScalarField alpha1
ISstream::defaultPrecision(18);
alpha1.write();
Info<< nl << "Phase-1 volume fraction = "
<< alpha1.weightedAverage(mesh.Vsc()).value()
<< " Min(" << alpha1.name() << ") = " << min(alpha1).value()
<< " Max(" << alpha1.name() << ") - 1 = " << max(alpha1).value() - 1
<< nl << endl;
Info<< "End\n" << endl;
return 0;
}
// ************************************************************************* //

View File

@ -0,0 +1,24 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: plus |
| \\ / A nd | Web: www.OpenFOAM.com |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class dictionary;
location "system";
object fvSolution;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
field alpha.water;
type cylinder;
radius 0.25;
direction (0 1 0);
centre (0.5 0 0.5);
// ************************************************************************* //

View File

@ -238,6 +238,9 @@ fvMatrices/fvMatrices.C
fvMatrices/fvScalarMatrix/fvScalarMatrix.C
fvMatrices/solvers/MULES/MULES.C
fvMatrices/solvers/MULES/CMULES.C
fvMatrices/solvers/isoAdvection/isoCutCell/isoCutCell.C
fvMatrices/solvers/isoAdvection/isoCutFace/isoCutFace.C
fvMatrices/solvers/isoAdvection/isoAdvection/isoAdvection.C
fvMatrices/solvers/GAMGSymSolver/GAMGAgglomerations/faceAreaPairGAMGAgglomeration/faceAreaPairGAMGAgglomeration.C
interpolation = interpolation/interpolation

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,388 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2016-2017 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
isoAdvector | Copyright (C) 2016-2017 DHI
-------------------------------------------------------------------------------
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::isoAdvection
Description
Calculates the new VOF (alpha) field after time step dt given the initial
VOF field and a velocity field U and face fluxes phi. The fluid transport
calculation is based on an idea of using isosurfaces to estimate the
internal distribution of fluid in cells and advecting such isosurfaces
across the mesh faces with the velocity field interpolated to the
isosurfaces.
Reference:
\verbatim
Roenby, J., Bredmose, H. and Jasak, H. (2016).
A computational method for sharp interface advection
Royal Society Open Science, 3
doi 10.1098/rsos.160405
\endverbatim
Original code supplied by Johan Roenby, DHI (2016)
SourceFiles
isoAdvection.C
isoAdvectionTemplates.C
\*---------------------------------------------------------------------------*/
#ifndef isoAdvection_H
#define isoAdvection_H
#include "fvMesh.H"
#include "volFieldsFwd.H"
#include "surfaceFields.H"
#include "className.H"
#include "isoCutCell.H"
#include "isoCutFace.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class isoAdvection Declaration
\*---------------------------------------------------------------------------*/
class isoAdvection
{
// Private data types
typedef DynamicList<label> DynamicLabelList;
typedef DynamicList<scalar> DynamicScalarList;
typedef DynamicList<vector> DynamicVectorList;
typedef DynamicList<point> DynamicPointList;
// Private data
//- Reference to mesh
const fvMesh& mesh_;
//- Dictionary for isoAdvection controls
const dictionary dict_;
//- VOF field
volScalarField& alpha1_;
//- Often used reference to alpha1 internal field
scalarField& alpha1In_;
//- Reference to flux field
const surfaceScalarField& phi_;
//- Reference to velocity field
const volVectorField& U_;
//- Face volumetric water transport
surfaceScalarField dVf_;
//- Time spent performing interface advection
scalar advectionTime_;
// Point interpolation data
//- VOF field interpolated to mesh points
scalarField ap_;
// Switches and tolerances. Tolerances need to go into toleranceSwitches
//- Number of alpha bounding steps
label nAlphaBounds_;
//- Tolerance for search of isoFace giving specified VOF value
scalar vof2IsoTol_;
//- Tolerance for marking of surface cells:
// Those with surfCellTol_ < alpha1 < 1 - surfCellTol_
scalar surfCellTol_;
//- Switch controlling whether to use isoface normals for interface
// orientation (default corresponding to false) to base it on
// a smoothed gradient of alpha calculation (giving better results
// on tri on tet meshes).
bool gradAlphaBasedNormal_;
//- Print isofaces in a <case>/isoFaces/isoFaces_#N.vtk files.
// Intended for debugging
bool writeIsoFacesToFile_;
// Cell and face cutting
//- List of surface cells
DynamicLabelList surfCells_;
//- Cell cutting object
isoCutCell isoCutCell_;
//- Face cutting object
isoCutFace isoCutFace_;
//- Bool list for cells that have been touched by the bounding step
boolList cellIsBounded_;
//- True for all surface cells and their neighbours
boolList checkBounding_;
//- Storage for boundary faces downwind to a surface cell
DynamicLabelList bsFaces_;
//- Storage for boundary surface iso face centre
DynamicVectorList bsx0_;
//- Storage for boundary surface iso face normal
DynamicVectorList bsn0_;
//- Storage for boundary surface iso face speed
DynamicScalarList bsUn0_;
//- Storage for boundary surface iso value
DynamicScalarList bsf0_;
// Additional data for parallel runs
//- List of processor patch labels
DynamicLabelList procPatchLabels_;
//- For each patch if it is a processor patch this is a list of the
// face labels on this patch that are downwind to a surface cell.
// For non-processor patches the list will be empty.
List<DynamicLabelList> surfaceCellFacesOnProcPatches_;
// Private Member Functions
//- Disallow default bitwise copy construct
isoAdvection(const isoAdvection&);
//- Disallow default bitwise copy assignment
void operator=(const isoAdvection&);
// Advection functions
//- For each face calculate volumetric face transport during dt
void timeIntegratedFlux();
//- Calculate volumetric face transport during dt given the isoFace
// data provided as input for face facei
scalar timeIntegratedFaceFlux
(
const label facei,
const vector& x0,
const vector& n0,
const scalar Un0,
const scalar f0,
const scalar dt,
const scalar phi,
const scalar magSf
);
//- For a given cell return labels of faces fluxing out of this cell
// (based on sign of phi)
void setDownwindFaces
(
const label celli,
DynamicLabelList& downwindFaces
) const;
// Limit fluxes
void limitFluxes();
// Bound fluxes
void boundFromAbove
(
const scalarField& alpha1,
surfaceScalarField& dVfcorrected,
DynamicLabelList& correctedFaces
);
//- Given the face volume transport dVf calculates the total volume
// leaving a given cell. Note: cannot use dVf member because
// netFlux is called also for corrected dVf
scalar netFlux
(
const surfaceScalarField& dVf,
const label celli
) const;
//- Determine if a cell is a surface cell
bool isASurfaceCell(const label celli) const
{
return
(
surfCellTol_ < alpha1In_[celli]
&& alpha1In_[celli] < 1 - surfCellTol_
);
}
//- Clear out isoFace data
void clearIsoFaceData()
{
surfCells_.clear();
bsFaces_.clear();
bsx0_.clear();
bsn0_.clear();
bsUn0_.clear();
bsf0_.clear();
}
// Face value functions needed for random face access where the face
// can be either internal or boundary face
//- Return face value for a given Geometric surface field
template<typename Type>
Type faceValue
(
const GeometricField<Type, fvsPatchField, surfaceMesh>& f,
const label facei
) const;
//- Set face value for a given Geometric surface field
template<typename Type>
void setFaceValue
(
GeometricField<Type, fvsPatchField, surfaceMesh>& f,
const label facei,
const Type& value
) const;
// Parallel run handling functions
//- Synchronize dVf across processor boundaries using upwind value
void syncProcPatches
(
surfaceScalarField& dVf,
const surfaceScalarField& phi
);
//- Check if the face is on processor patch and append it to the
// list of surface cell faces on processor patches
void checkIfOnProcPatch(const label facei);
public:
//- Runtime type information
TypeName("isoAdvection");
//- Constructors
//- Construct given alpha, phi and velocity field. Note: phi should be
// divergence free up to a sufficient tolerance
isoAdvection
(
volScalarField& alpha1,
const surfaceScalarField& phi,
const volVectorField& U
);
//- Destructor
virtual ~isoAdvection()
{}
// Member functions
//- Advect the free surface. Updates alpha field, taking into account
// multiple calls within a single time step.
void advect();
//- Apply the bounding based on user inputs
void applyBruteForceBounding();
// Access functions
//- Return alpha field
const volScalarField& alpha() const
{
return alpha1_;
}
//- Return the controls dictionary
const dictionary& dict() const
{
return dict_;
}
//- Return cellSet of surface cells
void writeSurfaceCells() const;
//- Return cellSet of bounded cells
void writeBoundedCells() const;
//- Return mass flux
tmp<surfaceScalarField> getRhoPhi
(
const dimensionedScalar rho1,
const dimensionedScalar rho2
) const
{
return tmp<surfaceScalarField>
(
new surfaceScalarField
(
"rhoPhi",
(rho1 - rho2)*dVf_/mesh_.time().deltaT() + rho2*phi_
)
);
}
scalar advectionTime() const
{
return advectionTime_;
}
//- Write isoface points to .obj file
void writeIsoFaces
(
const DynamicList<List<point>>& isoFacePts
) const;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository
# include "isoAdvectionTemplates.C"
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,111 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2016-2017 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
isoAdvector | Copyright (C) 2016-2017 DHI
-------------------------------------------------------------------------------
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 "isoAdvection.H"
// ************************************************************************* //
template<typename Type>
Type Foam::isoAdvection::faceValue
(
const GeometricField<Type, fvsPatchField, surfaceMesh>& f,
const label facei
) const
{
if (mesh_.isInternalFace(facei))
{
return f.primitiveField()[facei];
}
else
{
const polyBoundaryMesh& pbm = mesh_.boundaryMesh();
// Boundary face. Find out which face of which patch
const label patchi = pbm.patchID()[facei - mesh_.nInternalFaces()];
if (patchi < 0 || patchi >= pbm.size())
{
FatalErrorInFunction
<< "Cannot find patch for face " << facei
<< abort(FatalError);
}
// Handle empty patches
const polyPatch& pp = pbm[patchi];
if (isA<emptyPolyPatch>(pp) || pp.empty())
{
return pTraits<Type>::zero;
}
const label patchFacei = pp.whichFace(facei);
return f.boundaryField()[patchi][patchFacei];
}
}
template<typename Type>
void Foam::isoAdvection::setFaceValue
(
GeometricField<Type, fvsPatchField, surfaceMesh>& f,
const label facei,
const Type& value
) const
{
if (mesh_.isInternalFace(facei))
{
f.primitiveFieldRef()[facei] = value;
}
else
{
const polyBoundaryMesh& pbm = mesh_.boundaryMesh();
// Boundary face. Find out which face of which patch
const label patchi = pbm.patchID()[facei - mesh_.nInternalFaces()];
if (patchi < 0 || patchi >= pbm.size())
{
FatalErrorInFunction
<< "Cannot find patch for face " << facei
<< abort(FatalError);
}
// Handle empty patches
const polyPatch& pp = pbm[patchi];
if (isA<emptyPolyPatch>(pp) || pp.empty())
{
return;
}
const label patchFacei = pp.whichFace(facei);
f.boundaryFieldRef()[patchi][patchFacei] = value;
}
}
// ************************************************************************* //

View File

@ -0,0 +1,709 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2016 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
isoAdvector | Copyright (C) 2016 DHI
-------------------------------------------------------------------------------
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 "isoCutCell.H"
#include "scalarMatrices.H"
#include "volFields.H"
#include "surfaceFields.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
int Foam::isoCutCell::debug = 0;
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::isoCutCell::isoCutCell(const fvMesh& mesh, scalarField& f)
:
mesh_(mesh),
cellI_(-1),
f_(f),
isoValue_(0),
isoCutFace_(isoCutFace(mesh_, f_)),
isoCutFaces_(10),
isoCutFacePoints_(10),
isoCutFaceCentres_(10),
isoCutFaceAreas_(10),
isoFaceEdges_(10),
isoFacePoints_(10),
isoFaceCentre_(vector::zero),
isoFaceArea_(vector::zero),
subCellCentre_(vector::zero),
subCellVolume_(-10),
VOF_(-10),
fullySubFaces_(10),
cellStatus_(-1),
subCellCentreAndVolumeCalculated_(false),
isoFaceCentreAndAreaCalculated_(false)
{
clearStorage();
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
void Foam::isoCutCell::calcSubCellCentreAndVolume()
{
if (cellStatus_ == 0)
{
subCellCentre_ = vector::zero;
subCellVolume_ = 0.0;
// Estimate the approximate cell centre as the average of face centres
label nCellFaces(1 + isoCutFaceCentres_.size() + fullySubFaces_.size());
vector cEst = isoFaceCentre_ + sum(isoCutFaceCentres_);
forAll(fullySubFaces_, facei)
{
cEst += mesh_.faceCentres()[fullySubFaces_[facei]];
}
cEst /= scalar(nCellFaces);
// Contribution to subcell centre and volume from isoface
const scalar pyr3Vol0 =
max(mag(isoFaceArea_ & (isoFaceCentre_ - cEst)), VSMALL);
// Calculate face-pyramid centre
const vector pc0 = 0.75*isoFaceCentre_ + 0.25*cEst;
// Accumulate volume-weighted face-pyramid centre
subCellCentre_ += pyr3Vol0*pc0;
// Accumulate face-pyramid volume
subCellVolume_ += pyr3Vol0;
// Contribution to subcell centre and volume from cut faces
forAll(isoCutFaceCentres_, facei)
{
// Calculate 3*face-pyramid volume
scalar pyr3Vol =
max
(
mag
(
isoCutFaceAreas_[facei]
& (isoCutFaceCentres_[facei] - cEst)
),
VSMALL
);
// Calculate face-pyramid centre
vector pc = 0.75*isoCutFaceCentres_[facei] + 0.25*cEst;
// Accumulate volume-weighted face-pyramid centre
subCellCentre_ += pyr3Vol*pc;
// Accumulate face-pyramid volume
subCellVolume_ += pyr3Vol;
}
// Contribution to subcell centre and volume from fully submerged faces
forAll(fullySubFaces_, i)
{
const label facei = fullySubFaces_[i];
const point& fCentre = mesh_.faceCentres()[facei];
const vector& fArea = mesh_.faceAreas()[facei];
// Calculate 3*face-pyramid volume
scalar pyr3Vol = max(mag(fArea & (fCentre - cEst)), VSMALL);
// Calculate face-pyramid centre
vector pc = 0.75*fCentre + 0.25*cEst;
// Accumulate volume-weighted face-pyramid centre
subCellCentre_ += pyr3Vol*pc;
// Accumulate face-pyramid volume
subCellVolume_ += pyr3Vol;
}
subCellCentre_ /= subCellVolume_;
subCellVolume_ /= scalar(3);
VOF_ = subCellVolume_/mesh_.cellVolumes()[cellI_];
subCellCentreAndVolumeCalculated_ = true;
if (debug)
{
vector sumSf = isoFaceArea_;
scalar sumMagSf = mag(isoFaceArea_);
forAll(isoCutFaceCentres_, facei)
{
sumSf += isoCutFaceAreas_[facei];
sumMagSf += mag(isoCutFaceAreas_[facei]);
}
forAll(fullySubFaces_, facei)
{
sumSf += mesh_.faceAreas()[fullySubFaces_[facei]];
sumMagSf += mag(isoCutFaceAreas_[facei]);
}
if (mag(sumSf) > 1e-10)
{
Pout<< "Warninig: mag(sumSf)/magSumSf = "
<< mag(sumSf)/sumMagSf << " for surface cell"
<< cellI_ << endl;
}
}
}
else if (cellStatus_ == 1)
{
// Cell fully above isosurface
subCellCentre_ = vector::zero;
subCellVolume_ = 0;
VOF_ = 0;
}
else if (cellStatus_ == -1)
{
// Cell fully below isosurface
subCellCentre_ = mesh_.cellCentres()[cellI_];
subCellVolume_ = mesh_.cellVolumes()[cellI_];
VOF_ = 1;
}
}
void Foam::isoCutCell::calcIsoFaceCentreAndArea()
{
// Initial guess of face centre from edge points
point fCentre = vector::zero;
label nEdgePoints = 0;
forAll(isoFaceEdges_, ei)
{
DynamicList<point>& edgePoints = isoFaceEdges_[ei];
forAll(edgePoints, pi)
{
fCentre += edgePoints[pi];
nEdgePoints++;
}
}
if (nEdgePoints > 0)
{
fCentre /= nEdgePoints;
}
else
{
DebugPout << "Warning: nEdgePoints = 0 for cell " << cellI_ << endl;
}
vector sumN = vector::zero;
scalar sumA = 0;
vector sumAc = vector::zero;
forAll(isoFaceEdges_, ei)
{
const DynamicList<point>& edgePoints = isoFaceEdges_[ei];
const label nPoints = edgePoints.size();
for (label pi = 0; pi < nPoints-1; pi++)
{
const point& nextPoint = edgePoints[pi + 1];
vector c = edgePoints[pi] + nextPoint + fCentre;
vector n = (nextPoint - edgePoints[pi])^(fCentre - edgePoints[pi]);
scalar a = mag(n);
// Edges may have different orientation
sumN += Foam::sign(n & sumN)*n;
sumA += a;
sumAc += a*c;
}
}
// This is to deal with zero-area faces. Mark very small faces
// to be detected in e.g., processorPolyPatch.
if (sumA < ROOTVSMALL)
{
isoFaceCentre_ = fCentre;
isoFaceArea_ = vector::zero;
}
else
{
isoFaceCentre_ = sumAc/sumA/scalar(3);
isoFaceArea_ = 0.5*sumN;
}
// Check isoFaceArea_ direction and change if not pointing out of subcell
if ((isoFaceArea_ & (isoFaceCentre_ - subCellCentre())) < 0)
{
isoFaceArea_ *= (-1);
}
isoFaceCentreAndAreaCalculated_ = true;
}
void Foam::isoCutCell::calcIsoFacePointsFromEdges()
{
DebugPout
<< "Enter calcIsoFacePointsFromEdges() with isoFaceArea_ = "
<< isoFaceArea_ << " and isoFaceCentre_ = " << isoFaceCentre_
<< " and isoFaceEdges_ = " << isoFaceEdges_ << endl;
// Defining local coordinates with zhat along isoface normal and xhat from
// isoface centre to first point in isoFaceEdges_
const vector zhat = isoFaceArea_/mag(isoFaceArea_);
vector xhat = isoFaceEdges_[0][0] - isoFaceCentre_;
xhat = (xhat - (xhat & zhat)*zhat);
xhat /= mag(xhat);
vector yhat = zhat^xhat;
yhat /= mag(yhat);
DebugPout << "Calculated local coordinates" << endl;
// Calculating isoface point angles in local coordinates
DynamicList<point> unsortedIsoFacePoints(3*isoFaceEdges_.size());
DynamicList<scalar> unsortedIsoFacePointAngles(3*isoFaceEdges_.size());
forAll(isoFaceEdges_, ei)
{
const DynamicList<point>& edgePoints = isoFaceEdges_[ei];
forAll(edgePoints, pi)
{
const point& p = edgePoints[pi];
unsortedIsoFacePoints.append(p);
unsortedIsoFacePointAngles.append
(
Foam::atan2
(
((p - isoFaceCentre_) & yhat),
((p - isoFaceCentre_) & xhat)
)
);
}
}
DebugPout<< "Calculated isoFace point angles" << endl;
// Sorting isoface points by angle and inserting into isoFacePoints_
labelList order(unsortedIsoFacePointAngles.size());
Foam::sortedOrder(unsortedIsoFacePointAngles, order);
isoFacePoints_.append(unsortedIsoFacePoints[order[0]]);
for (label pi = 1; pi < order.size(); pi++)
{
if
(
mag
(
unsortedIsoFacePointAngles[order[pi]]
-unsortedIsoFacePointAngles[order[pi-1]]
) > 1e-8
)
{
isoFacePoints_.append(unsortedIsoFacePoints[order[pi]]);
}
}
DebugPout<< "Sorted isoface points by angle" << endl;
}
Foam::label Foam::isoCutCell::calcSubCell
(
const label celli,
const scalar isoValue
)
{
// Populate isoCutFaces_, isoCutFacePoints_, fullySubFaces_, isoFaceCentres_
// and isoFaceArea_.
clearStorage();
cellI_ = celli;
isoValue_ = isoValue;
const cell& c = mesh_.cells()[celli];
forAll(c, fi)
{
const label facei = c[fi];
const label faceStatus = isoCutFace_.calcSubFace(facei, isoValue_);
if (faceStatus == 0)
{
// Face is cut
isoCutFacePoints_.append(isoCutFace_.subFacePoints());
isoCutFaceCentres_.append(isoCutFace_.subFaceCentre());
isoCutFaceAreas_.append(isoCutFace_.subFaceArea());
isoFaceEdges_.append(isoCutFace_.surfacePoints());
}
else if (faceStatus == -1)
{
// Face fully below
fullySubFaces_.append(facei);
}
}
if (isoCutFacePoints_.size())
{
// Cell cut at least at one face
cellStatus_ = 0;
calcIsoFaceCentreAndArea();
}
else if (fullySubFaces_.empty())
{
// Cell fully above isosurface
cellStatus_ = 1;
}
else
{
// Cell fully below isosurface
cellStatus_ = -1;
}
return cellStatus_;
}
const Foam::point& Foam::isoCutCell::subCellCentre()
{
if (!subCellCentreAndVolumeCalculated_)
{
calcSubCellCentreAndVolume();
}
return subCellCentre_;
}
Foam::scalar Foam::isoCutCell::subCellVolume()
{
if (!subCellCentreAndVolumeCalculated_)
{
calcSubCellCentreAndVolume();
}
return subCellVolume_;
}
const Foam::DynamicList<Foam::point>& Foam::isoCutCell::isoFacePoints()
{
if (cellStatus_ == 0 && isoFacePoints_.size() == 0)
{
calcIsoFacePointsFromEdges();
}
return isoFacePoints_;
}
const Foam::point& Foam::isoCutCell::isoFaceCentre()
{
if (!isoFaceCentreAndAreaCalculated_)
{
calcIsoFaceCentreAndArea();
}
return isoFaceCentre_;
}
const Foam::vector& Foam::isoCutCell::isoFaceArea()
{
if (!isoFaceCentreAndAreaCalculated_)
{
calcIsoFaceCentreAndArea();
}
return isoFaceArea_;
}
Foam::scalar Foam::isoCutCell::volumeOfFluid()
{
if (!subCellCentreAndVolumeCalculated_)
{
calcSubCellCentreAndVolume();
}
return VOF_;
}
Foam::scalar Foam::isoCutCell::isoValue() const
{
return isoValue_;
}
void Foam::isoCutCell::clearStorage()
{
cellI_ = -1;
isoValue_ = 0;
isoCutFace_.clearStorage();
isoCutFaces_.clear();
isoCutFacePoints_.clear();
isoCutFaceCentres_.clear();
isoCutFaceAreas_.clear();
isoFaceEdges_.clear();
isoFacePoints_.clear();
isoFaceCentre_ = vector::zero;
isoFaceArea_ = vector::zero;
subCellCentre_ = vector::zero;
subCellVolume_ = -10;
VOF_ = -10;
fullySubFaces_.clear();
cellStatus_ = -1;
subCellCentreAndVolumeCalculated_ = false;
isoFaceCentreAndAreaCalculated_ = false;
}
Foam::label Foam::isoCutCell::vofCutCell
(
const label celli,
const scalar alpha1,
const scalar tol,
const label maxIter
)
{
DebugInFunction
<< "vofCutCell for cell " << celli << " with alpha1 = "
<< alpha1 << " ------" << endl;
// Finding cell vertex extrema values
const labelList& pLabels = mesh_.cellPoints(celli);
scalarField fvert(pLabels.size());
forAll(pLabels, pi)
{
fvert[pi] = f_[pLabels[pi]];
}
labelList order(fvert.size());
sortedOrder(fvert, order);
scalar f1 = fvert[order.first()];
scalar f2 = fvert[order.last()];
DebugPout << "fvert = " << fvert << ", and order = " << order << endl;
// Handling special case where method is handed an almost full/empty cell
if (alpha1 < tol)
{
return calcSubCell(celli, f2);
}
else if (1 - alpha1 < tol)
{
return calcSubCell(celli, f1);
}
// Finding the two vertices inbetween which the isovalue giving alpha1 lies
label L1 = 0;
label L2 = fvert.size() - 1;
scalar a1 = 1;
scalar a2 = 0;
scalar L3, f3, a3;
while (L2 - L1 > 1)
{
L3 = round(0.5*(L1 + L2));
f3 = fvert[order[L3]];
calcSubCell(celli, f3);
a3 = volumeOfFluid();
if (a3 > alpha1)
{
L1 = L3; f1 = f3; a1 = a3;
}
else if (a3 < alpha1)
{
L2 = L3; f2 = f3; a2 = a3;
}
}
if (mag(f1 - f2) < 10*SMALL)
{
DebugPout<< "Warning: mag(f1 - f2) < 10*SMALL" << endl;
return calcSubCell(celli, f1);
}
if (mag(a1 - a2) < tol)
{
DebugPout<< "Warning: mag(a1 - a2) < tol for cell " << celli << endl;
return calcSubCell(celli, 0.5*(f1 + f2));
}
// Now we know that a(f) = alpha1 is to be found on the f interval
// [f1, f2], i.e. alpha1 will be in the interval [a2,a1]
DebugPout
<< "L1 = " << L1 << ", f1 = " << f1 << ", a1 = " << a1 << nl
<< "L2 = " << L2 << ", f2 = " << f2 << ", a2 = " << a2 << endl;
// Finding coefficients in 3 deg polynomial alpha(f) from 4 solutions
// Finding 2 additional points on 3 deg polynomial
f3 = f1 + (f2 - f1)/scalar(3);
calcSubCell(celli, f3);
a3 = volumeOfFluid();
scalar f4 = f1 + 2*(f2 - f1)/3;
calcSubCell(celli, f4);
scalar a4 = volumeOfFluid();
// Building and solving Vandermonde matrix equation
scalarField a(4), f(4), C(4);
{
a[0] = a1, a[1] = a3, a[2] = a4, a[3] = a2;
f[0] = 0, f[1] = (f3-f1)/(f2-f1), f[2] = (f4-f1)/(f2-f1), f[3] = 1;
scalarSquareMatrix M(4);
forAll(f, i)
{
forAll(f, j)
{
M[i][j] = pow(f[i], 3 - j);
}
}
// C holds the 4 polynomial coefficients
C = a;
LUsolve(M, C);
}
// Finding root with Newton method
f3 = f[1]; a3 = a[1];
label nIter = 0;
scalar res = mag(a3 - alpha1);
while (res > tol && nIter < 10*maxIter)
{
f3 -=
(C[0]*pow3(f3) + C[1]*sqr(f3) + C[2]*f3 + C[3] - alpha1)
/(3*C[0]*sqr(f3) + 2*C[1]*f3 + C[2]);
a3 = C[0]*pow3(f3) + C[1]*sqr(f3) + C[2]*f3 + C[3];
res = mag(a3 - alpha1);
nIter++;
}
// Scaling back to original range
f3 = f3*(f2 - f1) + f1;
// Check result
calcSubCell(celli, f3);
const scalar VOF = volumeOfFluid();
res = mag(VOF - alpha1);
if (res > tol)
{
DebugPout
<< "Newton obtained f3 = " << f3 << " and a3 = " << a3
<< " with mag(a3-alpha1) = " << mag(a3-alpha1)
<< " but calcSubCell(celli,f3) gives VOF = " << VOF << nl
<< "M(f)*C = a with " << nl
<< "f_scaled = " << f << nl
<< "f = " << f*(f2 - f1) + f1 << nl
<< "a = " << a << nl
<< "C = " << C << endl;
}
else
{
DebugPout<< "Newton did the job" << endl;
return cellStatus_;
}
// If tolerance not met use the secant method with f3 as a hopefully very
// good initial guess to crank res the last piece down below tol
scalar x2 = f3;
scalar g2 = VOF - alpha1;
scalar x1 = max(1e-3*(f2 - f1), 100*SMALL);
x1 = min(max(x1, f1), f2);
calcSubCell(celli, x1);
scalar g1 = volumeOfFluid() - alpha1;
nIter = 0;
scalar g0(0), x0(0);
while (res > tol && nIter < maxIter && g1 != g2)
{
x0 = (x2*g1 - x1*g2)/(g1 - g2);
calcSubCell(celli, x0);
g0 = volumeOfFluid() - alpha1;
res = mag(g0);
x2 = x1; g2 = g1;
x1 = x0; g1 = g0;
nIter++;
}
if (debug)
{
if (res < tol)
{
Pout<< "Bisection finished the job in " << nIter << " iterations."
<< endl;
}
else
{
Pout<< "Warning: Bisection not converged " << endl;
Pout<< "Leaving vofCutCell with f3 = " << f3 << " giving a3 = "
<< a3 << " so alpha1 - a3 = " << alpha1 - a3 << endl;
}
}
return cellStatus_;
}
void Foam::isoCutCell::volumeOfFluid
(
volScalarField& alpha1,
const scalar f0
)
{
// Setting internal field
scalarField& alphaIn = alpha1;
forAll(alphaIn, celli)
{
const label cellStatus = calcSubCell(celli, f0);
if (cellStatus != 1)
{
// If cell not entirely above isosurface
alphaIn[celli] = volumeOfFluid();
}
}
// Setting boundary alpha1 values
forAll(mesh_.boundary(), patchi)
{
if (mesh_.boundary()[patchi].size() > 0)
{
const label start = mesh_.boundary()[patchi].patch().start();
scalarField& alphap = alpha1.boundaryFieldRef()[patchi];
const scalarField& magSfp = mesh_.magSf().boundaryField()[patchi];
forAll(alphap, patchFacei)
{
const label facei = patchFacei + start;
const label faceStatus = isoCutFace_.calcSubFace(facei, f0);
if (faceStatus != 1)
{
// Face not entirely above isosurface
alphap[patchFacei] =
mag(isoCutFace_.subFaceArea())/magSfp[patchFacei];
}
}
}
}
}
// ************************************************************************* //

View File

@ -0,0 +1,200 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2016 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
isoAdvector | Copyright (C) 2016 DHI
-------------------------------------------------------------------------------
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::isoCutCell
Description
Class for cutting a cell, celli, of an fvMesh, mesh_, at its intersection
with an isosurface defined by the mesh point values f_ and the isovalue,
isoValue_.
Reference:
\verbatim
Roenby, J., Bredmose, H. and Jasak, H. (2016).
A computational method for sharp interface advection
Royal Society Open Science, 3
doi 10.1098/rsos.160405
\endverbatim
Original code supplied by Johan Roenby, DHI (2016)
SourceFiles
isoCutCell.C
\*---------------------------------------------------------------------------*/
#ifndef isoCutCell_H
#define isoCutCell_H
#include "fvMesh.H"
#include "volFieldsFwd.H"
#include "isoCutFace.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class isoCutCell Declaration
\*---------------------------------------------------------------------------*/
class isoCutCell
{
// Private data
//- Mesh whose cells and faces to cut at their intersection with an
// isosurface.
const fvMesh& mesh_;
//- Cell to cut
label cellI_;
//- Isofunction values at mesh points. f_size() = mesh_.nPoints().
scalarField& f_;
//- Isovalue used to cut cell
scalar isoValue_;
//- An isoCutFace object to get access to its face cutting functionality
isoCutFace isoCutFace_;
//- List of face labels of isoCutFaces
DynamicList<label> isoCutFaces_;
//- List of point lists each defining an isoCutFace
DynamicList<DynamicList<point>> isoCutFacePoints_;
//- List of face centres for isoCutFaces
DynamicList<point> isoCutFaceCentres_;
//- List of face area vectors for isoCutFaces
DynamicList<vector> isoCutFaceAreas_;
//- Storage for subFace edges belonging to isoFace
DynamicList<DynamicList<point>> isoFaceEdges_;
//- Points constituting the cell-isosurface intersection (isoface)
DynamicList<point> isoFacePoints_;
//- Face centre of the isoface
point isoFaceCentre_;
//- Face normal of the isoface by convention pointing from high to low
// values (i.e. opposite of the gradient vector).
vector isoFaceArea_;
//- Cell centre of the subcell of celli which is "fully submerged", i.e.
// where the function value is higher than the isoValue_
point subCellCentre_;
//- Volume of fully submerged subcell
scalar subCellVolume_;
//- Volume of Fluid for celli (subCellVolume_/mesh_.V()[celli])
scalar VOF_;
//- List of fully submerged faces
DynamicList<label> fullySubFaces_;
//- A cell status label taking one of the values:
//
// - -1: cell is fully below the isosurface
// - 0: cell is cut
// - +1: cell is fully above the isosurface
label cellStatus_;
//- Boolean telling if subcell centre and volume have been calculated
bool subCellCentreAndVolumeCalculated_;
//- Boolean telling if isoface centre and area have been calculated
bool isoFaceCentreAndAreaCalculated_;
// Private Member Functions
void calcSubCellCentreAndVolume();
void calcIsoFaceCentreAndArea();
void calcIsoFacePointsFromEdges();
public:
// Constructors
//- Construct from fvMesh and a scalarField
// Length of scalarField should equal number of mesh points
isoCutCell(const fvMesh&, scalarField&);
// Static data
static int debug;
// Member functions
label calcSubCell(const label celli, const scalar isoValue);
const point& subCellCentre();
scalar subCellVolume();
const DynamicList<point>& isoFacePoints();
const point& isoFaceCentre();
const vector& isoFaceArea();
scalar volumeOfFluid();
scalar isoValue() const;
void clearStorage();
label vofCutCell
(
const label celli,
const scalar alpha1,
const scalar tol,
const label maxIter
);
void volumeOfFluid(volScalarField& alpha1, const scalar f0);
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,629 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2016 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
isoAdvector | Copyright (C) 2016 DHI
-------------------------------------------------------------------------------
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 "isoCutFace.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
int Foam::isoCutFace::debug = 0;
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::isoCutFace::isoCutFace
(
const fvMesh& mesh,
scalarField& f
)
:
mesh_(mesh),
f_(f),
firstEdgeCut_(-1),
lastEdgeCut_(-1),
firstFullySubmergedPoint_(-1),
nFullySubmergedPoints_(0),
subFaceCentre_(vector::zero),
subFaceArea_(vector::zero),
subFacePoints_(10),
surfacePoints_(4),
subFaceCentreAndAreaIsCalculated_(false)
{
clearStorage();
}
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
void Foam::isoCutFace::calcSubFaceCentreAndArea()
{
const label nPoints = subFacePoints_.size();
// If the face is a triangle, do a direct calculation for efficiency
// and to avoid round-off error-related problems
if (nPoints == 3)
{
subFaceCentre_ = sum(subFacePoints_)/scalar(3);
subFaceArea_ =
0.5
*(
(subFacePoints_[1] - subFacePoints_[0])
^(subFacePoints_[2] - subFacePoints_[0])
);
}
else if (nPoints > 0)
{
vector sumN = vector::zero;
scalar sumA = 0.0;
vector sumAc = vector::zero;
const point fCentre = sum(subFacePoints_)/scalar(nPoints);
for (label pi = 0; pi < nPoints; pi++)
{
const point& nextPoint = subFacePoints_[subFacePoints_.fcIndex(pi)];
vector c = subFacePoints_[pi] + nextPoint + fCentre;
vector n =
(nextPoint - subFacePoints_[pi])^(fCentre - subFacePoints_[pi]);
scalar a = magSqr(n);
sumN += n;
sumA += a;
sumAc += a*c;
}
// This is to deal with zero-area faces. Mark very small faces
// to be detected in e.g., processorPolyPatch.
if (sumA < ROOTVSMALL)
{
subFaceCentre_ = fCentre;
subFaceArea_ = vector::zero;
}
else
{
subFaceCentre_ = (1.0/3.0)*sumAc/sumA;
subFaceArea_ = 0.5*sumN;
}
}
subFaceCentreAndAreaIsCalculated_ = true;
}
Foam::label Foam::isoCutFace::calcSubFace
(
const scalar isoValue,
const pointField& points,
const scalarField& f,
const labelList& pLabels
)
{
// Face status set to one of the values:
// -1: face is fully below the isosurface
// 0: face is cut, i.e. has values larger and smaller than isoValue
// +1: face is fully above the isosurface
label faceStatus;
label pl1 = pLabels[0];
scalar f1 = f[pl1];
// If vertex values are very close to isoValue lift them slightly to avoid
// dealing with the many special cases of a face being touched either at a
// single point, along an edge, or the entire face being on the surface.
if (mag(f1 - isoValue) < 10*SMALL)
{
f1 += sign(f1 - isoValue)*10*SMALL;
}
// Finding cut edges, the point along them where they are cut, and all fully
// submerged face points.
forAll(pLabels, pi)
{
label pl2 = pLabels[pLabels.fcIndex(pi)];
scalar f2 = f[pl2];
if (mag(f2 - isoValue) < 10*SMALL)
{
f2 += sign(f2 - isoValue)*10*SMALL;
}
if (f1 > isoValue)
{
nFullySubmergedPoints_ += 1;
if (f2 < isoValue)
{
lastEdgeCut_ = (isoValue - f1)/(f2 - f1);
}
}
else if (f1 < isoValue && f2 > isoValue)
{
if (firstFullySubmergedPoint_ == -1)
{
firstFullySubmergedPoint_ = pLabels.fcIndex(pi);
firstEdgeCut_ = (isoValue - f1)/(f2 - f1);
}
else
{
if (debug)
{
const face fl(pLabels);
WarningInFunction
<< "More than two face cuts for face " << fl
<< endl;
Pout<< "Face values: f-isoValue = " << endl;
forAll(fl, fpi)
{
Pout<< f[fl[fpi]] - isoValue << " ";
}
Pout<< " " << endl;
}
}
}
pl1 = pl2;
f1 = f2;
}
if (firstFullySubmergedPoint_ != -1)
{
// Face is cut
faceStatus = 0;
subFacePoints(points, pLabels);
}
else if (f1 < isoValue)
{
// Face entirely above isosurface
faceStatus = 1;
}
else
{
// Face entirely below isosurface
faceStatus = -1;
}
return faceStatus;
}
void Foam::isoCutFace::subFacePoints
(
const pointField& points,
const labelList& pLabels
)
{
const label nPoints = pLabels.size();
surfacePoints(points, pLabels);
forAll(surfacePoints_, pi)
{
subFacePoints_.append(surfacePoints_[pi]);
}
for (label pi = 0; pi < nFullySubmergedPoints_; pi++)
{
subFacePoints_.append
(
points[pLabels[(firstFullySubmergedPoint_ + pi) % nPoints]]
);
}
}
void Foam::isoCutFace::surfacePoints
(
const pointField& points,
const labelList& pLabels
)
{
const label nPoints = pLabels.size();
const label n = firstFullySubmergedPoint_ + nFullySubmergedPoints_;
label pl1 = pLabels[(n - 1) % nPoints];
label pl2 = pLabels[n % nPoints];
surfacePoints_.append
(
points[pl1] + lastEdgeCut_*(points[pl2] - points[pl1])
);
pl1 = pLabels[(firstFullySubmergedPoint_ - 1 + nPoints) % nPoints];
pl2 = pLabels[firstFullySubmergedPoint_];
surfacePoints_.append
(
points[pl1] + firstEdgeCut_*(points[pl2] - points[pl1])
);
}
// * * * * * * * * * * * Public Member Functions * * * * * * * * * * * * * //
Foam::label Foam::isoCutFace::calcSubFace
(
const label faceI,
const scalar isoValue
)
{
clearStorage();
const labelList& pLabels = mesh_.faces()[faceI];
const pointField& points = mesh_.points();
return calcSubFace(isoValue, points, f_, pLabels);
}
Foam::label Foam::isoCutFace::calcSubFace
(
const pointField& points,
const scalarField& f,
const scalar isoValue
)
{
clearStorage();
const labelList pLabels(identity(f.size()));
return calcSubFace(isoValue, points, f, pLabels);
}
const Foam::point& Foam::isoCutFace::subFaceCentre()
{
if (!subFaceCentreAndAreaIsCalculated_)
{
calcSubFaceCentreAndArea();
}
return subFaceCentre_;
}
const Foam::vector& Foam::isoCutFace::subFaceArea()
{
if (!subFaceCentreAndAreaIsCalculated_)
{
calcSubFaceCentreAndArea();
}
return subFaceArea_;
}
const Foam::DynamicList<Foam::point>& Foam::isoCutFace::subFacePoints() const
{
return subFacePoints_;
}
const Foam::DynamicList<Foam::point>& Foam::isoCutFace::surfacePoints() const
{
return surfacePoints_;
}
void Foam::isoCutFace::clearStorage()
{
firstEdgeCut_ = -1;
lastEdgeCut_ = -1;
firstFullySubmergedPoint_ = -1;
nFullySubmergedPoints_ = 0;
subFaceCentre_ = vector::zero;
subFaceArea_ = vector::zero;
subFacePoints_.clear();
surfacePoints_.clear();
subFaceCentreAndAreaIsCalculated_ = false;
}
Foam::scalar Foam::isoCutFace::timeIntegratedArea
(
const pointField& fPts,
const scalarField& pTimes,
const scalar dt,
const scalar magSf,
const scalar Un0
)
{
// Initialise time integrated area returned by this function
scalar tIntArea = 0.0;
// Finding ordering of vertex points
labelList order(pTimes.size());
sortedOrder(pTimes, order);
const scalar firstTime = pTimes[order.first()];
const scalar lastTime = pTimes[order.last()];
// Dealing with case where face is not cut by surface during time interval
// [0,dt] because face was already passed by surface
if (lastTime <= 0)
{
// If all face cuttings were in the past and cell is filling up (Un0>0)
// then face must be full during whole time interval
tIntArea = magSf*dt*pos(Un0);
return tIntArea;
}
// Dealing with case where face is not cut by surface during time interval
// [0, dt] because dt is too small for surface to reach closest face point
if (firstTime >= dt)
{
// If all cuttings are in the future but non of them within [0,dt] then
// if cell is filling up (Un0 > 0) face must be empty during whole time
// interval
tIntArea = magSf*dt*(1 - pos(Un0));
return tIntArea;
}
// If we reach this point in the code some part of the face will be swept
// during [tSmall, dt-tSmall]. However, it may be the case that there are no
// vertex times within the interval. This will happen sometimes for small
// time steps where both the initial and the final face-interface
// intersection line (FIIL) will be along the same two edges.
// Face-interface intersection line (FIIL) to be swept across face
DynamicList<point> FIIL(3);
// Submerged area at beginning of each sub time interval time
scalar initialArea = 0.0;
//Running time keeper variable for the integration process
scalar time = 0.0;
// Special treatment of first sub time interval
if (firstTime > 0)
{
// If firstTime > 0 the face is uncut in the time interval
// [0, firstTime] and hence fully submerged in fluid A or B.
// If Un0 > 0 cell is filling up and it must initially be empty.
// If Un0 < 0 cell must initially be full(y immersed in fluid A).
time = firstTime;
initialArea = magSf*(1.0 - pos(Un0));
tIntArea = initialArea*time;
cutPoints(fPts, pTimes, time, FIIL);
}
else
{
// If firstTime <= 0 then face is initially cut and we must
// calculate the initial submerged area and FIIL:
time = 0.0;
// Note: calcSubFace assumes well-defined 2-point FIIL!!!!
calcSubFace(fPts, -sign(Un0)*pTimes, time);
initialArea = mag(subFaceArea());
cutPoints(fPts, pTimes, time, FIIL);
}
// Making sorted array of all vertex times that are between max(0,firstTime)
// and dt and further than tSmall from the previous time.
DynamicList<scalar> sortedTimes(pTimes.size());
{
scalar prevTime = time;
const scalar tSmall = max(1e-6*dt, 10*SMALL);
forAll(order, ti)
{
const scalar timeI = pTimes[order[ti]];
if ( timeI > prevTime + tSmall && timeI <= dt)
{
sortedTimes.append(timeI);
prevTime = timeI;
}
}
}
// Sweeping all quadrilaterals corresponding to the intervals defined above
forAll(sortedTimes, ti)
{
const scalar newTime = sortedTimes[ti];
// New face-interface intersection line
DynamicList<point> newFIIL(3);
cutPoints(fPts, pTimes, newTime, newFIIL);
// quadrilateral area coefficients
scalar alpha = 0, beta = 0;
quadAreaCoeffs(FIIL, newFIIL, alpha, beta);
// Integration of area(t) = A*t^2+B*t from t = 0 to 1
tIntArea += (newTime - time)*
(initialArea + sign(Un0)*(alpha/3.0 + 0.5*beta));
// Adding quad area to submerged area
initialArea += sign(Un0)*(alpha + beta);
FIIL = newFIIL;
time = newTime;
}
// Special treatment of last time interval
if (lastTime > dt)
{
// FIIL will end up cutting the face at dt
// New face-interface intersection line
DynamicList<point> newFIIL(3);
cutPoints(fPts, pTimes, dt, newFIIL);
// quadrilateral area coefficients
scalar alpha = 0, beta = 0;
quadAreaCoeffs(FIIL, newFIIL, alpha, beta);
// Integration of area(t) = A*t^2+B*t from t = 0 to 1
tIntArea += (dt - time)*
(initialArea + sign(Un0)*(alpha/3.0 + 0.5*beta));
}
else
{
// FIIL will leave the face at lastTime and face will be fully in fluid
// A or fluid B in the time interval from lastTime to dt.
tIntArea += magSf*(dt - lastTime)*pos(Un0);
}
return tIntArea;
}
void Foam::isoCutFace::cutPoints
(
const pointField& pts,
const scalarField& f,
const scalar f0,
DynamicList<point>& cutPoints
)
{
const label nPoints = pts.size();
scalar f1(f[0]);
// Snapping vertex value to f0 if very close (needed for 2D cases)
if (mag(f1 - f0) < 10*SMALL)
{
f1 = f0;
}
forAll(pts, pi)
{
label pi2 = (pi + 1) % nPoints;
scalar f2 = f[pi2];
// Snapping vertex value
if (mag(f2 - f0) < 10*SMALL)
{
f2 = f0;
}
if ((f1 < f0 && f2 > f0) || (f1 > f0 && f2 < f0))
{
const scalar s = (f0 - f1)/(f2 - f1);
cutPoints.append(pts[pi] + s*(pts[pi2] - pts[pi]));
}
else if (f1 == f0)
{
cutPoints.append(pts[pi]);
}
f1 = f2;
}
if (cutPoints.size() > 2)
{
WarningInFunction << "cutPoints = " << cutPoints << " for pts = " << pts
<< ", f - f0 = " << f - f0 << " and f0 = " << f0 << endl;
}
}
void Foam::isoCutFace::quadAreaCoeffs
(
const DynamicList<point>& pf0,
const DynamicList<point>& pf1,
scalar& alpha,
scalar& beta
) const
{
// Number of points in provided face-interface intersection lines
const label np0 = pf0.size();
const label np1 = pf1.size();
// quad area coeffs such that area(t) = alpha*t^2 + beta*t.
// With time interval normalised, we have full quadArea = alpha + beta
// and time integrated quad area = alpha/3 + beta/2;
alpha = 0.0;
beta = 0.0;
if (np0 && np1)
{
// Initialising quadrilateral vertices A, B, C and D
vector A(pf0[0]);
vector C(pf1[0]);
vector B(pf0[0]);
vector D(pf1[0]);
if (np0 == 2)
{
B = pf0[1];
}
else if (np0 > 2)
{
WarningInFunction << "Vertex face was cut at pf0 = " << pf0 << endl;
}
if (np1 == 2)
{
D = pf1[1];
}
else if (np1 > 2)
{
WarningInFunction << "Vertex face was cut at pf1 = " << pf1 << endl;
}
// Swapping pf1 points if pf0 and pf1 point in same general direction
// (because we want a quadrilateral ABCD where pf0 = AB and pf1 = CD)
if (((B - A) & (D - C)) > 0)
{
vector tmp = D;
D = C;
C = tmp;
}
// Defining local coordinates (xhat, yhat) for area integration of swept
// quadrilateral ABCD such that A = (0,0), B = (Bx,0), C = (Cx,Cy) and
// D = (Dx,Dy) with Cy = 0 and Dy > 0.
const scalar Bx = mag(B - A);
vector xhat(vector::zero);
if (Bx > 10*SMALL)
{
// If |AB| > 0 ABCD we use AB to define xhat
xhat = (B - A)/mag(B - A);
}
else if (mag(C - D) > 10*SMALL)
{
// If |AB| ~ 0 ABCD is a triangle ACD and we use CD for xhat
xhat = (C - D)/mag(C - D);
}
else
{
return;
}
// Defining vertical axis in local coordinates
vector yhat = D - A;
yhat -= ((yhat & xhat)*xhat);
if (mag(yhat) > 10*SMALL)
{
yhat /= mag(yhat);
const scalar Cx = (C - A) & xhat;
const scalar Cy = mag((C - A) & yhat);
const scalar Dx = (D - A) & xhat;
const scalar Dy = mag((D - A) & yhat);
// area = ((Cx - Bx)*Dy - Dx*Cy)/6.0 + 0.25*Bx*(Dy + Cy);
alpha = 0.5*((Cx - Bx)*Dy - Dx*Cy);
beta = 0.5*Bx*(Dy + Cy);
}
}
else
{
WarningInFunction
<< "Vertex face was cut at " << pf0 << " and at " << pf1 << endl;
}
}
// ************************************************************************* //

View File

@ -0,0 +1,200 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2016 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
isoAdvector | Copyright (C) 2016 DHI
-------------------------------------------------------------------------------
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::isoCutFace
Description
Class for cutting a face, faceI, of an fvMesh, mesh_, at its intersection
with an isosurface defined by the mesh point values f_ and the isovalue,
isoValue_.
Reference:
\verbatim
Roenby, J., Bredmose, H. and Jasak, H. (2016).
A computational method for sharp interface advection
Royal Society Open Science, 3
doi 10.1098/rsos.160405
\endverbatim
Original code supplied by Johan Roenby, DHI (2016)
SourceFiles
isoCutFace.C
\*---------------------------------------------------------------------------*/
#ifndef isoCutFace_H
#define isoCutFace_H
#include "fvMesh.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class isoCutFaces Declaration
\*---------------------------------------------------------------------------*/
class isoCutFace
{
// Private data
//- Mesh whose cells and faces to cut at their intersection with an
// isoface
const fvMesh& mesh_;
//- Isofunction values at mesh points. f_size() = mesh_.nPoints()
scalarField& f_;
//- Point along first cut edge where isosurface cuts edge
scalar firstEdgeCut_;
//- Point along last cut edge where isosurface cuts edge
scalar lastEdgeCut_;
//- Index in mesh_.faces()[faceI_] of first fully submerged (f > f0)
// face point
label firstFullySubmergedPoint_;
//- Index in mesh_.faces()[faceI_] of last fully submerged (f > f0)
// face point
label nFullySubmergedPoints_;
//- Storage for centre of subface
point subFaceCentre_;
//- Storage for area vector of subface
vector subFaceArea_;
//- Storage for subFacePoints
DynamicList<point> subFacePoints_;
//- Storage for subFacePoints
DynamicList<point> surfacePoints_;
//- Boolean telling if subface centre and area have been calculated
bool subFaceCentreAndAreaIsCalculated_;
// Private Member Functions
void calcSubFaceCentreAndArea();
//- Calculate cut points along edges of face with values f[pLabels]
// Returns the face status, where:
// -1: face is fully below the isosurface
// 0: face is cut, i.e. has values larger and smaller than isoValue
// +1: face is fully above the isosurface
label calcSubFace
(
const scalar isoValue,
const pointField& points,
const scalarField& f,
const labelList& pLabels
);
void subFacePoints(const pointField& points, const labelList& pLabels);
void surfacePoints(const pointField& points, const labelList& pLabels);
public:
// Constructors
//- Construct from fvMesh and a scalarField
// Length of scalarField should equal number of mesh points
isoCutFace(const fvMesh& mesh, scalarField& f);
// Static data
static int debug;
// Member functions
//- Calculate cut points along edges of faceI
label calcSubFace(const label faceI, const scalar isoValue);
//- Calculate cut points along edges of face with values f
label calcSubFace
(
const pointField& points,
const scalarField& f,
const scalar isoValue
);
const point& subFaceCentre();
const vector& subFaceArea();
const DynamicList<point>& subFacePoints() const;
const DynamicList<point>& surfacePoints() const;
void clearStorage();
//- Calculate time integrated area for a face
scalar timeIntegratedArea
(
const pointField& fPts,
const scalarField& pTimes,
const scalar dt,
const scalar magSf,
const scalar Un0
);
void cutPoints
(
const pointField& pts,
const scalarField& f,
const scalar f0,
DynamicList<point>& cutPoints
);
void quadAreaCoeffs
(
const DynamicList<point>& pf0,
const DynamicList<point>& pf1,
scalar& alpha,
scalar& beta
) const;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -18,6 +18,8 @@ nearWallFields/findCellParticleCloud.C
processorField/processorField.C
readFields/readFields.C
setFlow/setFlow.C
streamLine/streamLine.C
streamLine/streamLineBase.C
streamLine/streamLineParticle.C

View File

@ -0,0 +1,448 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2017 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "setFlow.H"
#include "volFields.H"
#include "surfaceFields.H"
#include "fvcFlux.H"
#include "addToRunTimeSelectionTable.H"
#include "fvcSurfaceIntegrate.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
namespace functionObjects
{
defineTypeNameAndDebug(setFlow, 0);
addToRunTimeSelectionTable
(
functionObject,
setFlow,
dictionary
);
}
}
const Foam::Enum<Foam::functionObjects::setFlow::modeType>
Foam::functionObjects::setFlow::modeTypeNames
{
{ functionObjects::setFlow::modeType::FUNCTION, "function" },
{ functionObjects::setFlow::modeType::ROTATION, "rotation" },
{ functionObjects::setFlow::modeType::VORTEX2D, "vortex2D" },
{ functionObjects::setFlow::modeType::VORTEX3D, "vortex3D" }
};
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
void Foam::functionObjects::setFlow::setPhi(const volVectorField& U)
{
surfaceScalarField* phiptr =
mesh_.lookupObjectRefPtr<surfaceScalarField>(phiName_);
if (!phiptr)
{
return;
}
if (rhoName_ != "none")
{
const volScalarField* rhoptr =
mesh_.lookupObjectPtr<volScalarField>(rhoName_);
if (rhoptr)
{
const volScalarField& rho = *rhoptr;
*phiptr = fvc::flux(rho*U);
}
else
{
FatalErrorInFunction
<< "Unable to find rho field'" << rhoName_
<< "' in the mesh database. Available fields are:"
<< mesh_.names<volScalarField>()
<< exit(FatalError);
}
}
else
{
*phiptr = fvc::flux(U);
}
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::functionObjects::setFlow::setFlow
(
const word& name,
const Time& runTime,
const dictionary& dict
)
:
fvMeshFunctionObject(name, runTime, dict),
UName_("U"),
rhoName_("none"),
phiName_("phi"),
mode_(modeType::FUNCTION),
reverseTime_(VGREAT),
scalePtr_(nullptr),
origin_(vector::zero),
R_(tensor::I),
omegaPtr_(nullptr),
velocityPtr_(nullptr)
{
read(dict);
}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::functionObjects::setFlow::~setFlow()
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
bool Foam::functionObjects::setFlow::read(const dictionary& dict)
{
if (fvMeshFunctionObject::read(dict))
{
Info<< name() << ":" << endl;
mode_ = modeTypeNames.read(dict.lookup("mode"));
Info<< " operating mode: " << modeTypeNames[mode_] << endl;
if (dict.readIfPresent("U", UName_))
{
Info<< " U field name: " << UName_ << endl;
}
if (dict.readIfPresent("rho", rhoName_))
{
Info<< " rho field name: " << rhoName_ << endl;
}
if (dict.readIfPresent("phi", phiName_))
{
Info<< " phi field name: " << phiName_ << endl;
}
if (dict.readIfPresent("reverseTime", reverseTime_))
{
Info<< " reverse flow direction at time: " << reverseTime_
<< endl;
reverseTime_ = mesh_.time().userTimeToTime(reverseTime_);
}
// Scaling is applied across all modes
scalePtr_ = Function1<scalar>::New("scale", dict);
switch (mode_)
{
case modeType::FUNCTION:
{
velocityPtr_ = Function1<vector>::New("velocity", dict);
break;
}
case modeType::ROTATION:
{
omegaPtr_ = Function1<scalar>::New("omega", dict);
dict.lookup("origin") >> origin_;
vector refDir(dict.lookup("refDir"));
refDir /= mag(refDir) + ROOTVSMALL;
vector axis(dict.lookup("axis"));
axis /= mag(axis) + ROOTVSMALL;
R_ = tensor(refDir, axis, refDir^axis);
break;
}
case modeType::VORTEX2D:
case modeType::VORTEX3D:
{
dict.lookup("origin") >> origin_;
vector refDir(dict.lookup("refDir"));
refDir /= mag(refDir) + ROOTVSMALL;
vector axis(dict.lookup("axis"));
axis /= mag(axis) + ROOTVSMALL;
R_ = tensor(refDir, axis, refDir^axis);
break;
}
}
Info<< endl;
return true;
}
return false;
}
bool Foam::functionObjects::setFlow::execute()
{
volVectorField* Uptr = mesh_.lookupObjectRefPtr<volVectorField>(UName_);
surfaceScalarField* phiptr =
mesh_.lookupObjectRefPtr<surfaceScalarField>(phiName_);
Log << nl << name() << ":" << nl;
if (!Uptr || !phiptr)
{
Info<< " Either field " << UName_ << " or " << phiName_
<< " not found in the mesh database" << nl;
return true;
}
const scalar t = mesh_.time().timeOutputValue();
Log << " setting " << UName_ << " and " << phiName_ << nl;
volVectorField& U = *Uptr;
surfaceScalarField& phi = *phiptr;
switch (mode_)
{
case modeType::FUNCTION:
{
const vector Uc = velocityPtr_->value(t);
U == dimensionedVector("Uc", dimVelocity, Uc);
U.correctBoundaryConditions();
setPhi(U);
break;
}
case modeType::ROTATION:
{
const volVectorField& C = mesh_.C();
const volVectorField d
(
typeName + ":d",
C - dimensionedVector("origin", dimLength, origin_)
);
const scalarField x(d.component(vector::X));
const scalarField z(d.component(vector::Z));
const scalar omega = omegaPtr_->value(t);
vectorField& Uc = U.primitiveFieldRef();
Uc.replace(vector::X, -omega*z);
Uc.replace(vector::Y, scalar(0));
Uc.replace(vector::Z, omega*x);
volVectorField::Boundary& Ubf = U.boundaryFieldRef();
forAll(Ubf, patchi)
{
vectorField& Uf = Ubf[patchi];
if (Uf.size())
{
const vectorField& Cp = C.boundaryField()[patchi];
const vectorField dp(Cp - origin_);
const scalarField xp(dp.component(vector::X));
const scalarField zp(dp.component(vector::Z));
Uf.replace(vector::X, -omega*zp);
Uf.replace(vector::Y, scalar(0));
Uf.replace(vector::Z, omega*xp);
}
}
U = U & R_;
U.correctBoundaryConditions();
setPhi(U);
break;
}
case modeType::VORTEX2D:
{
const scalar pi = Foam::constant::mathematical::pi;
const volVectorField& C = mesh_.C();
const volVectorField d
(
typeName + ":d",
C - dimensionedVector("origin", dimLength, origin_)
);
const scalarField x(d.component(vector::X));
const scalarField z(d.component(vector::Z));
vectorField& Uc = U.primitiveFieldRef();
Uc.replace(vector::X, -sin(2*pi*z)*sqr(sin(pi*x)));
Uc.replace(vector::Y, scalar(0));
Uc.replace(vector::Z, sin(2*pi*x)*sqr(sin(pi*z)));
U = U & R_;
// Calculating incompressible flux based on stream function
// Note: R_ rotation not implemented in phi calculation
const scalarField xp(mesh_.points().component(0) - origin_[0]);
const scalarField yp(mesh_.points().component(1) - origin_[1]);
const scalarField zp(mesh_.points().component(2) - origin_[2]);
const scalarField psi((1.0/pi)*sqr(sin(pi*xp))*sqr(sin(pi*zp)));
scalarField& phic = phi.primitiveFieldRef();
forAll(phic, fi)
{
phic[fi] = 0;
const face& f = mesh_.faces()[fi];
const label nPoints = f.size();
forAll(f, fpi)
{
const label p1 = f[fpi];
const label p2 = f[(fpi + 1) % nPoints];
phic[fi] += 0.5*(psi[p1] + psi[p2])*(yp[p2] - yp[p1]);
}
}
surfaceScalarField::Boundary& phibf = phi.boundaryFieldRef();
forAll(phibf, patchi)
{
scalarField& phif = phibf[patchi];
const label start = mesh_.boundaryMesh()[patchi].start();
forAll(phif, fi)
{
phif[fi] = 0;
const face& f = mesh_.faces()[start + fi];
const label nPoints = f.size();
forAll(f, fpi)
{
const label p1 = f[fpi];
const label p2 = f[(fpi + 1) % nPoints];
phif[fi] += 0.5*(psi[p1] + psi[p2])*(yp[p2] - yp[p1]);
}
}
}
break;
}
case modeType::VORTEX3D:
{
const scalar pi = Foam::constant::mathematical::pi;
const volVectorField& C = mesh_.C();
const volVectorField d
(
typeName + ":d",
C - dimensionedVector("origin", dimLength, origin_)
);
const scalarField x(d.component(vector::X));
const scalarField y(d.component(vector::Y));
const scalarField z(d.component(vector::Z));
vectorField& Uc = U.primitiveFieldRef();
Uc.replace(vector::X, 2*sqr(sin(pi*x))*sin(2*pi*y)*sin(2*pi*z));
Uc.replace(vector::Y, -sin(2*pi*x)*sqr(sin(pi*y))*sin(2*pi*z));
Uc.replace(vector::Z, -sin(2*pi*x)*sin(2*pi*y)*sqr(sin(pi*z)));
U = U & R_;
U.correctBoundaryConditions();
// Calculating phi
// Note: R_ rotation not implemented in phi calculation
const vectorField Cf(mesh_.Cf().primitiveField() - origin_);
const scalarField Xf(Cf.component(vector::X));
const scalarField Yf(Cf.component(vector::Y));
const scalarField Zf(Cf.component(vector::Z));
vectorField Uf(Xf.size());
Uf.replace(0, 2*sqr(sin(pi*Xf))*sin(2*pi*Yf)*sin(2*pi*Zf));
Uf.replace(1, -sin(2*pi*Xf)*sqr(sin(pi*Yf))*sin(2*pi*Zf));
Uf.replace(2, -sin(2*pi*Xf)*sin(2*pi*Yf)*sqr(sin(pi*Zf)));
scalarField& phic = phi.primitiveFieldRef();
const vectorField& Sfc = mesh_.Sf().primitiveField();
phic = Uf & Sfc;
surfaceScalarField::Boundary& phibf = phi.boundaryFieldRef();
const surfaceVectorField::Boundary& Sfbf =
mesh_.Sf().boundaryField();
const surfaceVectorField::Boundary& Cfbf =
mesh_.Cf().boundaryField();
forAll(phibf, patchi)
{
scalarField& phif = phibf[patchi];
const vectorField& Sff = Sfbf[patchi];
const vectorField& Cff = Cfbf[patchi];
const scalarField xf(Cff.component(vector::X));
const scalarField yf(Cff.component(vector::Y));
const scalarField zf(Cff.component(vector::Z));
vectorField Uf(xf.size());
Uf.replace(0, 2*sqr(sin(pi*xf))*sin(2*pi*yf)*sin(2*pi*zf));
Uf.replace(1, -sin(2*pi*xf)*sqr(sin(pi*yf))*sin(2*pi*zf));
Uf.replace(2, -sin(2*pi*xf)*sin(2*pi*yf)*sqr(sin(pi*zf)));
phif = Uf & Sff;
}
break;
}
}
if (t > reverseTime_)
{
Log << " flow direction: reverse" << nl;
U.negate();
phi.negate();
}
// Apply scaling
const scalar s = scalePtr_->value(t);
U *= s;
phi *= s;
U.correctBoundaryConditions();
const scalarField sumPhi(fvc::surfaceIntegrate(phi));
Log << " Continuity error: max(mag(sum(phi))) = "
<< gMax(mag(sumPhi)) << nl << endl;
return true;
}
bool Foam::functionObjects::setFlow::write()
{
const auto& Uptr = mesh_.lookupObjectRefPtr<volVectorField>(UName_);
if (Uptr)
{
Uptr->write();
}
const auto& phiptr = mesh_.lookupObjectRefPtr<surfaceScalarField>(phiName_);
if (phiptr)
{
phiptr->write();
}
return true;
}
// ************************************************************************* //

View File

@ -0,0 +1,199 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2017 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Class
Foam::functionObjects::setFlow
Group
grpFieldFunctionObjects
Description
Provides options to set the velocity and flux fields as a function of time
Useful for testing advection behaviour of numerical schemes by e.g.
imposing solid body rotation, vortex flows. All types include a scaling
Foam::Function1 type enabling the strength of the transformation to vary as
a function of time.
Usage
Example of function object specification:
\verbatim
setFlow1
{
type setFlow;
libs ("libfieldFunctionObjects.so");
...
mode rotation;
scale 1;
reverseTime 1;
omega 6.28318530718;
origin (0.5 0 0.5);
refDir (1 0 0);
axis (0 1 0);
}
\endverbatim
Where the entries comprise:
\table
Property | Description | Required | Default value
type | Type name: setFlow | yes |
U | Name of velocity field | no | U
rho | Name of density field | no | none
phi | Name of flux field | no | phi
mode | operating mode - see below | yes |
\endtable
Available \c mode types include:
- function
- rortation
- vortex2D
- vortex3D
See also
Foam::functionObjects::fvMeshFunctionObject
SourceFiles
setFlow.C
\*---------------------------------------------------------------------------*/
#ifndef functionObjects_setFlow_H
#define functionObjects_setFlow_H
#include "fvMeshFunctionObject.H"
#include "Function1.H"
#include "Enum.H"
#include "point.H"
#include "volFieldsFwd.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
namespace functionObjects
{
/*---------------------------------------------------------------------------*\
Class setFlow Declaration
\*---------------------------------------------------------------------------*/
class setFlow
:
public fvMeshFunctionObject
{
enum class modeType
{
FUNCTION,
ROTATION,
VORTEX2D,
VORTEX3D
};
static const Foam::Enum<modeType> modeTypeNames;
// Private Data
//- Name of vecloity field, default = "U"
word UName_;
//- Name of density field, default = "none"
word rhoName_;
//- Name of flux field, default = "phi"
word phiName_;
//- Operating mode
modeType mode_;
//- Reverse time
scalar reverseTime_;
//- Scaling function
autoPtr<Function1<scalar>> scalePtr_;
// Rotation
//- Origin
point origin_;
//- Rotation tensor for rotational mode
tensor R_;
//- Rotational speed function
autoPtr<Function1<scalar>> omegaPtr_;
// Function
//- Velocity function
autoPtr<Function1<vector>> velocityPtr_;
// Private Member Functions
//- Set the flux field
void setPhi(const volVectorField& U);
public:
//- Runtime type information
TypeName("setFlow");
// Constructors
//- Construct from Time and dictionary
setFlow
(
const word& name,
const Time& runTime,
const dictionary& dict
);
//- Destructor
virtual ~setFlow();
virtual bool read(const dictionary& dict);
virtual bool execute();
virtual bool write();
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace functionObjects
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,51 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: plus |
| \\ / A nd | Web: www.OpenFOAM.com |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class volVectorField;
location "0";
object U;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
dimensions [0 1 -1 0 0 0 0];
internalField uniform (0 0 0);
boundaryField
{
leftWall
{
type fixedValue;
value uniform (0 0 0);
}
rightWall
{
type fixedValue;
value uniform (0 0 0);
}
lowerWall
{
type fixedValue;
value uniform (0 0 0);
}
atmosphere
{
type pressureInletOutletVelocity;
value uniform (0 0 0);
}
defaultFaces
{
type empty;
}
}
// ************************************************************************* //

View File

@ -0,0 +1,51 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: plus |
| \\ / A nd | Web: www.OpenFOAM.com |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class volScalarField;
object alpha.water;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
dimensions [0 0 0 0 0 0 0];
internalField uniform 0;
boundaryField
{
leftWall
{
type zeroGradient;
}
rightWall
{
type zeroGradient;
}
lowerWall
{
type zeroGradient;
}
atmosphere
{
type inletOutlet;
inletValue uniform 0;
value uniform 0;
}
defaultFaces
{
type empty;
}
}
// ************************************************************************* //

View File

@ -0,0 +1,59 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: plus |
| \\ / A nd | Web: www.OpenFOAM.com |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class volScalarField;
object p_rgh;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
dimensions [1 -1 -2 0 0 0 0];
internalField uniform 0;
boundaryField
{
leftWall
{
type fixedFluxPressure;
value uniform 0;
}
rightWall
{
type fixedFluxPressure;
value uniform 0;
}
lowerWall
{
type fixedFluxPressure;
value uniform 0;
}
atmosphere
{
type totalPressure;
p0 uniform 0;
U U;
phi phi;
rho rho;
psi none;
gamma 1;
value uniform 0;
}
defaultFaces
{
type empty;
}
}
// ************************************************************************* //

View File

@ -0,0 +1,9 @@
#!/bin/sh
cd ${0%/*} || exit 1 # Run from this directory
# Source tutorial clean functions
. $WM_PROJECT_DIR/bin/tools/CleanFunctions
cleanCase
\rm -rf 0 isoFaces

View File

@ -0,0 +1,12 @@
#!/bin/sh
cd ${0%/*} || exit 1 # Run from this directory
# Source tutorial run functions
. $WM_PROJECT_DIR/bin/tools/RunFunctions
restore0Dir
runApplication blockMesh
runApplication setFields
runApplication $(getApplication)

View File

@ -0,0 +1,13 @@
#!/bin/sh
cd ${0%/*} || exit 1 # Run from this directory
# Source tutorial run functions
. $WM_PROJECT_DIR/bin/tools/RunFunctions
restore0Dir
runApplication blockMesh
runApplication decomposePar
runParallel setFields
runParallel $(getApplication)

View File

@ -0,0 +1,21 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: plus |
| \\ / A nd | Web: www.OpenFOAM.com |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class dictionary;
location "constant";
object dynamicMeshDict;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
dynamicFvMesh staticFvMesh;
// ************************************************************************* //

View File

@ -0,0 +1,22 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: plus |
| \\ / A nd | Web: www.OpenFOAM.com |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class uniformDimensionedVectorField;
location "constant";
object g;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
dimensions [0 1 -2 0 0 0 0];
value ( 0 -9.81 0 );
// ************************************************************************* //

View File

@ -0,0 +1,38 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: plus |
| \\ / A nd | Web: www.OpenFOAM.com |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class dictionary;
location "constant";
object transportProperties;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
phases (water air);
water
{
transportModel Newtonian;
nu [0 2 -1 0 0 0 0] 1e-06;
rho [1 -3 0 0 0 0 0] 1000;
}
air
{
transportModel Newtonian;
nu [0 2 -1 0 0 0 0] 1.48e-05;
rho [1 -3 0 0 0 0 0] 1;
}
sigma sigma [ 1 0 -2 0 0 0 0 ] 0.07;
// ************************************************************************* //

View File

@ -0,0 +1,21 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: plus |
| \\ / A nd | Web: www.OpenFOAM.com |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class dictionary;
location "constant";
object turbulenceProperties;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
simulationType laminar;
// ************************************************************************* //

View File

@ -0,0 +1,108 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: plus |
| \\ / A nd | Web: www.OpenFOAM.com |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class dictionary;
object blockMeshDict;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
convertToMeters 0.146;
vertices
(
(0 0 0)
(2 0 0)
(2.16438 0 0)
(4 0 0)
(0 0.32876 0)
(2 0.32876 0)
(2.16438 0.32876 0)
(4 0.32876 0)
(0 4 0)
(2 4 0)
(2.16438 4 0)
(4 4 0)
(0 0 0.1)
(2 0 0.1)
(2.16438 0 0.1)
(4 0 0.1)
(0 0.32876 0.1)
(2 0.32876 0.1)
(2.16438 0.32876 0.1)
(4 0.32876 0.1)
(0 4 0.1)
(2 4 0.1)
(2.16438 4 0.1)
(4 4 0.1)
);
blocks
(
hex (0 1 5 4 12 13 17 16) (46 16 1) simpleGrading (1 1 1)
hex (2 3 7 6 14 15 19 18) (38 16 1) simpleGrading (1 1 1)
hex (4 5 9 8 16 17 21 20) (46 84 1) simpleGrading (1 1 1)
hex (5 6 10 9 17 18 22 21) (8 84 1) simpleGrading (1 1 1)
hex (6 7 11 10 18 19 23 22) (38 84 1) simpleGrading (1 1 1)
);
edges
(
);
boundary
(
leftWall
{
type wall;
faces
(
(0 12 16 4)
(4 16 20 8)
);
}
rightWall
{
type wall;
faces
(
(7 19 15 3)
(11 23 19 7)
);
}
lowerWall
{
type wall;
faces
(
(0 1 13 12)
(1 5 17 13)
(5 6 18 17)
(2 14 18 6)
(2 3 15 14)
);
}
atmosphere
{
type patch;
faces
(
(8 20 21 9)
(9 21 22 10)
(10 22 23 11)
);
}
);
mergePatchPairs
(
);
// ************************************************************************* //

View File

@ -0,0 +1,56 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: plus |
| \\ / A nd | Web: www.OpenFOAM.com |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class dictionary;
location "system";
object controlDict;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
application interIsoFoam;
startFrom latestTime;
startTime 0;
stopAt endTime;
endTime 2;
deltaT 0.001;
writeControl adjustableRunTime;
writeInterval 0.02;
purgeWrite 0;
writeFormat ascii;
writePrecision 6;
writeCompression uncompressed;
timeFormat general;
timePrecision 6;
runTimeModifiable yes;
adjustTimeStep yes;
maxCo 10;
maxAlphaCo 0.5;
maxDeltaT 1;
// ************************************************************************* //

View File

@ -0,0 +1,45 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: plus |
| \\ / A nd | Web: www.OpenFOAM.com |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class dictionary;
location "system";
object decomposeParDict;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
numberOfSubdomains 4;
method simple;
simpleCoeffs
{
n ( 2 2 1 );
delta 0.001;
}
hierarchicalCoeffs
{
n ( 1 1 1 );
delta 0.001;
order xyz;
}
manualCoeffs
{
dataFile "";
}
distributed no;
roots ( );
// ************************************************************************* //

View File

@ -0,0 +1,60 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: plus |
| \\ / A nd | Web: www.OpenFOAM.com |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class dictionary;
location "system";
object fvSchemes;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
ddtSchemes
{
default Euler;
}
gradSchemes
{
default Gauss linear;
}
divSchemes
{
div(rhoPhi,U) Gauss limitedLinearV 1;
div(phi,alpha) Gauss vanLeer;
div(phirb,alpha) Gauss interfaceCompression;
div(((rho*nuEff)*dev2(T(grad(U))))) Gauss linear;
}
laplacianSchemes
{
default Gauss linear corrected;
}
interpolationSchemes
{
default linear;
}
snGradSchemes
{
default corrected;
}
fluxRequired
{
default no;
p_rgh;
pcorr;
alpha.water;
}
// ************************************************************************* //

View File

@ -0,0 +1,76 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: plus |
| \\ / A nd | Web: www.OpenFOAM.com |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class dictionary;
location "system";
object fvSolution;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
solvers
{
"alpha.water.*"
{
isoFaceTol 1e-6;
surfCellTol 1e-6;
nAlphaBounds 3;
snapTol 1e-12;
clip true;
nAlphaSubCycles 1;
cAlpha 1;
}
"pcorr.*"
{
solver PCG;
preconditioner DIC;
tolerance 1e-10;
relTol 0;
}
p_rgh
{
solver GAMG;
smoother DICGaussSeidel;
tolerance 1e-07;
relTol 0.05;
}
p_rghFinal
{
$p_rgh;
tolerance 1e-07;
relTol 0;
}
U
{
solver PBiCGStab;
preconditioner DILU;
tolerance 1e-06;
relTol 0;
}
}
PIMPLE
{
momentumPredictor no;
nCorrectors 3;
nOuterCorrectors 1;
nNonOrthogonalCorrectors 0;
pRefCell 0;
pRefValue 0;
}
// ************************************************************************* //

View File

@ -0,0 +1,36 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: plus |
| \\ / A nd | Web: www.OpenFOAM.com |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class dictionary;
location "system";
object setFieldsDict;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
defaultFieldValues
(
volScalarFieldValue alpha.water 0
);
regions
(
boxToCell
{
box (0 0 -1) (0.1461 0.292 1);
fieldValues
(
volScalarFieldValue alpha.water 1
);
}
);
// ************************************************************************* //

View File

@ -0,0 +1,39 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: plus |
| \\ / A nd | Web: www.OpenFOAM.com |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class volVectorField;
location "0";
object U;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
dimensions [0 1 -1 0 0 0 0];
internalField uniform (1 0 0.5);
boundaryField
{
rim
{
type zeroGradient;
}
front
{
type empty;
}
back
{
type empty;
}
}
// ************************************************************************* //

View File

@ -0,0 +1,37 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: plus |
| \\ / A nd | Web: www.OpenFOAM.com |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class volScalarField;
object alpha.water;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
dimensions [0 0 0 0 0 0 0];
internalField uniform 0;
boundaryField
{
rim
{
type zeroGradient;
}
front
{
type empty;
}
back
{
type empty;
}
}
// ************************************************************************* //

View File

@ -0,0 +1,37 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: plus |
| \\ / A nd | Web: www.OpenFOAM.com |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class volScalarField;
object p_rgh;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
dimensions [1 -1 -2 0 0 0 0];
internalField uniform 0;
boundaryField
{
rim
{
type zeroGradient;
}
front
{
type empty;
}
back
{
type empty;
}
}
// ************************************************************************* //

View File

@ -0,0 +1,8 @@
#!/bin/sh
cd ${0%/*} || exit 1 # run from this directory
# Source tutorial clean functions
. $WM_PROJECT_DIR/bin/tools/CleanFunctions
cleanCase
\rm -rf 0

View File

@ -0,0 +1,11 @@
cd ${0%/*} || exit 1 # Run from this directory
# Source tutorial run functions
. $WM_PROJECT_DIR/bin/tools/RunFunctions
restore0Dir
runApplication blockMesh
runApplication setAlphaField
runApplication $(getApplication)

View File

@ -0,0 +1,22 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: plus |
| \\ / A nd | Web: www.OpenFOAM.com |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class uniformDimensionedVectorField;
location "constant";
object g;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
dimensions [0 1 -2 0 0 0 0];
value ( 0 -9.81 0 );
// ************************************************************************* //

View File

@ -0,0 +1,37 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: plus |
| \\ / A nd | Web: www.OpenFOAM.com |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class dictionary;
location "constant";
object transportProperties;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
phases (water air);
water
{
transportModel Newtonian;
nu 0;
rho 1000;
}
air
{
transportModel Newtonian;
nu 0;
rho 1;
}
sigma 0;
// ************************************************************************* //

View File

@ -0,0 +1,21 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: plus |
| \\ / A nd | Web: www.OpenFOAM.com |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class dictionary;
location "constant";
object turbulenceProperties;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
simulationType laminar;
// ************************************************************************* //

View File

@ -0,0 +1,85 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: plus |
| \\ / A nd | Web: www.OpenFOAM.com |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class dictionary;
object blockMeshDict;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
convertToMeters 1;
L 5;
nx 100;
y1 -.5;
y2 .5;
ny 1;
H 3;
nz 60;
vertices
(
(0 $y1 0)
($L $y1 0)
($L $y2 0)
(0 $y2 0)
(0 $y1 $H)
($L $y1 $H)
($L $y2 $H)
(0 $y2 $H)
);
blocks
(
hex (0 1 2 3 4 5 6 7) ($nx $ny $nz) simpleGrading (1 1 1)
);
edges
(
);
boundary
(
rim
{
type patch;
faces
(
(4 5 6 7)
(0 4 7 3)
(1 2 6 5)
(0 3 2 1)
);
}
front
{
type empty;
faces
(
(0 1 5 4)
);
}
back
{
type empty;
faces
(
(2 3 7 6)
);
}
);
mergePatchPairs
(
);
// ************************************************************************* //

View File

@ -0,0 +1,60 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: plus |
| \\ / A nd | Web: www.OpenFOAM.com |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class dictionary;
location "system";
object controlDict;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
application interIsoFoam;
startFrom latestTime;
startTime 0.0;
stopAt endTime;
endTime 4;
writeControl adjustableRunTime;
writeInterval 0.1;
deltaT 1e-3;
purgeWrite 0;
writeFormat ascii;
writePrecision 14;
writeCompression uncompressed;
timeFormat general;
timePrecision 6;
graphFormat raw;
runTimeModifiable no;
adjustTimeStep yes;
maxCo 1e6;
maxAlphaCo 0.5;
maxDeltaT 1e6;
// ************************************************************************* //

View File

@ -0,0 +1,60 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: plus |
| \\ / A nd | Web: www.OpenFOAM.com |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class dictionary;
location "system";
object fvSchemes;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
ddtSchemes
{
default Euler;
}
gradSchemes
{
default Gauss linear;
}
divSchemes
{
div(rho*phi,U) Gauss limitedLinearV 1;
div(phi,alpha) Gauss vanLeer;
div(phirb,alpha) Gauss interfaceCompression;
div((muEff*dev(T(grad(U))))) Gauss linear;
}
laplacianSchemes
{
default Gauss linear corrected;
}
interpolationSchemes
{
default linear;
}
snGradSchemes
{
default corrected;
}
fluxRequired
{
default no;
p_rgh;
pcorr;
alpha1;
}
// ************************************************************************* //

View File

@ -0,0 +1,44 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: plus |
| \\ / A nd | Web: www.OpenFOAM.com |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class dictionary;
location "system";
object fvSolution;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
solvers
{
"alpha.*"
{
isoFaceTol 1e-8;
surfCellTol 1e-8;
nAlphaBounds 3;
snapTol 0;
clip false;
cAlpha 1;
nAlphaSubCycles 1;
}
}
PIMPLE
{
frozenFlow yes;
momentumPredictor no;
nCorrectors -1;
nNonOrthogonalCorrectors -1;
pRefCell 0;
pRefValue 0;
}
// ************************************************************************* //

View File

@ -0,0 +1,24 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: plus |
| \\ / A nd | Web: www.OpenFOAM.com |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class dictionary;
location "system";
object fvSolution;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
field alpha.water;
type cylinder;
radius 0.25;
direction (0 1 0);
centre (0.5 0 0.5);
// ************************************************************************* //

View File

@ -0,0 +1,39 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: plus |
| \\ / A nd | Web: www.OpenFOAM.com |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class volVectorField;
location "0";
object U;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
dimensions [0 1 -1 0 0 0 0];
internalField uniform (0 0 0);
boundaryField
{
rim
{
type zeroGradient;
}
front
{
type empty;
}
back
{
type empty;
}
}
// ************************************************************************* //

View File

@ -0,0 +1,38 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: plus |
| \\ / A nd | Web: www.OpenFOAM.com |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class volScalarField;
object alpha;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
dimensions [0 0 0 0 0 0 0];
internalField uniform 0;
boundaryField
{
rim
{
type fixedValue;
value uniform 0;
}
front
{
type empty;
}
back
{
type empty;
}
}
// ************************************************************************* //

View File

@ -0,0 +1,37 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: plus |
| \\ / A nd | Web: www.OpenFOAM.com |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class volScalarField;
object p_rgh;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
dimensions [1 -1 -2 0 0 0 0];
internalField uniform 0;
boundaryField
{
rim
{
type zeroGradient;
}
front
{
type empty;
}
back
{
type empty;
}
}
// ************************************************************************* //

View File

@ -0,0 +1,7 @@
#!/bin/bash
# Source tutorial clean functions
. $WM_PROJECT_DIR/bin/tools/CleanFunctions
cleanCase
\rm -rf 0

View File

@ -0,0 +1,17 @@
#!/bin/sh
cd ${0%/*} || exit 1 # Run from this directory
# Source tutorial run functions
. $WM_PROJECT_DIR/bin/tools/RunFunctions
restore0Dir
runApplication blockMesh
runApplication -s 1 topoSet
runApplication -s 1 refineMesh -overwrite
runApplication -s 2 topoSet -dict system/topoSetDict2
runApplication -s 2 refineMesh -overwrite
runApplication setAlphaField
runApplication $(getApplication)

View File

@ -0,0 +1,22 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: plus |
| \\ / A nd | Web: www.OpenFOAM.com |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class uniformDimensionedVectorField;
location "constant";
object g;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
dimensions [0 1 -2 0 0 0 0];
value ( 0 -9.81 0 );
// ************************************************************************* //

View File

@ -0,0 +1,86 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: plus |
| \\ / A nd | Web: www.OpenFOAM.com |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class dictionary;
location "constant";
object transportProperties;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
DT DT [ 0 2 -1 0 0 0 0 ] 0;
//Input for OF-2.3.0 and later
phases (water air);
water
{
transportModel Newtonian;
nu [0 2 -1 0 0 0 0] 1e-06;
rho [1 -3 0 0 0 0 0] 1000;
}
air
{
transportModel Newtonian;
nu [0 2 -1 0 0 0 0] 1.48e-05;
rho [1 -3 0 0 0 0 0] 1;
}
//Input for OF-2.2.0 and earlier
phase1
{
transportModel Newtonian;
nu nu [ 0 2 -1 0 0 0 0 ] 0;
rho rho [ 1 -3 0 0 0 0 0 ] 1000;
CrossPowerLawCoeffs
{
nu0 nu0 [ 0 2 -1 0 0 0 0 ] 1e-06;
nuInf nuInf [ 0 2 -1 0 0 0 0 ] 1e-06;
m m [ 0 0 1 0 0 0 0 ] 1;
n n [ 0 0 0 0 0 0 0 ] 0;
}
BirdCarreauCoeffs
{
nu0 nu0 [ 0 2 -1 0 0 0 0 ] 0.0142515;
nuInf nuInf [ 0 2 -1 0 0 0 0 ] 1e-06;
k k [ 0 0 1 0 0 0 0 ] 99.6;
n n [ 0 0 0 0 0 0 0 ] 0.1003;
}
}
phase2
{
transportModel Newtonian;
nu nu [ 0 2 -1 0 0 0 0 ] 0;
rho rho [ 1 -3 0 0 0 0 0 ] 1;
CrossPowerLawCoeffs
{
nu0 nu0 [ 0 2 -1 0 0 0 0 ] 1e-06;
nuInf nuInf [ 0 2 -1 0 0 0 0 ] 1e-06;
m m [ 0 0 1 0 0 0 0 ] 1;
n n [ 0 0 0 0 0 0 0 ] 0;
}
BirdCarreauCoeffs
{
nu0 nu0 [ 0 2 -1 0 0 0 0 ] 0.0142515;
nuInf nuInf [ 0 2 -1 0 0 0 0 ] 1e-06;
k k [ 0 0 1 0 0 0 0 ] 99.6;
n n [ 0 0 0 0 0 0 0 ] 0.1003;
}
}
sigma sigma [ 1 0 -2 0 0 0 0 ] 0.0;
// ************************************************************************* //

View File

@ -0,0 +1,21 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: plus |
| \\ / A nd | Web: www.OpenFOAM.com |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class dictionary;
location "constant";
object turbulenceProperties;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
simulationType laminar;
// ************************************************************************* //

View File

@ -0,0 +1,85 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: plus |
| \\ / A nd | Web: www.OpenFOAM.com |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class dictionary;
object blockMeshDict;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
convertToMeters 1;
L 1;
nx 100;
y1 -.01;
y2 .01;
ny 1;
H 1;
nz 100;
vertices
(
(0 $y1 0)
($L $y1 0)
($L $y2 0)
(0 $y2 0)
(0 $y1 $H)
($L $y1 $H)
($L $y2 $H)
(0 $y2 $H)
);
blocks
(
hex (0 1 2 3 4 5 6 7) ($nx $ny $nz) simpleGrading (1 1 1)
);
edges
(
);
boundary
(
rim
{
type patch;
faces
(
(4 5 6 7)
(0 4 7 3)
(1 2 6 5)
(0 3 2 1)
);
}
front
{
type empty;
faces
(
(0 1 5 4)
);
}
back
{
type empty;
faces
(
(2 3 7 6)
);
}
);
mergePatchPairs
(
);
// ************************************************************************* //

View File

@ -0,0 +1,81 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: plus |
| \\ / A nd | Web: www.OpenFOAM.com |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class dictionary;
location "system";
object controlDict;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
application interIsoFoam;
startFrom latestTime;
startTime 0.0;
stopAt endTime;
endTime 8;
writeControl adjustableRunTime;
writeInterval 0.1;
deltaT 0.002;
purgeWrite 0;
writeFormat binary;
writePrecision 14;
writeCompression uncompressed;
timeFormat general;
timePrecision 6;
graphFormat raw;
runTimeModifiable no;
adjustTimeStep no;
maxCo 1e10;
maxAlphaCo 0.5;
maxDeltaT 0.05;
functions
{
setVelocity
{
type setFlow;
libs ("libfieldFunctionObjects.so");
writeControl writeTime;
mode vortex2D;
scale sine;
scaleCoeffs
{
amplitude 1;
frequency 0.0625; // = 1/16
t0 -4; // want cos -> time shift = -(pi/2)/(2 pi f)
scale 1;
level 0;
}
origin (0 0 0);
refDir (1 0 0);
axis (0 1 0);
}
}
// ************************************************************************* //

View File

@ -0,0 +1,61 @@
/*---------------------------------------------------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: plus |
| \\ / A nd | Web: www.OpenFOAM.com |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class dictionary;
location "system";
object decomposeParDict;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
numberOfSubdomains 4;
method simple;
simpleCoeffs
{
n (2 1 2);
delta 0.001;
}
hierarchicalCoeffs
{
n (1 1 1);
delta 0.001;
order xyz;
}
metisCoeffs
{
processorWeights
(
1
1
1
1
);
}
manualCoeffs
{
dataFile "";
}
distributed no;
roots
(
);
// ************************************************************************* //

View File

@ -0,0 +1,51 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: plus |
| \\ / A nd | Web: www.OpenFOAM.com |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class dictionary;
location "system";
object fvSchemes;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
ddtSchemes
{
default Euler;
}
gradSchemes
{
default Gauss linear;
}
divSchemes
{
div(rhoPhi,U) Gauss limitedLinearV 1;
div(phi,alpha) Gauss vanLeer;
div(phirb,alpha) Gauss linear;
}
laplacianSchemes
{
default Gauss linear corrected;
}
interpolationSchemes
{
default linear;
}
snGradSchemes
{
default corrected;
}
// ************************************************************************* //

View File

@ -0,0 +1,43 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: plus |
| \\ / A nd | Web: www.OpenFOAM.com |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class dictionary;
location "system";
object fvSolution;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
solvers
{
"alpha.*"
{
isoFaceTol 1e-8;
surfCellTol 1e-8;
nAlphaBounds 3;
snapTol 0;
clip false;
nAlphaSubCycles 1;
cAlpha 1;
}
}
PIMPLE
{
frozenFlow yes;
momentumPredictor no;
nCorrectors -1;
nNonOrthogonalCorrectors -1;
pRefCell 0;
pRefValue 0;
}
// ************************************************************************* //

View File

@ -0,0 +1,62 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: plus |
| \\ / A nd | Web: www.OpenFOAM.com |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class dictionary;
object refineMeshDict;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// Cells to refine; name of cell set
set c1;
// Type of coordinate system:
// - global : coordinate system same for every cell. Usually aligned with
// x,y,z axis. Specify in globalCoeffs section below.
// - patchLocal : coordinate system different for every cell. Specify in
// patchLocalCoeffs section below.
coordinateSystem global;
//coordinateSystem patchLocal;
// .. and its coefficients. x,y in this case. (normal direction is calculated
// as tan1^tan2)
globalCoeffs
{
tan1 (1 0 0);
tan2 (0 1 0);
}
patchLocalCoeffs
{
patch outside; // Normal direction is facenormal of zero'th face of patch
tan1 (1 0 0);
}
// List of directions to refine
directions
(
tan1
// tan2
normal
);
// Whether to use hex topology. This will
// - if patchLocal: all cells on selected patch should be hex
// - split all hexes in 2x2x2 through the middle of edges.
useHexTopology true;
// Cut purely geometric (will cut hexes through vertices) or take topology
// into account. Incompatible with useHexTopology
geometricCut false;
// Write meshes from intermediate steps
writeMesh false;
// ************************************************************************* //

View File

@ -0,0 +1,24 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: plus |
| \\ / A nd | Web: www.OpenFOAM.com |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class dictionary;
location "system";
object fvSolution;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
field "alpha.water";
type cylinder;
radius 0.15;
direction (0 1 0);
centre (0.5 0 0.75);
// ************************************************************************* //

View File

@ -0,0 +1,37 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: plus |
| \\ / A nd | Web: www.OpenFOAM.com |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class dictionary;
object topoSetDict;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
actions
(
{
name c1;
type cellSet;
action new;
source boxToCell;
sourceInfo
{
boxes
(
(.1 -1e10 0.08) (.9 1e10 0.2)
(.75 -1e10 0.2) (.92 1e10 0.9)
(.1 -1e10 0.2) (.25 1e10 0.7)
);
}
}
);
// ************************************************************************* //

View File

@ -0,0 +1,35 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: plus |
| \\ / A nd | Web: www.OpenFOAM.com |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class dictionary;
object topoSetDict;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
actions
(
{
name c1;
type cellSet;
action new;
source boxToCell;
sourceInfo
{
boxes
(
(.4 -1e10 0.09) (.7 1e10 0.15)
);
}
}
);
// ************************************************************************* //

View File

@ -0,0 +1,39 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: plus |
| \\ / A nd | Web: www.OpenFOAM.com |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class volVectorField;
location "0";
object U;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
dimensions [0 1 -1 0 0 0 0];
internalField uniform (0 0 0);
boundaryField
{
rim
{
type zeroGradient;
}
front
{
type empty;
}
back
{
type empty;
}
}
// ************************************************************************* //

View File

@ -0,0 +1,38 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: plus |
| \\ / A nd | Web: www.OpenFOAM.com |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class volScalarField;
object alpha.water;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
dimensions [0 0 0 0 0 0 0];
internalField uniform 0;
boundaryField
{
rim
{
type fixedValue;
value uniform 0;
}
front
{
type empty;
}
back
{
type empty;
}
}
// ************************************************************************* //

View File

@ -0,0 +1,37 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: plus |
| \\ / A nd | Web: www.OpenFOAM.com |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class volScalarField;
object p_rgh;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
dimensions [1 -1 -2 0 0 0 0];
internalField uniform 0;
boundaryField
{
rim
{
type zeroGradient;
}
front
{
type empty;
}
back
{
type empty;
}
}
// ************************************************************************* //

View File

@ -0,0 +1,9 @@
#!/bin/sh
cd ${0%/*} || exit 1 # run from this directory
# Source tutorial clean functions
. $WM_PROJECT_DIR/bin/tools/CleanFunctions
cleanCase
\rm -rf 0

View File

@ -0,0 +1,19 @@
#!/bin/sh
cd ${0%/*} || exit 1 # run from this directory
# Source tutorial run functions
. $WM_PROJECT_DIR/bin/tools/RunFunctions
application=$(getApplication)
restore0Dir
runApplication blockMesh
runApplication -s postProcess ${application} -postProcess -time 0
runApplication setAlphaField
runApplication setFields
runApplication ${application}

View File

@ -0,0 +1,22 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: plus |
| \\ / A nd | Web: www.OpenFOAM.com |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class uniformDimensionedVectorField;
location "constant";
object g;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
dimensions [0 1 -2 0 0 0 0];
value ( 0 -9.81 0 );
// ************************************************************************* //

View File

@ -0,0 +1,37 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: plus |
| \\ / A nd | Web: www.OpenFOAM.com |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class dictionary;
location "constant";
object transportProperties;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
phases (water air);
water
{
transportModel Newtonian;
nu 0;
rho 1000;
}
air
{
transportModel Newtonian;
nu 0;
rho 1;
}
sigma 0;
// ************************************************************************* //

View File

@ -0,0 +1,21 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: plus |
| \\ / A nd | Web: www.OpenFOAM.com |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class dictionary;
location "constant";
object turbulenceProperties;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
simulationType laminar;
// ************************************************************************* //

View File

@ -0,0 +1,85 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: plus |
| \\ / A nd | Web: www.OpenFOAM.com |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class dictionary;
object blockMeshDict;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
convertToMeters 1;
L 1;
nx 100;
y1 -.01;
y2 .01;
ny 1;
H 1;
nz 100;
vertices
(
(0 $y1 0)
($L $y1 0)
($L $y2 0)
(0 $y2 0)
(0 $y1 $H)
($L $y1 $H)
($L $y2 $H)
(0 $y2 $H)
);
blocks
(
hex (0 1 2 3 4 5 6 7) ($nx $ny $nz) simpleGrading (1 1 1)
);
edges
(
);
boundary
(
rim
{
type patch;
faces
(
(4 5 6 7)
(0 4 7 3)
(1 2 6 5)
(0 3 2 1)
);
}
front
{
type empty;
faces
(
(0 1 5 4)
);
}
back
{
type empty;
faces
(
(2 3 7 6)
);
}
);
mergePatchPairs
(
);
// ************************************************************************* //

View File

@ -0,0 +1,76 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: plus |
| \\ / A nd | Web: www.OpenFOAM.com |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class dictionary;
location "system";
object controlDict;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
application interIsoFoam;
startFrom latestTime;
startTime 0.0;
stopAt endTime;
endTime 2;
writeControl adjustableRunTime;
writeInterval 0.05;
deltaT 0.001;
purgeWrite 0;
writeFormat ascii;
writePrecision 14;
writeCompression uncompressed;
timeFormat general;
timePrecision 6;
graphFormat raw;
runTimeModifiable no;
adjustTimeStep no;
maxCo 1e6;
maxAlphaCo 0.5;
maxDeltaT 0.05;
functions
{
setVelocity
{
type setFlow;
libs ("libfieldFunctionObjects.so");
writeControl writeTime;
mode rotation;
scale 1;
reverseTime 1;
omega 6.28318530718;
origin (0.5 0 0.5);
refDir (1 0 0);
axis (0 1 0);
}
}
// ************************************************************************* //

View File

@ -0,0 +1,52 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: plus |
| \\ / A nd | Web: www.OpenFOAM.com |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class dictionary;
location "system";
object fvSchemes;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
ddtSchemes
{
default Euler;
}
gradSchemes
{
default Gauss linear;
}
divSchemes
{
div(rhoPhi,U) Gauss limitedLinearV 1;
div(phi,alpha) Gauss vanLeer;
div(phirb,alpha) Gauss linear;
div(((rho*nuEff)*dev2(T(grad(U))))) Gauss linear;
}
laplacianSchemes
{
default Gauss linear corrected;
}
interpolationSchemes
{
default linear;
}
snGradSchemes
{
default corrected;
}
// ************************************************************************* //

View File

@ -0,0 +1,43 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: plus |
| \\ / A nd | Web: www.OpenFOAM.com |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class dictionary;
location "system";
object fvSolution;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
solvers
{
"alpha.*"
{
isoFaceTol 1e-8;
surfCellTol 1e-8;
snapTol 0;
nAlphaBounds 3;
clip false;
nAlphaSubCycles 1;
cAlpha 1;
}
}
PIMPLE
{
frozenFlow yes;
momentumPredictor no;
nCorrectors -1;
nNonOrthogonalCorrectors -1;
pRefCell 0;
pRefValue 0;
}
// ************************************************************************* //

View File

@ -0,0 +1,24 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: plus |
| \\ / A nd | Web: www.OpenFOAM.com |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class dictionary;
location "system";
object fvSolution;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
field alpha.water;
type cylinder;
radius 0.15;
direction (0 1 0);
centre (0.5 0 0.75);
// ************************************************************************* //

View File

@ -0,0 +1,31 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: plus |
| \\ / A nd | Web: www.OpenFOAM.com |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class dictionary;
location "system";
object setFieldsDict;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
regions
(
boxToCell
{
box (.47 -1 0) (.53 1 .85);
fieldValues
(
volScalarFieldValue alpha.water 0
);
}
);
// ************************************************************************* //

View File

@ -0,0 +1,31 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: plus |
| \\ / A nd | Web: www.OpenFOAM.com |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class volVectorField;
location "0";
object U;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
dimensions [0 1 -1 0 0 0 0];
internalField uniform (0 0 0);
boundaryField
{
sides
{
type zeroGradient;
}
}
// ************************************************************************* //

View File

@ -0,0 +1,30 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: plus |
| \\ / A nd | Web: www.OpenFOAM.com |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class volScalarField;
object alpha.water;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
dimensions [0 0 0 0 0 0 0];
internalField uniform 0;
boundaryField
{
sides
{
type fixedValue;
value uniform 0;
}
}
// ************************************************************************* //

View File

@ -0,0 +1,30 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: plus |
| \\ / A nd | Web: www.OpenFOAM.com |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class volScalarField;
object p_rgh;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
dimensions [1 -1 -2 0 0 0 0];
internalField uniform 0;
boundaryField
{
sides
{
type fixedValue;
value uniform 0;
}
}
// ************************************************************************* //

View File

@ -0,0 +1,7 @@
#!/bin/bash
# Source tutorial clean functions
. $WM_PROJECT_DIR/bin/tools/CleanFunctions
cleanCase
\rm -rf 0

View File

@ -0,0 +1,13 @@
#!/bin/sh
cd ${0%/*} || exit 1 # Run from this directory
# Source tutorial run functions
. $WM_PROJECT_DIR/bin/tools/RunFunctions
restore0Dir
runApplication blockMesh
runApplication setAlphaField
runApplication decomposePar
runParallel $(getApplication)

View File

@ -0,0 +1,22 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: plus |
| \\ / A nd | Web: www.OpenFOAM.com |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class uniformDimensionedVectorField;
location "constant";
object g;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
dimensions [0 1 -2 0 0 0 0];
value ( 0 -9.81 0 );
// ************************************************************************* //

View File

@ -0,0 +1,37 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: plus |
| \\ / A nd | Web: www.OpenFOAM.com |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class dictionary;
location "constant";
object transportProperties;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
phases (water air);
water
{
transportModel Newtonian;
nu [0 2 -1 0 0 0 0] 1e-06;
rho [1 -3 0 0 0 0 0] 1000;
}
air
{
transportModel Newtonian;
nu [0 2 -1 0 0 0 0] 1.48e-05;
rho [1 -3 0 0 0 0 0] 1;
}
sigma sigma [ 1 0 -2 0 0 0 0 ] 0.0;
// ************************************************************************* //

View File

@ -0,0 +1,21 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: plus |
| \\ / A nd | Web: www.OpenFOAM.com |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class dictionary;
location "constant";
object turbulenceProperties;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
simulationType laminar;
// ************************************************************************* //

View File

@ -0,0 +1,71 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: plus |
| \\ / A nd | Web: www.OpenFOAM.com |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class dictionary;
object blockMeshDict;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
convertToMeters 1;
x1 0;
x2 1;
y1 0;
y2 1;
z1 0;
z2 1;
nx 64;
ny 64;
nz 64;
vertices
(
($x1 $y1 $z1)
($x2 $y1 $z1)
($x2 $y2 $z1)
($x1 $y2 $z1)
($x1 $y1 $z2)
($x2 $y1 $z2)
($x2 $y2 $z2)
($x1 $y2 $z2)
);
blocks
(
hex (0 1 2 3 4 5 6 7) ($nx $ny $nz) simpleGrading (1 1 1)
);
edges
(
);
boundary
(
sides
{
type patch;
faces
(
(4 5 6 7)
(0 4 7 3)
(1 2 6 5)
(0 3 2 1)
(0 1 5 4)
(2 3 7 6)
);
}
);
mergePatchPairs
(
);
// ************************************************************************* //

View File

@ -0,0 +1,81 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: plus |
| \\ / A nd | Web: www.OpenFOAM.com |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class dictionary;
location "system";
object controlDict;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
application interIsoFoam;
startFrom startTime;
startTime 0.0;
stopAt endTime;
endTime 3.0;
writeControl adjustableRunTime;
writeInterval 0.1;
deltaT 0.0025;
purgeWrite 0;
writeFormat ascii;
writePrecision 14;
writeCompression uncompressed;
timeFormat general;
timePrecision 6;
graphFormat raw;
runTimeModifiable yes;
adjustTimeStep no;
maxCo 1e10;
maxAlphaCo 0.5;
maxDeltaT 0.2;
functions
{
setVelocity
{
type setFlow;
libs ("libfieldFunctionObjects.so");
writeControl writeTime;
mode vortex3D;
scale sine;
scaleCoeffs
{
amplitude 1;
frequency 0.16666;// = 1/6
t0 -1.5; // want cos -> time shift = -(pi/2)/(2 pi f)
scale 1;
level 0;
}
origin (0 0 0);
refDir (1 0 0);
axis (0 1 0);
}
}
// ************************************************************************* //

View File

@ -0,0 +1,31 @@
/*---------------------------------------------------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: plus |
| \\ / A nd | Web: www.OpenFOAM.com |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class dictionary;
location "system";
object decomposeParDict;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
numberOfSubdomains 8;
method simple;
simpleCoeffs
{
n (2 2 2);
delta 0.001;
}
// ************************************************************************* //

View File

@ -0,0 +1,51 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: plus |
| \\ / A nd | Web: www.OpenFOAM.com |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class dictionary;
location "system";
object fvSchemes;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
ddtSchemes
{
default Euler;
}
gradSchemes
{
default Gauss linear;
}
divSchemes
{
div(rhoPhi,U) Gauss limitedLinearV 1;
div(phi,alpha) Gauss vanLeer;
div(phirb,alpha) Gauss linear;
}
laplacianSchemes
{
default Gauss linear corrected;
}
interpolationSchemes
{
default linear;
}
snGradSchemes
{
default corrected;
}
// ************************************************************************* //

Some files were not shown because too many files have changed in this diff Show More