Merge branch 'feature-localWorld' into 'develop'

Feature local world

See merge request Development/openfoam!398
This commit is contained in:
Andrew Heather
2020-12-09 15:20:30 +00:00
152 changed files with 8777 additions and 597 deletions

View File

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

View File

@ -0,0 +1,24 @@
EXE_INC = \
-DFULLDEBUG -g -O0 \
-I$(LIB_SRC)/finiteVolume/lnInclude \
-I$(LIB_SRC)/meshTools/lnInclude \
-I$(LIB_SRC)/dynamicMesh/lnInclude \
-I$(LIB_SRC)/dynamicFvMesh/lnInclude \
-I$(LIB_SRC)/sampling/lnInclude \
-I$(LIB_SRC)/transportModels/compressible/lnInclude \
-I$(LIB_SRC)/thermophysicalModels/basic/lnInclude \
-I$(LIB_SRC)/thermophysicalModels/solidThermo/lnInclude \
-I$(LIB_SRC)/thermophysicalModels/radiation/lnInclude
EXE_LIBS = \
-lfiniteVolume \
-lfvOptions \
-lmeshTools \
-lsampling \
-ldynamicMesh \
-ldynamicFvMesh \
-ltopoChangerFvMesh \
-lcompressibleTransportModels \
-lfluidThermophysicalModels \
-lradiationModels \
-lspecie

View File

@ -0,0 +1,102 @@
Info<< "Reading thermophysical properties\n" << endl;
autoPtr<solidThermo> pThermo(solidThermo::New(mesh));
solidThermo& thermo = pThermo();
tmp<volScalarField> trho = thermo.rho();
const volScalarField& rho = trho();
tmp<volScalarField> tcp = thermo.Cp();
const volScalarField& cp = tcp();
volScalarField& p = thermo.p();
volScalarField& h = thermo.he();
autoPtr<coordinateSystem> coordinatesPtr;
autoPtr<volSymmTensorField> taniAlpha;
if (!thermo.isotropic())
{
Info<< "Adding coordinateSystem\n" << endl;
coordinatesPtr = coordinateSystem::New
(
mesh,
thermo,
coordinateSystem::typeName_()
);
tmp<volVectorField> tkappaByCp = thermo.Kappa()/thermo.Cp();
taniAlpha.reset
(
new volSymmTensorField
(
IOobject
(
"Anialpha",
runTime.timeName(),
mesh,
IOobject::NO_READ,
IOobject::NO_WRITE
),
mesh,
dimensionedSymmTensor(tkappaByCp().dimensions(), Zero),
zeroGradientFvPatchSymmTensorField::typeName
)
);
volSymmTensorField& aniAlpha = *taniAlpha;
aniAlpha.primitiveFieldRef() =
coordinatesPtr->transformPrincipal
(
mesh.cellCentres(),
tkappaByCp()
);
aniAlpha.correctBoundaryConditions();
}
IOobject betavSolidIO
(
"betavSolid",
runTime.timeName(),
mesh,
IOobject::MUST_READ,
IOobject::AUTO_WRITE
);
autoPtr<volScalarField> betavPtr;
if (betavSolidIO.typeHeaderOk<volScalarField>(true))
{
betavPtr.reset
(
new volScalarField
(
betavSolidIO,
mesh
)
);
}
else
{
betavPtr.reset
(
new volScalarField
(
IOobject
(
"betavSolid",
runTime.timeName(),
mesh,
IOobject::NO_READ,
IOobject::NO_WRITE
),
mesh,
dimensionedScalar("1", dimless, scalar(1))
)
);
}
const volScalarField& betav = *betavPtr;
#include "createRadiationModel.H"
#include "createFvOptions.H"

View File

@ -0,0 +1,38 @@
{
fvScalarMatrix hEqn
(
fvm::ddt(betav*rho, h)
- (
thermo.isotropic()
? fvm::laplacian(betav*thermo.alpha(), h, "laplacian(alpha,h)")
: fvm::laplacian(betav*taniAlpha(), h, "laplacian(alpha,h)")
)
==
fvOptions(rho, h)
);
if (mesh.changing())
{
surfaceScalarField phihMesh
(
fvc::interpolate(betav*rho*h)*mesh.phi()
);
hEqn -= fvc::div(phihMesh);
}
hEqn.relax();
fvOptions.constrain(hEqn);
hEqn.solve(); //mesh.solver(h.select(finalIter)));
fvOptions.correct(h);
thermo.correct();
Info<< "Min/max T:" << min(thermo.T()).value() << ' '
<< max(thermo.T()).value() << endl;
radiation->correct();
}

View File

@ -0,0 +1,120 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2020 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Application
solidFoam
Group
grpHeatTransferSolvers
Description
Solver for energy transport and thermodynamics on a solid.
\*---------------------------------------------------------------------------*/
#include "fvCFD.H"
#include "dynamicFvMesh.H"
#include "solidThermo.H"
#include "radiationModel.H"
#include "fvOptions.H"
#include "simpleControl.H"
#include "pimpleControl.H"
#include "coordinateSystem.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
int main(int argc, char *argv[])
{
argList::addNote
(
"Solver for energy transport and thermodynamics on a solid"
);
#define NO_CONTROL
#include "postProcess.H"
#include "addCheckCaseOptions.H"
#include "setRootCaseLists.H"
#include "createTime.H"
#include "createDynamicFvMesh.H"
#include "createFields.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
Info<< "\nEvolving thermodynamics\n" << endl;
if (mesh.solutionDict().found("SIMPLE"))
{
simpleControl simple(mesh);
while (simple.loop())
{
Info<< "Time = " << runTime.timeName() << nl << endl;
while (simple.correctNonOrthogonal())
{
#include "hEqn.H"
}
runTime.write();
runTime.printExecutionTime(Info);
}
}
else
{
pimpleControl pimple(mesh);
while (runTime.run())
{
++runTime;
Info<< "Time = " << runTime.timeName() << nl << endl;
while (pimple.loop())
{
if (pimple.firstIter())
{
mesh.update();
}
while (pimple.correct())
{
#include "hEqn.H"
}
}
runTime.write();
runTime.printExecutionTime(Info);
}
}
Info<< "End\n" << endl;
return 0;
}
// ************************************************************************* //

View File

@ -0,0 +1,18 @@
#!/bin/sh
cd ${0%/*} || exit 1 # Run from this directory
. $WM_PROJECT_DIR/bin/tools/RunFunctions # Tutorial run functions
# Run serial
(cd left && runApplication blockMesh)
(cd right && runApplication blockMesh)
mpirun -app ./mpirun_left_right.schema
## Run parallel
#(cd left && runApplication blockMesh)
#(cd left && runApplication decomposePar)
#(cd right && runApplication blockMesh)
#(cd right && runApplication decomposePar)
#
#mpirun -app ./mpirun.schema
#------------------------------------------------------------------------------

View File

@ -0,0 +1,49 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: v1906 |
| \\ / A nd | Web: www.OpenFOAM.com |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class volScalarField;
object T;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
dimensions [0 0 0 1 0 0 0];
internalField uniform 300;
boundaryField
{
#includeEtc "caseDicts/setConstraintTypes"
bottom
{
type compressible::turbulentTemperatureCoupledBaffle2Mixed;
value uniform 300;
Tnbr T;
kappaMethod fluidThermo;
}
top
{
type zeroGradient;
}
left
{
type fixedValue;
value uniform 300;
}
right
{
type inletOutlet;
value uniform 300;
inletValue uniform 300;
}
}
// ************************************************************************* //

View File

@ -0,0 +1,50 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: plus |
| \\ / A nd | Web: www.OpenFOAM.com |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class volVectorField;
location "0/topAir";
object U;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
dimensions [ 0 1 -1 0 0 0 0 ];
internalField uniform ( 0.1 0 0 );
boundaryField
{
#includeEtc "caseDicts/setConstraintTypes"
top
{
type fixedValue;
value uniform ( 0 0 0 );
}
left
{
type fixedValue;
value uniform ( 0.1 0 0 );
}
right
{
type inletOutlet;
value uniform ( 0.1 0 0 );
inletValue uniform ( 0 0 0 );
}
bottom
{
type fixedValue;
value uniform ( 0 0 0 );
}
}
// ************************************************************************* //

View File

@ -0,0 +1,50 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: plus |
| \\ / A nd | Web: www.OpenFOAM.com |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class volScalarField;
location "0/topAir";
object epsilon;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
dimensions [ 0 2 -3 0 0 0 0 ];
internalField uniform 0.01;
boundaryField
{
#includeEtc "caseDicts/setConstraintTypes"
left
{
type fixedValue;
value $internalField;
}
right
{
type inletOutlet;
value $internalField;
inletValue $internalField;
}
top
{
type epsilonWallFunction;
value $internalField;
}
bottom
{
type epsilonWallFunction;
value $internalField;
}
}
// ************************************************************************* //

View File

@ -0,0 +1,50 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: plus |
| \\ / A nd | Web: www.OpenFOAM.com |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class volScalarField;
location "0/topAir";
object k;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
dimensions [ 0 2 -2 0 0 0 0 ];
internalField uniform 0.1;
boundaryField
{
#includeEtc "caseDicts/setConstraintTypes"
top
{
type kqRWallFunction;
value $internalField;
}
left
{
type fixedValue;
value $internalField;
}
right
{
type inletOutlet;
value $internalField;
inletValue $internalField;
}
bottom
{
type kqRWallFunction;
value $internalField;
}
}
// ************************************************************************* //

View File

@ -0,0 +1,49 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: plus |
| \\ / A nd | Web: www.OpenFOAM.com |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class volScalarField;
location "0/topAir";
object p;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
dimensions [ 1 -1 -2 0 0 0 0 ];
internalField uniform 100000;
boundaryField
{
#includeEtc "caseDicts/setConstraintTypes"
top
{
type calculated;
value uniform 100000;
}
left
{
type calculated;
value uniform 100000;
}
right
{
type calculated;
value uniform 100000;
}
bottom
{
type calculated;
value uniform 100000;
}
}
// ************************************************************************* //

View File

@ -0,0 +1,49 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: plus |
| \\ / A nd | Web: www.OpenFOAM.com |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class volScalarField;
location "0/topAir";
object p_rgh;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
dimensions [ 1 -1 -2 0 0 0 0 ];
internalField uniform 100000;
boundaryField
{
#includeEtc "caseDicts/setConstraintTypes"
left
{
type fixedFluxPressure;
value uniform 100000;
}
top
{
type fixedFluxPressure;
value uniform 100000;
}
right
{
type fixedValue;
value uniform 100000;
}
bottom
{
type fixedFluxPressure;
value uniform 100000;
}
}
// ************************************************************************* //

View File

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

View File

@ -0,0 +1,24 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: v1906 |
| \\ / A nd | Web: www.OpenFOAM.com |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class dictionary;
location "constant";
object regionProperties;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
regions
(
fluid (topAir)
solid ()
);
// ************************************************************************* //

View File

@ -0,0 +1,22 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: v1906 |
| \\ / A nd | Web: www.OpenFOAM.com |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class dictionary;
object radiationProperties;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
radiation off;
radiationModel none;
// ************************************************************************* //

View File

@ -0,0 +1,47 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: v1906 |
| \\ / A nd | Web: www.OpenFOAM.com |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class dictionary;
object thermophysicalProperties;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
thermoType
{
type heRhoThermo;
mixture pureMixture;
transport const;
thermo hConst;
equationOfState perfectGas;
specie specie;
energy sensibleEnthalpy;
}
mixture
{
specie
{
molWeight 28.9;
}
thermodynamics
{
Cp 1000;
Hf 0;
}
transport
{
mu 1.8e-05;
Pr 0.7;
}
}
// ************************************************************************* //

View File

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

View File

@ -0,0 +1,66 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: v1906 |
| \\ / A nd | Web: www.OpenFOAM.com |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class dictionary;
location "system";
object controlDict;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
DebugSwitches
{
//UPstream 1;
mappedPatchBase 1;
}
application chtMultiRegionFoam;
startFrom startTime;
startTime 0;
stopAt endTime;
endTime 1;
deltaT 0.001;
writeControl adjustable;
writeInterval 0.1;
purgeWrite 0;
writeFormat ascii;
writePrecision 8;
writeCompression off;
timeFormat general;
timePrecision 6;
runTimeModifiable yes;
maxCo 0.6;
// Maximum diffusion number
maxDi 10.0;
adjustTimeStep yes;
//functions
//{
// #include "vtkWrite"
//}
// ************************************************************************* //

View File

@ -0,0 +1,54 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: v1906 |
| \\ / A nd | Web: www.OpenFOAM.com |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class dictionary;
object decomposeParDict;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
numberOfSubdomains 4;
method scotch;
// method hierarchical;
// method simple;
regions
{
heater
{
numberOfSubdomains 1;
method simple; // none;
coeffs
{
n (1 1 1);
}
}
}
coeffs
{
n (2 2 1);
}
/*
constraints
{
//- Keep owner and neighbour on same processor for faces in zones:
faces
{
type preserveFaceZones;
zones (heater solid1 solid3);
}
}
*/
// ************************************************************************* //

View File

@ -0,0 +1,58 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: v1906 |
| \\ / A nd | Web: www.OpenFOAM.com |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class dictionary;
object fvSchemes;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
ddtSchemes
{
//default Euler;
default steadyState;
}
gradSchemes
{
default Gauss linear;
}
divSchemes
{
default none;
div(phi,U) Gauss upwind;
div(phi,K) Gauss linear;
div(phi,h) Gauss upwind;
div(phi,k) Gauss upwind;
div(phi,epsilon) Gauss upwind;
div(phi,R) Gauss upwind;
div(R) Gauss linear;
div(((rho*nuEff)*dev2(T(grad(U))))) Gauss linear;
}
laplacianSchemes
{
default Gauss linear corrected;
}
interpolationSchemes
{
default linear;
}
snGradSchemes
{
default corrected;
}
// ************************************************************************* //

View File

@ -0,0 +1,105 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: v1906 |
| \\ / A nd | Web: www.OpenFOAM.com |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class dictionary;
object fvSolution;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
solvers
{
rho
{
solver PCG;
preconditioner DIC;
tolerance 1e-7;
relTol 0.1;
}
rhoFinal
{
$rho;
tolerance 1e-7;
relTol 0;
}
p_rgh
{
solver GAMG;
tolerance 1e-7;
relTol 0.01;
smoother GaussSeidel;
}
p_rghFinal
{
$p_rgh;
tolerance 1e-7;
relTol 0;
}
"(U|h|k|epsilon|R)"
{
solver PBiCGStab;
preconditioner DILU;
tolerance 1e-7;
relTol 0.1;
}
"(U|h|k|epsilon|R)Final"
{
$U;
tolerance 1e-7;
relTol 0;
}
}
//PIMPLE
//{
// momentumPredictor yes;
// nCorrectors 2;
// nNonOrthogonalCorrectors 0;
//}
//
//relaxationFactors
//{
// equations
// {
// "h.*" 1;
// "U.*" 1;
// }
//}
SIMPLE
{
nNonOrthogonalCorrectors 0;
}
relaxationFactors
{
fields
{
rho 1;
p_rgh 0.7;
}
equations
{
U 0.3;
"(h|e)" 0.3;
k 0.3;
epsilon 0.3;
}
}
// ************************************************************************* //

View File

@ -0,0 +1,96 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: v1906 |
| \\ / A nd | Web: www.OpenFOAM.com |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class dictionary;
object blockMeshDict;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
scale 1;
vertices
(
(-0.1 0.00 -0.05)
( 0.1 0.00 -0.05)
( 0.1 0.04 -0.05)
(-0.1 0.04 -0.05)
(-0.1 0.00 0.05)
( 0.1 0.00 0.05)
( 0.1 0.04 0.05)
(-0.1 0.04 0.05)
);
blocks
(
hex (0 1 2 3 4 5 6 7) (20 10 1) simpleGrading (1 1 1)
);
edges
(
);
boundary
(
bottom
{
type mappedWall;
inGroups 1 ( wall );
sampleMode nearestPatchFace;
sampleWorld solid;
sampleRegion bottomSolid;
samplePatch top;
faces
(
(1 5 4 0)
);
}
top
{
type wall;
faces
(
(3 7 6 2)
);
}
left
{
type wall;
faces
(
(0 4 7 3)
);
}
right
{
type wall;
faces
(
(2 6 5 1)
);
}
frontAndBack
{
type empty;
faces
(
(0 3 2 1)
(4 5 6 7)
);
}
);
mergePatchPairs
(
);
// ************************************************************************* //

View File

@ -0,0 +1 @@
../fvSolution

View File

@ -0,0 +1,61 @@
// -*- C++ -*-
// Use the vtkWrite function object
vtkWrite
{
type vtkWrite;
libs (utilityFunctionObjects);
log true;
writeControl writeTime;
writeInterval 1;
regions (".*");
internal true;
boundary true;
single false;
interpolate true;
// Fields to output (words or regex)
fields (".*");
//- Output format (ascii | binary) - Default=binary
// format binary;
//- Use legacy output format - Default=false
// legacy false;
//- Output directory name - Default="postProcessing/<name>"
// directory "VTK";
//- Write cell ids as field - Default=true
writeIds false;
}
// Solid walls only
walls
{
type vtkWrite;
libs (utilityFunctionObjects);
log true;
writeControl writeTime;
writeInterval 1;
internal false;
// single true;
regions ( heater "(?i).*solid" );
patches ( "(?i).*solid_to.*" "heater.*(Air|Water)" );
fields (T);
}
// ************************************************************************* //

View File

@ -0,0 +1,2 @@
-np 1 xterm -font fixed -title fluid -geometry 200x15+0+0 -e ./run_fluid.sh
-np 1 xterm -font fixed -title solid -geometry 200x15+0+200 -e ./run_solid.sh

View File

@ -0,0 +1,6 @@
#!/bin/bash
#. /home/mattijs/OpenFOAM/OpenFOAM-plus.feature-localWorld/etc/bashrc
. $WM_PROJECT_DIR/etc/bashrc
#cd /home/mattijs/OpenFOAM/OpenFOAM-plus.feature-localWorld/applications/test/multiWorld/chtMultiRegionSimpleFoam
chtMultiRegionSimpleFoam -case ./fluid -world fluid 2>&1 | tee run_fluid.log
read dummy

View File

@ -0,0 +1,6 @@
#!/bin/bash
. $WM_PROJECT_DIR/etc/bashrc
#. /home/mattijs/OpenFOAM/OpenFOAM-plus.feature-localWorld/etc/bashrc
#cd /home/mattijs/OpenFOAM/OpenFOAM-plus.feature-localWorld/applications/test/multiWorld/chtMultiRegionSimpleFoam
chtMultiRegionSimpleFoam -case ./solid -world solid 2>&1 | tee run_solid.log
read dummy

View File

@ -0,0 +1,53 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: plus |
| \\ / A nd | Web: www.OpenFOAM.com |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class volScalarField;
location "0/leftSolid";
object T;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
dimensions [ 0 0 0 1 0 0 0 ];
internalField uniform 300;
boundaryField
{
#includeEtc "caseDicts/setConstraintTypes"
left
{
type zeroGradient;
value $internalField;
}
right
{
type zeroGradient;
value $internalField;
}
bottom
{
//type zeroGradient;
//value $internalField;
type uniformFixedValue;
uniformValue 270;
}
top
{
type compressible::turbulentTemperatureCoupledBaffle2Mixed;
value $internalField;
Tnbr T;
kappaMethod solidThermo;
}
}
// ************************************************************************* //

View File

@ -0,0 +1,50 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: plus |
| \\ / A nd | Web: www.OpenFOAM.com |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class volScalarField;
location "0/leftSolid";
object p;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
dimensions [1 -1 -2 0 0 0 0];
internalField uniform 100000;
boundaryField
{
#includeEtc "caseDicts/setConstraintTypes"
left
{
type calculated;
value $internalField;
}
right
{
type calculated;
value $internalField;
}
top
{
type calculated;
value $internalField;
}
bottom
{
type calculated;
value $internalField;
}
}
// ************************************************************************* //

View File

@ -0,0 +1,23 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: v1906 |
| \\ / A nd | Web: www.OpenFOAM.com |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class dictionary;
location "constant";
object radiationProperties;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
radiation off;
radiationModel none;
// ************************************************************************* //

View File

@ -0,0 +1,52 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: v1906 |
| \\ / A nd | Web: www.OpenFOAM.com |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class dictionary;
object thermophysicalProperties;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
thermoType
{
type heSolidThermo;
mixture pureMixture;
transport constIso;
thermo hConst;
equationOfState rhoConst;
specie specie;
energy sensibleEnthalpy;
}
mixture
{
specie
{
molWeight 50;
}
transport
{
kappa 80;
}
thermodynamics
{
Hf 0;
Cp 450;
}
equationOfState
{
rho 8000;
}
}
// ************************************************************************* //

View File

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

View File

@ -0,0 +1,24 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: v1906 |
| \\ / A nd | Web: www.OpenFOAM.com |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class dictionary;
location "constant";
object regionProperties;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
regions
(
fluid ()
solid (bottomSolid)
);
// ************************************************************************* //

View File

@ -0,0 +1,96 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: v1906 |
| \\ / A nd | Web: www.OpenFOAM.com |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class dictionary;
object blockMeshDict;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
scale 1;
vertices
(
(-0.1 -0.04 -0.05)
( 0.1 -0.04 -0.05)
( 0.1 0.00 -0.05)
(-0.1 0.00 -0.05)
(-0.1 -0.04 0.05)
( 0.1 -0.04 0.05)
( 0.1 0.00 0.05)
(-0.1 0.00 0.05)
);
blocks
(
hex (0 1 2 3 4 5 6 7) (20 10 1) simpleGrading (1 1 1)
);
edges
(
);
boundary
(
bottom
{
type wall;
faces
(
(1 5 4 0)
);
}
top
{
type mappedWall;
inGroups 1 ( wall );
sampleMode nearestPatchFace;
sampleWorld fluid;
sampleRegion topAir;
samplePatch bottom;
faces
(
(3 7 6 2)
);
}
left
{
type wall;
faces
(
(0 4 7 3)
);
}
right
{
type wall;
faces
(
(2 6 5 1)
);
}
frontAndBack
{
type empty;
faces
(
(0 3 2 1)
(4 5 6 7)
);
}
);
mergePatchPairs
(
);
// ************************************************************************* //

View File

@ -0,0 +1,50 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: v1906 |
| \\ / A nd | Web: www.OpenFOAM.com |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class dictionary;
object fvSchemes;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
ddtSchemes
{
//default Euler;
default steadyState;
}
gradSchemes
{
default Gauss linear;
}
divSchemes
{
default none;
}
laplacianSchemes
{
default none;
laplacian(alpha,h) Gauss linear corrected;
}
interpolationSchemes
{
default linear;
}
snGradSchemes
{
default corrected;
}
// ************************************************************************* //

View File

@ -0,0 +1,53 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: v1906 |
| \\ / A nd | Web: www.OpenFOAM.com |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class dictionary;
object fvSolution;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
solvers
{
h
{
solver PCG;
preconditioner DIC;
tolerance 1e-06;
relTol 0.1;
}
hFinal
{
$h;
tolerance 1e-06;
relTol 0;
}
}
//PIMPLE
//{
// nNonOrthogonalCorrectors 0;
//}
SIMPLE
{
nNonOrthogonalCorrectors 0;
}
relaxationFactors
{
equations
{
h 0.7;
}
}
// ************************************************************************* //

View File

@ -0,0 +1,66 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: v1906 |
| \\ / A nd | Web: www.OpenFOAM.com |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class dictionary;
location "system";
object controlDict;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
DebugSwitches
{
//UPstream 1;
mappedPatchBase 1;
}
application chtMultiRegionFoam;
startFrom startTime;
startTime 0;
stopAt endTime;
endTime 1;
deltaT 0.001;
writeControl adjustable;
writeInterval 0.1;
purgeWrite 0;
writeFormat ascii;
writePrecision 8;
writeCompression off;
timeFormat general;
timePrecision 6;
runTimeModifiable yes;
maxCo 0.6;
// Maximum diffusion number
maxDi 10.0;
adjustTimeStep yes;
//functions
//{
// #include "vtkWrite"
//}
// ************************************************************************* //

View File

@ -0,0 +1,54 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: v1906 |
| \\ / A nd | Web: www.OpenFOAM.com |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class dictionary;
object decomposeParDict;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
numberOfSubdomains 4;
method scotch;
// method hierarchical;
// method simple;
regions
{
heater
{
numberOfSubdomains 1;
method simple; // none;
coeffs
{
n (1 1 1);
}
}
}
coeffs
{
n (2 2 1);
}
/*
constraints
{
//- Keep owner and neighbour on same processor for faces in zones:
faces
{
type preserveFaceZones;
zones (heater solid1 solid3);
}
}
*/
// ************************************************************************* //

View File

@ -0,0 +1,57 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: v1906 |
| \\ / A nd | Web: www.OpenFOAM.com |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class dictionary;
object fvSchemes;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
ddtSchemes
{
default Euler;
}
gradSchemes
{
default Gauss linear;
}
divSchemes
{
default none;
div(phi,U) Gauss upwind;
div(phi,K) Gauss linear;
div(phi,h) Gauss upwind;
div(phi,k) Gauss upwind;
div(phi,epsilon) Gauss upwind;
div(phi,R) Gauss upwind;
div(R) Gauss linear;
div(((rho*nuEff)*dev2(T(grad(U))))) Gauss linear;
}
laplacianSchemes
{
default Gauss linear corrected;
}
interpolationSchemes
{
default linear;
}
snGradSchemes
{
default corrected;
}
// ************************************************************************* //

View File

@ -0,0 +1,83 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: v1906 |
| \\ / A nd | Web: www.OpenFOAM.com |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class dictionary;
object fvSolution;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
solvers
{
rho
{
solver PCG;
preconditioner DIC;
tolerance 1e-7;
relTol 0.1;
}
rhoFinal
{
$rho;
tolerance 1e-7;
relTol 0;
}
p_rgh
{
solver GAMG;
tolerance 1e-7;
relTol 0.01;
smoother GaussSeidel;
}
p_rghFinal
{
$p_rgh;
tolerance 1e-7;
relTol 0;
}
"(U|h|k|epsilon|R)"
{
solver PBiCGStab;
preconditioner DILU;
tolerance 1e-7;
relTol 0.1;
}
"(U|h|k|epsilon|R)Final"
{
$U;
tolerance 1e-7;
relTol 0;
}
}
PIMPLE
{
momentumPredictor yes;
nCorrectors 2;
nNonOrthogonalCorrectors 0;
}
relaxationFactors
{
equations
{
"h.*" 1;
"U.*" 1;
}
}
// ************************************************************************* //

View File

@ -0,0 +1,61 @@
// -*- C++ -*-
// Use the vtkWrite function object
vtkWrite
{
type vtkWrite;
libs (utilityFunctionObjects);
log true;
writeControl writeTime;
writeInterval 1;
regions (".*");
internal true;
boundary true;
single false;
interpolate true;
// Fields to output (words or regex)
fields (".*");
//- Output format (ascii | binary) - Default=binary
// format binary;
//- Use legacy output format - Default=false
// legacy false;
//- Output directory name - Default="postProcessing/<name>"
// directory "VTK";
//- Write cell ids as field - Default=true
writeIds false;
}
// Solid walls only
walls
{
type vtkWrite;
libs (utilityFunctionObjects);
log true;
writeControl writeTime;
writeInterval 1;
internal false;
// single true;
regions ( heater "(?i).*solid" );
patches ( "(?i).*solid_to.*" "heater.*(Air|Water)" );
fields (T);
}
// ************************************************************************* //

View File

@ -0,0 +1,80 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: v1906 |
| \\ / A nd | Web: www.OpenFOAM.com |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class volScalarField;
object T;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
dimensions [0 0 0 1 0 0 0];
internalField uniform 1;
boundaryField
{
coupled
{
//type mappedField;
type mappedMixedField;
// What to sample:
sampleMode nearestPatchFace;
// Simulation world to sample
sampleWorld RIGHT;
// Region to sample
sampleRegion region0;
// If sampleMode is nearestPatchFace : patch to find faces of
samplePatch coupled;
// Use database to get data from (one-way or loose coupling in
// combination with functionObject)
//sampleDatabase false; //true;
// According to offsetMode (see above) supply one of
// offset, offsets or distance
offset (0 0 0);
value uniform 0.0;
// For mappedMixed
//weightField DTV;
refValue $value;
refGradient uniform 0.0;
valueFraction uniform 1.0;
}
top
{
type zeroGradient;
}
bottom
{
type zeroGradient;
}
left
{
type fixedValue;
value uniform 1;
}
frontAndBack
{
type empty;
}
}
// ************************************************************************* //

View File

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

View File

@ -0,0 +1,90 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: v1906 |
| \\ / A nd | Web: www.OpenFOAM.com |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class dictionary;
object blockMeshDict;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
scale 0.1;
vertices
(
(0 0 0)
(0.5 0 0)
(0.5 1 0)
(0 1 0)
(0 0 0.1)
(0.5 0 0.1)
(0.5 1 0.1)
(0 1 0.1)
);
blocks
(
hex (0 1 2 3 4 5 6 7) (2 2 1) simpleGrading (1 1 1)
);
edges
(
);
boundary
(
coupled
{
type wall;
faces
(
(2 6 5 1)
);
}
top
{
type wall;
faces
(
(3 7 6 2)
);
}
bottom
{
type wall;
faces
(
(1 5 4 0)
);
}
left
{
type wall;
faces
(
(0 4 7 3)
);
}
frontAndBack
{
type empty;
faces
(
(0 3 2 1)
(4 5 6 7)
);
}
);
mergePatchPairs
(
);
// ************************************************************************* //

View File

@ -0,0 +1,75 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: v1906 |
| \\ / A nd | Web: www.OpenFOAM.com |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class dictionary;
location "system";
object controlDict;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
libs (utilityFunctionObjects);
DebugSwitches
{
// mappedPatchBase 1;
// syncObjects 1;
}
application laplacianFoam;
startFrom startTime; //latestTime;
startTime 0;
stopAt endTime;
endTime 50;
deltaT 1;
//writeControl runTime;
//writeInterval 0.1;
writeControl timeStep;
writeInterval 1;
purgeWrite 0;
writeFormat ascii;
writePrecision 6;
writeCompression off;
timeFormat general;
timePrecision 6;
runTimeModifiable true;
functions
{
syncObjects
{
type syncObjects;
libs (utilityFunctionObjects);
// Where is data located relative to runTime. Given as a filename
// with every '/' indicating a sub-objectRegistry w.r.t. runTime.
// Local data is under <root>/send/processorXXX. After execution
// data will be under the corresponding <root>/receive/processorYYY
// objectRegistry
//root "level0/level1/level2";
}
}
// ************************************************************************* //

View File

@ -0,0 +1,25 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: v1906 |
| \\ / A nd | Web: www.OpenFOAM.com |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class dictionary;
note "mesh decomposition control dictionary";
object decomposeParDict;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
//- The total number of domains (mandatory)
numberOfSubdomains 2;
//- The decomposition method (mandatory)
method hierarchical;
n (2 1 1);
// ************************************************************************* //

View File

@ -0,0 +1,52 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: v1906 |
| \\ / A nd | Web: www.OpenFOAM.com |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class dictionary;
location "system";
object fvSchemes;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
ddtSchemes
{
default steadyState; //Euler;
}
gradSchemes
{
default Gauss linear;
grad(T) Gauss linear;
}
divSchemes
{
default none;
}
laplacianSchemes
{
default none;
laplacian(DT,T) Gauss linear corrected;
laplacian(DTV,T) Gauss linear corrected;
}
interpolationSchemes
{
default linear;
}
snGradSchemes
{
default corrected;
}
// ************************************************************************* //

View File

@ -0,0 +1,35 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: v1906 |
| \\ / A nd | Web: www.OpenFOAM.com |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class dictionary;
location "system";
object fvSolution;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
solvers
{
T
{
solver PCG;
preconditioner DIC;
tolerance 1e-06;
relTol 0;
}
}
SIMPLE
{
nNonOrthogonalCorrectors 2;
}
// ************************************************************************* //

View File

@ -0,0 +1,7 @@
-np 2 laplacianFoam -case ./left -world LEFT -parallel
-np 2 laplacianFoam -case ./right -world RIGHT -parallel
#-np 1 xterm -font fixed -title processor0 -geometry 200x15+0+0 -e /home/mattijs/OpenFOAM/OpenFOAM-plus.feature-localWorld/applications/test/multiWorld/processor0.sh
#-np 1 xterm -font fixed -title processor1 -geometry 200x15+0+200 -e /home/mattijs/OpenFOAM/OpenFOAM-plus.feature-localWorld/applications/test/multiWorld/processor1.sh
#-np 1 xterm -font fixed -title processor2 -geometry 200x15+0+400 -e /home/mattijs/OpenFOAM/OpenFOAM-plus.feature-localWorld/applications/test/multiWorld/processor2.sh
#-np 1 xterm -font fixed -title processor3 -geometry 200x15+0+600 -e /home/mattijs/OpenFOAM/OpenFOAM-plus.feature-localWorld/applications/test/multiWorld/processor3.sh

View File

@ -0,0 +1,2 @@
-np 1 xterm -font fixed -title processor0 -geometry 200x15+0+0 -e ./run_left.sh
-np 1 xterm -font fixed -title processor1 -geometry 200x15+0+200 -e ./run_right.sh

View File

@ -0,0 +1,79 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: v1906 |
| \\ / A nd | Web: www.OpenFOAM.com |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class volScalarField;
object T;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
dimensions [0 0 0 1 0 0 0];
internalField uniform 0;
boundaryField
{
coupled
{
//type mappedField;
type mappedMixedField;
// What to sample:
sampleMode nearestPatchFace;
// Simulation world to sample
sampleWorld LEFT;
// Region to sample
sampleRegion region0;
// If sampleMode is nearestPatchFace : patch to find faces of
samplePatch coupled;
// Use database to get data from (one-way or loose coupling in
// combination with functionObject)
//sampleDatabase false; //true;
// According to offsetMode (see above) supply one of
// offset, offsets or distance
offset (0 0 0);
value uniform 1.1;
// For mappedMixed
//weightField DTV;
refValue $value;
refGradient uniform 0.0;
valueFraction uniform 1.0;
}
top
{
type zeroGradient;
}
bottom
{
type zeroGradient;
}
right
{
type fixedValue;
value uniform 0;
}
frontAndBack
{
type empty;
}
}
// ************************************************************************* //

View File

@ -0,0 +1 @@
../../left/constant/transportProperties

View File

@ -0,0 +1,89 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: v1906 |
| \\ / A nd | Web: www.OpenFOAM.com |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class dictionary;
object blockMeshDict;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
scale 0.1;
vertices
(
(0.5 0 0)
(1 0 0)
(1 1 0)
(0.5 1 0)
(0.5 0 0.1)
(1 0 0.1)
(1 1 0.1)
(0.5 1 0.1)
);
blocks
(
hex (0 1 2 3 4 5 6 7) (2 2 1) simpleGrading (1 1 1)
);
edges
(
);
boundary
(
coupled
{
type wall;
faces
(
(0 4 7 3)
);
}
top
{
type wall;
faces
(
(3 7 6 2)
);
}
bottom
{
type wall;
faces
(
(1 5 4 0)
);
}
right
{
type wall;
faces
(
(2 6 5 1)
);
}
frontAndBack
{
type empty;
faces
(
(0 3 2 1)
(4 5 6 7)
);
}
);
mergePatchPairs
(
);
// ************************************************************************* //

View File

@ -0,0 +1 @@
../../left/system/controlDict

View File

@ -0,0 +1 @@
../../left/system/decomposeParDict

View File

@ -0,0 +1 @@
../../left/system/fvSchemes

View File

@ -0,0 +1 @@
../../left/system/fvSolution

View File

@ -0,0 +1,3 @@
#!/bin/bash
laplacianFoam -case ./left -world LEFT 2>&1 | tee log.run_left
read dummy

View File

@ -0,0 +1,3 @@
#!/bin/bash
laplacianFoam -case ./right -world RIGHT 2>&1 | tee log.run_right
read dummy

View File

@ -511,9 +511,9 @@ void writeProcAddressing
patchDistMap.constructMap(),
patchDistMap.constructHasFlip(),
patchMap,
label(-1),
eqOp<label>(),
flipOp(),
label(-1),
UPstream::msgType()
);
}

