Merge branch 'master' of ssh://noisy/home/noisy3/OpenFOAM/OpenFOAM-dev

This commit is contained in:
andy
2010-12-08 17:17:10 +00:00
522 changed files with 11792 additions and 104627 deletions

View File

@ -11,7 +11,7 @@ unset COMP_FLAGS LINK_FLAGS
#
if [ -f /usr/include/sys/inotify.h -a "${1%USE_STAT}" = "$1" ]
then
echo "Found <sys/inotify.h> -- using inotify for file monitoring."
echo "Found <sys/inotify.h> -- enabling inotify for file monitoring."
export COMP_FLAGS="-DFOAM_USE_INOTIFY"
else
unset COMP_FLAGS

View File

@ -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)
// Assign synchronised state
unsigned int stat = stats[watchFd];
state_[watchFd] = fileState(stat);
if (!masterOnly)
{
// No need to check for inconsistent state. Just assign.
unsigned int stat = stats[watchFd];
state_[watchFd] = fileState(stat);
}
else
{
// 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_)
{

View File

@ -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

View File

@ -47,6 +47,8 @@ Foam::memInfo::~memInfo()
const Foam::memInfo& Foam::memInfo::update()
{
// reset to invalid values first
peak_ = size_ = rss_ = -1;
IFstream is("/proc/" + name(pid()) + "/status");
while (is.good())

View File

@ -27,6 +27,9 @@ Class
Description
Memory usage information for the process running this object.
Note
Uses the information from /proc/\<pid\>/status
SourceFiles
memInfo.C
@ -52,13 +55,13 @@ class memInfo
{
// Private data
//- Peak memory used by the process (VmPeak in /proc/<pid>/status)
//- Peak memory used by the process (VmPeak in /proc/\<pid\>/status)
int peak_;
//- Memory used by the process (VmSize in /proc/<pid>/status)
//- Memory used by the process (VmSize in /proc/\<pid\>/status)
int size_;
//- Resident set size of the process (VmRSS in /proc/<pid>/status)
//- Resident set size of the process (VmRSS in /proc/\<pid\>/status)
int rss_;
@ -76,24 +79,27 @@ public:
// Member Functions
//- Parse /proc/<pid>/status
//- Parse /proc/\<pid\>/status
const memInfo& update();
// Access
//- Access the stored peak memory
//- Access the stored peak memory (VmPeak in /proc/\<pid\>/status)
// The value is stored from the previous update()
int peak() const
{
return peak_;
}
//- Access the stored memory size
//- Access the stored memory size (VmSize in /proc/\<pid\>/status)
// The value is stored from the previous update()
int size() const
{
return size_;
}
//- Access the stored rss value
//- Access the stored rss value (VmRSS in /proc/\<pid\>/status)
// The value is stored from the previous update()
int rss() const
{
return rss_;
@ -102,7 +108,10 @@ public:
// IOstream Operators
//- Read peak/size/rss from stream
friend Istream& operator>>(Istream&, memInfo&);
//- Write peak/size/rss to stream
friend Ostream& operator<<(Ostream&, const memInfo&);
};

View File

@ -537,7 +537,7 @@ void Foam::FaceCellWave<Type, TrackingData>::handleProcPatches()
{
transform
(
procPatch.reverseT(),
procPatch.forwardT(),
receiveFaces.size(),
receiveFacesInfo
);

View File

@ -55,46 +55,59 @@ void Foam::IOdictionary::readFile(const bool masterOnly)
close();
}
if (masterOnly)
if (masterOnly && Pstream::parRun())
{
// Scatter master data
if (Pstream::master())
{
for
(
int slave=Pstream::firstSlave();
slave<=Pstream::lastSlave();
slave++
)
{
// Note: use ASCII for now - binary IO of dictionaries is
// not currently supported
OPstream toSlave
(
Pstream::scheduled,
slave,
0,
UPstream::msgType(),
IOstream::ASCII
);
IOdictionary::writeData(toSlave);
}
}
else
// Scatter master data using communication scheme
const List<Pstream::commsStruct>& comms =
(
(Pstream::nProcs() < Pstream::nProcsSimpleSum)
? Pstream::linearCommunication()
: Pstream::treeCommunication()
);
// Get my communication order
const Pstream::commsStruct& myComm = comms[Pstream::myProcNo()];
// Reveive from up
if (myComm.above() != -1)
{
if (debug)
{
Pout<< "IOdictionary : Reading " << objectPath()
<< " from master processor " << Pstream::masterNo() << endl;
<< " from processor " << myComm.above() << endl;
}
IPstream fromMaster
// Note: use ASCII for now - binary IO of dictionaries is
// not currently supported
IPstream fromAbove
(
Pstream::scheduled,
Pstream::masterNo(),
myComm.above(),
0,
IOstream::ASCII
);
IOdictionary::readData(fromMaster);
IOdictionary::readData(fromAbove);
}
// Send to my downstairs neighbours
forAll(myComm.below(), belowI)
{
if (debug)
{
Pout<< "IOdictionary : Sending " << objectPath()
<< " to processor " << myComm.below()[belowI] << endl;
}
OPstream toBelow
(
Pstream::scheduled,
myComm.below()[belowI],
0,
Pstream::msgType(),
IOstream::ASCII
);
IOdictionary::writeData(toBelow);
}
}
}

View File

@ -60,7 +60,6 @@ Foam::regIOobject::fileCheckTypes Foam::regIOobject::fileModificationChecking
debug::optimisationSwitches().lookup
(
"fileModificationChecking"
//Foam::regIOobject::timeStamp
)
)
);

View File

@ -177,55 +177,69 @@ bool Foam::regIOobject::read()
regIOobject::fileModificationChecking == timeStampMaster
|| regIOobject::fileModificationChecking == inotifyMaster;
bool ok;
bool ok = true;
if (Pstream::master() || !masterOnly)
{
if (IFstream::debug)
{
Pout<< "regIOobject::read() : "
<< "reading object " << name()
<< " from file " << endl;
}
ok = readData(readStream(type()));
close();
}
if (masterOnly)
if (masterOnly && Pstream::parRun())
{
// Scatter master data
if (Pstream::master())
{
for
(
int slave=Pstream::firstSlave();
slave<=Pstream::lastSlave();
slave++
)
{
// Note: use ASCII for now - binary IO of dictionaries is
// not currently supported
OPstream toSlave
(
Pstream::scheduled,
slave,
0,
UPstream::msgType(),
IOstream::ASCII
);
writeData(toSlave);
}
}
else
// Scatter master data using communication scheme
const List<Pstream::commsStruct>& comms =
(
(Pstream::nProcs() < Pstream::nProcsSimpleSum)
? Pstream::linearCommunication()
: Pstream::treeCommunication()
);
// Get my communication order
const Pstream::commsStruct& myComm = comms[Pstream::myProcNo()];
// Reveive from up
if (myComm.above() != -1)
{
if (IFstream::debug)
{
Pout<< "regIOobject::read() : "
<< "reading object " << name()
<< " from master processor " << Pstream::masterNo()
<< " from processor " << myComm.above()
<< endl;
}
IPstream fromMaster
// Note: use ASCII for now - binary IO of dictionaries is
// not currently supported
IPstream fromAbove
(
Pstream::scheduled,
Pstream::masterNo(),
myComm.above(),
0,
IOstream::ASCII
);
ok = readData(fromMaster);
ok = readData(fromAbove);
}
// Send to my downstairs neighbours
forAll(myComm.below(), belowI)
{
OPstream toBelow
(
Pstream::scheduled,
myComm.below()[belowI],
0,
Pstream::msgType(),
IOstream::ASCII
);
writeData(toBelow);
}
}
return ok;

View File

@ -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;

View File

@ -41,16 +41,20 @@ Foam::cyclicLduInterfaceField::~cyclicLduInterfaceField()
void Foam::cyclicLduInterfaceField::transformCoupleField
(
scalarField& pnf,
scalarField& f,
const direction cmpt
) const
{
if (doTransform())
{
scalar forwardScale =
pow(diag(forwardT()[0]).component(cmpt), rank());
pnf *= forwardScale;
if (forwardT().size() == 1)
{
f *= pow(diag(forwardT()[0]).component(cmpt), rank());
}
else
{
f *= pow(diag(forwardT())().component(cmpt), rank());
}
}
}

View File

@ -43,9 +43,39 @@ static const Foam::List<Foam::word> subDictNames
);
//! @endcond
// * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * * //
void Foam::solution::read(const dictionary& dict)
{
if (dict.found("cache"))
{
cache_ = dict.subDict("cache");
caching_ = cache_.lookupOrDefault("active", true);
}
if (dict.found("relaxationFactors"))
{
relaxationFactors_ = dict.subDict("relaxationFactors");
}
relaxationFactors_.readIfPresent("default", defaultRelaxationFactor_);
if (dict.found("solvers"))
{
solvers_ = dict.subDict("solvers");
upgradeSolverDict(solvers_);
}
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::solution::solution(const objectRegistry& obr, const fileName& dictName)
Foam::solution::solution
(
const objectRegistry& obr,
const fileName& dictName
)
:
IOdictionary
(
@ -64,7 +94,7 @@ Foam::solution::solution(const objectRegistry& obr, const fileName& dictName)
defaultRelaxationFactor_(0),
solvers_(ITstream("solvers", tokenList())())
{
read();
read(solutionDict());
}
@ -250,26 +280,7 @@ bool Foam::solution::read()
{
if (regIOobject::read())
{
const dictionary& dict = solutionDict();
if (dict.found("cache"))
{
cache_ = dict.subDict("cache");
caching_ = cache_.lookupOrDefault("active", true);
}
if (dict.found("relaxationFactors"))
{
relaxationFactors_ = dict.subDict("relaxationFactors");
}
relaxationFactors_.readIfPresent("default", defaultRelaxationFactor_);
if (dict.found("solvers"))
{
solvers_ = dict.subDict("solvers");
upgradeSolverDict(solvers_);
}
read(solutionDict());
return true;
}

View File

@ -70,6 +70,9 @@ class solution
// Private Member Functions
//- Read settings from the dictionary
void read(const dictionary&);
//- Disallow default bitwise copy construct and assignment
solution(const solution&);
void operator=(const solution&);
@ -89,7 +92,11 @@ public:
// Constructors
//- Construct for given objectRegistry and dictionary
solution(const objectRegistry& obr, const fileName& dictName);
solution
(
const objectRegistry& obr,
const fileName& dictName
);
// Member Functions

View File

@ -1220,7 +1220,17 @@ void Foam::globalPoints::calculateSharedPoints
// Do one exchange iteration to get neighbour points.
{
PstreamBuffers pBufs(Pstream::defaultCommsType);
// Note: to use 'scheduled' would have to intersperse send and receive.
// So for now just use nonBlocking. Also globalPoints itself gets
// constructed by mesh.globalData().patchSchedule() so creates a loop.
PstreamBuffers pBufs
(
(
Pstream::defaultCommsType == Pstream::scheduled
? Pstream::nonBlocking
: Pstream::defaultCommsType
)
);
sendPatchPoints
(
mergeSeparated,
@ -1251,7 +1261,14 @@ void Foam::globalPoints::calculateSharedPoints
do
{
PstreamBuffers pBufs(Pstream::defaultCommsType);
PstreamBuffers pBufs
(
(
Pstream::defaultCommsType == Pstream::scheduled
? Pstream::nonBlocking
: Pstream::defaultCommsType
)
);
sendPatchPoints
(
mergeSeparated,
@ -1400,7 +1417,15 @@ void Foam::globalPoints::calculateSharedPoints
Pout<< "Determined " << changedIndices.size() << " shared points."
<< " Exchanging them" << endl;
}
PstreamBuffers pBufs(Pstream::defaultCommsType);
PstreamBuffers pBufs
(
(
Pstream::defaultCommsType == Pstream::scheduled
? Pstream::nonBlocking
: Pstream::defaultCommsType
)
);
sendSharedPoints(mergeSeparated, pBufs, changedIndices);
pBufs.finishedSends();
receiveSharedPoints

View File

@ -165,6 +165,35 @@ const Foam::List<Foam::labelPair>& Foam::mapDistribute::schedule() const
}
void Foam::mapDistribute::checkReceivedSize
(
const label procI,
const label expectedSize,
const label receivedSize
)
{
if (receivedSize != expectedSize)
{
FatalErrorIn
(
"template<class T>\n"
"void mapDistribute::distribute\n"
"(\n"
" const Pstream::commsTypes commsType,\n"
" const List<labelPair>& schedule,\n"
" const label constructSize,\n"
" const labelListList& subMap,\n"
" const labelListList& constructMap,\n"
" List<T>& field\n"
")\n"
) << "Expected from processor " << procI
<< " " << expectedSize << " but received "
<< receivedSize << " elements."
<< abort(FatalError);
}
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
//- Construct from components

View File

@ -93,6 +93,15 @@ class mapDistribute
mutable autoPtr<List<labelPair> > schedulePtr_;
// Private Member Functions
static void checkReceivedSize
(
const label procI,
const label expectedSize,
const label receivedSize
);
public:
// Constructors
@ -319,6 +328,62 @@ public:
}
}
//- Reverse distribute data using default commsType.
// Since constructSize might be larger than supplied size supply
// a nullValue
template<class T>
void reverseDistribute
(
const label constructSize,
const T& nullValue,
List<T>& fld
)
const
{
if (Pstream::defaultCommsType == Pstream::nonBlocking)
{
distribute
(
Pstream::nonBlocking,
List<labelPair>(),
constructSize,
constructMap_,
subMap_,
fld,
eqOp<T>(),
nullValue
);
}
else if (Pstream::defaultCommsType == Pstream::scheduled)
{
distribute
(
Pstream::scheduled,
schedule(),
constructSize,
constructMap_,
subMap_,
fld,
eqOp<T>(),
nullValue
);
}
else
{
distribute
(
Pstream::blocking,
List<labelPair>(),
constructSize,
constructMap_,
subMap_,
fld,
eqOp<T>(),
nullValue
);
}
}
//- Do all sends using PstreamBuffers
template<class T>
void send(PstreamBuffers&, const List<T>&) const;

View File

@ -111,25 +111,7 @@ void Foam::mapDistribute::distribute
IPstream fromNbr(Pstream::blocking, domain);
List<T> subField(fromNbr);
if (subField.size() != map.size())
{
FatalErrorIn
(
"template<class T>\n"
"void mapDistribute::distribute\n"
"(\n"
" const Pstream::commsTypes commsType,\n"
" const List<labelPair>& schedule,\n"
" const label constructSize,\n"
" const labelListList& subMap,\n"
" const labelListList& constructMap,\n"
" List<T>& field\n"
")\n"
) << "Expected from processor " << domain
<< " " << map.size() << " but received "
<< subField.size() << " elements."
<< abort(FatalError);
}
checkReceivedSize(domain, map.size(), subField.size());
forAll(map, i)
{
@ -160,46 +142,52 @@ void Foam::mapDistribute::distribute
forAll(schedule, i)
{
const labelPair& twoProcs = schedule[i];
// twoProcs is a swap pair of processors. The first one is the
// one that needs to send first and then receive.
label sendProc = twoProcs[0];
label recvProc = twoProcs[1];
if (Pstream::myProcNo() == sendProc)
{
// I am sender. Send to recvProc.
OPstream toNbr(Pstream::scheduled, recvProc);
toNbr << UIndirectList<T>(field, subMap[recvProc]);
// I am send first, receive next
{
OPstream toNbr(Pstream::scheduled, recvProc);
toNbr << UIndirectList<T>(field, subMap[recvProc]);
}
{
IPstream fromNbr(Pstream::scheduled, recvProc);
List<T> subField(fromNbr);
const labelList& map = constructMap[recvProc];
checkReceivedSize(recvProc, map.size(), subField.size());
forAll(map, i)
{
newField[map[i]] = subField[i];
}
}
}
else
{
// I am receiver. Receive from sendProc.
IPstream fromNbr(Pstream::scheduled, sendProc);
List<T> subField(fromNbr);
const labelList& map = constructMap[sendProc];
if (subField.size() != map.size())
// I am receive first, send next
{
FatalErrorIn
(
"template<class T>\n"
"void mapDistribute::distribute\n"
"(\n"
" const Pstream::commsTypes commsType,\n"
" const List<labelPair>& schedule,\n"
" const label constructSize,\n"
" const labelListList& subMap,\n"
" const labelListList& constructMap,\n"
" List<T>& field\n"
")\n"
) << "Expected from processor " << sendProc
<< " " << map.size() << " but received "
<< subField.size() << " elements."
<< abort(FatalError);
IPstream fromNbr(Pstream::scheduled, sendProc);
List<T> subField(fromNbr);
const labelList& map = constructMap[sendProc];
checkReceivedSize(sendProc, map.size(), subField.size());
forAll(map, i)
{
newField[map[i]] = subField[i];
}
}
forAll(map, i)
{
newField[map[i]] = subField[i];
OPstream toNbr(Pstream::scheduled, sendProc);
toNbr << UIndirectList<T>(field, subMap[sendProc]);
}
}
}
@ -258,25 +246,7 @@ void Foam::mapDistribute::distribute
UIPstream str(domain, pBufs);
List<T> recvField(str);
if (recvField.size() != map.size())
{
FatalErrorIn
(
"template<class T>\n"
"void mapDistribute::distribute\n"
"(\n"
" const Pstream::commsTypes commsType,\n"
" const List<labelPair>& schedule,\n"
" const label constructSize,\n"
" const labelListList& subMap,\n"
" const labelListList& constructMap,\n"
" List<T>& field\n"
")\n"
) << "Expected from processor " << domain
<< " " << map.size() << " but received "
<< recvField.size() << " elements."
<< abort(FatalError);
}
checkReceivedSize(domain, map.size(), recvField.size());
forAll(map, i)
{
@ -379,29 +349,13 @@ void Foam::mapDistribute::distribute
if (domain != Pstream::myProcNo() && map.size())
{
if (recvFields[domain].size() != map.size())
{
FatalErrorIn
(
"template<class T>\n"
"void mapDistribute::distribute\n"
"(\n"
" const Pstream::commsTypes commsType,\n"
" const List<labelPair>& schedule,\n"
" const label constructSize,\n"
" const labelListList& subMap,\n"
" const labelListList& constructMap,\n"
" List<T>& field\n"
")\n"
) << "Expected from processor " << domain
<< " " << map.size() << " but received "
<< recvFields[domain].size() << " elements."
<< abort(FatalError);
}
const List<T>& subField = recvFields[domain];
checkReceivedSize(domain, map.size(), subField.size());
forAll(map, i)
{
field[map[i]] = recvFields[domain][i];
field[map[i]] = subField[i];
}
}
}
@ -446,10 +400,11 @@ void Foam::mapDistribute::distribute
const labelList& map = constructMap[Pstream::myProcNo()];
field.setSize(constructSize);
field = nullValue;
forAll(map, i)
{
field[map[i]] = subField[i];
cop(field[map[i]], subField[i]);
}
return;
}
@ -501,25 +456,7 @@ void Foam::mapDistribute::distribute
IPstream fromNbr(Pstream::blocking, domain);
List<T> subField(fromNbr);
if (subField.size() != map.size())
{
FatalErrorIn
(
"template<class T>\n"
"void mapDistribute::distribute\n"
"(\n"
" const Pstream::commsTypes commsType,\n"
" const List<labelPair>& schedule,\n"
" const label constructSize,\n"
" const labelListList& subMap,\n"
" const labelListList& constructMap,\n"
" List<T>& field\n"
")\n"
) << "Expected from processor " << domain
<< " " << map.size() << " but received "
<< subField.size() << " elements."
<< abort(FatalError);
}
checkReceivedSize(domain, map.size(), subField.size());
forAll(map, i)
{
@ -550,46 +487,50 @@ void Foam::mapDistribute::distribute
forAll(schedule, i)
{
const labelPair& twoProcs = schedule[i];
// twoProcs is a swap pair of processors. The first one is the
// one that needs to send first and then receive.
label sendProc = twoProcs[0];
label recvProc = twoProcs[1];
if (Pstream::myProcNo() == sendProc)
{
// I am sender. Send to recvProc.
OPstream toNbr(Pstream::scheduled, recvProc);
toNbr << UIndirectList<T>(field, subMap[recvProc]);
// I am send first, receive next
{
OPstream toNbr(Pstream::scheduled, recvProc);
toNbr << UIndirectList<T>(field, subMap[recvProc]);
}
{
IPstream fromNbr(Pstream::scheduled, recvProc);
List<T> subField(fromNbr);
const labelList& map = constructMap[recvProc];
checkReceivedSize(recvProc, map.size(), subField.size());
forAll(map, i)
{
cop(newField[map[i]], subField[i]);
}
}
}
else
{
// I am receiver. Receive from sendProc.
IPstream fromNbr(Pstream::scheduled, sendProc);
List<T> subField(fromNbr);
const labelList& map = constructMap[sendProc];
if (subField.size() != map.size())
// I am receive first, send next
{
FatalErrorIn
(
"template<class T>\n"
"void mapDistribute::distribute\n"
"(\n"
" const Pstream::commsTypes commsType,\n"
" const List<labelPair>& schedule,\n"
" const label constructSize,\n"
" const labelListList& subMap,\n"
" const labelListList& constructMap,\n"
" List<T>& field\n"
")\n"
) << "Expected from processor " << sendProc
<< " " << map.size() << " but received "
<< subField.size() << " elements."
<< abort(FatalError);
IPstream fromNbr(Pstream::scheduled, sendProc);
List<T> subField(fromNbr);
const labelList& map = constructMap[sendProc];
checkReceivedSize(sendProc, map.size(), subField.size());
forAll(map, i)
{
cop(newField[map[i]], subField[i]);
}
}
forAll(map, i)
{
cop(newField[map[i]], subField[i]);
OPstream toNbr(Pstream::scheduled, sendProc);
toNbr << UIndirectList<T>(field, subMap[sendProc]);
}
}
}
@ -648,25 +589,7 @@ void Foam::mapDistribute::distribute
UIPstream str(domain, pBufs);
List<T> recvField(str);
if (recvField.size() != map.size())
{
FatalErrorIn
(
"template<class T>\n"
"void mapDistribute::distribute\n"
"(\n"
" const Pstream::commsTypes commsType,\n"
" const List<labelPair>& schedule,\n"
" const label constructSize,\n"
" const labelListList& subMap,\n"
" const labelListList& constructMap,\n"
" List<T>& field\n"
")\n"
) << "Expected from processor " << domain
<< " " << map.size() << " but received "
<< recvField.size() << " elements."
<< abort(FatalError);
}
checkReceivedSize(domain, map.size(), recvField.size());
forAll(map, i)
{
@ -768,29 +691,13 @@ void Foam::mapDistribute::distribute
if (domain != Pstream::myProcNo() && map.size())
{
if (recvFields[domain].size() != map.size())
{
FatalErrorIn
(
"template<class T>\n"
"void mapDistribute::distribute\n"
"(\n"
" const Pstream::commsTypes commsType,\n"
" const List<labelPair>& schedule,\n"
" const label constructSize,\n"
" const labelListList& subMap,\n"
" const labelListList& constructMap,\n"
" List<T>& field\n"
")\n"
) << "Expected from processor " << domain
<< " " << map.size() << " but received "
<< recvFields[domain].size() << " elements."
<< abort(FatalError);
}
const List<T>& subField = recvFields[domain];
checkReceivedSize(domain, map.size(), subField.size());
forAll(map, i)
{
cop(field[map[i]], recvFields[domain][i]);
cop(field[map[i]], subField[i]);
}
}
}

View File

@ -49,6 +49,7 @@ class objectMap;
inline bool operator==(const objectMap& a, const objectMap& b);
inline bool operator!=(const objectMap& a, const objectMap& b);
inline Ostream& operator<<(Ostream&, const objectMap&);
inline Istream& operator>>(Istream&, objectMap&);
/*---------------------------------------------------------------------------*\
@ -100,6 +101,8 @@ public:
// IOstream Operators
friend Ostream& operator<<(Ostream&, const objectMap&);
friend Istream& operator>>(Istream&, objectMap&);
};

View File

@ -122,6 +122,19 @@ inline Ostream& operator<<(Ostream& os, const objectMap& a)
}
inline Istream& operator>>(Istream& is, objectMap& a)
{
is.readBegin("objectMap");
is >> a.index_ >> a.masterObjects_;
is.readEnd("objectMap");
// Check state of Istream
is.check("Istream& operator>>(Istream&, objectMap&)");
return is;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // Master namespace Foam

View File

@ -29,8 +29,9 @@ License
// Note: the use of this tolerance is ad-hoc, there may be extreme
// cases where the resulting tetrahedra still have particle tracking
// problems.
const Foam::scalar Foam::polyMeshTetDecomposition::minTetQuality = SMALL;
// problems, or tets with lower quality may track OK.
// const Foam::scalar Foam::polyMeshTetDecomposition::minTetQuality = SMALL;
const Foam::scalar Foam::polyMeshTetDecomposition::minTetQuality = ROOTVSMALL;
// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
@ -104,11 +105,10 @@ Foam::label Foam::polyMeshTetDecomposition::findSharedBasePoint
{
return faceBasePtI;
}
}
// If a base point hasn't triggered a return by now, then there is
// non that can produce a good decomposition
// none that can produce a good decomposition
return -1;
}
@ -554,15 +554,17 @@ Foam::List<Foam::tetIndices> Foam::polyMeshTetDecomposition::faceTetIndices
if (tetBasePtI == -1)
{
FatalErrorIn
WarningIn
(
"Foam::List<Foam::FixedList<Foam::label, 4> >"
"Foam::Cloud<ParticleType>::"
"faceTetIndices(label fI, label cI) const"
)
<< "No base point for face " << fI << ", " << f
<< "No base point for face " << fI << ", " << f
<< ", produces a valid tet decomposition."
<< abort(FatalError);
<< endl;
tetBasePtI = 0;
}
for (label tetPtI = 1; tetPtI < f.size() - 1; tetPtI++)

View File

@ -194,6 +194,10 @@ void Foam::cyclicPolyPatch::calcTransforms
vectorField half0Normals(half0Areas.size());
vectorField half1Normals(half1Areas.size());
//- Additional warning about faces non-aligned with rotation axis
//scalar maxCos = -GREAT;
//label maxFacei = -1;
forAll(half0, facei)
{
scalar magSf = mag(half0Areas[facei]);
@ -233,9 +237,33 @@ void Foam::cyclicPolyPatch::calcTransforms
{
half0Normals[facei] = half0Areas[facei] / magSf;
half1Normals[facei] = half1Areas[facei] / nbrMagSf;
//if (transform_ == ROTATIONAL)
//{
// scalar cos = mag(half0Normals[facei] & rotationAxis_);
// if (cos > maxCos)
// {
// maxCos = cos;
// maxFacei = facei;
// }
//}
}
}
//if (maxCos > sqrt(SMALL))
//{
// WarningIn
// (
// "cyclicPolyPatch::calcTransforms()"
// ) << "on patch " << name()
// << " face:" << maxFacei << " fc:" << half0Ctrs[maxFacei]
// << " is not perpendicular to the rotationAxis." << endl
// << "This will cause problems with topology changes." << endl
// << "rotation axis : " << rotationAxis_ << endl
// << "face normal : " << half0Normals[maxFacei] << endl
// << "cosine of angle : " << maxCos << endl;
//}
// Calculate transformation tensors
calcTransformTensors
(
@ -450,6 +478,35 @@ Foam::cyclicPolyPatch::cyclicPolyPatch
}
Foam::cyclicPolyPatch::cyclicPolyPatch
(
const word& name,
const label size,
const label start,
const label index,
const polyBoundaryMesh& bm,
const word& neighbPatchName,
const transformType transform,
const vector& rotationAxis,
const point& rotationCentre,
const vector& separationVector
)
:
coupledPolyPatch(name, size, start, index, bm),
neighbPatchName_(neighbPatchName),
neighbPatchID_(-1),
transform_(transform),
rotationAxis_(rotationAxis),
rotationCentre_(rotationCentre),
separationVector_(separationVector),
coupledPointsPtr_(NULL),
coupledEdgesPtr_(NULL)
{
// Neighbour patch might not be valid yet so no transformation
// calculation possible.
}
Foam::cyclicPolyPatch::cyclicPolyPatch
(
const word& name,

View File

@ -213,6 +213,21 @@ public:
const polyBoundaryMesh& bm
);
//- Construct from components
cyclicPolyPatch
(
const word& name,
const label size,
const label start,
const label index,
const polyBoundaryMesh& bm,
const word& neighbPatchName,
const transformType transform, // transformation type
const vector& rotationAxis, // for rotation only
const point& rotationCentre, // for rotation only
const vector& separationVector // for translation only
);
//- Construct from dictionary
cyclicPolyPatch
(

View File

@ -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
(

View File

@ -142,6 +142,7 @@ $(derivedFvPatchFields)/pressureInletUniformVelocity/pressureInletUniformVelocit
$(derivedFvPatchFields)/pressureInletVelocity/pressureInletVelocityFvPatchVectorField.C
$(derivedFvPatchFields)/rotatingPressureInletOutletVelocity/rotatingPressureInletOutletVelocityFvPatchVectorField.C
$(derivedFvPatchFields)/rotatingTotalPressure/rotatingTotalPressureFvPatchScalarField.C
$(derivedFvPatchFields)/selfContainedDirectMapped/selfContainedDirectMappedFixedValueFvPatchFields.C
$(derivedFvPatchFields)/slip/slipFvPatchFields.C
$(derivedFvPatchFields)/supersonicFreestream/supersonicFreestreamFvPatchVectorField.C
$(derivedFvPatchFields)/surfaceNormalFixedValue/surfaceNormalFixedValueFvPatchVectorField.C

View File

@ -26,6 +26,7 @@ License
#include "directMappedFixedValueFvPatchField.H"
#include "directMappedPatchBase.H"
#include "volFields.H"
#include "interpolationCell.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -42,8 +43,10 @@ directMappedFixedValueFvPatchField<Type>::directMappedFixedValueFvPatchField
)
:
fixedValueFvPatchField<Type>(p, iF),
fieldName_(iF.name()),
setAverage_(false),
average_(pTraits<Type>::zero)
average_(pTraits<Type>::zero),
interpolationScheme_(interpolationCell<Type>::typeName)
{}
@ -57,8 +60,10 @@ directMappedFixedValueFvPatchField<Type>::directMappedFixedValueFvPatchField
)
:
fixedValueFvPatchField<Type>(ptf, p, iF, mapper),
fieldName_(ptf.fieldName_),
setAverage_(ptf.setAverage_),
average_(ptf.average_)
average_(ptf.average_),
interpolationScheme_(ptf.interpolationScheme_)
{
if (!isA<directMappedPatchBase>(this->patch().patch()))
{
@ -91,8 +96,10 @@ directMappedFixedValueFvPatchField<Type>::directMappedFixedValueFvPatchField
)
:
fixedValueFvPatchField<Type>(p, iF, dict),
fieldName_(dict.lookupOrDefault<word>("fieldName", iF.name())),
setAverage_(readBool(dict.lookup("setAverage"))),
average_(pTraits<Type>(dict.lookup("average")))
average_(pTraits<Type>(dict.lookup("average"))),
interpolationScheme_(interpolationCell<Type>::typeName)
{
if (!isA<directMappedPatchBase>(this->patch().patch()))
{
@ -112,6 +119,15 @@ directMappedFixedValueFvPatchField<Type>::directMappedFixedValueFvPatchField
<< " in file " << this->dimensionedInternalField().objectPath()
<< exit(FatalError);
}
const directMappedPatchBase& mpp = refCast<const directMappedPatchBase>
(
directMappedFixedValueFvPatchField<Type>::patch().patch()
);
if (mpp.mode() == directMappedPatchBase::NEARESTCELL)
{
dict.lookup("interpolationScheme") >> interpolationScheme_;
}
}
@ -122,8 +138,10 @@ directMappedFixedValueFvPatchField<Type>::directMappedFixedValueFvPatchField
)
:
fixedValueFvPatchField<Type>(ptf),
fieldName_(ptf.fieldName_),
setAverage_(ptf.setAverage_),
average_(ptf.average_)
average_(ptf.average_),
interpolationScheme_(ptf.interpolationScheme_)
{}
@ -135,13 +153,67 @@ directMappedFixedValueFvPatchField<Type>::directMappedFixedValueFvPatchField
)
:
fixedValueFvPatchField<Type>(ptf, iF),
fieldName_(ptf.fieldName_),
setAverage_(ptf.setAverage_),
average_(ptf.average_)
average_(ptf.average_),
interpolationScheme_(ptf.interpolationScheme_)
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class Type>
const GeometricField<Type, fvPatchField, volMesh>&
directMappedFixedValueFvPatchField<Type>::sampleField() const
{
typedef GeometricField<Type, fvPatchField, volMesh> fieldType;
const directMappedPatchBase& mpp = refCast<const directMappedPatchBase>
(
directMappedFixedValueFvPatchField<Type>::patch().patch()
);
const fvMesh& nbrMesh = refCast<const fvMesh>(mpp.sampleMesh());
if (mpp.sameRegion())
{
if (fieldName_ == this->dimensionedInternalField().name())
{
// Optimisation: bypass field lookup
return
dynamic_cast<const fieldType&>
(
this->dimensionedInternalField()
);
}
else
{
const fvMesh& thisMesh = this->patch().boundaryMesh().mesh();
return thisMesh.lookupObject<fieldType>(fieldName_);
}
}
else
{
return nbrMesh.lookupObject<fieldType>(fieldName_);
}
}
template<class Type>
const interpolation<Type>&
directMappedFixedValueFvPatchField<Type>::interpolator() const
{
if (!interpolator_.valid())
{
interpolator_ = interpolation<Type>::New
(
interpolationScheme_,
sampleField()
);
}
return interpolator_();
}
template<class Type>
void directMappedFixedValueFvPatchField<Type>::updateCoeffs()
{
@ -159,11 +231,8 @@ void directMappedFixedValueFvPatchField<Type>::updateCoeffs()
);
const mapDistribute& distMap = mpp.map();
// Force recalculation of schedule
(void)distMap.schedule();
const fvMesh& thisMesh = this->patch().boundaryMesh().mesh();
const fvMesh& nbrMesh = refCast<const fvMesh>(mpp.sampleMesh());
const word& fldName = this->dimensionedInternalField().name();
// Result of obtaining remote values
Field<Type> newValues;
@ -172,26 +241,38 @@ void directMappedFixedValueFvPatchField<Type>::updateCoeffs()
{
case directMappedPatchBase::NEARESTCELL:
{
if (mpp.sameRegion())
if (interpolationScheme_ != interpolationCell<Type>::typeName)
{
newValues = this->internalField();
// Send back sample points to the processor that holds the cell
vectorField samples(mpp.samplePoints());
distMap.reverseDistribute
(
(mpp.sameRegion() ? thisMesh.nCells() : nbrMesh.nCells()),
point::max,
samples
);
const interpolation<Type>& interp = interpolator();
newValues.setSize(samples.size(), pTraits<Type>::max);
forAll(samples, cellI)
{
if (samples[cellI] != point::max)
{
newValues[cellI] = interp.interpolate
(
samples[cellI],
cellI
);
}
}
}
else
{
newValues = nbrMesh.lookupObject<fieldType>
(
fldName
).internalField();
newValues = sampleField();
}
mapDistribute::distribute
(
Pstream::defaultCommsType,
distMap.schedule(),
distMap.constructSize(),
distMap.subMap(),
distMap.constructMap(),
newValues
);
distMap.distribute(newValues);
break;
}
@ -213,20 +294,10 @@ void directMappedFixedValueFvPatchField<Type>::updateCoeffs()
<< abort(FatalError);
}
const fieldType& nbrField = nbrMesh.lookupObject<fieldType>
(
fldName
);
const fieldType& nbrField = sampleField();
newValues = nbrField.boundaryField()[nbrPatchID];
mapDistribute::distribute
(
Pstream::defaultCommsType,
distMap.schedule(),
distMap.constructSize(),
distMap.subMap(),
distMap.constructMap(),
newValues
);
distMap.distribute(newValues);
break;
}
@ -234,10 +305,8 @@ void directMappedFixedValueFvPatchField<Type>::updateCoeffs()
{
Field<Type> allValues(nbrMesh.nFaces(), pTraits<Type>::zero);
const fieldType& nbrField = nbrMesh.lookupObject<fieldType>
(
fldName
);
const fieldType& nbrField = sampleField();
forAll(nbrField.boundaryField(), patchI)
{
const fvPatchField<Type>& pf =
@ -250,16 +319,7 @@ void directMappedFixedValueFvPatchField<Type>::updateCoeffs()
}
}
mapDistribute::distribute
(
Pstream::defaultCommsType,
distMap.schedule(),
distMap.constructSize(),
distMap.subMap(),
distMap.constructMap(),
allValues
);
distMap.distribute(allValues);
newValues.transfer(allValues);
break;
@ -294,7 +354,8 @@ void directMappedFixedValueFvPatchField<Type>::updateCoeffs()
if (debug)
{
Info<< "directMapped on field:" << fldName
Info<< "directMapped on field:"
<< this->dimensionedInternalField().name()
<< " patch:" << this->patch().name()
<< " avg:" << gAverage(*this)
<< " min:" << gMin(*this)
@ -310,8 +371,11 @@ template<class Type>
void directMappedFixedValueFvPatchField<Type>::write(Ostream& os) const
{
fvPatchField<Type>::write(os);
os.writeKeyword("fieldName") << fieldName_ << token::END_STATEMENT << nl;
os.writeKeyword("setAverage") << setAverage_ << token::END_STATEMENT << nl;
os.writeKeyword("average") << average_ << token::END_STATEMENT << nl;
os.writeKeyword("interpolationScheme") << interpolationScheme_
<< token::END_STATEMENT << nl;
this->writeEntry("value", os);
}

View File

@ -33,6 +33,17 @@ Description
mode = NEARESTFACE : sample nearest face on any patch. Note: does not
warn if nearest actually is on internal face!
For NEARESTCELL you have to provide an 'interpolationScheme' entry
which can be any one of the interpolation schemes (cell, cellPoint, etc.)
In case of interpolation (so scheme != cell) the limitation is that
there is only one value per cell. So e.g. if you have a cell with two
boundary faces and both faces sample into the cell both faces will get
the same value.
See directMappedPatchBase for options on sampling.
Optional 'fieldName' entry to supply a different filename
SourceFiles
directMappedFixedValueFvPatchField.C
@ -43,6 +54,7 @@ SourceFiles
#include "fixedValueFvPatchFields.H"
#include "directMappedFvPatch.H"
#include "interpolation.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -60,12 +72,29 @@ class directMappedFixedValueFvPatchField
{
// Private data
//- Name of field to sample - defaults to field associated with this
// patchField if not specified
word fieldName_;
//- If true adjust the mapped field to maintain average value average_
bool setAverage_;
const bool setAverage_;
//- Average value the mapped field is adjusted to maintain if
// setAverage_ is set true
Type average_;
const Type average_;
//- Interpolation scheme to use for nearestcell mode
word interpolationScheme_;
mutable autoPtr<interpolation<Type> > interpolator_;
// Private Member Functions
//- Field to sample. Either on my or nbr mesh
const GeometricField<Type, fvPatchField, volMesh>& sampleField() const;
//- Access the interpolation method
const interpolation<Type>& interpolator() const;
public:

View File

@ -112,6 +112,29 @@ directMappedVelocityFluxFixedValueFvPatchField
<< " in file " << dimensionedInternalField().objectPath()
<< exit(FatalError);
}
const directMappedPatchBase& mpp = refCast<const directMappedPatchBase>
(
this->patch().patch()
);
if (mpp.mode() == directMappedPolyPatch::NEARESTCELL)
{
FatalErrorIn
(
"directMappedVelocityFluxFixedValueFvPatchField::"
"directMappedVelocityFluxFixedValueFvPatchField"
"("
"const fvPatch&, "
"const DimensionedField<vector, volMesh>&, "
"const dictionary&"
")"
) << "Patch " << p.name()
<< " of type '" << p.type()
<< "' can not be used in 'nearestCell' mode"
<< " of field " << dimensionedInternalField().name()
<< " in file " << dimensionedInternalField().objectPath()
<< exit(FatalError);
}
}
@ -189,26 +212,10 @@ void directMappedVelocityFluxFixedValueFvPatchField::updateCoeffs()
}
}
mapDistribute::distribute
(
Pstream::defaultCommsType,
distMap.schedule(),
distMap.constructSize(),
distMap.subMap(),
distMap.constructMap(),
allUValues
);
distMap.distribute(allUValues);
newUValues.transfer(allUValues);
mapDistribute::distribute
(
Pstream::defaultCommsType,
distMap.schedule(),
distMap.constructSize(),
distMap.subMap(),
distMap.constructMap(),
allPhiValues
);
distMap.distribute(allPhiValues);
newPhiValues.transfer(allPhiValues);
break;
@ -221,28 +228,10 @@ void directMappedVelocityFluxFixedValueFvPatchField::updateCoeffs()
);
newUValues = UField.boundaryField()[nbrPatchID];
mapDistribute::distribute
(
Pstream::defaultCommsType,
distMap.schedule(),
distMap.constructSize(),
distMap.subMap(),
distMap.constructMap(),
newUValues
);
distMap.distribute(newUValues);
newPhiValues = phiField.boundaryField()[nbrPatchID];
mapDistribute::distribute
(
Pstream::defaultCommsType,
distMap.schedule(),
distMap.constructSize(),
distMap.subMap(),
distMap.constructMap(),
newPhiValues
);
distMap.distribute(newPhiValues);
break;
}

View File

@ -0,0 +1,387 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 1991-2010 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 "selfContainedDirectMappedFixedValueFvPatchField.H"
#include "volFields.H"
#include "interpolationCell.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
template<class Type>
selfContainedDirectMappedFixedValueFvPatchField<Type>::
selfContainedDirectMappedFixedValueFvPatchField
(
const fvPatch& p,
const DimensionedField<Type, volMesh>& iF
)
:
directMappedPatchBase(p.patch()),
fixedValueFvPatchField<Type>(p, iF),
fieldName_(iF.name()),
setAverage_(false),
average_(pTraits<Type>::zero),
interpolationScheme_(interpolationCell<Type>::typeName)
{}
template<class Type>
selfContainedDirectMappedFixedValueFvPatchField<Type>::
selfContainedDirectMappedFixedValueFvPatchField
(
const selfContainedDirectMappedFixedValueFvPatchField<Type>& ptf,
const fvPatch& p,
const DimensionedField<Type, volMesh>& iF,
const fvPatchFieldMapper& mapper
)
:
directMappedPatchBase(p.patch(), ptf),
fixedValueFvPatchField<Type>(ptf, p, iF, mapper),
fieldName_(ptf.fieldName_),
setAverage_(ptf.setAverage_),
average_(ptf.average_),
interpolationScheme_(ptf.interpolationScheme_)
{}
template<class Type>
selfContainedDirectMappedFixedValueFvPatchField<Type>::
selfContainedDirectMappedFixedValueFvPatchField
(
const fvPatch& p,
const DimensionedField<Type, volMesh>& iF,
const dictionary& dict
)
:
directMappedPatchBase(p.patch(), dict),
fixedValueFvPatchField<Type>(p, iF, dict),
fieldName_(dict.lookupOrDefault<word>("fieldName", iF.name())),
setAverage_(readBool(dict.lookup("setAverage"))),
average_(pTraits<Type>(dict.lookup("average"))),
interpolationScheme_(interpolationCell<Type>::typeName)
{
if (mode() == directMappedPatchBase::NEARESTCELL)
{
dict.lookup("interpolationScheme") >> interpolationScheme_;
}
}
template<class Type>
selfContainedDirectMappedFixedValueFvPatchField<Type>::
selfContainedDirectMappedFixedValueFvPatchField
(
const fvPatch& p,
const DimensionedField<Type, volMesh>& iF,
// directMappedPatchBase
const word& sampleRegion,
const sampleMode sampleMode,
const word& samplePatch,
const scalar distance,
// My settings
const word& fieldName,
const bool setAverage,
const Type average,
const word& interpolationScheme
)
:
directMappedPatchBase
(
p.patch(),
sampleRegion,
sampleMode,
samplePatch,
distance
),
fixedValueFvPatchField<Type>(p, iF),
fieldName_(fieldName),
setAverage_(setAverage),
average_(average),
interpolationScheme_(interpolationScheme)
{}
template<class Type>
selfContainedDirectMappedFixedValueFvPatchField<Type>::
selfContainedDirectMappedFixedValueFvPatchField
(
const selfContainedDirectMappedFixedValueFvPatchField<Type>& ptf
)
:
directMappedPatchBase(ptf.patch().patch(), ptf),
fixedValueFvPatchField<Type>(ptf),
fieldName_(ptf.fieldName_),
setAverage_(ptf.setAverage_),
average_(ptf.average_),
interpolationScheme_(ptf.interpolationScheme_)
{}
template<class Type>
selfContainedDirectMappedFixedValueFvPatchField<Type>::
selfContainedDirectMappedFixedValueFvPatchField
(
const selfContainedDirectMappedFixedValueFvPatchField<Type>& ptf,
const DimensionedField<Type, volMesh>& iF
)
:
directMappedPatchBase(ptf.patch().patch(), ptf),
fixedValueFvPatchField<Type>(ptf, iF),
fieldName_(ptf.fieldName_),
setAverage_(ptf.setAverage_),
average_(ptf.average_),
interpolationScheme_(ptf.interpolationScheme_)
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class Type>
const GeometricField<Type, fvPatchField, volMesh>&
selfContainedDirectMappedFixedValueFvPatchField<Type>::sampleField() const
{
typedef GeometricField<Type, fvPatchField, volMesh> fieldType;
const fvMesh& nbrMesh = refCast<const fvMesh>(sampleMesh());
if (sameRegion())
{
if (fieldName_ == this->dimensionedInternalField().name())
{
// Optimisation: bypass field lookup
return
dynamic_cast<const fieldType&>
(
this->dimensionedInternalField()
);
}
else
{
const fvMesh& thisMesh = this->patch().boundaryMesh().mesh();
return thisMesh.lookupObject<fieldType>(fieldName_);
}
}
else
{
return nbrMesh.lookupObject<fieldType>(fieldName_);
}
}
template<class Type>
const interpolation<Type>&
selfContainedDirectMappedFixedValueFvPatchField<Type>::interpolator() const
{
if (!interpolator_.valid())
{
interpolator_ = interpolation<Type>::New
(
interpolationScheme_,
sampleField()
);
}
return interpolator_();
}
template<class Type>
void selfContainedDirectMappedFixedValueFvPatchField<Type>::updateCoeffs()
{
if (this->updated())
{
return;
}
typedef GeometricField<Type, fvPatchField, volMesh> fieldType;
const fvMesh& thisMesh = this->patch().boundaryMesh().mesh();
const fvMesh& nbrMesh = refCast<const fvMesh>(sampleMesh());
const mapDistribute& distMap = directMappedPatchBase::map();
// Result of obtaining remote values
Field<Type> newValues;
switch (mode())
{
case NEARESTCELL:
{
if (interpolationScheme_ != interpolationCell<Type>::typeName)
{
// Need to do interpolation so need cells to sample.
// Send back sample points to the processor that holds the cell
vectorField samples(samplePoints());
distMap.reverseDistribute
(
(sameRegion() ? thisMesh.nCells() : nbrMesh.nCells()),
point::max,
samples
);
const interpolation<Type>& interp = interpolator();
newValues.setSize(samples.size(), pTraits<Type>::max);
forAll(samples, cellI)
{
if (samples[cellI] != point::max)
{
newValues[cellI] = interp.interpolate
(
samples[cellI],
cellI
);
}
}
}
else
{
newValues = sampleField();
}
distMap.distribute(newValues);
break;
}
case NEARESTPATCHFACE:
{
const label nbrPatchID = nbrMesh.boundaryMesh().findPatchID
(
samplePatch()
);
if (nbrPatchID < 0)
{
FatalErrorIn
(
"void "
"selfContainedDirectMappedFixedValueFvPatchField<Type>::"
"updateCoeffs()"
)<< "Unable to find sample patch " << samplePatch()
<< " in region " << sampleRegion()
<< " for patch " << this->patch().name() << nl
<< abort(FatalError);
}
const fieldType& nbrField = sampleField();
newValues = nbrField.boundaryField()[nbrPatchID];
distMap.distribute(newValues);
break;
}
case NEARESTFACE:
{
Field<Type> allValues(nbrMesh.nFaces(), pTraits<Type>::zero);
const fieldType& nbrField = sampleField();
forAll(nbrField.boundaryField(), patchI)
{
const fvPatchField<Type>& pf =
nbrField.boundaryField()[patchI];
label faceStart = pf.patch().start();
forAll(pf, faceI)
{
allValues[faceStart++] = pf[faceI];
}
}
distMap.distribute(allValues);
newValues.transfer(allValues);
break;
}
default:
{
FatalErrorIn
(
"selfContainedDirectMappedFixedValueFvPatchField<Type>::"
"updateCoeffs()"
) << "Unknown sampling mode: " << mode()
<< nl << abort(FatalError);
}
}
if (setAverage_)
{
Type averagePsi =
gSum(this->patch().magSf()*newValues)
/gSum(this->patch().magSf());
if (mag(averagePsi)/mag(average_) > 0.5)
{
newValues *= mag(average_)/mag(averagePsi);
}
else
{
newValues += (average_ - averagePsi);
}
}
this->operator==(newValues);
if (debug)
{
Info<< "selfContainedDirectMapped on field:"
<< this->dimensionedInternalField().name()
<< " patch:" << this->patch().name()
<< " avg:" << gAverage(*this)
<< " min:" << gMin(*this)
<< " max:" << gMax(*this)
<< endl;
}
fixedValueFvPatchField<Type>::updateCoeffs();
}
template<class Type>
void selfContainedDirectMappedFixedValueFvPatchField<Type>::write(Ostream& os)
const
{
fvPatchField<Type>::write(os);
directMappedPatchBase::write(os);
os.writeKeyword("fieldName") << fieldName_ << token::END_STATEMENT << nl;
os.writeKeyword("setAverage") << setAverage_ << token::END_STATEMENT << nl;
os.writeKeyword("average") << average_ << token::END_STATEMENT << nl;
os.writeKeyword("interpolationScheme") << interpolationScheme_
<< token::END_STATEMENT << nl;
this->writeEntry("value", os);
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// ************************************************************************* //

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2010-2010 OpenCFD Ltd.
\\ / A nd | Copyright (C) 1991-2010 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
@ -22,22 +22,25 @@ License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Class
Foam::directMappedNamedFixedValueFvPatchField
Foam::selfContainedDirectMappedFixedValueFvPatchField
Description
Variant of directMappedFixedValueFvPatch where the name of the field to
map is input.
Self-contained version of directMapped. Does not use information on
patch, instead holds it locally (and possibly duplicate) so use
normal directMapped in preference and only use this if you cannot
change the underlying patch type to directMapped.
SourceFiles
directMappedNamedFixedValueFvPatchField.C
selfContainedDirectMappedFixedValueFvPatchField.C
\*---------------------------------------------------------------------------*/
#ifndef directMappedNamedFixedValueFvPatchField_H
#define directMappedNamedFixedValueFvPatchField_H
#ifndef selfContainedDirectMappedFixedValueFvPatchField_H
#define selfContainedDirectMappedFixedValueFvPatchField_H
#include "fixedValueFvPatchField.H"
#include "directMappedFvPatch.H"
#include "directMappedPatchBase.H"
#include "fixedValueFvPatchFields.H"
#include "interpolation.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -45,65 +48,99 @@ namespace Foam
{
/*---------------------------------------------------------------------------*\
Class directMappedNamesFixedValueFvPatchField Declaration
Class selfContainedDirectMappedFixedValueFvPatch Declaration
\*---------------------------------------------------------------------------*/
template<class Type>
class directMappedNamedFixedValueFvPatchField
class selfContainedDirectMappedFixedValueFvPatchField
:
public directMappedPatchBase,
public fixedValueFvPatchField<Type>
{
// Private data
//- Name of field to sample - defaults to field associated with this
// patch if not specified
// patchField if not specified
word fieldName_;
//- If true adjust the mapped field to maintain average value average_
bool setAverage_;
const bool setAverage_;
//- Average value the mapped field is adjusted to maintain if
// setAverage_ is set true
Type average_;
const Type average_;
//- Interpolation scheme to use for nearestcell mode
word interpolationScheme_;
mutable autoPtr<interpolation<Type> > interpolator_;
// Private Member Functions
//- Field to sample. Either on my or nbr mesh
const GeometricField<Type, fvPatchField, volMesh>& sampleField() const;
//- Access the interpolation method
const interpolation<Type>& interpolator() const;
public:
//- Runtime type information
TypeName("directMappedNamedFixedValue");
TypeName("selfContainedDirectMapped");
// Constructors
//- Construct from patch and internal field
directMappedNamedFixedValueFvPatchField
selfContainedDirectMappedFixedValueFvPatchField
(
const fvPatch&,
const DimensionedField<Type, volMesh>&
);
//- Construct from patch, internal field and dictionary
directMappedNamedFixedValueFvPatchField
selfContainedDirectMappedFixedValueFvPatchField
(
const fvPatch&,
const DimensionedField<Type, volMesh>&,
const dictionary&
);
//- Construct by mapping given directMappedNamedFixedValueFvPatchField
// onto a new patch
directMappedNamedFixedValueFvPatchField
//- Construct from patch, internal field and distance for normal type
// sampling
selfContainedDirectMappedFixedValueFvPatchField
(
const directMappedNamedFixedValueFvPatchField<Type>&,
const fvPatch&,
const DimensionedField<Type, volMesh>&,
// directMappedPatchBase
const word& sampleRegion,
const sampleMode sampleMode,
const word& samplePatch,
const scalar distance,
// My settings
const word& fieldName,
const bool setAverage,
const Type average,
const word& interpolationScheme
);
//- Construct by mapping given
// selfContainedDirectMappedFixedValueFvPatchField
// onto a new patch
selfContainedDirectMappedFixedValueFvPatchField
(
const selfContainedDirectMappedFixedValueFvPatchField<Type>&,
const fvPatch&,
const DimensionedField<Type, volMesh>&,
const fvPatchFieldMapper&
);
//- Construct as copy
directMappedNamedFixedValueFvPatchField
selfContainedDirectMappedFixedValueFvPatchField
(
const directMappedNamedFixedValueFvPatchField<Type>&
const selfContainedDirectMappedFixedValueFvPatchField<Type>&
);
//- Construct and return a clone
@ -111,14 +148,17 @@ public:
{
return tmp<fvPatchField<Type> >
(
new directMappedNamedFixedValueFvPatchField<Type>(*this)
new selfContainedDirectMappedFixedValueFvPatchField<Type>
(
*this
)
);
}
//- Construct as copy setting internal field reference
directMappedNamedFixedValueFvPatchField
selfContainedDirectMappedFixedValueFvPatchField
(
const directMappedNamedFixedValueFvPatchField<Type>&,
const selfContainedDirectMappedFixedValueFvPatchField<Type>&,
const DimensionedField<Type, volMesh>&
);
@ -130,7 +170,11 @@ public:
{
return tmp<fvPatchField<Type> >
(
new directMappedNamedFixedValueFvPatchField<Type>(*this, iF)
new selfContainedDirectMappedFixedValueFvPatchField<Type>
(
*this,
iF
)
);
}
@ -154,7 +198,7 @@ public:
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository
# include "directMappedNamedFixedValueFvPatchField.C"
# include "selfContainedDirectMappedFixedValueFvPatchField.C"
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2010-2010 OpenCFD Ltd.
\\ / A nd | Copyright (C) 1991-2010 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
@ -23,7 +23,7 @@ License
\*---------------------------------------------------------------------------*/
#include "directMappedNamedFixedValueFvPatchFields.H"
#include "selfContainedDirectMappedFixedValueFvPatchFields.H"
#include "volMesh.H"
#include "addToRunTimeSelectionTable.H"
@ -34,7 +34,7 @@ namespace Foam
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
makePatchFields(directMappedNamedFixedValue);
makePatchFields(selfContainedDirectMappedFixedValue);
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2010-2010 OpenCFD Ltd.
\\ / A nd | Copyright (C) 1991-2010 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
@ -23,9 +23,10 @@ License
\*---------------------------------------------------------------------------*/
#ifndef directMappedNamedFixedValueFvPatchFieldsFwd_H
#define directMappedNamedFixedValueFvPatchFieldsFwd_H
#ifndef selfContainedDirectMappedFixedValueFvPatchFields_H
#define selfContainedDirectMappedFixedValueFvPatchFields_H
#include "selfContainedDirectMappedFixedValueFvPatchField.H"
#include "fieldTypes.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -35,9 +36,7 @@ namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
template<class Type> class directMappedNamedFixedValueFvPatchField;
makePatchTypeFieldTypedefs(directMappedNamedFixedValue)
makePatchTypeFieldTypedefs(selfContainedDirectMappedFixedValue)
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2010-2010 OpenCFD Ltd.
\\ / A nd | Copyright (C) 1991-2010 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
@ -23,8 +23,8 @@ License
\*---------------------------------------------------------------------------*/
#ifndef directMappedNamedFixedValueFvPatchFieldsFwd_H
#define directMappedNamedFixedValueFvPatchFieldsFwd_H
#ifndef selfContainedDirectMappedFixedValueFvPatchFieldsFwd_H
#define selfContainedDirectMappedFixedValueFvPatchFieldsFwd_H
#include "fieldTypes.H"
@ -35,9 +35,9 @@ namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
template<class Type> class directMappedNamedFixedValueFvPatchField;
template<class Type> class selfContainedDirectMappedFixedValueFvPatchField;
makePatchTypeFieldTypedefs(directMappedNamedFixedValue)
makePatchTypeFieldTypedefs(selfContainedDirectMappedFixedValue)
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View File

@ -28,9 +28,9 @@ License
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
int Foam::fvSchemes::debug(Foam::debug::debugSwitch("fvSchemes", false));
// * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * * //
void Foam::fvSchemes::clear()
@ -53,6 +53,198 @@ void Foam::fvSchemes::clear()
defaultFluxRequired_ = false;
}
void Foam::fvSchemes::read(const dictionary& dict)
{
if (dict.found("ddtSchemes"))
{
ddtSchemes_ = dict.subDict("ddtSchemes");
}
else if (dict.found("timeScheme"))
{
// For backward compatibility.
// The timeScheme will be deprecated with warning or removed
WarningIn("fvSchemes::read()")
<< "Using deprecated 'timeScheme' instead of 'ddtSchemes'"
<< nl << endl;
word schemeName(dict.lookup("timeScheme"));
if (schemeName == "EulerImplicit")
{
schemeName = "Euler";
}
else if (schemeName == "BackwardDifferencing")
{
schemeName = "backward";
}
else if (schemeName == "SteadyState")
{
schemeName = "steadyState";
}
else
{
FatalIOErrorIn("fvSchemes::read()", dict.lookup("timeScheme"))
<< "\n Only EulerImplicit, BackwardDifferencing and "
"SteadyState\n are supported by the old timeScheme "
"specification.\n Please use ddtSchemes instead."
<< exit(FatalIOError);
}
ddtSchemes_.set("default", schemeName);
ddtSchemes_.lookup("default")[0].lineNumber() =
dict.lookup("timeScheme").lineNumber();
}
else
{
ddtSchemes_.set("default", "none");
}
if
(
ddtSchemes_.found("default")
&& word(ddtSchemes_.lookup("default")) != "none"
)
{
defaultDdtScheme_ = ddtSchemes_.lookup("default");
}
if (dict.found("d2dt2Schemes"))
{
d2dt2Schemes_ = dict.subDict("d2dt2Schemes");
}
else if (dict.found("timeScheme"))
{
// For backward compatibility.
// The timeScheme will be deprecated with warning or removed
WarningIn("fvSchemes::read()")
<< "Using deprecated 'timeScheme' instead of 'd2dt2Schemes'"
<< nl << endl;
word schemeName(dict.lookup("timeScheme"));
if (schemeName == "EulerImplicit")
{
schemeName = "Euler";
}
else if (schemeName == "SteadyState")
{
schemeName = "steadyState";
}
d2dt2Schemes_.set("default", schemeName);
d2dt2Schemes_.lookup("default")[0].lineNumber() =
dict.lookup("timeScheme").lineNumber();
}
else
{
d2dt2Schemes_.set("default", "none");
}
if
(
d2dt2Schemes_.found("default")
&& word(d2dt2Schemes_.lookup("default")) != "none"
)
{
defaultD2dt2Scheme_ = d2dt2Schemes_.lookup("default");
}
if (dict.found("interpolationSchemes"))
{
interpolationSchemes_ = dict.subDict("interpolationSchemes");
}
else if (!interpolationSchemes_.found("default"))
{
interpolationSchemes_.add("default", "linear");
}
if
(
interpolationSchemes_.found("default")
&& word(interpolationSchemes_.lookup("default")) != "none"
)
{
defaultInterpolationScheme_ =
interpolationSchemes_.lookup("default");
}
divSchemes_ = dict.subDict("divSchemes");
if
(
divSchemes_.found("default")
&& word(divSchemes_.lookup("default")) != "none"
)
{
defaultDivScheme_ = divSchemes_.lookup("default");
}
gradSchemes_ = dict.subDict("gradSchemes");
if
(
gradSchemes_.found("default")
&& word(gradSchemes_.lookup("default")) != "none"
)
{
defaultGradScheme_ = gradSchemes_.lookup("default");
}
if (dict.found("snGradSchemes"))
{
snGradSchemes_ = dict.subDict("snGradSchemes");
}
else if (!snGradSchemes_.found("default"))
{
snGradSchemes_.add("default", "corrected");
}
if
(
snGradSchemes_.found("default")
&& word(snGradSchemes_.lookup("default")) != "none"
)
{
defaultSnGradScheme_ = snGradSchemes_.lookup("default");
}
laplacianSchemes_ = dict.subDict("laplacianSchemes");
if
(
laplacianSchemes_.found("default")
&& word(laplacianSchemes_.lookup("default")) != "none"
)
{
defaultLaplacianScheme_ = laplacianSchemes_.lookup("default");
}
if (dict.found("fluxRequired"))
{
fluxRequired_ = dict.subDict("fluxRequired");
if
(
fluxRequired_.found("default")
&& word(fluxRequired_.lookup("default")) != "none"
)
{
defaultFluxRequired_ = Switch(fluxRequired_.lookup("default"));
}
}
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::fvSchemes::fvSchemes(const objectRegistry& obr)
@ -169,7 +361,10 @@ Foam::fvSchemes::fvSchemes(const objectRegistry& obr)
),
defaultFluxRequired_(false)
{
read();
// persistent settings across reads is incorrect
clear();
read(schemesDict());
}
@ -179,197 +374,10 @@ bool Foam::fvSchemes::read()
{
if (regIOobject::read())
{
const dictionary& dict = schemesDict();
// persistent settings across reads is incorrect
clear();
if (dict.found("ddtSchemes"))
{
ddtSchemes_ = dict.subDict("ddtSchemes");
}
else if (dict.found("timeScheme"))
{
// For backward compatibility.
// The timeScheme will be deprecated with warning or removed
WarningIn("fvSchemes::read()")
<< "Using deprecated 'timeScheme' instead of 'ddtSchemes'"
<< nl << endl;
word schemeName(dict.lookup("timeScheme"));
if (schemeName == "EulerImplicit")
{
schemeName = "Euler";
}
else if (schemeName == "BackwardDifferencing")
{
schemeName = "backward";
}
else if (schemeName == "SteadyState")
{
schemeName = "steadyState";
}
else
{
FatalIOErrorIn("fvSchemes::read()", dict.lookup("timeScheme"))
<< "\n Only EulerImplicit, BackwardDifferencing and "
"SteadyState\n are supported by the old timeScheme "
"specification.\n Please use ddtSchemes instead."
<< exit(FatalIOError);
}
ddtSchemes_.set("default", schemeName);
ddtSchemes_.lookup("default")[0].lineNumber() =
dict.lookup("timeScheme").lineNumber();
}
else
{
ddtSchemes_.set("default", "none");
}
if
(
ddtSchemes_.found("default")
&& word(ddtSchemes_.lookup("default")) != "none"
)
{
defaultDdtScheme_ = ddtSchemes_.lookup("default");
}
if (dict.found("d2dt2Schemes"))
{
d2dt2Schemes_ = dict.subDict("d2dt2Schemes");
}
else if (dict.found("timeScheme"))
{
// For backward compatibility.
// The timeScheme will be deprecated with warning or removed
WarningIn("fvSchemes::read()")
<< "Using deprecated 'timeScheme' instead of 'd2dt2Schemes'"
<< nl << endl;
word schemeName(dict.lookup("timeScheme"));
if (schemeName == "EulerImplicit")
{
schemeName = "Euler";
}
else if (schemeName == "SteadyState")
{
schemeName = "steadyState";
}
d2dt2Schemes_.set("default", schemeName);
d2dt2Schemes_.lookup("default")[0].lineNumber() =
dict.lookup("timeScheme").lineNumber();
}
else
{
d2dt2Schemes_.set("default", "none");
}
if
(
d2dt2Schemes_.found("default")
&& word(d2dt2Schemes_.lookup("default")) != "none"
)
{
defaultD2dt2Scheme_ = d2dt2Schemes_.lookup("default");
}
if (dict.found("interpolationSchemes"))
{
interpolationSchemes_ = dict.subDict("interpolationSchemes");
}
else if (!interpolationSchemes_.found("default"))
{
interpolationSchemes_.add("default", "linear");
}
if
(
interpolationSchemes_.found("default")
&& word(interpolationSchemes_.lookup("default")) != "none"
)
{
defaultInterpolationScheme_ =
interpolationSchemes_.lookup("default");
}
divSchemes_ = dict.subDict("divSchemes");
if
(
divSchemes_.found("default")
&& word(divSchemes_.lookup("default")) != "none"
)
{
defaultDivScheme_ = divSchemes_.lookup("default");
}
gradSchemes_ = dict.subDict("gradSchemes");
if
(
gradSchemes_.found("default")
&& word(gradSchemes_.lookup("default")) != "none"
)
{
defaultGradScheme_ = gradSchemes_.lookup("default");
}
if (dict.found("snGradSchemes"))
{
snGradSchemes_ = dict.subDict("snGradSchemes");
}
else if (!snGradSchemes_.found("default"))
{
snGradSchemes_.add("default", "corrected");
}
if
(
snGradSchemes_.found("default")
&& word(snGradSchemes_.lookup("default")) != "none"
)
{
defaultSnGradScheme_ = snGradSchemes_.lookup("default");
}
laplacianSchemes_ = dict.subDict("laplacianSchemes");
if
(
laplacianSchemes_.found("default")
&& word(laplacianSchemes_.lookup("default")) != "none"
)
{
defaultLaplacianScheme_ = laplacianSchemes_.lookup("default");
}
if (dict.found("fluxRequired"))
{
fluxRequired_ = dict.subDict("fluxRequired");
if
(
fluxRequired_.found("default")
&& word(fluxRequired_.lookup("default")) != "none"
)
{
defaultFluxRequired_ = Switch(fluxRequired_.lookup("default"));
}
}
read(schemesDict());
return true;
}

View File

@ -84,6 +84,9 @@ class fvSchemes
//- Clear the dictionaries and streams before reading
void clear();
//- Read settings from the dictionary
void read(const dictionary&);
//- Disallow default bitwise copy construct
fvSchemes(const fvSchemes&);

View File

@ -36,7 +36,10 @@ Foam::interpolationCellPoint<Type>::interpolationCellPoint
:
interpolation<Type>(psi),
psip_(volPointInterpolation::New(psi.mesh()).interpolate(psi))
{}
{
// Uses cellPointWeight to do interpolation which needs tet decomposition
(void)psi.mesh().tetBasePtIs();
}
// ************************************************************************* //

View File

@ -253,7 +253,11 @@ public:
//- Increment the nTrackingRescues counter
void trackingRescue() const
{
nTrackingRescues_++;
if (++nTrackingRescues_ % size() == 0)
{
Info<< " " << nTrackingRescues_
<< " tracking rescues " << endl;
}
}
//- Whether each cell has any wall faces (demand driven data)

View File

@ -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();
@ -264,6 +256,17 @@ Foam::scalar Foam::Particle<ParticleType>::trackToFace
faceI_ = -1;
// Pout<< "Particle " << origId_ << " " << origProc_
// << " Tracking from " << position_
// << " to " << endPosition
// << endl;
// Pout<< "stepFraction " << stepFraction_ << nl
// << "cellI " << cellI_ << nl
// << "tetFaceI " << tetFaceI_ << nl
// << "tetPtI " << tetPtI_
// << endl;
scalar trackFraction = 0.0;
// Minimum tetrahedron decomposition of each cell of the mesh into
@ -405,6 +408,8 @@ Foam::scalar Foam::Particle<ParticleType>::trackToFace
triI = -1;
lambdaMin = VGREAT;
// Pout<< "tris " << tris << endl;
// Sets a value for lambdaMin and faceI_ if a wall face is hit
// by the track.
hitWallFaces(position_, endPosition, lambdaMin, faceHitTetIs);
@ -469,6 +474,35 @@ Foam::scalar Foam::Particle<ParticleType>::trackToFace
faceI_ = -1;
}
// Pout<< "track loop " << position_ << " " << endPosition << nl
// << " " << cellI_
// << " " << faceI_
// << " " << tetFaceI_
// << " " << tetPtI_
// << " " << triI
// << " " << lambdaMin
// << " " << trackFraction
// << endl;
// Pout<< "# Tracking loop tet "
// << origId_ << " " << origProc_<< nl
// << "# face: " << tetFaceI_ << nl
// << "# tetPtI: " << tetPtI_ << nl
// << "# tetBasePtI: " << mesh.tetBasePtIs()[tetFaceI_] << nl
// << "# tet.mag(): " << tet.mag() << nl
// << "# tet.quality(): " << tet.quality()
// << endl;
// meshTools::writeOBJ(Pout, tet.a());
// meshTools::writeOBJ(Pout, tet.b());
// meshTools::writeOBJ(Pout, tet.c());
// meshTools::writeOBJ(Pout, tet.d());
// Pout<< "f 1 3 2" << nl
// << "f 2 3 4" << nl
// << "f 1 4 3" << nl
// << "f 1 2 4" << endl;
// The particle can be 'outside' the tet. This will yield a
// lambda larger than 1, or smaller than 0. For values < 0,
// the particle travels away from the tet and we don't move
@ -773,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
if (!cpp.parallel())
if (!receiveCpp.parallel())
{
const tensor& T = cpp.reverseT()[0];
const tensor& T =
(
receiveCpp.forwardT().size() == 1
? receiveCpp.forwardT()[0]
: receiveCpp.forwardT()[receiveCpp.whichFace(faceI_)]
);
transformPosition(T);
static_cast<ParticleType&>(*this).transformProperties(T);
}
else if (cpp.separated())
else if (receiveCpp.separated())
{
position_ += cpp.separation()[0];
const vector& s =
(
(receiveCpp.separation().size() == 1)
? receiveCpp.separation()[0]
: receiveCpp.separation()[receiveCpp.whichFace(faceI_)]
);
position_ -= s;
static_cast<ParticleType&>(*this).transformProperties
(
cpp.separation()[0]
-s
);
}
}

View File

@ -343,9 +343,6 @@ inline void Foam::Particle<ParticleType>::tetNeighbour(label triI)
label tetBasePtI = mesh.tetBasePtIs()[tetFaceI_];
label facePtI = (tetPtI_ + tetBasePtI) % f.size();
label otherFacePtI = f.fcIndex(facePtI);
if (tetBasePtI == -1)
{
FatalErrorIn
@ -357,6 +354,9 @@ inline void Foam::Particle<ParticleType>::tetNeighbour(label triI)
<< abort(FatalError);
}
label facePtI = (tetPtI_ + tetBasePtI) % f.size();
label otherFacePtI = f.fcIndex(facePtI);
switch (triI)
{
case 0:

View File

@ -8,8 +8,8 @@ EXE_INC = \
-I$(LIB_SRC)/thermophysicalModels/basic/lnInclude \
-I$(LIB_SRC)/thermophysicalModels/liquids/lnInclude \
-I$(LIB_SRC)/thermophysicalModels/liquidMixture/lnInclude \
-I$(LIB_SRC)/thermophysicalModels/solids/lnInclude \
-I$(LIB_SRC)/thermophysicalModels/solidMixture/lnInclude \
-I$(LIB_SRC)/thermophysicalModels/pointSolids/lnInclude \
-I$(LIB_SRC)/thermophysicalModels/pointSolidMixture/lnInclude \
-I$(LIB_SRC)/thermophysicalModels/reactionThermo/lnInclude \
-I$(LIB_SRC)/thermophysicalModels/SLGThermo/lnInclude \
-I$(LIB_SRC)/thermophysicalModels/radiation/lnInclude \
@ -30,8 +30,8 @@ LIB_LIBS = \
-lbasicThermophysicalModels \
-lliquids \
-lliquidMixture \
-lsolids \
-lsolidMixture \
-lpointSolids \
-lpointSolidMixture \
-lreactionThermophysicalModels \
-lSLGThermo \
-lcompressibleRASModels \

View File

@ -28,7 +28,7 @@ License
#include "breakupModel.H"
#include "collisionModel.H"
#include "dispersionModel.H"
#include "interpolationCellPoint.H"
#include "interpolation.H"
#include "processorPolyPatch.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View File

@ -7,8 +7,8 @@ EXE_INC = \
-I$(LIB_SRC)/thermophysicalModels/basic/lnInclude \
-I$(LIB_SRC)/thermophysicalModels/liquids/lnInclude \
-I$(LIB_SRC)/thermophysicalModels/liquidMixture/lnInclude \
-I$(LIB_SRC)/thermophysicalModels/solids/lnInclude \
-I$(LIB_SRC)/thermophysicalModels/solidMixture/lnInclude \
-I$(LIB_SRC)/thermophysicalModels/pointSolids/lnInclude \
-I$(LIB_SRC)/thermophysicalModels/pointSolidMixture/lnInclude \
-I$(LIB_SRC)/thermophysicalModels/reactionThermo/lnInclude \
-I$(LIB_SRC)/thermophysicalModels/SLGThermo/lnInclude \
-I$(LIB_SRC)/thermophysicalModels/radiation/lnInclude \
@ -27,8 +27,8 @@ LIB_LIBS = \
-lpdf \
-lliquids \
-lliquidMixture \
-lsolids \
-lsolidMixture \
-lpointSolids \
-lpointSolidMixture \
-lspecie \
-lbasicThermophysicalModels \
-lreactionThermophysicalModels \

View File

@ -24,7 +24,6 @@ License
\*---------------------------------------------------------------------------*/
#include "ThermoCloud.H"
#include "interpolationCellPoint.H"
#include "ThermoParcel.H"
#include "HeatTransferModel.H"

View File

@ -48,7 +48,7 @@ SourceFiles
#include "Particle.H"
#include "IOstream.H"
#include "autoPtr.H"
#include "interpolationCellPoint.H"
#include "interpolation.H"
#include "contiguous.H"
#include "KinematicCloud.H"

View File

@ -38,7 +38,24 @@ Foam::label Foam::PatchInjection<CloudType>::parcelsToInject
{
if ((time0 >= 0.0) && (time0 < duration_))
{
return round(fraction_*(time1 - time0)*parcelsPerSecond_);
scalar nParcels =fraction_*(time1 - time0)*parcelsPerSecond_;
cachedRandom& rnd = this->owner().rndGen();
label nParcelsToInject = floor(nParcels);
// Inject an additional parcel with a probability based on the
// remainder after the floor function
if
(
nParcelsToInject > 0
&& (nParcels - scalar(nParcelsToInject) > rnd.position(0.0, 1.0))
)
{
++nParcelsToInject;
}
return nParcelsToInject;
}
else
{
@ -173,6 +190,7 @@ void Foam::PatchInjection<CloudType>::setPositionAndCell
if (cellOwners_.size() > 0)
{
cachedRandom& rnd = this->owner().rndGen();
label cellI = rnd.position<label>(0, cellOwners_.size() - 1);
cellOwner = cellOwners_[cellI];

View File

@ -100,7 +100,7 @@ const Foam::liquidMixture& Foam::CompositionModel<CloudType>::liquids() const
template<class CloudType>
const Foam::solidMixture& Foam::CompositionModel<CloudType>::solids() const
const Foam::pointSolidMixture& Foam::CompositionModel<CloudType>::solids() const
{
return thermo_.solids();
}

View File

@ -143,7 +143,7 @@ public:
const liquidMixture& liquids() const;
//- Return the global (additional) solids
const solidMixture& solids() const;
const pointSolidMixture& solids() const;
//- Return the list of phase properties
const phasePropertiesList& phaseProps() const;

View File

@ -32,11 +32,11 @@ bool Foam::blockMesh::blockMesh::verboseOutput(false);
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::blockMesh::blockMesh(IOdictionary& dict)
Foam::blockMesh::blockMesh(const IOdictionary& dict, const word& regionName)
:
blockPointField_(dict.lookup("vertices")),
scaleFactor_(1.0),
topologyPtr_(createTopology(dict))
topologyPtr_(createTopology(dict, regionName))
{
calcMergeInfo();
}

View File

@ -128,7 +128,7 @@ class blockMesh
void createCellShapes(cellShapeList& tmpBlockCells);
polyMesh* createTopology(IOdictionary&);
polyMesh* createTopology(const IOdictionary&, const word& regionName);
void checkBlockMesh(const polyMesh&) const;
//- Determine the merge info and the final number of cells/points
@ -149,7 +149,7 @@ public:
// Constructors
//- Construct from IOdictionary
blockMesh(IOdictionary&);
blockMesh(const IOdictionary&, const word& regionName);
//- Destructor

View File

@ -261,7 +261,11 @@ void Foam::blockMesh::createCellShapes
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
Foam::polyMesh* Foam::blockMesh::createTopology(IOdictionary& meshDescription)
Foam::polyMesh* Foam::blockMesh::createTopology
(
const IOdictionary& meshDescription,
const word& regionName
)
{
bool topologyOK = true;
@ -500,7 +504,22 @@ Foam::polyMesh* Foam::blockMesh::createTopology(IOdictionary& meshDescription)
dictionary& dict = patchDicts[patchI];
// Add but not override type
dict.add("type", patchTypes[patchI], false);
if (!dict.found("type"))
{
dict.add("type", patchTypes[patchI], false);
}
else if (word(dict.lookup("type")) != patchTypes[patchI])
{
IOWarningIn
(
"blockMesh::createTopology(IOdictionary&)",
meshDescription
) << "For patch " << patchNames[patchI]
<< " overriding type '" << patchTypes[patchI]
<< "' with '" << word(dict.lookup("type"))
<< "' (read from boundary file)"
<< endl;
}
// Override neighbourpatch name
if (nbrPatchNames[patchI] != word::null)
@ -514,7 +533,7 @@ Foam::polyMesh* Foam::blockMesh::createTopology(IOdictionary& meshDescription)
(
IOobject
(
"blockMesh",
regionName,
meshDescription.time().constant(),
meshDescription.time(),
IOobject::NO_READ,
@ -563,7 +582,7 @@ Foam::polyMesh* Foam::blockMesh::createTopology(IOdictionary& meshDescription)
(
IOobject
(
"blockMesh",
regionName,
meshDescription.time().constant(),
meshDescription.time(),
IOobject::NO_READ,

View File

@ -473,7 +473,7 @@ void Foam::PointEdgeWave<Type>::handleProcPatches()
// Apply transform to received data for non-parallel planes
if (!procPatch.parallel())
{
transform(procPatch.reverseT(), patchInfo);
transform(procPatch.forwardT(), patchInfo);
}
updateFromPatchInfo

View File

@ -35,6 +35,7 @@ License
#include "polyMesh.H"
#include "polyPatch.H"
#include "Time.H"
#include "mapDistribute.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -54,32 +55,16 @@ namespace Foam
directMappedPatchBase::sampleModeNames_;
//- Private class for finding nearest
// - point+local index
// - sqr(distance)
// - processor
typedef Tuple2<pointIndexHit, Tuple2<scalar, label> > nearInfo;
class nearestEqOp
template<>
const char* NamedEnum<directMappedPatchBase::offsetMode, 3>::names[] =
{
public:
void operator()(nearInfo& x, const nearInfo& y) const
{
if (y.first().hit())
{
if (!x.first().hit())
{
x = y;
}
else if (y.second().first() < x.second().first())
{
x = y;
}
}
}
"uniform",
"nonuniform",
"normal"
};
const NamedEnum<directMappedPatchBase::offsetMode, 3>
directMappedPatchBase::offsetModeNames_;
}
@ -100,7 +85,7 @@ void Foam::directMappedPatchBase::collectSamples
labelListList globalFaces(Pstream::nProcs());
globalFc[Pstream::myProcNo()] = patch_.faceCentres();
globalSamples[Pstream::myProcNo()] = globalFc[Pstream::myProcNo()]+offsets_;
globalSamples[Pstream::myProcNo()] = samplePoints();
globalFaces[Pstream::myProcNo()] = identity(patch_.size());
// Distribute to all processors
@ -393,19 +378,34 @@ void Foam::directMappedPatchBase::calcMapping() const
<< "Mapping already calculated" << exit(FatalError);
}
if
// Do a sanity check
// Am I sampling my own patch? This only makes sense for a non-zero
// offset.
bool sampleMyself =
(
gAverage(mag(offsets_)) <= ROOTVSMALL
&& mode_ == NEARESTPATCHFACE
mode_ == NEARESTPATCHFACE
&& sampleRegion_ == patch_.boundaryMesh().mesh().name()
&& samplePatch_ == patch_.name()
)
);
// Check offset
vectorField d(samplePoints()-patch_.faceCentres());
if (sampleMyself && gAverage(mag(d)) <= ROOTVSMALL)
{
WarningIn("directMappedPatchBase::calcMapping() const")
<< "Invalid offset " << offsets_ << endl
WarningIn
(
"directMappedPatchBase::directMappedPatchBase\n"
"(\n"
" const polyPatch& pp,\n"
" const word& sampleRegion,\n"
" const sampleMode mode,\n"
" const word& samplePatch,\n"
" const vector& offset\n"
")\n"
) << "Invalid offset " << d << endl
<< "Offset is the vector added to the patch face centres to"
<< " find the patch face supplying the data." << endl
<< "Setting it to " << offsets_
<< "Setting it to " << d
<< " on the same patch, on the same region"
<< " will find the faces themselves which does not make sense"
<< " for anything but testing." << endl
@ -413,10 +413,11 @@ void Foam::directMappedPatchBase::calcMapping() const
<< "sampleRegion_:" << sampleRegion_ << endl
<< "mode_:" << sampleModeNames_[mode_] << endl
<< "samplePatch_:" << samplePatch_ << endl
<< "offsets_:" << offsets_ << endl;
<< "offsetMode_:" << offsetModeNames_[offsetMode_] << endl;
}
// Get global list of all samples and the processor and face they come from.
pointField samples;
labelList patchFaceProcs;
@ -477,40 +478,6 @@ void Foam::directMappedPatchBase::calcMapping() const
}
//// Check that actual offset vector (sampleLocations - patchFc) is more or
//// less constant.
//if (Pstream::master())
//{
// const scalarField magOffset(mag(sampleLocations - patchFc));
// const scalar avgOffset(average(magOffset));
//
// forAll(magOffset, sampleI)
// {
// if
// (
// mag(magOffset[sampleI]-avgOffset)
// > max(SMALL, 0.001*avgOffset)
// )
// {
// WarningIn("directMappedPatchBase::calcMapping() const")
// << "The actual cell/face centres picked up using offset "
// << offsets_ << " are not" << endl
// << " on a single plane."
// << " This might give numerical problems." << endl
// << " At patchface " << patchFc[sampleI]
// << " the sampled cell/face " << sampleLocations[sampleI]
// << endl
// << " is not on a plane " << avgOffset
// << " offset from the patch." << endl
// << " You might want to shift your plane offset."
// << " Set the debug flag to get a dump of sampled cells."
// << endl;
// break;
// }
// }
//}
// Determine schedule.
mapPtr_.reset(new mapDistribute(sampleProcs, patchFaceProcs));
@ -533,13 +500,14 @@ void Foam::directMappedPatchBase::calcMapping() const
constructMap[procI]
);
if (debug)
{
Pout<< "To proc:" << procI << " sending values of cells/faces:"
<< subMap[procI] << endl;
Pout<< "From proc:" << procI << " receiving values of patch faces:"
<< constructMap[procI] << endl;
}
//if (debug)
//{
// Pout<< "To proc:" << procI << " sending values of cells/faces:"
// << subMap[procI] << endl;
// Pout<< "From proc:" << procI
// << " receiving values of patch faces:"
// << constructMap[procI] << endl;
//}
}
// Redo constructSize
@ -597,9 +565,10 @@ Foam::directMappedPatchBase::directMappedPatchBase
sampleRegion_(patch_.boundaryMesh().mesh().name()),
mode_(NEARESTPATCHFACE),
samplePatch_("none"),
uniformOffset_(true),
offsetMode_(UNIFORM),
offset_(vector::zero),
offsets_(pp.size(), offset_),
distance_(0),
sameRegion_(sampleRegion_ == patch_.boundaryMesh().mesh().name()),
mapPtr_(NULL)
{}
@ -618,8 +587,10 @@ Foam::directMappedPatchBase::directMappedPatchBase
sampleRegion_(sampleRegion),
mode_(mode),
samplePatch_(samplePatch),
uniformOffset_(false),
offsetMode_(NONUNIFORM),
offset_(vector::zero),
offsets_(offsets),
distance_(0),
sameRegion_(sampleRegion_ == patch_.boundaryMesh().mesh().name()),
mapPtr_(NULL)
{}
@ -638,9 +609,32 @@ Foam::directMappedPatchBase::directMappedPatchBase
sampleRegion_(sampleRegion),
mode_(mode),
samplePatch_(samplePatch),
uniformOffset_(true),
offsetMode_(UNIFORM),
offset_(offset),
offsets_(pp.size(), offset_),
offsets_(0),
distance_(0),
sameRegion_(sampleRegion_ == patch_.boundaryMesh().mesh().name()),
mapPtr_(NULL)
{}
Foam::directMappedPatchBase::directMappedPatchBase
(
const polyPatch& pp,
const word& sampleRegion,
const sampleMode mode,
const word& samplePatch,
const scalar distance
)
:
patch_(pp),
sampleRegion_(sampleRegion),
mode_(mode),
samplePatch_(samplePatch),
offsetMode_(NORMAL),
offset_(vector::zero),
offsets_(0),
distance_(distance),
sameRegion_(sampleRegion_ == patch_.boundaryMesh().mesh().name()),
mapPtr_(NULL)
{}
@ -663,22 +657,62 @@ Foam::directMappedPatchBase::directMappedPatchBase
),
mode_(sampleModeNames_.read(dict.lookup("sampleMode"))),
samplePatch_(dict.lookup("samplePatch")),
uniformOffset_(dict.found("offset")),
offset_
(
uniformOffset_
? point(dict.lookup("offset"))
: vector::zero
),
offsets_
(
uniformOffset_
? pointField(pp.size(), offset_)
: dict.lookup("offsets")
),
offsetMode_(UNIFORM),
offset_(vector::zero),
offsets_(0),
distance_(0.0),
sameRegion_(sampleRegion_ == patch_.boundaryMesh().mesh().name()),
mapPtr_(NULL)
{}
{
if (dict.found("offsetMode"))
{
offsetMode_ = offsetModeNames_.read(dict.lookup("offsetMode"));
switch(offsetMode_)
{
case UNIFORM:
{
offset_ = point(dict.lookup("offset"));
}
break;
case NONUNIFORM:
{
offsets_ = pointField(dict.lookup("offsets"));
}
break;
case NORMAL:
{
distance_ = readScalar(dict.lookup("distance"));
}
break;
}
}
else if (dict.found("offset"))
{
offsetMode_ = UNIFORM;
offset_ = point(dict.lookup("offset"));
}
else if (dict.found("offsets"))
{
offsetMode_ = NONUNIFORM;
offsets_ = pointField(dict.lookup("offsets"));
}
else
{
FatalErrorIn
(
"directMappedPatchBase::directMappedPatchBase\n"
"(\n"
" const polyPatch& pp,\n"
" const dictionary& dict\n"
")\n"
) << "Please supply the offsetMode as one of "
<< NamedEnum<offsetMode, 3>::words()
<< exit(FatalError);
}
}
Foam::directMappedPatchBase::directMappedPatchBase
@ -691,9 +725,10 @@ Foam::directMappedPatchBase::directMappedPatchBase
sampleRegion_(dmp.sampleRegion_),
mode_(dmp.mode_),
samplePatch_(dmp.samplePatch_),
uniformOffset_(dmp.uniformOffset_),
offsetMode_(dmp.offsetMode_),
offset_(dmp.offset_),
offsets_(dmp.offsets_),
distance_(dmp.distance_),
sameRegion_(dmp.sameRegion_),
mapPtr_(NULL)
{}
@ -710,9 +745,10 @@ Foam::directMappedPatchBase::directMappedPatchBase
sampleRegion_(dmp.sampleRegion_),
mode_(dmp.mode_),
samplePatch_(dmp.samplePatch_),
uniformOffset_(dmp.uniformOffset_),
offsetMode_(dmp.offsetMode_),
offset_(dmp.offset_),
offsets_(dmp.offsets_, mapAddressing),
distance_(dmp.distance_),
sameRegion_(dmp.sameRegion_),
mapPtr_(NULL)
{}
@ -762,6 +798,40 @@ const Foam::polyPatch& Foam::directMappedPatchBase::samplePolyPatch() const
}
Foam::tmp<Foam::pointField> Foam::directMappedPatchBase::samplePoints() const
{
tmp<pointField> tfld(new pointField(patch_.faceCentres()));
pointField& fld = tfld();
switch(offsetMode_)
{
case UNIFORM:
{
fld += offset_;
}
break;
case NONUNIFORM:
{
fld += offsets_;
}
break;
case NORMAL:
{
// Get outwards pointing normal
vectorField n(patch_.faceAreas());
n /= mag(n);
fld += distance_*n;
}
break;
}
return tfld;
}
void Foam::directMappedPatchBase::write(Ostream& os) const
{
os.writeKeyword("sampleMode") << sampleModeNames_[mode_]
@ -770,13 +840,31 @@ void Foam::directMappedPatchBase::write(Ostream& os) const
<< token::END_STATEMENT << nl;
os.writeKeyword("samplePatch") << samplePatch_
<< token::END_STATEMENT << nl;
if (uniformOffset_)
os.writeKeyword("offsetMode") << offsetModeNames_[offsetMode_]
<< token::END_STATEMENT << nl;
switch(offsetMode_)
{
os.writeKeyword("offset") << offset_ << token::END_STATEMENT << nl;
}
else
{
os.writeKeyword("offsets") << offsets_ << token::END_STATEMENT << nl;
case UNIFORM:
{
os.writeKeyword("offset") << offset_ << token::END_STATEMENT << nl;
}
break;
case NONUNIFORM:
{
os.writeKeyword("offsets") << offsets_ << token::END_STATEMENT
<< nl;
}
break;
case NORMAL:
{
os.writeKeyword("distance") << distance_ << token::END_STATEMENT
<< nl;
}
break;
}
}

View File

@ -28,6 +28,33 @@ Description
Determines a mapping between patch face centres and mesh cell or face
centres and processors they're on.
If constructed from dictionary:
// Region to sample (default is region0)
sampleRegion region0;
// What to sample:
// - nearestCell : sample nearest cell
// - nearestPatchFace : nearest face on selected patch
// - nearestFace : nearest boundary face on any patch
sampleMode nearestCell;
// If sampleMod is nearestPatchFace : patch to find faces of
samplePatch movingWall;
// How to supply offset (w.r.t. my patch face centres):
// - uniform : single offset vector
// - nonuniform : per-face offset vector
// - normal : using supplied distance and face normal
offsetMode uniform;
// According to offsetMode (see above) supply one of
// offset, offsets or distance
offset (1 0 0);
Note: if offsetMode is 'normal' it uses outwards pointing normals. So
supply a negative distance if sampling inside the domain.
Note
Storage is not optimal. It temporary collects all (patch)face centres
on all processors to keep the addressing calculation simple.
@ -43,8 +70,6 @@ SourceFiles
#include "pointField.H"
#include "Tuple2.H"
#include "pointIndexHit.H"
#include "mapDistribute.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -53,6 +78,7 @@ namespace Foam
class polyPatch;
class polyMesh;
class mapDistribute;
/*---------------------------------------------------------------------------*\
Class directMappedPatchBase Declaration
@ -71,12 +97,50 @@ public:
NEARESTFACE // nearest face
};
//- How to project face centres
enum offsetMode
{
UNIFORM, // single offset vector
NONUNIFORM, // per-face offset vector
NORMAL // use face normal + distance
};
//- Helper class for finding nearest
// - point+local index
// - sqr(distance)
// - processor
typedef Tuple2<pointIndexHit, Tuple2<scalar, label> > nearInfo;
class nearestEqOp
{
public:
void operator()(nearInfo& x, const nearInfo& y) const
{
if (y.first().hit())
{
if (!x.first().hit())
{
x = y;
}
else if (y.second().first() < x.second().first())
{
x = y;
}
}
}
};
private:
// Private data
static const NamedEnum<sampleMode, 3> sampleModeNames_;
static const NamedEnum<offsetMode, 3> offsetModeNames_;
//- Patch to sample
const polyPatch& patch_;
@ -89,14 +153,17 @@ private:
//- Patch (only if NEARESTPATCHFACE)
const word samplePatch_;
//- For backwards compatibility : reading/writing of uniform offset.
const bool uniformOffset_;
//- How to obtain samples
offsetMode offsetMode_;
//- Offset vector (uniform)
const vector offset_;
vector offset_;
//- Offset vector
const vectorField offsets_;
//- Offset vector (nonuniform)
vectorField offsets_;
//- Offset distance (normal)
scalar distance_;
//- Same region
const bool sameRegion_;
@ -146,17 +213,17 @@ public:
//- Construct from patch
directMappedPatchBase(const polyPatch&);
//- Construct from components
//- Construct with offsetMode=non-uniform
directMappedPatchBase
(
const polyPatch& pp,
const word& sampleRegion,
const sampleMode sampleMode,
const word& samplePatch,
const vectorField& offset
const vectorField& offsets
);
//- Construct from components
//- Construct from offsetMode=uniform
directMappedPatchBase
(
const polyPatch& pp,
@ -166,6 +233,16 @@ public:
const vector& offset
);
//- Construct from offsetMode=normal and distance
directMappedPatchBase
(
const polyPatch& pp,
const word& sampleRegion,
const sampleMode sampleMode,
const word& samplePatch,
const scalar distance
);
//- Construct from dictionary
directMappedPatchBase(const polyPatch&, const dictionary&);
@ -241,6 +318,9 @@ public:
//- Get the patch on the region
const polyPatch& samplePolyPatch() const;
//- Get the sample points
tmp<pointField> samplePoints() const;
//- Write as a dictionary
virtual void write(Ostream&) const;
};

View File

@ -0,0 +1,97 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 1991-2010 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/>.
Class
Foam::fieldDictionary
Description
Read field as dictionary (without mesh).
\*---------------------------------------------------------------------------*/
#ifndef fieldDictionary_H
#define fieldDictionary_H
#include "regIOobject.H"
#include "dictionary.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class fieldDictionary Declaration
\*---------------------------------------------------------------------------*/
class fieldDictionary
:
public regIOobject,
public dictionary
{
const word type_;
public:
// Redefine type name to be of the instantiated type
virtual const word& type() const
{
return type_;
}
// Constructors
//- Construct from ioobject and overloaded typename.
explicit fieldDictionary(const IOobject& io, const word& type)
:
regIOobject(io),
dictionary(readStream(type)),
type_(type)
{
close();
}
// Member functions
bool writeData(Ostream& os) const
{
static_cast<const dictionary&>(*this).write(os, false);
return os.good();
}
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -28,6 +28,7 @@ License
#include "cellSet.H"
#include "Time.H"
#include "IFstream.H"
#include "fieldDictionary.H"
#include "addToRunTimeSelectionTable.H"
@ -207,7 +208,7 @@ void Foam::fieldToCell::applyToSet
IFstream str(fieldObject.filePath());
// Read dictionary
dictionary fieldDict(str);
fieldDictionary fieldDict(fieldObject, fieldObject.headerClassName());
scalarField internalVals("internalField", fieldDict, mesh().nCells());
@ -218,7 +219,7 @@ void Foam::fieldToCell::applyToSet
IFstream str(fieldObject.filePath());
// Read dictionary
dictionary fieldDict(str);
fieldDictionary fieldDict(fieldObject, fieldObject.headerClassName());
vectorField internalVals("internalField", fieldDict, mesh().nCells());

View File

@ -108,6 +108,7 @@ License
#include "addToRunTimeSelectionTable.H"
#include "Time.H"
#include "OFstream.H"
#include "globalIndex.H"
extern "C"
{
@ -157,16 +158,204 @@ void Foam::ptscotchDecomp::check(const int retVal, const char* str)
}
//- Does prevention of 0 cell domains and calls ptscotch.
Foam::label Foam::ptscotchDecomp::decomposeZeroDomains
(
const List<int>& initadjncy,
const List<int>& initxadj,
const scalarField& initcWeights,
List<int>& finalDecomp
) const
{
globalIndex globalCells(initxadj.size()-1);
bool hasZeroDomain = false;
for (label procI = 0; procI < Pstream::nProcs(); procI++)
{
if (globalCells.localSize(procI) == 0)
{
hasZeroDomain = true;
break;
}
}
if (!hasZeroDomain)
{
return decompose
(
initadjncy,
initxadj,
initcWeights,
finalDecomp
);
}
if (debug)
{
Info<< "ptscotchDecomp : have graphs with locally 0 cells."
<< " trickling down." << endl;
}
// Make sure every domain has at least one cell
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// (scotch does not like zero sized domains)
// Trickle cells from processors that have them up to those that
// don't.
// Number of cells to send to the next processor
// (is same as number of cells next processor has to receive)
List<int> nSendCells(Pstream::nProcs(), 0);
for (label procI = nSendCells.size()-1; procI >=1; procI--)
{
label nLocalCells = globalCells.localSize(procI);
if (nLocalCells-nSendCells[procI] < 1)
{
nSendCells[procI-1] = nSendCells[procI]-nLocalCells+1;
}
}
// First receive (so increasing the sizes of all arrays)
Field<int> xadj(initxadj);
Field<int> adjncy(initadjncy);
scalarField cWeights(initcWeights);
if (Pstream::myProcNo() >= 1 && nSendCells[Pstream::myProcNo()-1] > 0)
{
// Receive cells from previous processor
IPstream fromPrevProc(Pstream::blocking, Pstream::myProcNo()-1);
Field<int> prevXadj(fromPrevProc);
Field<int> prevAdjncy(fromPrevProc);
scalarField prevCellWeights(fromPrevProc);
if (prevXadj.size() != nSendCells[Pstream::myProcNo()-1])
{
FatalErrorIn("ptscotchDecomp::decompose(..)")
<< "Expected from processor " << Pstream::myProcNo()-1
<< " connectivity for " << nSendCells[Pstream::myProcNo()-1]
<< " nCells but only received " << prevXadj.size()
<< abort(FatalError);
}
// Insert adjncy
prepend(prevAdjncy, adjncy);
// Adapt offsets and prepend xadj
xadj += prevAdjncy.size();
prepend(prevXadj, xadj);
// Weights
prepend(prevCellWeights, cWeights);
}
// Send to my next processor
if (nSendCells[Pstream::myProcNo()] > 0)
{
// Send cells to next processor
OPstream toNextProc(Pstream::blocking, Pstream::myProcNo()+1);
int nCells = nSendCells[Pstream::myProcNo()];
int startCell = xadj.size()-1 - nCells;
int startFace = xadj[startCell];
int nFaces = adjncy.size()-startFace;
// Send for all cell data: last nCells elements
// Send for all face data: last nFaces elements
toNextProc
<< Field<int>::subField(xadj, nCells, startCell)-startFace
<< Field<int>::subField(adjncy, nFaces, startFace)
<<
(
cWeights.size()
? scalarField::subField(cWeights, nCells, startCell)
: scalarField(0)
);
// Remove data that has been sent
if (cWeights.size())
{
cWeights.setSize(cWeights.size()-nCells);
}
adjncy.setSize(adjncy.size()-nFaces);
xadj.setSize(xadj.size() - nCells);
}
// Do decomposition as normal. Sets finalDecomp.
label result = decompose(adjncy, xadj, cWeights, finalDecomp);
if (debug)
{
Info<< "ptscotchDecomp : have graphs with locally 0 cells."
<< " trickling up." << endl;
}
// If we sent cells across make sure we undo it
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Receive back from next processor if I sent something
if (nSendCells[Pstream::myProcNo()] > 0)
{
IPstream fromNextProc(Pstream::blocking, Pstream::myProcNo()+1);
List<int> nextFinalDecomp(fromNextProc);
if (nextFinalDecomp.size() != nSendCells[Pstream::myProcNo()])
{
FatalErrorIn("parMetisDecomp::decompose(..)")
<< "Expected from processor " << Pstream::myProcNo()+1
<< " decomposition for " << nSendCells[Pstream::myProcNo()]
<< " nCells but only received " << nextFinalDecomp.size()
<< abort(FatalError);
}
append(nextFinalDecomp, finalDecomp);
}
// Send back to previous processor.
if (Pstream::myProcNo() >= 1 && nSendCells[Pstream::myProcNo()-1] > 0)
{
OPstream toPrevProc(Pstream::blocking, Pstream::myProcNo()-1);
int nToPrevious = nSendCells[Pstream::myProcNo()-1];
toPrevProc <<
SubList<int>
(
finalDecomp,
nToPrevious,
finalDecomp.size()-nToPrevious
);
// Remove locally what has been sent
finalDecomp.setSize(finalDecomp.size()-nToPrevious);
}
return result;
}
// Call scotch with options from dictionary.
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
{
if (debug)
{
Pout<< "ptscotchDecomp : entering with xadj:" << xadj.size() << endl;
}
// // Dump graph
// if (decompositionDict_.found("ptscotchCoeffs"))
// {
@ -262,8 +451,7 @@ Foam::label Foam::ptscotchDecomp::decompose
{
WarningIn
(
"ptscotchDecomp::decompose"
"(const pointField&, const scalarField&)"
"ptscotchDecomp::decompose(..)"
) << "Illegal minimum weight " << minWeights
<< endl;
}
@ -272,8 +460,7 @@ Foam::label Foam::ptscotchDecomp::decompose
{
FatalErrorIn
(
"ptscotchDecomp::decompose"
"(const pointField&, const scalarField&)"
"ptscotchDecomp::decompose(..)"
) << "Number of cell weights " << cWeights.size()
<< " does not equal number of cells " << xadj.size()-1
<< exit(FatalError);
@ -289,8 +476,25 @@ Foam::label Foam::ptscotchDecomp::decompose
if (debug)
{
Pout<< "SCOTCH_dgraphInit" << endl;
}
SCOTCH_Dgraph grafdat;
check(SCOTCH_dgraphInit(&grafdat, MPI_COMM_WORLD), "SCOTCH_dgraphInit");
if (debug)
{
Pout<< "SCOTCH_dgraphBuild with:" << nl
<< "xadj.size() : " << xadj.size()-1 << nl
<< "xadj : " << long(xadj.begin()) << nl
<< "velotab : " << long(velotab.begin()) << nl
<< "adjncy.size() : " << adjncy.size() << nl
<< "adjncy : " << long(adjncy.begin()) << nl
<< endl;
}
check
(
SCOTCH_dgraphBuild
@ -302,19 +506,25 @@ Foam::label Foam::ptscotchDecomp::decompose
const_cast<SCOTCH_Num*>(xadj.begin()),
// vertloctab, start index per cell into
// adjncy
&xadj[1], // vendloctab, end index ,,
const_cast<SCOTCH_Num*>(&xadj[1]),// vendloctab, end index ,,
velotab.begin(), // veloloctab, vertex weights
const_cast<SCOTCH_Num*>(velotab.begin()),// veloloctab, vtx weights
NULL, // vlblloctab
adjncy.size(), // edgelocnbr, number of arcs
adjncy.size(), // edgelocsiz
adjncy.begin(), // edgeloctab
const_cast<SCOTCH_Num*>(adjncy.begin()), // edgeloctab
NULL, // edgegsttab
NULL // edlotab, edge weights
),
"SCOTCH_dgraphBuild"
);
if (debug)
{
Pout<< "SCOTCH_dgraphCheck" << endl;
}
check(SCOTCH_dgraphCheck(&grafdat), "SCOTCH_dgraphCheck");
@ -322,6 +532,10 @@ Foam::label Foam::ptscotchDecomp::decompose
// ~~~~~~~~~~~~
// (fully connected network topology since using switch)
if (debug)
{
Pout<< "SCOTCH_archInit" << endl;
}
SCOTCH_Arch archdat;
check(SCOTCH_archInit(&archdat), "SCOTCH_archInit");
@ -349,6 +563,10 @@ Foam::label Foam::ptscotchDecomp::decompose
}
else
{
if (debug)
{
Pout<< "SCOTCH_archCmplt" << endl;
}
check
(
SCOTCH_archCmplt(&archdat, nProcessors_),
@ -373,6 +591,10 @@ Foam::label Foam::ptscotchDecomp::decompose
);
# endif
if (debug)
{
Pout<< "SCOTCH_dgraphMap" << endl;
}
finalDecomp.setSize(xadj.size()-1);
finalDecomp = 0;
check
@ -406,6 +628,10 @@ Foam::label Foam::ptscotchDecomp::decompose
// "SCOTCH_graphPart"
//);
if (debug)
{
Pout<< "SCOTCH_dgraphExit" << endl;
}
// Release storage for graph
SCOTCH_dgraphExit(&grafdat);
// Release storage for strategy
@ -465,7 +691,13 @@ Foam::labelList Foam::ptscotchDecomp::decompose
// Decompose using default weights
List<int> finalDecomp;
decompose(cellCells.m(), cellCells.offsets(), pointWeights, finalDecomp);
decomposeZeroDomains
(
cellCells.m(),
cellCells.offsets(),
pointWeights,
finalDecomp
);
// Copy back to labelList
labelList decomp(finalDecomp.size());
@ -510,7 +742,13 @@ Foam::labelList Foam::ptscotchDecomp::decompose
// Decompose using weights
List<int> finalDecomp;
decompose(cellCells.m(), cellCells.offsets(), pointWeights, finalDecomp);
decomposeZeroDomains
(
cellCells.m(),
cellCells.offsets(),
pointWeights,
finalDecomp
);
// Rework back into decomposition for original mesh
labelList fineDistribution(agglom.size());
@ -557,7 +795,13 @@ Foam::labelList Foam::ptscotchDecomp::decompose
// Decompose using weights
List<int> finalDecomp;
decompose(cellCells.m(), cellCells.offsets(), cWeights, finalDecomp);
decomposeZeroDomains
(
cellCells.m(),
cellCells.offsets(),
cWeights,
finalDecomp
);
// Copy back to labelList
labelList decomp(finalDecomp.size());

View File

@ -50,16 +50,33 @@ class ptscotchDecomp
{
// Private Member Functions
//- Insert list in front of list.
template<class Type>
static void prepend(const UList<Type>&, List<Type>&);
//- Insert list at end of list.
template<class Type>
static void append(const UList<Type>&, List<Type>&);
//- Check and print error message
static void check(const int, const char*);
//- Decompose with optionally zero sized domains
label decomposeZeroDomains
(
const List<int>& initadjncy,
const List<int>& initxadj,
const scalarField& initcWeights,
List<int>& finalDecomp
) const;
//- Decompose
label decompose
(
List<int>& adjncy,
List<int>& xadj,
const List<int>& adjncy,
const List<int>& xadj,
const scalarField& cWeights,
List<int>& finalDecomp
);
) const;
//- Disallow default bitwise copy construct and assignment
void operator=(const ptscotchDecomp&);
@ -135,6 +152,12 @@ public:
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository
# include "ptscotchDecompTemplates.C"
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,76 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2010-2010 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 "ptscotchDecomp.H"
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
// Insert at front of list
template<class Type>
void Foam::ptscotchDecomp::prepend
(
const UList<Type>& extraLst,
List<Type>& lst
)
{
label nExtra = extraLst.size();
// Make space for initial elements
lst.setSize(lst.size() + nExtra);
for (label i = lst.size()-1; i >= nExtra; i--)
{
lst[i] = lst[i-nExtra];
}
// Insert at front
forAll(extraLst, i)
{
lst[i] = extraLst[i];
}
}
// Insert at back of list
template<class Type>
void Foam::ptscotchDecomp::append
(
const UList<Type>& extraLst,
List<Type>& lst
)
{
label sz = lst.size();
// Make space for initial elements
lst.setSize(sz + extraLst.size());
// Insert at back
forAll(extraLst, i)
{
lst[sz++] = extraLst[i];
}
}
// ************************************************************************* //

View File

@ -440,15 +440,7 @@ void Foam::distributedTriSurfaceMesh::findLine
// Exchange the segments
// ~~~~~~~~~~~~~~~~~~~~~
map.distribute
(
Pstream::nonBlocking, //Pstream::scheduled,
List<labelPair>(0), //map.schedule(),
map.constructSize(),
map.subMap(), // what to send
map.constructMap(), // what to receive
allSegments
);
map.distribute(allSegments);
// Do tests I need to do
@ -490,21 +482,7 @@ void Foam::distributedTriSurfaceMesh::findLine
// Exchange the intersections (opposite to segments)
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
map.distribute
(
//Pstream::scheduled,
//map.schedule // Note reverse schedule
//(
// map.constructMap(),
// map.subMap()
//),
Pstream::nonBlocking,
List<labelPair>(0),
nOldAllSegments,
map.constructMap(), // what to send
map.subMap(), // what to receive
intersections
);
map.reverseDistribute(nOldAllSegments, intersections);
// Extract the hits
@ -657,17 +635,7 @@ Foam::distributedTriSurfaceMesh::calcLocalQueries
// Send over queries
// ~~~~~~~~~~~~~~~~~
map.distribute
(
//Pstream::scheduled,
//map.schedule(),
Pstream::nonBlocking,
List<labelPair>(0),
map.constructSize(),
map.subMap(), // what to send
map.constructMap(), // what to receive
triangleIndex
);
map.distribute(triangleIndex);
return mapPtr;
@ -1594,28 +1562,8 @@ void Foam::distributedTriSurfaceMesh::findNearest
// swap samples to local processor
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
map.distribute
(
//Pstream::scheduled,
//map.schedule(),
Pstream::nonBlocking,
List<labelPair>(0),
map.constructSize(),
map.subMap(), // what to send
map.constructMap(), // what to receive
allCentres
);
map.distribute
(
//Pstream::scheduled,
//map.schedule(),
Pstream::nonBlocking,
List<labelPair>(0),
map.constructSize(),
map.subMap(), // what to send
map.constructMap(), // what to receive
allRadiusSqr
);
map.distribute(allCentres);
map.distribute(allRadiusSqr);
// Do my tests
@ -1639,21 +1587,7 @@ void Foam::distributedTriSurfaceMesh::findNearest
// Send back results
// ~~~~~~~~~~~~~~~~~
map.distribute
(
//Pstream::scheduled,
//map.schedule // note reverse schedule
//(
// map.constructMap(),
// map.subMap()
//),
Pstream::nonBlocking,
List<labelPair>(0),
allSegmentMap.size(),
map.constructMap(), // what to send
map.subMap(), // what to receive
allInfo
);
map.reverseDistribute(allSegmentMap.size(), allInfo);
// Extract information
@ -1892,21 +1826,7 @@ void Foam::distributedTriSurfaceMesh::getRegion
// Send back results
// ~~~~~~~~~~~~~~~~~
map.distribute
(
//Pstream::scheduled,
//map.schedule // note reverse schedule
//(
// map.constructMap(),
// map.subMap()
//),
Pstream::nonBlocking,
List<labelPair>(0),
info.size(),
map.constructMap(), // what to send
map.subMap(), // what to receive
region
);
map.reverseDistribute(info.size(), region);
}
@ -1956,21 +1876,7 @@ void Foam::distributedTriSurfaceMesh::getNormal
// Send back results
// ~~~~~~~~~~~~~~~~~
map.distribute
(
//Pstream::scheduled,
//map.schedule // note reverse schedule
//(
// map.constructMap(),
// map.subMap()
//),
Pstream::nonBlocking,
List<labelPair>(0),
info.size(),
map.constructMap(), // what to send
map.subMap(), // what to receive
normal
);
map.reverseDistribute(info.size(), normal);
}
@ -2024,15 +1930,7 @@ void Foam::distributedTriSurfaceMesh::getField
// Send back results
// ~~~~~~~~~~~~~~~~~
map.distribute
(
Pstream::nonBlocking,
List<labelPair>(0),
info.size(),
map.constructMap(), // what to send
map.subMap(), // what to receive
values
);
map.reverseDistribute(info.size(), values);
}
}

View File

@ -76,15 +76,7 @@ License
// // Send back results
// // ~~~~~~~~~~~~~~~~~
//
// map.distribute
// (
// Pstream::nonBlocking,
// List<labelPair>(0),
// info.size(),
// map.constructMap(), // what to send
// map.subMap(), // what to receive
// values
// );
// map.reverseDistribute(info.size(), values);
//}
@ -115,15 +107,7 @@ void Foam::distributedTriSurfaceMesh::distributeFields
label oldSize = field.size();
map.distribute
(
Pstream::nonBlocking,
List<labelPair>(0),
map.constructSize(),
map.subMap(),
map.constructMap(),
field
);
map.distribute(field);
if (debug)
{

View File

@ -12,6 +12,9 @@ fieldValues/faceSource/faceSourceFunctionObject.C
fieldValues/cellSource/cellSource.C
fieldValues/cellSource/cellSourceFunctionObject.C
nearWallFields/nearWallFields.C
nearWallFields/nearWallFieldsFunctionObject.C
readFields/readFields.C
readFields/readFieldsFunctionObject.C

View File

@ -0,0 +1,49 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2010-2010 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/>.
Typedef
Foam::IOnearWallFields
Description
Instance of the generic IOOutputFilter for nearWallFields.
\*---------------------------------------------------------------------------*/
#ifndef IOnearWallFields_H
#define IOnearWallFields_H
#include "nearWallFields.H"
#include "IOOutputFilter.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
typedef IOOutputFilter<nearWallFields> IOnearWallFields;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,179 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2010-2010 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 "nearWallFields.H"
//#include "volFields.H"
//#include "selfContainedDirectMappedFixedValueFvPatchFields.H"
//#include "interpolationCellPoint.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
defineTypeNameAndDebug(nearWallFields, 0);
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::nearWallFields::nearWallFields
(
const word& name,
const objectRegistry& obr,
const dictionary& dict,
const bool loadFromFiles
)
:
name_(name),
obr_(obr),
active_(true),
fieldSet_()
{
// Check if the available mesh is an fvMesh otherise deactivate
if (!isA<fvMesh>(obr_))
{
active_ = false;
WarningIn
(
"nearWallFields::nearWallFields"
"("
"const word&, "
"const objectRegistry&, "
"const dictionary&, "
"const bool"
")"
) << "No fvMesh available, deactivating."
<< endl;
}
read(dict);
}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::nearWallFields::~nearWallFields()
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
void Foam::nearWallFields::read(const dictionary& dict)
{
if (active_)
{
const fvMesh& mesh = refCast<const fvMesh>(obr_);
dict.lookup("fields") >> fieldSet_;
patchSet_ =
mesh.boundaryMesh().patchSet(wordList(dict.lookup("patches")));
distance_ = readScalar(dict.lookup("distance"));
// Clear out any previously loaded fields
vsf_.clear();
vvf_.clear();
vSpheretf_.clear();
vSymmtf_.clear();
vtf_.clear();
fieldMap_.clear();
reverseFieldMap_.clear();
// Generate fields with selfContainedDirectMapped bc.
// Convert field to map
fieldMap_.resize(2*fieldSet_.size());
reverseFieldMap_.resize(2*fieldSet_.size());
forAll(fieldSet_, setI)
{
const word& fldName = fieldSet_[setI].first();
const word& sampleFldName = fieldSet_[setI].second();
fieldMap_.insert(fldName, sampleFldName);
reverseFieldMap_.insert(sampleFldName, fldName);
}
createFields(vsf_);
createFields(vvf_);
createFields(vSpheretf_);
createFields(vSymmtf_);
createFields(vtf_);
}
}
void Foam::nearWallFields::execute()
{
if (active_)
{
sampleFields(vsf_);
sampleFields(vvf_);
sampleFields(vSpheretf_);
sampleFields(vSymmtf_);
sampleFields(vtf_);
}
}
void Foam::nearWallFields::end()
{
// Do nothing
}
void Foam::nearWallFields::write()
{
// Do nothing
if (active_)
{
Info<< "Writing sampled fields to " << obr_.time().timeName()
<< endl;
forAll(vsf_, i)
{
vsf_[i].write();
}
forAll(vvf_, i)
{
vvf_[i].write();
}
forAll(vSpheretf_, i)
{
vSpheretf_[i].write();
}
forAll(vSymmtf_, i)
{
vSymmtf_[i].write();
}
forAll(vtf_, i)
{
vtf_[i].write();
}
}
}
// ************************************************************************* //

View File

@ -0,0 +1,206 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2010-2010 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/>.
Class
Foam::nearWallFields
Description
Samples near-patch volFields
Holds fields
- every timestep the field get updated with new values
- at write it writes the fields
so this functionObject can either be used to calculate a new field
as a postprocessing step or (since the fields are registered)
use these in another functionObject (e.g. faceSource).
surfaceValues
{
type nearWallFields;
..
enabled true;
outputControl outputTime;
..
// Name of volField and corresponding surfaceField
fields ((p pNear)(U UNear));
// Name of patch to sample
patches (movingWall);
// Distance away from the wall
distance 0.13; // distance away from wall
}
SourceFiles
nearWallFields.C
IOnearWallFields.H
\*---------------------------------------------------------------------------*/
#ifndef nearWallFields_H
#define nearWallFields_H
#include "OFstream.H"
#include "volFields.H"
#include "Tuple2.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// Forward declaration of classes
class objectRegistry;
class dictionary;
class mapPolyMesh;
/*---------------------------------------------------------------------------*\
Class nearWallFields Declaration
\*---------------------------------------------------------------------------*/
class nearWallFields
{
protected:
// Protected data
//- Name of this set of nearWallFields object
word name_;
const objectRegistry& obr_;
//- on/off switch
bool active_;
// Read from dictionary
//- Fields to process
List<Tuple2<word, word> > fieldSet_;
//- Patches to sample
labelHashSet patchSet_;
//- Distance away from wall
scalar distance_;
//- From original field to sampled result
HashTable<word> fieldMap_;
//- From resulting back to original field
HashTable<word> reverseFieldMap_;
//- Locally constructed fields
PtrList<volScalarField> vsf_;
PtrList<volVectorField> vvf_;
PtrList<volSphericalTensorField> vSpheretf_;
PtrList<volSymmTensorField> vSymmtf_;
PtrList<volTensorField> vtf_;
// Protected Member Functions
//- Disallow default bitwise copy construct
nearWallFields(const nearWallFields&);
//- Disallow default bitwise assignment
void operator=(const nearWallFields&);
template<class Type>
void createFields
(
PtrList<GeometricField<Type, fvPatchField, volMesh> >&
) const;
template<class Type>
void sampleFields
(
PtrList<GeometricField<Type, fvPatchField, volMesh> >&
) const;
public:
//- Runtime type information
TypeName("nearWallFields");
// Constructors
//- Construct for given objectRegistry and dictionary.
// Allow the possibility to load fields from files
nearWallFields
(
const word& name,
const objectRegistry&,
const dictionary&,
const bool loadFromFiles = false
);
//- Destructor
virtual ~nearWallFields();
// Member Functions
//- Return name of the nearWallFields object
virtual const word& name() const
{
return name_;
}
//- Read the field min/max data
virtual void read(const dictionary&);
//- Execute, currently does nothing
virtual void execute();
//- Execute at the final time-loop, currently does nothing
virtual void end();
//- Write
virtual void write();
//- Update for changes of mesh
virtual void updateMesh(const mapPolyMesh&)
{}
//- Update for changes of mesh
virtual void movePoints(const pointField&)
{}
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository
# include "nearWallFieldsTemplates.C"
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,46 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2010-2010 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 "nearWallFieldsFunctionObject.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
defineNamedTemplateTypeNameAndDebug
(
nearWallFieldsFunctionObject,
0
);
addToRunTimeSelectionTable
(
functionObject,
nearWallFieldsFunctionObject,
dictionary
);
}
// ************************************************************************* //

View File

@ -0,0 +1,54 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2010-2010 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/>.
Typedef
Foam::nearWallFieldsFunctionObject
Description
FunctionObject wrapper around nearWallFields to allow
them to be created via the functions entry within controlDict.
SourceFiles
nearWallFieldsFunctionObject.C
\*---------------------------------------------------------------------------*/
#ifndef nearWallFieldsFunctionObject_H
#define nearWallFieldsFunctionObject_H
#include "nearWallFields.H"
#include "OutputFilterFunctionObject.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
typedef OutputFilterFunctionObject<nearWallFields>
nearWallFieldsFunctionObject;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,124 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2010-2010 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 "nearWallFields.H"
#include "selfContainedDirectMappedFixedValueFvPatchFields.H"
#include "interpolationCellPoint.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
template<class Type>
void Foam::nearWallFields::createFields
(
PtrList<GeometricField<Type, fvPatchField, volMesh> >& sflds
) const
{
typedef GeometricField<Type, fvPatchField, volMesh> vfType;
HashTable<const vfType*> flds(obr_.lookupClass<vfType>());
forAllConstIter(typename HashTable<const vfType*>, flds, iter)
{
const vfType& fld = *iter();
if (fieldMap_.found(fld.name()))
{
const word& sampleFldName = fieldMap_[fld.name()];
if (obr_.found(sampleFldName))
{
Info<< " a field " << sampleFldName
<< " already exists on the mesh."
<< endl;
}
else
{
label sz = sflds.size();
sflds.setSize(sz+1);
IOobject io(fld);
io.readOpt() = IOobject::NO_READ;
io.rename(sampleFldName);
sflds.set(sz, new vfType(io, fld));
vfType& sampleFld = sflds[sz];
// Reset the bcs to be directMapped
forAllConstIter(labelHashSet, patchSet_, iter)
{
label patchI = iter.key();
sampleFld.boundaryField().set
(
patchI,
new selfContainedDirectMappedFixedValueFvPatchField
<Type>
(
sampleFld.mesh().boundary()[patchI],
sampleFld.dimensionedInternalField(),
sampleFld.mesh().name(),
directMappedPatchBase::NEARESTCELL,
word::null, // samplePatch
-distance_,
sampleFld.name(), // fieldName
false, // setAverage
pTraits<Type>::zero, // average
interpolationCellPoint<Type>::typeName
)
);
}
Info<< " created " << sampleFld.name() << " to sample "
<< fld.name() << endl;
}
}
}
}
template<class Type>
void Foam::nearWallFields::sampleFields
(
PtrList<GeometricField<Type, fvPatchField, volMesh> >& sflds
) const
{
typedef GeometricField<Type, fvPatchField, volMesh> vfType;
forAll(sflds, i)
{
const word& fldName = reverseFieldMap_[sflds[i].name()];
const vfType& fld = obr_.lookupObject<vfType>(fldName);
// Take over internal and boundary values
sflds[i] == fld;
// Evaluate to update the directMapped
sflds[i].correctBoundaryConditions();
}
}
// ************************************************************************* //

View File

@ -426,7 +426,8 @@ void Foam::streamLine::write()
);
// Distribute the track positions
// Distribute the track positions. Note: use scheduled comms
// to prevent buffering.
mapDistribute::distribute
(
Pstream::scheduled,

View File

@ -24,7 +24,6 @@ License
\*---------------------------------------------------------------------------*/
#include "surfaceInterpolateFields.H"
//#include "dictionary.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
@ -89,20 +88,21 @@ void Foam::surfaceInterpolateFields::read(const dictionary& dict)
void Foam::surfaceInterpolateFields::execute()
{
//Info<< type() << " " << name_ << ":" << nl;
if (active_)
{
// Clear out any previously loaded fields
ssf_.clear();
svf_.clear();
sSpheretf_.clear();
sSymmtf_.clear();
stf_.clear();
// Clear out any previously loaded fields
ssf_.clear();
svf_.clear();
sSpheretf_.clear();
sSymmtf_.clear();
stf_.clear();
interpolateFields<scalar>(ssf_);
interpolateFields<vector>(svf_);
interpolateFields<sphericalTensor>(sSpheretf_);
interpolateFields<symmTensor>(sSymmtf_);
interpolateFields<tensor>(stf_);
interpolateFields<scalar>(ssf_);
interpolateFields<vector>(svf_);
interpolateFields<sphericalTensor>(sSpheretf_);
interpolateFields<symmTensor>(sSymmtf_);
interpolateFields<tensor>(stf_);
}
}
@ -114,7 +114,32 @@ void Foam::surfaceInterpolateFields::end()
void Foam::surfaceInterpolateFields::write()
{
// Do nothing
if (active_)
{
Info<< "Writing interpolated surface fields to "
<< obr_.time().timeName() << endl;
forAll(ssf_, i)
{
ssf_[i].write();
}
forAll(svf_, i)
{
svf_[i].write();
}
forAll(sSpheretf_, i)
{
sSpheretf_[i].write();
}
forAll(sSymmtf_, i)
{
sSymmtf_[i].write();
}
forAll(stf_, i)
{
stf_[i].write();
}
}
}

View File

@ -27,9 +27,24 @@ Class
Description
Linear interpolates volFields to surfaceFields
Note: gets executed every time step. Could move it to write() but then
you'd have problems if you have different write frequencies for different
function objects.
- at write it writes the fields
- it executes every time step
so it can either be used to calculate and write the interpolate or
(since the interpolates are registered) use some other functionObject
to work on them.
sampleSomeFields
{
type surfaceInterpolateFields;
..
enabled true;
outputControl outputTime;
..
// Name of volField and corresponding surfaceField
fields ((p pInterpolate)(U UInterpolate));
}
SourceFiles
surfaceInterpolateFields.C

View File

@ -1,4 +1,5 @@
probes/probes.C
probes/patchProbes.C
probes/probesGrouping.C
probes/probesFunctionObject/probesFunctionObject.C
@ -27,6 +28,7 @@ $(setWriters)/xmgrace/xmgraceSetWriterRunTime.C
cuttingPlane/cuttingPlane.C
sampledSurface/sampledPatch/sampledPatch.C
sampledSurface/sampledPatchInternalField/sampledPatchInternalField.C
sampledSurface/sampledPlane/sampledPlane.C
sampledSurface/isoSurface/isoSurface.C
sampledSurface/isoSurface/sampledIsoSurface.C

View File

@ -33,6 +33,7 @@ Description
#define IOprobes_H
#include "probes.H"
#include "patchProbes.H"
#include "IOOutputFilter.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -40,6 +41,7 @@ Description
namespace Foam
{
typedef IOOutputFilter<probes> IOprobes;
typedef IOOutputFilter<patchProbes> IOpatchProbes;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View File

@ -0,0 +1,160 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2010-2010 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 "patchProbes.H"
#include "volFields.H"
#include "IOmanip.H"
// For 'nearInfo' helper class only
#include "directMappedPatchBase.H"
#include "meshSearch.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
defineTypeNameAndDebug(patchProbes, 0);
}
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
void Foam::patchProbes::findElements(const fvMesh& mesh)
{
elementList_.clear();
elementList_.setSize(size());
// All the info for nearest. Construct to miss
List<directMappedPatchBase::nearInfo> nearest(this->size());
// Octree based search engine
meshSearch meshSearchEngine(mesh, false);
forAll(*this, probeI)
{
const vector& sample = operator[](probeI);
label faceI = meshSearchEngine.findNearestBoundaryFace(sample);
if (faceI == -1)
{
nearest[probeI].second().first() = Foam::sqr(GREAT);
nearest[probeI].second().second() = Pstream::myProcNo();
}
else
{
const point& fc = mesh.faceCentres()[faceI];
nearest[probeI].first() = pointIndexHit
(
true,
fc,
faceI
);
nearest[probeI].second().first() = magSqr(fc-sample);
nearest[probeI].second().second() = Pstream::myProcNo();
}
}
// Find nearest.
Pstream::listCombineGather(nearest, directMappedPatchBase::nearestEqOp());
Pstream::listCombineScatter(nearest);
if (debug)
{
Info<< "patchProbes::findElements" << " : " << endl;
forAll(nearest, sampleI)
{
label procI = nearest[sampleI].second().second();
label localI = nearest[sampleI].first().index();
Info<< " " << sampleI << " coord:"<< operator[](sampleI)
<< " found on processor:" << procI
<< " in local cell/face:" << localI
<< " with cc:" << nearest[sampleI].first().rawPoint() << endl;
}
}
// Check if all patchProbes have been found.
forAll(nearest, sampleI)
{
label localI = nearest[sampleI].first().index();
if (localI == -1)
{
if (Pstream::master())
{
WarningIn("patchProbes::findElements()")
<< "Did not find location "
<< nearest[sampleI].second().first()
<< " in any cell. Skipping location." << endl;
}
}
else
{
elementList_[sampleI] = localI;
}
}
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::patchProbes::patchProbes
(
const word& name,
const objectRegistry& obr,
const dictionary& dict,
const bool loadFromFiles
)
:
probes(name, obr, dict, loadFromFiles)
{
read(dict);
}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::patchProbes::~patchProbes()
{}
void Foam::patchProbes::write()
{
if (this->size() && prepare())
{
sampleAndWrite(scalarFields_);
sampleAndWrite(vectorFields_);
sampleAndWrite(sphericalTensorFields_);
sampleAndWrite(symmTensorFields_);
sampleAndWrite(tensorFields_);
}
}
void Foam::patchProbes::read(const dictionary& dict)
{
probes::read(dict);
}
// ************************************************************************* //

View File

@ -0,0 +1,147 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2010-2010 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/>.
Class
Foam::patchProbes
Description
Set of locations to sample.at patches
Call write() to sample and write files.
SourceFiles
patchProbes.C
\*---------------------------------------------------------------------------*/
#ifndef patchProbes_H
#define patchProbes_H
#include "probes.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// Forward declaration of classes
class objectRegistry;
class dictionary;
class fvMesh;
class mapPolyMesh;
/*---------------------------------------------------------------------------*\
Class patchProbes Declaration
\*---------------------------------------------------------------------------*/
class patchProbes
:
public probes
{
// Private Member Functions
//- Sample and write a particular volume field
template<class Type>
void sampleAndWrite
(
const GeometricField<Type, fvPatchField, volMesh>&
);
//- Sample and write all the fields of the given type
template <class Type>
void sampleAndWrite(const fieldGroup<Type>&);
//- Sample a volume field at all locations
template<class Type>
tmp<Field<Type> > sample
(
const GeometricField<Type, fvPatchField, volMesh>&
) const;
//- Sample a single field on all sample locations
template <class Type>
tmp<Field<Type> > sample(const word& fieldName) const;
//- Disallow default bitwise copy construct
patchProbes(const patchProbes&);
//- Disallow default bitwise assignment
void operator=(const patchProbes&);
public:
//- Runtime type information
TypeName("patchProbes");
// Constructors
//- Construct for given objectRegistry and dictionary.
// Allow the possibility to load fields from files
patchProbes
(
const word& name,
const objectRegistry&,
const dictionary&,
const bool loadFromFiles = false
);
//- Destructor
virtual ~patchProbes();
//- Public members
//- Sample and write
virtual void write();
//- Read
virtual void read(const dictionary&);
//- Find elements containing patchProbes
virtual void findElements(const fvMesh&);
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository
# include "patchProbesTemplates.C"
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,162 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2010-2010 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 "patchProbes.H"
#include "volFields.H"
#include "IOmanip.H"
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
template<class Type>
void Foam::patchProbes::sampleAndWrite
(
const GeometricField<Type, fvPatchField, volMesh>& vField
)
{
Field<Type> values = sample(vField);
if (Pstream::master())
{
unsigned int w = IOstream::defaultPrecision() + 7;
OFstream& probeStream = *probeFilePtrs_[vField.name()];
probeStream << setw(w) << vField.time().value();
forAll(values, probeI)
{
probeStream << ' ' << setw(w) << values[probeI];
}
probeStream << endl;
}
}
template <class Type>
void Foam::patchProbes::sampleAndWrite
(
const fieldGroup<Type>& fields
)
{
forAll(fields, fieldI)
{
if (loadFromFiles_)
{
sampleAndWrite
(
GeometricField<Type, fvPatchField, volMesh>
(
IOobject
(
fields[fieldI],
mesh_.time().timeName(),
mesh_,
IOobject::MUST_READ,
IOobject::NO_WRITE,
false
),
mesh_
)
);
}
else
{
objectRegistry::const_iterator iter = mesh_.find(fields[fieldI]);
if
(
iter != objectRegistry::end()
&& iter()->type()
== GeometricField<Type, fvPatchField, volMesh>::typeName
)
{
sampleAndWrite
(
mesh_.lookupObject
<GeometricField<Type, fvPatchField, volMesh> >
(
fields[fieldI]
)
);
}
}
}
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class Type>
Foam::tmp<Foam::Field<Type> >
Foam::patchProbes::sample
(
const GeometricField<Type, fvPatchField, volMesh>& vField
) const
{
const Type unsetVal(-VGREAT*pTraits<Type>::one);
tmp<Field<Type> > tValues
(
new Field<Type>(this->size(), unsetVal)
);
Field<Type>& values = tValues();
const polyBoundaryMesh& patches = mesh_.boundaryMesh();
forAll(*this, probeI)
{
label faceI = elementList_[probeI];
if (faceI >= 0)
{
label patchI = patches.whichPatch(faceI);
label localFaceI = patches[patchI].whichFace(faceI);
values[probeI] = vField.boundaryField()[patchI][localFaceI];
}
}
Pstream::listCombineGather(values, isNotEqOp<Type>());
Pstream::listCombineScatter(values);
return tValues;
}
template<class Type>
Foam::tmp<Foam::Field<Type> >
Foam::patchProbes::sample(const word& fieldName) const
{
return sample
(
mesh_.lookupObject<GeometricField<Type, fvPatchField, volMesh> >
(
fieldName
)
);
}
// ************************************************************************* //

View File

@ -36,30 +36,30 @@ defineTypeNameAndDebug(Foam::probes, 0);
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
void Foam::probes::findCells(const fvMesh& mesh)
void Foam::probes::findElements(const fvMesh& mesh)
{
cellList_.clear();
cellList_.setSize(size());
elementList_.clear();
elementList_.setSize(size());
forAll(*this, probeI)
{
const vector& location = operator[](probeI);
cellList_[probeI] = mesh.findCell(location);
elementList_[probeI] = mesh.findCell(location);
if (debug && cellList_[probeI] != -1)
if (debug && elementList_[probeI] != -1)
{
Pout<< "probes : found point " << location
<< " in cell " << cellList_[probeI] << endl;
<< " in cell " << elementList_[probeI] << endl;
}
}
// Check if all probes have been found.
forAll(cellList_, probeI)
forAll(elementList_, probeI)
{
const vector& location = operator[](probeI);
label cellI = cellList_[probeI];
label cellI = elementList_[probeI];
// Check at least one processor with cell.
reduce(cellI, maxOp<label>());
@ -76,12 +76,12 @@ void Foam::probes::findCells(const fvMesh& mesh)
else
{
// Make sure location not on two domains.
if (cellList_[probeI] != -1 && cellList_[probeI] != cellI)
if (elementList_[probeI] != -1 && elementList_[probeI] != cellI)
{
WarningIn("probes::read()")
<< "Location " << location
<< " seems to be on multiple domains:"
<< " cell " << cellList_[probeI]
<< " cell " << elementList_[probeI]
<< " on my domain " << Pstream::myProcNo()
<< " and cell " << cellI << " on some other domain."
<< endl
@ -249,7 +249,7 @@ void Foam::probes::read(const dictionary& dict)
dict.lookup("fields") >> fieldSelection_;
// redetermined all cell locations
findCells(mesh_);
findElements(mesh_);
prepare();
}

View File

@ -64,7 +64,9 @@ class probes
:
public pointField
{
// Private classes
protected:
// Protected classes
//- Class used for grouping field types
template<class Type>
@ -110,7 +112,7 @@ class probes
fieldGroup<tensor> tensorFields_;
// Cells to be probed (obtained from the locations)
labelList cellList_;
labelList elementList_;
//- Current open files
HashPtrTable<OFstream> probeFilePtrs_;
@ -128,12 +130,14 @@ class probes
label classifyFields();
//- Find cells containing probes
void findCells(const fvMesh&);
virtual void findElements(const fvMesh&);
//- Classify field type and Open/close file streams,
// returns number of fields
label prepare();
private:
//- Sample and write a particular volume field
template<class Type>
void sampleAndWrite
@ -202,9 +206,9 @@ public:
}
//- Cells to be probed (obtained from the locations)
const labelList& cells() const
const labelList& elemets() const
{
return cellList_;
return elementList_;
}
//- Execute, currently does nothing

View File

@ -30,6 +30,7 @@ License
namespace Foam
{
defineNamedTemplateTypeNameAndDebug(probesFunctionObject, 0);
defineNamedTemplateTypeNameAndDebug(patchProbesFunctionObject, 0);
addToRunTimeSelectionTable
(
@ -37,6 +38,12 @@ namespace Foam
probesFunctionObject,
dictionary
);
addToRunTimeSelectionTable
(
functionObject,
patchProbesFunctionObject,
dictionary
);
}
// ************************************************************************* //

View File

@ -37,6 +37,7 @@ SourceFiles
#define probesFunctionObject_H
#include "probes.H"
#include "patchProbes.H"
#include "OutputFilterFunctionObject.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -44,6 +45,7 @@ SourceFiles
namespace Foam
{
typedef OutputFilterFunctionObject<probes> probesFunctionObject;
typedef OutputFilterFunctionObject<patchProbes> patchProbesFunctionObject;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View File

@ -158,9 +158,9 @@ Foam::probes::sample
forAll(*this, probeI)
{
if (cellList_[probeI] >= 0)
if (elementList_[probeI] >= 0)
{
values[probeI] = vField[cellList_[probeI]];
values[probeI] = vField[elementList_[probeI]];
}
}

View File

@ -118,6 +118,8 @@ void Foam::faceOnlySet::calcSamples
const vector smallVec = tol*offset;
const scalar smallDist = mag(smallVec);
// Force calculation of minimum-tet decomposition.
(void) mesh().tetBasePtIs();
// Get all boundary intersections
List<pointIndexHit> bHits = searchEngine().intersections

View File

@ -53,7 +53,7 @@ void Foam::midPointSet::genSamples()
label sampleI = 0;
while(true)
while(true && size()>0)
{
// calculate midpoint between sampleI and sampleI+1 (if in same segment)
while

View File

@ -55,7 +55,7 @@ void Foam::midPointAndFaceSet::genSamples()
label sampleI = 0;
while(true)
while(true && size()>0)
{
// sampleI is start of segment

View File

@ -159,6 +159,9 @@ void Foam::polyLineSet::calcSamples
oldPoint = sampleCoords_[sampleI];
}
// Force calculation of minimum-tet decomposition.
(void) mesh().tetBasePtIs();
// current segment number
label segmentI = 0;

View File

@ -96,6 +96,14 @@ void Foam::sampledSets::combineSampledSets
)
);
if (Pstream::master() && allCurveDist.size() == 0)
{
WarningIn("sampledSets::combineSampledSets(..)")
<< "Sample set " << samplePts.name()
<< " has zero points." << endl;
}
// Sort curveDist and use to fill masterSamplePts
SortableList<scalar> sortedDist(allCurveDist);
indexSets[setI] = sortedDist.indices();
@ -226,17 +234,8 @@ void Foam::sampledSets::read(const dictionary& dict)
dict_.lookup("fields") >> fieldSelection_;
clearFieldGroups();
interpolationScheme_ = dict.lookupOrDefault<word>
(
"interpolationScheme",
"cell"
);
writeFormat_ = dict.lookupOrDefault<word>
(
"setFormat",
"null"
);
dict.lookup("interpolationScheme") >> interpolationScheme_;
dict.lookup("setFormat") >> writeFormat_;
PtrList<sampledSet> newList
(

View File

@ -236,6 +236,9 @@ void Foam::uniformSet::calcSamples
const vector smallVec = tol*offset;
const scalar smallDist = mag(smallVec);
// Force calculation of minimum-tet decomposition.
(void) mesh().tetBasePtIs();
// Get all boundary intersections
List<pointIndexHit> bHits = searchEngine().intersections
(

View File

@ -50,6 +50,9 @@ void Foam::distanceSurface::createGeometry()
// Clear any stored topologies
facesPtr_.clear();
// Clear derived data
clearGeom();
const fvMesh& fvm = static_cast<const fvMesh&>(mesh());
// Distance to cell centres
@ -361,6 +364,9 @@ bool Foam::distanceSurface::expire()
// Clear any stored topologies
facesPtr_.clear();
// Clear derived data
clearGeom();
// already marked as expired
if (needsUpdate_)
{

View File

@ -333,6 +333,9 @@ bool Foam::sampledIsoSurface::updateGeometry() const
surfPtr_.clear();
facesPtr_.clear();
// Clear derived data
clearGeom();
if (subMeshPtr_.valid())
{
surfPtr_.reset
@ -471,6 +474,9 @@ bool Foam::sampledIsoSurface::expire()
facesPtr_.clear();
subMeshPtr_.clear();
// Clear derived data
clearGeom();
// already marked as expired
if (prevTimeIndex_ == -1)
{

View File

@ -62,6 +62,9 @@ bool Foam::sampledIsoSurfaceCell::updateGeometry() const
// Clear any stored topo
facesPtr_.clear();
// Clear derived data
sampledSurface::clearGeom();
// Optionally read volScalarField
autoPtr<volScalarField> readFieldPtr_;
@ -240,6 +243,9 @@ bool Foam::sampledIsoSurfaceCell::expire()
{
facesPtr_.clear();
// Clear derived data
sampledSurface::clearGeom();
// already marked as expired
if (prevTimeIndex_ == -1)
{

View File

@ -60,6 +60,8 @@ void Foam::sampledCuttingPlane::createGeometry()
pointDistance_.clear();
cellDistancePtr_.clear();
// Clear derived data
clearGeom();
// Get any subMesh
if (zoneID_.index() != -1 && !subMeshPtr_.valid())
@ -321,6 +323,9 @@ bool Foam::sampledCuttingPlane::expire()
// Clear any stored topologies
facesPtr_.clear();
// Clear derived data
clearGeom();
// already marked as expired
if (needsUpdate_)
{

View File

@ -157,6 +157,10 @@ void Foam::sampledPatch::remapFaces
if (&faceMap && faceMap.size())
{
MeshStorage::remapFaces(faceMap);
patchFaceLabels_ = labelList
(
UIndirectList<label>(patchFaceLabels_, faceMap)
);
}
}

View File

@ -0,0 +1,176 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 1991-2010 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 "sampledPatchInternalField.H"
#include "dictionary.H"
#include "polyMesh.H"
#include "polyPatch.H"
#include "volFields.H"
#include "addToRunTimeSelectionTable.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
defineTypeNameAndDebug(sampledPatchInternalField, 0);
addNamedToRunTimeSelectionTable
(
sampledSurface,
sampledPatchInternalField,
word,
patchInternalField
);
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::sampledPatchInternalField::sampledPatchInternalField
(
const word& name,
const polyMesh& mesh,
const dictionary& dict
)
:
sampledPatch(name, mesh, dict),
directMappedPatchBase
(
mesh.boundaryMesh()[sampledPatch::patchIndex()],
mesh.name(), // sampleRegion
directMappedPatchBase::NEARESTCELL, // sampleMode
word::null, // samplePatch
-readScalar(dict.lookup("distance"))
)
{}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::sampledPatchInternalField::~sampledPatchInternalField()
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
Foam::tmp<Foam::scalarField> Foam::sampledPatchInternalField::sample
(
const volScalarField& vField
) const
{
return sampleField(vField);
}
Foam::tmp<Foam::vectorField> Foam::sampledPatchInternalField::sample
(
const volVectorField& vField
) const
{
return sampleField(vField);
}
Foam::tmp<Foam::sphericalTensorField> Foam::sampledPatchInternalField::sample
(
const volSphericalTensorField& vField
) const
{
return sampleField(vField);
}
Foam::tmp<Foam::symmTensorField> Foam::sampledPatchInternalField::sample
(
const volSymmTensorField& vField
) const
{
return sampleField(vField);
}
Foam::tmp<Foam::tensorField> Foam::sampledPatchInternalField::sample
(
const volTensorField& vField
) const
{
return sampleField(vField);
}
Foam::tmp<Foam::scalarField> Foam::sampledPatchInternalField::interpolate
(
const interpolation<scalar>& interpolator
) const
{
return interpolateField(interpolator);
}
Foam::tmp<Foam::vectorField> Foam::sampledPatchInternalField::interpolate
(
const interpolation<vector>& interpolator
) const
{
return interpolateField(interpolator);
}
Foam::tmp<Foam::sphericalTensorField>
Foam::sampledPatchInternalField::interpolate
(
const interpolation<sphericalTensor>& interpolator
) const
{
return interpolateField(interpolator);
}
Foam::tmp<Foam::symmTensorField> Foam::sampledPatchInternalField::interpolate
(
const interpolation<symmTensor>& interpolator
) const
{
return interpolateField(interpolator);
}
Foam::tmp<Foam::tensorField> Foam::sampledPatchInternalField::interpolate
(
const interpolation<tensor>& interpolator
) const
{
return interpolateField(interpolator);
}
void Foam::sampledPatchInternalField::print(Ostream& os) const
{
os << "sampledPatchInternalField: " << name() << " :"
<< " patch:" << patchName()
<< " faces:" << faces().size()
<< " points:" << points().size();
}
// ************************************************************************* //

View File

@ -0,0 +1,177 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 1991-2010 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/>.
Class
Foam::sampledPatchInternalField
Description
Variation of sampledPatch that samples the internalField (at a given
normal distance from the patch) instead of the patchField.
Note:
- interpolate=false : get cell value on faces
- interpolate=true : interpolate inside cell and interpolate to points
There is no option to get interpolated value inside the cell on the faces.
SourceFiles
sampledPatchInternalField.C
\*---------------------------------------------------------------------------*/
#ifndef sampledPatchInternalField_H
#define sampledPatchInternalField_H
#include "sampledPatch.H"
#include "directMappedPatchBase.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class sampledPatchInternalField Declaration
\*---------------------------------------------------------------------------*/
class sampledPatchInternalField
:
public sampledPatch,
public directMappedPatchBase
{
// Private Member Functions
//- sample field on faces
template <class Type>
tmp<Field<Type> > sampleField
(
const GeometricField<Type, fvPatchField, volMesh>& vField
) const;
template <class Type>
tmp<Field<Type> > interpolateField(const interpolation<Type>&) const;
public:
//- Runtime type information
TypeName("sampledPatchInternalField");
// Constructors
//- Construct from dictionary
sampledPatchInternalField
(
const word& name,
const polyMesh& mesh,
const dictionary& dict
);
//- Destructor
virtual ~sampledPatchInternalField();
// Member Functions
//- sample field on surface
virtual tmp<scalarField> sample
(
const volScalarField&
) const;
//- sample field on surface
virtual tmp<vectorField> sample
(
const volVectorField&
) const;
//- sample field on surface
virtual tmp<sphericalTensorField> sample
(
const volSphericalTensorField&
) const;
//- sample field on surface
virtual tmp<symmTensorField> sample
(
const volSymmTensorField&
) const;
//- sample field on surface
virtual tmp<tensorField> sample
(
const volTensorField&
) const;
//- interpolate field on surface
virtual tmp<scalarField> interpolate
(
const interpolation<scalar>&
) const;
//- interpolate field on surface
virtual tmp<vectorField> interpolate
(
const interpolation<vector>&
) const;
//- interpolate field on surface
virtual tmp<sphericalTensorField> interpolate
(
const interpolation<sphericalTensor>&
) const;
//- interpolate field on surface
virtual tmp<symmTensorField> interpolate
(
const interpolation<symmTensor>&
) const;
//- interpolate field on surface
virtual tmp<tensorField> interpolate
(
const interpolation<tensor>&
) const;
//- Write
virtual void print(Ostream&) const;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository
# include "sampledPatchInternalFieldTemplates.C"
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,114 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 1991-2010 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 "sampledPatchInternalField.H"
#include "interpolationCellPoint.H"
#include "PrimitivePatchInterpolation.H"
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
template <class Type>
Foam::tmp<Foam::Field<Type> >
Foam::sampledPatchInternalField::sampleField
(
const GeometricField<Type, fvPatchField, volMesh>& vField
) const
{
const mapDistribute& distMap = map();
// One value per face
tmp<Field<Type> > tvalues(new Field<Type>(patchFaceLabels().size()));
Field<Type>& values = tvalues();
if (patchIndex() != -1)
{
Field<Type> interpVals = vField.internalField();
distMap.distribute(interpVals);
forAll(patchFaceLabels(), elemI)
{
values[elemI] = interpVals[patchFaceLabels()[elemI]];
}
}
return tvalues;
}
template <class Type>
Foam::tmp<Foam::Field<Type> >
Foam::sampledPatchInternalField::interpolateField
(
const interpolation<Type>& interpolator
) const
{
// One value per vertex
if (patchIndex() != -1)
{
// See directMappedFixedValueFvPatchField
const mapDistribute& distMap = map();
const polyPatch& pp = mesh().boundaryMesh()[patchIndex()];
// Send back sample points to processor that holds the cell.
// Mark cells with point::max so we know which ones we need
// to interpolate (since expensive).
vectorField samples(samplePoints());
distMap.reverseDistribute(mesh().nCells(), point::max, samples);
Field<Type> patchVals(mesh().nCells());
forAll(samples, cellI)
{
if (samples[cellI] != point::max)
{
patchVals[cellI] = interpolator.interpolate
(
samples[cellI],
cellI
);
}
}
distMap.distribute(patchVals);
// Now patchVals holds the interpolated data in patch face order.
// Interpolate to points. Note: points are patch.localPoints() so
// can use standard interpolation
return PrimitivePatchInterpolation<primitivePatch>
(
pp
).faceToPointInterpolate(patchVals);
}
else
{
return tmp<Field<Type> >(new Field<Type>(points().size()));
}
}
// ************************************************************************* //

View File

@ -220,17 +220,8 @@ void Foam::sampledSurfaces::read(const dictionary& dict)
dict.lookup("fields") >> fieldSelection_;
clearFieldGroups();
interpolationScheme_ = dict.lookupOrDefault<word>
(
"interpolationScheme",
"cell"
);
writeFormat_ = dict.lookupOrDefault<word>
(
"surfaceFormat",
"null"
);
dict.lookup("interpolationScheme") >> interpolationScheme_;
dict.lookup("surfaceFormat") >> writeFormat_;
// define the generic (geometry) writer
genericFormatter_ = surfaceWriter<bool>::New(writeFormat_);

View File

@ -124,6 +124,8 @@ bool Foam::sampledThresholdCellFaces::updateGeometry() const
).MeshedSurface<face>::transfer(surf);
meshCells_.transfer(surf.meshCells());
// clear derived data
sampledSurface::clearGeom();
if (debug)
{

View File

@ -26,7 +26,6 @@ submodels/thermo/heatTransferModel/mappedConvectiveHeatTransfer/mappedConvective
/* Boundary conditions */
derivedFvPatchFields/directMappedFixedInternalValue/directMappedFixedInternalValueFvPatchFields.C
derivedFvPatchFields/directMappedNamedFixedValue/directMappedNamedFixedValueFvPatchFields.C
derivedFvPatchFields/directMappedFixedPushedInternalValue/directMappedFixedPushedInternalValueFvPatchFields.C
derivedFvPatchFields/filmHeightInletVelocity/filmHeightInletVelocityFvPatchVectorField.C
derivedFvPatchFields/htcConv/htcConvFvPatchScalarField.C

View File

@ -5,8 +5,8 @@ EXE_INC = \
-I$(LIB_SRC)/thermophysicalModels/specie/lnInclude \
-I$(LIB_SRC)/thermophysicalModels/liquids/lnInclude \
-I$(LIB_SRC)/thermophysicalModels/liquidMixture/lnInclude \
-I$(LIB_SRC)/thermophysicalModels/solids/lnInclude \
-I$(LIB_SRC)/thermophysicalModels/solidMixture/lnInclude \
-I$(LIB_SRC)/thermophysicalModels/pointSolids/lnInclude \
-I$(LIB_SRC)/thermophysicalModels/pointSolidMixture/lnInclude \
-I$(LIB_SRC)/thermophysicalModels/reactionThermo/lnInclude \
-I$(LIB_SRC)/thermophysicalModels/SLGThermo/lnInclude \
-I$(LIB_SRC)/thermophysicalModels/pdfs/lnInclude \

View File

@ -132,15 +132,7 @@ void directMappedFixedInternalValueFvPatchField<Type>::updateCoeffs()
// Retrieve the neighbour patch internal field
Field<Type> nbrIntFld = nbrField.patchInternalField();
mapDistribute::distribute
(
Pstream::defaultCommsType,
distMap.schedule(),
distMap.constructSize(),
distMap.subMap(), // what to send
distMap.constructMap(), // what to receive
nbrIntFld
);
distMap.distribute(nbrIntFld);
// Assign (this) patch internal field to its neighbour values
Field<Type>& intFld = const_cast<Field<Type>&>(this->internalField());

View File

@ -1,334 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2010-2010 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 "directMappedNamedFixedValueFvPatchField.H"
#include "directMappedPatchBase.H"
#include "volFields.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
template<class Type>
directMappedNamedFixedValueFvPatchField<Type>::
directMappedNamedFixedValueFvPatchField
(
const fvPatch& p,
const DimensionedField<Type, volMesh>& iF
)
:
fixedValueFvPatchField<Type>(p, iF),
fieldName_(iF.name()),
setAverage_(false),
average_(pTraits<Type>::zero)
{}
template<class Type>
directMappedNamedFixedValueFvPatchField<Type>::
directMappedNamedFixedValueFvPatchField
(
const directMappedNamedFixedValueFvPatchField<Type>& ptf,
const fvPatch& p,
const DimensionedField<Type, volMesh>& iF,
const fvPatchFieldMapper& mapper
)
:
fixedValueFvPatchField<Type>(ptf, p, iF, mapper),
fieldName_(ptf.fieldName_),
setAverage_(ptf.setAverage_),
average_(ptf.average_)
{
if (!isA<directMappedPatchBase>(this->patch().patch()))
{
FatalErrorIn
(
"directMappedNamedFixedValueFvPatchField<Type>::"
"directMappedNamedFixedValueFvPatchField\n"
"("
"const directMappedNamedFixedValueFvPatchField<Type>&, "
"const fvPatch&, "
"const Field<Type>&, "
"const fvPatchFieldMapper& "
")"
) << " patch type '" << p.type()
<< "' not type '" << directMappedPatchBase::typeName << "'"
<< "\n for patch " << p.name()
<< " of field " << this->dimensionedInternalField().name()
<< " in file " << this->dimensionedInternalField().objectPath()
<< exit(FatalError);
}
}
template<class Type>
directMappedNamedFixedValueFvPatchField<Type>::
directMappedNamedFixedValueFvPatchField
(
const fvPatch& p,
const DimensionedField<Type, volMesh>& iF,
const dictionary& dict
)
:
fixedValueFvPatchField<Type>(p, iF, dict),
fieldName_(dict.lookupOrDefault<word>("fieldName", iF.name())),
setAverage_(readBool(dict.lookup("setAverage"))),
average_(pTraits<Type>(dict.lookup("average")))
{
if (!isA<directMappedPatchBase>(this->patch().patch()))
{
FatalErrorIn
(
"directMappedNamedFixedValueFvPatchField<Type>::"
"directMappedNamedFixedValueFvPatchField"
"("
"const fvPatch&, "
"const DimensionedField<Type, volMesh>& iF, "
"const dictionary&"
")"
) << " patch type '" << p.type()
<< "' not type '" << directMappedPatchBase::typeName << "'"
<< "\n for patch " << p.name()
<< " of field " << fieldName_
<< " in file " << this->dimensionedInternalField().objectPath()
<< exit(FatalError);
}
//// Force calculation of schedule (uses parallel comms)
//const directMappedPatchBase& mpp = refCast<const directMappedPatchBase>
//(
// this->patch().patch()
//);
//(void)mpp.map().schedule();
}
template<class Type>
directMappedNamedFixedValueFvPatchField<Type>::
directMappedNamedFixedValueFvPatchField
(
const directMappedNamedFixedValueFvPatchField<Type>& ptf
)
:
fixedValueFvPatchField<Type>(ptf),
fieldName_(ptf.fieldName_),
setAverage_(ptf.setAverage_),
average_(ptf.average_)
{}
template<class Type>
directMappedNamedFixedValueFvPatchField<Type>::
directMappedNamedFixedValueFvPatchField
(
const directMappedNamedFixedValueFvPatchField<Type>& ptf,
const DimensionedField<Type, volMesh>& iF
)
:
fixedValueFvPatchField<Type>(ptf, iF),
fieldName_(ptf.fieldName_),
setAverage_(ptf.setAverage_),
average_(ptf.average_)
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class Type>
void directMappedNamedFixedValueFvPatchField<Type>::updateCoeffs()
{
if (this->updated())
{
return;
}
typedef GeometricField<Type, fvPatchField, volMesh> fieldType;
// Get the scheduling information from the directMappedPatchBase
const directMappedPatchBase& mpp = refCast<const directMappedPatchBase>
(
directMappedNamedFixedValueFvPatchField<Type>::patch().patch()
);
const mapDistribute& distMap = mpp.map();
// Force recalculation of schedule
(void)distMap.schedule();
const fvMesh& nbrMesh = refCast<const fvMesh>(mpp.sampleMesh());
// Result of obtaining remote values
Field<Type> newValues;
switch (mpp.mode())
{
case directMappedPatchBase::NEARESTCELL:
{
if (mpp.sameRegion())
{
newValues = this->internalField();
}
else
{
newValues = nbrMesh.lookupObject<fieldType>
(
fieldName_
).internalField();
}
mapDistribute::distribute
(
Pstream::defaultCommsType,
distMap.schedule(),
distMap.constructSize(),
distMap.subMap(),
distMap.constructMap(),
newValues
);
break;
}
case directMappedPatchBase::NEARESTPATCHFACE:
{
const label nbrPatchID =
nbrMesh.boundaryMesh().findPatchID(mpp.samplePatch());
if (nbrPatchID < 0)
{
FatalErrorIn
(
"void directMappedNamedFixedValueFvPatchField<Type>::"
"updateCoeffs()"
)<< "Unable to find sample patch " << mpp.samplePatch()
<< " in region " << mpp.sampleRegion()
<< " for patch " << this->patch().name() << nl
<< abort(FatalError);
}
const fieldType& nbrField =
nbrMesh.lookupObject<fieldType>(fieldName_);
newValues = nbrField.boundaryField()[nbrPatchID];
mapDistribute::distribute
(
Pstream::defaultCommsType,
distMap.schedule(),
distMap.constructSize(),
distMap.subMap(),
distMap.constructMap(),
newValues
);
break;
}
case directMappedPatchBase::NEARESTFACE:
{
Field<Type> allValues(nbrMesh.nFaces(), pTraits<Type>::zero);
const fieldType& nbrField =
nbrMesh.lookupObject<fieldType>(fieldName_);
forAll(nbrField.boundaryField(), patchI)
{
const fvPatchField<Type>& pf =
nbrField.boundaryField()[patchI];
label faceStart = pf.patch().patch().start();
forAll(pf, faceI)
{
allValues[faceStart++] = pf[faceI];
}
}
mapDistribute::distribute
(
Pstream::defaultCommsType,
distMap.schedule(),
distMap.constructSize(),
distMap.subMap(),
distMap.constructMap(),
allValues
);
newValues = this->patch().patchSlice(allValues);
break;
}
default:
{
FatalErrorIn
(
"directMappedNamedFixedValueFvPatchField<Type>::updateCoeffs()"
)<< "Unknown sampling mode: " << mpp.mode()
<< nl << abort(FatalError);
}
}
if (setAverage_)
{
Type averagePsi =
gSum(this->patch().magSf()*newValues)
/gSum(this->patch().magSf());
if (mag(averagePsi)/mag(average_) > 0.5)
{
newValues *= mag(average_)/mag(averagePsi);
}
else
{
newValues += (average_ - averagePsi);
}
}
this->operator==(newValues);
if (debug)
{
Info<< "directMapped on field:" << fieldName_
<< " patch:" << this->patch().name()
<< " avg:" << gAverage(*this)
<< " min:" << gMin(*this)
<< " max:" << gMax(*this)
<< endl;
}
fixedValueFvPatchField<Type>::updateCoeffs();
}
template<class Type>
void directMappedNamedFixedValueFvPatchField<Type>::write(Ostream& os) const
{
fvPatchField<Type>::write(os);
os.writeKeyword("fieldName") << fieldName_ << token::END_STATEMENT << nl;
os.writeKeyword("setAverage") << setAverage_ << token::END_STATEMENT << nl;
os.writeKeyword("average") << average_ << token::END_STATEMENT << nl;
this->writeEntry("value", os);
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// ************************************************************************* //

View File

@ -3,11 +3,12 @@ cd ${0%/*} || exit 1 # run from this directory
set -x
wmake libso specie
wmake libso solid
wmake libso thermophysicalFunctions
wmake libso liquids
wmake libso liquidMixture
wmake libso solids
wmake libso solidMixture
wmake libso pointSolids
wmake libso pointSolidMixture
wmake libso basic
wmake libso reactionThermo

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