ENH: Support AMI for multi-world operation. Fixes #2099

Multi-world operation now supports AMI:

    // What to sample:
    sampleMode      nearestPatchFaceAMI;
This commit is contained in:
Mattijs Janssens 2021-05-26 08:27:30 +00:00 committed by Andrew Heather
parent 9a3d27e3df
commit f44dbbc200
28 changed files with 1124 additions and 106 deletions

View File

@ -67,6 +67,7 @@ void Foam::mappedPatchFieldBase<Type>::storeField
for (label domain = 0; domain < nProcs; domain++)
{
const labelList& map = procToMap[domain];
if (map.size())
{
const Field<T> subFld(fld, map);
@ -100,7 +101,7 @@ void Foam::mappedPatchFieldBase<Type>::storeField
template<class Type>
template<class T>
void Foam::mappedPatchFieldBase<Type>::retrieveField
bool Foam::mappedPatchFieldBase<Type>::retrieveField
(
const bool allowUnset,
const objectRegistry& obr,
@ -112,9 +113,10 @@ void Foam::mappedPatchFieldBase<Type>::retrieveField
) const
{
// Store my data onto database
//const label myRank = Pstream::myProcNo(0); // comm_
const label nProcs = Pstream::nProcs(0); // comm_
bool ok = true;
for (label domain = 0; domain < nProcs; domain++)
{
const labelList& map = procToMap[domain];
@ -128,39 +130,68 @@ void Foam::mappedPatchFieldBase<Type>::retrieveField
/ 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)
if (subFldPtr->size() != map.size())
{
Pout<< "*** RETRIEVED :"
<< " field:" << fieldName
<< " values:" << flatOutput(fld)
<< " from:" << subObr.objectPath() << endl;
// This is the dummy value inserted at start-up since the
// map is always non-zero size (checked above)
//Pout<< "*** RETRIEVED DUMMY :"
// << " field:" << fieldName
// << " subFldPtr:" << subFldPtr->size()
// << " map:" << map.size() << endl;
ok = false;
}
else
{
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;
if (fvPatchField<Type>::debug)
{
WarningInFunction << "Not found"
<< " field:" << fieldName
<< " in:" << subObr.objectPath() << endl;
}
// Store dummy value so the database has something on it.
// Note that size 0 should never occur naturally so we can
// detect it if necessary.
const Field<T> dummyFld(0);
mappedPatchBase::storeField
(
const_cast<objectRegistry&>(subObr),
fieldName,
dummyFld
);
ok = false;
}
else
{
// Not found. Make it fail
(void)subObr.lookupObject<IOField<T>>(fieldName);
ok = false;
}
}
}
return ok;
}
@ -171,18 +202,17 @@ void Foam::mappedPatchFieldBase<Type>::initRetrieveField
const objectRegistry& obr,
const word& region,
const word& patch,
const mapDistribute& map,
const labelListList& 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];
const labelList& constructMap = map[domain];
if (constructMap.size())
{
const objectRegistry& subObr = mappedPatchBase::subRegistry
@ -216,6 +246,71 @@ void Foam::mappedPatchFieldBase<Type>::initRetrieveField
}
template<class Type>
template<class T>
bool Foam::mappedPatchFieldBase<Type>::storeAndRetrieveField
(
const word& fieldName,
const labelListList& subMap,
const label constructSize,
const labelListList& constructMap,
const labelListList& address,
const scalarListList& weights,
Field<T>& fld
) const
{
storeField
(
patchField_.internalField().time(),
patchField_.patch().boundaryMesh().mesh().name(),
patchField_.patch().name(),
subMap,
fieldName,
fld
);
Field<T> work(constructSize);
const bool ok = retrieveField
(
true, // allow unset
patchField_.internalField().time(),
mapper_.sampleRegion(),
mapper_.samplePatch(),
constructMap,
fieldName,
work
);
if (ok)
{
// Do interpolation
fld.setSize(address.size());
fld = Zero;
const plusEqOp<T> cop;
const multiplyWeightedOp<T, plusEqOp<T>> mop(cop);
forAll(address, facei)
{
const labelList& slots = address[facei];
const scalarList& w = weights[facei];
forAll(slots, i)
{
mop(fld[facei], facei, work[slots[i]], w[i]);
}
}
}
else
{
// Leave fld intact
}
return ok;
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
template<class Type>
@ -263,16 +358,24 @@ Foam::mappedPatchFieldBase<Type>::mappedPatchFieldBase
if
(
mapper_.sampleDatabase()
&& mapper_.mode() != mappedPatchBase::NEARESTPATCHFACE
&& (
mapper_.mode() != mappedPatchBase::NEARESTPATCHFACE
&& mapper_.mode() != mappedPatchBase::NEARESTPATCHFACEAMI
)
)
{
FatalErrorInFunction
<< "Mapping using the database only supported for "
<< "sampleMode "
<< "sampleModes "
<< mappedPatchBase::sampleModeNames_
[
mappedPatchBase::NEARESTPATCHFACE
]
<< " and "
<< mappedPatchBase::sampleModeNames_
[
mappedPatchBase::NEARESTPATCHFACEAMI
]
<< exit(FatalError);
}
@ -297,22 +400,29 @@ Foam::mappedPatchFieldBase<Type>::mappedPatchFieldBase
:
mappedPatchFieldBase<Type>::mappedPatchFieldBase(mapper, patchField, dict)
{
if
(
mapper_.mode() == mappedPatchBase::NEARESTPATCHFACE
&& mapper_.sampleDatabase()
)
if (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_
);
if (mapper_.mode() == mappedPatchBase::NEARESTPATCHFACE)
{
// Store my data on receive buffers so we have some initial data
initRetrieveField
(
patchField_.internalField().time(),
//patchField_.patch().boundaryMesh().mesh().name(),
mapper_.sampleRegion(),
//patchField_.patch().name(),
mapper_.samplePatch(),
mapper_.map().constructMap(),
patchField_.internalField().name(),
patchField_
);
}
else if (mapper_.mode() == mappedPatchBase::NEARESTPATCHFACEAMI)
{
// Depend on fall-back (sorting dummy field) in retrieveField
// since it would be too hard to determine the field that gives
// the wanted result after interpolation
}
}
}
@ -410,37 +520,80 @@ template<class T>
void Foam::mappedPatchFieldBase<Type>::distribute
(
const word& fieldName,
Field<T>& newValues
Field<T>& fld
) 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
);
if (mapper_.mode() != mappedPatchBase::NEARESTPATCHFACEAMI)
{
// Store my data on send buffers
storeField
(
patchField_.internalField().time(),
patchField_.patch().boundaryMesh().mesh().name(),
patchField_.patch().name(),
mapper_.map().subMap(),
fieldName,
fld
);
// Construct my data from receive buffers
fld.setSize(mapper_.map().constructSize());
retrieveField
(
true, // allow unset
patchField_.internalField().time(),
mapper_.sampleRegion(),
mapper_.samplePatch(),
mapper_.map().constructMap(),
fieldName,
fld
);
}
else
{
const AMIPatchToPatchInterpolation& AMI = mapper_.AMI();
// The AMI does an interpolateToSource/ToTarget. This is a
// mapDistribute (so using subMap/constructMap) and then a
// weighted sum. We'll store the sent data as before and
// do the weighted summation after the retrieveField
if (mapper_.masterWorld())
{
// See AMIInterpolation::interpolateToSource. Use tgtMap,
// srcAddress, srcWeights
storeAndRetrieveField
(
fieldName,
AMI.srcMap().subMap(),
AMI.tgtMap().constructSize(),
AMI.tgtMap().constructMap(),
AMI.srcAddress(),
AMI.srcWeights(),
fld
);
}
else
{
// See AMIInterpolation::interpolateToTarget.
// Use srcMap, tgtAddress, tgtWeights
storeAndRetrieveField
(
fieldName,
AMI.tgtMap().subMap(),
AMI.srcMap().constructSize(),
AMI.srcMap().constructMap(),
AMI.tgtAddress(),
AMI.tgtWeights(),
fld
);
}
}
}
else
{
mapper_.distribute(newValues);
mapper_.distribute(fld);
}
}
@ -825,15 +978,18 @@ void Foam::mappedPatchFieldBase<Type>::initRetrieveField
{
// 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
);
if (mapper_.mode() == mappedPatchBase::NEARESTPATCHFACE)
{
initRetrieveField
(
patchField_.internalField().time(),
mapper_.sampleRegion(),
mapper_.samplePatch(),
mapper_.map().constructMap(),
fieldName,
fld
);
}
}
}