View File

@ -90,8 +90,8 @@ void Foam::UPstream::setParRun(const label nProcs, const bool haveThreads)
<< Foam::exit(FatalError);
}
Pout.prefix() = '[' + name(myProcNo(Pstream::worldComm)) + "] ";
Perr.prefix() = '[' + name(myProcNo(Pstream::worldComm)) + "] ";
Pout.prefix() = '[' + name(myProcNo(comm)) + "] ";
Perr.prefix() = '[' + name(myProcNo(comm)) + "] ";
}
}
@ -373,6 +373,8 @@ Foam::DynamicList<Foam::List<int>> Foam::UPstream::procIDs_(10);
Foam::DynamicList<Foam::label> Foam::UPstream::parentCommunicator_(10);
Foam::wordList Foam::UPstream::allWorlds_(1, "");
Foam::labelList Foam::UPstream::worldIDs_(1, 0);
Foam::DynamicList<Foam::List<Foam::UPstream::commsStruct>>
Foam::UPstream::linearCommunication_(10);

View File

@ -194,6 +194,13 @@ private:
//- Standard transfer message type
static int msgType_;
//- Names of all worlds
static wordList allWorlds_;
//- Per processor the name of the world
static labelList worldIDs_;
// Communicator specific data
//- Free communicators
@ -437,7 +444,7 @@ public:
}
//- Number of processes in parallel run, and 1 for serial run
static label nProcs(const label communicator = 0)
static label nProcs(const label communicator = worldComm)
{
return procIDs_[communicator].size();
}
@ -449,13 +456,13 @@ public:
}
//- Am I the master process
static bool master(const label communicator = 0)
static bool master(const label communicator = worldComm)
{
return myProcNo_[communicator] == masterNo();
}
//- Number of this process (starting from masterNo() = 0)
static int myProcNo(const label communicator = 0)
static int myProcNo(const label communicator = worldComm)
{
return myProcNo_[communicator];
}
@ -471,15 +478,43 @@ public:
return procIDs_[communicator];
}
// Worlds
//- All worlds
static const wordList& allWorlds()
{
return allWorlds_;
}
//- worldID (index in allWorlds) of all processes
static const labelList& worldIDs()
{
return worldIDs_;
}
//- My worldID
static label myWorldID()
{
return worldIDs_[myProcNo(0)];
}
//- My world
static const word& myWorld()
{
return allWorlds()[myWorldID()];
}
//- Range of process indices for all processes
static rangeType allProcs(const label communicator = 0)
static rangeType allProcs(const label communicator = worldComm)
{
// Proc 0 -> nProcs (int value)
return rangeType(static_cast<int>(nProcs(communicator)));
}
//- Range of process indices for sub-processes
static rangeType subProcs(const label communicator = 0)
static rangeType subProcs(const label communicator = worldComm)
{
// Proc 1 -> nProcs (int value)
return rangeType(1, static_cast<int>(nProcs(communicator)-1));
@ -488,7 +523,7 @@ public:
//- Communication schedule for linear all-to-master (proc 0)
static const List<commsStruct>& linearCommunication
(
const label communicator = 0
const label communicator = worldComm
)
{
return linearCommunication_[communicator];
@ -497,7 +532,7 @@ public:
//- Communication schedule for tree all-to-master (proc 0)
static const List<commsStruct>& treeCommunication
(
const label communicator = 0
const label communicator = worldComm
)
{
return treeCommunication_[communicator];
@ -542,7 +577,7 @@ public:
(
const labelUList& sendData,
labelUList& recvData,
const label communicator = 0
const label communicator = worldComm
);
//- Exchange data with all processors (in the communicator)
@ -559,7 +594,7 @@ public:
const UList<int>& recvSizes,
const UList<int>& recvOffsets,
const label communicator = 0
const label communicator = worldComm
);
//- Receive data from all processors on the master
@ -571,7 +606,7 @@ public:
char* recvData,
const UList<int>& recvSizes,
const UList<int>& recvOffsets,
const label communicator = 0
const label communicator = worldComm
);
//- Send data to all processors from the root of the communicator
@ -583,7 +618,7 @@ public:
char* recvData,
int recvSize,
const label communicator = 0
const label communicator = worldComm
);
@ -598,7 +633,7 @@ public:
//- Process index of last sub-process
// \deprecated(2020-09) use subProcs() method instead
static int lastSlave(const label communicator = 0)
static int lastSlave(const label communicator = worldComm)
{
return nProcs(communicator) - 1;
}

View File

