mirror of
https://develop.openfoam.com/Development/openfoam.git
synced 2025-11-28 03:28:01 +00:00
Merge commit 'OpenCFD/master' into olesenm
This commit is contained in:
@ -13,6 +13,14 @@ PtrList<volScalarField>& Y = composition.Y();
|
||||
|
||||
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
|
||||
(
|
||||
IOobject
|
||||
|
||||
@ -0,0 +1,3 @@
|
||||
porousSimpleFoam.C
|
||||
|
||||
EXE = $(FOAM_APPBIN)/porousSimpleFoam
|
||||
@ -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
|
||||
47
applications/solvers/incompressible/porousSimpleFoam/UEqn.H
Normal file
47
applications/solvers/incompressible/porousSimpleFoam/UEqn.H
Normal 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");
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
59
applications/solvers/incompressible/porousSimpleFoam/pEqn.H
Normal file
59
applications/solvers/incompressible/porousSimpleFoam/pEqn.H
Normal 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();
|
||||
@ -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;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -14,7 +14,7 @@ tmp<fv::convectionScheme<scalar> > mvConvection
|
||||
label inertIndex = -1;
|
||||
volScalarField Yt = 0.0*Y[0];
|
||||
|
||||
for (label i=0; i<Y.size(); i++)
|
||||
forAll(Y, i)
|
||||
{
|
||||
if (Y[i].name() != inertSpecie)
|
||||
{
|
||||
|
||||
@ -13,6 +13,14 @@
|
||||
|
||||
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& h = thermo.h();
|
||||
const volScalarField& T = thermo.T();
|
||||
|
||||
@ -15,7 +15,7 @@ tmp<fv::convectionScheme<scalar> > mvConvection
|
||||
label inertIndex = -1;
|
||||
volScalarField Yt = 0.0*Y[0];
|
||||
|
||||
for (label i=0; i<Y.size(); i++)
|
||||
forAll(Y, i)
|
||||
{
|
||||
if (Y[i].name() != inertSpecie)
|
||||
{
|
||||
|
||||
@ -13,6 +13,14 @@
|
||||
|
||||
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& h = thermo.h();
|
||||
const volScalarField& T = thermo.T();
|
||||
|
||||
@ -14,7 +14,7 @@ tmp<fv::convectionScheme<scalar> > mvConvection
|
||||
label inertIndex = -1;
|
||||
volScalarField Yt = 0.0*Y[0];
|
||||
|
||||
for (label i=0; i<Y.size(); i++)
|
||||
forAll(Y, i)
|
||||
{
|
||||
if (Y[i].name() != inertSpecie)
|
||||
{
|
||||
|
||||
@ -13,6 +13,14 @@
|
||||
|
||||
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& h = thermo.h();
|
||||
const volScalarField& T = thermo.T();
|
||||
|
||||
@ -0,0 +1,6 @@
|
||||
incompressibleThreePhaseMixture/threePhaseMixture.C
|
||||
threePhaseInterfaceProperties/threePhaseInterfaceProperties.C
|
||||
interMixingFoam.C
|
||||
|
||||
EXE = $(FOAM_APPBIN)/interMixingFoam
|
||||
|
||||
17
applications/solvers/multiphase/interMixingFoam/Make/options
Normal file
17
applications/solvers/multiphase/interMixingFoam/Make/options
Normal 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
|
||||
164
applications/solvers/multiphase/interMixingFoam/alphaEqns.H
Normal file
164
applications/solvers/multiphase/interMixingFoam/alphaEqns.H
Normal 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;
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
132
applications/solvers/multiphase/interMixingFoam/createFields.H
Normal file
132
applications/solvers/multiphase/interMixingFoam/createFields.H
Normal 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)
|
||||
);
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -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
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -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);
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -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();
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -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
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -22,13 +22,9 @@ License
|
||||
along with OpenFOAM; if not, write to the Free Software Foundation,
|
||||
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
Description
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "GatherBase.H"
|
||||
#include "IPstream.H"
|
||||
#include "OPstream.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
|
||||
@ -0,0 +1,6 @@
|
||||
#!/bin/sh
|
||||
|
||||
if [ "$TEC_360_2009" ]
|
||||
then
|
||||
wmake
|
||||
fi
|
||||
@ -0,0 +1,5 @@
|
||||
tecplotWriter.C
|
||||
vtkMesh.C
|
||||
foamToTecplot360.C
|
||||
|
||||
EXE = $(FOAM_APPBIN)/foamToTecplot360
|
||||
@ -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
|
||||
File diff suppressed because it is too large
Load Diff
@ -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
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -22,28 +22,50 @@ License
|
||||
along with OpenFOAM; if not, write to the Free Software Foundation,
|
||||
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
InClass
|
||||
Foam::readFields
|
||||
|
||||
Description
|
||||
Prints out a description of the streams
|
||||
|
||||
SourceFiles
|
||||
readFields.C
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "IPstream.H"
|
||||
#include "OPstream.H"
|
||||
#ifndef readFields_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
|
||||
{
|
||||
os << "Writing from processor " << toProcNo_
|
||||
<< " to processor " << myProcNo() << Foam::endl;
|
||||
}
|
||||
} // End namespace Foam
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#ifdef NoRepository
|
||||
# include "readFields.C"
|
||||
#endif
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -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
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -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
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -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;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -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
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -83,12 +83,13 @@ Usage
|
||||
Combine all patches into a single file
|
||||
|
||||
@param -excludePatches \<patchNames\>\n
|
||||
Specify patches to exclude. For example,
|
||||
Specify patches (wildcards) to exclude. For example,
|
||||
@verbatim
|
||||
-excludePatches "( inlet_1 inlet_2 )"
|
||||
-excludePatches '( inlet_1 inlet_2 "proc.*")'
|
||||
@endverbatim
|
||||
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
|
||||
use the time index in the VTK file name instead of the time index
|
||||
@ -140,6 +141,7 @@ Note
|
||||
#include "faceZoneMesh.H"
|
||||
#include "Cloud.H"
|
||||
#include "passiveParticle.H"
|
||||
#include "stringListOps.H"
|
||||
|
||||
#include "vtkMesh.H"
|
||||
#include "readFields.H"
|
||||
@ -192,7 +194,7 @@ void print(Ostream& os, const wordList& flds)
|
||||
labelList getSelectedPatches
|
||||
(
|
||||
const polyBoundaryMesh& patches,
|
||||
const HashSet<word>& excludePatches
|
||||
const List<wordRe>& excludePatches //HashSet<word>& excludePatches
|
||||
)
|
||||
{
|
||||
DynamicList<label> patchIDs(patches.size());
|
||||
@ -205,14 +207,19 @@ labelList getSelectedPatches
|
||||
|
||||
if
|
||||
(
|
||||
isA<emptyPolyPatch>(pp)
|
||||
|| (Pstream::parRun() && isA<processorPolyPatch>(pp))
|
||||
isType<emptyPolyPatch>(pp)
|
||||
|| (Pstream::parRun() && isType<processorPolyPatch>(pp))
|
||||
)
|
||||
{
|
||||
Info<< " discarding empty/processor patch " << patchI
|
||||
<< " " << 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);
|
||||
Info<< " patch " << patchI << " " << pp.name() << endl;
|
||||
@ -224,6 +231,8 @@ labelList getSelectedPatches
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Main program:
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
@ -283,7 +292,7 @@ int main(int argc, char *argv[])
|
||||
|
||||
bool allPatches = args.optionFound("allPatches");
|
||||
|
||||
HashSet<word> excludePatches;
|
||||
List<wordRe> excludePatches;
|
||||
if (args.optionFound("excludePatches"))
|
||||
{
|
||||
args.optionLookup("excludePatches")() >> excludePatches;
|
||||
@ -771,7 +780,7 @@ int main(int argc, char *argv[])
|
||||
{
|
||||
const polyPatch& pp = patches[patchI];
|
||||
|
||||
if (!excludePatches.found(pp.name()))
|
||||
if (!findStrings(excludePatches, pp.name()))
|
||||
{
|
||||
mkDir(fvPath/pp.name());
|
||||
|
||||
|
||||
@ -110,10 +110,9 @@ void Foam::vtkPV3Foam::convertVolFields
|
||||
// Convert patches - if activated
|
||||
//
|
||||
|
||||
// the name for the interpolated patch point field must be consistent
|
||||
// with the interpolated volume point field
|
||||
|
||||
// this could be done better
|
||||
// The name for the interpolated patch point field must be consistent
|
||||
// with the interpolated volume point field.
|
||||
// This could be done better.
|
||||
const word pointFldName = "volPointInterpolate(" + tf.name() + ')';
|
||||
|
||||
for
|
||||
|
||||
@ -109,11 +109,14 @@ StringStreams = $(Streams)/StringStreams
|
||||
$(StringStreams)/StringStreamsPrint.C
|
||||
|
||||
Pstreams = $(Streams)/Pstreams
|
||||
$(Pstreams)/Pstream.C
|
||||
$(Pstreams)/PstreamCommsStruct.C
|
||||
$(Pstreams)/UIPstream.C
|
||||
$(Pstreams)/IPstream.C
|
||||
$(Pstreams)/UPstream.C
|
||||
$(Pstreams)/UPstreamCommsStruct.C
|
||||
$(Pstreams)/Pstream.C
|
||||
$(Pstreams)/UOPstream.C
|
||||
$(Pstreams)/OPstream.C
|
||||
$(Pstreams)/PstreamsPrint.C
|
||||
$(Pstreams)/PstreamBuffers.C
|
||||
|
||||
dictionary = db/dictionary
|
||||
$(dictionary)/dictionary.C
|
||||
|
||||
@ -114,7 +114,7 @@ void Foam::ParSortableList<Type>::checkAndSend
|
||||
}
|
||||
|
||||
{
|
||||
OPstream toSlave(destProcI);
|
||||
OPstream toSlave(Pstream::blocking, destProcI);
|
||||
toSlave << values << indices;
|
||||
}
|
||||
}
|
||||
@ -311,7 +311,7 @@ void Foam::ParSortableList<Type>::sort()
|
||||
Pout<< "Receiving from " << procI << endl;
|
||||
}
|
||||
|
||||
IPstream fromSlave(procI);
|
||||
IPstream fromSlave(Pstream::blocking, procI);
|
||||
|
||||
fromSlave >> recValues >> recIndices;
|
||||
|
||||
|
||||
@ -24,291 +24,22 @@ License
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "error.H"
|
||||
#include "IPstream.H"
|
||||
#include "int.H"
|
||||
#include "token.H"
|
||||
#include <cctype>
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructor * * * * * * * * * * * * * * * //
|
||||
|
||||
// * * * * * * * * * * * * * Private member functions * * * * * * * * * * * //
|
||||
|
||||
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
|
||||
Foam::IPstream::IPstream
|
||||
(
|
||||
void* data,
|
||||
size_t count,
|
||||
size_t align
|
||||
const commsTypes commsType,
|
||||
const int fromProcNo,
|
||||
const label bufSize,
|
||||
streamFormat format,
|
||||
versionNumber version
|
||||
)
|
||||
{
|
||||
if (align > 1)
|
||||
{
|
||||
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;
|
||||
}
|
||||
:
|
||||
Pstream(commsType, bufSize),
|
||||
UIPstream(commsType, fromProcNo, buf_)
|
||||
{}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
|
||||
@ -38,7 +38,7 @@ SourceFiles
|
||||
#ifndef IPstream_H
|
||||
#define IPstream_H
|
||||
|
||||
#include "Istream.H"
|
||||
#include "UIPstream.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
@ -52,26 +52,8 @@ namespace Foam
|
||||
class IPstream
|
||||
:
|
||||
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:
|
||||
|
||||
@ -88,76 +70,6 @@ public:
|
||||
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;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@ -22,68 +22,9 @@ 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 OPstream
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "error.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 * * * * * * * * * * * * * * * //
|
||||
|
||||
@ -92,137 +33,14 @@ Foam::OPstream::OPstream
|
||||
const commsTypes commsType,
|
||||
const int toProcNo,
|
||||
const label bufSize,
|
||||
const int tag,
|
||||
streamFormat format,
|
||||
versionNumber version
|
||||
)
|
||||
:
|
||||
Pstream(commsType, bufSize),
|
||||
Ostream(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;
|
||||
}
|
||||
UOPstream(commsType, toProcNo, buf_, tag, true, format, version)
|
||||
{}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
|
||||
@ -38,7 +38,7 @@ SourceFiles
|
||||
#ifndef OPstream_H
|
||||
#define OPstream_H
|
||||
|
||||
#include "Ostream.H"
|
||||
#include "UOPstream.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
@ -52,25 +52,8 @@ namespace Foam
|
||||
class OPstream
|
||||
:
|
||||
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:
|
||||
|
||||
@ -83,126 +66,11 @@ public:
|
||||
const commsTypes commsType,
|
||||
const int toProcNo,
|
||||
const label bufSize = 0,
|
||||
const int tag = UPstream::msgType(),
|
||||
streamFormat format=BINARY,
|
||||
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;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@ -25,226 +25,16 @@ License
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "Pstream.H"
|
||||
#include "debug.H"
|
||||
#include "dictionary.H"
|
||||
|
||||
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||
|
||||
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 * * * * * * * * * * * //
|
||||
|
||||
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 * * * * * * * * * * * * * //
|
||||
|
||||
// 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"))
|
||||
);
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
|
||||
@ -30,22 +30,18 @@ Description
|
||||
|
||||
SourceFiles
|
||||
Pstream.C
|
||||
PstreamsPrint.C
|
||||
PstreamCommsStruct.C
|
||||
gatherScatter.C
|
||||
combineGatherScatter.C
|
||||
gatherScatterList.C
|
||||
exchange.C
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef Pstream_H
|
||||
#define Pstream_H
|
||||
|
||||
#include "labelList.H"
|
||||
#include "UPstream.H"
|
||||
#include "DynamicList.H"
|
||||
#include "HashTable.H"
|
||||
#include "string.H"
|
||||
#include "NamedEnum.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
@ -57,162 +53,16 @@ namespace Foam
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
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 data
|
||||
|
||||
//- Communications type of this stream
|
||||
commsTypes commsType_;
|
||||
|
||||
//- Transfer buffer
|
||||
List<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);
|
||||
|
||||
DynamicList<char> buf_;
|
||||
|
||||
public:
|
||||
|
||||
@ -220,21 +70,6 @@ public:
|
||||
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
|
||||
|
||||
//- Construct given optional buffer size
|
||||
@ -244,151 +79,16 @@ public:
|
||||
const label bufSize = 0
|
||||
)
|
||||
:
|
||||
commsType_(commsType),
|
||||
bufPosition_(0)
|
||||
UPstream(commsType),
|
||||
buf_(0)
|
||||
{
|
||||
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 data. Apply bop to combine Value
|
||||
@ -501,8 +201,8 @@ public:
|
||||
|
||||
|
||||
// Gather/scatter keeping the individual processor data separate.
|
||||
// Values is a List of size Pstream::nProcs() where
|
||||
// Values[Pstream::myProcNo()] is the data for the current processor.
|
||||
// Values is a List of size UPstream::nProcs() where
|
||||
// Values[UPstream::myProcNo()] is the data for the current processor.
|
||||
|
||||
//- Gather data but keep individual values separate
|
||||
template <class T>
|
||||
@ -527,18 +227,27 @@ public:
|
||||
//- Like above but switches between linear/tree communication
|
||||
template <class T>
|
||||
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
|
||||
@ -549,9 +258,9 @@ Ostream& operator<<(Ostream&, const Pstream::commsStruct&);
|
||||
# include "gatherScatter.C"
|
||||
# include "combineGatherScatter.C"
|
||||
# include "gatherScatterList.C"
|
||||
# include "exchange.C"
|
||||
#endif
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
117
src/OpenFOAM/db/IOstreams/Pstreams/PstreamBuffers.C
Normal file
117
src/OpenFOAM/db/IOstreams/Pstreams/PstreamBuffers.C
Normal 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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
155
src/OpenFOAM/db/IOstreams/Pstreams/PstreamBuffers.H
Normal file
155
src/OpenFOAM/db/IOstreams/Pstreams/PstreamBuffers.H
Normal 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
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -23,7 +23,7 @@ License
|
||||
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
InClass
|
||||
Foam::Pstream
|
||||
Foam
|
||||
|
||||
Description
|
||||
Combination-Reduction operation for a parallel run. The
|
||||
@ -37,6 +37,7 @@ Description
|
||||
#ifndef PstreamCombineReduceOps_H
|
||||
#define PstreamCombineReduceOps_H
|
||||
|
||||
#include "UPstream.H"
|
||||
#include "Pstream.H"
|
||||
#include "ops.H"
|
||||
|
||||
@ -50,7 +51,7 @@ namespace Foam
|
||||
template <class T, class CombineOp>
|
||||
void combineReduce
|
||||
(
|
||||
const List<Pstream::commsStruct>& comms,
|
||||
const List<UPstream::commsStruct>& comms,
|
||||
T& Value,
|
||||
const CombineOp& cop
|
||||
)
|
||||
@ -63,15 +64,15 @@ void combineReduce
|
||||
template <class T, class CombineOp>
|
||||
void combineReduce(T& Value, const CombineOp& cop)
|
||||
{
|
||||
if (Pstream::nProcs() < Pstream::nProcsSimpleSum)
|
||||
if (UPstream::nProcs() < UPstream::nProcsSimpleSum)
|
||||
{
|
||||
Pstream::combineGather(Pstream::linearCommunication(), Value, cop);
|
||||
Pstream::combineScatter(Pstream::linearCommunication(), Value);
|
||||
Pstream::combineGather(UPstream::linearCommunication(), Value, cop);
|
||||
Pstream::combineScatter(UPstream::linearCommunication(), Value);
|
||||
}
|
||||
else
|
||||
{
|
||||
Pstream::combineGather(Pstream::treeCommunication(), Value, cop);
|
||||
Pstream::combineScatter(Pstream::treeCommunication(), Value);
|
||||
Pstream::combineGather(UPstream::treeCommunication(), Value, cop);
|
||||
Pstream::combineScatter(UPstream::treeCommunication(), Value);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -41,7 +41,7 @@ namespace Foam
|
||||
template <class T, class BinaryOp>
|
||||
void reduce
|
||||
(
|
||||
const List<Pstream::commsStruct>& comms,
|
||||
const List<UPstream::commsStruct>& comms,
|
||||
T& Value,
|
||||
const BinaryOp& bop
|
||||
)
|
||||
@ -59,13 +59,13 @@ void reduce
|
||||
const BinaryOp& bop
|
||||
)
|
||||
{
|
||||
if (Pstream::nProcs() < Pstream::nProcsSimpleSum)
|
||||
if (UPstream::nProcs() < UPstream::nProcsSimpleSum)
|
||||
{
|
||||
reduce(Pstream::linearCommunication(), Value, bop);
|
||||
reduce(UPstream::linearCommunication(), Value, bop);
|
||||
}
|
||||
else
|
||||
{
|
||||
reduce(Pstream::treeCommunication(), Value, bop);
|
||||
reduce(UPstream::treeCommunication(), Value, bop);
|
||||
}
|
||||
}
|
||||
|
||||
@ -80,13 +80,13 @@ T returnReduce
|
||||
{
|
||||
T WorkValue(Value);
|
||||
|
||||
if (Pstream::nProcs() < Pstream::nProcsSimpleSum)
|
||||
if (UPstream::nProcs() < UPstream::nProcsSimpleSum)
|
||||
{
|
||||
reduce(Pstream::linearCommunication(), WorkValue, bop);
|
||||
reduce(UPstream::linearCommunication(), WorkValue, bop);
|
||||
}
|
||||
else
|
||||
{
|
||||
reduce(Pstream::treeCommunication(), WorkValue, bop);
|
||||
reduce(UPstream::treeCommunication(), WorkValue, bop);
|
||||
}
|
||||
|
||||
return WorkValue;
|
||||
|
||||
322
src/OpenFOAM/db/IOstreams/Pstreams/UIPstream.C
Normal file
322
src/OpenFOAM/db/IOstreams/Pstreams/UIPstream.C
Normal 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;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
187
src/OpenFOAM/db/IOstreams/Pstreams/UIPstream.H
Normal file
187
src/OpenFOAM/db/IOstreams/Pstreams/UIPstream.H
Normal 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
|
||||
|
||||
// ************************************************************************* //
|
||||
275
src/OpenFOAM/db/IOstreams/Pstreams/UOPstream.C
Normal file
275
src/OpenFOAM/db/IOstreams/Pstreams/UOPstream.C
Normal 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;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
233
src/OpenFOAM/db/IOstreams/Pstreams/UOPstream.H
Normal file
233
src/OpenFOAM/db/IOstreams/Pstreams/UOPstream.H
Normal 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
|
||||
|
||||
// ************************************************************************* //
|
||||
251
src/OpenFOAM/db/IOstreams/Pstreams/UPstream.C
Normal file
251
src/OpenFOAM/db/IOstreams/Pstreams/UPstream.C
Normal 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"))
|
||||
);
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
381
src/OpenFOAM/db/IOstreams/Pstreams/UPstream.H
Normal file
381
src/OpenFOAM/db/IOstreams/Pstreams/UPstream.H
Normal 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
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -24,12 +24,12 @@ License
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "Pstream.H"
|
||||
#include "UPstream.H"
|
||||
#include "boolList.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
Foam::Pstream::commsStruct::commsStruct()
|
||||
Foam::UPstream::commsStruct::commsStruct()
|
||||
:
|
||||
above_(-1),
|
||||
below_(0),
|
||||
@ -38,7 +38,7 @@ Foam::Pstream::commsStruct::commsStruct()
|
||||
{}
|
||||
|
||||
|
||||
Foam::Pstream::commsStruct::commsStruct
|
||||
Foam::UPstream::commsStruct::commsStruct
|
||||
(
|
||||
const label above,
|
||||
const labelList& below,
|
||||
@ -53,7 +53,7 @@ Foam::Pstream::commsStruct::commsStruct
|
||||
{}
|
||||
|
||||
|
||||
Foam::Pstream::commsStruct::commsStruct
|
||||
Foam::UPstream::commsStruct::commsStruct
|
||||
(
|
||||
const label nProcs,
|
||||
const label myProcID,
|
||||
@ -91,7 +91,7 @@ Foam::Pstream::commsStruct::commsStruct
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
|
||||
|
||||
bool Foam::Pstream::commsStruct::operator==(const commsStruct& comm) const
|
||||
bool Foam::UPstream::commsStruct::operator==(const commsStruct& comm) const
|
||||
{
|
||||
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);
|
||||
}
|
||||
@ -111,7 +111,7 @@ bool Foam::Pstream::commsStruct::operator!=(const commsStruct& comm) const
|
||||
|
||||
// * * * * * * * * * * * * * * * 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
|
||||
<< comm.below_ << token::SPACE
|
||||
@ -49,15 +49,15 @@ namespace Foam
|
||||
template <class T, class CombineOp>
|
||||
void Pstream::combineGather
|
||||
(
|
||||
const List<Pstream::commsStruct>& comms,
|
||||
const List<UPstream::commsStruct>& comms,
|
||||
T& Value,
|
||||
const CombineOp& cop
|
||||
)
|
||||
{
|
||||
if (Pstream::parRun())
|
||||
if (UPstream::parRun())
|
||||
{
|
||||
// Get my communication order
|
||||
const commsStruct& myComm = comms[Pstream::myProcNo()];
|
||||
const commsStruct& myComm = comms[UPstream::myProcNo()];
|
||||
|
||||
// Receive from my downstairs neighbours
|
||||
forAll(myComm.below(), belowI)
|
||||
@ -67,9 +67,9 @@ void Pstream::combineGather
|
||||
if (contiguous<T>())
|
||||
{
|
||||
T value;
|
||||
IPstream::read
|
||||
UIPstream::read
|
||||
(
|
||||
Pstream::scheduled,
|
||||
UPstream::scheduled,
|
||||
belowID,
|
||||
reinterpret_cast<char*>(&value),
|
||||
sizeof(T)
|
||||
@ -85,7 +85,7 @@ void Pstream::combineGather
|
||||
}
|
||||
else
|
||||
{
|
||||
IPstream fromBelow(Pstream::scheduled, belowID);
|
||||
IPstream fromBelow(UPstream::scheduled, belowID);
|
||||
T value(fromBelow);
|
||||
|
||||
if (debug & 2)
|
||||
@ -109,9 +109,9 @@ void Pstream::combineGather
|
||||
|
||||
if (contiguous<T>())
|
||||
{
|
||||
OPstream::write
|
||||
UOPstream::write
|
||||
(
|
||||
Pstream::scheduled,
|
||||
UPstream::scheduled,
|
||||
myComm.above(),
|
||||
reinterpret_cast<const char*>(&Value),
|
||||
sizeof(T)
|
||||
@ -119,7 +119,7 @@ void Pstream::combineGather
|
||||
}
|
||||
else
|
||||
{
|
||||
OPstream toAbove(Pstream::scheduled, myComm.above());
|
||||
OPstream toAbove(UPstream::scheduled, myComm.above());
|
||||
toAbove << Value;
|
||||
}
|
||||
}
|
||||
@ -130,33 +130,37 @@ void Pstream::combineGather
|
||||
template <class T, class CombineOp>
|
||||
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
|
||||
{
|
||||
combineGather(Pstream::treeCommunication(), Value, cop);
|
||||
combineGather(UPstream::treeCommunication(), Value, cop);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
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
|
||||
const Pstream::commsStruct& myComm = comms[Pstream::myProcNo()];
|
||||
const UPstream::commsStruct& myComm = comms[UPstream::myProcNo()];
|
||||
|
||||
// Reveive from up
|
||||
if (myComm.above() != -1)
|
||||
{
|
||||
if (contiguous<T>())
|
||||
{
|
||||
IPstream::read
|
||||
UIPstream::read
|
||||
(
|
||||
Pstream::scheduled,
|
||||
UPstream::scheduled,
|
||||
myComm.above(),
|
||||
reinterpret_cast<char*>(&Value),
|
||||
sizeof(T)
|
||||
@ -164,7 +168,7 @@ void Pstream::combineScatter(const List<Pstream::commsStruct>& comms, T& Value)
|
||||
}
|
||||
else
|
||||
{
|
||||
IPstream fromAbove(Pstream::scheduled, myComm.above());
|
||||
IPstream fromAbove(UPstream::scheduled, myComm.above());
|
||||
Value = T(fromAbove);
|
||||
}
|
||||
|
||||
@ -187,9 +191,9 @@ void Pstream::combineScatter(const List<Pstream::commsStruct>& comms, T& Value)
|
||||
|
||||
if (contiguous<T>())
|
||||
{
|
||||
OPstream::write
|
||||
UOPstream::write
|
||||
(
|
||||
Pstream::scheduled,
|
||||
UPstream::scheduled,
|
||||
belowID,
|
||||
reinterpret_cast<const char*>(&Value),
|
||||
sizeof(T)
|
||||
@ -197,7 +201,7 @@ void Pstream::combineScatter(const List<Pstream::commsStruct>& comms, T& Value)
|
||||
}
|
||||
else
|
||||
{
|
||||
OPstream toBelow(Pstream::scheduled, belowID);
|
||||
OPstream toBelow(UPstream::scheduled, belowID);
|
||||
toBelow << Value;
|
||||
}
|
||||
}
|
||||
@ -208,13 +212,13 @@ void Pstream::combineScatter(const List<Pstream::commsStruct>& comms, T& Value)
|
||||
template <class T>
|
||||
void Pstream::combineScatter(T& Value)
|
||||
{
|
||||
if (Pstream::nProcs() < Pstream::nProcsSimpleSum)
|
||||
if (UPstream::nProcs() < UPstream::nProcsSimpleSum)
|
||||
{
|
||||
combineScatter(Pstream::linearCommunication(), Value);
|
||||
combineScatter(UPstream::linearCommunication(), Value);
|
||||
}
|
||||
else
|
||||
{
|
||||
combineScatter(Pstream::treeCommunication(), Value);
|
||||
combineScatter(UPstream::treeCommunication(), Value);
|
||||
}
|
||||
}
|
||||
|
||||
@ -226,15 +230,15 @@ void Pstream::combineScatter(T& Value)
|
||||
template <class T, class CombineOp>
|
||||
void Pstream::listCombineGather
|
||||
(
|
||||
const List<Pstream::commsStruct>& comms,
|
||||
const List<UPstream::commsStruct>& comms,
|
||||
List<T>& Values,
|
||||
const CombineOp& cop
|
||||
)
|
||||
{
|
||||
if (Pstream::parRun())
|
||||
if (UPstream::parRun())
|
||||
{
|
||||
// Get my communication order
|
||||
const commsStruct& myComm = comms[Pstream::myProcNo()];
|
||||
const commsStruct& myComm = comms[UPstream::myProcNo()];
|
||||
|
||||
// Receive from my downstairs neighbours
|
||||
forAll(myComm.below(), belowI)
|
||||
@ -245,9 +249,9 @@ void Pstream::listCombineGather
|
||||
{
|
||||
List<T> receivedValues(Values.size());
|
||||
|
||||
IPstream::read
|
||||
UIPstream::read
|
||||
(
|
||||
Pstream::scheduled,
|
||||
UPstream::scheduled,
|
||||
belowID,
|
||||
reinterpret_cast<char*>(receivedValues.begin()),
|
||||
receivedValues.byteSize()
|
||||
@ -266,7 +270,7 @@ void Pstream::listCombineGather
|
||||
}
|
||||
else
|
||||
{
|
||||
IPstream fromBelow(Pstream::scheduled, belowID);
|
||||
IPstream fromBelow(UPstream::scheduled, belowID);
|
||||
List<T> receivedValues(fromBelow);
|
||||
|
||||
if (debug & 2)
|
||||
@ -293,9 +297,9 @@ void Pstream::listCombineGather
|
||||
|
||||
if (contiguous<T>())
|
||||
{
|
||||
OPstream::write
|
||||
UOPstream::write
|
||||
(
|
||||
Pstream::scheduled,
|
||||
UPstream::scheduled,
|
||||
myComm.above(),
|
||||
reinterpret_cast<const char*>(Values.begin()),
|
||||
Values.byteSize()
|
||||
@ -303,7 +307,7 @@ void Pstream::listCombineGather
|
||||
}
|
||||
else
|
||||
{
|
||||
OPstream toAbove(Pstream::scheduled, myComm.above());
|
||||
OPstream toAbove(UPstream::scheduled, myComm.above());
|
||||
toAbove << Values;
|
||||
}
|
||||
}
|
||||
@ -314,13 +318,13 @@ void Pstream::listCombineGather
|
||||
template <class T, class CombineOp>
|
||||
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
|
||||
{
|
||||
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>
|
||||
void Pstream::listCombineScatter
|
||||
(
|
||||
const List<Pstream::commsStruct>& comms,
|
||||
const List<UPstream::commsStruct>& comms,
|
||||
List<T>& Values
|
||||
)
|
||||
{
|
||||
if (Pstream::parRun())
|
||||
if (UPstream::parRun())
|
||||
{
|
||||
// Get my communication order
|
||||
const Pstream::commsStruct& myComm = comms[Pstream::myProcNo()];
|
||||
const UPstream::commsStruct& myComm = comms[UPstream::myProcNo()];
|
||||
|
||||
// Reveive from up
|
||||
if (myComm.above() != -1)
|
||||
{
|
||||
if (contiguous<T>())
|
||||
{
|
||||
IPstream::read
|
||||
UIPstream::read
|
||||
(
|
||||
Pstream::scheduled,
|
||||
UPstream::scheduled,
|
||||
myComm.above(),
|
||||
reinterpret_cast<char*>(Values.begin()),
|
||||
Values.byteSize()
|
||||
@ -352,7 +356,7 @@ void Pstream::listCombineScatter
|
||||
}
|
||||
else
|
||||
{
|
||||
IPstream fromAbove(Pstream::scheduled, myComm.above());
|
||||
IPstream fromAbove(UPstream::scheduled, myComm.above());
|
||||
fromAbove >> Values;
|
||||
}
|
||||
|
||||
@ -375,9 +379,9 @@ void Pstream::listCombineScatter
|
||||
|
||||
if (contiguous<T>())
|
||||
{
|
||||
OPstream::write
|
||||
UOPstream::write
|
||||
(
|
||||
Pstream::scheduled,
|
||||
UPstream::scheduled,
|
||||
belowID,
|
||||
reinterpret_cast<const char*>(Values.begin()),
|
||||
Values.byteSize()
|
||||
@ -385,7 +389,7 @@ void Pstream::listCombineScatter
|
||||
}
|
||||
else
|
||||
{
|
||||
OPstream toBelow(Pstream::scheduled, belowID);
|
||||
OPstream toBelow(UPstream::scheduled, belowID);
|
||||
toBelow << Values;
|
||||
}
|
||||
}
|
||||
@ -396,13 +400,13 @@ void Pstream::listCombineScatter
|
||||
template <class T>
|
||||
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
|
||||
{
|
||||
listCombineScatter(Pstream::treeCommunication(), Values);
|
||||
listCombineScatter(UPstream::treeCommunication(), Values);
|
||||
}
|
||||
}
|
||||
|
||||
@ -416,22 +420,22 @@ void Pstream::listCombineScatter(List<T>& Values)
|
||||
template <class Container, class CombineOp>
|
||||
void Pstream::mapCombineGather
|
||||
(
|
||||
const List<Pstream::commsStruct>& comms,
|
||||
const List<UPstream::commsStruct>& comms,
|
||||
Container& Values,
|
||||
const CombineOp& cop
|
||||
)
|
||||
{
|
||||
if (Pstream::parRun())
|
||||
if (UPstream::parRun())
|
||||
{
|
||||
// Get my communication order
|
||||
const commsStruct& myComm = comms[Pstream::myProcNo()];
|
||||
const commsStruct& myComm = comms[UPstream::myProcNo()];
|
||||
|
||||
// Receive from my downstairs neighbours
|
||||
forAll(myComm.below(), belowI)
|
||||
{
|
||||
label belowID = myComm.below()[belowI];
|
||||
|
||||
IPstream fromBelow(Pstream::scheduled, belowID);
|
||||
IPstream fromBelow(UPstream::scheduled, belowID);
|
||||
Container receivedValues(fromBelow);
|
||||
|
||||
if (debug & 2)
|
||||
@ -471,7 +475,7 @@ void Pstream::mapCombineGather
|
||||
<< " data:" << Values << endl;
|
||||
}
|
||||
|
||||
OPstream toAbove(Pstream::scheduled, myComm.above());
|
||||
OPstream toAbove(UPstream::scheduled, myComm.above());
|
||||
toAbove << Values;
|
||||
}
|
||||
}
|
||||
@ -481,13 +485,13 @@ void Pstream::mapCombineGather
|
||||
template <class Container, class CombineOp>
|
||||
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
|
||||
{
|
||||
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>
|
||||
void Pstream::mapCombineScatter
|
||||
(
|
||||
const List<Pstream::commsStruct>& comms,
|
||||
const List<UPstream::commsStruct>& comms,
|
||||
Container& Values
|
||||
)
|
||||
{
|
||||
if (Pstream::parRun())
|
||||
if (UPstream::parRun())
|
||||
{
|
||||
// Get my communication order
|
||||
const Pstream::commsStruct& myComm = comms[Pstream::myProcNo()];
|
||||
const UPstream::commsStruct& myComm = comms[UPstream::myProcNo()];
|
||||
|
||||
// Reveive from up
|
||||
if (myComm.above() != -1)
|
||||
{
|
||||
IPstream fromAbove(Pstream::scheduled, myComm.above());
|
||||
IPstream fromAbove(UPstream::scheduled, myComm.above());
|
||||
fromAbove >> Values;
|
||||
|
||||
if (debug & 2)
|
||||
@ -527,7 +531,7 @@ void Pstream::mapCombineScatter
|
||||
Pout<< " sending to " << belowID << " data:" << Values << endl;
|
||||
}
|
||||
|
||||
OPstream toBelow(Pstream::scheduled, belowID);
|
||||
OPstream toBelow(UPstream::scheduled, belowID);
|
||||
toBelow << Values;
|
||||
}
|
||||
}
|
||||
@ -537,19 +541,17 @@ void Pstream::mapCombineScatter
|
||||
template <class Container>
|
||||
void Pstream::mapCombineScatter(Container& Values)
|
||||
{
|
||||
if (Pstream::nProcs() < Pstream::nProcsSimpleSum)
|
||||
if (UPstream::nProcs() < UPstream::nProcsSimpleSum)
|
||||
{
|
||||
mapCombineScatter(Pstream::linearCommunication(), Values);
|
||||
mapCombineScatter(UPstream::linearCommunication(), Values);
|
||||
}
|
||||
else
|
||||
{
|
||||
mapCombineScatter(Pstream::treeCommunication(), Values);
|
||||
mapCombineScatter(UPstream::treeCommunication(), Values);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
160
src/OpenFOAM/db/IOstreams/Pstreams/exchange.C
Normal file
160
src/OpenFOAM/db/IOstreams/Pstreams/exchange.C
Normal 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
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -30,7 +30,9 @@ Description
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "UOPstream.H"
|
||||
#include "OPstream.H"
|
||||
#include "UIPstream.H"
|
||||
#include "IPstream.H"
|
||||
#include "contiguous.H"
|
||||
|
||||
@ -44,15 +46,15 @@ namespace Foam
|
||||
template <class T, class BinaryOp>
|
||||
void Pstream::gather
|
||||
(
|
||||
const List<Pstream::commsStruct>& comms,
|
||||
const List<UPstream::commsStruct>& comms,
|
||||
T& Value,
|
||||
const BinaryOp& bop
|
||||
)
|
||||
{
|
||||
if (Pstream::parRun())
|
||||
if (UPstream::parRun())
|
||||
{
|
||||
// Get my communication order
|
||||
const commsStruct& myComm = comms[Pstream::myProcNo()];
|
||||
const commsStruct& myComm = comms[UPstream::myProcNo()];
|
||||
|
||||
// Receive from my downstairs neighbours
|
||||
forAll(myComm.below(), belowI)
|
||||
@ -61,9 +63,9 @@ void Pstream::gather
|
||||
|
||||
if (contiguous<T>())
|
||||
{
|
||||
IPstream::read
|
||||
UIPstream::read
|
||||
(
|
||||
Pstream::scheduled,
|
||||
UPstream::scheduled,
|
||||
myComm.below()[belowI],
|
||||
reinterpret_cast<char*>(&value),
|
||||
sizeof(T)
|
||||
@ -71,7 +73,7 @@ void Pstream::gather
|
||||
}
|
||||
else
|
||||
{
|
||||
IPstream fromBelow(Pstream::scheduled, myComm.below()[belowI]);
|
||||
IPstream fromBelow(UPstream::scheduled, myComm.below()[belowI]);
|
||||
fromBelow >> value;
|
||||
}
|
||||
|
||||
@ -83,9 +85,9 @@ void Pstream::gather
|
||||
{
|
||||
if (contiguous<T>())
|
||||
{
|
||||
OPstream::write
|
||||
UOPstream::write
|
||||
(
|
||||
Pstream::scheduled,
|
||||
UPstream::scheduled,
|
||||
myComm.above(),
|
||||
reinterpret_cast<const char*>(&Value),
|
||||
sizeof(T)
|
||||
@ -93,7 +95,7 @@ void Pstream::gather
|
||||
}
|
||||
else
|
||||
{
|
||||
OPstream toAbove(Pstream::scheduled, myComm.above());
|
||||
OPstream toAbove(UPstream::scheduled, myComm.above());
|
||||
toAbove << Value;
|
||||
}
|
||||
}
|
||||
@ -104,33 +106,33 @@ void Pstream::gather
|
||||
template <class T, class BinaryOp>
|
||||
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
|
||||
{
|
||||
gather(Pstream::treeCommunication(), Value, bop);
|
||||
gather(UPstream::treeCommunication(), Value, bop);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
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
|
||||
const commsStruct& myComm = comms[Pstream::myProcNo()];
|
||||
const commsStruct& myComm = comms[UPstream::myProcNo()];
|
||||
|
||||
// Reveive from up
|
||||
if (myComm.above() != -1)
|
||||
{
|
||||
if (contiguous<T>())
|
||||
{
|
||||
IPstream::read
|
||||
UIPstream::read
|
||||
(
|
||||
Pstream::scheduled,
|
||||
UPstream::scheduled,
|
||||
myComm.above(),
|
||||
reinterpret_cast<char*>(&Value),
|
||||
sizeof(T)
|
||||
@ -138,7 +140,7 @@ void Pstream::scatter(const List<Pstream::commsStruct>& comms, T& Value)
|
||||
}
|
||||
else
|
||||
{
|
||||
IPstream fromAbove(Pstream::scheduled, myComm.above());
|
||||
IPstream fromAbove(UPstream::scheduled, myComm.above());
|
||||
fromAbove >> Value;
|
||||
}
|
||||
}
|
||||
@ -148,9 +150,9 @@ void Pstream::scatter(const List<Pstream::commsStruct>& comms, T& Value)
|
||||
{
|
||||
if (contiguous<T>())
|
||||
{
|
||||
OPstream::write
|
||||
UOPstream::write
|
||||
(
|
||||
Pstream::scheduled,
|
||||
UPstream::scheduled,
|
||||
myComm.below()[belowI],
|
||||
reinterpret_cast<const char*>(&Value),
|
||||
sizeof(T)
|
||||
@ -158,7 +160,7 @@ void Pstream::scatter(const List<Pstream::commsStruct>& comms, T& Value)
|
||||
}
|
||||
else
|
||||
{
|
||||
OPstream toBelow(Pstream::scheduled,myComm.below()[belowI]);
|
||||
OPstream toBelow(UPstream::scheduled,myComm.below()[belowI]);
|
||||
toBelow << Value;
|
||||
}
|
||||
}
|
||||
@ -169,13 +171,13 @@ void Pstream::scatter(const List<Pstream::commsStruct>& comms, T& Value)
|
||||
template <class T>
|
||||
void Pstream::scatter(T& Value)
|
||||
{
|
||||
if (Pstream::nProcs() < Pstream::nProcsSimpleSum)
|
||||
if (UPstream::nProcs() < UPstream::nProcsSimpleSum)
|
||||
{
|
||||
scatter(Pstream::linearCommunication(), Value);
|
||||
scatter(UPstream::linearCommunication(), Value);
|
||||
}
|
||||
else
|
||||
{
|
||||
scatter(Pstream::treeCommunication(), Value);
|
||||
scatter(UPstream::treeCommunication(), Value);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -27,7 +27,7 @@ Description
|
||||
communication schedule (usually linear-to-master or tree-to-master).
|
||||
The gathered data will be a list with element procID the data from processor
|
||||
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
|
||||
processors below it. Only the 'master' of the communication schedule holds
|
||||
a fully filled List. Use scatter to distribute the data.
|
||||
@ -48,26 +48,26 @@ namespace Foam
|
||||
template <class T>
|
||||
void Pstream::gatherList
|
||||
(
|
||||
const List<Pstream::commsStruct>& comms,
|
||||
const List<UPstream::commsStruct>& comms,
|
||||
List<T>& Values
|
||||
)
|
||||
{
|
||||
if (Pstream::parRun())
|
||||
if (UPstream::parRun())
|
||||
{
|
||||
if (Values.size() != Pstream::nProcs())
|
||||
if (Values.size() != UPstream::nProcs())
|
||||
{
|
||||
FatalErrorIn
|
||||
(
|
||||
"Pstream::gatherList(const List<Pstream::commsStruct>&"
|
||||
"UPstream::gatherList(const List<UPstream::commsStruct>&"
|
||||
", List<T>)"
|
||||
) << "Size of list:" << Values.size()
|
||||
<< " does not equal the number of processors:"
|
||||
<< Pstream::nProcs()
|
||||
<< UPstream::nProcs()
|
||||
<< Foam::abort(FatalError);
|
||||
}
|
||||
|
||||
// Get my communication order
|
||||
const commsStruct& myComm = comms[Pstream::myProcNo()];
|
||||
const commsStruct& myComm = comms[UPstream::myProcNo()];
|
||||
|
||||
// Receive from my downstairs neighbours
|
||||
forAll(myComm.below(), belowI)
|
||||
@ -79,9 +79,9 @@ void Pstream::gatherList
|
||||
{
|
||||
List<T> receivedValues(belowLeaves.size() + 1);
|
||||
|
||||
IPstream::read
|
||||
UIPstream::read
|
||||
(
|
||||
Pstream::scheduled,
|
||||
UPstream::scheduled,
|
||||
belowID,
|
||||
reinterpret_cast<char*>(receivedValues.begin()),
|
||||
receivedValues.byteSize()
|
||||
@ -96,7 +96,7 @@ void Pstream::gatherList
|
||||
}
|
||||
else
|
||||
{
|
||||
IPstream fromBelow(Pstream::scheduled, belowID);
|
||||
IPstream fromBelow(UPstream::scheduled, belowID);
|
||||
fromBelow >> Values[belowID];
|
||||
|
||||
if (debug & 2)
|
||||
@ -132,14 +132,14 @@ void Pstream::gatherList
|
||||
if (debug & 2)
|
||||
{
|
||||
Pout<< " sending to " << myComm.above()
|
||||
<< " data from me:" << Pstream::myProcNo()
|
||||
<< " data:" << Values[Pstream::myProcNo()] << endl;
|
||||
<< " data from me:" << UPstream::myProcNo()
|
||||
<< " data:" << Values[UPstream::myProcNo()] << endl;
|
||||
}
|
||||
|
||||
if (contiguous<T>())
|
||||
{
|
||||
List<T> sendingValues(belowLeaves.size() + 1);
|
||||
sendingValues[0] = Values[Pstream::myProcNo()];
|
||||
sendingValues[0] = Values[UPstream::myProcNo()];
|
||||
|
||||
forAll(belowLeaves, leafI)
|
||||
{
|
||||
@ -148,7 +148,7 @@ void Pstream::gatherList
|
||||
|
||||
OPstream::write
|
||||
(
|
||||
Pstream::scheduled,
|
||||
UPstream::scheduled,
|
||||
myComm.above(),
|
||||
reinterpret_cast<const char*>(sendingValues.begin()),
|
||||
sendingValues.byteSize()
|
||||
@ -156,8 +156,8 @@ void Pstream::gatherList
|
||||
}
|
||||
else
|
||||
{
|
||||
OPstream toAbove(Pstream::scheduled, myComm.above());
|
||||
toAbove << Values[Pstream::myProcNo()];
|
||||
OPstream toAbove(UPstream::scheduled, myComm.above());
|
||||
toAbove << Values[UPstream::myProcNo()];
|
||||
|
||||
forAll(belowLeaves, leafI)
|
||||
{
|
||||
@ -180,13 +180,13 @@ void Pstream::gatherList
|
||||
template <class T>
|
||||
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
|
||||
{
|
||||
gatherList(Pstream::treeCommunication(), Values);
|
||||
gatherList(UPstream::treeCommunication(), Values);
|
||||
}
|
||||
}
|
||||
|
||||
@ -194,26 +194,26 @@ void Pstream::gatherList(List<T>& Values)
|
||||
template <class T>
|
||||
void Pstream::scatterList
|
||||
(
|
||||
const List<Pstream::commsStruct>& comms,
|
||||
const List<UPstream::commsStruct>& comms,
|
||||
List<T>& Values
|
||||
)
|
||||
{
|
||||
if (Pstream::parRun())
|
||||
if (UPstream::parRun())
|
||||
{
|
||||
if (Values.size() != Pstream::nProcs())
|
||||
if (Values.size() != UPstream::nProcs())
|
||||
{
|
||||
FatalErrorIn
|
||||
(
|
||||
"Pstream::scatterList(const List<Pstream::commsStruct>&"
|
||||
"UPstream::scatterList(const List<UPstream::commsStruct>&"
|
||||
", List<T>)"
|
||||
) << "Size of list:" << Values.size()
|
||||
<< " does not equal the number of processors:"
|
||||
<< Pstream::nProcs()
|
||||
<< UPstream::nProcs()
|
||||
<< Foam::abort(FatalError);
|
||||
}
|
||||
|
||||
// Get my communication order
|
||||
const commsStruct& myComm = comms[Pstream::myProcNo()];
|
||||
const commsStruct& myComm = comms[UPstream::myProcNo()];
|
||||
|
||||
// Reveive from up
|
||||
if (myComm.above() != -1)
|
||||
@ -224,9 +224,9 @@ void Pstream::scatterList
|
||||
{
|
||||
List<T> receivedValues(notBelowLeaves.size());
|
||||
|
||||
IPstream::read
|
||||
UIPstream::read
|
||||
(
|
||||
Pstream::scheduled,
|
||||
UPstream::scheduled,
|
||||
myComm.above(),
|
||||
reinterpret_cast<char*>(receivedValues.begin()),
|
||||
receivedValues.byteSize()
|
||||
@ -239,7 +239,7 @@ void Pstream::scatterList
|
||||
}
|
||||
else
|
||||
{
|
||||
IPstream fromAbove(Pstream::scheduled, myComm.above());
|
||||
IPstream fromAbove(UPstream::scheduled, myComm.above());
|
||||
|
||||
forAll(notBelowLeaves, leafI)
|
||||
{
|
||||
@ -273,7 +273,7 @@ void Pstream::scatterList
|
||||
|
||||
OPstream::write
|
||||
(
|
||||
Pstream::scheduled,
|
||||
UPstream::scheduled,
|
||||
belowID,
|
||||
reinterpret_cast<const char*>(sendingValues.begin()),
|
||||
sendingValues.byteSize()
|
||||
@ -281,7 +281,7 @@ void Pstream::scatterList
|
||||
}
|
||||
else
|
||||
{
|
||||
OPstream toBelow(Pstream::scheduled, belowID);
|
||||
OPstream toBelow(UPstream::scheduled, belowID);
|
||||
|
||||
// Send data destined for all other processors below belowID
|
||||
forAll(notBelowLeaves, leafI)
|
||||
@ -305,13 +305,13 @@ void Pstream::scatterList
|
||||
template <class T>
|
||||
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
|
||||
{
|
||||
scatterList(Pstream::treeCommunication(), Values);
|
||||
scatterList(UPstream::treeCommunication(), Values);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -229,11 +229,7 @@ void processorPointPatch::initPatchPatchPoints()
|
||||
|
||||
// Send the patchPatchPoints to the neighbouring processor
|
||||
|
||||
OPstream toNeighbProc
|
||||
(
|
||||
Pstream::blocking,
|
||||
neighbProcNo()
|
||||
);
|
||||
OPstream toNeighbProc(Pstream::blocking, neighbProcNo());
|
||||
|
||||
toNeighbProc
|
||||
<< ppmp.size() // number of points for checking
|
||||
@ -252,11 +248,7 @@ void processorPointPatch::initPatchPatchPoints()
|
||||
void Foam::processorPointPatch::calcPatchPatchPoints()
|
||||
{
|
||||
// Get the patchPatchPoints from the neighbouring processor
|
||||
IPstream fromNeighbProc
|
||||
(
|
||||
Pstream::blocking,
|
||||
neighbProcNo()
|
||||
);
|
||||
IPstream fromNeighbProc(Pstream::blocking, neighbProcNo());
|
||||
|
||||
label nbrNPoints(readLabel(fromNeighbProc));
|
||||
labelListList patchPatchPoints(fromNeighbProc);
|
||||
|
||||
@ -381,7 +381,13 @@ Foam::mapDistribute::mapDistribute
|
||||
}
|
||||
|
||||
subMap_.setSize(Pstream::nProcs());
|
||||
exchange(wantedRemoteElements, subMap_);
|
||||
labelListList sendSizes;
|
||||
Pstream::exchange<labelList, label>
|
||||
(
|
||||
wantedRemoteElements,
|
||||
subMap_,
|
||||
sendSizes
|
||||
);
|
||||
|
||||
// Renumber elements
|
||||
forAll(elements, i)
|
||||
@ -528,7 +534,13 @@ Foam::mapDistribute::mapDistribute
|
||||
}
|
||||
|
||||
subMap_.setSize(Pstream::nProcs());
|
||||
exchange(wantedRemoteElements, subMap_);
|
||||
labelListList sendSizes;
|
||||
Pstream::exchange<labelList, label>
|
||||
(
|
||||
wantedRemoteElements,
|
||||
subMap_,
|
||||
sendSizes
|
||||
);
|
||||
|
||||
// Renumber elements
|
||||
forAll(cellCells, cellI)
|
||||
|
||||
@ -93,39 +93,8 @@ class mapDistribute
|
||||
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 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
|
||||
|
||||
//- Construct from components
|
||||
|
||||
@ -25,6 +25,7 @@ License
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "Pstream.H"
|
||||
#include "PstreamBuffers.H"
|
||||
#include "PstreamCombineReduceOps.H"
|
||||
|
||||
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||
@ -185,17 +186,9 @@ void Foam::mapDistribute::distribute
|
||||
{
|
||||
if (!contiguous<T>())
|
||||
{
|
||||
// 1. convert to contiguous buffer
|
||||
// 2. send buffer
|
||||
// 3. receive buffer
|
||||
// 4. read from buffer into List<T>
|
||||
PstreamBuffers pBuffs(Pstream::nonBlocking);
|
||||
|
||||
List<List<char> > sendFields(Pstream::nProcs());
|
||||
labelListList allNTrans(Pstream::nProcs());
|
||||
labelList& nsTransPs = allNTrans[Pstream::myProcNo()];
|
||||
nsTransPs.setSize(Pstream::nProcs(), 0);
|
||||
|
||||
// Stream data into sendField buffers
|
||||
// Stream data into buffer
|
||||
for (label domain = 0; domain < Pstream::nProcs(); domain++)
|
||||
{
|
||||
const labelList& map = subMap[domain];
|
||||
@ -203,66 +196,13 @@ void Foam::mapDistribute::distribute
|
||||
if (domain != Pstream::myProcNo() && map.size())
|
||||
{
|
||||
// Put data into send buffer
|
||||
OPstream toDomain(Pstream::nonBlocking, domain);
|
||||
UOPstream toDomain(domain, pBuffs);
|
||||
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
|
||||
fromSlave.set
|
||||
(
|
||||
domain,
|
||||
new IPstream
|
||||
(
|
||||
Pstream::nonBlocking,
|
||||
domain,
|
||||
allNTrans[domain][Pstream::myProcNo()]
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
pBuffs.finishedSends();
|
||||
|
||||
{
|
||||
// Set up 'send' to myself
|
||||
@ -285,10 +225,6 @@ void Foam::mapDistribute::distribute
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Wait till all finished
|
||||
Pstream::waitRequests();
|
||||
|
||||
// Consume
|
||||
for (label domain = 0; domain < Pstream::nProcs(); domain++)
|
||||
{
|
||||
@ -296,7 +232,8 @@ void Foam::mapDistribute::distribute
|
||||
|
||||
if (domain != Pstream::myProcNo() && map.size())
|
||||
{
|
||||
List<T> recvField(fromSlave[domain]);
|
||||
UIPstream str(domain, pBuffs);
|
||||
List<T> recvField(str);
|
||||
|
||||
if (recvField.size() != map.size())
|
||||
{
|
||||
@ -322,9 +259,6 @@ void Foam::mapDistribute::distribute
|
||||
{
|
||||
field[map[i]] = recvField[i];
|
||||
}
|
||||
|
||||
// Delete receive buffer
|
||||
fromSlave.set(domain, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -618,17 +552,10 @@ void Foam::mapDistribute::distribute
|
||||
{
|
||||
if (!contiguous<T>())
|
||||
{
|
||||
// 1. convert to contiguous buffer
|
||||
// 2. send buffer
|
||||
// 3. receive buffer
|
||||
// 4. read from buffer into List<T>
|
||||
//XXXXXX
|
||||
PstreamBuffers pBuffs(Pstream::nonBlocking);
|
||||
|
||||
List<List<char> > sendFields(Pstream::nProcs());
|
||||
labelListList allNTrans(Pstream::nProcs());
|
||||
labelList& nsTransPs = allNTrans[Pstream::myProcNo()];
|
||||
nsTransPs.setSize(Pstream::nProcs());
|
||||
|
||||
// Stream data into sendField buffers
|
||||
// Stream data into buffer
|
||||
for (label domain = 0; domain < Pstream::nProcs(); domain++)
|
||||
{
|
||||
const labelList& map = subMap[domain];
|
||||
@ -636,65 +563,13 @@ void Foam::mapDistribute::distribute
|
||||
if (domain != Pstream::myProcNo() && map.size())
|
||||
{
|
||||
// Put data into send buffer
|
||||
OPstream toDomain(Pstream::nonBlocking, domain);
|
||||
UOPstream toDomain(domain, pBuffs);
|
||||
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
|
||||
fromSlave.set
|
||||
(
|
||||
domain,
|
||||
new IPstream
|
||||
(
|
||||
Pstream::nonBlocking,
|
||||
domain,
|
||||
allNTrans[domain][Pstream::myProcNo()]
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
pBuffs.finishedSends();
|
||||
|
||||
{
|
||||
// Set up 'send' to myself
|
||||
@ -715,7 +590,7 @@ void Foam::mapDistribute::distribute
|
||||
|
||||
|
||||
// Wait till all finished
|
||||
Pstream::waitRequests();
|
||||
UPstream::waitRequests();
|
||||
|
||||
// Consume
|
||||
for (label domain = 0; domain < Pstream::nProcs(); domain++)
|
||||
@ -724,7 +599,8 @@ void Foam::mapDistribute::distribute
|
||||
|
||||
if (domain != Pstream::myProcNo() && map.size())
|
||||
{
|
||||
List<T> recvField(fromSlave[domain]);
|
||||
UIPstream str(domain, pBuffs);
|
||||
List<T> recvField(str);
|
||||
|
||||
if (recvField.size() != map.size())
|
||||
{
|
||||
@ -750,9 +626,6 @@ void Foam::mapDistribute::distribute
|
||||
{
|
||||
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())
|
||||
{
|
||||
recvFields[domain].setSize(map.size());
|
||||
IPstream::read
|
||||
UIPstream::read
|
||||
(
|
||||
Pstream::nonBlocking,
|
||||
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()];
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
|
||||
@ -402,11 +402,7 @@ void Foam::syncTools::syncPointMap
|
||||
{
|
||||
// Send to master
|
||||
{
|
||||
OPstream toMaster
|
||||
(
|
||||
Pstream::blocking,
|
||||
Pstream::masterNo()
|
||||
);
|
||||
OPstream toMaster(Pstream::blocking, Pstream::masterNo());
|
||||
toMaster << sharedPointValues;
|
||||
}
|
||||
// Receive merged values
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
Pstream.C
|
||||
IPread.C
|
||||
OPwrite.C
|
||||
UPstream.C
|
||||
UIPread.C
|
||||
UOPwrite.C
|
||||
|
||||
LIB = $(FOAM_LIBBIN)/dummy/libPstream
|
||||
|
||||
@ -23,38 +23,40 @@ License
|
||||
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
Description
|
||||
Read token and binary block from IPstream
|
||||
Read from UIPstream
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "error.H"
|
||||
#include "IPstream.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
#include "UIPstream.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructor * * * * * * * * * * * * * * * //
|
||||
|
||||
Foam::IPstream::IPstream
|
||||
Foam::UIPstream::UIPstream
|
||||
(
|
||||
const commsTypes commsType,
|
||||
const int fromProcNo,
|
||||
const label bufSize,
|
||||
DynamicList<char>& externalBuf,
|
||||
const int tag,
|
||||
streamFormat format,
|
||||
versionNumber version
|
||||
)
|
||||
:
|
||||
Pstream(commsType, bufSize),
|
||||
UPstream(commsType),
|
||||
Istream(format, version),
|
||||
fromProcNo_(fromProcNo),
|
||||
externalBuf_(externalBuf),
|
||||
externalBufPosition_(0),
|
||||
tag_(tag),
|
||||
messageSize_(0)
|
||||
{
|
||||
notImplemented
|
||||
(
|
||||
"IPsream::IPstream"
|
||||
"UIPstream::UIPstream"
|
||||
"("
|
||||
"const commsTypes,"
|
||||
"const int fromProcNo,"
|
||||
"const label bufSize,"
|
||||
"DynamicList<char>&,"
|
||||
"const int tag,"
|
||||
"streamFormat, versionNumber"
|
||||
")"
|
||||
);
|
||||
@ -63,22 +65,24 @@ Foam::IPstream::IPstream
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
int Foam::IPstream::read
|
||||
Foam::label Foam::UIPstream::read
|
||||
(
|
||||
const commsTypes commsType,
|
||||
const int fromProcNo,
|
||||
char* buf,
|
||||
const std::streamsize bufSize
|
||||
const std::streamsize bufSize,
|
||||
const int tag
|
||||
)
|
||||
{
|
||||
notImplemented
|
||||
(
|
||||
"IPstream::read"
|
||||
"UIPstream::read"
|
||||
"("
|
||||
"const commsTypes,"
|
||||
"const int fromProcNo,"
|
||||
"char* buf,"
|
||||
"const label bufSize"
|
||||
"const label bufSize,"
|
||||
"const int tag"
|
||||
")"
|
||||
);
|
||||
|
||||
@ -27,37 +27,28 @@ Description
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "error.H"
|
||||
#include "OPstream.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
|
||||
|
||||
Foam::OPstream::~OPstream()
|
||||
{
|
||||
notImplemented("OPstream::~OPstream()");
|
||||
}
|
||||
|
||||
#include "UOPstream.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
bool Foam::OPstream::write
|
||||
bool Foam::UOPstream::write
|
||||
(
|
||||
const commsTypes commsType,
|
||||
const int toProcNo,
|
||||
const char* buf,
|
||||
const std::streamsize bufSize
|
||||
const std::streamsize bufSize,
|
||||
const int tag
|
||||
)
|
||||
{
|
||||
notImplemented
|
||||
(
|
||||
"IPstream::write"
|
||||
"UOPstream::write"
|
||||
"("
|
||||
"const commsTypes commsType,"
|
||||
"const int fromProcNo,"
|
||||
"char* buf,"
|
||||
"const label bufSize"
|
||||
"const label bufSize,"
|
||||
"const int tag"
|
||||
")"
|
||||
);
|
||||
|
||||
@ -24,20 +24,18 @@ License
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "Pstream.H"
|
||||
#include "UPstream.H"
|
||||
#include "PstreamReduceOps.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
void Foam::Pstream::addValidParOptions(HashTable<string>& validParOptions)
|
||||
void Foam::UPstream::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
|
||||
<< "This dummy library cannot be used in parallel mode"
|
||||
<< 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;
|
||||
}
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
OPwrite.C
|
||||
IPread.C
|
||||
Pstream.C
|
||||
UOPwrite.C
|
||||
UIPread.C
|
||||
UPstream.C
|
||||
PstreamGlobals.C
|
||||
|
||||
LIB = $(FOAM_MPI_LIBBIN)/libPstream
|
||||
|
||||
@ -23,91 +23,161 @@ License
|
||||
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
Description
|
||||
Read token and binary block from IPstream
|
||||
Read from UIPstream
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "mpi.h"
|
||||
|
||||
#include "IPstream.H"
|
||||
#include "UIPstream.H"
|
||||
#include "PstreamGlobals.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||
|
||||
// Outstanding non-blocking operations.
|
||||
//! @cond fileScope
|
||||
//Foam::DynamicList<MPI_Request> IPstream_outstandingRequests_;
|
||||
//! @endcond fileScope
|
||||
#include "IOstreams.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructor * * * * * * * * * * * * * * * //
|
||||
|
||||
Foam::IPstream::IPstream
|
||||
Foam::UIPstream::UIPstream
|
||||
(
|
||||
const commsTypes commsType,
|
||||
const int fromProcNo,
|
||||
const label bufSize,
|
||||
DynamicList<char>& externalBuf,
|
||||
const int tag,
|
||||
streamFormat format,
|
||||
versionNumber version
|
||||
)
|
||||
:
|
||||
Pstream(commsType, bufSize),
|
||||
UPstream(commsType),
|
||||
Istream(format, version),
|
||||
fromProcNo_(fromProcNo),
|
||||
externalBuf_(externalBuf),
|
||||
externalBufPosition_(0),
|
||||
tag_(tag),
|
||||
messageSize_(0)
|
||||
{
|
||||
setOpened();
|
||||
setGood();
|
||||
|
||||
if (commsType == UPstream::nonBlocking)
|
||||
{
|
||||
// Message is already received into externalBuf
|
||||
}
|
||||
else
|
||||
{
|
||||
MPI_Status status;
|
||||
|
||||
// Cannot use buf_.size() since appends a few bytes extra
|
||||
label realBufSize = bufSize;
|
||||
label wantedSize = externalBuf_.capacity();
|
||||
|
||||
// If the buffer size is not specified, probe the incomming message
|
||||
// and set it
|
||||
if (!bufSize)
|
||||
if (!wantedSize)
|
||||
{
|
||||
if (commsType == nonBlocking)
|
||||
{
|
||||
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_Probe(procID(fromProcNo_), tag_, MPI_COMM_WORLD, &status);
|
||||
MPI_Get_count(&status, MPI_BYTE, &messageSize_);
|
||||
|
||||
buf_.setSize(messageSize_);
|
||||
realBufSize = buf_.size();
|
||||
externalBuf_.setCapacity(messageSize_);
|
||||
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_)
|
||||
{
|
||||
FatalErrorIn
|
||||
(
|
||||
"IPstream::IPstream(const commsTypes, const int, "
|
||||
"const label, streamFormat, versionNumber)"
|
||||
"UIPstream::UIPstream(const commsTypes, const int, "
|
||||
"DynamicList<char>&, streamFormat, versionNumber)"
|
||||
) << "read failed"
|
||||
<< 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 * * * * * * * * * * * * * //
|
||||
|
||||
Foam::label Foam::IPstream::read
|
||||
Foam::label Foam::UIPstream::read
|
||||
(
|
||||
const commsTypes commsType,
|
||||
const int fromProcNo,
|
||||
char* buf,
|
||||
const std::streamsize bufSize
|
||||
const std::streamsize bufSize,
|
||||
const int tag
|
||||
)
|
||||
{
|
||||
if (commsType == blocking || commsType == scheduled)
|
||||
@ -122,7 +192,7 @@ Foam::label Foam::IPstream::read
|
||||
bufSize,
|
||||
MPI_PACKED,
|
||||
procID(fromProcNo),
|
||||
msgType(),
|
||||
tag,
|
||||
MPI_COMM_WORLD,
|
||||
&status
|
||||
)
|
||||
@ -130,7 +200,7 @@ Foam::label Foam::IPstream::read
|
||||
{
|
||||
FatalErrorIn
|
||||
(
|
||||
"IPstream::read"
|
||||
"UIPstream::read"
|
||||
"(const int fromProcNo, char* buf, std::streamsize bufSize)"
|
||||
) << "MPI_Recv cannot receive incomming message"
|
||||
<< Foam::abort(FatalError);
|
||||
@ -148,7 +218,7 @@ Foam::label Foam::IPstream::read
|
||||
{
|
||||
FatalErrorIn
|
||||
(
|
||||
"IPstream::read"
|
||||
"UIPstream::read"
|
||||
"(const int fromProcNo, char* buf, std::streamsize bufSize)"
|
||||
) << "buffer (" << label(bufSize)
|
||||
<< ") not large enough for incomming message ("
|
||||
@ -170,7 +240,7 @@ Foam::label Foam::IPstream::read
|
||||
bufSize,
|
||||
MPI_PACKED,
|
||||
procID(fromProcNo),
|
||||
msgType(),
|
||||
tag,
|
||||
MPI_COMM_WORLD,
|
||||
&request
|
||||
)
|
||||
@ -178,7 +248,7 @@ Foam::label Foam::IPstream::read
|
||||
{
|
||||
FatalErrorIn
|
||||
(
|
||||
"IPstream::read"
|
||||
"UIPstream::read"
|
||||
"(const int fromProcNo, char* buf, std::streamsize bufSize)"
|
||||
) << "MPI_Recv cannot start non-blocking receive"
|
||||
<< Foam::abort(FatalError);
|
||||
@ -195,7 +265,7 @@ Foam::label Foam::IPstream::read
|
||||
{
|
||||
FatalErrorIn
|
||||
(
|
||||
"IPstream::read"
|
||||
"UIPstream::read"
|
||||
"(const int fromProcNo, char* buf, std::streamsize bufSize)"
|
||||
) << "Unsupported communications type " << commsType
|
||||
<< Foam::abort(FatalError);
|
||||
@ -205,6 +275,4 @@ Foam::label Foam::IPstream::read
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -29,54 +29,18 @@ Description
|
||||
|
||||
#include "mpi.h"
|
||||
|
||||
#include "OPstream.H"
|
||||
#include "UOPstream.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 * * * * * * * * * * * * * //
|
||||
|
||||
bool Foam::OPstream::write
|
||||
bool Foam::UOPstream::write
|
||||
(
|
||||
const commsTypes commsType,
|
||||
const int toProcNo,
|
||||
const char* buf,
|
||||
const std::streamsize bufSize
|
||||
const std::streamsize bufSize,
|
||||
const int tag
|
||||
)
|
||||
{
|
||||
bool transferFailed = true;
|
||||
@ -89,7 +53,7 @@ bool Foam::OPstream::write
|
||||
bufSize,
|
||||
MPI_PACKED,
|
||||
procID(toProcNo),
|
||||
msgType(),
|
||||
tag,
|
||||
MPI_COMM_WORLD
|
||||
);
|
||||
}
|
||||
@ -101,7 +65,7 @@ bool Foam::OPstream::write
|
||||
bufSize,
|
||||
MPI_PACKED,
|
||||
procID(toProcNo),
|
||||
msgType(),
|
||||
tag,
|
||||
MPI_COMM_WORLD
|
||||
);
|
||||
}
|
||||
@ -115,7 +79,7 @@ bool Foam::OPstream::write
|
||||
bufSize,
|
||||
MPI_PACKED,
|
||||
procID(toProcNo),
|
||||
msgType(),
|
||||
tag,
|
||||
MPI_COMM_WORLD,
|
||||
&request
|
||||
);
|
||||
@ -126,8 +90,9 @@ bool Foam::OPstream::write
|
||||
{
|
||||
FatalErrorIn
|
||||
(
|
||||
"OPstream::write"
|
||||
"(const int fromProcNo, char* buf, std::streamsize bufSize)"
|
||||
"UOPstream::write"
|
||||
"(const int fromProcNo, char* buf, std::streamsize bufSize"
|
||||
", const int)"
|
||||
) << "Unsupported communications type " << commsType
|
||||
<< Foam::abort(FatalError);
|
||||
}
|
||||
@ -26,7 +26,7 @@ License
|
||||
|
||||
#include "mpi.h"
|
||||
|
||||
#include "Pstream.H"
|
||||
#include "UPstream.H"
|
||||
#include "PstreamReduceOps.H"
|
||||
#include "OSspecific.H"
|
||||
#include "PstreamGlobals.H"
|
||||
@ -50,7 +50,7 @@ License
|
||||
// valid parallel options vary between implementations, but flag common ones.
|
||||
// if they are not removed by MPI_Init(), the subsequent argument processing
|
||||
// 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("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);
|
||||
|
||||
@ -72,8 +72,8 @@ bool Foam::Pstream::init(int& argc, char**& argv)
|
||||
|
||||
if (numprocs <= 1)
|
||||
{
|
||||
FatalErrorIn("Pstream::init(int& argc, char**& argv)")
|
||||
<< "bool Pstream::init(int& argc, char**& argv) : "
|
||||
FatalErrorIn("UPstream::init(int& argc, char**& argv)")
|
||||
<< "bool IPstream::init(int& argc, char**& argv) : "
|
||||
"attempt to run parallel on 1 processor"
|
||||
<< Foam::abort(FatalError);
|
||||
}
|
||||
@ -101,8 +101,8 @@ bool Foam::Pstream::init(int& argc, char**& argv)
|
||||
}
|
||||
else
|
||||
{
|
||||
FatalErrorIn("Pstream::init(int& argc, char**& argv)")
|
||||
<< "Pstream::init(int& argc, char**& argv) : "
|
||||
FatalErrorIn("UPstream::init(int& argc, char**& argv)")
|
||||
<< "UPstream::init(int& argc, char**& argv) : "
|
||||
<< "environment variable MPI_BUFFER_SIZE not defined"
|
||||
<< 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
|
||||
int size;
|
||||
@ -136,10 +136,10 @@ void Foam::Pstream::exit(int errnum)
|
||||
label n = PstreamGlobals::outstandingRequests_.size();
|
||||
PstreamGlobals::outstandingRequests_.clear();
|
||||
|
||||
WarningIn("Pstream::exit(int)")
|
||||
WarningIn("UPstream::exit(int)")
|
||||
<< "There are still " << n << " outstanding MPI_Requests." << endl
|
||||
<< "This means that your code exited before doing a"
|
||||
<< " Pstream::waitRequests()." << endl
|
||||
<< " UPstream::waitRequests()." << endl
|
||||
<< "This should not happen for a normal code exit."
|
||||
<< 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);
|
||||
}
|
||||
@ -164,19 +164,19 @@ void Foam::Pstream::abort()
|
||||
|
||||
void Foam::reduce(scalar& Value, const sumOp<scalar>& bop)
|
||||
{
|
||||
if (!Pstream::parRun())
|
||||
if (!UPstream::parRun())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (Pstream::nProcs() <= Pstream::nProcsSimpleSum)
|
||||
if (UPstream::nProcs() <= UPstream::nProcsSimpleSum)
|
||||
{
|
||||
if (Pstream::master())
|
||||
if (UPstream::master())
|
||||
{
|
||||
for
|
||||
(
|
||||
int slave=Pstream::firstSlave();
|
||||
slave<=Pstream::lastSlave();
|
||||
int slave=UPstream::firstSlave();
|
||||
slave<=UPstream::lastSlave();
|
||||
slave++
|
||||
)
|
||||
{
|
||||
@ -189,8 +189,8 @@ void Foam::reduce(scalar& Value, const sumOp<scalar>& bop)
|
||||
&value,
|
||||
1,
|
||||
MPI_SCALAR,
|
||||
Pstream::procID(slave),
|
||||
Pstream::msgType(),
|
||||
UPstream::procID(slave),
|
||||
UPstream::msgType(),
|
||||
MPI_COMM_WORLD,
|
||||
MPI_STATUS_IGNORE
|
||||
)
|
||||
@ -215,8 +215,8 @@ void Foam::reduce(scalar& Value, const sumOp<scalar>& bop)
|
||||
&Value,
|
||||
1,
|
||||
MPI_SCALAR,
|
||||
Pstream::procID(Pstream::masterNo()),
|
||||
Pstream::msgType(),
|
||||
UPstream::procID(UPstream::masterNo()),
|
||||
UPstream::msgType(),
|
||||
MPI_COMM_WORLD
|
||||
)
|
||||
)
|
||||
@ -230,12 +230,12 @@ void Foam::reduce(scalar& Value, const sumOp<scalar>& bop)
|
||||
}
|
||||
|
||||
|
||||
if (Pstream::master())
|
||||
if (UPstream::master())
|
||||
{
|
||||
for
|
||||
(
|
||||
int slave=Pstream::firstSlave();
|
||||
slave<=Pstream::lastSlave();
|
||||
int slave=UPstream::firstSlave();
|
||||
slave<=UPstream::lastSlave();
|
||||
slave++
|
||||
)
|
||||
{
|
||||
@ -246,8 +246,8 @@ void Foam::reduce(scalar& Value, const sumOp<scalar>& bop)
|
||||
&Value,
|
||||
1,
|
||||
MPI_SCALAR,
|
||||
Pstream::procID(slave),
|
||||
Pstream::msgType(),
|
||||
UPstream::procID(slave),
|
||||
UPstream::msgType(),
|
||||
MPI_COMM_WORLD
|
||||
)
|
||||
)
|
||||
@ -269,8 +269,8 @@ void Foam::reduce(scalar& Value, const sumOp<scalar>& bop)
|
||||
&Value,
|
||||
1,
|
||||
MPI_SCALAR,
|
||||
Pstream::procID(Pstream::masterNo()),
|
||||
Pstream::msgType(),
|
||||
UPstream::procID(UPstream::masterNo()),
|
||||
UPstream::msgType(),
|
||||
MPI_COMM_WORLD,
|
||||
MPI_STATUS_IGNORE
|
||||
)
|
||||
@ -291,8 +291,8 @@ void Foam::reduce(scalar& Value, const sumOp<scalar>& bop)
|
||||
Value = sum;
|
||||
|
||||
/*
|
||||
int myProcNo = Pstream::myProcNo();
|
||||
int nProcs = Pstream::nProcs();
|
||||
int myProcNo = UPstream::myProcNo();
|
||||
int nProcs = UPstream::nProcs();
|
||||
|
||||
//
|
||||
// receive from children
|
||||
@ -321,8 +321,8 @@ void Foam::reduce(scalar& Value, const sumOp<scalar>& bop)
|
||||
&value,
|
||||
1,
|
||||
MPI_SCALAR,
|
||||
Pstream::procID(childProcId),
|
||||
Pstream::msgType(),
|
||||
UPstream::procID(childProcId),
|
||||
UPstream::msgType(),
|
||||
MPI_COMM_WORLD,
|
||||
MPI_STATUS_IGNORE
|
||||
)
|
||||
@ -346,7 +346,7 @@ void Foam::reduce(scalar& Value, const sumOp<scalar>& bop)
|
||||
//
|
||||
// send and receive from parent
|
||||
//
|
||||
if (!Pstream::master())
|
||||
if (!UPstream::master())
|
||||
{
|
||||
int parentId = myProcNo - (myProcNo % thisLevelOffset);
|
||||
|
||||
@ -357,8 +357,8 @@ void Foam::reduce(scalar& Value, const sumOp<scalar>& bop)
|
||||
&Value,
|
||||
1,
|
||||
MPI_SCALAR,
|
||||
Pstream::procID(parentId),
|
||||
Pstream::msgType(),
|
||||
UPstream::procID(parentId),
|
||||
UPstream::msgType(),
|
||||
MPI_COMM_WORLD
|
||||
)
|
||||
)
|
||||
@ -377,8 +377,8 @@ void Foam::reduce(scalar& Value, const sumOp<scalar>& bop)
|
||||
&Value,
|
||||
1,
|
||||
MPI_SCALAR,
|
||||
Pstream::procID(parentId),
|
||||
Pstream::msgType(),
|
||||
UPstream::procID(parentId),
|
||||
UPstream::msgType(),
|
||||
MPI_COMM_WORLD,
|
||||
MPI_STATUS_IGNORE
|
||||
)
|
||||
@ -413,8 +413,8 @@ void Foam::reduce(scalar& Value, const sumOp<scalar>& bop)
|
||||
&Value,
|
||||
1,
|
||||
MPI_SCALAR,
|
||||
Pstream::procID(childProcId),
|
||||
Pstream::msgType(),
|
||||
UPstream::procID(childProcId),
|
||||
UPstream::msgType(),
|
||||
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())
|
||||
{
|
||||
@ -452,7 +452,7 @@ void Foam::Pstream::waitRequests()
|
||||
{
|
||||
FatalErrorIn
|
||||
(
|
||||
"Pstream::waitRequests()"
|
||||
"UPstream::waitRequests()"
|
||||
) << "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())
|
||||
{
|
||||
FatalErrorIn
|
||||
(
|
||||
"Pstream::finishedRequest(const label)"
|
||||
"UPstream::finishedRequest(const label)"
|
||||
) << "There are " << PstreamGlobals::outstandingRequests_.size()
|
||||
<< " outstanding send requests and you are asking for i=" << i
|
||||
<< nl
|
||||
@ -26,9 +26,6 @@ License
|
||||
|
||||
#include "edgeMesh.H"
|
||||
#include "mergePoints.H"
|
||||
#include "StaticHashTable.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||
|
||||
@ -204,7 +201,7 @@ void Foam::edgeMesh::mergePoints(const scalar mergeDist)
|
||||
}
|
||||
|
||||
// Compact using a hashtable and commutative hash of edge.
|
||||
StaticHashTable<label, edge, Hash<edge> > edgeToLabel
|
||||
HashTable<label, edge, Hash<edge> > edgeToLabel
|
||||
(
|
||||
2*edges_.size()
|
||||
);
|
||||
@ -228,7 +225,7 @@ void Foam::edgeMesh::mergePoints(const scalar mergeDist)
|
||||
|
||||
for
|
||||
(
|
||||
StaticHashTable<label, edge, Hash<edge> >::const_iterator iter =
|
||||
HashTable<label, edge, Hash<edge> >::const_iterator iter =
|
||||
edgeToLabel.begin();
|
||||
iter != edgeToLabel.end();
|
||||
++iter
|
||||
|
||||
@ -26,8 +26,6 @@ License
|
||||
|
||||
#include "processorFvPatchField.H"
|
||||
#include "processorFvPatch.H"
|
||||
#include "IPstream.H"
|
||||
#include "OPstream.H"
|
||||
#include "demandDrivenData.H"
|
||||
#include "transformField.H"
|
||||
|
||||
|
||||
@ -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 =
|
||||
const_cast<GeometricField<Type, fvPatchField, volMesh>&>(psi_);
|
||||
|
||||
|
||||
@ -27,9 +27,6 @@ Description
|
||||
list of selected cells, it creates the mesh consisting only of the
|
||||
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"
|
||||
|
||||
@ -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 TrackingData>
|
||||
void Foam::Cloud<ParticleType>::move(TrackingData& td)
|
||||
@ -196,7 +173,7 @@ void Foam::Cloud<ParticleType>::move(TrackingData& td)
|
||||
// processor patches for all the processors
|
||||
labelListList allNTrans(Pstream::nProcs());
|
||||
allNTrans[Pstream::myProcNo()] = nsTransPs;
|
||||
combineReduce(allNTrans, combineNsTransPs());
|
||||
combineReduce(allNTrans, UPstream::listEq());
|
||||
|
||||
transfered = false;
|
||||
|
||||
|
||||
@ -121,7 +121,7 @@ void Foam::ReactingParcel<ParcelType>::correctSurfaceValues
|
||||
return;
|
||||
}
|
||||
|
||||
// Far field gas molar fractions
|
||||
// Far field carrier molar fractions
|
||||
scalarField Xinf(Y_.size());
|
||||
|
||||
forAll(Xinf, i)
|
||||
@ -135,7 +135,7 @@ void Foam::ReactingParcel<ParcelType>::correctSurfaceValues
|
||||
// Molar fraction of far field species at particle surface
|
||||
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_);
|
||||
|
||||
// Surface carrier composition (molar fraction)
|
||||
@ -171,10 +171,10 @@ void Foam::ReactingParcel<ParcelType>::correctSurfaceValues
|
||||
cbrt(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);
|
||||
kappa +=
|
||||
Ys[i]*cbrtW*td.cloud().mcCarrierThermo().speciesData()[i].kappa(T);
|
||||
cps += Xs[i]*td.cloud().mcCarrierThermo().speciesData()[i].Cp(T);
|
||||
|
||||
sumYiSqrtW += Ys[i]*sqrtW;
|
||||
sumYiCbrtW += Ys[i]*cbrtW;
|
||||
@ -417,7 +417,7 @@ void Foam::ReactingParcel<ParcelType>::calcPhaseChange
|
||||
const scalarField& YComponents,
|
||||
scalarField& dMassPC,
|
||||
scalar& Sh,
|
||||
scalar& dhsTrans,
|
||||
scalar& dhsTrans, // TODO: not used
|
||||
scalar& N,
|
||||
scalar& NCpW,
|
||||
scalarField& Cs
|
||||
|
||||
@ -233,7 +233,7 @@ Foam::scalar Foam::ThermoParcel<ParcelType>::calcHeatTransfer
|
||||
|
||||
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);
|
||||
@ -256,9 +256,11 @@ Foam::scalar Foam::ThermoParcel<ParcelType>::calcHeatTransfer
|
||||
IntegrationScheme<scalar>::integrationResult Tres =
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -118,7 +118,7 @@ protected:
|
||||
scalar volumeTotal_;
|
||||
|
||||
//- Total mass to inject [kg]
|
||||
const scalar massTotal_;
|
||||
scalar massTotal_;
|
||||
|
||||
//- Total mass injected to date [kg]
|
||||
scalar massInjected_;
|
||||
|
||||
@ -124,11 +124,12 @@ Foam::PatchInjection<CloudType>::PatchInjection
|
||||
|
||||
label patchSize = cellOwners_.size();
|
||||
label totalPatchSize = patchSize;
|
||||
reduce(totalPatchSize, sumOp<scalar>());
|
||||
fraction_ = patchSize/totalPatchSize;
|
||||
reduce(totalPatchSize, sumOp<label>());
|
||||
fraction_ = scalar(patchSize)/totalPatchSize;
|
||||
|
||||
// Set total volume to inject
|
||||
// Set total volume/mass to inject
|
||||
this->volumeTotal_ = fraction_*volumeFlowRate_().integrate(0.0, duration_);
|
||||
this->massTotal_ *= fraction_;
|
||||
}
|
||||
|
||||
|
||||
@ -164,12 +165,21 @@ void Foam::PatchInjection<CloudType>::setPositionAndCell
|
||||
vector& position,
|
||||
label& cellOwner
|
||||
)
|
||||
{
|
||||
if (cellOwners_.size() > 0)
|
||||
{
|
||||
label cellI = this->owner().rndGen().integer(0, cellOwners_.size() - 1);
|
||||
|
||||
cellOwner = cellOwners_[cellI];
|
||||
position = this->owner().mesh().C()[cellOwner];
|
||||
}
|
||||
else
|
||||
{
|
||||
cellOwner = -1;
|
||||
// dummy position
|
||||
position = pTraits<vector>::max;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template<class CloudType>
|
||||
|
||||
@ -71,15 +71,12 @@ bool Foam::Rebound<CloudType>::correct
|
||||
nw /= mag(nw);
|
||||
|
||||
scalar Un = U & nw;
|
||||
vector Ut = U - Un*nw;
|
||||
|
||||
if (Un > 0.0)
|
||||
{
|
||||
U -= UFactor_*2.0*Un*nw;
|
||||
}
|
||||
|
||||
U -= Ut;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@ -170,7 +170,7 @@ public:
|
||||
|
||||
// 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.
|
||||
referredCell reRefer
|
||||
(
|
||||
|
||||
@ -7,10 +7,10 @@ fieldMinMax/fieldMinMax.C
|
||||
fieldMinMax/fieldMinMaxFunctionObject.C
|
||||
|
||||
fieldValues/fieldValue/fieldValue.C
|
||||
fieldValues/face/faceSource.C
|
||||
fieldValues/face/faceSourceFunctionObject.C
|
||||
fieldValues/cell/cellSource.C
|
||||
fieldValues/cell/cellSourceFunctionObject.C
|
||||
fieldValues/faceSource/faceSource.C
|
||||
fieldValues/faceSource/faceSourceFunctionObject.C
|
||||
fieldValues/cellSource/cellSource.C
|
||||
fieldValues/cellSource/cellSourceFunctionObject.C
|
||||
|
||||
streamLine/streamLine.C
|
||||
streamLine/streamLineParticle.C
|
||||
|
||||
@ -50,10 +50,13 @@ namespace Foam
|
||||
fieldValues::faceSource::sourceTypeNames_;
|
||||
|
||||
template<>
|
||||
const char* NamedEnum<fieldValues::faceSource::operationType, 4>::
|
||||
names[] = {"none", "sum", "areaAverage", "areaIntegrate"};
|
||||
const char* NamedEnum<fieldValues::faceSource::operationType, 5>::
|
||||
names[] =
|
||||
{
|
||||
"none", "sum", "areaAverage", "areaIntegrate", "weightedAverage"
|
||||
};
|
||||
|
||||
const NamedEnum<fieldValues::faceSource::operationType, 4>
|
||||
const NamedEnum<fieldValues::faceSource::operationType, 5>
|
||||
fieldValues::faceSource::operationTypeNames_;
|
||||
|
||||
}
|
||||
@ -68,6 +71,8 @@ void Foam::fieldValues::faceSource::setFaceZoneFaces()
|
||||
if (zoneId < 0)
|
||||
{
|
||||
FatalErrorIn("faceSource::faceSource::setFaceZoneFaces()")
|
||||
<< type() << " " << name_ << ": "
|
||||
<< sourceTypeNames_[source_] << "(" << sourceName_ << "):" << nl
|
||||
<< " Unknown face zone name: " << sourceName_
|
||||
<< ". Valid face zones are: " << mesh().faceZones().names()
|
||||
<< nl << exit(FatalError);
|
||||
@ -164,6 +169,8 @@ void Foam::fieldValues::faceSource::setPatchFaces()
|
||||
if (patchId < 0)
|
||||
{
|
||||
FatalErrorIn("faceSource::constructFaceAddressing()")
|
||||
<< type() << " " << name_ << ": "
|
||||
<< sourceTypeNames_[source_] << "(" << sourceName_ << "):" << nl
|
||||
<< " Unknown patch name: " << sourceName_
|
||||
<< ". Valid patch names are: "
|
||||
<< mesh().boundaryMesh().names() << nl
|
||||
@ -197,7 +204,7 @@ void Foam::fieldValues::faceSource::setPatchFaces()
|
||||
|
||||
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
|
||||
|
||||
void Foam::fieldValues::faceSource::initialise()
|
||||
void Foam::fieldValues::faceSource::initialise(const dictionary& dict)
|
||||
{
|
||||
switch (source_)
|
||||
{
|
||||
@ -214,15 +221,40 @@ void Foam::fieldValues::faceSource::initialise()
|
||||
default:
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
Info<< type() << " " << name_ << ":" << nl
|
||||
<< " total faces = " << faceId_.size() << nl
|
||||
<< " total area = " << sum(filterField(mesh().magSf()))
|
||||
<< nl << endl;
|
||||
<< " total area = " << sum(filterField(mesh().magSf())) << nl;
|
||||
|
||||
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_(),
|
||||
facePatchId_(),
|
||||
flipMap_(),
|
||||
outputFilePtr_(NULL)
|
||||
outputFilePtr_(NULL),
|
||||
weightFieldName_("undefinedWeightedFieldName")
|
||||
{
|
||||
initialise();
|
||||
|
||||
if (active_)
|
||||
{
|
||||
initialise(dict);
|
||||
|
||||
// Create the output file if not already created
|
||||
makeFile();
|
||||
}
|
||||
@ -327,7 +360,7 @@ void Foam::fieldValues::faceSource::read(const dictionary& dict)
|
||||
if (active_)
|
||||
{
|
||||
fieldValue::read(dict);
|
||||
initialise();
|
||||
initialise(dict);
|
||||
}
|
||||
}
|
||||
|
||||
@ -39,7 +39,7 @@ Description
|
||||
valueOutput true; // Write values at run-time output times?
|
||||
source faceZone; // Type of face source: faceZone, patch
|
||||
sourceName f0;
|
||||
operation sum; // none, sum, areaAverage, areaIntegrate
|
||||
operation sum;
|
||||
fields
|
||||
(
|
||||
p
|
||||
@ -48,6 +48,13 @@ Description
|
||||
);
|
||||
}
|
||||
|
||||
where operation is one of:
|
||||
- none
|
||||
- sum
|
||||
- areaAverage
|
||||
- areaIntegrate
|
||||
- weightedAverage
|
||||
|
||||
SourceFiles
|
||||
faceSource.C
|
||||
|
||||
@ -100,11 +107,12 @@ public:
|
||||
opNone,
|
||||
opSum,
|
||||
opAreaAverage,
|
||||
opAreaIntegrate
|
||||
opAreaIntegrate,
|
||||
opWeightedAverage
|
||||
};
|
||||
|
||||
//- Operation type names
|
||||
static const NamedEnum<operationType, 4> operationTypeNames_;
|
||||
static const NamedEnum<operationType, 5> operationTypeNames_;
|
||||
|
||||
|
||||
private:
|
||||
@ -143,11 +151,14 @@ protected:
|
||||
//- Output file pointer
|
||||
autoPtr<OFstream> outputFilePtr_;
|
||||
|
||||
//- Weight field name - only used for opWeightedAverage mode
|
||||
word weightFieldName_;
|
||||
|
||||
|
||||
// Protected member functions
|
||||
|
||||
//- Initialise, e.g. face addressing
|
||||
void initialise();
|
||||
void initialise(const dictionary& dict);
|
||||
|
||||
//- Insert field values into values list
|
||||
template<class Type>
|
||||
@ -129,6 +129,47 @@ Type Foam::fieldValues::faceSource::processValues
|
||||
result = sum(values*filterField(mesh().magSf()));
|
||||
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:
|
||||
{
|
||||
// Do nothing
|
||||
@ -137,7 +137,7 @@ public:
|
||||
//- Return the output field values flag
|
||||
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;
|
||||
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user