View File

@ -6,6 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2013-2016 OpenFOAM Foundation
Copyright (C) 2021 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -116,11 +117,26 @@ protected:
const objectRegistry& obr,
const word& region,
const word& patch,
const mapDistribute& map,
const labelListList& map,
const word& fieldName,
const Field<T>& fld
) const;
//- Helper : storeField and retrieveField and interpolate. Leaves fld
// unchanged (and returns false) if new values cannot be retrieved.
// Returns true otherwise.
template<class T>
bool storeAndRetrieveField
(
const word& fieldName,
const labelListList& subMap,
const label constructSize,
const labelListList& constructMap,
const labelListList& address,
const scalarListList& weights,
Field<T>& fld
) const;
public:
@ -244,9 +260,10 @@ public:
const Field<T>& fld
) const;
//- Construct field from registered elements
//- Construct field from registered elements. Return true if
// successful
template<class T>
void retrieveField
bool retrieveField
(
const bool allowUnset,
const objectRegistry& obr,

View File

@ -1105,14 +1105,14 @@ void Foam::mappedPatchBase::calcAMI() const
}
// Check if running locally
if (sampleWorld_.empty())
if (sampleWorld_.empty() || sameWorld())
{
const polyPatch& nbr = samplePolyPatch();
// Transform neighbour patch to local system
pointField nbrPoints(samplePoints(nbr.localPoints()));
const pointField nbrPoints(samplePoints(nbr.localPoints()));
primitivePatch nbrPatch0
const primitivePatch nbrPatch0
(
SubList<face>
(
@ -1135,44 +1135,57 @@ void Foam::mappedPatchBase::calcAMI() const
meshTools::writeOBJ(osO, patch_.localFaces(), patch_.localPoints());
}
// Construct/apply AMI interpolation to determine addressing and weights
AMIPtr_->calculate(patch_, nbrPatch0, surfPtr());
}
else
{
faceList nbrFaces;
pointField nbrPoints;
if (sampleWorld() == UPstream::myWorld())
{
const polyPatch& nbr = samplePolyPatch();
nbrFaces = nbr.localFaces();
nbrPoints = samplePoints(nbr.localPoints());
}
else
{
// Leave empty
}
// Construct/apply AMI interpolation to determine addressing and
// weights. Make sure to use optional inter-world communicator.
primitivePatch nbrPatch0
(
SubList<face>
(
nbrFaces,
nbrFaces.size()
),
nbrPoints
);
// Change to use ALL processors communicator
const label oldWorldComm = Pstream::worldComm;
Pstream::worldComm = comm_;
const label oldComm(Pstream::warnComm);
Pstream::warnComm = UPstream::worldComm;
// Construct/apply AMI interpolation to determine addressing and weights
AMIPtr_->calculate(patch_, nbrPatch0, surfPtr());
Pstream::warnComm = oldComm;
Pstream::worldComm = oldWorldComm;
}
else
{
faceList dummyFaces;
pointField dummyPoints;
const primitivePatch dummyPatch
(
SubList<face>
(
dummyFaces
),
dummyPoints
);
// Change to use inter-world communicator
const label oldWorldComm = Pstream::worldComm;
Pstream::worldComm = comm_;
const label oldComm(Pstream::warnComm);
Pstream::warnComm = UPstream::worldComm;
if (masterWorld())
{
// Construct/apply AMI interpolation to determine addressing
// and weights. Have patch_ for src faces, 0 faces for the
// target side
AMIPtr_->calculate(patch_, dummyPatch, surfPtr());
}
else
{
// Construct/apply AMI interpolation to determine addressing
// and weights. Have 0 faces for src side, patch_ for the tgt
// side
AMIPtr_->calculate(dummyPatch, patch_, surfPtr());
}
// Now the AMI addressing/weights will be from src side (on masterWorld
// processors) to tgt side (on other processors)
Pstream::warnComm = oldComm;
Pstream::worldComm = oldWorldComm;
}

View File

@ -492,9 +492,12 @@ public:
//- Communicator
inline label comm() const;
//- Is world the local world
//- Is sample world the local world?
inline bool sameWorld() const;
//- Is my world ordered before the sampleWorld?
inline bool masterWorld() const;
//- Cached sampleRegion != mesh.name()
inline bool sameRegion() const;

View File

@ -158,6 +158,23 @@ inline bool Foam::mappedPatchBase::sameWorld() const
}
inline bool Foam::mappedPatchBase::masterWorld() const
{
if (sameWorld())
{
return true;
}
else
{
// Use ordering in allWorlds
const label myWorld = UPstream::myWorldID();
const label mySampleWorld =
UPstream::allWorlds().find(sampleWorld_);
return myWorld < mySampleWorld;
}
}
inline bool Foam::mappedPatchBase::sameRegion() const
{
return sameRegion_;

View File

@ -36,7 +36,52 @@ void Foam::mappedPatchBase::distribute(List<Type>& lst) const
{
const label oldWorldComm = Pstream::worldComm;
Pstream::worldComm = comm_;
lst = AMI().interpolateToSource(Field<Type>(std::move(lst)));
if (sameWorld())
{
// lst is the other side's values
lst = AMI().interpolateToSource(Field<Type>(std::move(lst)));
}
else
{
// lst is my local data. Now the mapping in the AMI is
// from my side to other side. Each processor contains either
// faces from one side or from the other side.
if (masterWorld())
{
// I have lst.size() faces on my side, zero of the other
// side
tmp<Field<Type>> tmasterFld
(
AMI().interpolateToSource(Field<Type>(0))
);
(void)AMI().interpolateToTarget
(
Field<Type>(std::move(lst))
);
// We've received in our interpolateToSource the
// contribution from the other side
lst = tmasterFld;
}
else
{
(void)AMI().interpolateToSource
(
Field<Type>(std::move(lst))
);
tmp<Field<Type>> tmasterFld
(
AMI().interpolateToTarget(Field<Type>(0))
);
// We've received in our interpolateToTarget the
// contribution from the other side
lst = tmasterFld;
}
}
Pstream::worldComm = oldWorldComm;
break;
}

View File

@ -0,0 +1,10 @@
#!/bin/sh
cd "${0%/*}" || exit # Run from this directory
. ${WM_PROJECT_DIR:?}/bin/tools/CleanFunctions # Tutorial clean functions
#------------------------------------------------------------------------------
(cd left && cleanCase0)
(cd right && cleanCase0)
\rm -f log.*
#------------------------------------------------------------------------------

View File

@ -0,0 +1,28 @@
#!/bin/sh
cd "${0%/*}" || exit # Run from this directory
. ${WM_PROJECT_DIR:?}/bin/tools/RunFunctions # Tutorial run functions
#------------------------------------------------------------------------------
# Run serial
(cd left && runApplication blockMesh && \cp -r 0.orig 0)
(cd right && runApplication blockMesh && \cp -r 0.orig 0)
mpirun -app ./mpirun_left_right.schema
# Run with database
\mv log.run_left log.run_left_direct
\mv log.run_right log.run_right_direct
(cd left && foamListTimes -rm && \rm -r 0 && \cp -r 0.orig 0 && foamDictionary 0/T -entry boundaryField.coupled.sampleDatabase -add true)
(cd right && foamListTimes -rm && \rm -r 0 && \cp -r 0.orig 0 && foamDictionary 0/T -entry boundaryField.coupled.sampleDatabase -add true)
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,80 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: v2012 |
| \\ / A nd | Website: 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 nearestPatchFaceAMI;
// 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 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,81 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: v2012 |
| \\ / A nd | Website: 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 nearestPatchFaceAMI;
//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 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: v2012 |
| \\ / A nd | Website: 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,93 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: v2012 |
| \\ / A nd | Website: 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
(
//- AMI
hex (0 1 2 3 4 5 6 7) (3 3 1) simpleGrading (1 1 1)
//- one-to-one mapping
//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,74 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: v2012 |
| \\ / A nd | Website: www.openfoam.com |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class dictionary;
location "system";
object controlDict;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
libs (utilityFunctionObjects);
DebugSwitches
{
// mappedPatchBase 2;
// syncObjects 2;
}
application laplacianFoam;
startFrom startTime; //latestTime;
startTime 0;
stopAt endTime;
endTime 5;
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: v2012 |
| \\ / A nd | Website: 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: v2012 |
| \\ / A nd | Website: 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: v2012 |
| \\ / A nd | Website: 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: v2012 |
| \\ / A nd | Website: 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 nearestPatchFaceAMI;
// 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 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,80 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: v2012 |
| \\ / A nd | Website: 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 nearestPatchFaceAMI;
//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 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: v2012 |
| \\ / A nd | Website: 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