@ -166,6 +166,20 @@ Foam::argList::initValidTables::initValidTables()
true // advanced option
);
argList::addOption
(
"world",
"Name",
"Name of local world",
true
);
validParOptions.set
(
"world",
"Name of local world"
);
// Some standard option aliases (with or without version warnings)
// argList::addOptionCompat
// (
@ -493,6 +507,7 @@ void Foam::argList::noParallel()
removeOption("roots");
removeOption("decomposeParDict");
removeOption("hostRoots");
removeOption("world");
validParOptions.clear();
}
@ -711,6 +726,7 @@ void Foam::argList::setCasePaths()
}
else
{
caseDir.expand();
caseDir.toAbsolute();
}
}
@ -1241,7 +1257,7 @@ void Foam::argList::parse
dictNProcs = roots.size()+1;
}
}
else if (checkProcessorDirectories_)
else if (checkProcessorDirectories_ && Pstream::nProcs() > 1)
{
// Use values from decomposeParDict, the location was already
// established above.
@ -1268,6 +1284,13 @@ void Foam::argList::parse
Pstream::parRun(oldParRun); // Restore parallel state
decompDict.readEntry("numberOfSubdomains", dictNProcs);
if (Pstream::nProcs() == 1)
{
WarningInFunction
<< "Running parallel on single processor. This only"
<< " makes sense for multi-world simulation" << endl;
dictNProcs = 1;
}
if (decompDict.getOrDefault("distributed", false))
{
@ -1300,7 +1323,12 @@ void Foam::argList::parse
// - normal running : nProcs = dictNProcs = nProcDirs
// - decomposition to more processors : nProcs = dictNProcs
// - decomposition to fewer processors : nProcs = nProcDirs
if (checkProcessorDirectories_ && dictNProcs > Pstream::nProcs())
if
(
checkProcessorDirectories_
&& Pstream::nProcs() > 1
&& dictNProcs > Pstream::nProcs()
)
{
FatalError
<< source
@ -1353,6 +1381,7 @@ void Foam::argList::parse
if
(
checkProcessorDirectories_
&& Pstream::nProcs() > 1
&& dictNProcs < Pstream::nProcs()
)
{
@ -1405,7 +1434,14 @@ void Foam::argList::parse
}
nProcs = Pstream::nProcs();
case_ = globalCase_/("processor" + Foam::name(Pstream::myProcNo()));
if (Pstream::nProcs() > 1)
{
case_ = globalCase_/("processor" + Foam::name(Pstream::myProcNo()));
}
else
{
case_ = globalCase_;
}
}
else
{
@ -1468,6 +1504,13 @@ void Foam::argList::parse
<< Pstream::commsTypeNames[Pstream::defaultCommsType] << nl
<< " polling iterations : " << Pstream::nPollProcInterfaces
<< endl;
if (UPstream::allWorlds().size() > 1)
{
Info<< " worlds : "
<< flatOutput(UPstream::allWorlds()) << nl
<< " world : " << UPstream::myWorld()
<< endl;
}
}
}

View File

@ -93,7 +93,7 @@ inline Foam::label Foam::globalIndex::size() const
inline void Foam::globalIndex::reset(const label localSize)
{
reset(localSize, Pstream::msgType(), 0, true);
reset(localSize, Pstream::msgType(), UPstream::worldComm, true);
}

View File

@ -2745,13 +2745,16 @@ void Foam::globalMeshData::updateMesh()
// *** Temporary hack to avoid problems with overlapping communication
// *** between these reductions and the calculation of deltaCoeffs
//label comm = UPstream::worldComm + 1;
label comm = UPstream::allocateCommunicator
//const label comm = UPstream::worldComm + 1;
const label comm = UPstream::allocateCommunicator
(
UPstream::worldComm,
identity(UPstream::nProcs(UPstream::worldComm)),
true
);
const label oldWarnComm = UPstream::warnComm;
UPstream::warnComm = comm;
// Total number of faces.
nTotalFaces_ = returnReduce
@ -2789,6 +2792,7 @@ void Foam::globalMeshData::updateMesh()
);
UPstream::freeCommunicator(comm);
UPstream::warnComm = oldWarnComm;
if (debug)
{

View File

@ -148,9 +148,9 @@ void Foam::mapDistribute::printLayout(Ostream& os) const
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::mapDistribute::mapDistribute()
Foam::mapDistribute::mapDistribute(const label comm)
:
mapDistributeBase()
mapDistributeBase(comm)
{}
@ -176,7 +176,8 @@ Foam::mapDistribute::mapDistribute
labelListList&& subMap,
labelListList&& constructMap,
const bool subHasFlip,
const bool constructHasFlip
const bool constructHasFlip,
const label comm
)
:
mapDistributeBase
@ -185,7 +186,8 @@ Foam::mapDistribute::mapDistribute
std::move(subMap),
std::move(constructMap),
subHasFlip,
constructHasFlip
constructHasFlip,
comm
)
{}
@ -198,7 +200,8 @@ Foam::mapDistribute::mapDistribute
labelListList&& transformElements,
labelList&& transformStart,
const bool subHasFlip,
const bool constructHasFlip
const bool constructHasFlip,
const label comm
)
:
mapDistributeBase
@ -207,7 +210,8 @@ Foam::mapDistribute::mapDistribute
std::move(subMap),
std::move(constructMap),
subHasFlip,
constructHasFlip
constructHasFlip,
comm
),
transformElements_(std::move(transformElements)),
transformStart_(std::move(transformStart))
@ -217,10 +221,11 @@ Foam::mapDistribute::mapDistribute
Foam::mapDistribute::mapDistribute
(
const labelUList& sendProcs,
const labelUList& recvProcs
const labelUList& recvProcs,
const label comm
)
:
mapDistributeBase(sendProcs, recvProcs)
mapDistributeBase(sendProcs, recvProcs, comm)
{}
@ -229,7 +234,8 @@ Foam::mapDistribute::mapDistribute
const globalIndex& globalNumbering,
labelList& elements,
List<Map<label>>& compactMap,
const int tag
const int tag,
const label comm
)
:
mapDistributeBase
@ -237,7 +243,8 @@ Foam::mapDistribute::mapDistribute
globalNumbering,
elements,
compactMap,
tag
tag,
comm
)
{}
@ -247,7 +254,8 @@ Foam::mapDistribute::mapDistribute
const globalIndex& globalNumbering,
labelListList& cellCells,
List<Map<label>>& compactMap,
const int tag
const int tag,
const label comm
)
:
mapDistributeBase
@ -255,7 +263,8 @@ Foam::mapDistribute::mapDistribute
globalNumbering,
cellCells,
compactMap,
tag
tag,
comm
)
{}
@ -268,11 +277,14 @@ Foam::mapDistribute::mapDistribute
const labelPairList& transformedElements,
labelList& transformedIndices,
List<Map<label>>& compactMap,
const int tag
const int tag,
const label comm
)
:
mapDistributeBase()
mapDistributeBase(comm)
{
const label myRank = Pstream::myProcNo(comm);
// Construct per processor compact addressing of the global elements
// needed. The ones from the local processor are not included since
// these are always all needed.
@ -288,7 +300,7 @@ Foam::mapDistribute::mapDistribute
{
labelPair elem = transformedElements[i];
label proci = globalTransforms.processor(elem);
if (proci != Pstream::myProcNo())
if (proci != myRank)
{
label index = globalTransforms.index(elem);
label nCompact = compactMap[proci].size();
@ -345,7 +357,7 @@ Foam::mapDistribute::mapDistribute
// Get compact index for untransformed element
label rawElemI =
(
proci == Pstream::myProcNo()
proci == myRank
? index
: compactMap[proci][index]
);
@ -373,11 +385,14 @@ Foam::mapDistribute::mapDistribute
const List<labelPairList>& transformedElements,
labelListList& transformedIndices,
List<Map<label>>& compactMap,
const int tag
const int tag,
const label comm
)
:
mapDistributeBase()
mapDistributeBase(comm)
{
const label myRank = Pstream::myProcNo(comm_);
// Construct per processor compact addressing of the global elements
// needed. The ones from the local processor are not included since
// these are always all needed.
@ -396,7 +411,7 @@ Foam::mapDistribute::mapDistribute
forAll(elems, i)
{
label proci = globalTransforms.processor(elems[i]);
if (proci != Pstream::myProcNo())
if (proci != myRank)
{
label index = globalTransforms.index(elems[i]);
label nCompact = compactMap[proci].size();
@ -462,7 +477,7 @@ Foam::mapDistribute::mapDistribute
// Get compact index for untransformed element
label rawElemI =
(
proci == Pstream::myProcNo()
proci == myRank
? index
: compactMap[proci][index]
);
@ -487,10 +502,11 @@ Foam::mapDistribute::mapDistribute
(
labelListList&& subMap,
const bool subHasFlip,
const bool constructHasFlip
const bool constructHasFlip,
const label comm
)
:
mapDistributeBase(std::move(subMap), subHasFlip, constructHasFlip)
mapDistributeBase(std::move(subMap), subHasFlip, constructHasFlip, comm)
{}

View File

@ -328,7 +328,7 @@ public:
// Constructors
//- Construct null
mapDistribute();
mapDistribute(const label comm = UPstream::worldComm);
//- Copy construct
explicit mapDistribute(const mapDistribute& map);
@ -343,7 +343,8 @@ public:
labelListList&& subMap,
labelListList&& constructMap,
const bool subHasFlip = false,
const bool constructHasFlip = false
const bool constructHasFlip = false,
const label comm = UPstream::worldComm
);
//- Move construct from components
@ -355,7 +356,8 @@ public:
labelListList&& transformElements,
labelList&& transformStart,
const bool subHasFlip = false,
const bool constructHasFlip = false
const bool constructHasFlip = false,
const label comm = UPstream::worldComm
);
//- Construct from reverse addressing: per data item the send
@ -365,7 +367,8 @@ public:
mapDistribute
(
const labelUList& sendProcs,
const labelUList& recvProcs
const labelUList& recvProcs,
const label comm = UPstream::worldComm
);
//- Construct from list of (possibly) remote elements in globalIndex
@ -378,7 +381,8 @@ public:
const globalIndex&,
labelList& elements,
List<Map<label>>& compactMap,
const int tag = Pstream::msgType()
const int tag = Pstream::msgType(),
const label comm = UPstream::worldComm
);
//- Special variant that works with the info sorted into bins
@ -390,7 +394,8 @@ public:
const globalIndex&,
labelListList& cellCells,
List<Map<label>>& compactMap,
const int tag = Pstream::msgType()
const int tag = Pstream::msgType(),
const label comm = UPstream::worldComm
);
//- Construct from list of (possibly remote) untransformed elements
@ -407,7 +412,8 @@ public:
const labelPairList& transformedElements,
labelList& transformedIndices,
List<Map<label>>& compactMap,
const int tag = Pstream::msgType()
const int tag = Pstream::msgType(),
const label comm = UPstream::worldComm
);
//- As above but with ListLists.
@ -419,7 +425,8 @@ public:
const List<labelPairList>& transformedElements,
labelListList& transformedIndices,
List<Map<label>>& compactMap,
const int tag = Pstream::msgType()
const int tag = Pstream::msgType(),
const label comm = UPstream::worldComm
);
//- Construct from my elements to send. Assumes layout is my elements
@ -429,7 +436,8 @@ public:
(
labelListList&& subMap,
const bool subHasFlip = false,
const bool constructHasFlip = false
const bool constructHasFlip = false,
const label comm = UPstream::worldComm
);
//- Construct from Istream

View File

