Merge commit 'OpenCFD/master' into olesenm

This commit is contained in:
Mark Olesen
2009-11-04 08:56:20 +01:00
151 changed files with 9270 additions and 2026 deletions

View File

@ -13,6 +13,14 @@ PtrList<volScalarField>& Y = composition.Y();
word inertSpecie(thermo.lookup("inertSpecie")); word inertSpecie(thermo.lookup("inertSpecie"));
if (!composition.contains(inertSpecie))
{
FatalErrorIn(args.executable())
<< "Specified inert specie '" << inertSpecie << "' not found in "
<< "species list. Available species:" << composition.species()
<< exit(FatalError);
}
volScalarField rho volScalarField rho
( (
IOobject IOobject

View File

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

View File

@ -0,0 +1,14 @@
EXE_INC = \
-I../simpleFoam \
-I$(LIB_SRC)/turbulenceModels \
-I$(LIB_SRC)/turbulenceModels/incompressible/RAS/RASModel \
-I$(LIB_SRC)/transportModels \
-I$(LIB_SRC)/transportModels/incompressible/singlePhaseTransportModel \
-I$(LIB_SRC)/finiteVolume/lnInclude \
-I$(LIB_SRC)/meshTools/lnInclude
EXE_LIBS = \
-lincompressibleRASModels \
-lincompressibleTransportModels \
-lfiniteVolume \
-lmeshTools

View File

@ -0,0 +1,47 @@
// Construct the Momentum equation
tmp<fvVectorMatrix> UEqn
(
fvm::div(phi, U)
- fvm::Sp(fvc::div(phi), U)
+ turbulence->divDevReff(U)
);
UEqn().relax();
// Include the porous media resistance and solve the momentum equation
// either implicit in the tensorial resistance or transport using by
// including the spherical part of the resistance in the momentum diagonal
tmp<volScalarField> trAU;
tmp<volTensorField> trTU;
if (pressureImplicitPorosity)
{
tmp<volTensorField> tTU = tensor(I)*UEqn().A();
pZones.addResistance(UEqn(), tTU());
trTU = inv(tTU());
trTU().rename("rAU");
volVectorField gradp = fvc::grad(p);
for (int UCorr=0; UCorr<nUCorr; UCorr++)
{
U = trTU() & (UEqn().H() - gradp);
}
U.correctBoundaryConditions();
}
else
{
pZones.addResistance(UEqn());
eqnResidual = solve
(
UEqn() == -fvc::grad(p)
). initialResidual();
maxResidual = max(eqnResidual, maxResidual);
trAU = 1.0/UEqn().A();
trAU().rename("rAU");
}

View File

@ -0,0 +1,64 @@
Info << "Reading field p\n" << endl;
volScalarField p
(
IOobject
(
"p",
runTime.timeName(),
mesh,
IOobject::MUST_READ,
IOobject::AUTO_WRITE
),
mesh
);
Info << "Reading field U\n" << endl;
volVectorField U
(
IOobject
(
"U",
runTime.timeName(),
mesh,
IOobject::MUST_READ,
IOobject::AUTO_WRITE
),
mesh
);
# include "createPhi.H"
label pRefCell = 0;
scalar pRefValue = 0.0;
setRefCell(p, mesh.solutionDict().subDict("SIMPLE"), pRefCell, pRefValue);
singlePhaseTransportModel laminarTransport(U, phi);
autoPtr<incompressible::RASModel> turbulence
(
incompressible::RASModel::New(U, phi, laminarTransport)
);
porousZones pZones(mesh);
Switch pressureImplicitPorosity(false);
int nUCorr = 0;
if (pZones.size())
{
// nUCorrectors for pressureImplicitPorosity
if (mesh.solutionDict().subDict("SIMPLE").found("nUCorrectors"))
{
nUCorr = readInt
(
mesh.solutionDict().subDict("SIMPLE").lookup("nUCorrectors")
);
}
if (nUCorr > 0)
{
pressureImplicitPorosity = true;
}
}

View File

@ -0,0 +1,59 @@
if (pressureImplicitPorosity)
{
U = trTU()&UEqn().H();
}
else
{
U = trAU()*UEqn().H();
}
UEqn.clear();
phi = fvc::interpolate(U) & mesh.Sf();
adjustPhi(phi, U, p);
for (int nonOrth=0; nonOrth<=nNonOrthCorr; nonOrth++)
{
tmp<fvScalarMatrix> tpEqn;
if (pressureImplicitPorosity)
{
tpEqn = (fvm::laplacian(trTU(), p) == fvc::div(phi));
}
else
{
tpEqn = (fvm::laplacian(trAU(), p) == fvc::div(phi));
}
tpEqn().setReference(pRefCell, pRefValue);
// retain the residual from the first iteration
if (nonOrth == 0)
{
eqnResidual = tpEqn().solve().initialResidual();
maxResidual = max(eqnResidual, maxResidual);
}
else
{
tpEqn().solve();
}
if (nonOrth == nNonOrthCorr)
{
phi -= tpEqn().flux();
}
}
#include "continuityErrs.H"
// Explicitly relax pressure for momentum corrector
p.relax();
if (pressureImplicitPorosity)
{
U -= trTU()&fvc::grad(p);
}
else
{
U -= trAU()*fvc::grad(p);
}
U.correctBoundaryConditions();

View File

@ -0,0 +1,85 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 1991-2009 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 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Application
porousSimpleFoam
Description
Steady-state solver for incompressible, turbulent flow with
implicit or explicit porosity treatment
\*---------------------------------------------------------------------------*/
#include "fvCFD.H"
#include "singlePhaseTransportModel.H"
#include "RASModel.H"
#include "porousZones.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
int main(int argc, char *argv[])
{
#include "setRootCase.H"
#include "createTime.H"
#include "createMesh.H"
#include "createFields.H"
#include "initContinuityErrs.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
Info<< "\nStarting time loop\n" << endl;
while (runTime.loop())
{
Info<< "Time = " << runTime.timeName() << nl << endl;
#include "readSIMPLEControls.H"
#include "initConvergenceCheck.H"
p.storePrevIter();
// Pressure-velocity SIMPLE corrector
{
#include "UEqn.H"
#include "pEqn.H"
}
turbulence->correct();
runTime.write();
Info<< "ExecutionTime = " << runTime.elapsedCpuTime() << " s"
<< " ClockTime = " << runTime.elapsedClockTime() << " s"
<< nl << endl;
#include "convergenceCheck.H"
}
Info<< "End\n" << endl;
return 0;
}
// ************************************************************************* //

View File

@ -14,7 +14,7 @@ tmp<fv::convectionScheme<scalar> > mvConvection
label inertIndex = -1; label inertIndex = -1;
volScalarField Yt = 0.0*Y[0]; volScalarField Yt = 0.0*Y[0];
for (label i=0; i<Y.size(); i++) forAll(Y, i)
{ {
if (Y[i].name() != inertSpecie) if (Y[i].name() != inertSpecie)
{ {

View File

@ -13,6 +13,14 @@
word inertSpecie(thermo.lookup("inertSpecie")); word inertSpecie(thermo.lookup("inertSpecie"));
if (!composition.contains(inertSpecie))
{
FatalErrorIn(args.executable())
<< "Specified inert specie '" << inertSpecie << "' not found in "
<< "species list. Available species:" << composition.species()
<< exit(FatalError);
}
volScalarField& p = thermo.p(); volScalarField& p = thermo.p();
volScalarField& h = thermo.h(); volScalarField& h = thermo.h();
const volScalarField& T = thermo.T(); const volScalarField& T = thermo.T();

View File

@ -15,7 +15,7 @@ tmp<fv::convectionScheme<scalar> > mvConvection
label inertIndex = -1; label inertIndex = -1;
volScalarField Yt = 0.0*Y[0]; volScalarField Yt = 0.0*Y[0];
for (label i=0; i<Y.size(); i++) forAll(Y, i)
{ {
if (Y[i].name() != inertSpecie) if (Y[i].name() != inertSpecie)
{ {

View File

@ -13,6 +13,14 @@
word inertSpecie(thermo.lookup("inertSpecie")); word inertSpecie(thermo.lookup("inertSpecie"));
if (!composition.contains(inertSpecie))
{
FatalErrorIn(args.executable())
<< "Specified inert specie '" << inertSpecie << "' not found in "
<< "species list. Available species:" << composition.species()
<< exit(FatalError);
}
volScalarField& p = thermo.p(); volScalarField& p = thermo.p();
volScalarField& h = thermo.h(); volScalarField& h = thermo.h();
const volScalarField& T = thermo.T(); const volScalarField& T = thermo.T();

View File

@ -14,7 +14,7 @@ tmp<fv::convectionScheme<scalar> > mvConvection
label inertIndex = -1; label inertIndex = -1;
volScalarField Yt = 0.0*Y[0]; volScalarField Yt = 0.0*Y[0];
for (label i=0; i<Y.size(); i++) forAll(Y, i)
{ {
if (Y[i].name() != inertSpecie) if (Y[i].name() != inertSpecie)
{ {

View File

@ -13,6 +13,14 @@
word inertSpecie(thermo.lookup("inertSpecie")); word inertSpecie(thermo.lookup("inertSpecie"));
if (!composition.contains(inertSpecie))
{
FatalErrorIn(args.executable())
<< "Specified inert specie '" << inertSpecie << "' not found in "
<< "species list. Available species:" << composition.species()
<< exit(FatalError);
}
volScalarField& p = thermo.p(); volScalarField& p = thermo.p();
volScalarField& h = thermo.h(); volScalarField& h = thermo.h();
const volScalarField& T = thermo.T(); const volScalarField& T = thermo.T();

View File

@ -0,0 +1,6 @@
incompressibleThreePhaseMixture/threePhaseMixture.C
threePhaseInterfaceProperties/threePhaseInterfaceProperties.C
interMixingFoam.C
EXE = $(FOAM_APPBIN)/interMixingFoam

View File

@ -0,0 +1,17 @@
INTERFOAM = $(FOAM_SOLVERS)/multiphase/interFoam
EXE_INC = \
-I$(INTERFOAM) \
-IincompressibleThreePhaseMixture \
-IthreePhaseInterfaceProperties \
-I$(LIB_SRC)/transportModels/interfaceProperties/lnInclude \
-I$(LIB_SRC)/turbulenceModels/incompressible/turbulenceModel \
-I$(LIB_SRC)/finiteVolume/lnInclude \
-I$(LIB_SRC)/transportModels
EXE_LIBS = \
-linterfaceProperties \
-lincompressibleTransportModels \
-lincompressibleRASModels \
-lincompressibleLESModels \
-lfiniteVolume

View File

@ -0,0 +1,164 @@
{
word alphaScheme("div(phi,alpha)");
word alpharScheme("div(phirb,alpha)");
surfaceScalarField phir
(
IOobject
(
"phir",
runTime.timeName(),
mesh,
IOobject::NO_READ,
IOobject::NO_WRITE
),
interface.cAlpha()*mag(phi/mesh.magSf())*interface.nHatf()
);
for (int gCorr=0; gCorr<nAlphaCorr; gCorr++)
{
// Create the limiter to be used for all phase-fractions
scalarField allLambda(mesh.nFaces(), 1.0);
// Split the limiter into a surfaceScalarField
slicedSurfaceScalarField lambda
(
IOobject
(
"lambda",
mesh.time().timeName(),
mesh,
IOobject::NO_READ,
IOobject::NO_WRITE,
false
),
mesh,
dimless,
allLambda
);
// Create the complete convection flux for alpha1
surfaceScalarField phiAlpha1 =
fvc::flux
(
phi,
alpha1,
alphaScheme
)
+ fvc::flux
(
-fvc::flux(-phir, alpha2, alpharScheme),
alpha1,
alpharScheme
)
+ fvc::flux
(
-fvc::flux(-phir, alpha3, alpharScheme),
alpha1,
alpharScheme
);
// Create the bounded (upwind) flux for alpha1
surfaceScalarField phiAlpha1BD =
upwind<scalar>(mesh, phi).flux(alpha1);
// Calculate the flux correction for alpha1
phiAlpha1 -= phiAlpha1BD;
// Calculate the limiter for alpha1
MULES::limiter
(
allLambda,
oneField(),
alpha1,
phiAlpha1BD,
phiAlpha1,
zeroField(),
zeroField(),
1,
0,
3
);
// Create the complete flux for alpha2
surfaceScalarField phiAlpha2 =
fvc::flux
(
phi,
alpha2,
alphaScheme
)
+ fvc::flux
(
-fvc::flux(phir, alpha1, alpharScheme),
alpha2,
alpharScheme
);
// Create the bounded (upwind) flux for alpha2
surfaceScalarField phiAlpha2BD =
upwind<scalar>(mesh, phi).flux(alpha2);
// Calculate the flux correction for alpha2
phiAlpha2 -= phiAlpha2BD;
// Further limit the limiter for alpha2
MULES::limiter
(
allLambda,
oneField(),
alpha2,
phiAlpha2BD,
phiAlpha2,
zeroField(),
zeroField(),
1,
0,
3
);
// Construct the limited fluxes
phiAlpha1 = phiAlpha1BD + lambda*phiAlpha1;
phiAlpha2 = phiAlpha2BD + lambda*phiAlpha2;
// Solve for alpha1
solve(fvm::ddt(alpha1) + fvc::div(phiAlpha1));
// Create the diffusion coefficients for alpha2<->alpha3
volScalarField Dc23 = D23*max(alpha3, scalar(0))*pos(alpha2);
volScalarField Dc32 = D23*max(alpha2, scalar(0))*pos(alpha3);
// Add the diffusive flux for alpha3->alpha2
phiAlpha2 -= fvc::interpolate(Dc32)*mesh.magSf()*fvc::snGrad(alpha1);
// Solve for alpha2
fvScalarMatrix alpha2Eqn
(
fvm::ddt(alpha2)
+ fvc::div(phiAlpha2)
- fvm::laplacian(Dc23 + Dc32, alpha2)
);
alpha2Eqn.solve();
// Construct the complete mass flux
rhoPhi =
phiAlpha1*(rho1 - rho3)
+ (phiAlpha2 + alpha2Eqn.flux())*(rho2 - rho3)
+ phi*rho3;
alpha3 = 1.0 - alpha1 - alpha2;
}
Info<< "Air phase volume fraction = "
<< alpha1.weightedAverage(mesh.V()).value()
<< " Min(alpha1) = " << min(alpha1).value()
<< " Max(alpha1) = " << max(alpha1).value()
<< endl;
Info<< "Liquid phase volume fraction = "
<< alpha2.weightedAverage(mesh.V()).value()
<< " Min(alpha2) = " << min(alpha2).value()
<< " Max(alpha2) = " << max(alpha2).value()
<< endl;
}

View File

@ -0,0 +1,43 @@
label nAlphaCorr
(
readLabel(piso.lookup("nAlphaCorr"))
);
label nAlphaSubCycles
(
readLabel(piso.lookup("nAlphaSubCycles"))
);
if (nAlphaSubCycles > 1)
{
surfaceScalarField rhoPhiSum = 0.0*rhoPhi;
dimensionedScalar totalDeltaT = runTime.deltaT();
for
(
subCycle<volScalarField> alphaSubCycle(alpha1, nAlphaSubCycles);
!(++alphaSubCycle).end();
)
{
# include "alphaEqns.H"
rhoPhiSum += (runTime.deltaT()/totalDeltaT)*rhoPhi;
}
rhoPhi = rhoPhiSum;
}
else
{
# include "alphaEqns.H"
}
interface.correct();
{
volScalarField rhoNew = alpha1*rho1 + alpha2*rho2 + alpha3*rho3;
//solve(fvm::ddt(rho) + fvc::div(rhoPhi));
//Info<< "density error = "
// << max((mag(rho - rhoNew)/mag(rhoNew))().internalField()) << endl;
rho == rhoNew;
}

View File

@ -0,0 +1,132 @@
Info<< "Reading field p\n" << endl;
volScalarField p
(
IOobject
(
"p",
runTime.timeName(),
mesh,
IOobject::MUST_READ,
IOobject::AUTO_WRITE
),
mesh
);
Info<< "Reading field alpha1\n" << endl;
volScalarField alpha1
(
IOobject
(
"alpha1",
runTime.timeName(),
mesh,
IOobject::MUST_READ,
IOobject::AUTO_WRITE
),
mesh
);
Info<< "Reading field alpha2\n" << endl;
volScalarField alpha2
(
IOobject
(
"alpha2",
runTime.timeName(),
mesh,
IOobject::MUST_READ,
IOobject::AUTO_WRITE
),
mesh
);
Info<< "Reading field alpha3\n" << endl;
volScalarField alpha3
(
IOobject
(
"alpha3",
runTime.timeName(),
mesh,
IOobject::MUST_READ,
IOobject::AUTO_WRITE
),
mesh
);
alpha3 == 1.0 - alpha1 - alpha2;
Info<< "Reading field U\n" << endl;
volVectorField U
(
IOobject
(
"U",
runTime.timeName(),
mesh,
IOobject::MUST_READ,
IOobject::AUTO_WRITE
),
mesh
);
# include "createPhi.H"
threePhaseMixture threePhaseProperties(U, phi);
const dimensionedScalar& rho1 = threePhaseProperties.rho1();
const dimensionedScalar& rho2 = threePhaseProperties.rho2();
const dimensionedScalar& rho3 = threePhaseProperties.rho3();
dimensionedScalar D23(threePhaseProperties.lookup("D23"));
// Need to store rho for ddt(rho, U)
volScalarField rho
(
IOobject
(
"rho",
runTime.timeName(),
mesh,
IOobject::READ_IF_PRESENT
),
alpha1*rho1 + alpha2*rho2 + alpha3*rho3,
alpha1.boundaryField().types()
);
rho.oldTime();
// Mass flux
// Initialisation does not matter because rhoPhi is reset after the
// alpha solution before it is used in the U equation.
surfaceScalarField rhoPhi
(
IOobject
(
"rho*phi",
runTime.timeName(),
mesh,
IOobject::NO_READ,
IOobject::NO_WRITE
),
rho1*phi
);
label pRefCell = 0;
scalar pRefValue = 0.0;
setRefCell(p, mesh.solutionDict().subDict("PISO"), pRefCell, pRefValue);
// Construct interface from alpha distribution
threePhaseInterfaceProperties interface(threePhaseProperties);
// Construct incompressible turbulence model
autoPtr<incompressible::turbulenceModel> turbulence
(
incompressible::turbulenceModel::New(U, phi, threePhaseProperties)
);

View File

@ -0,0 +1,204 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 1991-2009 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 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Class
threePhaseMixture
\*---------------------------------------------------------------------------*/
#include "threePhaseMixture.H"
#include "addToRunTimeSelectionTable.H"
#include "surfaceFields.H"
#include "fvc.H"
// * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * * //
//- Calculate and return the laminar viscosity
void Foam::threePhaseMixture::calcNu()
{
// Average kinematic viscosity calculated from dynamic viscosity
nu_ = mu()/(alpha1_*rho1_ + alpha2_*rho2_ + alpha3_*rho3_);
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::threePhaseMixture::threePhaseMixture
(
const volVectorField& U,
const surfaceScalarField& phi
)
:
transportModel(U, phi),
phase1Name_("phase1"),
phase2Name_("phase2"),
phase3Name_("phase3"),
nuModel1_
(
viscosityModel::New
(
"nu1",
subDict(phase1Name_),
U,
phi
)
),
nuModel2_
(
viscosityModel::New
(
"nu2",
subDict(phase2Name_),
U,
phi
)
),
nuModel3_
(
viscosityModel::New
(
"nu3",
subDict(phase2Name_),
U,
phi
)
),
rho1_(nuModel1_->viscosityProperties().lookup("rho")),
rho2_(nuModel2_->viscosityProperties().lookup("rho")),
rho3_(nuModel3_->viscosityProperties().lookup("rho")),
U_(U),
phi_(phi),
alpha1_(U_.db().lookupObject<const volScalarField> ("alpha1")),
alpha2_(U_.db().lookupObject<const volScalarField> ("alpha2")),
alpha3_(U_.db().lookupObject<const volScalarField> ("alpha3")),
nu_
(
IOobject
(
"nu",
U_.time().timeName(),
U_.db()
),
U_.mesh(),
dimensionedScalar("nu", dimensionSet(0, 2, -1, 0, 0), 0),
calculatedFvPatchScalarField::typeName
)
{
calcNu();
}
// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
Foam::tmp<Foam::volScalarField> Foam::threePhaseMixture::mu() const
{
return tmp<volScalarField>
(
new volScalarField
(
"mu",
alpha1_*rho1_*nuModel1_->nu()
+ alpha2_*rho2_*nuModel2_->nu()
+ alpha3_*rho3_*nuModel3_->nu()
)
);
}
Foam::tmp<Foam::surfaceScalarField> Foam::threePhaseMixture::muf() const
{
surfaceScalarField alpha1f = fvc::interpolate(alpha1_);
surfaceScalarField alpha2f = fvc::interpolate(alpha2_);
surfaceScalarField alpha3f = fvc::interpolate(alpha3_);
return tmp<surfaceScalarField>
(
new surfaceScalarField
(
"mu",
alpha1f*rho1_*fvc::interpolate(nuModel1_->nu())
+ alpha2f*rho2_*fvc::interpolate(nuModel2_->nu())
+ alpha3f*rho3_*fvc::interpolate(nuModel3_->nu())
)
);
}
Foam::tmp<Foam::surfaceScalarField> Foam::threePhaseMixture::nuf() const
{
surfaceScalarField alpha1f = fvc::interpolate(alpha1_);
surfaceScalarField alpha2f = fvc::interpolate(alpha2_);
surfaceScalarField alpha3f = fvc::interpolate(alpha3_);
return tmp<surfaceScalarField>
(
new surfaceScalarField
(
"nu",
(
alpha1f*rho1_*fvc::interpolate(nuModel1_->nu())
+ alpha2f*rho2_*fvc::interpolate(nuModel2_->nu())
+ alpha3f*rho3_*fvc::interpolate(nuModel3_->nu())
)/(alpha1f*rho1_ + alpha2f*rho2_ + alpha3f*rho3_)
)
);
}
bool Foam::threePhaseMixture::read()
{
if (transportModel::read())
{
if
(
nuModel1_().read(*this)
&& nuModel2_().read(*this)
&& nuModel3_().read(*this)
)
{
nuModel1_->viscosityProperties().lookup("rho") >> rho1_;
nuModel2_->viscosityProperties().lookup("rho") >> rho2_;
nuModel3_->viscosityProperties().lookup("rho") >> rho3_;
return true;
}
else
{
return false;
}
}
else
{
return false;
}
}
// ************************************************************************* //

View File

@ -0,0 +1,197 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 1991-2009 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 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Class
threePhaseMixture
Description
SourceFiles
threePhaseMixture.C
\*---------------------------------------------------------------------------*/
#ifndef threePhaseMixture_H
#define threePhaseMixture_H
#include "incompressible/transportModel/transportModel.H"
#include "incompressible/viscosityModels/viscosityModel/viscosityModel.H"
#include "dimensionedScalar.H"
#include "volFields.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class threePhaseMixture Declaration
\*---------------------------------------------------------------------------*/
class threePhaseMixture
:
public transportModel
{
// Private data
word phase1Name_;
word phase2Name_;
word phase3Name_;
autoPtr<viscosityModel> nuModel1_;
autoPtr<viscosityModel> nuModel2_;
autoPtr<viscosityModel> nuModel3_;
dimensionedScalar rho1_;
dimensionedScalar rho2_;
dimensionedScalar rho3_;
const volVectorField& U_;
const surfaceScalarField& phi_;
const volScalarField& alpha1_;
const volScalarField& alpha2_;
const volScalarField& alpha3_;
volScalarField nu_;
// Private Member Functions
//- Calculate and return the laminar viscosity
void calcNu();
public:
// Constructors
//- Construct from components
threePhaseMixture
(
const volVectorField& U,
const surfaceScalarField& phi
);
// Destructor
~threePhaseMixture()
{}
// Member Functions
//- Return const-access to phase1 viscosityModel
const viscosityModel& nuModel1() const
{
return nuModel1_();
}
//- Return const-access to phase2 viscosityModel
const viscosityModel& nuModel2() const
{
return nuModel2_();
}
//- Return const-access to phase3 viscosityModel
const viscosityModel& nuModel3() const
{
return nuModel3_();
}
//- Return const-access to phase1 density
const dimensionedScalar& rho1() const
{
return rho1_;
}
//- Return const-access to phase2 density
const dimensionedScalar& rho2() const
{
return rho2_;
};
//- Return const-access to phase3 density
const dimensionedScalar& rho3() const
{
return rho3_;
};
const volScalarField& alpha1() const
{
return alpha1_;
}
const volScalarField& alpha2() const
{
return alpha2_;
}
const volScalarField& alpha3() const
{
return alpha3_;
}
//- Return the velocity
const volVectorField& U() const
{
return U_;
}
//- Return the dynamic laminar viscosity
tmp<volScalarField> mu() const;
//- Return the face-interpolated dynamic laminar viscosity
tmp<surfaceScalarField> muf() const;
//- Return the kinematic laminar viscosity
tmp<volScalarField> nu() const
{
return nu_;
}
//- Return the face-interpolated dynamic laminar viscosity
tmp<surfaceScalarField> nuf() const;
//- Correct the laminar viscosity
void correct()
{
calcNu();
}
//- Read base transportProperties dictionary
bool read();
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,102 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 1991-2009 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 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Application
interMixingFoam
Description
Solver for 3 incompressible fluids, two of which are miscible,
using a VOF method to capture the interface.
\*---------------------------------------------------------------------------*/
#include "fvCFD.H"
#include "MULES.H"
#include "subCycle.H"
#include "threePhaseMixture.H"
#include "threePhaseInterfaceProperties.H"
#include "turbulenceModel.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
int main(int argc, char *argv[])
{
#include "setRootCase.H"
#include "createTime.H"
#include "createMesh.H"
#include "readGravitationalAcceleration.H"
#include "readPISOControls.H"
#include "initContinuityErrs.H"
#include "createFields.H"
#include "readTimeControls.H"
#include "CourantNo.H"
#include "setInitialDeltaT.H"
#include "correctPhi.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
Info<< "\nStarting time loop\n" << endl;
while (runTime.run())
{
#include "readPISOControls.H"
#include "readTimeControls.H"
#include "CourantNo.H"
#include "setDeltaT.H"
runTime++;
Info<< "Time = " << runTime.timeName() << nl << endl;
threePhaseProperties.correct();
#include "alphaEqnsSubCycle.H"
#define twoPhaseProperties threePhaseProperties
#include "UEqn.H"
// --- PISO loop
for (int corr=0; corr<nCorr; corr++)
{
#include "pEqn.H"
}
#include "continuityErrs.H"
turbulence->correct();
runTime.write();
Info<< "ExecutionTime = " << runTime.elapsedCpuTime() << " s"
<< " ClockTime = " << runTime.elapsedClockTime() << " s"
<< nl << endl;
}
Info<< "\n end \n";
return(0);
}
// ************************************************************************* //

View File

@ -0,0 +1,209 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 1991-2009 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 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Application
threePhaseInterfaceProperties
Description
Properties to aid interFoam :
1. Correct the alpha boundary condition for dynamic contact angle.
2. Calculate interface curvature.
\*---------------------------------------------------------------------------*/
#include "threePhaseInterfaceProperties.H"
#include "alphaContactAngleFvPatchScalarField.H"
#include "mathematicalConstants.H"
#include "surfaceInterpolate.H"
#include "fvcDiv.H"
#include "fvcGrad.H"
// * * * * * * * * * * * * * * * Static Member Data * * * * * * * * * * * * //
const Foam::scalar Foam::threePhaseInterfaceProperties::convertToRad =
Foam::constant::mathematical::pi/180.0;
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
// Correction for the boundary condition on the unit normal nHat on
// walls to produce the correct contact angle.
// The dynamic contact angle is calculated from the component of the
// velocity on the direction of the interface, parallel to the wall.
void Foam::threePhaseInterfaceProperties::correctContactAngle
(
surfaceVectorField::GeometricBoundaryField& nHatb
) const
{
const volScalarField::GeometricBoundaryField& alpha1 =
mixture_.alpha1().boundaryField();
const volScalarField::GeometricBoundaryField& alpha2 =
mixture_.alpha2().boundaryField();
const volScalarField::GeometricBoundaryField& alpha3 =
mixture_.alpha3().boundaryField();
const volVectorField::GeometricBoundaryField& U =
mixture_.U().boundaryField();
const fvMesh& mesh = mixture_.U().mesh();
const fvBoundaryMesh& boundary = mesh.boundary();
forAll(boundary, patchi)
{
if (isA<alphaContactAngleFvPatchScalarField>(alpha1[patchi]))
{
const alphaContactAngleFvPatchScalarField& a2cap =
refCast<const alphaContactAngleFvPatchScalarField>
(alpha2[patchi]);
const alphaContactAngleFvPatchScalarField& a3cap =
refCast<const alphaContactAngleFvPatchScalarField>
(alpha3[patchi]);
scalarField twoPhaseAlpha2 = max(a2cap, scalar(0));
scalarField twoPhaseAlpha3 = max(a3cap, scalar(0));
scalarField sumTwoPhaseAlpha =
twoPhaseAlpha2 + twoPhaseAlpha3 + SMALL;
twoPhaseAlpha2 /= sumTwoPhaseAlpha;
twoPhaseAlpha3 /= sumTwoPhaseAlpha;
fvsPatchVectorField& nHatp = nHatb[patchi];
scalarField theta =
convertToRad
*(
twoPhaseAlpha2*(180 - a2cap.theta(U[patchi], nHatp))
+ twoPhaseAlpha3*(180 - a3cap.theta(U[patchi], nHatp))
);
vectorField nf = boundary[patchi].nf();
// Reset nHatPatch to correspond to the contact angle
scalarField a12 = nHatp & nf;
scalarField b1 = cos(theta);
scalarField b2(nHatp.size());
forAll(b2, facei)
{
b2[facei] = cos(acos(a12[facei]) - theta[facei]);
}
scalarField det = 1.0 - a12*a12;
scalarField a = (b1 - a12*b2)/det;
scalarField b = (b2 - a12*b1)/det;
nHatp = a*nf + b*nHatp;
nHatp /= (mag(nHatp) + deltaN_.value());
}
}
}
void Foam::threePhaseInterfaceProperties::calculateK()
{
const volScalarField& alpha1 = mixture_.alpha1();
const fvMesh& mesh = alpha1.mesh();
const surfaceVectorField& Sf = mesh.Sf();
// Cell gradient of alpha
volVectorField gradAlpha = fvc::grad(alpha1);
// Interpolated face-gradient of alpha
surfaceVectorField gradAlphaf = fvc::interpolate(gradAlpha);
// Face unit interface normal
surfaceVectorField nHatfv = gradAlphaf/(mag(gradAlphaf) + deltaN_);
correctContactAngle(nHatfv.boundaryField());
// Face unit interface normal flux
nHatf_ = nHatfv & Sf;
// Simple expression for curvature
K_ = -fvc::div(nHatf_);
// Complex expression for curvature.
// Correction is formally zero but numerically non-zero.
//volVectorField nHat = gradAlpha/(mag(gradAlpha) + deltaN_);
//nHat.boundaryField() = nHatfv.boundaryField();
//K_ = -fvc::div(nHatf_) + (nHat & fvc::grad(nHatfv) & nHat);
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::threePhaseInterfaceProperties::threePhaseInterfaceProperties
(
const threePhaseMixture& mixture
)
:
mixture_(mixture),
cAlpha_
(
readScalar
(
mixture.U().mesh().solutionDict().subDict("PISO").lookup("cAlpha")
)
),
sigma12_(mixture.lookup("sigma12")),
sigma13_(mixture.lookup("sigma13")),
deltaN_
(
"deltaN",
1e-8/pow(average(mixture.U().mesh().V()), 1.0/3.0)
),
nHatf_
(
(
fvc::interpolate(fvc::grad(mixture.alpha1()))
/(mag(fvc::interpolate(fvc::grad(mixture.alpha1()))) + deltaN_)
) & mixture.alpha1().mesh().Sf()
),
K_
(
IOobject
(
"K",
mixture.alpha1().time().timeName(),
mixture.alpha1().mesh()
),
-fvc::div(nHatf_)
)
{
calculateK();
}
// ************************************************************************* //

View File

@ -0,0 +1,157 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 1991-2009 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 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Class
threePhaseInterfaceProperties
Description
Properties to aid interFoam :
1. Correct the alpha boundary condition for dynamic contact angle.
2. Calculate interface curvature.
SourceFiles
threePhaseInterfaceProperties.C
\*---------------------------------------------------------------------------*/
#ifndef threePhaseInterfaceProperties_H
#define threePhaseInterfaceProperties_H
#include "threePhaseMixture.H"
#include "surfaceFields.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class threePhaseInterfaceProperties Declaration
\*---------------------------------------------------------------------------*/
class threePhaseInterfaceProperties
{
// Private data
const threePhaseMixture& mixture_;
//- Compression coefficient
scalar cAlpha_;
//- Surface tension 1-2
dimensionedScalar sigma12_;
//- Surface tension 1-3
dimensionedScalar sigma13_;
//- Stabilisation for normalisation of the interface normal
const dimensionedScalar deltaN_;
surfaceScalarField nHatf_;
volScalarField K_;
// Private Member Functions
//- Disallow default bitwise copy construct and assignment
threePhaseInterfaceProperties(const threePhaseInterfaceProperties&);
void operator=(const threePhaseInterfaceProperties&);
//- Correction for the boundary condition on the unit normal nHat on
// walls to produce the correct contact dynamic angle
// calculated from the component of U parallel to the wall
void correctContactAngle
(
surfaceVectorField::GeometricBoundaryField& nHat
) const;
//- Re-calculate the interface curvature
void calculateK();
public:
//- Conversion factor for degrees into radians
static const scalar convertToRad;
// Constructors
//- Construct from volume fraction field alpha and IOdictionary
threePhaseInterfaceProperties(const threePhaseMixture& mixture);
// Member Functions
scalar cAlpha() const
{
return cAlpha_;
}
const dimensionedScalar& deltaN() const
{
return deltaN_;
}
const surfaceScalarField& nHatf() const
{
return nHatf_;
}
const volScalarField& K() const
{
return K_;
}
tmp<volScalarField> sigma() const
{
volScalarField limitedAlpha2 = max(mixture_.alpha2(), scalar(0));
volScalarField limitedAlpha3 = max(mixture_.alpha3(), scalar(0));
return
(limitedAlpha2*sigma12_ + limitedAlpha3*sigma13_)
/(limitedAlpha2 + limitedAlpha3 + SMALL);
}
tmp<volScalarField> sigmaK() const
{
return sigma()*K_;
}
void correct()
{
calculateK();
}
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -22,13 +22,9 @@ License
along with OpenFOAM; if not, write to the Free Software Foundation, along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Description
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#include "GatherBase.H" #include "GatherBase.H"
#include "IPstream.H"
#include "OPstream.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View File

@ -0,0 +1,6 @@
#!/bin/sh
if [ "$TEC_360_2009" ]
then
wmake
fi

View File

@ -0,0 +1,5 @@
tecplotWriter.C
vtkMesh.C
foamToTecplot360.C
EXE = $(FOAM_APPBIN)/foamToTecplot360

View File

@ -0,0 +1,14 @@
EXE_INC = \
-I$(TEC_360_2009)/include \
/* -I../tecio/tecsrc/lnInclude/ */ \
-I$(LIB_SRC)/lagrangian/basic/lnInclude \
-I$(LIB_SRC)/finiteVolume/lnInclude \
-I$(LIB_SRC)/meshTools/lnInclude
EXE_LIBS = \
$(TEC_360_2009)/lib/tecio64.a \
/* -L$(FOAM_USER_LIBBIN) -ltecio */ \
-llagrangian \
-lfiniteVolume \
-lmeshTools

View File

@ -0,0 +1,87 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 1991-2009 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 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
\*---------------------------------------------------------------------------*/
#include "readFields.H"
#include "IOobjectList.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * * Global Functions * * * * * * * * * * * * * //
template<class GeoField>
void readFields
(
const vtkMesh& vMesh,
const typename GeoField::Mesh& mesh,
const IOobjectList& objects,
const HashSet<word>& selectedFields,
PtrList<GeoField>& fields
)
{
// Search list of objects for volScalarFields
IOobjectList fieldObjects(objects.lookupClass(GeoField::typeName));
// Construct the vol scalar fields
label nFields = fields.size();
fields.setSize(nFields + fieldObjects.size());
for
(
IOobjectList::iterator iter = fieldObjects.begin();
iter != fieldObjects.end();
++iter
)
{
if (selectedFields.empty() || selectedFields.found(iter()->name()))
{
fields.set
(
nFields,
vMesh.interpolate
(
GeoField
(
*iter(),
mesh
)
)
);
nFields++;
}
}
fields.setSize(nFields);
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// ************************************************************************* //

View File

@ -22,28 +22,50 @@ License
along with OpenFOAM; if not, write to the Free Software Foundation, along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
InClass
Foam::readFields
Description Description
Prints out a description of the streams
SourceFiles
readFields.C
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#include "IPstream.H" #ifndef readFields_H
#include "OPstream.H" #define readFields_H
#include "fvMesh.H"
#include "PtrList.H"
#include "IOobjectList.H"
#include "HashSet.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
void Foam::IPstream::print(Ostream& os) const namespace Foam
{ {
os << "Reading from processor " << fromProcNo_
<< " to processor " << myProcNo() << Foam::endl;
}
// Read the fields and optionally subset and put on the pointer list
template<class GeoField>
void readFields
(
const vtkMesh& vMesh,
const typename GeoField::Mesh& mesh,
const IOobjectList& objects,
const HashSet<word>& selectedFields,
PtrList<GeoField>& fields
);
void Foam::OPstream::print(Ostream& os) const } // End namespace Foam
{
os << "Writing from processor " << toProcNo_
<< " to processor " << myProcNo() << Foam::endl;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository
# include "readFields.C"
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* // // ************************************************************************* //

View File

@ -0,0 +1,517 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 1991-2009 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 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
\*---------------------------------------------------------------------------*/
#include "tecplotWriter.H"
#include "fvMesh.H"
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
// Construct from components
Foam::tecplotWriter::tecplotWriter(const Time& runTime)
:
runTime_(runTime)
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
void Foam::tecplotWriter::writeInit
(
const word& name,
const string& varNames,
const fileName& fName,
INTEGER4 tecplotFileType
) const
{
Pout<< endl
<< endl
<< "Name:" << name
<< " varNames:" << varNames
<< " to file:" << fName
<< " of type:" << tecplotFileType
<< endl;
INTEGER4 IsDouble = 0; //float
INTEGER4 Debug = 0; //nodebug
if
(
!TECINI112
(
const_cast<char*>(name.c_str()), /* Data Set Title */
const_cast<char*>(varNames.c_str()), /* Variable List */
const_cast<char*>(fName.c_str()), /* File Name */
const_cast<char*>(runTime_.path().c_str()), /* Scratch Directory */
&tecplotFileType,
&Debug,
&IsDouble
)
)
{
// FatalErrorIn("tecplotWriter::writeInit(..) const")
// << "Error in TECINI112." << exit(FatalError);
}
}
void Foam::tecplotWriter::writePolyhedralZone
(
const word& zoneName,
const INTEGER4 strandID,
const fvMesh& mesh,
const List<INTEGER4>& varLocArray,
INTEGER4 nFaceNodes
) const
{
/* Call TECZNE112 */
INTEGER4 NumNodes = mesh.nPoints(); /* number of unique nodes */
INTEGER4 NumElems = mesh.nCells(); /* number of elements */
INTEGER4 NumFaces = mesh.nFaces(); /* number of unique faces */
INTEGER4 ICellMax = 0; /* Not Used, set to zero */
INTEGER4 JCellMax = 0; /* Not Used, set to zero */
INTEGER4 KCellMax = 0; /* Not Used, set to zero */
double SolTime = runTime_.value(); /* solution time */
INTEGER4 StrandID = 1; /* static zone */
INTEGER4 ParentZone = 0; /* no parent zone */
INTEGER4 IsBlock = 1; /* block format */
INTEGER4 NFConns = 0; /* not used for FEPolyhedron
* zones
*/
INTEGER4 FNMode = 0; /* not used for FEPolyhedron
* zones
*/
Pout<< "zoneName:" << zoneName
//<< " varLocArray:" << varLocArray
<< " solTime:" << SolTime
<< endl;
INTEGER4 *PassiveVarArray = NULL;
INTEGER4 *VarShareArray = NULL;
INTEGER4 ShrConn = 0;
INTEGER4 NumBConns = 0; /* No Boundary Connections */
INTEGER4 NumBItems = 0; /* No Boundary Items */
INTEGER4 ZoneType = ZoneType_FEPolyhedron;
if
(
!TECZNE112
(
const_cast<char*>(zoneName.c_str()),
&ZoneType,
&NumNodes,
&NumElems,
&NumFaces,
&ICellMax,
&JCellMax,
&KCellMax,
&SolTime,
&StrandID,
&ParentZone,
&IsBlock,
&NFConns,
&FNMode,
&nFaceNodes,
&NumBConns,
&NumBItems,
PassiveVarArray,
const_cast<INTEGER4*>(varLocArray.begin()),
VarShareArray,
&ShrConn
)
)
{
// FatalErrorIn("tecplotWriter::writePolyhedralZone(..) const")
// << "Error in TECZNE112." << exit(FatalError);
}
}
void Foam::tecplotWriter::writePolygonalZone
(
const word& zoneName,
INTEGER4 strandID,
const indirectPrimitivePatch& pp,
const List<INTEGER4>& varLocArray
) const
{
/* Call TECZNE112 */
INTEGER4 NumNodes = pp.nPoints(); /* number of unique nodes */
INTEGER4 NumElems = pp.size(); /* number of elements */
INTEGER4 NumFaces = pp.nEdges(); /* number of unique faces */
INTEGER4 ICellMax = 0; /* Not Used, set to zero */
INTEGER4 JCellMax = 0; /* Not Used, set to zero */
INTEGER4 KCellMax = 0; /* Not Used, set to zero */
double SolTime = runTime_.value(); /* solution time */
INTEGER4 ParentZone = 0; /* no parent zone */
INTEGER4 IsBlock = 1; /* block format */
INTEGER4 NFConns = 0; /* not used for FEPolyhedron
* zones
*/
INTEGER4 FNMode = 0; /* not used for FEPolyhedron
* zones
*/
INTEGER4 NumFaceNodes = 2*pp.nEdges();
Pout<< "zoneName:" << zoneName
<< " strandID:" << strandID
//<< " varLocArray:" << varLocArray
<< " solTime:" << SolTime
<< endl;
INTEGER4 *PassiveVarArray = NULL;
INTEGER4 *VarShareArray = NULL;
INTEGER4 ShrConn = 0;
INTEGER4 NumBConns = 0; /* No Boundary Connections */
INTEGER4 NumBItems = 0; /* No Boundary Items */
INTEGER4 ZoneType = ZoneType_FEPolygon;
if
(
!TECZNE112
(
const_cast<char*>(zoneName.c_str()),
&ZoneType,
&NumNodes,
&NumElems,
&NumFaces,
&ICellMax,
&JCellMax,
&KCellMax,
&SolTime,
&strandID,
&ParentZone,
&IsBlock,
&NFConns,
&FNMode,
&NumFaceNodes,
&NumBConns,
&NumBItems,
PassiveVarArray,
const_cast<INTEGER4*>(varLocArray.begin()),
VarShareArray,
&ShrConn
)
)
{
// FatalErrorIn("tecplotWriter::writePolygonalZone(..) const")
// << "Error in TECZNE112." << exit(FatalError);
}
}
void Foam::tecplotWriter::writeOrderedZone
(
const word& zoneName,
INTEGER4 strandID,
const label n,
const List<INTEGER4>& varLocArray
) const
{
/* Call TECZNE112 */
INTEGER4 IMax = n; /* number of unique nodes */
INTEGER4 JMax = 1; /* number of elements */
INTEGER4 KMax = 1; /* number of unique faces */
INTEGER4 ICellMax = 0; /* Not Used, set to zero */
INTEGER4 JCellMax = 0; /* Not Used, set to zero */
INTEGER4 KCellMax = 0; /* Not Used, set to zero */
double SolTime = runTime_.value(); /* solution time */
INTEGER4 ParentZone = 0; /* no parent zone */
INTEGER4 IsBlock = 1; /* block format */
INTEGER4 NFConns = 0; /* not used for FEPolyhedron
* zones
*/
INTEGER4 FNMode = 0; /* not used for FEPolyhedron
* zones
*/
INTEGER4 NumFaceNodes = 1;
INTEGER4 NumBConns = 1; /* No Boundary Connections */
INTEGER4 NumBItems = 1; /* No Boundary Items */
Pout<< "zoneName:" << zoneName
<< " strandID:" << strandID
//<< " varLocArray:" << varLocArray
<< " solTime:" << SolTime
<< endl;
INTEGER4 *PassiveVarArray = NULL;
INTEGER4 *VarShareArray = NULL;
INTEGER4 ShrConn = 0;
INTEGER4 ZoneType = ZoneType_Ordered;
if
(
!TECZNE112
(
const_cast<char*>(zoneName.c_str()),
&ZoneType,
&IMax,
&JMax,
&KMax,
&ICellMax,
&JCellMax,
&KCellMax,
&SolTime,
&strandID,
&ParentZone,
&IsBlock,
&NFConns,
&FNMode,
&NumFaceNodes,
&NumBConns,
&NumBItems,
PassiveVarArray,
const_cast<INTEGER4*>(varLocArray.begin()),
VarShareArray,
&ShrConn
)
)
{
// FatalErrorIn("tecplotWriter::writePolygonalZone(..) const")
// << "Error in TECZNE112." << exit(FatalError);
}
}
void Foam::tecplotWriter::writeConnectivity(const fvMesh& mesh) const
{
List<INTEGER4> FaceNodeCounts(mesh.nFaces());
forAll(mesh.faces(), faceI)
{
const face& f = mesh.faces()[faceI];
FaceNodeCounts[faceI] = INTEGER4(f.size());
}
INTEGER4 nFaceNodes = 0;
forAll(mesh.faces(), faceI)
{
nFaceNodes += mesh.faces()[faceI].size();
}
List<INTEGER4> FaceNodes(nFaceNodes);
label nodeI = 0;
forAll(mesh.faces(), faceI)
{
const face& f = mesh.faces()[faceI];
forAll(f, fp)
{
FaceNodes[nodeI++] = INTEGER4(f[fp]+1);
}
}
List<INTEGER4> FaceLeftElems(mesh.nFaces());
forAll(mesh.faceOwner(), faceI)
{
FaceLeftElems[faceI] = mesh.faceOwner()[faceI]+1;
}
List<INTEGER4> FaceRightElems(mesh.nFaces());
forAll(mesh.faceNeighbour(), faceI)
{
FaceRightElems[faceI] = mesh.faceNeighbour()[faceI]+1;
}
for
(
label faceI = mesh.nInternalFaces();
faceI < mesh.nFaces();
faceI++
)
{
FaceRightElems[faceI] = 0;
}
if
(
!TECPOLY112
(
FaceNodeCounts.begin(), /* The face node counts array */
FaceNodes.begin(), /* The face nodes array */
FaceLeftElems.begin(), /* The left elements array */
FaceRightElems.begin(), /* The right elements array */
NULL, /* No boundary connection counts */
NULL, /* No boundary connection elements */
NULL /* No boundary connection zones */
)
)
{
// FatalErrorIn("tecplotWriter::writeConnectivity(const fvMesh&) const")
// << "Error in TECPOLY112." << exit(FatalError);
}
}
void Foam::tecplotWriter::writeConnectivity
(
const indirectPrimitivePatch& pp
) const
{
INTEGER4 NumFaces = pp.nEdges(); /* number of unique faces */
INTEGER4 NumFaceNodes = 2*pp.nEdges();
// All faces (=edges) have 2 nodes
List<INTEGER4> FaceNodeCounts(NumFaces, 2);
List<INTEGER4> FaceNodes(NumFaceNodes);
label nodeI = 0;
forAll(pp.edges(), edgeI)
{
edge e = pp.edges()[edgeI];
if (e[0] > e[1])
{
e = e.reverseEdge();
}
FaceNodes[nodeI++] = INTEGER4(e[0]+1);
FaceNodes[nodeI++] = INTEGER4(e[1]+1);
}
/* Define the right and left elements of each face.
*
* The last step for writing out the polyhedral data is to
* define the right and left neighboring elements for each
* face. The neighboring elements can be determined using the
* right-hand rule. For each face, place your right-hand along
* the face which your fingers pointing the direction of
* incrementing node numbers (i.e. from node 1 to node 2).
* Your right thumb will point towards the right element; the
* element on the other side of your hand is the left element.
*
* The number zero is used to indicate that there isn't an
* element on that side of the face.
*
* Because of the way we numbered the nodes and faces, the
* right element for every face is the element itself
* (element 1) and the left element is "no-neighboring element"
* (element 0).
*/
List<INTEGER4> FaceLeftElems(NumFaces);
List<INTEGER4> FaceRightElems(NumFaces);
const labelListList& edgeFaces = pp.edgeFaces();
forAll(edgeFaces, edgeI)
{
const labelList& eFaces = edgeFaces[edgeI];
if (eFaces.size() == 1)
{
FaceLeftElems[edgeI] = 0;
FaceRightElems[edgeI] = eFaces[0]+1;
}
else if (eFaces.size() == 2)
{
edge e = pp.edges()[edgeI];
if (e[0] > e[1])
{
e = e.reverseEdge();
}
const face& f0 = pp.localFaces()[eFaces[0]];
// The face that uses the vertices of e in increasing order
// is the left face.
label fp = findIndex(f0, e[0]);
bool f0IsLeft = (f0.nextLabel(fp) == e[1]);
if (f0IsLeft)
{
FaceLeftElems[edgeI] = eFaces[0]+1;
FaceRightElems[edgeI] = eFaces[1]+1;
}
else
{
FaceLeftElems[edgeI] = eFaces[1]+1;
FaceRightElems[edgeI] = eFaces[0]+1;
}
}
else
{
// non-manifold. Treat as if open.
FaceLeftElems[edgeI] = 0;
FaceRightElems[edgeI] = eFaces[0]+1;
}
}
/* Write the face map (created above) using TECPOLY112. */
if
(
!TECPOLY112
(
FaceNodeCounts.begin(), /* The face node counts array */
FaceNodes.begin(), /* The face nodes array */
FaceLeftElems.begin(), /* The left elements array */
FaceRightElems.begin(), /* The right elements array */
NULL, /* No boundary connection counts */
NULL, /* No boundary connection elements */
NULL /* No boundary connection zones */
)
)
{
// FatalErrorIn("tecplotWriter::writeConnectivity(..) const")
// << "Error in TECPOLY112." << exit(FatalError);
}
}
void Foam::tecplotWriter::writeEnd() const
{
Pout<< "writeEnd" << endl;
if (!TECEND112())
{
// FatalErrorIn("tecplotWriter::writeEnd() const")
// << "Error in TECEND112." << exit(FatalError);
}
}
// ************************************************************************* //

View File

@ -0,0 +1,179 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 1991-2009 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 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Class
Foam::tecplotWriter
Description
Write binary tecplot files using tecio.
SourceFiles
tecplotWriter.C
tecplotWriterTemplates.C
\*---------------------------------------------------------------------------*/
#ifndef tecplotWriter_H
#define tecplotWriter_H
#include "TECIO.h"
#include "Time.H"
#include "indirectPrimitivePatch.H"
#include "volFields.H"
#include "surfaceFields.H"
using namespace Foam;
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
class fvMesh;
/*---------------------------------------------------------------------------*\
Class tecplotWriter Declaration
\*---------------------------------------------------------------------------*/
class tecplotWriter
{
const Time& runTime_;
public:
// Constructors
//- Construct from components
tecplotWriter(const Time&);
// Member Functions
void writeInit
(
const word& name,
const string& varNames,
const fileName&,
INTEGER4 tecplotFileType
) const;
//- Write mesh as polyhedral zone
void writePolyhedralZone
(
const word& zoneName,
const INTEGER4 strandID,
const fvMesh& mesh,
const List<INTEGER4>& varLocArray,
INTEGER4 nFaceNodes
) const;
//- Write surface as polygonal zone
void writePolygonalZone
(
const word& zoneName,
const INTEGER4 strandID,
const indirectPrimitivePatch& pp,
const List<INTEGER4>& varLocArray
) const;
//- Write unordered data (or rather 1D ordered)
void writeOrderedZone
(
const word& zoneName,
INTEGER4 strandID,
const label n,
const List<INTEGER4>& varLocArray
) const;
//- Write mesh
void writeConnectivity(const fvMesh& mesh) const;
//- Write surface
void writeConnectivity(const indirectPrimitivePatch& pp) const;
void writeEnd() const;
//- Write generic Field
template<class Type>
void writeField(const Field<Type>& fld) const;
//- Get either fvPatchField or patchInternalField
template<class Type>
tmp<Field<Type> > getPatchField
(
const bool nearCellValue,
const GeometricField<Type, fvPatchField, volMesh>& vfld,
const label patchI
) const;
//- Get mixed field: fvsPatchField for boundary faces and
// internalField for internal faces.
template<class Type>
tmp<Field<Type> > getFaceField
(
const GeometricField<Type, fvsPatchField, surfaceMesh>&,
const labelList& faceLabels
) const;
template<class GeoField>
static wordList getNames(const PtrList<GeoField>&);
template<class Type>
static void getTecplotNames
(
const wordList& names,
const INTEGER4 loc,
string& varNames,
DynamicList<INTEGER4>& varLocation
);
template<class GeoField>
static void getTecplotNames
(
const PtrList<GeoField>& flds,
const INTEGER4 loc,
string& varNames,
DynamicList<INTEGER4>& varLocation
);
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository
# include "tecplotWriterTemplates.C"
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,199 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 1991-2009 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 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
\*---------------------------------------------------------------------------*/
#include "tecplotWriter.H"
extern "C"
{
#include "MASTER.h"
#include "GLOBAL.h"
}
#include "fvc.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
template<class Type>
void Foam::tecplotWriter::writeField(const Field<Type>& fld) const
{
for (direction cmpt = 0; cmpt < pTraits<Type>::nComponents; cmpt++)
{
scalarField cmptFld(fld.component(cmpt));
// Convert to float
Field<float> floats(cmptFld.size());
forAll(cmptFld, i)
{
floats[i] = float(cmptFld[i]);
}
INTEGER4 size = INTEGER4(floats.size());
INTEGER4 IsDouble = 0; //float
//Pout<< "Writing component:" << cmpt << " of size:" << size
// << " floats." << endl;
if (!TECDAT112(&size, floats.begin(), &IsDouble))
{
// FatalErrorIn("tecplotWriter::writeField(..) const")
// << "Error in TECDAT112." << exit(FatalError);
}
}
}
template<class Type>
Foam::tmp<Field<Type> > Foam::tecplotWriter::getPatchField
(
const bool nearCellValue,
const GeometricField<Type, fvPatchField, volMesh>& vfld,
const label patchI
) const
{
if (nearCellValue)
{
return vfld.boundaryField()[patchI].patchInternalField();
}
else
{
return vfld.boundaryField()[patchI];
}
}
template<class Type>
Foam::tmp<Field<Type> > Foam::tecplotWriter::getFaceField
(
const GeometricField<Type, fvsPatchField, surfaceMesh>& sfld,
const labelList& faceLabels
) const
{
const polyBoundaryMesh& patches = sfld.mesh().boundaryMesh();
tmp<Field<Type> > tfld(new Field<Type>(faceLabels.size()));
Field<Type>& fld = tfld();
forAll(faceLabels, i)
{
label faceI = faceLabels[i];
label patchI = patches.whichPatch(faceI);
if (patchI == -1)
{
fld[i] = sfld[faceI];
}
else
{
label localFaceI = faceI - patches[patchI].start();
fld[i] = sfld.boundaryField()[patchI][localFaceI];
}
}
return tfld;
}
template<class GeoField>
Foam::wordList Foam::tecplotWriter::getNames
(
const PtrList<GeoField>& flds
)
{
wordList names(flds.size());
forAll(flds, i)
{
names[i] = flds[i].name();
}
return names;
}
template<class Type>
void Foam::tecplotWriter::getTecplotNames
(
const wordList& names,
const INTEGER4 loc,
string& varNames,
DynamicList<INTEGER4>& varLocation
)
{
forAll(names, i)
{
if (!varNames.empty())
{
varNames += " ";
}
label nCmpts = pTraits<Type>::nComponents;
if (nCmpts == 1)
{
varNames += names[i];
varLocation.append(loc);
}
else
{
for
(
direction cmpt = 0;
cmpt < nCmpts;
cmpt++
)
{
string fldName =
(cmpt != 0 ? " " : string::null)
+ names[i]
+ "_"
+ pTraits<Type>::componentNames[cmpt];
varNames += fldName;
varLocation.append(loc);
}
}
}
}
template<class GeoField>
void Foam::tecplotWriter::getTecplotNames
(
const PtrList<GeoField>& flds,
const INTEGER4 loc,
string& varNames,
DynamicList<INTEGER4>& varLocation
)
{
getTecplotNames<typename GeoField::value_type>
(
getNames(flds),
loc,
varNames,
varLocation
);
}
// ************************************************************************* //

View File

@ -0,0 +1,84 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 1991-2009 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 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
\*---------------------------------------------------------------------------*/
#include "vtkMesh.H"
#include "fvMeshSubset.H"
#include "Time.H"
#include "cellSet.H"
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
// Construct from components
Foam::vtkMesh::vtkMesh
(
fvMesh& baseMesh,
const word& setName
)
:
baseMesh_(baseMesh),
subsetter_(baseMesh),
setName_(setName)
{
if (setName.size())
{
// Read cellSet using whole mesh
cellSet currentSet(baseMesh_, setName_);
// Set current subset
subsetter_.setLargeCellSubset(currentSet);
}
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
Foam::polyMesh::readUpdateState Foam::vtkMesh::readUpdate()
{
polyMesh::readUpdateState meshState = baseMesh_.readUpdate();
if (meshState != polyMesh::UNCHANGED)
{
// Note: since fvMeshSubset has no movePoints() functionality reconstruct
// the subset even if only movement.
// topoPtr_.clear();
if (setName_.size())
{
Info<< "Subsetting mesh based on cellSet " << setName_ << endl;
// Read cellSet using whole mesh
cellSet currentSet(baseMesh_, setName_);
subsetter_.setLargeCellSubset(currentSet);
}
}
return meshState;
}
// ************************************************************************* //

View File

@ -0,0 +1,179 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 1991-2009 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 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Class
Foam::vtkMesh
Description
Encapsulation of VTK mesh data. Holds mesh or meshsubset and
polyhedral-cell decomposition on it.
SourceFiles
vtkMesh.C
\*---------------------------------------------------------------------------*/
#ifndef vtkMesh_H
#define vtkMesh_H
#include "fvMeshSubset.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// Forward declaration of classes
class Time;
/*---------------------------------------------------------------------------*\
Class vtkMesh Declaration
\*---------------------------------------------------------------------------*/
class vtkMesh
{
// Private data
//- Reference to mesh
fvMesh& baseMesh_;
//- Subsetting engine + sub-fvMesh
fvMeshSubset subsetter_;
//- Current cellSet (or empty)
const word setName_;
// //- Current decomposition of topology
// mutable autoPtr<vtkTopo> topoPtr_;
// Private Member Functions
//- Disallow default bitwise copy construct
vtkMesh(const vtkMesh&);
//- Disallow default bitwise assignment
void operator=(const vtkMesh&);
public:
// Constructors
//- Construct from components
vtkMesh(fvMesh& baseMesh, const word& setName = "");
// Member Functions
// Access
//- whole mesh
const fvMesh& baseMesh() const
{
return baseMesh_;
}
const fvMeshSubset& subsetter() const
{
return subsetter_;
}
//- Check if running subMesh
bool useSubMesh() const
{
return setName_.size();
}
// //- topology
// const vtkTopo& topo() const
// {
// if (topoPtr_.empty())
// {
// topoPtr_.reset(new vtkTopo(mesh()));
// }
// return topoPtr_();
// }
//- Access either mesh or submesh
const fvMesh& mesh() const
{
if (useSubMesh())
{
return subsetter_.subMesh();
}
else
{
return baseMesh_;
}
}
// //- Number of field cells
// label nFieldCells() const
// {
// return topo().vertLabels().size();
// }
//
// //- Number of field points
// label nFieldPoints() const
// {
// return mesh().nPoints() + topo().addPointCellLabels().size();
// }
// Edit
//- Read mesh
polyMesh::readUpdateState readUpdate();
//- Map volume field (does in fact do very little interpolation;
// just copied from fvMeshSubset)
template<class GeoField>
tmp<GeoField> interpolate(const GeoField& fld) const
{
if (useSubMesh())
{
tmp<GeoField> subFld = subsetter_.interpolate(fld);
subFld().rename(fld.name());
return subFld;
}
else
{
return fld;
}
}
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -83,12 +83,13 @@ Usage
Combine all patches into a single file Combine all patches into a single file
@param -excludePatches \<patchNames\>\n @param -excludePatches \<patchNames\>\n
Specify patches to exclude. For example, Specify patches (wildcards) to exclude. For example,
@verbatim @verbatim
-excludePatches "( inlet_1 inlet_2 )" -excludePatches '( inlet_1 inlet_2 "proc.*")'
@endverbatim @endverbatim
The quoting is required to avoid shell expansions and to pass the The quoting is required to avoid shell expansions and to pass the
information as a single argument. information as a single argument. The double quotes denote a regular
expression.
@param -useTimeName \n @param -useTimeName \n
use the time index in the VTK file name instead of the time index use the time index in the VTK file name instead of the time index
@ -140,6 +141,7 @@ Note
#include "faceZoneMesh.H" #include "faceZoneMesh.H"
#include "Cloud.H" #include "Cloud.H"
#include "passiveParticle.H" #include "passiveParticle.H"
#include "stringListOps.H"
#include "vtkMesh.H" #include "vtkMesh.H"
#include "readFields.H" #include "readFields.H"
@ -192,7 +194,7 @@ void print(Ostream& os, const wordList& flds)
labelList getSelectedPatches labelList getSelectedPatches
( (
const polyBoundaryMesh& patches, const polyBoundaryMesh& patches,
const HashSet<word>& excludePatches const List<wordRe>& excludePatches //HashSet<word>& excludePatches
) )
{ {
DynamicList<label> patchIDs(patches.size()); DynamicList<label> patchIDs(patches.size());
@ -205,14 +207,19 @@ labelList getSelectedPatches
if if
( (
isA<emptyPolyPatch>(pp) isType<emptyPolyPatch>(pp)
|| (Pstream::parRun() && isA<processorPolyPatch>(pp)) || (Pstream::parRun() && isType<processorPolyPatch>(pp))
) )
{ {
Info<< " discarding empty/processor patch " << patchI Info<< " discarding empty/processor patch " << patchI
<< " " << pp.name() << endl; << " " << pp.name() << endl;
} }
else if (!excludePatches.found(pp.name())) else if (findStrings(excludePatches, pp.name()))
{
Info<< " excluding patch " << patchI
<< " " << pp.name() << endl;
}
else
{ {
patchIDs.append(patchI); patchIDs.append(patchI);
Info<< " patch " << patchI << " " << pp.name() << endl; Info<< " patch " << patchI << " " << pp.name() << endl;
@ -224,6 +231,8 @@ labelList getSelectedPatches
// Main program: // Main program:
int main(int argc, char *argv[]) int main(int argc, char *argv[])
@ -283,7 +292,7 @@ int main(int argc, char *argv[])
bool allPatches = args.optionFound("allPatches"); bool allPatches = args.optionFound("allPatches");
HashSet<word> excludePatches; List<wordRe> excludePatches;
if (args.optionFound("excludePatches")) if (args.optionFound("excludePatches"))
{ {
args.optionLookup("excludePatches")() >> excludePatches; args.optionLookup("excludePatches")() >> excludePatches;
@ -771,7 +780,7 @@ int main(int argc, char *argv[])
{ {
const polyPatch& pp = patches[patchI]; const polyPatch& pp = patches[patchI];
if (!excludePatches.found(pp.name())) if (!findStrings(excludePatches, pp.name()))
{ {
mkDir(fvPath/pp.name()); mkDir(fvPath/pp.name());

View File

@ -110,10 +110,9 @@ void Foam::vtkPV3Foam::convertVolFields
// Convert patches - if activated // Convert patches - if activated
// //
// the name for the interpolated patch point field must be consistent // The name for the interpolated patch point field must be consistent
// with the interpolated volume point field // with the interpolated volume point field.
// This could be done better.
// this could be done better
const word pointFldName = "volPointInterpolate(" + tf.name() + ')'; const word pointFldName = "volPointInterpolate(" + tf.name() + ')';
for for

View File

@ -109,11 +109,14 @@ StringStreams = $(Streams)/StringStreams
$(StringStreams)/StringStreamsPrint.C $(StringStreams)/StringStreamsPrint.C
Pstreams = $(Streams)/Pstreams Pstreams = $(Streams)/Pstreams
$(Pstreams)/Pstream.C $(Pstreams)/UIPstream.C
$(Pstreams)/PstreamCommsStruct.C
$(Pstreams)/IPstream.C $(Pstreams)/IPstream.C
$(Pstreams)/UPstream.C
$(Pstreams)/UPstreamCommsStruct.C
$(Pstreams)/Pstream.C
$(Pstreams)/UOPstream.C
$(Pstreams)/OPstream.C $(Pstreams)/OPstream.C
$(Pstreams)/PstreamsPrint.C $(Pstreams)/PstreamBuffers.C
dictionary = db/dictionary dictionary = db/dictionary
$(dictionary)/dictionary.C $(dictionary)/dictionary.C

View File

@ -114,7 +114,7 @@ void Foam::ParSortableList<Type>::checkAndSend
} }
{ {
OPstream toSlave(destProcI); OPstream toSlave(Pstream::blocking, destProcI);
toSlave << values << indices; toSlave << values << indices;
} }
} }
@ -311,7 +311,7 @@ void Foam::ParSortableList<Type>::sort()
Pout<< "Receiving from " << procI << endl; Pout<< "Receiving from " << procI << endl;
} }
IPstream fromSlave(procI); IPstream fromSlave(Pstream::blocking, procI);
fromSlave >> recValues >> recIndices; fromSlave >> recValues >> recIndices;

View File

@ -24,291 +24,22 @@ License
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#include "error.H"
#include "IPstream.H" #include "IPstream.H"
#include "int.H"
#include "token.H"
#include <cctype>
// * * * * * * * * * * * * * * * * Constructor * * * * * * * * * * * * * * * //
// * * * * * * * * * * * * * Private member functions * * * * * * * * * * * // Foam::IPstream::IPstream
inline void Foam::IPstream::checkEof()
{
if (bufPosition_ == messageSize_)
{
setEof();
}
}
template<class T>
inline void Foam::IPstream::readFromBuffer(T& t)
{
const size_t align = sizeof(T);
bufPosition_ = align + ((bufPosition_ - 1) & ~(align - 1));
t = reinterpret_cast<T&>(buf_[bufPosition_]);
bufPosition_ += sizeof(T);
checkEof();
}
inline void Foam::IPstream::readFromBuffer
( (
void* data, const commsTypes commsType,
size_t count, const int fromProcNo,
size_t align const label bufSize,
streamFormat format,
versionNumber version
) )
{ :
if (align > 1) Pstream(commsType, bufSize),
{ UIPstream(commsType, fromProcNo, buf_)
bufPosition_ = align + ((bufPosition_ - 1) & ~(align - 1)); {}
}
register const char* bufPtr = &buf_[bufPosition_];
register char* dataPtr = reinterpret_cast<char*>(data);
register size_t i = count;
while (i--) *dataPtr++ = *bufPtr++;
bufPosition_ += count;
checkEof();
}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::IPstream::~IPstream()
{
if (bufPosition_ < messageSize_)
{
FatalErrorIn("IPstream::~IPstream()")
<< "Message not fully consumed. messageSize:" << messageSize_
<< " bytes of which only " << bufPosition_
<< " consumed." << Foam::abort(FatalError);
}
}
// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
Foam::Istream& Foam::IPstream::read(token& t)
{
// Return the put back token if it exists
if (Istream::getBack(t))
{
return *this;
}
char c;
// return on error
if (!read(c))
{
t.setBad();
return *this;
}
// Set the line number of this token to the current stream line number
t.lineNumber() = lineNumber();
// Analyse input starting with this character.
switch (c)
{
// Punctuation
case token::END_STATEMENT :
case token::BEGIN_LIST :
case token::END_LIST :
case token::BEGIN_SQR :
case token::END_SQR :
case token::BEGIN_BLOCK :
case token::END_BLOCK :
case token::COLON :
case token::COMMA :
case token::ASSIGN :
case token::ADD :
case token::SUBTRACT :
case token::MULTIPLY :
case token::DIVIDE :
{
t = token::punctuationToken(c);
return *this;
}
// Word
case token::WORD :
{
word* pval = new word;
if (read(*pval))
{
if (token::compound::isCompound(*pval))
{
t = token::compound::New(*pval, *this).ptr();
delete pval;
}
else
{
t = pval;
}
}
else
{
delete pval;
t.setBad();
}
return *this;
}
// String
case token::STRING :
{
string* pval = new string;
if (read(*pval))
{
t = pval;
}
else
{
delete pval;
t.setBad();
}
return *this;
}
// Label
case token::LABEL :
{
label val;
if (read(val))
{
t = val;
}
else
{
t.setBad();
}
return *this;
}
// floatScalar
case token::FLOAT_SCALAR :
{
floatScalar val;
if (read(val))
{
t = val;
}
else
{
t.setBad();
}
return *this;
}
// doubleScalar
case token::DOUBLE_SCALAR :
{
doubleScalar val;
if (read(val))
{
t = val;
}
else
{
t.setBad();
}
return *this;
}
// Character (returned as a single character word) or error
default:
{
if (isalpha(c))
{
t = word(c);
return *this;
}
setBad();
t.setBad();
return *this;
}
}
}
Foam::Istream& Foam::IPstream::read(char& c)
{
c = buf_[bufPosition_];
bufPosition_++;
checkEof();
return *this;
}
Foam::Istream& Foam::IPstream::read(word& str)
{
size_t len;
readFromBuffer(len);
str = &buf_[bufPosition_];
bufPosition_ += len + 1;
checkEof();
return *this;
}
Foam::Istream& Foam::IPstream::read(string& str)
{
size_t len;
readFromBuffer(len);
str = &buf_[bufPosition_];
bufPosition_ += len + 1;
checkEof();
return *this;
}
Foam::Istream& Foam::IPstream::read(label& val)
{
readFromBuffer(val);
return *this;
}
Foam::Istream& Foam::IPstream::read(floatScalar& val)
{
readFromBuffer(val);
return *this;
}
Foam::Istream& Foam::IPstream::read(doubleScalar& val)
{
readFromBuffer(val);
return *this;
}
Foam::Istream& Foam::IPstream::read(char* data, std::streamsize count)
{
if (format() != BINARY)
{
FatalErrorIn("IPstream::read(char*, std::streamsize)")
<< "stream format not binary"
<< Foam::abort(FatalError);
}
readFromBuffer(data, count, 8);
return *this;
}
Foam::Istream& Foam::IPstream::rewind()
{
bufPosition_ = 0;
return *this;
}
// ************************************************************************* // // ************************************************************************* //

View File

@ -38,7 +38,7 @@ SourceFiles
#ifndef IPstream_H #ifndef IPstream_H
#define IPstream_H #define IPstream_H
#include "Istream.H" #include "UIPstream.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -52,26 +52,8 @@ namespace Foam
class IPstream class IPstream
: :
public Pstream, public Pstream,
public Istream public UIPstream
{ {
// Private data
int fromProcNo_;
label messageSize_;
// Private member functions
//- Check the bufferPosition_ against messageSize_ for EOF
inline void checkEof();
//- Read a T from the transfer buffer
template<class T>
inline void readFromBuffer(T&);
//- Read data from the transfer buffer
inline void readFromBuffer(void* data, size_t count, size_t align);
public: public:
@ -88,76 +70,6 @@ public:
versionNumber version=currentVersion versionNumber version=currentVersion
); );
// Destructor
~IPstream();
// Member functions
// Inquiry
//- Return flags of output stream
ios_base::fmtflags flags() const
{
return ios_base::fmtflags(0);
}
// Read functions
//- Read into given buffer from given processor and return the
// message size
static label read
(
const commsTypes commsType,
const int fromProcNo,
char* buf,
const std::streamsize bufSize
);
//- Return next token from stream
Istream& read(token&);
//- Read a character
Istream& read(char&);
//- Read a word
Istream& read(word&);
// Read a string (including enclosing double-quotes)
Istream& read(string&);
//- Read a label
Istream& read(label&);
//- Read a floatScalar
Istream& read(floatScalar&);
//- Read a doubleScalar
Istream& read(doubleScalar&);
//- Read binary block
Istream& read(char*, std::streamsize);
//- Rewind and return the stream so that it may be read again
Istream& rewind();
// Edit
//- Set flags of stream
ios_base::fmtflags flags(const ios_base::fmtflags)
{
return ios_base::fmtflags(0);
}
// Print
//- Print description of IOstream to Ostream
void print(Ostream&) const;
}; };

View File

@ -22,68 +22,9 @@ License
along with OpenFOAM; if not, write to the Free Software Foundation, along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Description
Write primitive and binary block from OPstream
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#include "error.H"
#include "OPstream.H" #include "OPstream.H"
#include "int.H"
#include "token.H"
#include <cctype>
// * * * * * * * * * * * * * Private member functions * * * * * * * * * * * //
template<class T>
inline void Foam::OPstream::writeToBuffer(const T& t)
{
writeToBuffer(&t, sizeof(T), sizeof(T));
}
inline void Foam::OPstream::writeToBuffer(const char& c)
{
if (size_t(buf_.size()) < bufPosition_ + 1U)
{
enlargeBuffer(1);
}
buf_[bufPosition_] = c;
bufPosition_ ++;
}
inline void Foam::OPstream::writeToBuffer
(
const void* data,
size_t count,
size_t align
)
{
label oldPos = bufPosition_;
if (align > 1)
{
// Align bufPosition. Pads bufPosition_ - oldPos characters.
bufPosition_ = align + ((bufPosition_ - 1) & ~(align - 1));
}
if (size_t(buf_.size()) < bufPosition_ + count)
{
enlargeBuffer(bufPosition_ - oldPos + count);
}
register char* bufPtr = &buf_[bufPosition_];
register const char* dataPtr = reinterpret_cast<const char*>(data);
register size_t i = count;
while (i--) *bufPtr++ = *dataPtr++;
bufPosition_ += count;
}
// * * * * * * * * * * * * * * * * Constructor * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * Constructor * * * * * * * * * * * * * * * //
@ -92,137 +33,14 @@ Foam::OPstream::OPstream
const commsTypes commsType, const commsTypes commsType,
const int toProcNo, const int toProcNo,
const label bufSize, const label bufSize,
const int tag,
streamFormat format, streamFormat format,
versionNumber version versionNumber version
) )
: :
Pstream(commsType, bufSize), Pstream(commsType, bufSize),
Ostream(format, version), UOPstream(commsType, toProcNo, buf_, tag, true, format, version)
toProcNo_(toProcNo) {}
{
setOpened();
setGood();
if (!bufSize)
{
buf_.setSize(1000);
}
}
// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
Foam::Ostream& Foam::OPstream::write(const token&)
{
notImplemented("Ostream& OPstream::write(const token&)");
setBad();
return *this;
}
Foam::Ostream& Foam::OPstream::write(const char c)
{
if (!isspace(c))
{
writeToBuffer(c);
}
return *this;
}
Foam::Ostream& Foam::OPstream::write(const char* str)
{
word nonWhiteChars(string::validate<word>(str));
if (nonWhiteChars.size() == 1)
{
return write(nonWhiteChars.c_str()[1]);
}
else if (nonWhiteChars.size())
{
return write(nonWhiteChars);
}
else
{
return *this;
}
}
Foam::Ostream& Foam::OPstream::write(const word& str)
{
write(char(token::WORD));
size_t len = str.size();
writeToBuffer(len);
writeToBuffer(str.c_str(), len + 1, 1);
return *this;
}
Foam::Ostream& Foam::OPstream::write(const string& str)
{
write(char(token::STRING));
size_t len = str.size();
writeToBuffer(len);
writeToBuffer(str.c_str(), len + 1, 1);
return *this;
}
Foam::Ostream& Foam::OPstream::writeQuoted(const std::string& str, const bool)
{
write(char(token::STRING));
size_t len = str.size();
writeToBuffer(len);
writeToBuffer(str.c_str(), len + 1, 1);
return *this;
}
Foam::Ostream& Foam::OPstream::write(const label val)
{
write(char(token::LABEL));
writeToBuffer(val);
return *this;
}
Foam::Ostream& Foam::OPstream::write(const floatScalar val)
{
write(char(token::FLOAT_SCALAR));
writeToBuffer(val);
return *this;
}
Foam::Ostream& Foam::OPstream::write(const doubleScalar val)
{
write(char(token::DOUBLE_SCALAR));
writeToBuffer(val);
return *this;
}
Foam::Ostream& Foam::OPstream::write(const char* data, std::streamsize count)
{
if (format() != BINARY)
{
FatalErrorIn("Ostream::write(const char*, std::streamsize)")
<< "stream format not binary"
<< Foam::abort(FatalError);
}
writeToBuffer(data, count, 8);
return *this;
}
// ************************************************************************* // // ************************************************************************* //

View File

@ -38,7 +38,7 @@ SourceFiles
#ifndef OPstream_H #ifndef OPstream_H
#define OPstream_H #define OPstream_H
#include "Ostream.H" #include "UOPstream.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -52,25 +52,8 @@ namespace Foam
class OPstream class OPstream
: :
public Pstream, public Pstream,
public Ostream public UOPstream
{ {
// Private data
int toProcNo_;
// Private member functions
//- Write a T to the transfer buffer
template<class T>
inline void writeToBuffer(const T&);
//- Write a char to the transfer buffer
inline void writeToBuffer(const char&);
//- Write data to the transfer buffer
inline void writeToBuffer(const void* data, size_t count, size_t align);
public: public:
@ -83,126 +66,11 @@ public:
const commsTypes commsType, const commsTypes commsType,
const int toProcNo, const int toProcNo,
const label bufSize = 0, const label bufSize = 0,
const int tag = UPstream::msgType(),
streamFormat format=BINARY, streamFormat format=BINARY,
versionNumber version=currentVersion versionNumber version=currentVersion
); );
// Destructor
~OPstream();
// Member functions
// Inquiry
//- Return flags of output stream
ios_base::fmtflags flags() const
{
return ios_base::fmtflags(0);
}
// Write functions
//- Write given buffer to given processor
static bool write
(
const commsTypes commsType,
const int toProcNo,
const char* buf,
const std::streamsize bufSize
);
//- Write next token to stream
Ostream& write(const token&);
//- Write character
Ostream& write(const char);
//- Write character string
Ostream& write(const char*);
//- Write word
Ostream& write(const word&);
//- Write string
Ostream& write(const string&);
//- Write std::string surrounded by quotes.
// Optional write without quotes.
Ostream& writeQuoted
(
const std::string&,
const bool quoted=true
);
//- Write label
Ostream& write(const label);
//- Write floatScalar
Ostream& write(const floatScalar);
//- Write doubleScalar
Ostream& write(const doubleScalar);
//- Write binary block
Ostream& write(const char*, std::streamsize);
//- Add indentation characters
void indent()
{}
// Stream state functions
//- Flush stream
void flush()
{}
//- Add newline and flush stream
void endl()
{}
//- Get width of output field
int width() const
{
return 0;
}
//- Set width of output field (and return old width)
int width(const int)
{
return 0;
}
//- Get precision of output field
int precision() const
{
return 0;
}
//- Set precision of output field (and return old precision)
int precision(const int)
{
return 0;
}
// Edit
//- Set flags of stream
ios_base::fmtflags flags(const ios_base::fmtflags)
{
return ios_base::fmtflags(0);
}
// Print
//- Print description of IOstream to Ostream
void print(Ostream&) const;
}; };

View File

@ -25,226 +25,16 @@ License
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#include "Pstream.H" #include "Pstream.H"
#include "debug.H"
#include "dictionary.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
defineTypeNameAndDebug(Foam::Pstream, 0); defineTypeNameAndDebug(Foam::Pstream, 0);
template<>
const char* Foam::NamedEnum<Foam::Pstream::commsTypes, 3>::names[] =
{
"blocking",
"scheduled",
"nonBlocking"
};
const Foam::NamedEnum<Foam::Pstream::commsTypes, 3>
Foam::Pstream::commsTypeNames;
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
void Foam::Pstream::setParRun()
{
parRun_ = true;
Pout.prefix() = '[' + name(myProcNo()) + "] ";
Perr.prefix() = '[' + name(myProcNo()) + "] ";
}
void Foam::Pstream::calcLinearComm(const label nProcs)
{
linearCommunication_.setSize(nProcs);
// Master
labelList belowIDs(nProcs - 1);
forAll(belowIDs, i)
{
belowIDs[i] = i + 1;
}
linearCommunication_[0] = commsStruct
(
nProcs,
0,
-1,
belowIDs,
labelList(0)
);
// Slaves. Have no below processors, only communicate up to master
for (label procID = 1; procID < nProcs; procID++)
{
linearCommunication_[procID] = commsStruct
(
nProcs,
procID,
0,
labelList(0),
labelList(0)
);
}
}
// Append my children (and my children children etc.) to allReceives.
void Foam::Pstream::collectReceives
(
const label procID,
const List<DynamicList<label> >& receives,
DynamicList<label>& allReceives
)
{
const DynamicList<label>& myChildren = receives[procID];
forAll(myChildren, childI)
{
allReceives.append(myChildren[childI]);
collectReceives(myChildren[childI], receives, allReceives);
}
}
// Tree like schedule. For 8 procs:
// (level 0)
// 0 receives from 1
// 2 receives from 3
// 4 receives from 5
// 6 receives from 7
// (level 1)
// 0 receives from 2
// 4 receives from 6
// (level 2)
// 0 receives from 4
//
// The sends/receives for all levels are collected per processor (one send per
// processor; multiple receives possible) creating a table:
//
// So per processor:
// proc receives from sends to
// ---- ------------- --------
// 0 1,2,4 -
// 1 - 0
// 2 3 0
// 3 - 2
// 4 5 0
// 5 - 4
// 6 7 4
// 7 - 6
void Foam::Pstream::calcTreeComm(label nProcs)
{
label nLevels = 1;
while ((1 << nLevels) < nProcs)
{
nLevels++;
}
List<DynamicList<label> > receives(nProcs);
labelList sends(nProcs, -1);
// Info<< "Using " << nLevels << " communication levels" << endl;
label offset = 2;
label childOffset = offset/2;
for (label level = 0; level < nLevels; level++)
{
label receiveID = 0;
while (receiveID < nProcs)
{
// Determine processor that sends and we receive from
label sendID = receiveID + childOffset;
if (sendID < nProcs)
{
receives[receiveID].append(sendID);
sends[sendID] = receiveID;
}
receiveID += offset;
}
offset <<= 1;
childOffset <<= 1;
}
// For all processors find the processors it receives data from
// (and the processors they receive data from etc.)
List<DynamicList<label> > allReceives(nProcs);
for (label procID = 0; procID < nProcs; procID++)
{
collectReceives(procID, receives, allReceives[procID]);
}
treeCommunication_.setSize(nProcs);
for (label procID = 0; procID < nProcs; procID++)
{
treeCommunication_[procID] = commsStruct
(
nProcs,
procID,
sends[procID],
receives[procID].shrink(),
allReceives[procID].shrink()
);
}
}
// Callback from Pstream::init() : initialize linear and tree communication
// schedules now that nProcs is known.
void Foam::Pstream::initCommunicationSchedule()
{
calcLinearComm(nProcs());
calcTreeComm(nProcs());
}
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
// Initialise my process number to 0 (the master)
int Foam::Pstream::myProcNo_(0);
// By default this is not a parallel run
bool Foam::Pstream::parRun_(false);
// List of process IDs
Foam::List<int> Foam::Pstream::procIDs_(1, 0);
// Standard transfer message type
int Foam::Pstream::msgType_(1);
// Linear communication schedule
Foam::List<Foam::Pstream::commsStruct> Foam::Pstream::linearCommunication_(0);
// Multi level communication schedule
Foam::List<Foam::Pstream::commsStruct> Foam::Pstream::treeCommunication_(0);
// Should compact transfer be used in which floats replace doubles
// reducing the bandwidth requirement at the expense of some loss
// in accuracy
bool Foam::Pstream::floatTransfer
(
debug::optimisationSwitch("floatTransfer", 0)
);
// Number of processors at which the reduce algorithm changes from linear to
// tree
int Foam::Pstream::nProcsSimpleSum
(
debug::optimisationSwitch("nProcsSimpleSum", 16)
);
// Default commsType
Foam::Pstream::commsTypes Foam::Pstream::defaultCommsType
(
commsTypeNames.read(debug::optimisationSwitches().lookup("commsType"))
);
// ************************************************************************* // // ************************************************************************* //

View File

@ -30,22 +30,18 @@ Description
SourceFiles SourceFiles
Pstream.C Pstream.C
PstreamsPrint.C
PstreamCommsStruct.C
gatherScatter.C gatherScatter.C
combineGatherScatter.C combineGatherScatter.C
gatherScatterList.C gatherScatterList.C
exchange.C
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#ifndef Pstream_H #ifndef Pstream_H
#define Pstream_H #define Pstream_H
#include "labelList.H" #include "UPstream.H"
#include "DynamicList.H" #include "DynamicList.H"
#include "HashTable.H"
#include "string.H"
#include "NamedEnum.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -57,162 +53,16 @@ namespace Foam
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
class Pstream class Pstream
:
public UPstream
{ {
public:
//- Types of communications
enum commsTypes
{
blocking,
scheduled,
nonBlocking
};
static const NamedEnum<commsTypes, 3> commsTypeNames;
//- Structure for communicating between processors
class commsStruct
{
// Private data
//- procID of above processor
label above_;
//- procIDs of processors directly below me
labelList below_;
//- procIDs of all processors below (so not just directly below)
labelList allBelow_;
//- procIDs of all processors not below. (inverse set of allBelow_
// and minus myProcNo)
labelList allNotBelow_;
public:
// Constructors
//- Construct null
commsStruct();
//- Construct from components
commsStruct
(
const label,
const labelList&,
const labelList&,
const labelList&
);
//- Construct from components; construct allNotBelow_
commsStruct
(
const label nProcs,
const label myProcID,
const label,
const labelList&,
const labelList&
);
// Member Functions
// Access
label above() const
{
return above_;
}
const labelList& below() const
{
return below_;
}
const labelList& allBelow() const
{
return allBelow_;
}
const labelList& allNotBelow() const
{
return allNotBelow_;
}
// Member operators
bool operator==(const commsStruct&) const;
bool operator!=(const commsStruct&) const;
// Ostream Operator
friend Ostream& operator<<(Ostream&, const commsStruct&);
};
private:
// Private data
static int myProcNo_;
static bool parRun_;
static List<int> procIDs_;
static int msgType_;
static List<commsStruct> linearCommunication_;
static List<commsStruct> treeCommunication_;
// Private member functions
//- Set data for parallel running
static void setParRun();
//- Calculate linear communication schedule
static void calcLinearComm(const label nProcs);
//- Calculate tree communication schedule
static void calcTreeComm(const label nProcs);
//- Helper function for tree communication schedule determination
// Collects all processorIDs below a processor
static void collectReceives
(
const label procID,
const List<DynamicList<label> >& receives,
DynamicList<label>& allReceives
);
//- Initialize all communication schedules. Callback from
// Pstream::init()
static void initCommunicationSchedule();
protected: protected:
// Protected data // Protected data
//- Communications type of this stream
commsTypes commsType_;
//- Transfer buffer //- Transfer buffer
List<char> buf_; DynamicList<char> buf_;
//- Current buffer read/write location
int bufPosition_;
// Protected member functions
//- Increase the size of the transfer buffer
inline void enlargeBuffer(size_t count);
public: public:
@ -220,21 +70,6 @@ public:
ClassName("Pstream"); ClassName("Pstream");
// Static data
//- Should compact transfer be used in which floats replace doubles
// reducing the bandwidth requirement at the expense of some loss
// in accuracy
static bool floatTransfer;
//- Number of processors at which the sum algorithm changes from linear
// to tree
static int nProcsSimpleSum;
//- Default commsType
static commsTypes defaultCommsType;
// Constructors // Constructors
//- Construct given optional buffer size //- Construct given optional buffer size
@ -244,151 +79,16 @@ public:
const label bufSize = 0 const label bufSize = 0
) )
: :
commsType_(commsType), UPstream(commsType),
bufPosition_(0) buf_(0)
{ {
if (bufSize) if (bufSize)
{ {
buf_.setSize(bufSize + 2*sizeof(scalar) + 1); buf_.setCapacity(bufSize + 2*sizeof(scalar) + 1);
} }
} }
// Member functions
//- Add the valid option this type of communications library
// adds/requires on the command line
static void addValidParOptions(HashTable<string>& validParOptions);
//- Initialisation function called from main
// Spawns slave processes and initialises inter-communication
static bool init(int& argc, char**& argv);
//- Non-blocking comms: wait until all have finished.
static void waitRequests();
//- Non-blocking comms: has request i finished?
static bool finishedRequest(const label i);
//- Is this a parallel run?
static bool parRun()
{
return parRun_;
}
//- Number of processes in parallel run
static label nProcs()
{
return procIDs_.size();
}
//- Am I the master process
static bool master()
{
return myProcNo_ == 0;
}
//- Process index of the master
static int masterNo()
{
return 0;
}
//- Number of this process (starting from masterNo() = 0)
static int myProcNo()
{
return myProcNo_;
}
//- Process IDs
static const List<int>& procIDs()
{
return procIDs_;
}
//- Process ID of given process index
static int procID(int procNo)
{
return procIDs_[procNo];
}
//- Process index of first slave
static int firstSlave()
{
return 1;
}
//- Process index of last slave
static int lastSlave()
{
return nProcs() - 1;
}
//- Communication schedule for linear all-to-master (proc 0)
static const List<commsStruct>& linearCommunication()
{
return linearCommunication_;
}
//- Communication schedule for tree all-to-master (proc 0)
static const List<commsStruct>& treeCommunication()
{
return treeCommunication_;
}
//- Message tag of standard messages
static int& msgType()
{
return msgType_;
}
//- Get the communications type of the stream
commsTypes commsType() const
{
return commsType_;
}
//- Set the communications type of the stream
commsTypes commsType(const commsTypes ct)
{
commsTypes oldCommsType = commsType_;
commsType_ = ct;
return oldCommsType;
}
//- Transfer buffer
const List<char>& buf() const
{
return buf_;
}
//- Transfer buffer
List<char>& buf()
{
return buf_;
}
//- Current buffer read/write location
int bufPosition() const
{
return bufPosition_;
}
//- Current buffer read/write location
int& bufPosition()
{
return bufPosition_;
}
//- Exit program
static void exit(int errnum = 1);
//- Abort program
static void abort();
// Gather and scatter // Gather and scatter
//- Gather data. Apply bop to combine Value //- Gather data. Apply bop to combine Value
@ -501,8 +201,8 @@ public:
// Gather/scatter keeping the individual processor data separate. // Gather/scatter keeping the individual processor data separate.
// Values is a List of size Pstream::nProcs() where // Values is a List of size UPstream::nProcs() where
// Values[Pstream::myProcNo()] is the data for the current processor. // Values[UPstream::myProcNo()] is the data for the current processor.
//- Gather data but keep individual values separate //- Gather data but keep individual values separate
template <class T> template <class T>
@ -527,18 +227,27 @@ public:
//- Like above but switches between linear/tree communication //- Like above but switches between linear/tree communication
template <class T> template <class T>
static void scatterList(List<T>& Values); static void scatterList(List<T>& Values);
// Exchange
//- Exchange data. Sends sendData, receives into recvData, sets
// sizes (not bytes). sizes[p0][p1] is what processor p0 has
// sent to p1. Continuous data only.
// If block=true will wait for all transfers to finish.
template <class Container, class T>
static void exchange
(
const List<Container >&,
List<Container >&,
labelListList& sizes,
const int tag = UPstream::msgType(),
const bool block = true
);
}; };
inline void Pstream::enlargeBuffer(size_t count)
{
buf_.setSize(max(int(buf_.size() + count), 2*buf_.size()));
}
Ostream& operator<<(Ostream&, const Pstream::commsStruct&);
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam } // End namespace Foam
@ -549,9 +258,9 @@ Ostream& operator<<(Ostream&, const Pstream::commsStruct&);
# include "gatherScatter.C" # include "gatherScatter.C"
# include "combineGatherScatter.C" # include "combineGatherScatter.C"
# include "gatherScatterList.C" # include "gatherScatterList.C"
# include "exchange.C"
#endif #endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif #endif

View File

@ -0,0 +1,117 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 1991-2009 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 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
\*---------------------------------------------------------------------------*/
#include "PstreamBuffers.H"
/* * * * * * * * * * * * * * * Static Member Data * * * * * * * * * * * * * */
namespace Foam
{
DynamicList<char> PstreamBuffers::nullBuf(0);
}
// * * * * * * * * * * * * * * * * Constructor * * * * * * * * * * * * * * * //
Foam::PstreamBuffers::PstreamBuffers
(
const UPstream::commsTypes commsType,
const int tag,
IOstream::streamFormat format,
IOstream::versionNumber version
)
:
commsType_(commsType),
tag_(tag),
format_(format),
version_(version),
sendBuf_(UPstream::nProcs()),
recvBuf_(UPstream::nProcs()),
finishedSendsCalled_(false)
{}
// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
void Foam::PstreamBuffers::finishedSends(const bool block)
{
finishedSendsCalled_ = true;
if (commsType_ == UPstream::nonBlocking)
{
labelListList sizes;
Pstream::exchange<DynamicList<char>, char>
(
sendBuf_,
recvBuf_,
sizes,
tag_,
block
);
}
}
void Foam::PstreamBuffers::finishedSends(labelListList& sizes, const bool block)
{
finishedSendsCalled_ = true;
if (commsType_ == UPstream::nonBlocking)
{
labelListList sizes;
labelListList send,recv;
Pstream::exchange<DynamicList<char>, char>
(
sendBuf_,
recvBuf_,
sizes,
tag_,
block
);
}
else
{
sizes.setSize(UPstream::nProcs());
labelList& nsTransPs = sizes[UPstream::myProcNo()];
nsTransPs.setSize(UPstream::nProcs());
forAll(sendBuf_, procI)
{
nsTransPs[procI] = sendBuf_[procI].size();
}
// Send sizes across.
int oldTag = UPstream::msgType();
UPstream::msgType() = tag_;
combineReduce(sizes, UPstream::listEq());
UPstream::msgType() = oldTag;
}
}
// ************************************************************************* //

View File

@ -0,0 +1,155 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 1991-2009 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 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Class
Foam::PstreamBuffers
Description
Buffers for inter-processor communications streams (UOPstream, UIPstream).
Use UOPstream to stream data into buffers, call finishedSends() to
notify that data is in buffers and then use IUPstream to get data out
of received buffers. Works with both blocking and nonBlocking. Does
not make much sense with scheduled since there you would not need these
explicit buffers.
Example usage:
PstreamBuffers pBuffers(Pstream::nonBlocking);
for (label procI = 0; procI < Pstream::nProcs(); procI++)
{
if (procI != Pstream::myProcNo())
{
someObject vals;
UOPstream str(procI, pBuffers);
str << vals;
}
}
pBuffers.finishedSends(); // no-op for blocking
for (label procI = 0; procI < Pstream::nProcs(); procI++)
{
if (procI != Pstream::myProcNo())
{
UIPstream str(procI, pBuffers);
someObject vals(str);
}
}
SourceFiles
PstreamBuffers.C
\*---------------------------------------------------------------------------*/
#include "Pstream.H"
#ifndef PstreamBuffers_H
#define PstreamBuffers_H
#include "DynamicList.H"
#include "UPstream.H"
#include "IOstream.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class PstreamBuffers Declaration
\*---------------------------------------------------------------------------*/
class PstreamBuffers
{
friend class UOPstream;
friend class UIPstream;
// Private data
//- Communications type of this stream
const UPstream::commsTypes commsType_;
const int tag_;
const IOstream::streamFormat format_;
const IOstream::versionNumber version_;
//- send buffer
List<DynamicList<char> > sendBuf_;
//- receive buffer
List<DynamicList<char> > recvBuf_;
bool finishedSendsCalled_;
// Private member functions
public:
// Static data
static DynamicList<char> nullBuf;
// Constructors
//- Construct given comms type,
// write format and IO version
PstreamBuffers
(
const UPstream::commsTypes commsType,
const int tag = UPstream::msgType(),
IOstream::streamFormat format=IOstream::BINARY,
IOstream::versionNumber version=IOstream::currentVersion
);
// Member functions
//- Mark all sends as having been done. This will start receives
// in non-blocking mode. If block will wait for all transfers to
// finish (only relevant for nonBlocking mode)
void finishedSends(const bool block = true);
//- Mark all sends as having been done. Same as above but also returns
// sizes (bytes) transferred.
void finishedSends(labelListList& sizes, const bool block = true);
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -23,7 +23,7 @@ License
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
InClass InClass
Foam::Pstream Foam
Description Description
Combination-Reduction operation for a parallel run. The Combination-Reduction operation for a parallel run. The
@ -37,6 +37,7 @@ Description
#ifndef PstreamCombineReduceOps_H #ifndef PstreamCombineReduceOps_H
#define PstreamCombineReduceOps_H #define PstreamCombineReduceOps_H
#include "UPstream.H"
#include "Pstream.H" #include "Pstream.H"
#include "ops.H" #include "ops.H"
@ -50,7 +51,7 @@ namespace Foam
template <class T, class CombineOp> template <class T, class CombineOp>
void combineReduce void combineReduce
( (
const List<Pstream::commsStruct>& comms, const List<UPstream::commsStruct>& comms,
T& Value, T& Value,
const CombineOp& cop const CombineOp& cop
) )
@ -63,15 +64,15 @@ void combineReduce
template <class T, class CombineOp> template <class T, class CombineOp>
void combineReduce(T& Value, const CombineOp& cop) void combineReduce(T& Value, const CombineOp& cop)
{ {
if (Pstream::nProcs() < Pstream::nProcsSimpleSum) if (UPstream::nProcs() < UPstream::nProcsSimpleSum)
{ {
Pstream::combineGather(Pstream::linearCommunication(), Value, cop); Pstream::combineGather(UPstream::linearCommunication(), Value, cop);
Pstream::combineScatter(Pstream::linearCommunication(), Value); Pstream::combineScatter(UPstream::linearCommunication(), Value);
} }
else else
{ {
Pstream::combineGather(Pstream::treeCommunication(), Value, cop); Pstream::combineGather(UPstream::treeCommunication(), Value, cop);
Pstream::combineScatter(Pstream::treeCommunication(), Value); Pstream::combineScatter(UPstream::treeCommunication(), Value);
} }
} }

View File

@ -41,7 +41,7 @@ namespace Foam
template <class T, class BinaryOp> template <class T, class BinaryOp>
void reduce void reduce
( (
const List<Pstream::commsStruct>& comms, const List<UPstream::commsStruct>& comms,
T& Value, T& Value,
const BinaryOp& bop const BinaryOp& bop
) )
@ -59,13 +59,13 @@ void reduce
const BinaryOp& bop const BinaryOp& bop
) )
{ {
if (Pstream::nProcs() < Pstream::nProcsSimpleSum) if (UPstream::nProcs() < UPstream::nProcsSimpleSum)
{ {
reduce(Pstream::linearCommunication(), Value, bop); reduce(UPstream::linearCommunication(), Value, bop);
} }
else else
{ {
reduce(Pstream::treeCommunication(), Value, bop); reduce(UPstream::treeCommunication(), Value, bop);
} }
} }
@ -80,13 +80,13 @@ T returnReduce
{ {
T WorkValue(Value); T WorkValue(Value);
if (Pstream::nProcs() < Pstream::nProcsSimpleSum) if (UPstream::nProcs() < UPstream::nProcsSimpleSum)
{ {
reduce(Pstream::linearCommunication(), WorkValue, bop); reduce(UPstream::linearCommunication(), WorkValue, bop);
} }
else else
{ {
reduce(Pstream::treeCommunication(), WorkValue, bop); reduce(UPstream::treeCommunication(), WorkValue, bop);
} }
return WorkValue; return WorkValue;

View File

@ -0,0 +1,322 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 1991-2009 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 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
\*---------------------------------------------------------------------------*/
#include "error.H"
#include "UIPstream.H"
#include "int.H"
#include "token.H"
#include <cctype>
// * * * * * * * * * * * * * Private member functions * * * * * * * * * * * //
inline void Foam::UIPstream::checkEof()
{
if (externalBufPosition_ == messageSize_)
{
setEof();
}
}
template<class T>
inline void Foam::UIPstream::readFromBuffer(T& t)
{
const size_t align = sizeof(T);
externalBufPosition_ = align + ((externalBufPosition_ - 1) & ~(align - 1));
t = reinterpret_cast<T&>(externalBuf_[externalBufPosition_]);
externalBufPosition_ += sizeof(T);
checkEof();
}
inline void Foam::UIPstream::readFromBuffer
(
void* data,
size_t count,
size_t align
)
{
if (align > 1)
{
externalBufPosition_ =
align
+ ((externalBufPosition_ - 1) & ~(align - 1));
}
register const char* bufPtr = &externalBuf_[externalBufPosition_];
register char* dataPtr = reinterpret_cast<char*>(data);
register size_t i = count;
while (i--) *dataPtr++ = *bufPtr++;
externalBufPosition_ += count;
checkEof();
}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::UIPstream::~UIPstream()
{
if (externalBufPosition_ < messageSize_)
{
FatalErrorIn("UIPstream::~UIPstream()")
<< "Message not fully consumed. messageSize:" << messageSize_
<< " bytes of which only " << externalBufPosition_
<< " consumed." << Foam::abort(FatalError);
}
}
// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
Foam::Istream& Foam::UIPstream::read(token& t)
{
// Return the put back token if it exists
if (Istream::getBack(t))
{
return *this;
}
char c;
// return on error
if (!read(c))
{
t.setBad();
return *this;
}
// Set the line number of this token to the current stream line number
t.lineNumber() = lineNumber();
// Analyse input starting with this character.
switch (c)
{
// Punctuation
case token::END_STATEMENT :
case token::BEGIN_LIST :
case token::END_LIST :
case token::BEGIN_SQR :
case token::END_SQR :
case token::BEGIN_BLOCK :
case token::END_BLOCK :
case token::COLON :
case token::COMMA :
case token::ASSIGN :
case token::ADD :
case token::SUBTRACT :
case token::MULTIPLY :
case token::DIVIDE :
{
t = token::punctuationToken(c);
return *this;
}
// Word
case token::WORD :
{
word* pval = new word;
if (read(*pval))
{
if (token::compound::isCompound(*pval))
{
t = token::compound::New(*pval, *this).ptr();
delete pval;
}
else
{
t = pval;
}
}
else
{
delete pval;
t.setBad();
}
return *this;
}
// String
case token::STRING :
{
string* pval = new string;
if (read(*pval))
{
t = pval;
}
else
{
delete pval;
t.setBad();
}
return *this;
}
// Label
case token::LABEL :
{
label val;
if (read(val))
{
t = val;
}
else
{
t.setBad();
}
return *this;
}
// floatScalar
case token::FLOAT_SCALAR :
{
floatScalar val;
if (read(val))
{
t = val;
}
else
{
t.setBad();
}
return *this;
}
// doubleScalar
case token::DOUBLE_SCALAR :
{
doubleScalar val;
if (read(val))
{
t = val;
}
else
{
t.setBad();
}
return *this;
}
// Character (returned as a single character word) or error
default:
{
if (isalpha(c))
{
t = word(c);
return *this;
}
setBad();
t.setBad();
return *this;
}
}
}
Foam::Istream& Foam::UIPstream::read(char& c)
{
c = externalBuf_[externalBufPosition_];
externalBufPosition_++;
checkEof();
return *this;
}
Foam::Istream& Foam::UIPstream::read(word& str)
{
size_t len;
readFromBuffer(len);
str = &externalBuf_[externalBufPosition_];
externalBufPosition_ += len + 1;
checkEof();
return *this;
}
Foam::Istream& Foam::UIPstream::read(string& str)
{
size_t len;
readFromBuffer(len);
str = &externalBuf_[externalBufPosition_];
externalBufPosition_ += len + 1;
checkEof();
return *this;
}
Foam::Istream& Foam::UIPstream::read(label& val)
{
readFromBuffer(val);
return *this;
}
Foam::Istream& Foam::UIPstream::read(floatScalar& val)
{
readFromBuffer(val);
return *this;
}
Foam::Istream& Foam::UIPstream::read(doubleScalar& val)
{
readFromBuffer(val);
return *this;
}
Foam::Istream& Foam::UIPstream::read(char* data, std::streamsize count)
{
if (format() != BINARY)
{
FatalErrorIn("UIPstream::read(char*, std::streamsize)")
<< "stream format not binary"
<< Foam::abort(FatalError);
}
readFromBuffer(data, count, 8);
return *this;
}
Foam::Istream& Foam::UIPstream::rewind()
{
externalBufPosition_ = 0;
return *this;
}
void Foam::UIPstream::print(Ostream& os) const
{
os << "Reading from processor " << fromProcNo_
<< " to processor " << myProcNo() << Foam::endl;
}
// ************************************************************************* //

View File

@ -0,0 +1,187 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 1991-2009 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 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Class
Foam::UIPstream
Description
Input inter-processor communications stream operating on external
buffer.
SourceFiles
UIPstream.C
\*---------------------------------------------------------------------------*/
#include "Pstream.H"
#ifndef UIPstream_H
#define UIPstream_H
#include "UPstream.H"
#include "Istream.H"
#include "PstreamBuffers.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class UIPstream Declaration
\*---------------------------------------------------------------------------*/
class UIPstream
:
public UPstream,
public Istream
{
// Private data
int fromProcNo_;
DynamicList<char>& externalBuf_;
label externalBufPosition_;
const int tag_;
label messageSize_;
// Private member functions
//- Check the bufferPosition against messageSize_ for EOF
inline void checkEof();
//- Read a T from the transfer buffer
template<class T>
inline void readFromBuffer(T&);
//- Read data from the transfer buffer
inline void readFromBuffer(void* data, size_t count, size_t align);
public:
// Constructors
//- Construct given process index to read from and optional buffer size,
// read format and IO version
UIPstream
(
const commsTypes commsType,
const int fromProcNo,
DynamicList<char>& externalBuf,
const int tag = UPstream::msgType(),
streamFormat format=BINARY,
versionNumber version=currentVersion
);
//- Construct given buffers
UIPstream(const int fromProcNo, PstreamBuffers&);
// Destructor
~UIPstream();
// Member functions
// Inquiry
//- Return flags of output stream
ios_base::fmtflags flags() const
{
return ios_base::fmtflags(0);
}
// Read functions
//- Read into given buffer from given processor and return the
// message size
static label read
(
const commsTypes commsType,
const int fromProcNo,
char* buf,
const std::streamsize bufSize,
const int tag = UPstream::msgType()
);
//- Return next token from stream
Istream& read(token&);
//- Read a character
Istream& read(char&);
//- Read a word
Istream& read(word&);
// Read a string (including enclosing double-quotes)
Istream& read(string&);
//- Read a label
Istream& read(label&);
//- Read a floatScalar
Istream& read(floatScalar&);
//- Read a doubleScalar
Istream& read(doubleScalar&);
//- Read binary block
Istream& read(char*, std::streamsize);
//- Rewind and return the stream so that it may be read again
Istream& rewind();
// Edit
//- Set flags of stream
ios_base::fmtflags flags(const ios_base::fmtflags)
{
return ios_base::fmtflags(0);
}
// Print
//- Print description of IOstream to Ostream
void print(Ostream&) const;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,275 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 1991-2009 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 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Description
Write primitive and binary block from UOPstream
\*---------------------------------------------------------------------------*/
#include "error.H"
#include "UOPstream.H"
#include "int.H"
#include "token.H"
#include <cctype>
// * * * * * * * * * * * * * Private member functions * * * * * * * * * * * //
template<class T>
inline void Foam::UOPstream::writeToBuffer(const T& t)
{
writeToBuffer(&t, sizeof(T), sizeof(T));
}
inline void Foam::UOPstream::writeToBuffer(const char& c)
{
if (!sendBuf_.capacity())
{
sendBuf_.setCapacity(1000);
}
sendBuf_.append(c);
}
inline void Foam::UOPstream::writeToBuffer
(
const void* data,
size_t count,
size_t align
)
{
if (!sendBuf_.capacity())
{
sendBuf_.setCapacity(1000);
}
label alignedPos = sendBuf_.size();
if (align > 1)
{
// Align bufPosition. Pads sendBuf_.size() - oldPos characters.
alignedPos = align + ((sendBuf_.size() - 1) & ~(align - 1));
}
// Extend if necessary
sendBuf_.setSize(alignedPos + count);
register const char* dataPtr = reinterpret_cast<const char*>(data);
register size_t i = count;
while (i--) sendBuf_[alignedPos++] = *dataPtr++;
}
// * * * * * * * * * * * * * * * * Constructor * * * * * * * * * * * * * * * //
Foam::UOPstream::UOPstream
(
const commsTypes commsType,
const int toProcNo,
DynamicList<char>& sendBuf,
const int tag,
const bool sendAtDestruct,
streamFormat format,
versionNumber version
)
:
UPstream(commsType),
Ostream(format, version),
toProcNo_(toProcNo),
sendBuf_(sendBuf),
tag_(tag),
sendAtDestruct_(sendAtDestruct)
{
setOpened();
setGood();
}
Foam::UOPstream::UOPstream(const int toProcNo, PstreamBuffers& buffers)
:
UPstream(buffers.commsType_),
Ostream(buffers.format_, buffers.version_),
toProcNo_(toProcNo),
sendBuf_(buffers.sendBuf_[toProcNo]),
tag_(buffers.tag_),
sendAtDestruct_(buffers.commsType_ != UPstream::nonBlocking)
{
setOpened();
setGood();
}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::UOPstream::~UOPstream()
{
if (sendAtDestruct_)
{
if
(
!UOPstream::write
(
commsType_,
toProcNo_,
sendBuf_.begin(),
sendBuf_.size(),
tag_
)
)
{
FatalErrorIn("UOPstream::~UOPstream()")
<< "Failed sending outgoing message of size " << sendBuf_.size()
<< " to processor " << toProcNo_
<< Foam::abort(FatalError);
}
}
}
// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
Foam::Ostream& Foam::UOPstream::write(const token&)
{
notImplemented("Ostream& UOPstream::write(const token&)");
setBad();
return *this;
}
Foam::Ostream& Foam::UOPstream::write(const char c)
{
if (!isspace(c))
{
writeToBuffer(c);
}
return *this;
}
Foam::Ostream& Foam::UOPstream::write(const char* str)
{
word nonWhiteChars(string::validate<word>(str));
if (nonWhiteChars.size() == 1)
{
return write(nonWhiteChars.c_str()[1]);
}
else if (nonWhiteChars.size())
{
return write(nonWhiteChars);
}
else
{
return *this;
}
}
Foam::Ostream& Foam::UOPstream::write(const word& str)
{
write(char(token::WORD));
size_t len = str.size();
writeToBuffer(len);
writeToBuffer(str.c_str(), len + 1, 1);
return *this;
}
Foam::Ostream& Foam::UOPstream::write(const string& str)
{
write(char(token::STRING));
size_t len = str.size();
writeToBuffer(len);
writeToBuffer(str.c_str(), len + 1, 1);
return *this;
}
Foam::Ostream& Foam::UOPstream::writeQuoted(const std::string& str, const bool)
{
write(char(token::STRING));
size_t len = str.size();
writeToBuffer(len);
writeToBuffer(str.c_str(), len + 1, 1);
return *this;
}
Foam::Ostream& Foam::UOPstream::write(const label val)
{
write(char(token::LABEL));
writeToBuffer(val);
return *this;
}
Foam::Ostream& Foam::UOPstream::write(const floatScalar val)
{
write(char(token::FLOAT_SCALAR));
writeToBuffer(val);
return *this;
}
Foam::Ostream& Foam::UOPstream::write(const doubleScalar val)
{
write(char(token::DOUBLE_SCALAR));
writeToBuffer(val);
return *this;
}
Foam::Ostream& Foam::UOPstream::write(const char* data, std::streamsize count)
{
if (format() != BINARY)
{
FatalErrorIn("Ostream::write(const char*, std::streamsize)")
<< "stream format not binary"
<< Foam::abort(FatalError);
}
writeToBuffer(data, count, 8);
return *this;
}
void Foam::UOPstream::print(Ostream& os) const
{
os << "Writing from processor " << toProcNo_
<< " to processor " << myProcNo() << Foam::endl;
}
// ************************************************************************* //

View File

@ -0,0 +1,233 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 1991-2009 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 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Class
Foam::UOPstream
Description
Output inter-processor communications stream operating on external
buffer.
SourceFiles
UOPstream.C
\*---------------------------------------------------------------------------*/
#include "Pstream.H"
#ifndef UOPstream_H
#define UOPstream_H
#include "UPstream.H"
#include "Ostream.H"
#include "DynamicList.H"
#include "PstreamBuffers.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class UOPstream Declaration
\*---------------------------------------------------------------------------*/
class UOPstream
:
public UPstream,
public Ostream
{
// Private data
int toProcNo_;
DynamicList<char>& sendBuf_;
const int tag_;
const bool sendAtDestruct_;
// Private member functions
//- Write a T to the transfer buffer
template<class T>
inline void writeToBuffer(const T&);
//- Write a char to the transfer buffer
inline void writeToBuffer(const char&);
//- Write data to the transfer buffer
inline void writeToBuffer(const void* data, size_t count, size_t align);
public:
// Constructors
//- Construct given process index to send to and optional buffer size,
// write format and IO version
UOPstream
(
const commsTypes commsType,
const int toProcNo,
DynamicList<char>& sendBuf,
const int tag = UPstream::msgType(),
const bool sendAtDestruct = true,
streamFormat format=BINARY,
versionNumber version=currentVersion
);
//- Construct given buffers
UOPstream(const int toProcNo, PstreamBuffers&);
// Destructor
~UOPstream();
// Member functions
// Inquiry
//- Return flags of output stream
ios_base::fmtflags flags() const
{
return ios_base::fmtflags(0);
}
// Write functions
//- Write given buffer to given processor
static bool write
(
const commsTypes commsType,
const int toProcNo,
const char* buf,
const std::streamsize bufSize,
const int tag = UPstream::msgType()
);
//- Write next token to stream
Ostream& write(const token&);
//- Write character
Ostream& write(const char);
//- Write character string
Ostream& write(const char*);
//- Write word
Ostream& write(const word&);
//- Write string
Ostream& write(const string&);
//- Write std::string surrounded by quotes.
// Optional write without quotes.
Ostream& writeQuoted
(
const std::string&,
const bool quoted=true
);
//- Write label
Ostream& write(const label);
//- Write floatScalar
Ostream& write(const floatScalar);
//- Write doubleScalar
Ostream& write(const doubleScalar);
//- Write binary block
Ostream& write(const char*, std::streamsize);
//- Add indentation characters
void indent()
{}
// Stream state functions
//- Flush stream
void flush()
{}
//- Add newline and flush stream
void endl()
{}
//- Get width of output field
int width() const
{
return 0;
}
//- Set width of output field (and return old width)
int width(const int)
{
return 0;
}
//- Get precision of output field
int precision() const
{
return 0;
}
//- Set precision of output field (and return old precision)
int precision(const int)
{
return 0;
}
// Edit
//- Set flags of stream
ios_base::fmtflags flags(const ios_base::fmtflags)
{
return ios_base::fmtflags(0);
}
// Print
//- Print description of IOstream to Ostream
void print(Ostream&) const;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,251 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 1991-2009 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 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
\*---------------------------------------------------------------------------*/
#include "UPstream.H"
#include "debug.H"
#include "dictionary.H"
#include "IOstreams.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
defineTypeNameAndDebug(Foam::UPstream, 0);
template<>
const char* Foam::NamedEnum<Foam::UPstream::commsTypes, 3>::names[] =
{
"blocking",
"scheduled",
"nonBlocking"
};
const Foam::NamedEnum<Foam::UPstream::commsTypes, 3>
Foam::UPstream::commsTypeNames;
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
void Foam::UPstream::setParRun()
{
parRun_ = true;
Pout.prefix() = '[' + name(myProcNo()) + "] ";
Perr.prefix() = '[' + name(myProcNo()) + "] ";
}
void Foam::UPstream::calcLinearComm(const label nProcs)
{
linearCommunication_.setSize(nProcs);
// Master
labelList belowIDs(nProcs - 1);
forAll(belowIDs, i)
{
belowIDs[i] = i + 1;
}
linearCommunication_[0] = commsStruct
(
nProcs,
0,
-1,
belowIDs,
labelList(0)
);
// Slaves. Have no below processors, only communicate up to master
for (label procID = 1; procID < nProcs; procID++)
{
linearCommunication_[procID] = commsStruct
(
nProcs,
procID,
0,
labelList(0),
labelList(0)
);
}
}
// Append my children (and my children children etc.) to allReceives.
void Foam::UPstream::collectReceives
(
const label procID,
const List<DynamicList<label> >& receives,
DynamicList<label>& allReceives
)
{
const DynamicList<label>& myChildren = receives[procID];
forAll(myChildren, childI)
{
allReceives.append(myChildren[childI]);
collectReceives(myChildren[childI], receives, allReceives);
}
}
// Tree like schedule. For 8 procs:
// (level 0)
// 0 receives from 1
// 2 receives from 3
// 4 receives from 5
// 6 receives from 7
// (level 1)
// 0 receives from 2
// 4 receives from 6
// (level 2)
// 0 receives from 4
//
// The sends/receives for all levels are collected per processor (one send per
// processor; multiple receives possible) creating a table:
//
// So per processor:
// proc receives from sends to
// ---- ------------- --------
// 0 1,2,4 -
// 1 - 0
// 2 3 0
// 3 - 2
// 4 5 0
// 5 - 4
// 6 7 4
// 7 - 6
void Foam::UPstream::calcTreeComm(label nProcs)
{
label nLevels = 1;
while ((1 << nLevels) < nProcs)
{
nLevels++;
}
List<DynamicList<label> > receives(nProcs);
labelList sends(nProcs, -1);
// Info<< "Using " << nLevels << " communication levels" << endl;
label offset = 2;
label childOffset = offset/2;
for (label level = 0; level < nLevels; level++)
{
label receiveID = 0;
while (receiveID < nProcs)
{
// Determine processor that sends and we receive from
label sendID = receiveID + childOffset;
if (sendID < nProcs)
{
receives[receiveID].append(sendID);
sends[sendID] = receiveID;
}
receiveID += offset;
}
offset <<= 1;
childOffset <<= 1;
}
// For all processors find the processors it receives data from
// (and the processors they receive data from etc.)
List<DynamicList<label> > allReceives(nProcs);
for (label procID = 0; procID < nProcs; procID++)
{
collectReceives(procID, receives, allReceives[procID]);
}
treeCommunication_.setSize(nProcs);
for (label procID = 0; procID < nProcs; procID++)
{
treeCommunication_[procID] = commsStruct
(
nProcs,
procID,
sends[procID],
receives[procID].shrink(),
allReceives[procID].shrink()
);
}
}
// Callback from UPstream::init() : initialize linear and tree communication
// schedules now that nProcs is known.
void Foam::UPstream::initCommunicationSchedule()
{
calcLinearComm(nProcs());
calcTreeComm(nProcs());
}
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
// Initialise my process number to 0 (the master)
int Foam::UPstream::myProcNo_(0);
// By default this is not a parallel run
bool Foam::UPstream::parRun_(false);
// List of process IDs
Foam::List<int> Foam::UPstream::procIDs_(1, 0);
// Standard transfer message type
int Foam::UPstream::msgType_(1);
// Linear communication schedule
Foam::List<Foam::UPstream::commsStruct> Foam::UPstream::linearCommunication_(0);
// Multi level communication schedule
Foam::List<Foam::UPstream::commsStruct> Foam::UPstream::treeCommunication_(0);
// Should compact transfer be used in which floats replace doubles
// reducing the bandwidth requirement at the expense of some loss
// in accuracy
bool Foam::UPstream::floatTransfer
(
debug::optimisationSwitch("floatTransfer", 0)
);
// Number of processors at which the reduce algorithm changes from linear to
// tree
int Foam::UPstream::nProcsSimpleSum
(
debug::optimisationSwitch("nProcsSimpleSum", 16)
);
// Default commsType
Foam::UPstream::commsTypes Foam::UPstream::defaultCommsType
(
commsTypeNames.read(debug::optimisationSwitches().lookup("commsType"))
);
// ************************************************************************* //

View File

@ -0,0 +1,381 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 1991-2009 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 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Class
Foam::UPstream
Description
Inter-processor communications stream
SourceFiles
UPstream.C
UPstreamsPrint.C
UPstreamCommsStruct.C
gatherScatter.C
combineGatherScatter.C
gatherScatterList.C
\*---------------------------------------------------------------------------*/
#ifndef UPstream_H
#define UPstream_H
#include "labelList.H"
#include "DynamicList.H"
#include "HashTable.H"
#include "string.H"
#include "NamedEnum.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class UPstream Declaration
\*---------------------------------------------------------------------------*/
class UPstream
{
public:
//- Types of communications
enum commsTypes
{
blocking,
scheduled,
nonBlocking
};
static const NamedEnum<commsTypes, 3> commsTypeNames;
// Public classes
//- Structure for communicating between processors
class commsStruct
{
// Private data
//- procID of above processor
label above_;
//- procIDs of processors directly below me
labelList below_;
//- procIDs of all processors below (so not just directly below)
labelList allBelow_;
//- procIDs of all processors not below. (inverse set of
// allBelow_ and minus myProcNo)
labelList allNotBelow_;
public:
// Constructors
//- Construct null
commsStruct();
//- Construct from components
commsStruct
(
const label,
const labelList&,
const labelList&,
const labelList&
);
//- Construct from components; construct allNotBelow_
commsStruct
(
const label nProcs,
const label myProcID,
const label,
const labelList&,
const labelList&
);
// Member Functions
// Access
label above() const
{
return above_;
}
const labelList& below() const
{
return below_;
}
const labelList& allBelow() const
{
return allBelow_;
}
const labelList& allNotBelow() const
{
return allNotBelow_;
}
// Member operators
bool operator==(const commsStruct&) const;
bool operator!=(const commsStruct&) const;
// Ostream Operator
friend Ostream& operator<<(Ostream&, const commsStruct&);
};
//- combineReduce operator for lists. Used for counting.
class listEq
{
public:
template<class T>
void operator()(T& x, const T& y) const
{
forAll(y, i)
{
if (y[i].size())
{
x[i] = y[i];
}
}
}
};
private:
// Private data
static int myProcNo_;
static bool parRun_;
static List<int> procIDs_;
static int msgType_;
static List<commsStruct> linearCommunication_;
static List<commsStruct> treeCommunication_;
// Private member functions
//- Set data for parallel running
static void setParRun();
//- Calculate linear communication schedule
static void calcLinearComm(const label nProcs);
//- Calculate tree communication schedule
static void calcTreeComm(const label nProcs);
//- Helper function for tree communication schedule determination
// Collects all processorIDs below a processor
static void collectReceives
(
const label procID,
const List<DynamicList<label> >& receives,
DynamicList<label>& allReceives
);
//- Initialize all communication schedules. Callback from
// UPstream::init()
static void initCommunicationSchedule();
protected:
// Protected data
//- Communications type of this stream
commsTypes commsType_;
public:
// Declare name of the class and its debug switch
ClassName("UPstream");
// Static data
//- Should compact transfer be used in which floats replace doubles
// reducing the bandwidth requirement at the expense of some loss
// in accuracy
static bool floatTransfer;
//- Number of processors at which the sum algorithm changes from linear
// to tree
static int nProcsSimpleSum;
//- Default commsType
static commsTypes defaultCommsType;
// Constructors
//- Construct given optional buffer size
UPstream(const commsTypes commsType)
:
commsType_(commsType)
{}
// Member functions
//- Add the valid option this type of communications library
// adds/requires on the command line
static void addValidParOptions(HashTable<string>& validParOptions);
//- Initialisation function called from main
// Spawns slave processes and initialises inter-communication
static bool init(int& argc, char**& argv);
//- Non-blocking comms: wait until all have finished.
static void waitRequests();
//- Non-blocking comms: has request i finished?
static bool finishedRequest(const label i);
//- Is this a parallel run?
static bool parRun()
{
return parRun_;
}
//- Number of processes in parallel run
static label nProcs()
{
return procIDs_.size();
}
//- Am I the master process
static bool master()
{
return myProcNo_ == 0;
}
//- Process index of the master
static int masterNo()
{
return 0;
}
//- Number of this process (starting from masterNo() = 0)
static int myProcNo()
{
return myProcNo_;
}
//- Process IDs
static const List<int>& procIDs()
{
return procIDs_;
}
//- Process ID of given process index
static int procID(int procNo)
{
return procIDs_[procNo];
}
//- Process index of first slave
static int firstSlave()
{
return 1;
}
//- Process index of last slave
static int lastSlave()
{
return nProcs() - 1;
}
//- Communication schedule for linear all-to-master (proc 0)
static const List<commsStruct>& linearCommunication()
{
return linearCommunication_;
}
//- Communication schedule for tree all-to-master (proc 0)
static const List<commsStruct>& treeCommunication()
{
return treeCommunication_;
}
//- Message tag of standard messages
static int& msgType()
{
return msgType_;
}
//- Get the communications type of the stream
commsTypes commsType() const
{
return commsType_;
}
//- Set the communications type of the stream
commsTypes commsType(const commsTypes ct)
{
commsTypes oldCommsType = commsType_;
commsType_ = ct;
return oldCommsType;
}
//- Exit program
static void exit(int errnum = 1);
//- Abort program
static void abort();
};
Ostream& operator<<(Ostream&, const UPstream::commsStruct&);
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -24,12 +24,12 @@ License
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#include "Pstream.H" #include "UPstream.H"
#include "boolList.H" #include "boolList.H"
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::Pstream::commsStruct::commsStruct() Foam::UPstream::commsStruct::commsStruct()
: :
above_(-1), above_(-1),
below_(0), below_(0),
@ -38,7 +38,7 @@ Foam::Pstream::commsStruct::commsStruct()
{} {}
Foam::Pstream::commsStruct::commsStruct Foam::UPstream::commsStruct::commsStruct
( (
const label above, const label above,
const labelList& below, const labelList& below,
@ -53,7 +53,7 @@ Foam::Pstream::commsStruct::commsStruct
{} {}
Foam::Pstream::commsStruct::commsStruct Foam::UPstream::commsStruct::commsStruct
( (
const label nProcs, const label nProcs,
const label myProcID, const label myProcID,
@ -91,7 +91,7 @@ Foam::Pstream::commsStruct::commsStruct
// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
bool Foam::Pstream::commsStruct::operator==(const commsStruct& comm) const bool Foam::UPstream::commsStruct::operator==(const commsStruct& comm) const
{ {
return return
( (
@ -103,7 +103,7 @@ bool Foam::Pstream::commsStruct::operator==(const commsStruct& comm) const
} }
bool Foam::Pstream::commsStruct::operator!=(const commsStruct& comm) const bool Foam::UPstream::commsStruct::operator!=(const commsStruct& comm) const
{ {
return !operator==(comm); return !operator==(comm);
} }
@ -111,7 +111,7 @@ bool Foam::Pstream::commsStruct::operator!=(const commsStruct& comm) const
// * * * * * * * * * * * * * * * Ostream Operator * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * Ostream Operator * * * * * * * * * * * * * //
Foam::Ostream& Foam::operator<<(Ostream& os, const Pstream::commsStruct& comm) Foam::Ostream& Foam::operator<<(Ostream& os, const UPstream::commsStruct& comm)
{ {
os << comm.above_ << token::SPACE os << comm.above_ << token::SPACE
<< comm.below_ << token::SPACE << comm.below_ << token::SPACE

View File

@ -49,15 +49,15 @@ namespace Foam
template <class T, class CombineOp> template <class T, class CombineOp>
void Pstream::combineGather void Pstream::combineGather
( (
const List<Pstream::commsStruct>& comms, const List<UPstream::commsStruct>& comms,
T& Value, T& Value,
const CombineOp& cop const CombineOp& cop
) )
{ {
if (Pstream::parRun()) if (UPstream::parRun())
{ {
// Get my communication order // Get my communication order
const commsStruct& myComm = comms[Pstream::myProcNo()]; const commsStruct& myComm = comms[UPstream::myProcNo()];
// Receive from my downstairs neighbours // Receive from my downstairs neighbours
forAll(myComm.below(), belowI) forAll(myComm.below(), belowI)
@ -67,9 +67,9 @@ void Pstream::combineGather
if (contiguous<T>()) if (contiguous<T>())
{ {
T value; T value;
IPstream::read UIPstream::read
( (
Pstream::scheduled, UPstream::scheduled,
belowID, belowID,
reinterpret_cast<char*>(&value), reinterpret_cast<char*>(&value),
sizeof(T) sizeof(T)
@ -85,7 +85,7 @@ void Pstream::combineGather
} }
else else
{ {
IPstream fromBelow(Pstream::scheduled, belowID); IPstream fromBelow(UPstream::scheduled, belowID);
T value(fromBelow); T value(fromBelow);
if (debug & 2) if (debug & 2)
@ -109,9 +109,9 @@ void Pstream::combineGather
if (contiguous<T>()) if (contiguous<T>())
{ {
OPstream::write UOPstream::write
( (
Pstream::scheduled, UPstream::scheduled,
myComm.above(), myComm.above(),
reinterpret_cast<const char*>(&Value), reinterpret_cast<const char*>(&Value),
sizeof(T) sizeof(T)
@ -119,7 +119,7 @@ void Pstream::combineGather
} }
else else
{ {
OPstream toAbove(Pstream::scheduled, myComm.above()); OPstream toAbove(UPstream::scheduled, myComm.above());
toAbove << Value; toAbove << Value;
} }
} }
@ -130,33 +130,37 @@ void Pstream::combineGather
template <class T, class CombineOp> template <class T, class CombineOp>
void Pstream::combineGather(T& Value, const CombineOp& cop) void Pstream::combineGather(T& Value, const CombineOp& cop)
{ {
if (Pstream::nProcs() < Pstream::nProcsSimpleSum) if (UPstream::nProcs() < UPstream::nProcsSimpleSum)
{ {
combineGather(Pstream::linearCommunication(), Value, cop); combineGather(UPstream::linearCommunication(), Value, cop);
} }
else else
{ {
combineGather(Pstream::treeCommunication(), Value, cop); combineGather(UPstream::treeCommunication(), Value, cop);
} }
} }
template <class T> template <class T>
void Pstream::combineScatter(const List<Pstream::commsStruct>& comms, T& Value) void Pstream::combineScatter
(
const List<UPstream::commsStruct>& comms,
T& Value
)
{ {
if (Pstream::parRun()) if (UPstream::parRun())
{ {
// Get my communication order // Get my communication order
const Pstream::commsStruct& myComm = comms[Pstream::myProcNo()]; const UPstream::commsStruct& myComm = comms[UPstream::myProcNo()];
// Reveive from up // Reveive from up
if (myComm.above() != -1) if (myComm.above() != -1)
{ {
if (contiguous<T>()) if (contiguous<T>())
{ {
IPstream::read UIPstream::read
( (
Pstream::scheduled, UPstream::scheduled,
myComm.above(), myComm.above(),
reinterpret_cast<char*>(&Value), reinterpret_cast<char*>(&Value),
sizeof(T) sizeof(T)
@ -164,7 +168,7 @@ void Pstream::combineScatter(const List<Pstream::commsStruct>& comms, T& Value)
} }
else else
{ {
IPstream fromAbove(Pstream::scheduled, myComm.above()); IPstream fromAbove(UPstream::scheduled, myComm.above());
Value = T(fromAbove); Value = T(fromAbove);
} }
@ -187,9 +191,9 @@ void Pstream::combineScatter(const List<Pstream::commsStruct>& comms, T& Value)
if (contiguous<T>()) if (contiguous<T>())
{ {
OPstream::write UOPstream::write
( (
Pstream::scheduled, UPstream::scheduled,
belowID, belowID,
reinterpret_cast<const char*>(&Value), reinterpret_cast<const char*>(&Value),
sizeof(T) sizeof(T)
@ -197,7 +201,7 @@ void Pstream::combineScatter(const List<Pstream::commsStruct>& comms, T& Value)
} }
else else
{ {
OPstream toBelow(Pstream::scheduled, belowID); OPstream toBelow(UPstream::scheduled, belowID);
toBelow << Value; toBelow << Value;
} }
} }
@ -208,13 +212,13 @@ void Pstream::combineScatter(const List<Pstream::commsStruct>& comms, T& Value)
template <class T> template <class T>
void Pstream::combineScatter(T& Value) void Pstream::combineScatter(T& Value)
{ {
if (Pstream::nProcs() < Pstream::nProcsSimpleSum) if (UPstream::nProcs() < UPstream::nProcsSimpleSum)
{ {
combineScatter(Pstream::linearCommunication(), Value); combineScatter(UPstream::linearCommunication(), Value);
} }
else else
{ {
combineScatter(Pstream::treeCommunication(), Value); combineScatter(UPstream::treeCommunication(), Value);
} }
} }
@ -226,15 +230,15 @@ void Pstream::combineScatter(T& Value)
template <class T, class CombineOp> template <class T, class CombineOp>
void Pstream::listCombineGather void Pstream::listCombineGather
( (
const List<Pstream::commsStruct>& comms, const List<UPstream::commsStruct>& comms,
List<T>& Values, List<T>& Values,
const CombineOp& cop const CombineOp& cop
) )
{ {
if (Pstream::parRun()) if (UPstream::parRun())
{ {
// Get my communication order // Get my communication order
const commsStruct& myComm = comms[Pstream::myProcNo()]; const commsStruct& myComm = comms[UPstream::myProcNo()];
// Receive from my downstairs neighbours // Receive from my downstairs neighbours
forAll(myComm.below(), belowI) forAll(myComm.below(), belowI)
@ -245,9 +249,9 @@ void Pstream::listCombineGather
{ {
List<T> receivedValues(Values.size()); List<T> receivedValues(Values.size());
IPstream::read UIPstream::read
( (
Pstream::scheduled, UPstream::scheduled,
belowID, belowID,
reinterpret_cast<char*>(receivedValues.begin()), reinterpret_cast<char*>(receivedValues.begin()),
receivedValues.byteSize() receivedValues.byteSize()
@ -266,7 +270,7 @@ void Pstream::listCombineGather
} }
else else
{ {
IPstream fromBelow(Pstream::scheduled, belowID); IPstream fromBelow(UPstream::scheduled, belowID);
List<T> receivedValues(fromBelow); List<T> receivedValues(fromBelow);
if (debug & 2) if (debug & 2)
@ -293,9 +297,9 @@ void Pstream::listCombineGather
if (contiguous<T>()) if (contiguous<T>())
{ {
OPstream::write UOPstream::write
( (
Pstream::scheduled, UPstream::scheduled,
myComm.above(), myComm.above(),
reinterpret_cast<const char*>(Values.begin()), reinterpret_cast<const char*>(Values.begin()),
Values.byteSize() Values.byteSize()
@ -303,7 +307,7 @@ void Pstream::listCombineGather
} }
else else
{ {
OPstream toAbove(Pstream::scheduled, myComm.above()); OPstream toAbove(UPstream::scheduled, myComm.above());
toAbove << Values; toAbove << Values;
} }
} }
@ -314,13 +318,13 @@ void Pstream::listCombineGather
template <class T, class CombineOp> template <class T, class CombineOp>
void Pstream::listCombineGather(List<T>& Values, const CombineOp& cop) void Pstream::listCombineGather(List<T>& Values, const CombineOp& cop)
{ {
if (Pstream::nProcs() < Pstream::nProcsSimpleSum) if (UPstream::nProcs() < UPstream::nProcsSimpleSum)
{ {
listCombineGather(Pstream::linearCommunication(), Values, cop); listCombineGather(UPstream::linearCommunication(), Values, cop);
} }
else else
{ {
listCombineGather(Pstream::treeCommunication(), Values, cop); listCombineGather(UPstream::treeCommunication(), Values, cop);
} }
} }
@ -328,23 +332,23 @@ void Pstream::listCombineGather(List<T>& Values, const CombineOp& cop)
template <class T> template <class T>
void Pstream::listCombineScatter void Pstream::listCombineScatter
( (
const List<Pstream::commsStruct>& comms, const List<UPstream::commsStruct>& comms,
List<T>& Values List<T>& Values
) )
{ {
if (Pstream::parRun()) if (UPstream::parRun())
{ {
// Get my communication order // Get my communication order
const Pstream::commsStruct& myComm = comms[Pstream::myProcNo()]; const UPstream::commsStruct& myComm = comms[UPstream::myProcNo()];
// Reveive from up // Reveive from up
if (myComm.above() != -1) if (myComm.above() != -1)
{ {
if (contiguous<T>()) if (contiguous<T>())
{ {
IPstream::read UIPstream::read
( (
Pstream::scheduled, UPstream::scheduled,
myComm.above(), myComm.above(),
reinterpret_cast<char*>(Values.begin()), reinterpret_cast<char*>(Values.begin()),
Values.byteSize() Values.byteSize()
@ -352,7 +356,7 @@ void Pstream::listCombineScatter
} }
else else
{ {
IPstream fromAbove(Pstream::scheduled, myComm.above()); IPstream fromAbove(UPstream::scheduled, myComm.above());
fromAbove >> Values; fromAbove >> Values;
} }
@ -375,9 +379,9 @@ void Pstream::listCombineScatter
if (contiguous<T>()) if (contiguous<T>())
{ {
OPstream::write UOPstream::write
( (
Pstream::scheduled, UPstream::scheduled,
belowID, belowID,
reinterpret_cast<const char*>(Values.begin()), reinterpret_cast<const char*>(Values.begin()),
Values.byteSize() Values.byteSize()
@ -385,7 +389,7 @@ void Pstream::listCombineScatter
} }
else else
{ {
OPstream toBelow(Pstream::scheduled, belowID); OPstream toBelow(UPstream::scheduled, belowID);
toBelow << Values; toBelow << Values;
} }
} }
@ -396,13 +400,13 @@ void Pstream::listCombineScatter
template <class T> template <class T>
void Pstream::listCombineScatter(List<T>& Values) void Pstream::listCombineScatter(List<T>& Values)
{ {
if (Pstream::nProcs() < Pstream::nProcsSimpleSum) if (UPstream::nProcs() < UPstream::nProcsSimpleSum)
{ {
listCombineScatter(Pstream::linearCommunication(), Values); listCombineScatter(UPstream::linearCommunication(), Values);
} }
else else
{ {
listCombineScatter(Pstream::treeCommunication(), Values); listCombineScatter(UPstream::treeCommunication(), Values);
} }
} }
@ -416,22 +420,22 @@ void Pstream::listCombineScatter(List<T>& Values)
template <class Container, class CombineOp> template <class Container, class CombineOp>
void Pstream::mapCombineGather void Pstream::mapCombineGather
( (
const List<Pstream::commsStruct>& comms, const List<UPstream::commsStruct>& comms,
Container& Values, Container& Values,
const CombineOp& cop const CombineOp& cop
) )
{ {
if (Pstream::parRun()) if (UPstream::parRun())
{ {
// Get my communication order // Get my communication order
const commsStruct& myComm = comms[Pstream::myProcNo()]; const commsStruct& myComm = comms[UPstream::myProcNo()];
// Receive from my downstairs neighbours // Receive from my downstairs neighbours
forAll(myComm.below(), belowI) forAll(myComm.below(), belowI)
{ {
label belowID = myComm.below()[belowI]; label belowID = myComm.below()[belowI];
IPstream fromBelow(Pstream::scheduled, belowID); IPstream fromBelow(UPstream::scheduled, belowID);
Container receivedValues(fromBelow); Container receivedValues(fromBelow);
if (debug & 2) if (debug & 2)
@ -471,7 +475,7 @@ void Pstream::mapCombineGather
<< " data:" << Values << endl; << " data:" << Values << endl;
} }
OPstream toAbove(Pstream::scheduled, myComm.above()); OPstream toAbove(UPstream::scheduled, myComm.above());
toAbove << Values; toAbove << Values;
} }
} }
@ -481,13 +485,13 @@ void Pstream::mapCombineGather
template <class Container, class CombineOp> template <class Container, class CombineOp>
void Pstream::mapCombineGather(Container& Values, const CombineOp& cop) void Pstream::mapCombineGather(Container& Values, const CombineOp& cop)
{ {
if (Pstream::nProcs() < Pstream::nProcsSimpleSum) if (UPstream::nProcs() < UPstream::nProcsSimpleSum)
{ {
mapCombineGather(Pstream::linearCommunication(), Values, cop); mapCombineGather(UPstream::linearCommunication(), Values, cop);
} }
else else
{ {
mapCombineGather(Pstream::treeCommunication(), Values, cop); mapCombineGather(UPstream::treeCommunication(), Values, cop);
} }
} }
@ -495,19 +499,19 @@ void Pstream::mapCombineGather(Container& Values, const CombineOp& cop)
template <class Container> template <class Container>
void Pstream::mapCombineScatter void Pstream::mapCombineScatter
( (
const List<Pstream::commsStruct>& comms, const List<UPstream::commsStruct>& comms,
Container& Values Container& Values
) )
{ {
if (Pstream::parRun()) if (UPstream::parRun())
{ {
// Get my communication order // Get my communication order
const Pstream::commsStruct& myComm = comms[Pstream::myProcNo()]; const UPstream::commsStruct& myComm = comms[UPstream::myProcNo()];
// Reveive from up // Reveive from up
if (myComm.above() != -1) if (myComm.above() != -1)
{ {
IPstream fromAbove(Pstream::scheduled, myComm.above()); IPstream fromAbove(UPstream::scheduled, myComm.above());
fromAbove >> Values; fromAbove >> Values;
if (debug & 2) if (debug & 2)
@ -527,7 +531,7 @@ void Pstream::mapCombineScatter
Pout<< " sending to " << belowID << " data:" << Values << endl; Pout<< " sending to " << belowID << " data:" << Values << endl;
} }
OPstream toBelow(Pstream::scheduled, belowID); OPstream toBelow(UPstream::scheduled, belowID);
toBelow << Values; toBelow << Values;
} }
} }
@ -537,19 +541,17 @@ void Pstream::mapCombineScatter
template <class Container> template <class Container>
void Pstream::mapCombineScatter(Container& Values) void Pstream::mapCombineScatter(Container& Values)
{ {
if (Pstream::nProcs() < Pstream::nProcsSimpleSum) if (UPstream::nProcs() < UPstream::nProcsSimpleSum)
{ {
mapCombineScatter(Pstream::linearCommunication(), Values); mapCombineScatter(UPstream::linearCommunication(), Values);
} }
else else
{ {
mapCombineScatter(Pstream::treeCommunication(), Values); mapCombineScatter(UPstream::treeCommunication(), Values);
} }
} }
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam } // End namespace Foam

View File

@ -0,0 +1,160 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 1991-2009 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 2 of the License, or (at your
option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Description
Exchange data.
\*---------------------------------------------------------------------------*/
#include "Pstream.H"
#include "contiguous.H"
#include "PstreamCombineReduceOps.H"
#include "UPstream.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
//template <template<class> class ListType, class T>
template <class Container, class T>
void Pstream::exchange
(
const List<Container >& sendBufs,
List<Container >& recvBufs,
labelListList& sizes,
const int tag,
const bool block
)
{
if (UPstream::parRun())
{
if (!contiguous<T>())
{
FatalErrorIn
(
"Pstream::exchange(..)"
) << "Continuous data only." << Foam::abort(FatalError);
}
if (sendBufs.size() != UPstream::nProcs())
{
FatalErrorIn
(
"Pstream::exchange(..)"
) << "Size of list:" << sendBufs.size()
<< " does not equal the number of processors:"
<< UPstream::nProcs()
<< Foam::abort(FatalError);
}
sizes.setSize(UPstream::nProcs());
labelList& nsTransPs = sizes[UPstream::myProcNo()];
nsTransPs.setSize(UPstream::nProcs());
forAll(sendBufs, procI)
{
nsTransPs[procI] = sendBufs[procI].size();
}
// Send sizes across.
int oldTag = UPstream::msgType();
UPstream::msgType() = tag;
combineReduce(sizes, UPstream::listEq());
UPstream::msgType() = oldTag;
// Set up receives
// ~~~~~~~~~~~~~~~
recvBufs.setSize(sendBufs.size());
forAll(sizes, procI)
{
label nRecv = sizes[procI][UPstream::myProcNo()];
if (procI != Pstream::myProcNo() && nRecv > 0)
{
recvBufs[procI].setSize(nRecv);
UIPstream::read
(
UPstream::nonBlocking,
procI,
reinterpret_cast<char*>(recvBufs[procI].begin()),
nRecv*sizeof(T),
tag
);
}
}
// Set up sends
// ~~~~~~~~~~~~
forAll(sendBufs, procI)
{
if (procI != Pstream::myProcNo() && sendBufs[procI].size() > 0)
{
if
(
!UOPstream::write
(
UPstream::nonBlocking,
procI,
reinterpret_cast<const char*>(sendBufs[procI].begin()),
sendBufs[procI].size()*sizeof(T),
tag
)
)
{
FatalErrorIn("Pstream::exchange(..)")
<< "Cannot send outgoing message. "
<< "to:" << procI << " nBytes:"
<< label(sendBufs[procI].size()*sizeof(T))
<< Foam::abort(FatalError);
}
}
}
// Wait for all to finish
// ~~~~~~~~~~~~~~~~~~~~~~
if (block)
{
Pstream::waitRequests();
}
}
// Do myself
recvBufs[Pstream::myProcNo()] = sendBufs[Pstream::myProcNo()];
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// ************************************************************************* //

View File

@ -30,7 +30,9 @@ Description
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#include "UOPstream.H"
#include "OPstream.H" #include "OPstream.H"
#include "UIPstream.H"
#include "IPstream.H" #include "IPstream.H"
#include "contiguous.H" #include "contiguous.H"
@ -44,15 +46,15 @@ namespace Foam
template <class T, class BinaryOp> template <class T, class BinaryOp>
void Pstream::gather void Pstream::gather
( (
const List<Pstream::commsStruct>& comms, const List<UPstream::commsStruct>& comms,
T& Value, T& Value,
const BinaryOp& bop const BinaryOp& bop
) )
{ {
if (Pstream::parRun()) if (UPstream::parRun())
{ {
// Get my communication order // Get my communication order
const commsStruct& myComm = comms[Pstream::myProcNo()]; const commsStruct& myComm = comms[UPstream::myProcNo()];
// Receive from my downstairs neighbours // Receive from my downstairs neighbours
forAll(myComm.below(), belowI) forAll(myComm.below(), belowI)
@ -61,9 +63,9 @@ void Pstream::gather
if (contiguous<T>()) if (contiguous<T>())
{ {
IPstream::read UIPstream::read
( (
Pstream::scheduled, UPstream::scheduled,
myComm.below()[belowI], myComm.below()[belowI],
reinterpret_cast<char*>(&value), reinterpret_cast<char*>(&value),
sizeof(T) sizeof(T)
@ -71,7 +73,7 @@ void Pstream::gather
} }
else else
{ {
IPstream fromBelow(Pstream::scheduled, myComm.below()[belowI]); IPstream fromBelow(UPstream::scheduled, myComm.below()[belowI]);
fromBelow >> value; fromBelow >> value;
} }
@ -83,9 +85,9 @@ void Pstream::gather
{ {
if (contiguous<T>()) if (contiguous<T>())
{ {
OPstream::write UOPstream::write
( (
Pstream::scheduled, UPstream::scheduled,
myComm.above(), myComm.above(),
reinterpret_cast<const char*>(&Value), reinterpret_cast<const char*>(&Value),
sizeof(T) sizeof(T)
@ -93,7 +95,7 @@ void Pstream::gather
} }
else else
{ {
OPstream toAbove(Pstream::scheduled, myComm.above()); OPstream toAbove(UPstream::scheduled, myComm.above());
toAbove << Value; toAbove << Value;
} }
} }
@ -104,33 +106,33 @@ void Pstream::gather
template <class T, class BinaryOp> template <class T, class BinaryOp>
void Pstream::gather(T& Value, const BinaryOp& bop) void Pstream::gather(T& Value, const BinaryOp& bop)
{ {
if (Pstream::nProcs() < Pstream::nProcsSimpleSum) if (UPstream::nProcs() < UPstream::nProcsSimpleSum)
{ {
gather(Pstream::linearCommunication(), Value, bop); gather(UPstream::linearCommunication(), Value, bop);
} }
else else
{ {
gather(Pstream::treeCommunication(), Value, bop); gather(UPstream::treeCommunication(), Value, bop);
} }
} }
template <class T> template <class T>
void Pstream::scatter(const List<Pstream::commsStruct>& comms, T& Value) void Pstream::scatter(const List<UPstream::commsStruct>& comms, T& Value)
{ {
if (Pstream::parRun()) if (UPstream::parRun())
{ {
// Get my communication order // Get my communication order
const commsStruct& myComm = comms[Pstream::myProcNo()]; const commsStruct& myComm = comms[UPstream::myProcNo()];
// Reveive from up // Reveive from up
if (myComm.above() != -1) if (myComm.above() != -1)
{ {
if (contiguous<T>()) if (contiguous<T>())
{ {
IPstream::read UIPstream::read
( (
Pstream::scheduled, UPstream::scheduled,
myComm.above(), myComm.above(),
reinterpret_cast<char*>(&Value), reinterpret_cast<char*>(&Value),
sizeof(T) sizeof(T)
@ -138,7 +140,7 @@ void Pstream::scatter(const List<Pstream::commsStruct>& comms, T& Value)
} }
else else
{ {
IPstream fromAbove(Pstream::scheduled, myComm.above()); IPstream fromAbove(UPstream::scheduled, myComm.above());
fromAbove >> Value; fromAbove >> Value;
} }
} }
@ -148,9 +150,9 @@ void Pstream::scatter(const List<Pstream::commsStruct>& comms, T& Value)
{ {
if (contiguous<T>()) if (contiguous<T>())
{ {
OPstream::write UOPstream::write
( (
Pstream::scheduled, UPstream::scheduled,
myComm.below()[belowI], myComm.below()[belowI],
reinterpret_cast<const char*>(&Value), reinterpret_cast<const char*>(&Value),
sizeof(T) sizeof(T)
@ -158,7 +160,7 @@ void Pstream::scatter(const List<Pstream::commsStruct>& comms, T& Value)
} }
else else
{ {
OPstream toBelow(Pstream::scheduled,myComm.below()[belowI]); OPstream toBelow(UPstream::scheduled,myComm.below()[belowI]);
toBelow << Value; toBelow << Value;
} }
} }
@ -169,13 +171,13 @@ void Pstream::scatter(const List<Pstream::commsStruct>& comms, T& Value)
template <class T> template <class T>
void Pstream::scatter(T& Value) void Pstream::scatter(T& Value)
{ {
if (Pstream::nProcs() < Pstream::nProcsSimpleSum) if (UPstream::nProcs() < UPstream::nProcsSimpleSum)
{ {
scatter(Pstream::linearCommunication(), Value); scatter(UPstream::linearCommunication(), Value);
} }
else else
{ {
scatter(Pstream::treeCommunication(), Value); scatter(UPstream::treeCommunication(), Value);
} }
} }

View File

@ -27,7 +27,7 @@ Description
communication schedule (usually linear-to-master or tree-to-master). communication schedule (usually linear-to-master or tree-to-master).
The gathered data will be a list with element procID the data from processor The gathered data will be a list with element procID the data from processor
procID. Before calling every processor should insert its value into procID. Before calling every processor should insert its value into
Values[Pstream::myProcNo()]. Values[UPstream::myProcNo()].
Note: after gather every processor only knows its own data and that of the Note: after gather every processor only knows its own data and that of the
processors below it. Only the 'master' of the communication schedule holds processors below it. Only the 'master' of the communication schedule holds
a fully filled List. Use scatter to distribute the data. a fully filled List. Use scatter to distribute the data.
@ -48,26 +48,26 @@ namespace Foam
template <class T> template <class T>
void Pstream::gatherList void Pstream::gatherList
( (
const List<Pstream::commsStruct>& comms, const List<UPstream::commsStruct>& comms,
List<T>& Values List<T>& Values
) )
{ {
if (Pstream::parRun()) if (UPstream::parRun())
{ {
if (Values.size() != Pstream::nProcs()) if (Values.size() != UPstream::nProcs())
{ {
FatalErrorIn FatalErrorIn
( (
"Pstream::gatherList(const List<Pstream::commsStruct>&" "UPstream::gatherList(const List<UPstream::commsStruct>&"
", List<T>)" ", List<T>)"
) << "Size of list:" << Values.size() ) << "Size of list:" << Values.size()
<< " does not equal the number of processors:" << " does not equal the number of processors:"
<< Pstream::nProcs() << UPstream::nProcs()
<< Foam::abort(FatalError); << Foam::abort(FatalError);
} }
// Get my communication order // Get my communication order
const commsStruct& myComm = comms[Pstream::myProcNo()]; const commsStruct& myComm = comms[UPstream::myProcNo()];
// Receive from my downstairs neighbours // Receive from my downstairs neighbours
forAll(myComm.below(), belowI) forAll(myComm.below(), belowI)
@ -79,9 +79,9 @@ void Pstream::gatherList
{ {
List<T> receivedValues(belowLeaves.size() + 1); List<T> receivedValues(belowLeaves.size() + 1);
IPstream::read UIPstream::read
( (
Pstream::scheduled, UPstream::scheduled,
belowID, belowID,
reinterpret_cast<char*>(receivedValues.begin()), reinterpret_cast<char*>(receivedValues.begin()),
receivedValues.byteSize() receivedValues.byteSize()
@ -96,7 +96,7 @@ void Pstream::gatherList
} }
else else
{ {
IPstream fromBelow(Pstream::scheduled, belowID); IPstream fromBelow(UPstream::scheduled, belowID);
fromBelow >> Values[belowID]; fromBelow >> Values[belowID];
if (debug & 2) if (debug & 2)
@ -132,14 +132,14 @@ void Pstream::gatherList
if (debug & 2) if (debug & 2)
{ {
Pout<< " sending to " << myComm.above() Pout<< " sending to " << myComm.above()
<< " data from me:" << Pstream::myProcNo() << " data from me:" << UPstream::myProcNo()
<< " data:" << Values[Pstream::myProcNo()] << endl; << " data:" << Values[UPstream::myProcNo()] << endl;
} }
if (contiguous<T>()) if (contiguous<T>())
{ {
List<T> sendingValues(belowLeaves.size() + 1); List<T> sendingValues(belowLeaves.size() + 1);
sendingValues[0] = Values[Pstream::myProcNo()]; sendingValues[0] = Values[UPstream::myProcNo()];
forAll(belowLeaves, leafI) forAll(belowLeaves, leafI)
{ {
@ -148,7 +148,7 @@ void Pstream::gatherList
OPstream::write OPstream::write
( (
Pstream::scheduled, UPstream::scheduled,
myComm.above(), myComm.above(),
reinterpret_cast<const char*>(sendingValues.begin()), reinterpret_cast<const char*>(sendingValues.begin()),
sendingValues.byteSize() sendingValues.byteSize()
@ -156,8 +156,8 @@ void Pstream::gatherList
} }
else else
{ {
OPstream toAbove(Pstream::scheduled, myComm.above()); OPstream toAbove(UPstream::scheduled, myComm.above());
toAbove << Values[Pstream::myProcNo()]; toAbove << Values[UPstream::myProcNo()];
forAll(belowLeaves, leafI) forAll(belowLeaves, leafI)
{ {
@ -180,13 +180,13 @@ void Pstream::gatherList
template <class T> template <class T>
void Pstream::gatherList(List<T>& Values) void Pstream::gatherList(List<T>& Values)
{ {
if (Pstream::nProcs() < Pstream::nProcsSimpleSum) if (UPstream::nProcs() < UPstream::nProcsSimpleSum)
{ {
gatherList(Pstream::linearCommunication(), Values); gatherList(UPstream::linearCommunication(), Values);
} }
else else
{ {
gatherList(Pstream::treeCommunication(), Values); gatherList(UPstream::treeCommunication(), Values);
} }
} }
@ -194,26 +194,26 @@ void Pstream::gatherList(List<T>& Values)
template <class T> template <class T>
void Pstream::scatterList void Pstream::scatterList
( (
const List<Pstream::commsStruct>& comms, const List<UPstream::commsStruct>& comms,
List<T>& Values List<T>& Values
) )
{ {
if (Pstream::parRun()) if (UPstream::parRun())
{ {
if (Values.size() != Pstream::nProcs()) if (Values.size() != UPstream::nProcs())
{ {
FatalErrorIn FatalErrorIn
( (
"Pstream::scatterList(const List<Pstream::commsStruct>&" "UPstream::scatterList(const List<UPstream::commsStruct>&"
", List<T>)" ", List<T>)"
) << "Size of list:" << Values.size() ) << "Size of list:" << Values.size()
<< " does not equal the number of processors:" << " does not equal the number of processors:"
<< Pstream::nProcs() << UPstream::nProcs()
<< Foam::abort(FatalError); << Foam::abort(FatalError);
} }
// Get my communication order // Get my communication order
const commsStruct& myComm = comms[Pstream::myProcNo()]; const commsStruct& myComm = comms[UPstream::myProcNo()];
// Reveive from up // Reveive from up
if (myComm.above() != -1) if (myComm.above() != -1)
@ -224,9 +224,9 @@ void Pstream::scatterList
{ {
List<T> receivedValues(notBelowLeaves.size()); List<T> receivedValues(notBelowLeaves.size());
IPstream::read UIPstream::read
( (
Pstream::scheduled, UPstream::scheduled,
myComm.above(), myComm.above(),
reinterpret_cast<char*>(receivedValues.begin()), reinterpret_cast<char*>(receivedValues.begin()),
receivedValues.byteSize() receivedValues.byteSize()
@ -239,7 +239,7 @@ void Pstream::scatterList
} }
else else
{ {
IPstream fromAbove(Pstream::scheduled, myComm.above()); IPstream fromAbove(UPstream::scheduled, myComm.above());
forAll(notBelowLeaves, leafI) forAll(notBelowLeaves, leafI)
{ {
@ -273,7 +273,7 @@ void Pstream::scatterList
OPstream::write OPstream::write
( (
Pstream::scheduled, UPstream::scheduled,
belowID, belowID,
reinterpret_cast<const char*>(sendingValues.begin()), reinterpret_cast<const char*>(sendingValues.begin()),
sendingValues.byteSize() sendingValues.byteSize()
@ -281,7 +281,7 @@ void Pstream::scatterList
} }
else else
{ {
OPstream toBelow(Pstream::scheduled, belowID); OPstream toBelow(UPstream::scheduled, belowID);
// Send data destined for all other processors below belowID // Send data destined for all other processors below belowID
forAll(notBelowLeaves, leafI) forAll(notBelowLeaves, leafI)
@ -305,13 +305,13 @@ void Pstream::scatterList
template <class T> template <class T>
void Pstream::scatterList(List<T>& Values) void Pstream::scatterList(List<T>& Values)
{ {
if (Pstream::nProcs() < Pstream::nProcsSimpleSum) if (UPstream::nProcs() < UPstream::nProcsSimpleSum)
{ {
scatterList(Pstream::linearCommunication(), Values); scatterList(UPstream::linearCommunication(), Values);
} }
else else
{ {
scatterList(Pstream::treeCommunication(), Values); scatterList(UPstream::treeCommunication(), Values);
} }
} }

View File

@ -229,11 +229,7 @@ void processorPointPatch::initPatchPatchPoints()
// Send the patchPatchPoints to the neighbouring processor // Send the patchPatchPoints to the neighbouring processor
OPstream toNeighbProc OPstream toNeighbProc(Pstream::blocking, neighbProcNo());
(
Pstream::blocking,
neighbProcNo()
);
toNeighbProc toNeighbProc
<< ppmp.size() // number of points for checking << ppmp.size() // number of points for checking
@ -252,11 +248,7 @@ void processorPointPatch::initPatchPatchPoints()
void Foam::processorPointPatch::calcPatchPatchPoints() void Foam::processorPointPatch::calcPatchPatchPoints()
{ {
// Get the patchPatchPoints from the neighbouring processor // Get the patchPatchPoints from the neighbouring processor
IPstream fromNeighbProc IPstream fromNeighbProc(Pstream::blocking, neighbProcNo());
(
Pstream::blocking,
neighbProcNo()
);
label nbrNPoints(readLabel(fromNeighbProc)); label nbrNPoints(readLabel(fromNeighbProc));
labelListList patchPatchPoints(fromNeighbProc); labelListList patchPatchPoints(fromNeighbProc);

View File

@ -381,7 +381,13 @@ Foam::mapDistribute::mapDistribute
} }
subMap_.setSize(Pstream::nProcs()); subMap_.setSize(Pstream::nProcs());
exchange(wantedRemoteElements, subMap_); labelListList sendSizes;
Pstream::exchange<labelList, label>
(
wantedRemoteElements,
subMap_,
sendSizes
);
// Renumber elements // Renumber elements
forAll(elements, i) forAll(elements, i)
@ -528,7 +534,13 @@ Foam::mapDistribute::mapDistribute
} }
subMap_.setSize(Pstream::nProcs()); subMap_.setSize(Pstream::nProcs());
exchange(wantedRemoteElements, subMap_); labelListList sendSizes;
Pstream::exchange<labelList, label>
(
wantedRemoteElements,
subMap_,
sendSizes
);
// Renumber elements // Renumber elements
forAll(cellCells, cellI) forAll(cellCells, cellI)

View File

@ -93,39 +93,8 @@ class mapDistribute
mutable autoPtr<List<labelPair> > schedulePtr_; mutable autoPtr<List<labelPair> > schedulePtr_;
//- Exchange data. sendBuf[procI] : data to send to processor procI
// To be moved into Pstream.
template<class T>
static void exchange
(
const List<List<T> >& sendBuf,
List<List<T> >& recvBuf
);
public: public:
// Public classes
//- combineReduce operator for lists. Used for counting.
class listEq
{
public:
template<class T>
void operator()(T& x, const T& y) const
{
forAll(y, i)
{
if (y[i].size())
{
x[i] = y[i];
}
}
}
};
// Constructors // Constructors
//- Construct from components //- Construct from components

View File

@ -25,6 +25,7 @@ License
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#include "Pstream.H" #include "Pstream.H"
#include "PstreamBuffers.H"
#include "PstreamCombineReduceOps.H" #include "PstreamCombineReduceOps.H"
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
@ -185,17 +186,9 @@ void Foam::mapDistribute::distribute
{ {
if (!contiguous<T>()) if (!contiguous<T>())
{ {
// 1. convert to contiguous buffer PstreamBuffers pBuffs(Pstream::nonBlocking);
// 2. send buffer
// 3. receive buffer
// 4. read from buffer into List<T>
List<List<char> > sendFields(Pstream::nProcs()); // Stream data into buffer
labelListList allNTrans(Pstream::nProcs());
labelList& nsTransPs = allNTrans[Pstream::myProcNo()];
nsTransPs.setSize(Pstream::nProcs(), 0);
// Stream data into sendField buffers
for (label domain = 0; domain < Pstream::nProcs(); domain++) for (label domain = 0; domain < Pstream::nProcs(); domain++)
{ {
const labelList& map = subMap[domain]; const labelList& map = subMap[domain];
@ -203,66 +196,13 @@ void Foam::mapDistribute::distribute
if (domain != Pstream::myProcNo() && map.size()) if (domain != Pstream::myProcNo() && map.size())
{ {
// Put data into send buffer // Put data into send buffer
OPstream toDomain(Pstream::nonBlocking, domain); UOPstream toDomain(domain, pBuffs);
toDomain << UIndirectList<T>(field, map); toDomain << UIndirectList<T>(field, map);
// Store the size
nsTransPs[domain] = toDomain.bufPosition();
// Transfer buffer out
sendFields[domain].transfer(toDomain.buf());
toDomain.bufPosition() = 0;
} }
} }
// Send sizes across
combineReduce(allNTrans, listEq());
// Start sending buffers
for (label domain = 0; domain < Pstream::nProcs(); domain++)
{
const labelList& map = subMap[domain];
if (domain != Pstream::myProcNo() && map.size())
{
OPstream::write
(
Pstream::nonBlocking,
domain,
reinterpret_cast<const char*>
(
sendFields[domain].begin()
),
nsTransPs[domain]
);
}
}
// Set up receives from neighbours
PtrList<IPstream> fromSlave(Pstream::nProcs());
for (label domain = 0; domain < Pstream::nProcs(); domain++)
{
const labelList& map = constructMap[domain];
if (domain != Pstream::myProcNo() && map.size())
{
// Start receiving // Start receiving
fromSlave.set pBuffs.finishedSends();
(
domain,
new IPstream
(
Pstream::nonBlocking,
domain,
allNTrans[domain][Pstream::myProcNo()]
)
);
}
}
{ {
// Set up 'send' to myself // Set up 'send' to myself
@ -285,10 +225,6 @@ void Foam::mapDistribute::distribute
} }
} }
// Wait till all finished
Pstream::waitRequests();
// Consume // Consume
for (label domain = 0; domain < Pstream::nProcs(); domain++) for (label domain = 0; domain < Pstream::nProcs(); domain++)
{ {
@ -296,7 +232,8 @@ void Foam::mapDistribute::distribute
if (domain != Pstream::myProcNo() && map.size()) if (domain != Pstream::myProcNo() && map.size())
{ {
List<T> recvField(fromSlave[domain]); UIPstream str(domain, pBuffs);
List<T> recvField(str);
if (recvField.size() != map.size()) if (recvField.size() != map.size())
{ {
@ -322,9 +259,6 @@ void Foam::mapDistribute::distribute
{ {
field[map[i]] = recvField[i]; field[map[i]] = recvField[i];
} }
// Delete receive buffer
fromSlave.set(domain, NULL);
} }
} }
} }
@ -618,17 +552,10 @@ void Foam::mapDistribute::distribute
{ {
if (!contiguous<T>()) if (!contiguous<T>())
{ {
// 1. convert to contiguous buffer //XXXXXX
// 2. send buffer PstreamBuffers pBuffs(Pstream::nonBlocking);
// 3. receive buffer
// 4. read from buffer into List<T>
List<List<char> > sendFields(Pstream::nProcs()); // Stream data into buffer
labelListList allNTrans(Pstream::nProcs());
labelList& nsTransPs = allNTrans[Pstream::myProcNo()];
nsTransPs.setSize(Pstream::nProcs());
// Stream data into sendField buffers
for (label domain = 0; domain < Pstream::nProcs(); domain++) for (label domain = 0; domain < Pstream::nProcs(); domain++)
{ {
const labelList& map = subMap[domain]; const labelList& map = subMap[domain];
@ -636,65 +563,13 @@ void Foam::mapDistribute::distribute
if (domain != Pstream::myProcNo() && map.size()) if (domain != Pstream::myProcNo() && map.size())
{ {
// Put data into send buffer // Put data into send buffer
OPstream toDomain(Pstream::nonBlocking, domain); UOPstream toDomain(domain, pBuffs);
toDomain << UIndirectList<T>(field, map); toDomain << UIndirectList<T>(field, map);
// Store the size
nsTransPs[domain] = toDomain.bufPosition();
// Transfer buffer out
sendFields[domain].transfer(toDomain.buf());
toDomain.bufPosition() = 0;
} }
} }
// Send sizes across
combineReduce(allNTrans, listEq());
// Start sending buffers
for (label domain = 0; domain < Pstream::nProcs(); domain++)
{
const labelList& map = subMap[domain];
if (domain != Pstream::myProcNo() && map.size())
{
OPstream::write
(
Pstream::nonBlocking,
domain,
reinterpret_cast<const char*>
(
sendFields[domain].begin()
),
nsTransPs[domain]
);
}
}
// Set up receives from neighbours
PtrList<IPstream> fromSlave(Pstream::nProcs());
for (label domain = 0; domain < Pstream::nProcs(); domain++)
{
const labelList& map = constructMap[domain];
if (domain != Pstream::myProcNo() && map.size())
{
// Start receiving // Start receiving
fromSlave.set pBuffs.finishedSends();
(
domain,
new IPstream
(
Pstream::nonBlocking,
domain,
allNTrans[domain][Pstream::myProcNo()]
)
);
}
}
{ {
// Set up 'send' to myself // Set up 'send' to myself
@ -715,7 +590,7 @@ void Foam::mapDistribute::distribute
// Wait till all finished // Wait till all finished
Pstream::waitRequests(); UPstream::waitRequests();
// Consume // Consume
for (label domain = 0; domain < Pstream::nProcs(); domain++) for (label domain = 0; domain < Pstream::nProcs(); domain++)
@ -724,7 +599,8 @@ void Foam::mapDistribute::distribute
if (domain != Pstream::myProcNo() && map.size()) if (domain != Pstream::myProcNo() && map.size())
{ {
List<T> recvField(fromSlave[domain]); UIPstream str(domain, pBuffs);
List<T> recvField(str);
if (recvField.size() != map.size()) if (recvField.size() != map.size())
{ {
@ -750,9 +626,6 @@ void Foam::mapDistribute::distribute
{ {
cop(field[map[i]], recvField[i]); cop(field[map[i]], recvField[i]);
} }
// Delete receive buffer
fromSlave.set(domain, NULL);
} }
} }
} }
@ -796,7 +669,7 @@ void Foam::mapDistribute::distribute
if (domain != Pstream::myProcNo() && map.size()) if (domain != Pstream::myProcNo() && map.size())
{ {
recvFields[domain].setSize(map.size()); recvFields[domain].setSize(map.size());
IPstream::read UIPstream::read
( (
Pstream::nonBlocking, Pstream::nonBlocking,
domain, domain,
@ -886,78 +759,4 @@ void Foam::mapDistribute::distribute
} }
template<class T>
void Foam::mapDistribute::exchange
(
const List<List<T> >& sendBuf,
List<List<T> >& recvBuf
)
{
if (!contiguous<T>())
{
FatalErrorIn("mapDistribute::exchange(..)")
<< "Not contiguous" << exit(FatalError);
}
if (Pstream::parRun())
{
// Determine sizes
// ~~~~~~~~~~~~~~~
labelListList allNTrans(Pstream::nProcs());
allNTrans[Pstream::myProcNo()].setSize(Pstream::nProcs());
forAll(allNTrans, procI)
{
allNTrans[Pstream::myProcNo()][procI] = sendBuf[procI].size();
}
combineReduce(allNTrans, listEq());
// Set up receives
// ~~~~~~~~~~~~~~~
recvBuf.setSize(Pstream::nProcs());
forAll(recvBuf, procI)
{
if (procI != Pstream::myProcNo())
{
recvBuf[procI].setSize(allNTrans[procI][Pstream::myProcNo()]);
IPstream::read
(
Pstream::nonBlocking,
procI,
reinterpret_cast<char*>(recvBuf[procI].begin()),
recvBuf[procI].byteSize()
);
}
}
// Set up sends
// ~~~~~~~~~~~~
forAll(sendBuf, procI)
{
if (procI != Pstream::myProcNo())
{
OPstream::write
(
Pstream::nonBlocking,
procI,
reinterpret_cast<const char*>(sendBuf[procI].begin()),
sendBuf[procI].byteSize()
);
}
}
// Wait for completion
Pstream::waitRequests();
}
// Do myself
recvBuf[Pstream::myProcNo()] = sendBuf[Pstream::myProcNo()];
}
// ************************************************************************* // // ************************************************************************* //

View File

@ -402,11 +402,7 @@ void Foam::syncTools::syncPointMap
{ {
// Send to master // Send to master
{ {
OPstream toMaster OPstream toMaster(Pstream::blocking, Pstream::masterNo());
(
Pstream::blocking,
Pstream::masterNo()
);
toMaster << sharedPointValues; toMaster << sharedPointValues;
} }
// Receive merged values // Receive merged values

View File

@ -1,5 +1,5 @@
Pstream.C UPstream.C
IPread.C UIPread.C
OPwrite.C UOPwrite.C
LIB = $(FOAM_LIBBIN)/dummy/libPstream LIB = $(FOAM_LIBBIN)/dummy/libPstream

View File

@ -23,38 +23,40 @@ License
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Description Description
Read token and binary block from IPstream Read from UIPstream
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#include "error.H" #include "UIPstream.H"
#include "IPstream.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// * * * * * * * * * * * * * * * * Constructor * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * Constructor * * * * * * * * * * * * * * * //
Foam::IPstream::IPstream Foam::UIPstream::UIPstream
( (
const commsTypes commsType, const commsTypes commsType,
const int fromProcNo, const int fromProcNo,
const label bufSize, DynamicList<char>& externalBuf,
const int tag,
streamFormat format, streamFormat format,
versionNumber version versionNumber version
) )
: :
Pstream(commsType, bufSize), UPstream(commsType),
Istream(format, version), Istream(format, version),
fromProcNo_(fromProcNo), fromProcNo_(fromProcNo),
externalBuf_(externalBuf),
externalBufPosition_(0),
tag_(tag),
messageSize_(0) messageSize_(0)
{ {
notImplemented notImplemented
( (
"IPsream::IPstream" "UIPstream::UIPstream"
"(" "("
"const commsTypes," "const commsTypes,"
"const int fromProcNo," "const int fromProcNo,"
"const label bufSize," "DynamicList<char>&,"
"const int tag,"
"streamFormat, versionNumber" "streamFormat, versionNumber"
")" ")"
); );
@ -63,22 +65,24 @@ Foam::IPstream::IPstream
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
int Foam::IPstream::read Foam::label Foam::UIPstream::read
( (
const commsTypes commsType, const commsTypes commsType,
const int fromProcNo, const int fromProcNo,
char* buf, char* buf,
const std::streamsize bufSize const std::streamsize bufSize,
const int tag
) )
{ {
notImplemented notImplemented
( (
"IPstream::read" "UIPstream::read"
"(" "("
"const commsTypes," "const commsTypes,"
"const int fromProcNo," "const int fromProcNo,"
"char* buf," "char* buf,"
"const label bufSize" "const label bufSize,"
"const int tag"
")" ")"
); );

View File

@ -27,37 +27,28 @@ Description
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#include "error.H" #include "UOPstream.H"
#include "OPstream.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::OPstream::~OPstream()
{
notImplemented("OPstream::~OPstream()");
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
bool Foam::OPstream::write bool Foam::UOPstream::write
( (
const commsTypes commsType, const commsTypes commsType,
const int toProcNo, const int toProcNo,
const char* buf, const char* buf,
const std::streamsize bufSize const std::streamsize bufSize,
const int tag
) )
{ {
notImplemented notImplemented
( (
"IPstream::write" "UOPstream::write"
"(" "("
"const commsTypes commsType," "const commsTypes commsType,"
"const int fromProcNo," "const int fromProcNo,"
"char* buf," "char* buf,"
"const label bufSize" "const label bufSize,"
"const int tag"
")" ")"
); );

View File

@ -24,20 +24,18 @@ License
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#include "Pstream.H" #include "UPstream.H"
#include "PstreamReduceOps.H" #include "PstreamReduceOps.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // void Foam::UPstream::addValidParOptions(HashTable<string>& validParOptions)
void Foam::Pstream::addValidParOptions(HashTable<string>& validParOptions)
{} {}
bool Foam::Pstream::init(int& argc, char**& argv) bool Foam::UPstream::init(int& argc, char**& argv)
{ {
FatalErrorIn("Pstream::init(int& argc, char**& argv)") FatalErrorIn("UPstream::init(int& argc, char**& argv)")
<< "Trying to use the dummy Pstream library." << nl << "Trying to use the dummy Pstream library." << nl
<< "This dummy library cannot be used in parallel mode" << "This dummy library cannot be used in parallel mode"
<< Foam::exit(FatalError); << Foam::exit(FatalError);
@ -46,15 +44,15 @@ bool Foam::Pstream::init(int& argc, char**& argv)
} }
void Foam::Pstream::exit(int errnum) void Foam::UPstream::exit(int errnum)
{ {
notImplemented("Pstream::exit(int errnum)"); notImplemented("UPstream::exit(int errnum)");
} }
void Foam::Pstream::abort() void Foam::UPstream::abort()
{ {
notImplemented("Pstream::abort()"); notImplemented("UPstream::abort()");
} }
@ -63,13 +61,13 @@ void Foam::reduce(scalar&, const sumOp<scalar>&)
void Foam::Pstream::waitRequests() void Foam::UPstream::waitRequests()
{} {}
bool Foam::Pstream::finishedRequest(const label i) bool Foam::UPstream::finishedRequest(const label i)
{ {
notImplemented("Pstream::finishedRequest()"); notImplemented("UPstream::finishedRequest()");
return false; return false;
} }

View File

@ -1,6 +1,6 @@
OPwrite.C UOPwrite.C
IPread.C UIPread.C
Pstream.C UPstream.C
PstreamGlobals.C PstreamGlobals.C
LIB = $(FOAM_MPI_LIBBIN)/libPstream LIB = $(FOAM_MPI_LIBBIN)/libPstream

View File

@ -23,91 +23,161 @@ License
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Description Description
Read token and binary block from IPstream Read from UIPstream
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#include "mpi.h" #include "mpi.h"
#include "IPstream.H" #include "UIPstream.H"
#include "PstreamGlobals.H" #include "PstreamGlobals.H"
#include "IOstreams.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
// Outstanding non-blocking operations.
//! @cond fileScope
//Foam::DynamicList<MPI_Request> IPstream_outstandingRequests_;
//! @endcond fileScope
// * * * * * * * * * * * * * * * * Constructor * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * Constructor * * * * * * * * * * * * * * * //
Foam::IPstream::IPstream Foam::UIPstream::UIPstream
( (
const commsTypes commsType, const commsTypes commsType,
const int fromProcNo, const int fromProcNo,
const label bufSize, DynamicList<char>& externalBuf,
const int tag,
streamFormat format, streamFormat format,
versionNumber version versionNumber version
) )
: :
Pstream(commsType, bufSize), UPstream(commsType),
Istream(format, version), Istream(format, version),
fromProcNo_(fromProcNo), fromProcNo_(fromProcNo),
externalBuf_(externalBuf),
externalBufPosition_(0),
tag_(tag),
messageSize_(0) messageSize_(0)
{ {
setOpened(); setOpened();
setGood(); setGood();
if (commsType == UPstream::nonBlocking)
{
// Message is already received into externalBuf
}
else
{
MPI_Status status; MPI_Status status;
// Cannot use buf_.size() since appends a few bytes extra label wantedSize = externalBuf_.capacity();
label realBufSize = bufSize;
// If the buffer size is not specified, probe the incomming message // If the buffer size is not specified, probe the incomming message
// and set it // and set it
if (!bufSize) if (!wantedSize)
{ {
if (commsType == nonBlocking) MPI_Probe(procID(fromProcNo_), tag_, MPI_COMM_WORLD, &status);
{
FatalErrorIn
(
"IPstream::IPstream(const commsTypes, const int, "
"const label, streamFormat, versionNumber)"
) << "Can use nonBlocking mode only with pre-allocated buffers"
<< Foam::abort(FatalError);
}
MPI_Probe(procID(fromProcNo_), msgType(), MPI_COMM_WORLD, &status);
MPI_Get_count(&status, MPI_BYTE, &messageSize_); MPI_Get_count(&status, MPI_BYTE, &messageSize_);
buf_.setSize(messageSize_); externalBuf_.setCapacity(messageSize_);
realBufSize = buf_.size(); wantedSize = messageSize_;
} }
messageSize_ = read(commsType, fromProcNo_, buf_.begin(), realBufSize); messageSize_ = UIPstream::read
(
commsType,
fromProcNo_,
externalBuf_.begin(),
wantedSize,
tag_
);
// Set addressed size. Leave actual allocated memory intact.
externalBuf_.setSize(messageSize_);
if (!messageSize_) if (!messageSize_)
{ {
FatalErrorIn FatalErrorIn
( (
"IPstream::IPstream(const commsTypes, const int, " "UIPstream::UIPstream(const commsTypes, const int, "
"const label, streamFormat, versionNumber)" "DynamicList<char>&, streamFormat, versionNumber)"
) << "read failed" ) << "read failed"
<< Foam::abort(FatalError); << Foam::abort(FatalError);
} }
} }
}
Foam::UIPstream::UIPstream(const int fromProcNo, PstreamBuffers& buffers)
:
UPstream(buffers.commsType_),
Istream(buffers.format_, buffers.version_),
fromProcNo_(fromProcNo),
externalBuf_(buffers.recvBuf_[fromProcNo]),
externalBufPosition_(0),
tag_(buffers.tag_),
messageSize_(0)
{
if (commsType() != UPstream::scheduled && !buffers.finishedSendsCalled_)
{
FatalErrorIn("UIPstream::UIPstream(const int, PstreamBuffers&)")
<< "PstreamBuffers::finishedSends() never called." << endl
<< "Please call PstreamBuffers::finishedSends() after doing"
<< " all your sends (using UOPstream) and before doing any"
<< " receives (using UIPstream)" << Foam::exit(FatalError);
}
setOpened();
setGood();
if (commsType() == UPstream::nonBlocking)
{
// Message is already received into externalBuf
}
else
{
MPI_Status status;
label wantedSize = externalBuf_.capacity();
// If the buffer size is not specified, probe the incomming message
// and set it
if (!wantedSize)
{
MPI_Probe(procID(fromProcNo_), tag_, MPI_COMM_WORLD, &status);
MPI_Get_count(&status, MPI_BYTE, &messageSize_);
externalBuf_.setCapacity(messageSize_);
wantedSize = messageSize_;
}
messageSize_ = UIPstream::read
(
commsType(),
fromProcNo_,
externalBuf_.begin(),
wantedSize,
tag_
);
// Set addressed size. Leave actual allocated memory intact.
externalBuf_.setSize(messageSize_);
if (!messageSize_)
{
FatalErrorIn
(
"UIPstream::UIPstream(const int, PstreamBuffers&)"
) << "read failed"
<< Foam::abort(FatalError);
}
}
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
Foam::label Foam::IPstream::read Foam::label Foam::UIPstream::read
( (
const commsTypes commsType, const commsTypes commsType,
const int fromProcNo, const int fromProcNo,
char* buf, char* buf,
const std::streamsize bufSize const std::streamsize bufSize,
const int tag
) )
{ {
if (commsType == blocking || commsType == scheduled) if (commsType == blocking || commsType == scheduled)
@ -122,7 +192,7 @@ Foam::label Foam::IPstream::read
bufSize, bufSize,
MPI_PACKED, MPI_PACKED,
procID(fromProcNo), procID(fromProcNo),
msgType(), tag,
MPI_COMM_WORLD, MPI_COMM_WORLD,
&status &status
) )
@ -130,7 +200,7 @@ Foam::label Foam::IPstream::read
{ {
FatalErrorIn FatalErrorIn
( (
"IPstream::read" "UIPstream::read"
"(const int fromProcNo, char* buf, std::streamsize bufSize)" "(const int fromProcNo, char* buf, std::streamsize bufSize)"
) << "MPI_Recv cannot receive incomming message" ) << "MPI_Recv cannot receive incomming message"
<< Foam::abort(FatalError); << Foam::abort(FatalError);
@ -148,7 +218,7 @@ Foam::label Foam::IPstream::read
{ {
FatalErrorIn FatalErrorIn
( (
"IPstream::read" "UIPstream::read"
"(const int fromProcNo, char* buf, std::streamsize bufSize)" "(const int fromProcNo, char* buf, std::streamsize bufSize)"
) << "buffer (" << label(bufSize) ) << "buffer (" << label(bufSize)
<< ") not large enough for incomming message (" << ") not large enough for incomming message ("
@ -170,7 +240,7 @@ Foam::label Foam::IPstream::read
bufSize, bufSize,
MPI_PACKED, MPI_PACKED,
procID(fromProcNo), procID(fromProcNo),
msgType(), tag,
MPI_COMM_WORLD, MPI_COMM_WORLD,
&request &request
) )
@ -178,7 +248,7 @@ Foam::label Foam::IPstream::read
{ {
FatalErrorIn FatalErrorIn
( (
"IPstream::read" "UIPstream::read"
"(const int fromProcNo, char* buf, std::streamsize bufSize)" "(const int fromProcNo, char* buf, std::streamsize bufSize)"
) << "MPI_Recv cannot start non-blocking receive" ) << "MPI_Recv cannot start non-blocking receive"
<< Foam::abort(FatalError); << Foam::abort(FatalError);
@ -195,7 +265,7 @@ Foam::label Foam::IPstream::read
{ {
FatalErrorIn FatalErrorIn
( (
"IPstream::read" "UIPstream::read"
"(const int fromProcNo, char* buf, std::streamsize bufSize)" "(const int fromProcNo, char* buf, std::streamsize bufSize)"
) << "Unsupported communications type " << commsType ) << "Unsupported communications type " << commsType
<< Foam::abort(FatalError); << Foam::abort(FatalError);
@ -205,6 +275,4 @@ Foam::label Foam::IPstream::read
} }
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// ************************************************************************* // // ************************************************************************* //

View File

@ -29,54 +29,18 @@ Description
#include "mpi.h" #include "mpi.h"
#include "OPstream.H" #include "UOPstream.H"
#include "PstreamGlobals.H" #include "PstreamGlobals.H"
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::OPstream::~OPstream()
{
if (commsType_ == nonBlocking)
{
// alloc nonBlocking only if empty buffer. This denotes the buffer
// having been transfered out.
if (bufPosition_ > 0)
{
FatalErrorIn("OPstream::~OPstream()")
<< "OPstream contains buffer so cannot be used with nonBlocking"
<< " since destructor would destroy buffer whilst possibly"
<< " still sending." << Foam::abort(FatalError);
}
}
else
{
if
(
!write
(
commsType_,
toProcNo_,
buf_.begin(),
bufPosition_
)
)
{
FatalErrorIn("OPstream::~OPstream()")
<< "MPI cannot send outgoing message"
<< Foam::abort(FatalError);
}
}
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
bool Foam::OPstream::write bool Foam::UOPstream::write
( (
const commsTypes commsType, const commsTypes commsType,
const int toProcNo, const int toProcNo,
const char* buf, const char* buf,
const std::streamsize bufSize const std::streamsize bufSize,
const int tag
) )
{ {
bool transferFailed = true; bool transferFailed = true;
@ -89,7 +53,7 @@ bool Foam::OPstream::write
bufSize, bufSize,
MPI_PACKED, MPI_PACKED,
procID(toProcNo), procID(toProcNo),
msgType(), tag,
MPI_COMM_WORLD MPI_COMM_WORLD
); );
} }
@ -101,7 +65,7 @@ bool Foam::OPstream::write
bufSize, bufSize,
MPI_PACKED, MPI_PACKED,
procID(toProcNo), procID(toProcNo),
msgType(), tag,
MPI_COMM_WORLD MPI_COMM_WORLD
); );
} }
@ -115,7 +79,7 @@ bool Foam::OPstream::write
bufSize, bufSize,
MPI_PACKED, MPI_PACKED,
procID(toProcNo), procID(toProcNo),
msgType(), tag,
MPI_COMM_WORLD, MPI_COMM_WORLD,
&request &request
); );
@ -126,8 +90,9 @@ bool Foam::OPstream::write
{ {
FatalErrorIn FatalErrorIn
( (
"OPstream::write" "UOPstream::write"
"(const int fromProcNo, char* buf, std::streamsize bufSize)" "(const int fromProcNo, char* buf, std::streamsize bufSize"
", const int)"
) << "Unsupported communications type " << commsType ) << "Unsupported communications type " << commsType
<< Foam::abort(FatalError); << Foam::abort(FatalError);
} }

View File

@ -26,7 +26,7 @@ License
#include "mpi.h" #include "mpi.h"
#include "Pstream.H" #include "UPstream.H"
#include "PstreamReduceOps.H" #include "PstreamReduceOps.H"
#include "OSspecific.H" #include "OSspecific.H"
#include "PstreamGlobals.H" #include "PstreamGlobals.H"
@ -50,7 +50,7 @@ License
// valid parallel options vary between implementations, but flag common ones. // valid parallel options vary between implementations, but flag common ones.
// if they are not removed by MPI_Init(), the subsequent argument processing // if they are not removed by MPI_Init(), the subsequent argument processing
// will notice that they are wrong // will notice that they are wrong
void Foam::Pstream::addValidParOptions(HashTable<string>& validParOptions) void Foam::UPstream::addValidParOptions(HashTable<string>& validParOptions)
{ {
validParOptions.insert("np", ""); validParOptions.insert("np", "");
validParOptions.insert("p4pg", "PI file"); validParOptions.insert("p4pg", "PI file");
@ -62,7 +62,7 @@ void Foam::Pstream::addValidParOptions(HashTable<string>& validParOptions)
} }
bool Foam::Pstream::init(int& argc, char**& argv) bool Foam::UPstream::init(int& argc, char**& argv)
{ {
MPI_Init(&argc, &argv); MPI_Init(&argc, &argv);
@ -72,8 +72,8 @@ bool Foam::Pstream::init(int& argc, char**& argv)
if (numprocs <= 1) if (numprocs <= 1)
{ {
FatalErrorIn("Pstream::init(int& argc, char**& argv)") FatalErrorIn("UPstream::init(int& argc, char**& argv)")
<< "bool Pstream::init(int& argc, char**& argv) : " << "bool IPstream::init(int& argc, char**& argv) : "
"attempt to run parallel on 1 processor" "attempt to run parallel on 1 processor"
<< Foam::abort(FatalError); << Foam::abort(FatalError);
} }
@ -101,8 +101,8 @@ bool Foam::Pstream::init(int& argc, char**& argv)
} }
else else
{ {
FatalErrorIn("Pstream::init(int& argc, char**& argv)") FatalErrorIn("UPstream::init(int& argc, char**& argv)")
<< "Pstream::init(int& argc, char**& argv) : " << "UPstream::init(int& argc, char**& argv) : "
<< "environment variable MPI_BUFFER_SIZE not defined" << "environment variable MPI_BUFFER_SIZE not defined"
<< Foam::abort(FatalError); << Foam::abort(FatalError);
} }
@ -122,7 +122,7 @@ bool Foam::Pstream::init(int& argc, char**& argv)
} }
void Foam::Pstream::exit(int errnum) void Foam::UPstream::exit(int errnum)
{ {
# ifndef SGIMPI # ifndef SGIMPI
int size; int size;
@ -136,10 +136,10 @@ void Foam::Pstream::exit(int errnum)
label n = PstreamGlobals::outstandingRequests_.size(); label n = PstreamGlobals::outstandingRequests_.size();
PstreamGlobals::outstandingRequests_.clear(); PstreamGlobals::outstandingRequests_.clear();
WarningIn("Pstream::exit(int)") WarningIn("UPstream::exit(int)")
<< "There are still " << n << " outstanding MPI_Requests." << endl << "There are still " << n << " outstanding MPI_Requests." << endl
<< "This means that your code exited before doing a" << "This means that your code exited before doing a"
<< " Pstream::waitRequests()." << endl << " UPstream::waitRequests()." << endl
<< "This should not happen for a normal code exit." << "This should not happen for a normal code exit."
<< endl; << endl;
} }
@ -156,7 +156,7 @@ void Foam::Pstream::exit(int errnum)
} }
void Foam::Pstream::abort() void Foam::UPstream::abort()
{ {
MPI_Abort(MPI_COMM_WORLD, 1); MPI_Abort(MPI_COMM_WORLD, 1);
} }
@ -164,19 +164,19 @@ void Foam::Pstream::abort()
void Foam::reduce(scalar& Value, const sumOp<scalar>& bop) void Foam::reduce(scalar& Value, const sumOp<scalar>& bop)
{ {
if (!Pstream::parRun()) if (!UPstream::parRun())
{ {
return; return;
} }
if (Pstream::nProcs() <= Pstream::nProcsSimpleSum) if (UPstream::nProcs() <= UPstream::nProcsSimpleSum)
{ {
if (Pstream::master()) if (UPstream::master())
{ {
for for
( (
int slave=Pstream::firstSlave(); int slave=UPstream::firstSlave();
slave<=Pstream::lastSlave(); slave<=UPstream::lastSlave();
slave++ slave++
) )
{ {
@ -189,8 +189,8 @@ void Foam::reduce(scalar& Value, const sumOp<scalar>& bop)
&value, &value,
1, 1,
MPI_SCALAR, MPI_SCALAR,
Pstream::procID(slave), UPstream::procID(slave),
Pstream::msgType(), UPstream::msgType(),
MPI_COMM_WORLD, MPI_COMM_WORLD,
MPI_STATUS_IGNORE MPI_STATUS_IGNORE
) )
@ -215,8 +215,8 @@ void Foam::reduce(scalar& Value, const sumOp<scalar>& bop)
&Value, &Value,
1, 1,
MPI_SCALAR, MPI_SCALAR,
Pstream::procID(Pstream::masterNo()), UPstream::procID(UPstream::masterNo()),
Pstream::msgType(), UPstream::msgType(),
MPI_COMM_WORLD MPI_COMM_WORLD
) )
) )
@ -230,12 +230,12 @@ void Foam::reduce(scalar& Value, const sumOp<scalar>& bop)
} }
if (Pstream::master()) if (UPstream::master())
{ {
for for
( (
int slave=Pstream::firstSlave(); int slave=UPstream::firstSlave();
slave<=Pstream::lastSlave(); slave<=UPstream::lastSlave();
slave++ slave++
) )
{ {
@ -246,8 +246,8 @@ void Foam::reduce(scalar& Value, const sumOp<scalar>& bop)
&Value, &Value,
1, 1,
MPI_SCALAR, MPI_SCALAR,
Pstream::procID(slave), UPstream::procID(slave),
Pstream::msgType(), UPstream::msgType(),
MPI_COMM_WORLD MPI_COMM_WORLD
) )
) )
@ -269,8 +269,8 @@ void Foam::reduce(scalar& Value, const sumOp<scalar>& bop)
&Value, &Value,
1, 1,
MPI_SCALAR, MPI_SCALAR,
Pstream::procID(Pstream::masterNo()), UPstream::procID(UPstream::masterNo()),
Pstream::msgType(), UPstream::msgType(),
MPI_COMM_WORLD, MPI_COMM_WORLD,
MPI_STATUS_IGNORE MPI_STATUS_IGNORE
) )
@ -291,8 +291,8 @@ void Foam::reduce(scalar& Value, const sumOp<scalar>& bop)
Value = sum; Value = sum;
/* /*
int myProcNo = Pstream::myProcNo(); int myProcNo = UPstream::myProcNo();
int nProcs = Pstream::nProcs(); int nProcs = UPstream::nProcs();
// //
// receive from children // receive from children
@ -321,8 +321,8 @@ void Foam::reduce(scalar& Value, const sumOp<scalar>& bop)
&value, &value,
1, 1,
MPI_SCALAR, MPI_SCALAR,
Pstream::procID(childProcId), UPstream::procID(childProcId),
Pstream::msgType(), UPstream::msgType(),
MPI_COMM_WORLD, MPI_COMM_WORLD,
MPI_STATUS_IGNORE MPI_STATUS_IGNORE
) )
@ -346,7 +346,7 @@ void Foam::reduce(scalar& Value, const sumOp<scalar>& bop)
// //
// send and receive from parent // send and receive from parent
// //
if (!Pstream::master()) if (!UPstream::master())
{ {
int parentId = myProcNo - (myProcNo % thisLevelOffset); int parentId = myProcNo - (myProcNo % thisLevelOffset);
@ -357,8 +357,8 @@ void Foam::reduce(scalar& Value, const sumOp<scalar>& bop)
&Value, &Value,
1, 1,
MPI_SCALAR, MPI_SCALAR,
Pstream::procID(parentId), UPstream::procID(parentId),
Pstream::msgType(), UPstream::msgType(),
MPI_COMM_WORLD MPI_COMM_WORLD
) )
) )
@ -377,8 +377,8 @@ void Foam::reduce(scalar& Value, const sumOp<scalar>& bop)
&Value, &Value,
1, 1,
MPI_SCALAR, MPI_SCALAR,
Pstream::procID(parentId), UPstream::procID(parentId),
Pstream::msgType(), UPstream::msgType(),
MPI_COMM_WORLD, MPI_COMM_WORLD,
MPI_STATUS_IGNORE MPI_STATUS_IGNORE
) )
@ -413,8 +413,8 @@ void Foam::reduce(scalar& Value, const sumOp<scalar>& bop)
&Value, &Value,
1, 1,
MPI_SCALAR, MPI_SCALAR,
Pstream::procID(childProcId), UPstream::procID(childProcId),
Pstream::msgType(), UPstream::msgType(),
MPI_COMM_WORLD MPI_COMM_WORLD
) )
) )
@ -436,7 +436,7 @@ void Foam::reduce(scalar& Value, const sumOp<scalar>& bop)
} }
void Foam::Pstream::waitRequests() void Foam::UPstream::waitRequests()
{ {
if (PstreamGlobals::outstandingRequests_.size()) if (PstreamGlobals::outstandingRequests_.size())
{ {
@ -452,7 +452,7 @@ void Foam::Pstream::waitRequests()
{ {
FatalErrorIn FatalErrorIn
( (
"Pstream::waitRequests()" "UPstream::waitRequests()"
) << "MPI_Waitall returned with error" << Foam::endl; ) << "MPI_Waitall returned with error" << Foam::endl;
} }
@ -461,13 +461,13 @@ void Foam::Pstream::waitRequests()
} }
bool Foam::Pstream::finishedRequest(const label i) bool Foam::UPstream::finishedRequest(const label i)
{ {
if (i >= PstreamGlobals::outstandingRequests_.size()) if (i >= PstreamGlobals::outstandingRequests_.size())
{ {
FatalErrorIn FatalErrorIn
( (
"Pstream::finishedRequest(const label)" "UPstream::finishedRequest(const label)"
) << "There are " << PstreamGlobals::outstandingRequests_.size() ) << "There are " << PstreamGlobals::outstandingRequests_.size()
<< " outstanding send requests and you are asking for i=" << i << " outstanding send requests and you are asking for i=" << i
<< nl << nl

View File

@ -26,9 +26,6 @@ License
#include "edgeMesh.H" #include "edgeMesh.H"
#include "mergePoints.H" #include "mergePoints.H"
#include "StaticHashTable.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
@ -204,7 +201,7 @@ void Foam::edgeMesh::mergePoints(const scalar mergeDist)
} }
// Compact using a hashtable and commutative hash of edge. // Compact using a hashtable and commutative hash of edge.
StaticHashTable<label, edge, Hash<edge> > edgeToLabel HashTable<label, edge, Hash<edge> > edgeToLabel
( (
2*edges_.size() 2*edges_.size()
); );
@ -228,7 +225,7 @@ void Foam::edgeMesh::mergePoints(const scalar mergeDist)
for for
( (
StaticHashTable<label, edge, Hash<edge> >::const_iterator iter = HashTable<label, edge, Hash<edge> >::const_iterator iter =
edgeToLabel.begin(); edgeToLabel.begin();
iter != edgeToLabel.end(); iter != edgeToLabel.end();
++iter ++iter

View File

@ -26,8 +26,6 @@ License
#include "processorFvPatchField.H" #include "processorFvPatchField.H"
#include "processorFvPatch.H" #include "processorFvPatch.H"
#include "IPstream.H"
#include "OPstream.H"
#include "demandDrivenData.H" #include "demandDrivenData.H"
#include "transformField.H" #include "transformField.H"

View File

@ -227,7 +227,7 @@ Foam::fvMatrix<Type>::fvMatrix
); );
} }
// Update the boundary coefficients of psi without changing it's event No. // Update the boundary coefficients of psi without changing its event No.
GeometricField<Type, fvPatchField, volMesh>& psiRef = GeometricField<Type, fvPatchField, volMesh>& psiRef =
const_cast<GeometricField<Type, fvPatchField, volMesh>&>(psi_); const_cast<GeometricField<Type, fvPatchField, volMesh>&>(psi_);

View File

@ -27,9 +27,6 @@ Description
list of selected cells, it creates the mesh consisting only of the list of selected cells, it creates the mesh consisting only of the
desired cells, with the mapping list for points, faces, and cells. desired cells, with the mapping list for points, faces, and cells.
MJ 23/03/05 on coupled faces change the patch of the face to the
oldInternalFaces patch.
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#include "fvMeshSubset.H" #include "fvMeshSubset.H"

View File

@ -98,29 +98,6 @@ void Foam::Cloud<ParticleType>::deleteParticle(ParticleType& p)
} }
namespace Foam
{
class combineNsTransPs
{
public:
void operator()(labelListList& x, const labelListList& y) const
{
forAll(y, i)
{
if (y[i].size())
{
x[i] = y[i];
}
}
}
};
} // End namespace Foam
template<class ParticleType> template<class ParticleType>
template<class TrackingData> template<class TrackingData>
void Foam::Cloud<ParticleType>::move(TrackingData& td) void Foam::Cloud<ParticleType>::move(TrackingData& td)
@ -196,7 +173,7 @@ void Foam::Cloud<ParticleType>::move(TrackingData& td)
// processor patches for all the processors // processor patches for all the processors
labelListList allNTrans(Pstream::nProcs()); labelListList allNTrans(Pstream::nProcs());
allNTrans[Pstream::myProcNo()] = nsTransPs; allNTrans[Pstream::myProcNo()] = nsTransPs;
combineReduce(allNTrans, combineNsTransPs()); combineReduce(allNTrans, UPstream::listEq());
transfered = false; transfered = false;

View File

@ -121,7 +121,7 @@ void Foam::ReactingParcel<ParcelType>::correctSurfaceValues
return; return;
} }
// Far field gas molar fractions // Far field carrier molar fractions
scalarField Xinf(Y_.size()); scalarField Xinf(Y_.size());
forAll(Xinf, i) forAll(Xinf, i)
@ -135,7 +135,7 @@ void Foam::ReactingParcel<ParcelType>::correctSurfaceValues
// Molar fraction of far field species at particle surface // Molar fraction of far field species at particle surface
const scalar Xsff = 1.0 - min(sum(Cs)*specie::RR*this->T_/pc_, 1.0); const scalar Xsff = 1.0 - min(sum(Cs)*specie::RR*this->T_/pc_, 1.0);
// Surface gas total molar concentration // Surface carrier total molar concentration
const scalar CsTot = pc_/(specie::RR*this->T_); const scalar CsTot = pc_/(specie::RR*this->T_);
// Surface carrier composition (molar fraction) // Surface carrier composition (molar fraction)
@ -171,10 +171,10 @@ void Foam::ReactingParcel<ParcelType>::correctSurfaceValues
cbrt(td.cloud().mcCarrierThermo().speciesData()[i].W()); cbrt(td.cloud().mcCarrierThermo().speciesData()[i].W());
rhos += Xs[i]*td.cloud().mcCarrierThermo().speciesData()[i].W(); rhos += Xs[i]*td.cloud().mcCarrierThermo().speciesData()[i].W();
cps += Xs[i]*td.cloud().mcCarrierThermo().speciesData()[i].Cp(T);
mus += Ys[i]*sqrtW*td.cloud().mcCarrierThermo().speciesData()[i].mu(T); mus += Ys[i]*sqrtW*td.cloud().mcCarrierThermo().speciesData()[i].mu(T);
kappa += kappa +=
Ys[i]*cbrtW*td.cloud().mcCarrierThermo().speciesData()[i].kappa(T); Ys[i]*cbrtW*td.cloud().mcCarrierThermo().speciesData()[i].kappa(T);
cps += Xs[i]*td.cloud().mcCarrierThermo().speciesData()[i].Cp(T);
sumYiSqrtW += Ys[i]*sqrtW; sumYiSqrtW += Ys[i]*sqrtW;
sumYiCbrtW += Ys[i]*cbrtW; sumYiCbrtW += Ys[i]*cbrtW;
@ -417,7 +417,7 @@ void Foam::ReactingParcel<ParcelType>::calcPhaseChange
const scalarField& YComponents, const scalarField& YComponents,
scalarField& dMassPC, scalarField& dMassPC,
scalar& Sh, scalar& Sh,
scalar& dhsTrans, scalar& dhsTrans, // TODO: not used
scalar& N, scalar& N,
scalar& NCpW, scalar& NCpW,
scalarField& Cs scalarField& Cs

View File

@ -233,7 +233,7 @@ Foam::scalar Foam::ThermoParcel<ParcelType>::calcHeatTransfer
if (mag(htc) < ROOTVSMALL && !td.cloud().radiation()) if (mag(htc) < ROOTVSMALL && !td.cloud().radiation())
{ {
return T + dt*Sh/(this->volume(d)*rho*cp); return max(T + dt*Sh/(this->volume(d)*rho*cp), td.constProps().TMin());
} }
const scalar As = this->areaS(d); const scalar As = this->areaS(d);
@ -256,9 +256,11 @@ Foam::scalar Foam::ThermoParcel<ParcelType>::calcHeatTransfer
IntegrationScheme<scalar>::integrationResult Tres = IntegrationScheme<scalar>::integrationResult Tres =
td.cloud().TIntegrator().integrate(T, dt, ap, bp); td.cloud().TIntegrator().integrate(T, dt, ap, bp);
dhsTrans += dt*htc*As*(Tres.average() - Tc_); scalar Tnew = max(Tres.value(), td.constProps().TMin());
return Tres.value(); dhsTrans += dt*htc*As*(0.5*(T + Tnew) - Tc_);
return Tnew;
} }

View File

@ -118,7 +118,7 @@ protected:
scalar volumeTotal_; scalar volumeTotal_;
//- Total mass to inject [kg] //- Total mass to inject [kg]
const scalar massTotal_; scalar massTotal_;
//- Total mass injected to date [kg] //- Total mass injected to date [kg]
scalar massInjected_; scalar massInjected_;

View File

@ -124,11 +124,12 @@ Foam::PatchInjection<CloudType>::PatchInjection
label patchSize = cellOwners_.size(); label patchSize = cellOwners_.size();
label totalPatchSize = patchSize; label totalPatchSize = patchSize;
reduce(totalPatchSize, sumOp<scalar>()); reduce(totalPatchSize, sumOp<label>());
fraction_ = patchSize/totalPatchSize; fraction_ = scalar(patchSize)/totalPatchSize;
// Set total volume to inject // Set total volume/mass to inject
this->volumeTotal_ = fraction_*volumeFlowRate_().integrate(0.0, duration_); this->volumeTotal_ = fraction_*volumeFlowRate_().integrate(0.0, duration_);
this->massTotal_ *= fraction_;
} }
@ -164,12 +165,21 @@ void Foam::PatchInjection<CloudType>::setPositionAndCell
vector& position, vector& position,
label& cellOwner label& cellOwner
) )
{
if (cellOwners_.size() > 0)
{ {
label cellI = this->owner().rndGen().integer(0, cellOwners_.size() - 1); label cellI = this->owner().rndGen().integer(0, cellOwners_.size() - 1);
cellOwner = cellOwners_[cellI]; cellOwner = cellOwners_[cellI];
position = this->owner().mesh().C()[cellOwner]; position = this->owner().mesh().C()[cellOwner];
} }
else
{
cellOwner = -1;
// dummy position
position = pTraits<vector>::max;
}
}
template<class CloudType> template<class CloudType>

View File

@ -71,15 +71,12 @@ bool Foam::Rebound<CloudType>::correct
nw /= mag(nw); nw /= mag(nw);
scalar Un = U & nw; scalar Un = U & nw;
vector Ut = U - Un*nw;
if (Un > 0.0) if (Un > 0.0)
{ {
U -= UFactor_*2.0*Un*nw; U -= UFactor_*2.0*Un*nw;
} }
U -= Ut;
return true; return true;
} }

View File

@ -170,7 +170,7 @@ public:
// Member Functions // Member Functions
//- Take this referredCell object that has already had it's transform //- Take this referredCell object that has already had its transform
// calculated and refer it on again, retaining same source info. // calculated and refer it on again, retaining same source info.
referredCell reRefer referredCell reRefer
( (

View File

@ -7,10 +7,10 @@ fieldMinMax/fieldMinMax.C
fieldMinMax/fieldMinMaxFunctionObject.C fieldMinMax/fieldMinMaxFunctionObject.C
fieldValues/fieldValue/fieldValue.C fieldValues/fieldValue/fieldValue.C
fieldValues/face/faceSource.C fieldValues/faceSource/faceSource.C
fieldValues/face/faceSourceFunctionObject.C fieldValues/faceSource/faceSourceFunctionObject.C
fieldValues/cell/cellSource.C fieldValues/cellSource/cellSource.C
fieldValues/cell/cellSourceFunctionObject.C fieldValues/cellSource/cellSourceFunctionObject.C
streamLine/streamLine.C streamLine/streamLine.C
streamLine/streamLineParticle.C streamLine/streamLineParticle.C

View File

@ -50,10 +50,13 @@ namespace Foam
fieldValues::faceSource::sourceTypeNames_; fieldValues::faceSource::sourceTypeNames_;
template<> template<>
const char* NamedEnum<fieldValues::faceSource::operationType, 4>:: const char* NamedEnum<fieldValues::faceSource::operationType, 5>::
names[] = {"none", "sum", "areaAverage", "areaIntegrate"}; names[] =
{
"none", "sum", "areaAverage", "areaIntegrate", "weightedAverage"
};
const NamedEnum<fieldValues::faceSource::operationType, 4> const NamedEnum<fieldValues::faceSource::operationType, 5>
fieldValues::faceSource::operationTypeNames_; fieldValues::faceSource::operationTypeNames_;
} }
@ -68,6 +71,8 @@ void Foam::fieldValues::faceSource::setFaceZoneFaces()
if (zoneId < 0) if (zoneId < 0)
{ {
FatalErrorIn("faceSource::faceSource::setFaceZoneFaces()") FatalErrorIn("faceSource::faceSource::setFaceZoneFaces()")
<< type() << " " << name_ << ": "
<< sourceTypeNames_[source_] << "(" << sourceName_ << "):" << nl
<< " Unknown face zone name: " << sourceName_ << " Unknown face zone name: " << sourceName_
<< ". Valid face zones are: " << mesh().faceZones().names() << ". Valid face zones are: " << mesh().faceZones().names()
<< nl << exit(FatalError); << nl << exit(FatalError);
@ -164,6 +169,8 @@ void Foam::fieldValues::faceSource::setPatchFaces()
if (patchId < 0) if (patchId < 0)
{ {
FatalErrorIn("faceSource::constructFaceAddressing()") FatalErrorIn("faceSource::constructFaceAddressing()")
<< type() << " " << name_ << ": "
<< sourceTypeNames_[source_] << "(" << sourceName_ << "):" << nl
<< " Unknown patch name: " << sourceName_ << " Unknown patch name: " << sourceName_
<< ". Valid patch names are: " << ". Valid patch names are: "
<< mesh().boundaryMesh().names() << nl << mesh().boundaryMesh().names() << nl
@ -197,7 +204,7 @@ void Foam::fieldValues::faceSource::setPatchFaces()
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * // // * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
void Foam::fieldValues::faceSource::initialise() void Foam::fieldValues::faceSource::initialise(const dictionary& dict)
{ {
switch (source_) switch (source_)
{ {
@ -214,15 +221,40 @@ void Foam::fieldValues::faceSource::initialise()
default: default:
{ {
FatalErrorIn("faceSource::constructFaceAddressing()") FatalErrorIn("faceSource::constructFaceAddressing()")
<< "Unknown source type. Valid source types are:" << type() << " " << name_ << ": "
<< sourceTypeNames_[source_] << "(" << sourceName_ << "):"
<< nl << " Unknown source type. Valid source types are:"
<< sourceTypeNames_ << nl << exit(FatalError); << sourceTypeNames_ << nl << exit(FatalError);
} }
} }
Info<< type() << " " << name_ << ":" << nl Info<< type() << " " << name_ << ":" << nl
<< " total faces = " << faceId_.size() << nl << " total faces = " << faceId_.size() << nl
<< " total area = " << sum(filterField(mesh().magSf())) << " total area = " << sum(filterField(mesh().magSf())) << nl;
<< nl << endl;
if (operation_ == opWeightedAverage)
{
dict.lookup("weightField") >> weightFieldName_;
if
(
obr().foundObject<volScalarField>(weightFieldName_)
|| obr().foundObject<surfaceScalarField>(weightFieldName_)
)
{
Info<< " weight field = " << weightFieldName_;
}
else
{
FatalErrorIn("faceSource::constructFaceAddressing()")
<< type() << " " << name_ << ": "
<< sourceTypeNames_[source_] << "(" << sourceName_ << "):"
<< nl << " Weight field " << weightFieldName_
<< " must be either a " << volScalarField::typeName << " or "
<< surfaceScalarField::typeName << nl << exit(FatalError);
}
}
Info<< nl << endl;
} }
@ -302,12 +334,13 @@ Foam::fieldValues::faceSource::faceSource
faceId_(), faceId_(),
facePatchId_(), facePatchId_(),
flipMap_(), flipMap_(),
outputFilePtr_(NULL) outputFilePtr_(NULL),
weightFieldName_("undefinedWeightedFieldName")
{ {
initialise();
if (active_) if (active_)
{ {
initialise(dict);
// Create the output file if not already created // Create the output file if not already created
makeFile(); makeFile();
} }
@ -327,7 +360,7 @@ void Foam::fieldValues::faceSource::read(const dictionary& dict)
if (active_) if (active_)
{ {
fieldValue::read(dict); fieldValue::read(dict);
initialise(); initialise(dict);
} }
} }

View File

@ -39,7 +39,7 @@ Description
valueOutput true; // Write values at run-time output times? valueOutput true; // Write values at run-time output times?
source faceZone; // Type of face source: faceZone, patch source faceZone; // Type of face source: faceZone, patch
sourceName f0; sourceName f0;
operation sum; // none, sum, areaAverage, areaIntegrate operation sum;
fields fields
( (
p p
@ -48,6 +48,13 @@ Description
); );
} }
where operation is one of:
- none
- sum
- areaAverage
- areaIntegrate
- weightedAverage
SourceFiles SourceFiles
faceSource.C faceSource.C
@ -100,11 +107,12 @@ public:
opNone, opNone,
opSum, opSum,
opAreaAverage, opAreaAverage,
opAreaIntegrate opAreaIntegrate,
opWeightedAverage
}; };
//- Operation type names //- Operation type names
static const NamedEnum<operationType, 4> operationTypeNames_; static const NamedEnum<operationType, 5> operationTypeNames_;
private: private:
@ -143,11 +151,14 @@ protected:
//- Output file pointer //- Output file pointer
autoPtr<OFstream> outputFilePtr_; autoPtr<OFstream> outputFilePtr_;
//- Weight field name - only used for opWeightedAverage mode
word weightFieldName_;
// Protected member functions // Protected member functions
//- Initialise, e.g. face addressing //- Initialise, e.g. face addressing
void initialise(); void initialise(const dictionary& dict);
//- Insert field values into values list //- Insert field values into values list
template<class Type> template<class Type>

View File

@ -129,6 +129,47 @@ Type Foam::fieldValues::faceSource::processValues
result = sum(values*filterField(mesh().magSf())); result = sum(values*filterField(mesh().magSf()));
break; break;
} }
case opWeightedAverage:
{
if (mesh().foundObject<volScalarField>(weightFieldName_))
{
tmp<scalarField> wField =
filterField
(
mesh().lookupObject<volScalarField>(weightFieldName_)
);
result = sum(values*wField())/sum(wField());
}
else if (mesh().foundObject<surfaceScalarField>(weightFieldName_))
{
tmp<scalarField> wField =
filterField
(
mesh().lookupObject<surfaceScalarField>
(
weightFieldName_
)
);
result = sum(values*wField())/sum(wField());
}
else
{
FatalErrorIn
(
"fieldValues::faceSource::processValues"
"("
"List<Type>&"
") const"
) << type() << " " << name_ << ": "
<< sourceTypeNames_[source_] << "(" << sourceName_ << "):"
<< nl
<< " Weight field " << weightFieldName_
<< " must be either a " << volScalarField::typeName
<< " or " << surfaceScalarField::typeName << nl
<< abort(FatalError);
}
break;
}
default: default:
{ {
// Do nothing // Do nothing

View File

@ -137,7 +137,7 @@ public:
//- Return the output field values flag //- Return the output field values flag
const Switch& valueOutput() const; const Switch& valueOutput() const;
//- Helper funvction to return the reference to the mesh //- Helper function to return the reference to the mesh
const fvMesh& mesh() const; const fvMesh& mesh() const;

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