Commit 2ec4f363 authored by Henry's avatar Henry
Browse files
parents 62e5c128 40315b21
......@@ -104,6 +104,8 @@
taking film into account
+ Parallel aware
*** *New* ptscotch decomposition method
*** *Updated* decomposePar maps polyPatches instead of recreating them so
polyPatches holding data can map the data.
*** *Updated* particle tracking algorithm
+ uses non-blocking parallel transfers
+ does 'minimum-tet' decomposition of face to work with warped faces (snappyHexMesh!)
......@@ -150,7 +152,12 @@
OpenFOAM.
+ *New* wall functions:
+ kappatJayatillekeWallFunction: incompressible RAS thermal wall function
+ directMappedFixedValue:
+ takes interpolationScheme so can interpolate instead of always getting
cell value
+ takes optional fieldName to sample
+ directMapped patch added 'normal' method to calculate sample points
to e.g. sample fields just above wall (e.g. for streaklines)
* Utilities
There have been some utilities added and updated in this release.
*** *New* utilities
......@@ -172,8 +179,10 @@
*** Updated utilities
+ =setFields=: optionally use faceSets to set patch values (see e.g. hotRoom tutorial).
+ =blockMesh=: specify patches via dictionary instead of type only. This
makes rereading the boundary superfluous. see
makes rereading the boundary file superfluous. see
e.g. pitzDailyDirectMapped tutorial.
+ =setSet=: allows time range (e.g. 0:100) in combination with -batch argument
to execute the commands for multiple times.
* Post-processing
+ =foamToEnsight=: parallel continuous data. new =-nodeValues= option to generate and output nodal
field data.
......@@ -190,6 +199,12 @@
specified time has been reached, e.g. to automagically change fvSchemes and
fvSolution during a calculation
+ =streamLine=: generate streamlines; ouputs both trajectory and field data
+ =surfaceInterpolateFields=: constructs face interpolate of registered
volFields for any future functionObjects that need surfaceFields.
+ =readFields=: reads field if not yet registered. Makes functionObjects
useable through standalone execFlowFunctionObjects.
+ =faceSource=: can now calculate on a sampledSurface (e.g. flow through a
triSurfaceMesh)
* New tutorials
There is a large number of new tutorials for existing and new solvers in the
......
......@@ -19,15 +19,17 @@ FoamFile
numberOfSubdomains 8;
//- Keep owner and neighbour on same processor for faces in zones:
// preserveFaceZones (heater solid1 solid3);
//- Keep owner and neighbour on same processor for faces in patches:
// (makes sense only for cyclic patches)
//preservePatches (cyclic_half0 cyclic_half1);
//- Use the volScalarField named here as a weight for each cell in the
// decomposition. For example, use a particle population field to decompose
// for a balanced number of particles in a lagrangian simulation.
// weightField dsmcRhoNMean;
method scotch;
// method hierarchical;
......@@ -59,11 +61,8 @@ multiLevelCoeffs
}
}
// Desired output
simpleCoeffs
{
n (2 1 1);
......
......@@ -24,7 +24,6 @@ License
\*---------------------------------------------------------------------------*/
#include "domainDecomposition.H"
#include "Time.H"
#include "dictionary.H"
#include "labelIOList.H"
#include "processorPolyPatch.H"
......@@ -341,10 +340,10 @@ bool Foam::domainDecomposition::writeDecomposition()
const labelList& curProcessorPatchStarts =
procProcessorPatchStartIndex_[procI];
const labelListList& curSubPatchIDs =
const labelListList& curSubPatchIDs =
procProcessorPatchSubPatchIDs_[procI];
const labelListList& curSubStarts =
const labelListList& curSubStarts =
procProcessorPatchSubPatchStarts_[procI];
const polyPatchList& meshPatches = boundaryMesh();
......
......@@ -41,6 +41,9 @@ SourceFiles
#include "SLList.H"
#include "PtrList.H"
#include "point.H"
#include "Time.H"
#include "volFields.H"
namespace Foam
{
......@@ -80,7 +83,7 @@ class domainDecomposition
// original face. In order to do this properly, all face
// indices will be incremented by 1 and the decremented as
// necessary to avoid the problem of face number zero having no
// sign.
// sign.
List<DynamicList<label> > procFaceAddressing_;
//- Labels of cells for each processor
......
......@@ -114,7 +114,35 @@ void Foam::domainDecomposition::distributeCells()
if (sameProcFaces.empty())
{
cellToProc_ = decomposePtr().decompose(*this, cellCentres());
if (decompositionDict_.found("weightField"))
{
word weightName = decompositionDict_.lookup("weightField");
volScalarField weights
(
IOobject
(
weightName,
time().timeName(),
*this,
IOobject::MUST_READ,
IOobject::NO_WRITE
),
*this
);
cellToProc_ = decomposePtr().decompose
(
*this,
cellCentres(),
weights.internalField()
);
}
else
{
cellToProc_ = decomposePtr().decompose(*this, cellCentres());
}
}
else
{
......@@ -173,12 +201,49 @@ void Foam::domainDecomposition::distributeCells()
// Do decomposition on agglomeration
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
cellToProc_ = decomposePtr().decompose
(
*this,
globalRegion,
regionCentres
);
if (decompositionDict_.found("weightField"))
{
scalarField regionWeights(globalRegion.nRegions(), 0);
word weightName = decompositionDict_.lookup("weightField");
volScalarField weights
(
IOobject
(
weightName,
time().timeName(),
*this,
IOobject::MUST_READ,
IOobject::NO_WRITE
),
*this
);
forAll(globalRegion, cellI)
{
label regionI = globalRegion[cellI];
regionWeights[regionI] += weights.internalField()[cellI];
}
cellToProc_ = decomposePtr().decompose
(
*this,
globalRegion,
regionCentres,
regionWeights
);
}
else
{
cellToProc_ = decomposePtr().decompose
(
*this,
globalRegion,
regionCentres
);
}
}
Info<< "\nFinished decomposition in "
......
......@@ -86,9 +86,35 @@ autoPtr<fvMesh> createMesh
if (!haveMesh)
{
// Create dummy mesh. Only used on procs that don't have mesh.
// WIP: how to avoid parallel comms when loading IOdictionaries?
// For now just give error message.
if
(
regIOobject::fileModificationChecking
== regIOobject::timeStampMaster
|| regIOobject::fileModificationChecking
== regIOobject::inotifyMaster
)
{
FatalErrorIn("createMesh(..)")
<< "Cannot use 'fileModificationChecking' mode "
<< regIOobject::fileCheckTypesNames
[
regIOobject::fileModificationChecking
]
<< " since this uses parallel communication."
<< exit(FatalError);
}
fvMesh dummyMesh
(
io,
IOobject
(
regionName,
instDir,
runTime,
IOobject::NO_READ
),
xferCopy(pointField()),
xferCopy(faceList()),
xferCopy(labelList()),
......@@ -510,16 +536,14 @@ int main(int argc, char *argv[])
"specify the merge distance relative to the bounding box size "
"(default 1E-6)"
);
// Create argList. This will check for non-existing processor dirs.
# include "setRootCase.H"
//- Not useful anymore. See above.
//// Create processor directory if non-existing
//if (!Pstream::master() && !isDir(args.path()))
//{
// Pout<< "Creating case directory " << args.path() << endl;
// mkDir(args.path());
//}
// Create processor directory if non-existing
if (!Pstream::master() && !isDir(args.path()))
{
Pout<< "Creating case directory " << args.path() << endl;
mkDir(args.path());
}
# include "createTime.H"
......
......@@ -319,7 +319,7 @@ void Foam::fileMonitor::checkFiles() const
if (ready < 0)
{
FatalErrorIn("fileMonitor::updateStates()")
FatalErrorIn("fileMonitor::checkFiles()")
<< "Problem in issuing select."
<< abort(FatalError);
}
......@@ -335,7 +335,7 @@ void Foam::fileMonitor::checkFiles() const
if (nBytes < 0)
{
FatalErrorIn("fileMonitor::updateStates(const fileName&)")
FatalErrorIn("fileMonitor::checkFiles()")
<< "read of " << watcher_->inotifyFd_
<< " failed with " << label(nBytes)
<< abort(FatalError);
......@@ -374,7 +374,7 @@ void Foam::fileMonitor::checkFiles() const
)
{
// Correct directory and name
state_[i] = MODIFIED;
localState_[i] = MODIFIED;
}
}
}
......@@ -403,18 +403,17 @@ void Foam::fileMonitor::checkFiles() const
if (newTime == 0)
{
state_[watchFd] = DELETED;
localState_[watchFd] = DELETED;
}
else
{
if (newTime > (oldTime + regIOobject::fileModificationSkew))
{
watcher_->lastMod_[watchFd] = newTime;
state_[watchFd] = MODIFIED;
localState_[watchFd] = MODIFIED;
}
else
{
state_[watchFd] = UNMODIFIED;
localState_[watchFd] = UNMODIFIED;
}
}
}
......@@ -422,12 +421,14 @@ void Foam::fileMonitor::checkFiles() const
}
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::fileMonitor::fileMonitor(const bool useInotify)
:
useInotify_(useInotify),
localState_(20),
state_(20),
watchFile_(20),
freeWatchFds_(2),
......@@ -476,6 +477,7 @@ Foam::label Foam::fileMonitor::addWatch(const fileName& fName)
}
else
{
localState_(watchFd) = UNMODIFIED;
state_(watchFd) = UNMODIFIED;
watchFile_(watchFd) = fName;
}
......@@ -517,30 +519,26 @@ void Foam::fileMonitor::updateStates
{
if (Pstream::master() || !masterOnly)
{
// Update the localState_
checkFiles();
}
if (syncPar)
{
// Pack current state (might be on master only)
// Pack local state (might be on master only)
PackedList<2> stats(state_.size(), MODIFIED);
if (Pstream::master() || !masterOnly)
{
forAll(state_, watchFd)
{
stats[watchFd] = static_cast<unsigned int>(state_[watchFd]);
stats[watchFd] = static_cast<unsigned int>
(
localState_[watchFd]
);
}
}
// Save local state for warning message below
PackedList<2> thisProcStats;
if (!masterOnly)
{
thisProcStats = stats;
}
// Scatter or reduce to synchronise state
if (masterOnly)
{
......@@ -573,43 +571,49 @@ void Foam::fileMonitor::updateStates
}
// Update local state
// Update synchronised state
forAll(state_, watchFd)
{
if (masterOnly)
{
// No need to check for inconsistent state. Just assign.
unsigned int stat = stats[watchFd];
state_[watchFd] = fileState(stat);
}
else
// Assign synchronised state
unsigned int stat = stats[watchFd];
state_[watchFd] = fileState(stat);
if (!masterOnly)
{
// Check for inconsistent state before assigning.
if (thisProcStats[watchFd] != UNMODIFIED)
// Give warning for inconsistent state
if (state_[watchFd] != localState_[watchFd])
{
if (stats[watchFd] == UNMODIFIED)
if (debug)
{
WarningIn("fileMonitor::updateStates(const bool) const")
<< "Delaying reading " << watchFile_[watchFd]
Pout<< "fileMonitor : Delaying reading "
<< watchFile_[watchFd]
<< " due to inconsistent "
"file time-stamps between processors"
<< endl;
}
else
{
unsigned int stat = stats[watchFd];
state_[watchFd] = fileState(stat);
}
WarningIn
(
"fileMonitor::updateStates"
"(const bool, const bool) const"
) << "Delaying reading " << watchFile_[watchFd]
<< " due to inconsistent "
"file time-stamps between processors" << endl;
}
}
}
}
else
{
state_ = localState_;
}
}
void Foam::fileMonitor::setUnmodified(const label watchFd)
{
state_[watchFd] = UNMODIFIED;
localState_[watchFd] = UNMODIFIED;
if (!useInotify_)
{
......
......@@ -71,7 +71,7 @@ public:
{
UNMODIFIED = 0,
MODIFIED = 1,
DELETED = 2,
DELETED = 2
};
static const NamedEnum<fileState, 3> fileStateNames_;
......@@ -82,7 +82,10 @@ private:
//- Whether to use inotify (requires -DFOAM_USE_INOTIFY, see above)
const bool useInotify_;
//- State for all watchFds
//- State for all watchFds based on local files
mutable DynamicList<fileState> localState_;
//- State for all watchFds - synchronised
mutable DynamicList<fileState> state_;
//- Filename for all watchFds
......@@ -97,7 +100,7 @@ private:
// Private Member Functions
//- Update state_ from any events.
//- Update localState_ from any events.
void checkFiles() const;
//- Disallow default bitwise copy construct
......
......@@ -60,7 +60,6 @@ Foam::regIOobject::fileCheckTypes Foam::regIOobject::fileModificationChecking
debug::optimisationSwitches().lookup
(
"fileModificationChecking"
//Foam::regIOobject::timeStamp
)
)
);
......
......@@ -31,6 +31,7 @@ License
#include "IOobject.H"
#include "JobInfo.H"
#include "labelList.H"
#include "regIOobject.H"
#include <cctype>
......@@ -767,6 +768,16 @@ Foam::argList::argList
sigQuit_.set(bannerEnabled);
sigSegv_.set(bannerEnabled);
if (bannerEnabled)
{
Info<< "Monitoring run-time modified files using "
<< regIOobject::fileCheckTypesNames
[
regIOobject::fileModificationChecking
]
<< endl;
}
if (Pstream::master() && bannerEnabled)
{
Info<< endl;
......
......@@ -58,13 +58,35 @@ void Foam::ptscotchDecomp::check(const int retVal, const char* str)
{}
Foam::label Foam::ptscotchDecomp::decomposeZeroDomains
(
const List<int>& initxadj,
const List<int>& initadjncy,
const scalarField& initcWeights,
List<int>& finalDecomp
) const
{
FatalErrorIn
(
"label ptscotchDecomp::decompose"
"("
"const List<int>&, "
"const List<int>&, "
"const scalarField&, "
"List<int>&"
")"
) << notImplementedMessage << exit(FatalError);
return -1;
}
Foam::label Foam::ptscotchDecomp::decompose
(
List<int>& adjncy,
List<int>& xadj,
const List<int>& adjncy,
const List<int>& xadj,
const scalarField& cWeights,
List<int>& finalDecomp
)
) const
{
FatalErrorIn
(
......
......@@ -62,37 +62,29 @@ void Foam::Particle<ParticleType>::correctAfterParallelTransfer
if (!ppp.parallel())
{
if (ppp.forwardT().size() == 1)
{
const tensor& T = ppp.forwardT()[0];
transformPosition(T);
static_cast<ParticleType&>(*this).transformProperties(T);
}
else
{
const tensor& T = ppp.forwardT()[faceI_];
transformPosition(T);
static_cast<ParticleType&>(*this).transformProperties(T);
}
const tensor& T =
(
ppp.forwardT().size() == 1
? ppp.forwardT()[0]
: ppp.forwardT()[faceI_]
);
transformPosition(T);
static_cast<ParticleType&>(*this).transformProperties(T);
}
else if (ppp.separated())
{
if (ppp.separation().size() == 1)
{
position_ -= ppp.separation()[0];
static_cast<ParticleType&>(*this).transformProperties
(
-ppp.separation()[0]
);
}
else
{
position_ -= ppp.separation()[faceI_];
static_cast<ParticleType&>(*this).transformProperties
(
-ppp.separation()[faceI_]
);
}
const vector& s =
(
(ppp.separation().size() == 1)
? ppp.separation()[0]
: ppp.separation()[faceI_]
);
position_ -= s;
static_cast<ParticleType&>(*this).transformProperties
(
-s
);
}
tetFaceI_ = faceI_ + ppp.start();
......@@ -815,21 +807,34 @@ void Foam::Particle<ParticleType>::hitCyclicPatch
// See note in correctAfterParallelTransfer for tetPtI_ addressing.
tetPtI_ = cloud_.polyMesh_.faces()[tetFaceI_].size() - 1 - tetPtI_;
const cyclicPolyPatch& receiveCpp = cpp.neighbPatch();
// Now the particle is on the receiving side