@ -46,29 +46,33 @@ Foam::List<Foam::labelPair> Foam::mapDistributeBase::schedule
(
const labelListList& subMap,
const labelListList& constructMap,
const int tag
const int tag,
const label comm
)
{
const label myRank = Pstream::myProcNo(comm);
const label nProcs = Pstream::nProcs(comm);
// Communications: send and receive processor
List<labelPair> allComms;
{
labelPairHashSet commsSet(Pstream::nProcs());
labelPairHashSet commsSet(nProcs);
// Find what communication is required
forAll(subMap, proci)
{
if (proci != Pstream::myProcNo())
if (proci != myRank)
{
if (subMap[proci].size())
{
// I need to send to proci
commsSet.insert(labelPair(Pstream::myProcNo(), proci));
commsSet.insert(labelPair(myRank, proci));
}
if (constructMap[proci].size())
{
// I need to receive from proci
commsSet.insert(labelPair(proci, Pstream::myProcNo()));
commsSet.insert(labelPair(proci, myRank));
}
}
}
@ -77,12 +81,19 @@ Foam::List<Foam::labelPair> Foam::mapDistributeBase::schedule
// Reduce
if (Pstream::master())
if (Pstream::master(comm))
{
// Receive and merge
for (const int slave : Pstream::subProcs())
for (const int slave : Pstream::subProcs(comm))
{
IPstream fromSlave(Pstream::commsTypes::scheduled, slave, 0, tag);
IPstream fromSlave
(
Pstream::commsTypes::scheduled,
slave,
0,
tag,
comm
);
List<labelPair> nbrData(fromSlave);
forAll(nbrData, i)
@ -96,9 +107,16 @@ Foam::List<Foam::labelPair> Foam::mapDistributeBase::schedule
}
}
// Send back
for (const int slave : Pstream::subProcs())
for (const int slave : Pstream::subProcs(comm))
{
OPstream toSlave(Pstream::commsTypes::scheduled, slave, 0, tag);
OPstream toSlave
(
Pstream::commsTypes::scheduled,
slave,
0,
tag,
comm
);
toSlave << allComms;
}
}
@ -110,7 +128,8 @@ Foam::List<Foam::labelPair> Foam::mapDistributeBase::schedule
Pstream::commsTypes::scheduled,
Pstream::masterNo(),
0,
tag
tag,
comm
);
toMaster << allComms;
}
@ -120,7 +139,8 @@ Foam::List<Foam::labelPair> Foam::mapDistributeBase::schedule
Pstream::commsTypes::scheduled,
Pstream::masterNo(),
0,
tag
tag,
comm
);
fromMaster >> allComms;
}
@ -132,9 +152,9 @@ Foam::List<Foam::labelPair> Foam::mapDistributeBase::schedule
(
commSchedule
(
Pstream::nProcs(),
nProcs,
allComms
).procSchedule()[Pstream::myProcNo()]
).procSchedule()[myRank]
);
// Processors involved in my schedule
@ -151,7 +171,7 @@ Foam::List<Foam::labelPair> Foam::mapDistributeBase::schedule
// label sendProc = twoProcs[0];
// label recvProc = twoProcs[1];
//
// if (recvProc == Pstream::myProcNo())
// if (recvProc == myRank)
// {
// Pout<< " receive from " << sendProc << endl;
// }
@ -172,7 +192,7 @@ const Foam::List<Foam::labelPair>& Foam::mapDistributeBase::schedule() const
(
new List<labelPair>
(
schedule(subMap_, constructMap_, Pstream::msgType())
schedule(subMap_, constructMap_, Pstream::msgType(), comm_)
)
);
}
@ -200,9 +220,12 @@ void Foam::mapDistributeBase::checkReceivedSize
void Foam::mapDistributeBase::printLayout(Ostream& os) const
{
const label myRank = Pstream::myProcNo(comm_);
const label nProcs = Pstream::nProcs(comm_);
// Determine offsets of remote data.
labelList minIndex(Pstream::nProcs(), labelMax);
labelList maxIndex(Pstream::nProcs(), labelMin);
labelList minIndex(nProcs, labelMax);
labelList maxIndex(nProcs, labelMin);
forAll(constructMap_, proci)
{
const labelList& construct = constructMap_[proci];
@ -227,27 +250,27 @@ void Foam::mapDistributeBase::printLayout(Ostream& os) const
}
label localSize;
if (maxIndex[Pstream::myProcNo()] == labelMin)
if (maxIndex[myRank] == labelMin)
{
localSize = 0;
}
else
{
localSize = maxIndex[Pstream::myProcNo()]+1;
localSize = maxIndex[myRank]+1;
}
os << "Layout: (constructSize:" << constructSize_
<< " subHasFlip:" << subHasFlip_
<< " constructHasFlip:" << constructHasFlip_
<< ")" << endl
<< "local (processor " << Pstream::myProcNo() << "):" << endl
<< "local (processor " << myRank << "):" << endl
<< " start : 0" << endl
<< " size : " << localSize << endl;
label offset = localSize;
forAll(minIndex, proci)
{
if (proci != Pstream::myProcNo())
if (proci != myRank)
{
if (constructMap_[proci].size() > 0)
{
@ -279,10 +302,13 @@ void Foam::mapDistributeBase::calcCompactAddressing
List<Map<label>>& compactMap
) const
{
compactMap.setSize(Pstream::nProcs());
const label myRank = Pstream::myProcNo(comm_);
const label nProcs = Pstream::nProcs(comm_);
compactMap.setSize(nProcs);
// Count all (non-local) elements needed. Just for presizing map.
labelList nNonLocal(Pstream::nProcs(), Zero);
labelList nNonLocal(nProcs, Zero);
for (const label globalIdx : elements)
{
@ -296,7 +322,7 @@ void Foam::mapDistributeBase::calcCompactAddressing
forAll(compactMap, proci)
{
compactMap[proci].clear();
if (proci != Pstream::myProcNo())
if (proci != myRank)
{
compactMap[proci].resize(2*nNonLocal[proci]);
}
@ -324,10 +350,13 @@ void Foam::mapDistributeBase::calcCompactAddressing
List<Map<label>>& compactMap
) const
{
compactMap.setSize(Pstream::nProcs());
const label myRank = Pstream::myProcNo(comm_);
const label nProcs = Pstream::nProcs(comm_);
compactMap.setSize(nProcs);
// Count all (non-local) elements needed. Just for presizing map.
labelList nNonLocal(Pstream::nProcs(), Zero);
labelList nNonLocal(nProcs, Zero);
for (const labelList& cCells : cellCells)
{
@ -344,7 +373,7 @@ void Foam::mapDistributeBase::calcCompactAddressing
forAll(compactMap, proci)
{
compactMap[proci].clear();
if (proci != Pstream::myProcNo())
if (proci != myRank)
{
compactMap[proci].resize(2*nNonLocal[proci]);
}
@ -377,16 +406,19 @@ void Foam::mapDistributeBase::exchangeAddressing
labelList& compactStart
)
{
const label myRank = Pstream::myProcNo(comm_);
const label nProcs = Pstream::nProcs(comm_);
// The overall compact addressing is
// - myProcNo data first (uncompacted)
// - all other processors consecutively
compactStart.setSize(Pstream::nProcs());
compactStart[Pstream::myProcNo()] = 0;
compactStart.setSize(nProcs);
compactStart[myRank] = 0;
constructSize_ = globalNumbering.localSize();
forAll(compactStart, proci)
{
if (proci != Pstream::myProcNo())
if (proci != myRank)
{
compactStart[proci] = constructSize_;
constructSize_ += compactMap[proci].size();
@ -398,12 +430,12 @@ void Foam::mapDistributeBase::exchangeAddressing
// Find out what to receive/send in compact addressing.
// What I want to receive is what others have to send
labelListList wantedRemoteElements(Pstream::nProcs());
labelListList wantedRemoteElements(nProcs);
// Compact addressing for received data
constructMap_.setSize(Pstream::nProcs());
constructMap_.setSize(nProcs);
forAll(compactMap, proci)
{
if (proci == Pstream::myProcNo())
if (proci == myRank)
{
// All my own elements are used
label nLocal = globalNumbering.localSize();
@ -429,13 +461,13 @@ void Foam::mapDistributeBase::exchangeAddressing
}
}
subMap_.setSize(Pstream::nProcs());
subMap_.setSize(nProcs);
Pstream::exchange<labelList, label>
(
wantedRemoteElements,
subMap_,
tag,
Pstream::worldComm //TBD
comm_
);
// Renumber elements
@ -455,16 +487,19 @@ void Foam::mapDistributeBase::exchangeAddressing
labelList& compactStart
)
{
const label myRank = Pstream::myProcNo(comm_);
const label nProcs = Pstream::nProcs(comm_);
// The overall compact addressing is
// - myProcNo data first (uncompacted)
// - all other processors consecutively
compactStart.setSize(Pstream::nProcs());
compactStart[Pstream::myProcNo()] = 0;
compactStart.setSize(nProcs);
compactStart[myRank] = 0;
constructSize_ = globalNumbering.localSize();
forAll(compactStart, proci)
{
if (proci != Pstream::myProcNo())
if (proci != myRank)
{
compactStart[proci] = constructSize_;
constructSize_ += compactMap[proci].size();
@ -475,12 +510,12 @@ void Foam::mapDistributeBase::exchangeAddressing
// Find out what to receive/send in compact addressing.
// What I want to receive is what others have to send
labelListList wantedRemoteElements(Pstream::nProcs());
labelListList wantedRemoteElements(nProcs);
// Compact addressing for received data
constructMap_.setSize(Pstream::nProcs());
constructMap_.setSize(nProcs);
forAll(compactMap, proci)
{
if (proci == Pstream::myProcNo())
if (proci == myRank)
{
// All my own elements are used
label nLocal = globalNumbering.localSize();
@ -506,13 +541,13 @@ void Foam::mapDistributeBase::exchangeAddressing
}
}
subMap_.setSize(Pstream::nProcs());
subMap_.setSize(nProcs);
Pstream::exchange<labelList, label>
(
wantedRemoteElements,
subMap_,
tag,
Pstream::worldComm //TBD
comm_
);
// Renumber elements
@ -528,11 +563,12 @@ void Foam::mapDistributeBase::exchangeAddressing
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::mapDistributeBase::mapDistributeBase()
Foam::mapDistributeBase::mapDistributeBase(const label comm)
:
constructSize_(0),
subHasFlip_(false),
constructHasFlip_(false),
comm_(comm),
schedulePtr_()
{}
@ -545,6 +581,7 @@ Foam::mapDistributeBase::mapDistributeBase(const mapDistributeBase& map)
constructMap_(map.constructMap_),
subHasFlip_(map.subHasFlip_),
constructHasFlip_(map.constructHasFlip_),
comm_(map.comm_),
schedulePtr_()
{}
@ -563,7 +600,8 @@ Foam::mapDistributeBase::mapDistributeBase
labelListList&& subMap,
labelListList&& constructMap,
const bool subHasFlip,
const bool constructHasFlip
const bool constructHasFlip,
const label comm
)
:
constructSize_(constructSize),
@ -571,6 +609,7 @@ Foam::mapDistributeBase::mapDistributeBase
constructMap_(std::move(constructMap)),
subHasFlip_(subHasFlip),
constructHasFlip_(constructHasFlip),
comm_(comm),
schedulePtr_()
{}
@ -578,14 +617,19 @@ Foam::mapDistributeBase::mapDistributeBase
Foam::mapDistributeBase::mapDistributeBase
(
const labelUList& sendProcs,
const labelUList& recvProcs
const labelUList& recvProcs,
const label comm
)
:
constructSize_(0),
subHasFlip_(false),
constructHasFlip_(false),
comm_(comm),
schedulePtr_()
{
const label myRank = Pstream::myProcNo(comm_);
const label nProcs = Pstream::nProcs(comm_);
if (sendProcs.size() != recvProcs.size())
{
FatalErrorInFunction
@ -595,8 +639,8 @@ Foam::mapDistributeBase::mapDistributeBase
}
// Per processor the number of samples we have to send/receive.
labelList nSend(Pstream::nProcs(), Zero);
labelList nRecv(Pstream::nProcs(), Zero);
labelList nSend(nProcs, Zero);
labelList nRecv(nProcs, Zero);
forAll(sendProcs, sampleI)
{
@ -606,20 +650,20 @@ Foam::mapDistributeBase::mapDistributeBase
// Note that also need to include local communication (both
// RecvProc and sendProc on local processor)
if (Pstream::myProcNo() == sendProc)
if (myRank == sendProc)
{
// I am the sender. Count destination processor.
nSend[recvProc]++;
}
if (Pstream::myProcNo() == recvProc)
if (myRank == recvProc)
{
// I am the receiver.
nRecv[sendProc]++;
}
}
subMap_.setSize(Pstream::nProcs());
constructMap_.setSize(Pstream::nProcs());
subMap_.setSize(nProcs);
constructMap_.setSize(nProcs);
forAll(nSend, proci)
{
subMap_[proci].setSize(nSend[proci]);
@ -633,12 +677,12 @@ Foam::mapDistributeBase::mapDistributeBase
const label sendProc = sendProcs[sampleI];
const label recvProc = recvProcs[sampleI];
if (Pstream::myProcNo() == sendProc)
if (myRank == sendProc)
{
// I am the sender. Store index I need to send.
subMap_[recvProc][nSend[recvProc]++] = sampleI;
}
if (Pstream::myProcNo() == recvProc)
if (myRank == recvProc)
{
// I am the receiver.
constructMap_[sendProc][nRecv[sendProc]++] = sampleI;
@ -654,12 +698,14 @@ Foam::mapDistributeBase::mapDistributeBase
const globalIndex& globalNumbering,
labelList& elements,
List<Map<label>>& compactMap,
const int tag
const int tag,
const label comm
)
:
constructSize_(0),
subHasFlip_(false),
constructHasFlip_(false),
comm_(comm),
schedulePtr_()
{
// Construct per processor compact addressing of the global elements
@ -675,7 +721,7 @@ Foam::mapDistributeBase::mapDistributeBase
//// Sort remote elements needed (not really necessary)
//forAll(compactMap, proci)
//{
// if (proci != Pstream::myProcNo())
// if (proci != myRank)
// {
// Map<label>& globalMap = compactMap[proci];
//
@ -713,12 +759,14 @@ Foam::mapDistributeBase::mapDistributeBase
const globalIndex& globalNumbering,
labelListList& cellCells,
List<Map<label>>& compactMap,
const int tag
const int tag,
const label comm
)
:
constructSize_(0),
subHasFlip_(false),
constructHasFlip_(false),
comm_(comm),
schedulePtr_()
{
// Construct per processor compact addressing of the global elements
@ -734,7 +782,7 @@ Foam::mapDistributeBase::mapDistributeBase
//// Sort remote elements needed (not really necessary)
//forAll(compactMap, proci)
//{
// if (proci != Pstream::myProcNo())
// if (proci != myRank)
// {
// Map<label>& globalMap = compactMap[proci];
//
@ -771,26 +819,31 @@ Foam::mapDistributeBase::mapDistributeBase
(
labelListList&& subMap,
const bool subHasFlip,
const bool constructHasFlip
const bool constructHasFlip,
const label comm
)
:
constructSize_(0),
subMap_(std::move(subMap)),
subHasFlip_(subHasFlip),
constructHasFlip_(constructHasFlip),
comm_(comm),
schedulePtr_()
{
const label myRank = Pstream::myProcNo(comm_);
const label nProcs = Pstream::nProcs(comm_);
// Send over how many i need to receive.
labelList recvSizes;
Pstream::exchangeSizes(subMap_, recvSizes);
Pstream::exchangeSizes(subMap_, recvSizes, comm_);
// Determine order of receiving
labelListList constructMap(Pstream::nProcs());
labelListList constructMap(nProcs);
// My local segments first
label nLocal = recvSizes[Pstream::myProcNo()];
label nLocal = recvSizes[myRank];
{
labelList& myMap = constructMap[Pstream::myProcNo()];
labelList& myMap = constructMap[myRank];
myMap.setSize(nLocal);
forAll(myMap, i)
{
@ -801,7 +854,7 @@ Foam::mapDistributeBase::mapDistributeBase
label segmenti = nLocal;
forAll(constructMap, proci)
{
if (proci != Pstream::myProcNo())
if (proci != myRank)
{
// What i need to receive is what other processor is sending to me.
label nRecv = recvSizes[proci];
@ -840,6 +893,7 @@ void Foam::mapDistributeBase::transfer(mapDistributeBase& rhs)
constructMap_.transfer(rhs.constructMap_);
subHasFlip_ = rhs.subHasFlip_;
constructHasFlip_ = rhs.constructHasFlip_;
comm_ = rhs.comm_;
schedulePtr_.clear();
rhs.constructSize_ = 0;
@ -872,8 +926,15 @@ Foam::label Foam::mapDistributeBase::renumber
}
void Foam::mapDistributeBase::compact(const boolList& elemIsUsed, const int tag)
void Foam::mapDistributeBase::compact
(
const boolList& elemIsUsed,
const int tag
)
{
const label myRank = Pstream::myProcNo(comm_);
const label nProcs = Pstream::nProcs(comm_);
// 1. send back to sender. Have sender delete the corresponding element
// from the submap and do the same to the constructMap locally
// (and in same order).
@ -886,13 +947,13 @@ void Foam::mapDistributeBase::compact(const boolList& elemIsUsed, const int tag)
// Set up receives from neighbours
List<boolList> recvFields(Pstream::nProcs());
List<boolList> recvFields(nProcs);
for (const int domain : Pstream::allProcs())
for (const int domain : Pstream::allProcs(comm_))
{
const labelList& map = subMap_[domain];
if (domain != Pstream::myProcNo() && map.size())
if (domain != myRank && map.size())
{
recvFields[domain].setSize(map.size());
IPstream::read
@ -901,19 +962,20 @@ void Foam::mapDistributeBase::compact(const boolList& elemIsUsed, const int tag)
domain,
reinterpret_cast<char*>(recvFields[domain].data()),
recvFields[domain].size()*sizeof(bool),
tag
tag,
comm_
);
}
}
List<boolList> sendFields(Pstream::nProcs());
List<boolList> sendFields(nProcs);
for (const int domain : Pstream::allProcs())
for (const int domain : Pstream::allProcs(comm_))
{
const labelList& map = constructMap_[domain];
if (domain != Pstream::myProcNo() && map.size())
if (domain != myRank && map.size())
{
boolList& subField = sendFields[domain];
subField.setSize(map.size());
@ -934,7 +996,8 @@ void Foam::mapDistributeBase::compact(const boolList& elemIsUsed, const int tag)
domain,
reinterpret_cast<const char*>(subField.cdata()),
subField.size()*sizeof(bool),
tag
tag,
comm_
);
}
}
@ -944,12 +1007,12 @@ void Foam::mapDistributeBase::compact(const boolList& elemIsUsed, const int tag)
// Set up 'send' to myself - write directly into recvFields
{
const labelList& map = constructMap_[Pstream::myProcNo()];
const labelList& map = constructMap_[myRank];
recvFields[Pstream::myProcNo()].setSize(map.size());
recvFields[myRank].setSize(map.size());
forAll(map, i)
{
recvFields[Pstream::myProcNo()][i] = accessAndFlip
recvFields[myRank][i] = accessAndFlip
(
elemIsUsed,
map[i],
@ -966,7 +1029,7 @@ void Foam::mapDistributeBase::compact(const boolList& elemIsUsed, const int tag)
// Compact out all submap entries that are referring to unused elements
for (const int domain : Pstream::allProcs())
for (const int domain : Pstream::allProcs(comm_))
{
const labelList& map = subMap_[domain];
@ -995,7 +1058,7 @@ void Foam::mapDistributeBase::compact(const boolList& elemIsUsed, const int tag)
label maxConstructIndex = -1;
for (const int domain : Pstream::allProcs())
for (const int domain : Pstream::allProcs(comm_))
{
const labelList& map = constructMap_[domain];
@ -1041,6 +1104,9 @@ void Foam::mapDistributeBase::compact
const int tag
)
{
const label myRank = Pstream::myProcNo(comm_);
const label nProcs = Pstream::nProcs(comm_);
// 1. send back to sender. Have sender delete the corresponding element
// from the submap and do the same to the constructMap locally
// (and in same order).
@ -1053,13 +1119,13 @@ void Foam::mapDistributeBase::compact
// Set up receives from neighbours
List<boolList> recvFields(Pstream::nProcs());
List<boolList> recvFields(nProcs);
for (const int domain : Pstream::allProcs())
for (const int domain : Pstream::allProcs(comm_))
{
const labelList& map = subMap_[domain];
if (domain != Pstream::myProcNo() && map.size())
if (domain != myRank && map.size())
{
recvFields[domain].setSize(map.size());
IPstream::read
@ -1068,19 +1134,20 @@ void Foam::mapDistributeBase::compact
domain,
reinterpret_cast<char*>(recvFields[domain].data()),
recvFields[domain].size()*sizeof(bool),
tag
tag,
comm_
);
}
}
List<boolList> sendFields(Pstream::nProcs());
List<boolList> sendFields(nProcs);
for (const int domain : Pstream::allProcs())
for (const int domain : Pstream::allProcs(comm_))
{
const labelList& map = constructMap_[domain];
if (domain != Pstream::myProcNo() && map.size())
if (domain != myRank && map.size())
{
boolList& subField = sendFields[domain];
subField.setSize(map.size());
@ -1100,7 +1167,8 @@ void Foam::mapDistributeBase::compact
domain,
reinterpret_cast<const char*>(subField.cdata()),
subField.size()*sizeof(bool),
tag
tag,
comm_
);
}
}
@ -1110,9 +1178,9 @@ void Foam::mapDistributeBase::compact
// Set up 'send' to myself - write directly into recvFields
{
const labelList& map = constructMap_[Pstream::myProcNo()];
const labelList& map = constructMap_[myRank];
recvFields[Pstream::myProcNo()].setSize(map.size());
recvFields[myRank].setSize(map.size());
forAll(map, i)
{
label index = map[i];
@ -1120,7 +1188,7 @@ void Foam::mapDistributeBase::compact
{
index = mag(index)-1;
}
recvFields[Pstream::myProcNo()][i] = elemIsUsed[index];
recvFields[myRank][i] = elemIsUsed[index];
}
}
@ -1138,7 +1206,7 @@ void Foam::mapDistributeBase::compact
boolList sendElemIsUsed(localSize, false);
for (const int domain : Pstream::allProcs())
for (const int domain : Pstream::allProcs(comm_))
{
const labelList& map = subMap_[domain];
forAll(map, i)
@ -1167,7 +1235,7 @@ void Foam::mapDistributeBase::compact
// Compact out all submap entries that are referring to unused elements
for (const int domain : Pstream::allProcs())
for (const int domain : Pstream::allProcs(comm_))
{
const labelList& map = subMap_[domain];
@ -1217,7 +1285,7 @@ void Foam::mapDistributeBase::compact
}
}
for (const int domain : Pstream::allProcs())
for (const int domain : Pstream::allProcs(comm_))
{
const labelList& map = constructMap_[domain];
@ -1268,6 +1336,7 @@ void Foam::mapDistributeBase::operator=(const mapDistributeBase& rhs)
constructMap_ = rhs.constructMap_;
subHasFlip_ = rhs.subHasFlip_;
constructHasFlip_ = rhs.constructHasFlip_;
comm_ = rhs.comm_;
schedulePtr_.clear();
}
@ -1289,7 +1358,8 @@ Foam::Istream& Foam::operator>>(Istream& is, mapDistributeBase& map)
is.fatalCheck(FUNCTION_NAME);
is >> map.constructSize_ >> map.subMap_ >> map.constructMap_
>> map.subHasFlip_ >> map.constructHasFlip_;
>> map.subHasFlip_ >> map.constructHasFlip_
>> map.comm_;
return is;
}
@ -1303,7 +1373,7 @@ Foam::Ostream& Foam::operator<<(Ostream& os, const mapDistributeBase& map)
<< map.subMap_ << token::NL
<< map.constructMap_ << token::NL
<< map.subHasFlip_ << token::SPACE << map.constructHasFlip_
<< token::NL;
<< token::SPACE << map.comm_ << token::NL;
return os;
}

View File

@ -122,6 +122,8 @@ protected:
//- Whether constructMap includes flip or not
bool constructHasFlip_;
//- Communicator to use for parallel operations
label comm_;
//- Schedule
mutable autoPtr<List<labelPair>> schedulePtr_;
@ -199,7 +201,7 @@ public:
// Constructors
//- Construct null
mapDistributeBase();
mapDistributeBase(const label comm = UPstream::worldComm);
//- Copy construct
mapDistributeBase(const mapDistributeBase& map);
@ -214,7 +216,8 @@ public:
labelListList&& subMap,
labelListList&& constructMap,
const bool subHasFlip = false,
const bool constructHasFlip = false
const bool constructHasFlip = false,
const label comm = UPstream::worldComm
);
//- Construct from reverse addressing: per data item the send
@ -223,7 +226,8 @@ public:
mapDistributeBase
(
const labelUList& sendProcs,
const labelUList& recvProcs
const labelUList& recvProcs,
const label comm = UPstream::worldComm
);
//- Construct from list of (possibly) remote elements in globalIndex
@ -235,7 +239,8 @@ public:
const globalIndex&,
labelList& elements,
List<Map<label>>& compactMap,
const int tag = Pstream::msgType()
const int tag = Pstream::msgType(),
const label comm = UPstream::worldComm
);
//- Special variant that works with the info sorted into bins
@ -246,7 +251,8 @@ public:
const globalIndex&,
labelListList& cellCells,
List<Map<label>>& compactMap,
const int tag = Pstream::msgType()
const int tag = Pstream::msgType(),
const label comm = UPstream::worldComm
);
//- Construct from my elements to send. Assumes layout is my elements
@ -256,7 +262,8 @@ public:
(
labelListList&& subMap,
const bool subHasFlip = false,
const bool constructHasFlip = false
const bool constructHasFlip = false,
const label comm = UPstream::worldComm
);
//- Construct from Istream
@ -327,12 +334,18 @@ public:
return constructHasFlip_;
}
label comm() const
{
return comm_;
}
//- Calculate a schedule. See above.
static List<labelPair> schedule
(
const labelListList& subMap,
const labelListList& constructMap,
const int tag
const int tag,
const label comm = UPstream::worldComm
);
//- Return a schedule. Demand driven. See above.
@ -389,7 +402,8 @@ public:
const bool constructHasFlip,
List<T>&,
const negateOp& negOp,
const int tag = UPstream::msgType()
const int tag = UPstream::msgType(),
const label comm = UPstream::worldComm
);
//- Distribute data. If multiple processors writing to same
@ -405,10 +419,11 @@ public:
const labelListList& constructMap,
const bool constructHasFlip,
List<T>&,
const T& nullValue,
const CombineOp& cop,
const negateOp& negOp,
const T& nullValue,
const int tag = UPstream::msgType()
const int tag = UPstream::msgType(),
const label comm = UPstream::worldComm
);
//- Distribute data using default commsType.

View File

@ -129,14 +129,18 @@ void Foam::mapDistributeBase::distribute
const bool constructHasFlip,
List<T>& field,
const negateOp& negOp,
const int tag
const int tag,
const label comm
)
{
const label myRank = Pstream::myProcNo(comm);
const label nProcs = Pstream::nProcs(comm);
if (!Pstream::parRun())
{
// Do only me to me.
const labelList& mySubMap = subMap[Pstream::myProcNo()];
const labelList& mySubMap = subMap[myRank];
List<T> subField(mySubMap.size());
forAll(mySubMap, i)
@ -145,7 +149,7 @@ void Foam::mapDistributeBase::distribute
}
// Receive sub field from myself (subField)
const labelList& map = constructMap[Pstream::myProcNo()];
const labelList& map = constructMap[myRank];
field.setSize(constructSize);
@ -168,13 +172,20 @@ void Foam::mapDistributeBase::distribute
// received data.
// Send sub field to neighbour
for (const int domain : Pstream::allProcs())
for (const int domain : Pstream::allProcs(comm))
{
const labelList& map = subMap[domain];
if (domain != Pstream::myProcNo() && map.size())
if (domain != myRank && map.size())
{
OPstream toNbr(Pstream::commsTypes::blocking, domain, 0, tag);
OPstream toNbr
(
Pstream::commsTypes::blocking,
domain,
0,
tag,
comm
);
List<T> subField(map.size());
forAll(subField, i)
@ -192,7 +203,7 @@ void Foam::mapDistributeBase::distribute
}
// Subset myself
const labelList& mySubMap = subMap[Pstream::myProcNo()];
const labelList& mySubMap = subMap[myRank];
List<T> subField(mySubMap.size());
forAll(mySubMap, i)
@ -201,7 +212,7 @@ void Foam::mapDistributeBase::distribute
}
// Receive sub field from myself (subField)
const labelList& map = constructMap[Pstream::myProcNo()];
const labelList& map = constructMap[myRank];
field.setSize(constructSize);
@ -216,13 +227,20 @@ void Foam::mapDistributeBase::distribute
);
// Receive sub field from neighbour
for (const int domain : Pstream::allProcs())
for (const int domain : Pstream::allProcs(comm))
{
const labelList& map = constructMap[domain];
if (domain != Pstream::myProcNo() && map.size())
if (domain != myRank && map.size())
{
IPstream fromNbr(Pstream::commsTypes::blocking, domain, 0, tag);
IPstream fromNbr
(
Pstream::commsTypes::blocking,
domain,
0,
tag,
comm
);
List<T> subField(fromNbr);
checkReceivedSize(domain, map.size(), subField.size());
@ -248,7 +266,7 @@ void Foam::mapDistributeBase::distribute
// Receive sub field from myself
{
const labelList& mySubMap = subMap[Pstream::myProcNo()];
const labelList& mySubMap = subMap[myRank];
List<T> subField(mySubMap.size());
forAll(subField, i)
@ -265,7 +283,7 @@ void Foam::mapDistributeBase::distribute
// Receive sub field from myself (subField)
flipAndCombine
(
constructMap[Pstream::myProcNo()],
constructMap[myRank],
constructHasFlip,
subField,
eqOp<T>(),
@ -284,7 +302,7 @@ void Foam::mapDistributeBase::distribute
label sendProc = twoProcs[0];
label recvProc = twoProcs[1];
if (Pstream::myProcNo() == sendProc)
if (myRank == sendProc)
{
// I am send first, receive next
{
@ -293,7 +311,8 @@ void Foam::mapDistributeBase::distribute
Pstream::commsTypes::scheduled,
recvProc,
0,
tag
tag,
comm
);
const labelList& map = subMap[recvProc];
@ -316,7 +335,8 @@ void Foam::mapDistributeBase::distribute
Pstream::commsTypes::scheduled,
recvProc,
0,
tag
tag,
comm
);
List<T> subField(fromNbr);
@ -344,7 +364,8 @@ void Foam::mapDistributeBase::distribute
Pstream::commsTypes::scheduled,
sendProc,
0,
tag
tag,
comm
);
List<T> subField(fromNbr);
@ -368,7 +389,8 @@ void Foam::mapDistributeBase::distribute
Pstream::commsTypes::scheduled,
sendProc,
0,
tag
tag,
comm
);
const labelList& map = subMap[sendProc];
@ -395,14 +417,14 @@ void Foam::mapDistributeBase::distribute
if (!is_contiguous<T>::value)
{
PstreamBuffers pBufs(Pstream::commsTypes::nonBlocking, tag);
PstreamBuffers pBufs(Pstream::commsTypes::nonBlocking, tag, comm);
// Stream data into buffer
for (const int domain : Pstream::allProcs())
for (const int domain : Pstream::allProcs(comm))
{
const labelList& map = subMap[domain];
if (domain != Pstream::myProcNo() && map.size())
if (domain != myRank && map.size())
{
// Put data into send buffer
UOPstream toDomain(domain, pBufs);
@ -427,7 +449,7 @@ void Foam::mapDistributeBase::distribute
{
// Set up 'send' to myself
const labelList& mySub = subMap[Pstream::myProcNo()];
const labelList& mySub = subMap[myRank];
List<T> mySubField(mySub.size());
forAll(mySub, i)
{
@ -443,7 +465,7 @@ void Foam::mapDistributeBase::distribute
field.setSize(constructSize);
// Receive sub field from myself
{
const labelList& map = constructMap[Pstream::myProcNo()];
const labelList& map = constructMap[myRank];
flipAndCombine
(
@ -461,11 +483,11 @@ void Foam::mapDistributeBase::distribute
Pstream::waitRequests(nOutstanding);
// Consume
for (const int domain : Pstream::allProcs())
for (const int domain : Pstream::allProcs(comm))
{
const labelList& map = constructMap[domain];
if (domain != Pstream::myProcNo() && map.size())
if (domain != myRank && map.size())
{
UIPstream str(domain, pBufs);
List<T> recvField(str);
@ -488,13 +510,13 @@ void Foam::mapDistributeBase::distribute
{
// Set up sends to neighbours
List<List<T>> sendFields(Pstream::nProcs());
List<List<T>> sendFields(nProcs);
for (const int domain : Pstream::allProcs())
for (const int domain : Pstream::allProcs(comm))
{
const labelList& map = subMap[domain];
if (domain != Pstream::myProcNo() && map.size())
if (domain != myRank && map.size())
{
List<T>& subField = sendFields[domain];
subField.setSize(map.size());
@ -515,20 +537,21 @@ void Foam::mapDistributeBase::distribute
domain,
reinterpret_cast<const char*>(subField.cdata()),
subField.byteSize(),
tag
tag,
comm
);
}
}
// Set up receives from neighbours
List<List<T>> recvFields(Pstream::nProcs());
List<List<T>> recvFields(nProcs);
for (const int domain : Pstream::allProcs())
for (const int domain : Pstream::allProcs(comm))
{
const labelList& map = constructMap[domain];
if (domain != Pstream::myProcNo() && map.size())
if (domain != myRank && map.size())
{
recvFields[domain].setSize(map.size());
IPstream::read
@ -537,7 +560,8 @@ void Foam::mapDistributeBase::distribute
domain,
reinterpret_cast<char*>(recvFields[domain].data()),
recvFields[domain].byteSize(),
tag
tag,
comm
);
}
}
@ -546,9 +570,9 @@ void Foam::mapDistributeBase::distribute
// Set up 'send' to myself
{
const labelList& map = subMap[Pstream::myProcNo()];
const labelList& map = subMap[myRank];
List<T>& subField = sendFields[Pstream::myProcNo()];
List<T>& subField = sendFields[myRank];
subField.setSize(map.size());
forAll(map, i)
{
@ -568,10 +592,10 @@ void Foam::mapDistributeBase::distribute
field.setSize(constructSize);
// Receive sub field from myself (sendFields[Pstream::myProcNo()])
// Receive sub field from myself (sendFields[myRank])
{
const labelList& map = constructMap[Pstream::myProcNo()];
const List<T>& subField = sendFields[Pstream::myProcNo()];
const labelList& map = constructMap[myRank];
const List<T>& subField = sendFields[myRank];
flipAndCombine
(
@ -592,11 +616,11 @@ void Foam::mapDistributeBase::distribute
// Collect neighbour fields
for (const int domain : Pstream::allProcs())
for (const int domain : Pstream::allProcs(comm))
{
const labelList& map = constructMap[domain];
if (domain != Pstream::myProcNo() && map.size())
if (domain != myRank && map.size())
{
const List<T>& subField = recvFields[domain];
@ -636,17 +660,21 @@ void Foam::mapDistributeBase::distribute
const labelListList& constructMap,
const bool constructHasFlip,
List<T>& field,
const T& nullValue,
const CombineOp& cop,
const negateOp& negOp,
const T& nullValue,
const int tag
const int tag,
const label comm
)
{
const label myRank = Pstream::myProcNo(comm);
const label nProcs = Pstream::nProcs(comm);
if (!Pstream::parRun())
{
// Do only me to me.
const labelList& mySubMap = subMap[Pstream::myProcNo()];
const labelList& mySubMap = subMap[myRank];
List<T> subField(mySubMap.size());
forAll(mySubMap, i)
@ -655,7 +683,7 @@ void Foam::mapDistributeBase::distribute
}
// Receive sub field from myself (subField)
const labelList& map = constructMap[Pstream::myProcNo()];
const labelList& map = constructMap[myRank];
field.setSize(constructSize);
field = nullValue;
@ -671,13 +699,20 @@ void Foam::mapDistributeBase::distribute
// received data.
// Send sub field to neighbour
for (const int domain : Pstream::allProcs())
for (const int domain : Pstream::allProcs(comm))
{
const labelList& map = subMap[domain];
if (domain != Pstream::myProcNo() && map.size())
if (domain != myRank && map.size())
{
OPstream toNbr(Pstream::commsTypes::blocking, domain, 0, tag);
OPstream toNbr
(
Pstream::commsTypes::blocking,
domain,
0,
tag,
comm
);
List<T> subField(map.size());
forAll(subField, i)
{
@ -694,7 +729,7 @@ void Foam::mapDistributeBase::distribute
}
// Subset myself
const labelList& mySubMap = subMap[Pstream::myProcNo()];
const labelList& mySubMap = subMap[myRank];
List<T> subField(mySubMap.size());
forAll(mySubMap, i)
@ -703,7 +738,7 @@ void Foam::mapDistributeBase::distribute
}
// Receive sub field from myself (subField)
const labelList& map = constructMap[Pstream::myProcNo()];
const labelList& map = constructMap[myRank];
field.setSize(constructSize);
field = nullValue;
@ -711,13 +746,20 @@ void Foam::mapDistributeBase::distribute
flipAndCombine(map, constructHasFlip, subField, cop, negOp, field);
// Receive sub field from neighbour
for (const int domain : Pstream::allProcs())
for (const int domain : Pstream::allProcs(comm))
{
const labelList& map = constructMap[domain];
if (domain != Pstream::myProcNo() && map.size())
if (domain != myRank && map.size())
{
IPstream fromNbr(Pstream::commsTypes::blocking, domain, 0, tag);
IPstream fromNbr
(
Pstream::commsTypes::blocking,
domain,
0,
tag,
comm
);
List<T> subField(fromNbr);
checkReceivedSize(domain, map.size(), subField.size());
@ -742,7 +784,7 @@ void Foam::mapDistributeBase::distribute
List<T> newField(constructSize, nullValue);
{
const labelList& mySubMap = subMap[Pstream::myProcNo()];
const labelList& mySubMap = subMap[myRank];
// Subset myself
List<T> subField(mySubMap.size());
@ -758,7 +800,7 @@ void Foam::mapDistributeBase::distribute
}
// Receive sub field from myself (subField)
const labelList& map = constructMap[Pstream::myProcNo()];
const labelList& map = constructMap[myRank];
flipAndCombine
(
@ -782,7 +824,7 @@ void Foam::mapDistributeBase::distribute
label sendProc = twoProcs[0];
label recvProc = twoProcs[1];
if (Pstream::myProcNo() == sendProc)
if (myRank == sendProc)
{
// I am send first, receive next
{
@ -791,7 +833,8 @@ void Foam::mapDistributeBase::distribute
Pstream::commsTypes::scheduled,
recvProc,
0,
tag
tag,
comm
);
const labelList& map = subMap[recvProc];
@ -815,7 +858,8 @@ void Foam::mapDistributeBase::distribute
Pstream::commsTypes::scheduled,
recvProc,
0,
tag
tag,
comm
);
List<T> subField(fromNbr);
const labelList& map = constructMap[recvProc];
@ -842,7 +886,8 @@ void Foam::mapDistributeBase::distribute
Pstream::commsTypes::scheduled,
sendProc,
0,
tag
tag,
comm
);
List<T> subField(fromNbr);
const labelList& map = constructMap[sendProc];
@ -865,7 +910,8 @@ void Foam::mapDistributeBase::distribute
Pstream::commsTypes::scheduled,
sendProc,
0,
tag
tag,
comm
);
const labelList& map = subMap[sendProc];
@ -893,14 +939,14 @@ void Foam::mapDistributeBase::distribute
if (!is_contiguous<T>::value)
{
PstreamBuffers pBufs(Pstream::commsTypes::nonBlocking, tag);
PstreamBuffers pBufs(Pstream::commsTypes::nonBlocking, tag, comm);
// Stream data into buffer
for (const int domain : Pstream::allProcs())
for (const int domain : Pstream::allProcs(comm))
{
const labelList& map = subMap[domain];
if (domain != Pstream::myProcNo() && map.size())
if (domain != myRank && map.size())
{
// Put data into send buffer
UOPstream toDomain(domain, pBufs);
@ -925,7 +971,7 @@ void Foam::mapDistributeBase::distribute
{
// Set up 'send' to myself
const labelList& myMap = subMap[Pstream::myProcNo()];
const labelList& myMap = subMap[myRank];
List<T> mySubField(myMap.size());
forAll(myMap, i)
@ -944,7 +990,7 @@ void Foam::mapDistributeBase::distribute
field = nullValue;
// Receive sub field from myself
{
const labelList& map = constructMap[Pstream::myProcNo()];
const labelList& map = constructMap[myRank];
flipAndCombine
(
@ -962,11 +1008,11 @@ void Foam::mapDistributeBase::distribute
Pstream::waitRequests(nOutstanding);
// Consume
for (const int domain : Pstream::allProcs())
for (const int domain : Pstream::allProcs(comm))
{
const labelList& map = constructMap[domain];
if (domain != Pstream::myProcNo() && map.size())
if (domain != myRank && map.size())
{
UIPstream str(domain, pBufs);
List<T> recvField(str);
@ -989,13 +1035,13 @@ void Foam::mapDistributeBase::distribute
{
// Set up sends to neighbours
List<List<T>> sendFields(Pstream::nProcs());
List<List<T>> sendFields(nProcs);
for (const int domain : Pstream::allProcs())
for (const int domain : Pstream::allProcs(comm))
{
const labelList& map = subMap[domain];
if (domain != Pstream::myProcNo() && map.size())
if (domain != myRank && map.size())
{
List<T>& subField = sendFields[domain];
subField.setSize(map.size());
@ -1016,20 +1062,21 @@ void Foam::mapDistributeBase::distribute
domain,
reinterpret_cast<const char*>(subField.cdata()),
subField.size()*sizeof(T),
tag
tag,
comm
);
}
}
// Set up receives from neighbours
List<List<T>> recvFields(Pstream::nProcs());
List<List<T>> recvFields(nProcs);
for (const int domain : Pstream::allProcs())
for (const int domain : Pstream::allProcs(comm))
{
const labelList& map = constructMap[domain];
if (domain != Pstream::myProcNo() && map.size())
if (domain != myRank && map.size())
{
recvFields[domain].setSize(map.size());
UIPstream::read
@ -1038,7 +1085,8 @@ void Foam::mapDistributeBase::distribute
domain,
reinterpret_cast<char*>(recvFields[domain].data()),
recvFields[domain].size()*sizeof(T),
tag
tag,
comm
);
}
}
@ -1046,9 +1094,9 @@ void Foam::mapDistributeBase::distribute
// Set up 'send' to myself
{
const labelList& map = subMap[Pstream::myProcNo()];
const labelList& map = subMap[myRank];
List<T>& subField = sendFields[Pstream::myProcNo()];
List<T>& subField = sendFields[myRank];
subField.setSize(map.size());
forAll(map, i)
{
@ -1070,8 +1118,8 @@ void Foam::mapDistributeBase::distribute
// Receive sub field from myself (subField)
{
const labelList& map = constructMap[Pstream::myProcNo()];
const List<T>& subField = sendFields[Pstream::myProcNo()];
const labelList& map = constructMap[myRank];
const List<T>& subField = sendFields[myRank];
flipAndCombine
(
@ -1092,11 +1140,11 @@ void Foam::mapDistributeBase::distribute
// Collect neighbour fields
for (const int domain : Pstream::allProcs())
for (const int domain : Pstream::allProcs(comm))
{
const labelList& map = constructMap[domain];
if (domain != Pstream::myProcNo() && map.size())
if (domain != myRank && map.size())
{
const List<T>& subField = recvFields[domain];
@ -1129,7 +1177,7 @@ void Foam::mapDistributeBase::send(PstreamBuffers& pBufs, const List<T>& field)
const
{
// Stream data into buffer
for (const int domain : Pstream::allProcs())
for (const int domain : Pstream::allProcs(comm_))
{
const labelList& map = subMap_[domain];
@ -1165,7 +1213,7 @@ const
// Consume
field.setSize(constructSize_);
for (const int domain : Pstream::allProcs())
for (const int domain : Pstream::allProcs(comm_))
{
const labelList& map = constructMap_[domain];
@ -1219,7 +1267,8 @@ void Foam::mapDistributeBase::distribute
constructHasFlip_,
fld,
negOp,
tag
tag,
comm_
);
}
else if (Pstream::defaultCommsType == Pstream::commsTypes::scheduled)
@ -1235,7 +1284,8 @@ void Foam::mapDistributeBase::distribute
constructHasFlip_,
fld,
negOp,
tag
tag,
comm_
);
}
else
@ -1251,7 +1301,8 @@ void Foam::mapDistributeBase::distribute
constructHasFlip_,
fld,
negOp,
tag
tag,
comm_
);
}
}
@ -1309,7 +1360,8 @@ void Foam::mapDistributeBase::reverseDistribute
subHasFlip_,
fld,
flipOp(),
tag
tag,
comm_
);
}
else if (Pstream::defaultCommsType == Pstream::commsTypes::scheduled)
@ -1325,7 +1377,8 @@ void Foam::mapDistributeBase::reverseDistribute
subHasFlip_,
fld,
flipOp(),
tag
tag,
comm_
);
}
else
@ -1341,7 +1394,8 @@ void Foam::mapDistributeBase::reverseDistribute
subHasFlip_,
fld,
flipOp(),
tag
tag,
comm_
);
}
}
@ -1371,10 +1425,11 @@ void Foam::mapDistributeBase::reverseDistribute
subMap_,
subHasFlip_,
fld,
nullValue,
eqOp<T>(),
flipOp(),
nullValue,
tag
tag,
comm_
);
}
else if (Pstream::defaultCommsType == Pstream::commsTypes::scheduled)
@ -1389,10 +1444,11 @@ void Foam::mapDistributeBase::reverseDistribute
subMap_,
subHasFlip_,
fld,
nullValue,
eqOp<T>(),
flipOp(),
nullValue,
tag
tag,
comm_
);
}
else
@ -1407,10 +1463,11 @@ void Foam::mapDistributeBase::reverseDistribute
subMap_,
subHasFlip_,
fld,
nullValue,
eqOp<T>(),
flipOp(),
nullValue,
tag
tag,
comm_
);
}
}

View File

@ -245,16 +245,46 @@ bool Foam::UPstream::init(int& argc, char**& argv, const bool needsThread)
ourMpi = true;
}
// Check argument list for local world
label worldIndex = -1;
word world;
for (int argi = 1; argi < argc; ++argi)
{
if (strcmp(argv[argi], "-world") == 0)
{
worldIndex = argi++;
if (argi >= argc)
{
FatalErrorInFunction
<< "Missing world name to argument \"world\""
<< Foam::abort(FatalError);
}
world = argv[argi];
break;
}
}
// Filter 'world' option
if (worldIndex != -1)
{
for (label i = worldIndex+2; i < argc; i++)
{
argv[i-2] = argv[i];
}
argc -= 2;
}
MPI_Comm_size(MPI_COMM_WORLD, &numprocs);
MPI_Comm_rank(MPI_COMM_WORLD, &myRank);
if (debug)
{
Pout<< "UPstream::init : procs=" << numprocs
<< " rank:" << myRank << endl;
Pout<< "UPstream::init : procs:" << numprocs
<< " rank:" << myRank
<< " world:" << world << endl;
}
if (numprocs <= 1)
if (worldIndex == -1 && numprocs <= 1)
{
FatalErrorInFunction
<< "attempt to run parallel on 1 processor"
@ -264,6 +294,85 @@ bool Foam::UPstream::init(int& argc, char**& argv, const bool needsThread)
// Initialise parallel structure
setParRun(numprocs, provided_thread_support == MPI_THREAD_MULTIPLE);
if (worldIndex != -1)
{
wordList worlds(numprocs);
worlds[Pstream::myProcNo()] = world;
Pstream::gatherList(worlds);
Pstream::scatterList(worlds);
// Compact
if (Pstream::master())
{
DynamicList<word> allWorlds(numprocs);
for (const auto& world : worlds)
{
if (!allWorlds.found(world))
{
allWorlds.append(world);
}
}
allWorlds_ = std::move(allWorlds);
worldIDs_.setSize(numprocs);
forAll(worlds, proci)
{
const word& world = worlds[proci];
worldIDs_[proci] = allWorlds_.find(world);
}
}
Pstream::scatter(allWorlds_);
Pstream::scatter(worldIDs_);
DynamicList<label> subRanks;
forAll(worlds, proci)
{
if (worlds[proci] == worlds[Pstream::myProcNo()])
{
subRanks.append(proci);
}
}
// Allocate new communicator 1 with parent 0 (= mpi_world)
const label subComm = allocateCommunicator(0, subRanks, true);
// Override worldComm
UPstream::worldComm = subComm;
// For testing: warn use of non-worldComm
UPstream::warnComm = UPstream::worldComm;
if (debug)
{
// Check
int subNProcs, subRank;
MPI_Comm_size
(
PstreamGlobals::MPICommunicators_[subComm],
&subNProcs
);
MPI_Comm_rank
(
PstreamGlobals::MPICommunicators_[subComm],
&subRank
);
Pout<< "UPstream::init : in world:" << world
<< " using local communicator:" << subComm
<< " with procs:" << subNProcs
<< " and rank:" << subRank
<< endl;
}
// Override Pout prefix (move to setParRun?)
Pout.prefix() = '[' + world + '/' + name(myProcNo(subComm)) + "] ";
Perr.prefix() = '[' + world + '/' + name(myProcNo(subComm)) + "] ";
}
else
{
// All processors use world 0
worldIDs_.setSize(numprocs, 0);
}
attachOurBuffers();
return true;
@ -357,6 +466,7 @@ void Foam::UPstream::shutdown(int errNo)
}
else
{
// Abort only locally or world?
MPI_Abort(MPI_COMM_WORLD, errNo);
}
}
@ -443,7 +553,7 @@ void Foam::sumReduce
{
if (UPstream::warnComm != -1 && communicator != UPstream::warnComm)
{
Pout<< "** reducing:" << Value << " with comm:" << communicator
Pout<< "** sumReduce:" << Value << " with comm:" << communicator
<< " warnComm:" << UPstream::warnComm
<< endl;
error::printStack(Pout);
@ -623,7 +733,18 @@ void Foam::UPstream::allToAll
const label communicator
)
{
label np = nProcs(communicator);
const label np = nProcs(communicator);
if (UPstream::warnComm != -1 && communicator != UPstream::warnComm)
{
Pout<< "** allToAll :"
<< " np:" << np
<< " sendData:" << sendData.size()
<< " with comm:" << communicator
<< " warnComm:" << UPstream::warnComm
<< endl;
error::printStack(Pout);
}
if (sendData.size() != np || recvData.size() != np)
{
@ -683,7 +804,18 @@ void Foam::UPstream::allToAll
const label communicator
)
{
label np = nProcs(communicator);
const label np = nProcs(communicator);
if (UPstream::warnComm != -1 && communicator != UPstream::warnComm)
{
Pout<< "** allToAll :"
<< " sendSizes:" << sendSizes
<< " sendOffsets:" << sendOffsets
<< " with comm:" << communicator
<< " warnComm:" << UPstream::warnComm
<< endl;
error::printStack(Pout);
}
if
(
@ -757,7 +889,19 @@ void Foam::UPstream::gather
const label communicator
)
{
label np = nProcs(communicator);
const label np = nProcs(communicator);
if (UPstream::warnComm != -1 && communicator != UPstream::warnComm)
{
Pout<< "** allToAll :"
<< " np:" << np
<< " recvSizes:" << recvSizes
<< " recvOffsets:" << recvOffsets
<< " with comm:" << communicator
<< " warnComm:" << UPstream::warnComm
<< endl;
error::printStack(Pout);
}
if
(
@ -823,7 +967,19 @@ void Foam::UPstream::scatter
const label communicator
)
{
label np = nProcs(communicator);
const label np = nProcs(communicator);
if (UPstream::warnComm != -1 && communicator != UPstream::warnComm)
{
Pout<< "** allToAll :"
<< " np:" << np
<< " sendSizes:" << sendSizes
<< " sendOffsets:" << sendOffsets
<< " with comm:" << communicator
<< " warnComm:" << UPstream::warnComm
<< endl;
error::printStack(Pout);
}
if
(
@ -976,7 +1132,7 @@ void Foam::UPstream::allocatePstreamCommunicator
void Foam::UPstream::freePstreamCommunicator(const label communicator)
{
if (communicator != UPstream::worldComm)
if (communicator != 0)
{
if (PstreamGlobals::MPICommunicators_[communicator] != MPI_COMM_NULL)
{

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2019 OpenCFD Ltd.
Copyright (C) 2019-2020 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -57,6 +57,11 @@ turbulentTemperatureCoupledBaffleMixedFvPatchScalarField
"undefined-K",
"undefined-alpha"
),
mappedPatchFieldBase<scalar>
(
mappedPatchFieldBase<scalar>::mapper(p, iF),
*this
),
TnbrName_("undefined-Tnbr"),
thicknessLayers_(0),
kappaLayers_(0),
@ -79,6 +84,12 @@ turbulentTemperatureCoupledBaffleMixedFvPatchScalarField
:
mixedFvPatchScalarField(ptf, p, iF, mapper),
temperatureCoupledBase(patch(), ptf),
mappedPatchFieldBase<scalar>
(
mappedPatchFieldBase<scalar>::mapper(p, iF),
*this,
ptf
),
TnbrName_(ptf.TnbrName_),
thicknessLayers_(ptf.thicknessLayers_),
kappaLayers_(ptf.kappaLayers_),
@ -96,21 +107,17 @@ turbulentTemperatureCoupledBaffleMixedFvPatchScalarField
:
mixedFvPatchScalarField(p, iF),
temperatureCoupledBase(patch(), dict),
mappedPatchFieldBase<scalar>
(
mappedPatchFieldBase<scalar>::mapper(p, iF),
*this,
dict
),
TnbrName_(dict.get<word>("Tnbr")),
thicknessLayers_(0),
kappaLayers_(0),
contactRes_(0.0)
{
if (!isA<mappedPatchBase>(this->patch().patch()))
{
FatalErrorInFunction
<< "' not type '" << mappedPatchBase::typeName << "'"
<< "\n for patch " << p.name()
<< " of field " << internalField().name()
<< " in file " << internalField().objectPath()
<< exit(FatalError);
}
if (dict.readIfPresent("thicknessLayers", thicknessLayers_))
{
dict.readEntry("kappaLayers", kappaLayers_);
@ -142,6 +149,18 @@ turbulentTemperatureCoupledBaffleMixedFvPatchScalarField
refGrad() = 0.0;
valueFraction() = 1.0;
}
// Store patch value as initial guess when running in database mode
mappedPatchFieldBase<scalar>::initRetrieveField
(
this->internalField().name(),
*this
);
mappedPatchFieldBase<scalar>::initRetrieveField
(
this->internalField().name() + "_weights",
this->patch().deltaCoeffs()
);
}
@ -154,6 +173,33 @@ turbulentTemperatureCoupledBaffleMixedFvPatchScalarField
:
mixedFvPatchScalarField(wtcsf, iF),
temperatureCoupledBase(patch(), wtcsf),
mappedPatchFieldBase<scalar>
(
mappedPatchFieldBase<scalar>::mapper(patch(), iF),
*this,
wtcsf
),
TnbrName_(wtcsf.TnbrName_),
thicknessLayers_(wtcsf.thicknessLayers_),
kappaLayers_(wtcsf.kappaLayers_),
contactRes_(wtcsf.contactRes_)
{}
turbulentTemperatureCoupledBaffleMixedFvPatchScalarField::
turbulentTemperatureCoupledBaffleMixedFvPatchScalarField
(
const turbulentTemperatureCoupledBaffleMixedFvPatchScalarField& wtcsf
)
:
mixedFvPatchScalarField(wtcsf),
temperatureCoupledBase(patch(), wtcsf),
mappedPatchFieldBase<scalar>
(
mappedPatchFieldBase<scalar>::mapper(patch(), wtcsf.internalField()),
*this,
wtcsf
),
TnbrName_(wtcsf.TnbrName_),
thicknessLayers_(wtcsf.thicknessLayers_),
kappaLayers_(wtcsf.kappaLayers_),
@ -172,51 +218,89 @@ void turbulentTemperatureCoupledBaffleMixedFvPatchScalarField::updateCoeffs()
// Since we're inside initEvaluate/evaluate there might be processor
// comms underway. Change the tag we use.
int oldTag = UPstream::msgType();
const int oldTag = UPstream::msgType();
UPstream::msgType() = oldTag+1;
// Get the coupling information from the mappedPatchBase
const mappedPatchBase& mpp =
refCast<const mappedPatchBase>(patch().patch());
const polyMesh& nbrMesh = mpp.sampleMesh();
const label samplePatchi = mpp.samplePolyPatch().index();
const fvPatch& nbrPatch =
refCast<const fvMesh>(nbrMesh).boundary()[samplePatchi];
// Calculate the temperature by harmonic averaging
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
const turbulentTemperatureCoupledBaffleMixedFvPatchScalarField& nbrField =
refCast
<
const turbulentTemperatureCoupledBaffleMixedFvPatchScalarField
>
(
nbrPatch.lookupPatchField<volScalarField, scalar>
mappedPatchFieldBase<scalar>::mapper
(
TnbrName_
)
);
patch(),
this->internalField()
);
// Swap to obtain full local values of neighbour internal field
tmp<scalarField> nbrIntFld(new scalarField(nbrField.size(), Zero));
tmp<scalarField> nbrKDelta(new scalarField(nbrField.size(), Zero));
const tmp<scalarField> myKDelta = kappa(*this)*patch().deltaCoeffs();
tmp<scalarField> nbrIntFld;
tmp<scalarField> nbrKDelta;
if (contactRes_ == 0.0)
//Pout<< "updateCoeffs() : mpp.sameWorld():" << mpp.sameWorld() << endl;
if (mpp.sameWorld())
{
nbrIntFld.ref() = nbrField.patchInternalField();
nbrKDelta.ref() = nbrField.kappa(nbrField)*nbrPatch.deltaCoeffs();
// Same world so lookup
const auto& nbrMesh = refCast<const fvMesh>(mpp.sampleMesh());
const label nbrPatchID = mpp.samplePolyPatch().index();
const auto& nbrPatch = nbrMesh.boundary()[nbrPatchID];
const turbulentTemperatureCoupledBaffleMixedFvPatchScalarField&
nbrField =
refCast
<
const turbulentTemperatureCoupledBaffleMixedFvPatchScalarField
>
(
nbrPatch.lookupPatchField<volScalarField, scalar>
(
TnbrName_
)
);
if (contactRes_ == 0.0)
{
// Get neighbour internal data in local order. Does all
// comms/reordering already
nbrIntFld = this->mappedInternalField();
// Calculate neighbour weighting (in neighbouring ordering)
nbrKDelta = nbrField.kappa(nbrField)*nbrPatch.deltaCoeffs();
}
else
{
// Get neighbour patch values
nbrIntFld = new scalarField(nbrField);
// Comms/reorder to local
distribute(this->internalField().name(), nbrIntFld.ref());
// Constant neighbour weighting. Reorder/comms below
nbrKDelta = new scalarField(nbrField.size(), contactRes_);
}
}
else
{
nbrIntFld.ref() = nbrField;
nbrKDelta.ref() = contactRes_;
// Different world so use my region,patch. Distribution below will
// do the reordering
if (contactRes_ == 0.0)
{
nbrIntFld = this->mappedInternalField();
nbrKDelta = new scalarField(myKDelta());
}
else
{
nbrIntFld = *this;
nbrKDelta = new scalarField(this->size(), contactRes_);
}
}
mpp.distribute(nbrIntFld.ref());
mpp.distribute(nbrKDelta.ref());
tmp<scalarField> myKDelta = kappa(*this)*patch().deltaCoeffs();
//Pout<< "updateCoeffs() : nbrIntFld:" << flatOutput(nbrIntFld()) << endl;
//Pout<< "updateCoeffs() : nbrKDelta BEFORE:" << flatOutput(nbrKDelta())
// << endl;
distribute(this->internalField().name() + "_weights", nbrKDelta.ref());
//Pout<< "updateCoeffs() : nbrKDelta AFTER:" << flatOutput(nbrKDelta())
// << endl;
//Pout<< "updateCoeffs() : myKDelta:" << flatOutput(myKDelta())
// << endl;
// Both sides agree on
@ -247,8 +331,8 @@ void turbulentTemperatureCoupledBaffleMixedFvPatchScalarField::updateCoeffs()
Info<< patch().boundaryMesh().mesh().name() << ':'
<< patch().name() << ':'
<< this->internalField().name() << " <- "
<< nbrMesh.name() << ':'
<< nbrPatch.name() << ':'
<< mpp.sampleRegion() << ':'
<< mpp.samplePatch() << ':'
<< this->internalField().name() << " :"
<< " heat transfer rate:" << Q
<< " walltemperature "
@ -274,6 +358,7 @@ void turbulentTemperatureCoupledBaffleMixedFvPatchScalarField::write
kappaLayers_.writeEntry("kappaLayers", os);
temperatureCoupledBase::write(os);
mappedPatchFieldBase<scalar>::write(os);
}

View File

@ -82,6 +82,7 @@ SourceFiles
#include "mixedFvPatchFields.H"
#include "temperatureCoupledBase.H"
#include "mappedPatchFieldBase.H"
#include "scalarField.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -98,7 +99,8 @@ namespace compressible
class turbulentTemperatureCoupledBaffleMixedFvPatchScalarField
:
public mixedFvPatchScalarField,
public temperatureCoupledBase
public temperatureCoupledBase,
public mappedPatchFieldBase<scalar>
{
// Private data
@ -149,6 +151,12 @@ public:
const fvPatchFieldMapper&
);
//- Construct as copy setting internal field reference
turbulentTemperatureCoupledBaffleMixedFvPatchScalarField
(
const turbulentTemperatureCoupledBaffleMixedFvPatchScalarField&
);
//- Construct and return a clone
virtual tmp<fvPatchScalarField> clone() const
{

View File

@ -228,8 +228,9 @@ $(derivedFvPatchFields)/plenumPressure/plenumPressureFvPatchScalarField.C
$(derivedFvPatchFields)/interfaceCompression/interfaceCompressionFvPatchScalarField.C
$(derivedFvPatchFields)/swirlFanVelocity/swirlFanVelocityFvPatchField.C
$(derivedFvPatchFields)/mappedMixed/mappedMixedFvPatchFields.C
$(derivedFvPatchFields)/mappedField/Sampled/makeSampledPatchFunction1s.C
$(derivedFvPatchFields)/mappedField/mappedMixedFieldFvPatchField/mappedMixedFieldFvPatchFields.C
fvsPatchFields = fields/fvsPatchFields
$(fvsPatchFields)/fvsPatchField/fvsPatchFields.C

View File

@ -54,7 +54,7 @@ Foam::mappedFieldFvPatchField<Type>::mappedFieldFvPatchField
:
fixedValueFvPatchField<Type>(p, iF, dict),
mappedPatchBase(p.patch(), dict),
mappedPatchFieldBase<Type>(*this, *this, dict)
mappedPatchFieldBase<Type>(*this, *this, dict, *this)
{}

View File

@ -0,0 +1,233 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2019-2020 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "mappedMixedFieldFvPatchField.H"
#include "volFields.H"
#include "interpolationCell.H"
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
template<class Type>
Foam::mappedMixedFieldFvPatchField<Type>::mappedMixedFieldFvPatchField
(
const fvPatch& p,
const DimensionedField<Type, volMesh>& iF
)
:
mixedFvPatchField<Type>(p, iF),
mappedPatchBase(p.patch()),
mappedPatchFieldBase<Type>(*this, *this),
weightFieldName_(word::null)
{
this->refValue() = Zero;
this->refGrad() = Zero;
this->valueFraction() = 0.0;
}
template<class Type>
Foam::mappedMixedFieldFvPatchField<Type>::mappedMixedFieldFvPatchField
(
const fvPatch& p,
const DimensionedField<Type, volMesh>& iF,
const dictionary& dict
)
:
mixedFvPatchField<Type>(p, iF, dict),
mappedPatchBase(p.patch(), dict),
mappedPatchFieldBase<Type>(*this, *this, dict),
weightFieldName_(dict.getOrDefault<word>("weightField", word::null))
{
mixedFvPatchField<Type>::operator=
(
Field<Type>("value", dict, p.size())
);
if (dict.found("refValue"))
{
// Full restart
this->refValue() = Field<Type>("refValue", dict, p.size());
this->refGrad() = Field<Type>("refGradient", dict, p.size());
this->valueFraction() = scalarField("valueFraction", dict, p.size());
}
else
{
// Start from user entered data. Assume fixedValue.
this->refValue() = *this;
this->refGrad() = Zero;
this->valueFraction() = 1.0;
}
// Store patch value as initial guess when running in database mode
mappedPatchFieldBase<Type>::initRetrieveField
(
this->internalField().name(),
*this
);
mappedPatchFieldBase<Type>::initRetrieveField
(
this->internalField().name() + "_weights",
this->patch().deltaCoeffs()
);
}
template<class Type>
Foam::mappedMixedFieldFvPatchField<Type>::mappedMixedFieldFvPatchField
(
const mappedMixedFieldFvPatchField<Type>& ptf,
const fvPatch& p,
const DimensionedField<Type, volMesh>& iF,
const fvPatchFieldMapper& mapper
)
:
mixedFvPatchField<Type>(ptf, p, iF, mapper),
mappedPatchBase(p.patch(), ptf),
mappedPatchFieldBase<Type>(*this, *this, ptf),
weightFieldName_(ptf.weightFieldName_)
{}
template<class Type>
Foam::mappedMixedFieldFvPatchField<Type>::mappedMixedFieldFvPatchField
(
const mappedMixedFieldFvPatchField<Type>& ptf
)
:
mixedFvPatchField<Type>(ptf),
mappedPatchBase(ptf.patch().patch(), ptf),
mappedPatchFieldBase<Type>(ptf),
weightFieldName_(ptf.weightFieldName_)
{}
template<class Type>
Foam::mappedMixedFieldFvPatchField<Type>::mappedMixedFieldFvPatchField
(
const mappedMixedFieldFvPatchField<Type>& ptf,
const DimensionedField<Type, volMesh>& iF
)
:
mixedFvPatchField<Type>(ptf, iF),
mappedPatchBase(ptf.patch().patch(), ptf),
mappedPatchFieldBase<Type>(*this, *this, ptf),
weightFieldName_(ptf.weightFieldName_)
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class Type>
void Foam::mappedMixedFieldFvPatchField<Type>::autoMap
(
const fvPatchFieldMapper& m
)
{
mixedFvPatchField<Type>::autoMap(m);
mappedPatchBase::clearOut();
}
template<class Type>
void Foam::mappedMixedFieldFvPatchField<Type>::rmap
(
const fvPatchField<Type>& ptf,
const labelList& addr
)
{
mixedFvPatchField<Type>::rmap(ptf, addr);
mappedPatchBase::clearOut();
}
template<class Type>
void Foam::mappedMixedFieldFvPatchField<Type>::updateCoeffs()
{
if (this->updated())
{
return;
}
const tmp<Field<Type>> nbrIntFld(this->mappedInternalField());
//- Unweighted
//const tmp<scalarField> nbrKDelta(this->mappedWeightField());
//- Weighted
tmp<scalarField> myKDelta;
tmp<scalarField> nbrKDelta;
this->mappedWeightField(weightFieldName_, myKDelta, nbrKDelta);
// Both sides agree on
// - temperature : (myKDelta*fld + nbrKDelta*nbrFld)/(myKDelta+nbrKDelta)
// - gradient : (temperature-fld)*delta
// We've got a degree of freedom in how to implement this in a mixed bc.
// (what gradient, what fixedValue and mixing coefficient)
// Two reasonable choices:
// 1. specify above temperature on one side (preferentially the high side)
// and above gradient on the other. So this will switch between pure
// fixedvalue and pure fixedgradient
// 2. specify gradient and temperature such that the equations are the
// same on both sides. This leads to the choice of
// - refGradient = zero gradient
// - refValue = neighbour value
// - mixFraction = nbrKDelta / (nbrKDelta + myKDelta())
this->refValue() = nbrIntFld;
this->refGrad() = Zero;
this->valueFraction() = nbrKDelta()/(nbrKDelta() + myKDelta());
mixedFvPatchField<Type>::updateCoeffs();
if (debug)
{
Info<< this->patch().boundaryMesh().mesh().name() << ':'
<< this->patch().name() << ':'
<< this->internalField().name() << " <- "
<< this->mapper_.sampleRegion() << ':'
<< this->mapper_.samplePatch() << ':'
<< this->fieldName_ << " :"
<< " value "
<< " min:" << gMin(*this)
<< " max:" << gMax(*this)
<< " avg:" << gAverage(*this)
<< endl;
}
}
template<class Type>
void Foam::mappedMixedFieldFvPatchField<Type>::write(Ostream& os) const
{
mappedPatchBase::write(os);
mappedPatchFieldBase<Type>::write(os);
os.writeEntryIfDifferent<word>("weightField", word::null, weightFieldName_);
mixedFvPatchField<Type>::write(os);
}
// ************************************************************************* //

View File

@ -0,0 +1,234 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2019-2020 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Class
Foam::mappedMixedFieldFvPatchField
Group
grpGenericBoundaryConditions grpCoupledBoundaryConditions
Description
This boundary condition provides a self-contained version of e.g. mapped
boundary conditions
- it expects two-way coupling (so the sampled field needs to run the
same bc)
- it does not use information on the patch; instead it holds the coupling
data locally.
Usage
\table
Property | Description | Required | Default
field | Name of field to be mapped | no | this field name
weightField | Name of field to use as weight | no |
setAverage | Use average value | no | false |
average | Average value to use if \c setAverage = yes | partly |
\endtable
Example of the boundary condition specification:
\verbatim
<patchName>
{
type mappedMixedField;
field T; // optional field name
setAverage no; // apply an average value
average 0; // average to apply if setAverage
value uniform 0; // place holder
}
\endverbatim
Note
Supports multi-world operation:
+----+ +----+
| | | |
| | | |
+----+ +----+
worldA worldB
regionA regionB
patchA patchB
See also
Foam::mappedPatchBase
Foam::mappedPolyPatch
Foam::mappedFvPatch
Foam::mappedFieldFvPatchField
Foam::mixedFvPatchField
SourceFiles
mappedMixedFieldFvPatchField.C
\*---------------------------------------------------------------------------*/
#ifndef mappedMixedFieldFvPatchField_H
#define mappedMixedFieldFvPatchField_H
#include "mappedPatchBase.H"
#include "mappedPatchFieldBase.H"
#include "mixedFvPatchFields.H"
#include "interpolation.H"
#include "volFieldsFwd.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class mappedMixedFieldFvPatchField Declaration
\*---------------------------------------------------------------------------*/
template<class Type>
class mappedMixedFieldFvPatchField
:
public mixedFvPatchField<Type>,
public mappedPatchBase,
public mappedPatchFieldBase<Type>
{
//- Name of weight field to sample
word weightFieldName_;
public:
//- Runtime type information
TypeName("mappedMixedField");
// Constructors
//- Construct from patch and internal field
mappedMixedFieldFvPatchField
(
const fvPatch&,
const DimensionedField<Type, volMesh>&
);
//- Construct from patch, internal field and dictionary
mappedMixedFieldFvPatchField
(
const fvPatch&,
const DimensionedField<Type, volMesh>&,
const dictionary&
);
//- Construct by mapping given
// mappedMixedFieldFvPatchField
// onto a new patch
mappedMixedFieldFvPatchField
(
const mappedMixedFieldFvPatchField<Type>&,
const fvPatch&,
const DimensionedField<Type, volMesh>&,
const fvPatchFieldMapper&
);
//- Construct as copy
mappedMixedFieldFvPatchField
(
const mappedMixedFieldFvPatchField<Type>&
);
//- Construct and return a clone
virtual tmp<fvPatchField<Type>> clone() const
{
return tmp<fvPatchField<Type>>
(
new mappedMixedFieldFvPatchField<Type>
(
*this
)
);
}
//- Construct as copy setting internal field reference
mappedMixedFieldFvPatchField
(
const mappedMixedFieldFvPatchField<Type>&,
const DimensionedField<Type, volMesh>&
);
//- Construct and return a clone setting internal field reference
virtual tmp<fvPatchField<Type>> clone
(
const DimensionedField<Type, volMesh>& iF
) const
{
return tmp<fvPatchField<Type>>
(
new mappedMixedFieldFvPatchField<Type>
(
*this,
iF
)
);
}
// Member functions
// Mapping functions
//- Map (and resize as needed) from self given a mapping object
virtual void autoMap
(
const fvPatchFieldMapper&
);
//- Reverse map the given fvPatchField onto this fvPatchField
virtual void rmap
(
const fvPatchField<Type>&,
const labelList&
);
// Evaluation functions
//- Update the coefficients associated with the patch field
virtual void updateCoeffs();
//- Write
virtual void write(Ostream&) const;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository
#include "mappedMixedFieldFvPatchField.C"
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,44 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2019 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "mappedMixedFieldFvPatchFields.H"
#include "volMesh.H"
#include "addToRunTimeSelectionTable.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
//makeTemplatePatchTypeField(scalar, mappedMixedField);
makePatchFields(mappedMixedField);
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// ************************************************************************* //

View File

@ -0,0 +1,51 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2019 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#ifndef mappedMixedFieldFvPatchFields_H
#define mappedMixedFieldFvPatchFields_H
#include "mappedMixedFieldFvPatchField.H"
#include "fieldTypes.H"
#include "fvPatchFields.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
//makePatchTypeFieldTypedef(scalar, mappedMixedField);
makePatchTypeFieldTypedefs(mappedMixedField)
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -48,6 +48,174 @@ Type Foam::mappedPatchFieldBase<Type>::getAverage
}
template<class Type>
template<class T>
void Foam::mappedPatchFieldBase<Type>::storeField
(
const objectRegistry& obr,
const word& region,
const word& patch,
const labelListList& procToMap,
const word& fieldName,
const Field<T>& fld
) const
{
// Store my data onto database
//const label myRank = Pstream::myProcNo(0); // comm_
const label nProcs = Pstream::nProcs(0); // comm_
for (label domain = 0; domain < nProcs; domain++)
{
const labelList& map = procToMap[domain];
if (map.size())
{
const Field<T> subFld(fld, map);
const objectRegistry& subObr = mappedPatchBase::subRegistry
(
obr,
mapper_.sendPath(domain)
/ region
/ patch
);
if (fvPatchField<Type>::debug)
{
Pout<< "*** STORING :"
<< " field:" << fieldName
<< " values:" << flatOutput(subFld)
<< " as:" << subObr.objectPath() << endl;
}
mappedPatchBase::storeField
(
const_cast<objectRegistry&>(subObr),
fieldName,
subFld
);
}
}
}
template<class Type>
template<class T>
void Foam::mappedPatchFieldBase<Type>::retrieveField
(
const bool allowUnset,
const objectRegistry& obr,
const word& region,
const word& patch,
const labelListList& procToMap,
const word& fieldName,
Field<T>& fld
) const
{
// Store my data onto database
//const label myRank = Pstream::myProcNo(0); // comm_
const label nProcs = Pstream::nProcs(0); // comm_
for (label domain = 0; domain < nProcs; domain++)
{
const labelList& map = procToMap[domain];
if (map.size())
{
const objectRegistry& subObr = mappedPatchBase::subRegistry
(
obr,
mapper_.receivePath(domain)
/ region
/ patch
);
//const IOField<T>& subFld = subObr.lookupObject<IOField<T>>
//(
// fieldName
//);
const IOField<T>* subFldPtr = subObr.getObjectPtr<IOField<T>>
(
fieldName
);
if (subFldPtr)
{
UIndirectList<T>(fld, map) = *subFldPtr;
if (fvPatchField<Type>::debug)
{
Pout<< "*** RETRIEVED :"
<< " field:" << fieldName
<< " values:" << flatOutput(fld)
<< " from:" << subObr.objectPath() << endl;
}
}
else if (allowUnset)
{
WarningInFunction << "Not found"
<< " field:" << fieldName
<< " in:" << subObr.objectPath() << endl;
}
else
{
// Not found. Make it fail
(void)subObr.lookupObject<IOField<T>>(fieldName);
}
}
}
}
template<class Type>
template<class T>
void Foam::mappedPatchFieldBase<Type>::initRetrieveField
(
const objectRegistry& obr,
const word& region,
const word& patch,
const mapDistribute& map,
const word& fieldName,
const Field<T>& fld
) const
{
// Store my data onto database
//const label myRank = Pstream::myProcNo(0); // comm_
const label nProcs = Pstream::nProcs(0); // comm_
for (label domain = 0; domain < nProcs; domain++)
{
const labelList& constructMap = map.constructMap()[domain];
if (constructMap.size())
{
const objectRegistry& subObr = mappedPatchBase::subRegistry
(
obr,
mapper_.receivePath(domain)
/ region
/ patch
);
const Field<T> receiveFld(fld, constructMap);
if (fvPatchField<Type>::debug)
{
Pout<< "*** STORING INITIAL :"
<< " field:" << fieldName << " values:"
<< flatOutput(receiveFld)
<< " from:" << flatOutput(fld)
<< " constructMap:" << flatOutput(constructMap)
<< " as:" << subObr.objectPath() << endl;
}
mappedPatchBase::storeField
(
const_cast<objectRegistry&>(subObr),
fieldName,
receiveFld
);
}
}
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
template<class Type>
@ -92,10 +260,60 @@ Foam::mappedPatchFieldBase<Type>::mappedPatchFieldBase
average_(getAverage(dict, setAverage_)),
interpolationScheme_(interpolationCell<Type>::typeName)
{
if
(
mapper_.sampleDatabase()
&& mapper_.mode() != mappedPatchBase::NEARESTPATCHFACE
)
{
FatalErrorInFunction
<< "Mapping using the database only supported for "
<< "sampleMode "
<< mappedPatchBase::sampleModeNames_
[
mappedPatchBase::NEARESTPATCHFACE
]
<< exit(FatalError);
}
if (mapper_.mode() == mappedPatchBase::NEARESTCELL)
{
dict.readEntry("interpolationScheme", interpolationScheme_);
}
// Note: in database mode derived boundary conditions need to initialise
// fields
}
template<class Type>
Foam::mappedPatchFieldBase<Type>::mappedPatchFieldBase
(
const mappedPatchBase& mapper,
const fvPatchField<Type>& patchField,
const dictionary& dict,
const Field<Type>& fld
)
:
mappedPatchFieldBase<Type>::mappedPatchFieldBase(mapper, patchField, dict)
{
if
(
mapper_.mode() == mappedPatchBase::NEARESTPATCHFACE
&& mapper_.sampleDatabase()
)
{
// Store my data on receive buffers so we have some initial data
initRetrieveField
(
patchField_.internalField().time(),
patchField_.patch().boundaryMesh().mesh().name(),
patchField_.patch().name(),
mapper_.map(),
patchField_.internalField().name(),
patchField_
);
}
}
@ -150,14 +368,15 @@ Foam::mappedPatchFieldBase<Type>::mappedPatchFieldBase
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class Type>
const Foam::GeometricField<Type, Foam::fvPatchField, Foam::volMesh>&
Foam::mappedPatchFieldBase<Type>::sampleField() const
template<class Type2>
const Foam::GeometricField<Type2, Foam::fvPatchField, Foam::volMesh>&
Foam::mappedPatchFieldBase<Type>::sampleField(const word& fieldName) const
{
typedef GeometricField<Type, fvPatchField, volMesh> fieldType;
typedef GeometricField<Type2, fvPatchField, volMesh> fieldType;
if (mapper_.sameRegion())
{
if (fieldName_ == patchField_.internalField().name())
if (fieldName == patchField_.internalField().name())
{
// Optimisation: bypass field lookup
return
@ -169,18 +388,70 @@ Foam::mappedPatchFieldBase<Type>::sampleField() const
else
{
const fvMesh& thisMesh = patchField_.patch().boundaryMesh().mesh();
return thisMesh.template lookupObject<fieldType>(fieldName_);
return thisMesh.template lookupObject<fieldType>(fieldName);
}
}
const fvMesh& nbrMesh = refCast<const fvMesh>(mapper_.sampleMesh());
return nbrMesh.template lookupObject<fieldType>(fieldName_);
return nbrMesh.template lookupObject<fieldType>(fieldName);
}
template<class Type>
const Foam::GeometricField<Type, Foam::fvPatchField, Foam::volMesh>&
Foam::mappedPatchFieldBase<Type>::sampleField() const
{
return sampleField<Type>(fieldName_);
}
template<class Type>
template<class T>
void Foam::mappedPatchFieldBase<Type>::distribute
(
const word& fieldName,
Field<T>& newValues
) const
{
if (mapper_.sampleDatabase())
{
// Store my data on send buffers
storeField
(
patchField_.internalField().time(),
patchField_.patch().boundaryMesh().mesh().name(),
patchField_.patch().name(),
mapper_.map().subMap(),
fieldName,
newValues
);
// Construct my data from receive buffers
newValues.setSize(mapper_.map().constructSize());
retrieveField
(
true, // allow unset
patchField_.internalField().time(),
mapper_.sampleRegion(),
mapper_.samplePatch(),
mapper_.map().constructMap(),
fieldName,
newValues
);
}
else
{
mapper_.distribute(newValues);
}
}
template<class Type>
//template<class T>
Foam::tmp<Foam::Field<Type>>
Foam::mappedPatchFieldBase<Type>::mappedField() const
Foam::mappedPatchFieldBase<Type>::mappedField
(
// const GeometricField<T, fvPatchField, volMesh>& fld
) const
{
typedef GeometricField<Type, fvPatchField, volMesh> fieldType;
@ -190,7 +461,6 @@ Foam::mappedPatchFieldBase<Type>::mappedField() const
UPstream::msgType() = oldTag + 1;
const fvMesh& thisMesh = patchField_.patch().boundaryMesh().mesh();
const fvMesh& nbrMesh = refCast<const fvMesh>(mapper_.sampleMesh());
// Result of obtaining remote values
auto tnewValues = tmp<Field<Type>>::New();
@ -200,12 +470,25 @@ Foam::mappedPatchFieldBase<Type>::mappedField() const
{
case mappedPatchBase::NEARESTCELL:
{
const fieldType& fld = sampleField();
const mapDistribute& distMap = mapper_.map();
if (interpolationScheme_ != interpolationCell<Type>::typeName)
{
if (!mapper_.sameWorld() || mapper_.sampleDatabase())
{
FatalErrorInFunction
<< "Interpolating cell values from different world"
<< " or database currently not supported"
<< exit(FatalError);
}
const fvMesh& nbrMesh =
refCast<const fvMesh>(mapper_.sampleMesh());
// Send back sample points to the processor that holds the cell
vectorField samples(mapper_.samplePoints());
distMap.reverseDistribute
(
(
@ -221,7 +504,7 @@ Foam::mappedPatchFieldBase<Type>::mappedField() const
interpolation<Type>::New
(
interpolationScheme_,
sampleField()
fld
);
const auto& interp = *interpolator;
@ -241,52 +524,94 @@ Foam::mappedPatchFieldBase<Type>::mappedField() const
}
else
{
newValues = sampleField();
newValues = fld;
}
distMap.distribute(newValues);
distribute(fieldName_, newValues);
break;
}
case mappedPatchBase::NEARESTPATCHFACE:
case mappedPatchBase::NEARESTPATCHFACEAMI:
{
const label nbrPatchID =
nbrMesh.boundaryMesh().findPatchID(mapper_.samplePatch());
if (nbrPatchID < 0)
if (mapper_.sameWorld())
{
FatalErrorInFunction
<< "Unable to find sample patch " << mapper_.samplePatch()
<< " in region " << mapper_.sampleRegion()
<< " for patch " << patchField_.patch().name() << nl
<< abort(FatalError);
const fvMesh& nbrMesh =
refCast<const fvMesh>(mapper_.sampleMesh());
const fieldType& fld = sampleField();
const label nbrPatchID =
nbrMesh.boundaryMesh().findPatchID(mapper_.samplePatch());
if (nbrPatchID < 0)
{
FatalErrorInFunction
<< "Unable to find sample patch " << mapper_.samplePatch()
<< " in region " << mapper_.sampleRegion()
<< " for patch " << patchField_.patch().name() << nl
<< abort(FatalError);
}
const auto& nbrField = fld;
newValues = nbrField.boundaryField()[nbrPatchID];
}
const fieldType& nbrField = sampleField();
newValues = nbrField.boundaryField()[nbrPatchID];
mapper_.distribute(newValues);
else
{
// Start off from my patch values, let distribute function below
// do all the work
newValues = patchField_;
}
distribute(fieldName_, newValues);
break;
}
case mappedPatchBase::NEARESTFACE:
{
Field<Type> allValues(nbrMesh.nFaces(), Zero);
const fieldType& nbrField = sampleField();
for (const fvPatchField<Type>& pf : nbrField.boundaryField())
Field<Type> allValues;
if (mapper_.sameWorld())
{
label faceStart = pf.patch().start();
const fvMesh& nbrMesh =
refCast<const fvMesh>(mapper_.sampleMesh());
const fieldType& fld = sampleField();
forAll(pf, facei)
allValues.setSize(nbrMesh.nFaces(), Zero);
const auto& nbrField = fld;
for (const fvPatchField<Type>& pf : nbrField.boundaryField())
{
allValues[faceStart++] = pf[facei];
label faceStart = pf.patch().start();
forAll(pf, facei)
{
allValues[faceStart++] = pf[facei];
}
}
}
else
{
// Start off from my patch values. Let distribute function below
// do all the work
allValues.setSize(thisMesh.nFaces(), Zero);
const fieldType& thisFld = dynamic_cast<const fieldType&>
(
patchField_.internalField()
);
for (const fvPatchField<Type>& pf : thisFld.boundaryField())
{
label faceStart = pf.patch().start();
forAll(pf, facei)
{
allValues[faceStart++] = pf[facei];
}
}
}
mapper_.distribute(allValues);
distribute(fieldName_, allValues);
newValues.transfer(allValues);
break;
@ -322,6 +647,197 @@ Foam::mappedPatchFieldBase<Type>::mappedField() const
}
//template<class Type>
//Foam::tmp<Foam::Field<Type>>
//Foam::mappedPatchFieldBase<Type>::mappedField() const
//{
// const GeometricField<Type, fvPatchField, volMesh>& fld = sampleField();
// return mappedField<Type>(fld);
//}
template<class Type>
Foam::tmp<Foam::Field<Type>>
Foam::mappedPatchFieldBase<Type>::mappedInternalField() const
{
// Swap to obtain full local values of neighbour internal field
tmp<Field<Type>> tnbrIntFld(new Field<Type>());
Field<Type>& nbrIntFld = tnbrIntFld.ref();
if (mapper_.sameWorld())
{
// Same world so lookup
const label nbrPatchID = mapper_.samplePolyPatch().index();
const auto& nbrField = this->sampleField();
nbrIntFld = nbrField.boundaryField()[nbrPatchID].patchInternalField();
}
else
{
// Different world so use my region,patch. Distribution below will
// do the reordering
nbrIntFld = patchField_.patchInternalField();
}
// Since we're inside initEvaluate/evaluate there might be processor
// comms underway. Change the tag we use.
int oldTag = UPstream::msgType();
UPstream::msgType() = oldTag+1;
distribute(fieldName_, nbrIntFld);
// Restore tag
UPstream::msgType() = oldTag;
return tnbrIntFld;
}
template<class Type>
Foam::tmp<Foam::scalarField>
Foam::mappedPatchFieldBase<Type>::mappedWeightField() const
{
// Swap to obtain full local values of neighbour internal field
tmp<scalarField> tnbrKDelta(new scalarField());
scalarField& nbrKDelta = tnbrKDelta.ref();
if (mapper_.sameWorld())
{
// Same world so lookup
const auto& nbrMesh = refCast<const fvMesh>(this->mapper_.sampleMesh());
const label nbrPatchID = mapper_.samplePolyPatch().index();
const auto& nbrPatch = nbrMesh.boundary()[nbrPatchID];
nbrKDelta = nbrPatch.deltaCoeffs();
}
else
{
// Different world so use my region,patch. Distribution below will
// do the reordering
nbrKDelta = patchField_.patch().deltaCoeffs();
}
// Since we're inside initEvaluate/evaluate there might be processor
// comms underway. Change the tag we use.
const int oldTag = UPstream::msgType();
UPstream::msgType() = oldTag+1;
distribute(fieldName_ + "_deltaCoeffs", nbrKDelta);
// Restore tag
UPstream::msgType() = oldTag;
return tnbrKDelta;
}
template<class Type>
void Foam::mappedPatchFieldBase<Type>::mappedWeightField
(
const word& fieldName,
tmp<scalarField>& thisWeights,
tmp<scalarField>& nbrWeights
) const
{
thisWeights = new scalarField(patchField_.patch().deltaCoeffs());
if (!fieldName.empty())
{
thisWeights.ref() *=
patchField_.patch().template lookupPatchField
<
volScalarField,
scalar
>
(
fieldName
).patchInternalField();
}
// Swap to obtain full local values of neighbour internal field
if (mapper_.sameWorld())
{
// Same world so lookup
const auto& nbrMesh = refCast<const fvMesh>(mapper_.sampleMesh());
const label nbrPatchID = mapper_.samplePolyPatch().index();
const auto& nbrPatch = nbrMesh.boundary()[nbrPatchID];
nbrWeights = new scalarField(nbrPatch.deltaCoeffs());
if (!fieldName.empty())
{
// Weightfield is volScalarField
const auto& nbrWeightField =
nbrMesh.template lookupObject<volScalarField>(fieldName);
nbrWeights.ref() *=
nbrWeightField.boundaryField()[nbrPatchID].patchInternalField();
}
}
else
{
// Different world so use my region,patch. Distribution below will
// do the reordering
nbrWeights = new scalarField(thisWeights());
}
// Since we're inside initEvaluate/evaluate there might be processor
// comms underway. Change the tag we use.
int oldTag = UPstream::msgType();
UPstream::msgType() = oldTag+1;
distribute(fieldName_ + "_weights", nbrWeights.ref());
// Restore tag
UPstream::msgType() = oldTag;
}
template<class Type>
const Foam::mappedPatchBase& Foam::mappedPatchFieldBase<Type>::mapper
(
const fvPatch& p,
const DimensionedField<Type, volMesh>& iF
)
{
if (!isA<mappedPatchBase>(p.patch()))
{
FatalErrorInFunction
<< "Incorrect patch type " << p.patch().type()
<< " for patch " << p.patch().name()
<< " of field " << iF.name()
<< " in file " << iF.objectPath() << nl
<< "Type should be a mappedPatch"
<< exit(FatalError);
}
return refCast<const mappedPatchBase>(p.patch());
}
template<class Type>
template<class T>
void Foam::mappedPatchFieldBase<Type>::initRetrieveField
(
const word& fieldName,
const Field<T>& fld
) const
{
if (mapper_.sampleDatabase())
{
// Store my data on receive buffers (reverse of storeField;
// i.e. retrieveField will obtain patchField)
initRetrieveField
(
patchField_.internalField().time(),
mapper_.sampleRegion(),
mapper_.samplePatch(),
mapper_.map(),
fieldName,
fld
);
}
}
template<class Type>
void Foam::mappedPatchFieldBase<Type>::write(Ostream& os) const
{
@ -333,7 +849,10 @@ void Foam::mappedPatchFieldBase<Type>::write(Ostream& os) const
os.writeEntry("average", average_);
}
os.writeEntry("interpolationScheme", interpolationScheme_);
if (mapper_.mode() == mappedPatchBase::NEARESTCELL)
{
os.writeEntry("interpolationScheme", interpolationScheme_);
}
}

View File

@ -67,6 +67,7 @@ namespace Foam
// Forward declarations
class mappedPatchBase;
template<class> class interpolation;
class mapDistribute;
/*---------------------------------------------------------------------------*\
Class mappedPatchFieldBase Declaration
@ -80,6 +81,7 @@ class mappedPatchFieldBase
//- Selective retrieval of "average" entry from the dictionary
static Type getAverage(const dictionary& dict, bool mandatory);
protected:
// Protected data
@ -104,6 +106,21 @@ protected:
word interpolationScheme_;
// Protected Member Functions
//- Construct field from registered elements
template<class T>
void initRetrieveField
(
const objectRegistry& obr,
const word& region,
const word& patch,
const mapDistribute& map,
const word& fieldName,
const Field<T>& fld
) const;
public:
// Constructors
@ -127,6 +144,16 @@ public:
const dictionary& dict
);
//- Construct from dictionary and initial field value
// (for when running in database mode)
mappedPatchFieldBase
(
const mappedPatchBase& mapper,
const fvPatchField<Type>& patchField,
const dictionary& dict,
const Field<Type>& fld
);
//- Construct empty
mappedPatchFieldBase
(
@ -135,7 +162,7 @@ public:
);
//- Construct copy
mappedPatchFieldBase
explicit mappedPatchFieldBase
(
const mappedPatchFieldBase<Type>& mapper
);
@ -155,14 +182,84 @@ public:
// Member Functions
//- Field to sample. Either on my or nbr mesh
template<class T>
const GeometricField<T, fvPatchField, volMesh>& sampleField
(
const word& fieldName
) const;
//- Field to sample. Either on my or nbr mesh
const GeometricField<Type, fvPatchField, volMesh>& sampleField() const;
//- Map sampleField onto *this patch
virtual tmp<Field<Type>> mappedField() const;
//- Map internal of sampleField onto *this patch
virtual tmp<Field<Type>> mappedInternalField() const;
//- Map optional weightField onto *this patch. Default is deltaCoeffs
virtual tmp<scalarField> mappedWeightField() const;
//- Map optional weightField (given by name) onto *this patch
virtual void mappedWeightField
(
const word& weightFieldName,
tmp<scalarField>& thisWeights,
tmp<scalarField>& nbrWeights
) const;
//- Write
virtual void write(Ostream& os) const;
// Helpers
//- Check that patch is of correct type
static const mappedPatchBase& mapper
(
const fvPatch& p,
const DimensionedField<Type, volMesh>& iF
);
//- Initialise field to retrieve (used e.g. when value read from
// dictionary)
template<class T>
void initRetrieveField
(
const word& fieldName,
const Field<T>& fld
) const;
//- Store elements of field onto (sub) registry
template<class T>
void storeField
(
const objectRegistry& obr,
const word& region,
const word& patch,
const labelListList& procToMap,
const word& fieldName,
const Field<T>& fld
) const;
//- Construct field from registered elements
template<class T>
void retrieveField
(
const bool allowUnset,
const objectRegistry& obr,
const word& region,
const word& patch,
const labelListList& procToMap,
const word& fieldName,
Field<T>& fld
) const;
//- Wrapper for mapDistribute::distribute that knows about
//- dabase mapping
template<class T>
void distribute(const word& fieldName, Field<T>& newValues) const;
};

View File

@ -38,7 +38,7 @@ Foam::mappedFixedValueFvPatchField<Type>::mappedFixedValueFvPatchField
)
:
fixedValueFvPatchField<Type>(p, iF),
mappedPatchFieldBase<Type>(this->mapper(p, iF), *this)
mappedPatchFieldBase<Type>(mappedPatchFieldBase<Type>::mapper(p, iF), *this)
{}
@ -51,7 +51,13 @@ Foam::mappedFixedValueFvPatchField<Type>::mappedFixedValueFvPatchField
)
:
fixedValueFvPatchField<Type>(p, iF, dict),
mappedPatchFieldBase<Type>(this->mapper(p, iF), *this, dict)
mappedPatchFieldBase<Type>
(
mappedPatchFieldBase<Type>::mapper(p, iF),
*this,
dict,
*this // initial value for database operation
)
{}
@ -65,7 +71,12 @@ Foam::mappedFixedValueFvPatchField<Type>::mappedFixedValueFvPatchField
)
:
fixedValueFvPatchField<Type>(ptf, p, iF, mapper),
mappedPatchFieldBase<Type>(this->mapper(p, iF), *this, ptf)
mappedPatchFieldBase<Type>
(
mappedPatchFieldBase<Type>::mapper(p, iF),
*this,
ptf
)
{}
@ -88,32 +99,17 @@ Foam::mappedFixedValueFvPatchField<Type>::mappedFixedValueFvPatchField
)
:
fixedValueFvPatchField<Type>(ptf, iF),
mappedPatchFieldBase<Type>(this->mapper(this->patch(), iF), *this, ptf)
mappedPatchFieldBase<Type>
(
mappedPatchFieldBase<Type>::mapper(this->patch(), iF),
*this,
ptf
)
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class Type>
const Foam::mappedPatchBase& Foam::mappedFixedValueFvPatchField<Type>::mapper
(
const fvPatch& p,
const DimensionedField<Type, volMesh>& iF
)
{
if (!isA<mappedPatchBase>(p.patch()))
{
FatalErrorInFunction
<< "' not type '" << mappedPatchBase::typeName << "'"
<< "\n for patch " << p.patch().name()
<< " of field " << iF.name()
<< " in file " << iF.objectPath()
<< exit(FatalError);
}
return refCast<const mappedPatchBase>(p.patch());
}
template<class Type>
void Foam::mappedFixedValueFvPatchField<Type>::updateCoeffs()
{

View File

@ -103,18 +103,6 @@ class mappedFixedValueFvPatchField
public fixedValueFvPatchField<Type>,
public mappedPatchFieldBase<Type>
{
protected:
// Protected Member Functions
const mappedPatchBase& mapper
(
const fvPatch& p,
const DimensionedField<Type, volMesh>& iF
);
public:
//- Runtime type information
@ -190,6 +178,7 @@ public:
//- Update the coefficients associated with the patch field
virtual void updateCoeffs();
//- Write
virtual void write(Ostream&) const;
};

View File

@ -0,0 +1,242 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2020 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "mappedMixedFvPatchField.H"
#include "volFields.H"
#include "interpolationCell.H"
#include "mappedFixedValueFvPatchField.H"
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
template<class Type>
Foam::mappedMixedFvPatchField<Type>::mappedMixedFvPatchField
(
const fvPatch& p,
const DimensionedField<Type, volMesh>& iF
)
:
mixedFvPatchField<Type>(p, iF),
mappedPatchFieldBase<Type>
(
mappedFixedValueFvPatchField<Type>::mapper(p, iF),
*this
),
weightFieldName_(word::null)
{
this->refValue() = Zero;
this->refGrad() = Zero;
this->valueFraction() = 0.0;
}
template<class Type>
Foam::mappedMixedFvPatchField<Type>::mappedMixedFvPatchField
(
const fvPatch& p,
const DimensionedField<Type, volMesh>& iF,
const dictionary& dict
)
:
mixedFvPatchField<Type>(p, iF, dict),
mappedPatchFieldBase<Type>
(
mappedFixedValueFvPatchField<Type>::mapper(p, iF),
*this,
dict
),
weightFieldName_(dict.getOrDefault<word>("weightField", word::null))
{
mixedFvPatchField<Type>::operator=
(
Field<Type>("value", dict, p.size())
);
if (dict.found("refValue"))
{
// Full restart
this->refValue() = Field<Type>("refValue", dict, p.size());
this->refGrad() = Field<Type>("refGradient", dict, p.size());
this->valueFraction() = scalarField("valueFraction", dict, p.size());
}
else
{
// Start from user entered data. Assume fixedValue.
this->refValue() = *this;
this->refGrad() = Zero;
this->valueFraction() = 1.0;
}
// Store patch value as initial guess when running in database mode
mappedPatchFieldBase<Type>::initRetrieveField
(
this->internalField().name(),
*this
);
mappedPatchFieldBase<Type>::initRetrieveField
(
this->internalField().name() + "_weights",
this->patch().deltaCoeffs()
);
}
template<class Type>
Foam::mappedMixedFvPatchField<Type>::mappedMixedFvPatchField
(
const mappedMixedFvPatchField<Type>& ptf,
const fvPatch& p,
const DimensionedField<Type, volMesh>& iF,
const fvPatchFieldMapper& mapper
)
:
mixedFvPatchField<Type>(ptf, p, iF, mapper),
mappedPatchFieldBase<Type>
(
mappedFixedValueFvPatchField<Type>::mapper(p, iF),
*this,
ptf
),
weightFieldName_(ptf.weightFieldName_)
{}
template<class Type>
Foam::mappedMixedFvPatchField<Type>::mappedMixedFvPatchField
(
const mappedMixedFvPatchField<Type>& ptf
)
:
mixedFvPatchField<Type>(ptf),
mappedPatchFieldBase<Type>(ptf),
weightFieldName_(ptf.weightFieldName_)
{}
template<class Type>
Foam::mappedMixedFvPatchField<Type>::mappedMixedFvPatchField
(
const mappedMixedFvPatchField<Type>& ptf,
const DimensionedField<Type, volMesh>& iF
)
:
mixedFvPatchField<Type>(ptf, iF),
mappedPatchFieldBase<Type>
(
mappedFixedValueFvPatchField<Type>::mapper(ptf.patch(), iF),
*this,
ptf
),
weightFieldName_(ptf.weightFieldName_)
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class Type>
void Foam::mappedMixedFvPatchField<Type>::autoMap(const fvPatchFieldMapper& m)
{
mixedFvPatchField<Type>::autoMap(m);
}
template<class Type>
void Foam::mappedMixedFvPatchField<Type>::rmap
(
const fvPatchField<Type>& ptf,
const labelList& addr
)
{
mixedFvPatchField<Type>::rmap(ptf, addr);
}
template<class Type>
void Foam::mappedMixedFvPatchField<Type>::updateCoeffs()
{
if (this->updated())
{
return;
}
const tmp<Field<Type>> nbrIntFld(this->mappedInternalField());
//- Unweighted
//const tmp<scalarField> nbrKDelta(this->mappedWeightField());
//- Weighted
tmp<scalarField> myKDelta;
tmp<scalarField> nbrKDelta;
this->mappedWeightField(weightFieldName_, myKDelta, nbrKDelta);
// Both sides agree on
// - temperature : (myKDelta*fld + nbrKDelta*nbrFld)/(myKDelta+nbrKDelta)
// - gradient : (temperature-fld)*delta
// We've got a degree of freedom in how to implement this in a mixed bc.
// (what gradient, what fixedValue and mixing coefficient)
// Two reasonable choices:
// 1. specify above temperature on one side (preferentially the high side)
// and above gradient on the other. So this will switch between pure
// fixedvalue and pure fixedgradient
// 2. specify gradient and temperature such that the equations are the
// same on both sides. This leads to the choice of
// - refGradient = zero gradient
// - refValue = neighbour value
// - mixFraction = nbrKDelta / (nbrKDelta + myKDelta())
this->refValue() = nbrIntFld;
this->refGrad() = Zero;
this->valueFraction() = nbrKDelta()/(nbrKDelta() + myKDelta());
mixedFvPatchField<Type>::updateCoeffs();
if (debug)
{
Info<< this->patch().boundaryMesh().mesh().name() << ':'
<< this->patch().name() << ':'
<< this->internalField().name() << " <- "
<< this->mapper_.sampleRegion() << ':'
<< this->mapper_.samplePatch() << ':'
<< this->fieldName_ << " :"
<< " value "
<< " min:" << gMin(*this)
<< " max:" << gMax(*this)
<< " avg:" << gAverage(*this)
<< endl;
}
}
template<class Type>
void Foam::mappedMixedFvPatchField<Type>::write(Ostream& os) const
{
mappedPatchFieldBase<Type>::write(os);
os.writeEntryIfDifferent<word>("weightField", word::null, weightFieldName_);
mixedFvPatchField<Type>::write(os);
}
// ************************************************************************* //

View File

@ -0,0 +1,232 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2019-2020 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Class
Foam::mappedMixedFvPatchField
Group
grpGenericBoundaryConditions grpCoupledBoundaryConditions
Description
This boundary condition maps the value at a set of cells or patch faces
back to *this.
The sample mode is set by the underlying mapping engine, provided by the
mappedPatchBase class.
Usage
\table
Property | Description | Required | Default
field | Name of field to be mapped | no | this field name
weightField | Name of field to use as weight | no |
setAverage | Use average value | no | false |
average | Average value to use if \c setAverage = yes | partly |
\endtable
Example of the boundary condition specification:
\verbatim
<patchName>
{
type mappedMixed;
field T; // optional field name
value uniform 273.0;
refValue $value;
refGradient uniform 0.0;
valueFraction uniform 1.0;
}
\endverbatim
Note
Supports multi-world operation:
+----+ +----+
| | | |
| | | |
+----+ +----+
worldA worldB
regionA regionB
patchA patchB
See also
Foam::mappedPatchBase
Foam::mappedPolyPatch
Foam::mappedFvPatch
Foam::mappedFieldFvPatchField
Foam::mixedFvPatchField
SourceFiles
mappedMixedFvPatchField.C
\*---------------------------------------------------------------------------*/
#ifndef mappedMixedFvPatchField_H
#define mappedMixedFvPatchField_H
#include "mappedPatchFieldBase.H"
#include "mixedFvPatchFields.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class mappedMixedFvPatchField Declaration
\*---------------------------------------------------------------------------*/
template<class Type>
class mappedMixedFvPatchField
:
public mixedFvPatchField<Type>,
public mappedPatchFieldBase<Type>
{
//- Name of weight field to sample
word weightFieldName_;
public:
//- Runtime type information
TypeName("mappedMixed");
// Constructors
//- Construct from patch and internal field
mappedMixedFvPatchField
(
const fvPatch&,
const DimensionedField<Type, volMesh>&
);
//- Construct from patch, internal field and dictionary
mappedMixedFvPatchField
(
const fvPatch&,
const DimensionedField<Type, volMesh>&,
const dictionary&
);
//- Construct by mapping given
// mappedMixedFvPatchField
// onto a new patch
mappedMixedFvPatchField
(
const mappedMixedFvPatchField<Type>&,
const fvPatch&,
const DimensionedField<Type, volMesh>&,
const fvPatchFieldMapper&
);
//- Construct as copy
mappedMixedFvPatchField
(
const mappedMixedFvPatchField<Type>&
);
//- Construct and return a clone
virtual tmp<fvPatchField<Type>> clone() const
{
return tmp<fvPatchField<Type>>
(
new mappedMixedFvPatchField<Type>
(
*this
)
);
}
//- Construct as copy setting internal field reference
mappedMixedFvPatchField
(
const mappedMixedFvPatchField<Type>&,
const DimensionedField<Type, volMesh>&
);
//- Construct and return a clone setting internal field reference
virtual tmp<fvPatchField<Type>> clone
(
const DimensionedField<Type, volMesh>& iF
) const
{
return tmp<fvPatchField<Type>>
(
new mappedMixedFvPatchField<Type>
(
*this,
iF
)
);
}
// Member functions
// Mapping functions
//- Map (and resize as needed) from self given a mapping object
virtual void autoMap
(
const fvPatchFieldMapper&
);
//- Reverse map the given fvPatchField onto this fvPatchField
virtual void rmap
(
const fvPatchField<Type>&,
const labelList&
);
// Evaluation functions
//- Update the coefficients associated with the patch field
virtual void updateCoeffs();
//- Write
virtual void write(Ostream&) const;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository
#include "mappedMixedFvPatchField.C"
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,44 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2020 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "mappedMixedFvPatchFields.H"
#include "volMesh.H"
#include "addToRunTimeSelectionTable.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
//makeTemplatePatchTypeField(scalar, mappedMixed);
makePatchFields(mappedMixed);
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// ************************************************************************* //

View File

@ -0,0 +1,51 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2019 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#ifndef mappedMixedFvPatchFields_H
#define mappedMixedFvPatchFields_H
#include "mappedMixedFvPatchField.H"
#include "fieldTypes.H"
#include "fvPatchFields.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
//makePatchTypeFieldTypedef(scalar, mappedMixed);
makePatchTypeFieldTypedefs(mappedMixed)
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -39,4 +39,6 @@ writeObjects/writeObjects.C
thermoCoupleProbes/thermoCoupleProbes.C
syncObjects/syncObjects.C
LIB = $(FOAM_LIBBIN)/libutilityFunctionObjects

View File

@ -0,0 +1,228 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2020 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "syncObjects.H"
#include "Time.H"
#include "polyMesh.H"
#include "addToRunTimeSelectionTable.H"
#include "objectRegistry.H"
#include "mappedPatchBase.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
namespace functionObjects
{
defineTypeNameAndDebug(syncObjects, 0);
addToRunTimeSelectionTable
(
functionObject,
syncObjects,
dictionary
);
}
}
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::functionObjects::syncObjects::syncObjects
(
const word& name,
const Time& runTime,
const dictionary& dict
)
:
functionObject(name),
obr_
(
//runTime.lookupObject<objectRegistry>
//(
// dict.lookupOrDefault("region", polyMesh::defaultRegion)
//)
runTime
)
{
read(dict);
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
void Foam::functionObjects::syncObjects::sync()
{
if (debug)
{
Pout<< type() << " : sync()"
<< " root:" << root_ << endl;
}
const label oldWarnComm = UPstream::warnComm;
UPstream::warnComm = 0;
if (!Pstream::parRun())
{
return;
}
// Send my data to all other processors
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Note provision of explicit all-world communicator
PstreamBuffers pBufs
(
Pstream::commsTypes::nonBlocking,
UPstream::msgType(),
0
);
const label nProcs = Pstream::nProcs(pBufs.comm());
for (label proci = 0; proci < nProcs; proci++)
{
// Get database to send
const objectRegistry& sendObr = mappedPatchBase::subRegistry
(
obr_,
mappedPatchBase::sendPath(root_, proci)
);
// Pack into dictionary
dictionary sendDataDict;
mappedPatchBase::writeDict(sendObr, sendDataDict);
//Pout<< "** to processor " << proci
// << " sendObr:" << sendObr.objectPath()
// << " sending dictionary:" << sendDataDict << endl;
UOPstream os(proci, pBufs);
os << sendDataDict;
}
// Start sending and receiving and block
pBufs.finishedSends();
for (label proci = 0; proci < nProcs; proci++)
{
// Get database to receive data into
const objectRegistry& receiveObr = mappedPatchBase::subRegistry
(
obr_,
mappedPatchBase::receivePath(root_, proci)
);
//Pout<< "** from processor " << proci
// << " receiveObr:" << receiveObr.objectPath()
// << " receiving dictionary" << endl;
UIPstream is(proci, pBufs);
const dictionary fromProcDict(is);
//Pout<< "** from processor " << proci
// << " received dictionary:" << fromProcDict << endl;
mappedPatchBase::readDict
(
fromProcDict,
const_cast<objectRegistry&>(receiveObr)
);
}
//if (debug)
//{
// dictionary allDict;
// // Add send subdictionary
// dictionary& sendDict = allDict.subDictOrAdd("send");
// mappedPatchBase::writeDict
// (
// mappedPatchBase::subRegistry(obr_, "send"),
// sendDict
// );
// // Add receive subdictionary
// dictionary& receiveDict = allDict.subDictOrAdd("receive");
// mappedPatchBase::writeDict
// (
// mappedPatchBase::subRegistry(obr_, "receive"),
// receiveDict
// );
// Pout<< type() << " : after synchronisation:" << allDict << endl;
//}
UPstream::warnComm = oldWarnComm;
}
bool Foam::functionObjects::syncObjects::read(const dictionary& dict)
{
if (debug)
{
Pout<< type() << " : read(const dictionary&)" << endl;
}
functionObject::read(dict);
root_ = dict.getOrDefault<fileName>("root", fileName::null);
if (debug)
{
Pout<< type() << " : root:" << root_ << endl;
}
// Make sure that at startup we're doing a sync (execute below only gets
// called at end of timeloop)
sync();
return true;
}
bool Foam::functionObjects::syncObjects::execute()
{
if (debug)
{
Pout<< type() << " : execute()" << endl;
}
sync();
return true;
}
bool Foam::functionObjects::syncObjects::write()
{
if (debug)
{
Pout<< type() << " : write()" << endl;
}
return true;
}
// ************************************************************************* //

View File

@ -0,0 +1,178 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2020 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Class
Foam::functionObjects::syncObjects
Group
grpUtilitiesFunctionObjects
Description
Copies content of local objectRegistry to all processors.
Currently only supports IOFields. It is used to distribute IOFields
from different processors/regions/worlds
when doing loose coupling. To be used in combination with 'mapped'
boundary conditions.
Usage
Example of function object specification:
\verbatim
syncObjects1
{
type syncObjects;
libs ("libutilityFunctionObjects.so");
...
// Where is data located relative to runTime. Given as a filename
// with every '/' indicating a sub-objectRegistry w.r.t. runTime.
// Local data is under <root>/send/processorXXX. After execution
// (potentially remote) data will be under the corresponding
// <root>/receive/processorYYY objectRegistry.
//root "level0/level1/level2";
}
\endverbatim
Where the entries comprise:
\table
Property | Description | Required | Default value
type | type name: syncObjects | yes |
root | relative location of data | no | ""
\endtable
See also
Foam::functionObject
SourceFiles
syncObjects.C
\*---------------------------------------------------------------------------*/
#ifndef functionObjects_syncObjects_H
#define functionObjects_syncObjects_H
#include "token.H"
#include "functionObject.H"
#include "IOField.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// Forward declaration of classes
class objectRegistry;
namespace functionObjects
{
/*---------------------------------------------------------------------------*\
Class functionObjects::syncObjects Declaration
\*---------------------------------------------------------------------------*/
class syncObjects
:
public functionObject
{
private:
// Private data
//- Top-level registry
const objectRegistry& obr_;
//- objectRegistry location relative to top-level
fileName root_;
// Private Member Functions
//- No copy construct
syncObjects(const syncObjects&) = delete;
//- No copy assignment
void operator=(const syncObjects&) = delete;
protected:
//- Do all: synchronise all IOFields and objectRegistry
void sync();
public:
//- Runtime type information
TypeName("syncObjects");
// Constructors
//- Construct from Time and dictionary
syncObjects
(
const word& name,
const Time& runTime,
const dictionary& dict
);
//- Destructor
virtual ~syncObjects() = default;
// Member Functions
const objectRegistry& obr() const
{
return obr_;
}
const fileName& root() const
{
return root_;
}
//- Read the syncObjects data
virtual bool read(const dictionary&);
//- Do nothing
virtual bool execute();
//- Write the registered objects
virtual bool write();
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace functionObjects
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,33 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2020 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "objectRegistry.H"
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
// ************************************************************************* //

View File

@ -737,9 +737,9 @@ bool Foam::faceAreaWeightAMI::calculate
extendedTgtMapPtr_->subMap(),
false, // has flip
tgtAddress_,
labelList(),
ListOps::appendEqOp<label>(),
flipOp(), // flip operation
labelList()
flipOp() // flip operation
);
mapDistributeBase::distribute
@ -752,9 +752,9 @@ bool Foam::faceAreaWeightAMI::calculate
extendedTgtMapPtr_->subMap(),
false,
tgtWeights_,
scalarList(),
ListOps::appendEqOp<scalar>(),
flipOp(),
scalarList()
flipOp()
);
// Note: using patch face areas calculated by the AMI method

View File

@ -200,9 +200,9 @@ Foam::autoPtr<Foam::mapDistribute> Foam::nearestFaceAMI::calcDistributed
map.subMap(),
map.subHasFlip(),
remoteInfo,
nearestZero,
nearestEqOp(),
noOp(), // no flipping
nearestZero
noOp() // no flipping
);

File diff suppressed because it is too large Load Diff

View File

@ -33,6 +33,13 @@ Description
If constructed from dictionary:
\verbatim
// Optional world to sample (default is all)
//sampleWorld solidSim;
// Optional explicit coupling (requires functionObject to synchronise
// databases. Default is close coupling (bc to bc)
//sampleDatabase true;
// Region to sample (default is region0)
sampleRegion region0;
@ -184,6 +191,38 @@ public:
};
//- nearest + world
// Used to only look at entries from same world
typedef Tuple2<nearInfo, label> nearInfoWorld;
class nearestWorldEqOp
{
public:
void operator()(nearInfoWorld& x, const nearInfoWorld& y) const
{
// Is there a hit and is it sampling the same world
const nearInfo& xi = x.first();
const nearInfo& yi = y.first();
if (yi.first().hit())
{
if (x.second() == y.second())
{
if (!xi.first().hit())
{
x = y;
}
else if (yi.second().first() < xi.second().first())
{
x = y;
}
}
}
}
};
protected:
// Protected data
@ -191,6 +230,9 @@ protected:
//- Patch to sample
const polyPatch& patch_;
//- World to sample
mutable word sampleWorld_;
//- Region to sample
mutable word sampleRegion_;
@ -203,6 +245,9 @@ protected:
//- PatchGroup (if in sampleMode NEARESTPATCH*)
const coupleGroupIdentifier coupleGroup_;
//- Empty or location of database
const autoPtr<fileName> sampleDatabasePtr_;
//- How to obtain samples
offsetMode offsetMode_;
@ -215,6 +260,9 @@ protected:
//- Offset distance (normal)
scalar distance_;
//- Communicator
label comm_;
//- Same region
mutable bool sameRegion_;
@ -246,25 +294,59 @@ protected:
// Protected Member Functions
//- Optionally allocate a world-local communicator
static label communicator(const word& sampleWorld);
//- Lookup mesh
const polyMesh& lookupMesh(const word& region) const;
//- Lookup patch
const polyPatch& lookupPatch
(
const word& sampleRegion,
const word& samplePatch
) const;
//- Get the points from face-centre-decomposition face centres
// and project them onto the face-diagonal-decomposition triangles.
tmp<pointField> facePoints(const polyPatch&) const;
//- Collect single list of samples and originating processor+face.
//- Collect single list of samples and originating processor+face +
// wanted world
void collectSamples
(
const label mySampleWorld, // My wanted sampling world
const pointField& facePoints,
pointField&,
labelList& patchFaceProcs,
labelList& patchFaces,
pointField& samples, // Per sample: coordinate
labelList& patchFaceWorlds, // Per sample: wanted world
labelList& patchFaceProcs, // Per sample: originating proc
labelList& patchFaces, // Per sample: originating face
pointField& patchFc
) const;
//- Find cells/faces containing samples
//- Find (local) cells/faces containing samples
void findLocalSamples
(
const sampleMode mode,
const label sampleWorld, // my world as index
const word& sampleRegion,
const word& samplePatch,
const pointField& samplePoints,
List<nearInfoWorld>& nearest
) const;
//- Find (global) cells/faces containing samples
void findSamples
(
const sampleMode mode, // search mode
const label myWorldIndex, // my world (in index form)
const pointField&,
const labelList& wantedWorlds,
const labelList& origProcs, // per sample the originating proc
labelList& sampleProcs, // processor containing sample
labelList& sampleIndices, // local index of cell/face
pointField& sampleLocations // actual representative location
@ -280,6 +362,38 @@ protected:
void calcAMI() const;
// Database handling
//- Read optional database name from dictionary
static autoPtr<fileName> readDatabase(const dictionary& dict);
//- Lookup (sub)objectRegistry by following names of sub registries.
//- Creates non-existing intermediate ones.
static const objectRegistry& subRegistry
(
const objectRegistry& obr,
const wordList& names,
const label index
);
//- Attempt to detect an IOField<Type> and write to dictionary
template<class Type>
static bool writeIOField
(
const regIOobject& obj,
dictionary& dict
);
//- Attempt to read an IOField<Type> and store on objectRegistry
template<class Type>
static bool constructIOField
(
const word& name,
token& tok,
Istream& is,
objectRegistry& obr
);
public:
//- Runtime type information
@ -289,7 +403,7 @@ public:
// Constructors
//- Construct from patch
mappedPatchBase(const polyPatch&);
explicit mappedPatchBase(const polyPatch&);
//- Construct with offsetMode=non-uniform
mappedPatchBase
@ -354,6 +468,9 @@ public:
//- What to sample
inline const sampleMode& mode() const;
//- World to sample
inline const word& sampleWorld() const;
//- Region to sample
inline const word& sampleRegion() const;
@ -372,6 +489,12 @@ public:
//- Offset vector (from patch faces to destination mesh objects)
inline const vectorField& offsets() const;
//- Communicator
inline label comm() const;
//- Is world the local world
inline bool sameWorld() const;
//- Cached sampleRegion != mesh.name()
inline bool sameRegion() const;
@ -412,6 +535,60 @@ public:
const polyMesh::cellDecomposition
);
// For database storage
inline const fileName& sampleDatabasePath() const
{
return *sampleDatabasePtr_;
}
inline bool sampleDatabase() const
{
return sampleDatabasePtr_.valid();
}
//- Helper: return path to store data to be sent to processor i
static fileName sendPath(const fileName& root, const label proci);
virtual fileName sendPath(const label proci) const;
//- Helper: return path to store data to be received from
//- processor i
static fileName receivePath
(
const fileName& root,
const label proci
);
virtual fileName receivePath(const label proci) const;
//- Lookup (sub)objectRegistry from '/' separated path (relative to
//- objectRegistry). Creates non-existing intermediate ones.
static const objectRegistry& subRegistry
(
const objectRegistry& obr,
const fileName& path
);
//- Store an IOField on the objectRegistry relative to obr
template<class Type>
static void storeField
(
objectRegistry& obr,
const word& fieldName,
const Field<Type>& values
);
//- Convert objectRegistry contents into dictionary
static void writeDict
(
const objectRegistry& obr,
dictionary& dict
);
//- (recursively) construct and register IOFields from dictionary
static void readDict(const dictionary& d, objectRegistry& obr);
// Distribute

View File

@ -33,6 +33,12 @@ Foam::mappedPatchBase::mode() const
}
inline const Foam::word& Foam::mappedPatchBase::sampleWorld() const
{
return sampleWorld_;
}
inline const Foam::word& Foam::mappedPatchBase::sampleRegion() const
{
if (sampleRegion_.empty())
@ -138,6 +144,20 @@ inline const Foam::vectorField& Foam::mappedPatchBase::offsets() const
}
inline Foam::label Foam::mappedPatchBase::comm() const
{
return comm_;
}
inline bool Foam::mappedPatchBase::sameWorld() const
{
return
UPstream::allWorlds().size() == 1
|| UPstream::myWorld() == sampleWorld_;
}
inline bool Foam::mappedPatchBase::sameRegion() const
{
return sameRegion_;
@ -147,7 +167,9 @@ inline bool Foam::mappedPatchBase::sameRegion() const
inline const Foam::mapDistribute& Foam::mappedPatchBase::map() const
{
const polyMesh& thisMesh = patch_.boundaryMesh().mesh();
bool topoChange = sampleMesh().topoChanging() || thisMesh.topoChanging();
bool topoChange =
(sameWorld() && sampleMesh().topoChanging())
|| thisMesh.topoChanging();
if (topoChange)
{
@ -169,7 +191,9 @@ inline const Foam::AMIPatchToPatchInterpolation& Foam::mappedPatchBase::AMI
) const
{
const polyMesh& thisMesh = patch_.boundaryMesh().mesh();
bool topoChange = sampleMesh().topoChanging() || thisMesh.topoChanging();
bool topoChange =
(sameWorld() && sampleMesh().topoChanging())
|| thisMesh.topoChanging();
if (topoChange || forceUpdate)
{

View File

@ -28,11 +28,16 @@ License
template<class Type>
void Foam::mappedPatchBase::distribute(List<Type>& lst) const
{
const label oldComm(Pstream::warnComm);
Pstream::warnComm = map().comm();
switch (mode_)
{
case NEARESTPATCHFACEAMI:
{
const label oldWorldComm = Pstream::worldComm;
Pstream::worldComm = comm_;
lst = AMI().interpolateToSource(Field<Type>(std::move(lst)));
Pstream::worldComm = oldWorldComm;
break;
}
default:
@ -40,6 +45,7 @@ void Foam::mappedPatchBase::distribute(List<Type>& lst) const
map().distribute(lst);
}
}
Pstream::warnComm = oldComm;
}
@ -50,11 +56,16 @@ void Foam::mappedPatchBase::distribute
const CombineOp& cop
) const
{
const label oldComm(Pstream::warnComm);
Pstream::warnComm = comm_;
switch (mode_)
{
case NEARESTPATCHFACEAMI:
{
const label oldWorldComm = Pstream::worldComm;
Pstream::worldComm = comm_;
lst = AMI().interpolateToSource(Field<Type>(std::move(lst)), cop);
Pstream::worldComm = oldWorldComm;
break;
}
default:
@ -69,23 +80,31 @@ void Foam::mappedPatchBase::distribute
map().constructMap(),
false,
lst,
Type(Zero),
cop,
flipOp(),
Type(Zero)
UPstream::msgType(),
comm_
);
}
}
Pstream::warnComm = oldComm;
}
template<class Type>
void Foam::mappedPatchBase::reverseDistribute(List<Type>& lst) const
{
const label oldComm(Pstream::warnComm);
Pstream::warnComm = map().comm();
switch (mode_)
{
case NEARESTPATCHFACEAMI:
{
const label oldWorldComm = Pstream::worldComm;
Pstream::worldComm = comm_;
lst = AMI().interpolateToTarget(Field<Type>(std::move(lst)));
Pstream::worldComm = oldWorldComm;
break;
}
default:
@ -94,6 +113,7 @@ void Foam::mappedPatchBase::reverseDistribute(List<Type>& lst) const
break;
}
}
Pstream::warnComm = oldComm;
}
@ -104,11 +124,16 @@ void Foam::mappedPatchBase::reverseDistribute
const CombineOp& cop
) const
{
const label oldComm(Pstream::warnComm);
Pstream::warnComm = map().comm();
switch (mode_)
{
case NEARESTPATCHFACEAMI:
{
const label oldWorldComm = Pstream::worldComm;
Pstream::worldComm = comm_;
lst = AMI().interpolateToTarget(Field<Type>(std::move(lst)), cop);
Pstream::worldComm = oldWorldComm;
break;
}
default:
@ -124,13 +149,137 @@ void Foam::mappedPatchBase::reverseDistribute
map().subMap(),
false,
lst,
Type(Zero),
cop,
flipOp(),
Type(Zero)
UPstream::msgType(),
comm_
);
break;
}
}
Pstream::warnComm = oldComm;
}
template<class Type>
bool Foam::mappedPatchBase::writeIOField
(
const regIOobject& obj,
dictionary& dict
)
{
const auto* fldPtr = isA<IOField<Type>>(obj);
if (fldPtr)
{
const auto& fld = *fldPtr;
token tok;
tok = new token::Compound<List<Type>>(fld);
primitiveEntry* pePtr = new primitiveEntry
(
fld.name(),
tokenList
(
one(),
std::move(tok)
)
);
dict.set(pePtr);
return true;
}
else
{
return false;
}
}
template<class Type>
bool Foam::mappedPatchBase::constructIOField
(
const word& name,
token& tok,
Istream& is,
objectRegistry& obr
)
{
const word tag = "List<" + word(pTraits<Type>::typeName) + '>';
if (tok.isCompound() && tok.compoundToken().type() == tag)
{
IOField<Type>* fldPtr = obr.findObject<IOField<Type>>(name);
if (fldPtr)
{
fldPtr->transfer
(
dynamicCast<token::Compound<List<Type>>>
(
tok.transferCompoundToken(is)
)
);
}
else
{
IOField<Type>* fldPtr = new IOField<Type>
(
IOobject
(
name,
obr,
IOobject::NO_READ,
IOobject::NO_WRITE
),
0
);
fldPtr->transfer
(
dynamicCast<token::Compound<List<Type>>>
(
tok.transferCompoundToken(is)
)
);
objectRegistry::store(fldPtr);
}
return true;
}
else
{
return false;
}
}
template<class Type>
void Foam::mappedPatchBase::storeField
(
objectRegistry& obr,
const word& fieldName,
const Field<Type>& values
)
{
IOField<Type>* fldPtr = obr.findObject<IOField<Type>>(fieldName);
if (fldPtr)
{
*fldPtr = values;
}
else
{
fldPtr = new IOField<Type>
(
IOobject
(
fieldName,
obr,
IOobject::NO_READ,
IOobject::NO_WRITE
),
values
);
objectRegistry::store(fldPtr);
}
}

View File

@ -1552,9 +1552,11 @@ void Foam::cellCellStencils::inverseDistance::createStencil
cellInterpolationMap().subMap(),
false,
samples,
greatPoint, // nullValue
minMagSqrEqOp<point>(),
flipOp(), // negateOp
greatPoint // nullValue
UPstream::msgType(),
cellInterpolationMap().comm()
);
// All the donor cells will now have a valid cell centre. Construct a

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