ENH: AMI - refactored caching

This commit is contained in:
Andrew Heather
2025-05-28 10:23:10 +01:00
parent a206824335
commit 38680d9c8c
8 changed files with 1029 additions and 613 deletions

View File

@ -0,0 +1,567 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2025 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "AMICache.H"
#include "AMIInterpolation.H"
#include "mathematicalConstants.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
Foam::scalar Foam::AMICache::cacheThetaTolerance_ = 1e-8;
int Foam::AMICache::debug = 0;
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
Foam::scalar Foam::AMICache::getRotationAngle(const point& globalPoint) const
{
if (!coordSysPtr_)
{
FatalErrorInFunction
<< "No co-ordinate system available for theta evaluation"
<< abort(FatalError);
}
scalar theta = coordSysPtr_->localPosition(globalPoint).y();
// Ensure 0 < theta < 2pi
if (mag(theta) < cacheThetaTolerance_)
{
theta = 0;
}
else if (theta < 0)
{
theta += constant::mathematical::twoPi;
}
return theta;
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::AMICache::AMICache(const dictionary& dict, const bool toSource)
:
size_(dict.getOrDefault<label>("cacheSize", 0)),
rotationAxis_(dict.getOrDefault<vector>("rotationAxis", Zero)),
rotationCentre_(dict.getOrDefault<point>("rotationCentre", Zero)),
complete_(false),
index0_(-1),
index1_(-1),
interpWeight_(0),
coordSysPtr_(nullptr),
theta_(),
cachedSrcAddress_(),
cachedSrcWeights_(),
cachedSrcWeightsSum_(),
cachedSrcMapPtr_(),
cachedTgtAddress_(),
cachedTgtWeights_(),
cachedTgtWeightsSum_(),
cachedTgtMapPtr_(),
toSource_(toSource)
{
if (size_ != 0)
{
theta_.resize(size_, GREAT);
cachedSrcAddress_.resize(size_);
cachedSrcWeights_.resize(size_);
cachedSrcWeightsSum_.resize(size_);
cachedSrcMapPtr_.resize(size_);
cachedTgtAddress_.resize(size_);
cachedTgtWeights_.resize(size_);
cachedTgtWeightsSum_.resize(size_);
cachedTgtMapPtr_.resize(size_);
}
}
Foam::AMICache::AMICache(const bool toSource)
:
size_(0),
rotationAxis_(Zero),
rotationCentre_(Zero),
complete_(false),
index0_(-1),
index1_(-1),
interpWeight_(0),
coordSysPtr_(nullptr),
theta_(),
cachedSrcAddress_(),
cachedSrcWeights_(),
cachedSrcWeightsSum_(),
cachedSrcMapPtr_(),
cachedTgtAddress_(),
cachedTgtWeights_(),
cachedTgtWeightsSum_(),
cachedTgtMapPtr_(),
toSource_(toSource)
{}
Foam::AMICache::AMICache(const AMICache& cache)
:
size_(cache.size_),
rotationAxis_(cache.rotationAxis_),
rotationCentre_(cache.rotationCentre_),
complete_(cache.complete_),
index0_(cache.index0_),
index1_(cache.index1_),
interpWeight_(cache.interpWeight_),
coordSysPtr_(nullptr), // Need to clone as cylindricalCS
theta_(cache.theta_),
cachedSrcAddress_(cache.cachedSrcAddress_),
cachedSrcWeights_(cache.cachedSrcWeights_),
cachedSrcWeightsSum_(cache.cachedSrcWeightsSum_),
cachedSrcMapPtr_(cache.cachedSrcMapPtr_.size()), // Need to clone
cachedTgtAddress_(cache.cachedTgtAddress_),
cachedTgtWeights_(cache.cachedTgtWeights_),
cachedTgtWeightsSum_(cache.cachedTgtWeightsSum_),
cachedTgtMapPtr_(cache.cachedTgtMapPtr_.size()), // Need to clone
toSource_(cache.toSource_)
{
if (cache.coordSysPtr_)
{
coordSysPtr_.reset(new coordSystem::cylindrical(cache.coordSysPtr_()));
}
forAll(cachedSrcMapPtr_, cachei)
{
cachedSrcMapPtr_[cachei].reset(cache.cachedSrcMapPtr_[cachei].clone());
}
forAll(cachedTgtMapPtr_, cachei)
{
cachedTgtMapPtr_[cachei].reset(cache.cachedTgtMapPtr_[cachei].clone());
}
}
Foam::AMICache::AMICache
(
const AMICache& cache,
const AMIInterpolation& fineAMI,
const labelList& sourceRestrictAddressing,
const labelList& targetRestrictAddressing
)
:
size_(cache.size_),
rotationAxis_(cache.rotationAxis_),
rotationCentre_(cache.rotationCentre_),
complete_(cache.complete_),
index0_(cache.index0_),
index1_(cache.index1_),
interpWeight_(cache.interpWeight_),
coordSysPtr_(nullptr),
theta_(cache.theta_),
cachedSrcAddress_(cache.size_),
cachedSrcWeights_(cache.size_),
cachedSrcWeightsSum_(cache.size_),
cachedSrcMapPtr_(cache.size_),
cachedTgtAddress_(cache.size_),
cachedTgtWeights_(cache.size_),
cachedTgtWeightsSum_(cache.size_),
cachedTgtMapPtr_(cache.size_),
toSource_(cache.toSource_)
{
if (size_ > 0 && fineAMI.comm() != -1)
{
for (label cachei : {index0_, index1_})
{
if (cachei == -1) continue;
scalarField dummySrcMagSf;
labelListList srcAddress;
scalarListList srcWeights;
scalarField srcWeightsSum;
autoPtr<mapDistribute> tgtMapPtr;
AMIInterpolation::agglomerate
(
cache.cachedTgtMapPtr()[cachei],
fineAMI.srcMagSf(),
cache.cachedSrcAddress()[cachei],
cache.cachedSrcWeights()[cachei],
sourceRestrictAddressing,
targetRestrictAddressing,
dummySrcMagSf,
srcAddress,
srcWeights,
srcWeightsSum,
tgtMapPtr,
fineAMI.comm()
);
scalarField dummyTgtMagSf;
labelListList tgtAddress;
scalarListList tgtWeights;
scalarField tgtWeightsSum;
autoPtr<mapDistribute> srcMapPtr;
AMIInterpolation::agglomerate
(
cache.cachedSrcMapPtr()[cachei],
fineAMI.tgtMagSf(),
cache.cachedTgtAddress()[cachei],
cache.cachedTgtWeights()[cachei],
targetRestrictAddressing,
sourceRestrictAddressing,
dummyTgtMagSf,
tgtAddress,
tgtWeights,
tgtWeightsSum,
srcMapPtr,
fineAMI.comm()
);
cachedSrcAddress_[cachei] = srcAddress;
cachedSrcWeights_[cachei] = srcWeights;
cachedSrcWeightsSum_[cachei] = srcWeightsSum;
cachedSrcMapPtr_[cachei] = srcMapPtr.clone();
cachedTgtAddress_[cachei] = tgtAddress;
cachedTgtWeights_[cachei] = tgtWeights;
cachedTgtWeightsSum_[cachei] = tgtWeightsSum;
cachedTgtMapPtr_[cachei] = tgtMapPtr.clone();
}
}
}
Foam::AMICache::AMICache(Istream& is)
:
size_(readLabel(is)),
rotationAxis_(is),
rotationCentre_(is),
complete_(readBool(is)),
index0_(-1),
index1_(-1),
interpWeight_(0),
coordSysPtr_(nullptr),
theta_(),
cachedSrcAddress_(),
cachedSrcWeights_(),
cachedSrcWeightsSum_(),
cachedSrcMapPtr_(),
cachedTgtAddress_(),
cachedTgtWeights_(),
cachedTgtWeightsSum_(),
cachedTgtMapPtr_()
{
const bitSet goodMap(is);
if (goodMap.size())
{
is >> index0_
>> index1_
>> interpWeight_
>> theta_;
const bool goodCoord(readBool(is));
if (goodCoord)
{
coordSysPtr_.reset(new coordSystem::cylindrical(is));
}
is >> cachedSrcAddress_
>> cachedSrcWeights_
>> cachedSrcWeightsSum_;
cachedSrcMapPtr_.setSize(goodMap.size());
forAll(goodMap, cachei)
{
if (goodMap[cachei])
{
cachedSrcMapPtr_[cachei].reset(new mapDistribute(is));
}
}
is >> cachedTgtAddress_
>> cachedTgtWeights_
>> cachedTgtWeightsSum_;
cachedTgtMapPtr_.setSize(goodMap.size());
forAll(goodMap, cachei)
{
if (goodMap[cachei])
{
cachedTgtMapPtr_[cachei].reset(new mapDistribute(is));
}
}
}
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
void Foam::AMICache::addToCache
(
const AMIInterpolation& ami,
const point& globalPoint
)
{
DebugPout<< "-- addToCache" << endl;
if (!active())
{
DebugInfo<< "-- addToCache - deactivated" << endl;
return;
}
if (!coordSysPtr_)
{
DebugInfo
<< "Creating rotation co-ordinate system:"
<< " rotationCentre:" << rotationCentre_
<< " rotationAxis:" << rotationAxis_
<< " p:" << globalPoint
<< endl;
coordSysPtr_.reset
(
new coordSystem::cylindrical(rotationCentre_, rotationAxis_)
);
DebugPout<< "Coord sys:" << coordSysPtr_() << endl;
}
// Check if cache is complete
if (!complete_)
{
for (const scalar angle : theta_)
{
if (angle > constant::mathematical::twoPi)
{
complete_ = false;
break;
}
}
}
if (!complete_)
{
const scalar theta = getRotationAngle(globalPoint);
const label bini = theta/constant::mathematical::twoPi*size_;
DebugPout<< " -- bini:" << bini << " for theta:" << theta << endl;
if (theta_[bini] > constant::mathematical::twoPi)
{
DebugPout<< " -- setting cache at index " << bini << endl;
// New entry
theta_[bini] = theta;
cachedSrcAddress_[bini] = ami.srcAddress();
cachedSrcWeights_[bini] = ami.srcWeights();
cachedSrcWeightsSum_[bini] = ami.srcWeightsSum();
if (ami.hasSrcMap())
{
cachedSrcMapPtr_[bini] = ami.srcMap().clone();
}
cachedTgtAddress_[bini] = ami.tgtAddress();
cachedTgtWeights_[bini] = ami.tgtWeights();
cachedTgtWeightsSum_[bini] = ami.tgtWeightsSum();
if (ami.hasTgtMap())
{
cachedTgtMapPtr_[bini] = ami.tgtMap().clone();
}
}
}
}
bool Foam::AMICache::restoreCache(const point& globalPoint)
{
DebugPout<< "-- restoreCache" << endl;
index0_ = -1;
index1_ = -1;
interpWeight_ = -1;
if (!coordSysPtr_ || size_ == -1)
{
return false;
}
const scalar theta = getRotationAngle(globalPoint);
const label bini = theta/constant::mathematical::twoPi*size_;
DebugPout<< " -- bini:" << bini << " for theta:" << theta << endl;
const auto validIndex = [&](const scalar bini)
{
return theta_[bini] < constant::mathematical::twoPi;
};
bool cacheValid = false;
if (validIndex(bini))
{
// Find participating bins
// TODO: allow skipping of bins according to user-defined max dTheta
if (mag(theta - theta_[bini]) < cacheThetaTolerance_)
{
// Hit cached value - no interpolation needed
index0_ = bini;
interpWeight_ = 0;
cacheValid = true;
}
else if (theta > theta_[bini])
{
// Check that next bin is valid
const label i1 = theta_.fcIndex(bini);
if (validIndex(i1))
{
index0_ = bini;
index1_ = i1;
cacheValid = true;
}
}
else // (theta < theta_[bini])
{
// Check that previous bin is valid
const label i1 = theta_.rcIndex(bini);
if (validIndex(i1))
{
index0_ = i1;
index1_ = bini;
cacheValid = true;
}
}
if (!cacheValid)
{
DebugPout<< " -- no cache available" << endl;
return false;
}
// Calculate weighting factor
if (index1_ != -1)
{
const scalar t0 = theta_[index0_];
scalar t1 = theta_[index1_];
if (index1_ < index0_)
{
t1 += constant::mathematical::twoPi;
}
// Set time-based weighting factor
interpWeight_ = (theta - t0)/(t1 - t0);
DebugInfo
<< " -- t0:" << t0 << " theta:" << theta << " t1:" << t1
<< " i0:" << index0_ << " i1:" << index1_
<< " w:" << interpWeight_ << endl;
}
}
else
{
DebugPout<< " -- no cache available" << endl;
}
return cacheValid;
}
void Foam::AMICache::write(Ostream& os) const
{
if (size_ > 0)
{
os.writeEntry("cacheSize", size_);
os.writeEntry("rotationAxis", rotationAxis_);
os.writeEntry("rotationCentre", rotationCentre_);
}
}
bool Foam::AMICache::writeData(Ostream& os) const
{
os << token::SPACE<< size_
<< token::SPACE<< rotationAxis_
<< token::SPACE<< rotationCentre_
<< token::SPACE<< complete_;
bitSet goodMap(cachedSrcMapPtr_.size());
forAll(goodMap, cachei)
{
goodMap.set(cachei, cachedSrcMapPtr_[cachei].good());
}
os << token::SPACE << goodMap;
if (goodMap.size())
{
os << token::SPACE << index0_
<< token::SPACE << index1_
<< token::SPACE << interpWeight_
<< token::SPACE << theta_;
os << token::SPACE << coordSysPtr_.good();
if (coordSysPtr_.good())
{
os << token::SPACE << coordSysPtr_();
}
os << token::SPACE << cachedSrcAddress_
<< token::SPACE << cachedSrcWeights_
<< token::SPACE << cachedSrcWeightsSum_;
for (const auto& index : goodMap)
{
os << token::SPACE << cachedSrcMapPtr_[index]();
}
os << token::SPACE << cachedTgtAddress_
<< token::SPACE << cachedTgtWeights_
<< token::SPACE << cachedTgtWeightsSum_;
for (const auto& index : goodMap)
{
os << token::SPACE << cachedTgtMapPtr_[index]();
}
}
return true;
}
// ************************************************************************* //

View File

@ -0,0 +1,385 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2025 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Class
Foam::AMICache
Description
Provides caching of weights and addressing to AMIInterpolation
SourceFiles
AMICache.C
SeeAlso
Foam::AMIInterpolation.H
\*---------------------------------------------------------------------------*/
#ifndef Foam_AMICache_H
#define Foam_AMICache_H
#include "cylindricalCS.H"
#include "mapDistribute.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
class AMIInterpolation;
/*---------------------------------------------------------------------------*\
Class AMICache Declaration
\*---------------------------------------------------------------------------*/
class AMICache
{
public:
// Public Data Types
//- Tolerance used when caching the AMI to identify e.g. if the
//- current rotation angle has already been captured
static scalar cacheThetaTolerance_;
static int debug;
private:
// Private Data
//- Cache size
label size_;
//- Axis of rotation for rotational cyclics
vector rotationAxis_;
//- Point on axis of rotation for rotational cyclics
point rotationCentre_;
//- Flag to indicate that the cache is complete
bool complete_;
//- Cache index 0 in lists
label index0_;
//- Cache index 1 in lists
label index1_;
//- Interpolation weight between cache indices 0 and 1
scalar interpWeight_;
//- Local co-ordinate system
autoPtr<coordSystem::cylindrical> coordSysPtr_;
//- List of cached angle snapshots
List<scalar> theta_;
//- List of source addresses
List<labelListList> cachedSrcAddress_;
//- List of source weights
List<scalarListList> cachedSrcWeights_;
//- List of source weights sums
List<scalarField> cachedSrcWeightsSum_;
//- List of source parallel maps
List<autoPtr<mapDistribute>> cachedSrcMapPtr_;
//- List of target addresses
List<labelListList> cachedTgtAddress_;
//- List of target weights
List<scalarListList> cachedTgtWeights_;
//- List of target weights sums
List<scalarField> cachedTgtWeightsSum_;
//- List of target parallel maps
List<autoPtr<mapDistribute>> cachedTgtMapPtr_;
//- Flag to indicate interpolation direction
mutable bool toSource_;
// Private Member Functions
//- Get rotation angle for point using local co-ordinate system
scalar getRotationAngle(const point& globalPoint) const;
public:
// Constructors
//- Null constructor
AMICache(const bool toSource = true);
//- Construct from dictionary
AMICache(const dictionary& dict, const bool toSource = true);
//- Construct as copy
AMICache(const AMICache& cache);
//- Construct from agglomeration of AMIInterpolation. Agglomeration
//- passed in as new coarse size and addressing from fine from coarse
AMICache
(
const AMICache& cache,
const AMIInterpolation& fineAMI,
const labelList& sourceRestrictAddressing,
const labelList& targetRestrictAddressing
);
//- Construct from stream
AMICache(Istream& is);
// Member Functions
//- Return true if cache is active
constexpr bool active() const noexcept { return size_ > 0; }
//- Return cache size
constexpr label size() const noexcept { return size_; }
//- Return true if cache is complete
constexpr bool complete() const noexcept { return complete_; }
//- Return cache lower bound index
constexpr label index0() const noexcept { return index0_; }
//- Return cache upper bound index
constexpr label index1() const noexcept { return index1_; }
//- Return cache interpolation weight
constexpr label weight() const noexcept { return interpWeight_; }
//- Return list of cached rotation angles
const List<scalar>& theta() const noexcept { return theta_; }
//- Return List of source addresses
const List<labelListList>& cachedSrcAddress() const noexcept
{
return cachedSrcAddress_;
}
//- Return List of source weights
const List<scalarListList>& cachedSrcWeights() const noexcept
{
return cachedSrcWeights_;
}
//- Return List of source weights sums
const List<scalarField>& cachedSrcWeightsSum() const noexcept
{
return cachedSrcWeightsSum_;
}
//- Return List of source parallel maps
const List<autoPtr<mapDistribute>>& cachedSrcMapPtr() const noexcept
{
return cachedSrcMapPtr_;
}
//- Return List of target addresses
const List<labelListList>& cachedTgtAddress() const noexcept
{
return cachedTgtAddress_;
}
//- Return List of target weights
const List<scalarListList>& cachedTgtWeights() const noexcept
{
return cachedTgtWeights_;
}
//- Return List of target weights sums
const List<scalarField>& cachedTgtWeightsSum() const noexcept
{
return cachedTgtWeightsSum_;
}
//- Return List of target parallel maps
const List<autoPtr<mapDistribute>>& cachedTgtMapPtr() const noexcept
{
return cachedTgtMapPtr_;
}
//- Apply cached evaluation based on user supplied evaluation function
template<class Type, class EvalFunction>
bool apply(List<Type>& result, const EvalFunction& eval) const;
//- Flag that lower bound is applicable
constexpr bool applyLower() const noexcept
{
return index0_ != -1 && index1_ == -1;
}
//- Flag that upper bound is applicable
constexpr bool applyUpper() const noexcept
{
return index0_ == -1 && index1_ != -1;
}
//- Flag that interpolation is applicable
constexpr bool applyInterpolate() const noexcept
{
return index0_ != -1 && index1_ != -1;
}
//- Set the interpolation direction
constexpr bool setDirection(bool toSource) const noexcept
{
toSource_ = toSource;
return toSource_;
}
//- Restore AMI weights and addressing from the cache
bool restoreCache(const point& globalPoint);
//- Add AMI weights and addressing to the cache
void addToCache
(
const AMIInterpolation& ami,
const point& globalPoint
);
//- Check cache index is valid
void checkIndex(const label index) const
{
if ((index < 0) || (index > size_-1))
{
FatalErrorInFunction
<< "Supplied out of bounds: " << index << "/"
<< size_ << abort(FatalError);
}
}
// Helper functions to retrieve cached values at index0 and index1
// Note: uses interpolation direction toSource_
#undef defineMethods01
#define defineMethods01(Src, Tgt, idx) \
const labelListList& c##Src##Address##idx() const \
{ \
checkIndex(index##idx##_); \
return toSource_ ? \
cached##Src##Address_[index##idx##_] \
: cached##Tgt##Address_[index##idx##_]; \
} \
const scalarListList& c##Src##Weights##idx() const \
{ \
checkIndex(index##idx##_); \
return toSource_ ? \
cached##Src##Weights_[index##idx##_] \
: cached##Tgt##Weights_[index##idx##_]; \
} \
const scalarField& c##Src##WeightsSum##idx() const \
{ \
checkIndex(index##idx##_); \
return toSource_ ? \
cached##Src##WeightsSum_[index##idx##_] \
: cached##Tgt##WeightsSum_[index##idx##_]; \
} \
const autoPtr<mapDistribute>& c##Src##MapPtr##idx() const \
{ \
checkIndex(index##idx##_); \
return toSource_ ? \
cached##Src##MapPtr_[index##idx##_] \
: cached##Tgt##MapPtr_[index##idx##_]; \
}
defineMethods01(Src, Tgt, 0)
defineMethods01(Src, Tgt, 1)
defineMethods01(Tgt, Src, 0)
defineMethods01(Tgt, Src, 1)
// Helper functions to retrieve cached values at supplied index
// Note: uses interpolation direction toSource_
#undef defineMethodsIndex
#define defineMethodsIndex(Src, Tgt) \
const labelListList& c##Src##Address(const label index) const \
{ \
checkIndex(index); \
return toSource_ ? \
cached##Src##Address_[index] \
: cached##Tgt##Address_[index]; \
} \
const scalarListList& c##Src##Weights(const label index) const \
{ \
checkIndex(index); \
return toSource_ ? \
cached##Src##Weights_[index] \
: cached##Tgt##Weights_[index]; \
} \
const scalarField& c##Src##WeightsSum(const label index) const \
{ \
checkIndex(index); \
return toSource_ ? \
cached##Src##WeightsSum_[index] \
: cached##Tgt##WeightsSum_[index]; \
} \
const autoPtr<mapDistribute>& c##Src##MapPtr(const label index) \
const \
{ \
checkIndex(index); \
return toSource_ ? \
cached##Src##MapPtr_[index] \
: cached##Tgt##MapPtr_[index]; \
}
defineMethodsIndex(Src, Tgt)
defineMethodsIndex(Tgt, Src)
// I-O
//- Write AMI as a dictionary
void write(Ostream& os) const;
//- Write AMI raw
bool writeData(Ostream& os) const;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository
#include "AMICacheTemplates.C"
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -58,110 +58,14 @@ registerOptSwitch
Foam::AMIInterpolation::useLocalComm_
);
Foam::scalar Foam::AMIInterpolation::cacheThetaTolerance_ = 1e-8;
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
Foam::scalar Foam::AMIInterpolation::getRotationAngle(const point& p) const
void Foam::AMIInterpolation::addToCache(const point& refPt)
{
if (!coordSysPtr_)
{
FatalErrorInFunction
<< "No co-ordinate system available for theta evaluation"
<< abort(FatalError);
}
scalar theta = -GREAT;
if (p != point::max)
{
theta = coordSysPtr_->localPosition(p)[1];
}
reduce(theta, maxOp<scalar>());
// Ensure 0 < theta < 2pi
if (mag(theta) < cacheThetaTolerance_)
{
theta = 0;
}
else if (theta < 0)
{
theta += constant::mathematical::twoPi;
}
return theta;
}
void Foam::AMIInterpolation::addToCache
(
const point& refPt,
const vector& rotationAxis,
const vector& rotationCentre
)
{
if (cacheSize_ == -1)
{
DebugInfo<< "-- addToCache - deactivated" << endl;
return;
}
DebugInfo<< "-- addToCache" << endl;
if (!coordSysPtr_)
{
DebugInfo
<< "Creating rotation co-ordinate system:"
<< " rotationCentre:" << rotationCentre
<< " rotationAxis:" << rotationAxis
<< " p:" << refPt
<< endl;
vector axis(normalised(refPt - rotationCentre));
coordSysPtr_.reset
(
new coordSystem::cylindrical(rotationCentre, rotationAxis, axis)
);
DebugInfo<< "Coord sys:" << coordSysPtr_() << endl;
}
// Check if cache is complete
if (!cacheComplete_)
{
forAll(cachedTheta_, i)
{
if (cachedTheta_[i] > constant::mathematical::twoPi)
{
cacheComplete_ = false;
break;
}
}
}
if (!cacheComplete_)
{
const scalar theta = getRotationAngle(refPt);
const label bini = theta/constant::mathematical::twoPi*cacheSize_;
DebugInfo<< "-- bini:" << bini << " for theta:" << theta << endl;
if (cachedTheta_[bini] > constant::mathematical::twoPi)
{
DebugInfo<< "-- setting cache at index " << bini << endl;
// New entry
cachedTheta_[bini] = theta;
cachedSrcAddress_[bini] = srcAddress_;
cachedSrcWeights_[bini] = srcWeights_;
cachedSrcWeightsSum_[bini] = srcWeightsSum_;
cachedSrcMapPtr_[bini] = srcMapPtr_.clone();
cachedTgtAddress_[bini] = tgtAddress_;
cachedTgtWeights_[bini] = tgtWeights_;
cachedTgtWeightsSum_[bini] = tgtWeightsSum_;
cachedTgtMapPtr_[bini] = tgtMapPtr_.clone();
}
}
cache_.addToCache(*this, refPt);
}
@ -169,88 +73,7 @@ bool Foam::AMIInterpolation::restoreCache(const point& refPt)
{
DebugInfo<< "-- restoreCache" << endl;
upToDate_ = false;
cachedIndex0_ = -1;
cachedIndex1_ = -1;
cachedWeight_ = -1;
if (!coordSysPtr_ || cacheSize_ == -1)
{
return upToDate_;
}
const scalar theta = getRotationAngle(refPt);
const label bini = theta/constant::mathematical::twoPi*cacheSize_;
DebugInfo<< "-- bini:" << bini << " for theta:" << theta << endl;
auto validIndex = [&](const scalar bini)
{
return cachedTheta_[bini] < constant::mathematical::twoPi;
};
if (validIndex(bini))
{
// Find participating bins
if (mag(theta - cachedTheta_[bini]) < cacheThetaTolerance_)
{
// Hit cached value - no interpolation needed
cachedIndex0_ = bini;
upToDate_ = true;
}
else if (theta > cachedTheta_[bini])
{
// Check that previous bin is valid
const label i1 = cachedTheta_.fcIndex(bini);
if (validIndex(i1))
{
cachedIndex0_ = bini;
cachedIndex1_ = i1;
upToDate_ = true;
}
}
else // (theta < cachedTheta_[bini])
{
// Check that previous bin is valid
const label i1 = cachedTheta_.rcIndex(bini);
if (validIndex(i1))
{
cachedIndex0_ = i1;
cachedIndex1_ = bini;
upToDate_ = true;
}
}
if (!upToDate_)
{
DebugInfo<< "-- no cache available" << endl;
return false;
}
// Calculate weighting factor
if (cachedIndex1_ != -1)
{
const scalar t0 = cachedTheta_[cachedIndex0_];
scalar t1 = cachedTheta_[cachedIndex1_];
if (cachedIndex1_ < cachedIndex0_)
{
t1 += constant::mathematical::twoPi;
}
// Set time-based weighting factor
cachedWeight_ = (theta - t0)/(t1 - t0);
DebugInfo
<< "-- i0:" << cachedIndex0_ << " i1:" << cachedIndex1_
<< " w:" << cachedWeight_ << endl;
}
}
else
{
DebugInfo<< " -- no cache available" << endl;
}
upToDate_ = cache_.restoreCache(refPt);
return upToDate_;
}
@ -897,35 +720,8 @@ Foam::AMIInterpolation::AMIInterpolation
tgtCentroids_(),
tgtMapPtr_(nullptr),
upToDate_(false),
cacheSize_(dict.getOrDefault<scalar>("cacheSize", -1)),
cacheComplete_(false),
cachedIndex0_(-1),
cachedIndex1_(-1),
cachedWeight_(0),
coordSysPtr_(nullptr),
cachedTheta_(),
cachedSrcAddress_(),
cachedSrcWeights_(),
cachedSrcWeightsSum_(),
cachedSrcMapPtr_(),
cachedTgtAddress_(),
cachedTgtWeights_(),
cachedTgtWeightsSum_(),
cachedTgtMapPtr_()
{
if (cacheSize_ != -1)
{
cachedTheta_.resize(cacheSize_, GREAT);
cachedSrcAddress_.resize(cacheSize_);
cachedSrcWeights_.resize(cacheSize_);
cachedSrcWeightsSum_.resize(cacheSize_);
cachedSrcMapPtr_.resize(cacheSize_);
cachedTgtAddress_.resize(cacheSize_);
cachedTgtWeights_.resize(cacheSize_);
cachedTgtWeightsSum_.resize(cacheSize_);
cachedTgtMapPtr_.resize(cacheSize_);
}
}
cache_(dict)
{}
Foam::AMIInterpolation::AMIInterpolation
@ -955,21 +751,7 @@ Foam::AMIInterpolation::AMIInterpolation
tgtPatchPts_(),
tgtMapPtr_(nullptr),
upToDate_(false),
cacheSize_(0),
cacheComplete_(false),
cachedIndex0_(-1),
cachedIndex1_(-1),
cachedWeight_(0),
coordSysPtr_(nullptr),
cachedTheta_(),
cachedSrcAddress_(),
cachedSrcWeights_(),
cachedSrcWeightsSum_(),
cachedSrcMapPtr_(),
cachedTgtAddress_(),
cachedTgtWeights_(),
cachedTgtWeightsSum_(),
cachedTgtMapPtr_()
cache_()
{}
@ -999,21 +781,7 @@ Foam::AMIInterpolation::AMIInterpolation
tgtPatchPts_(),
tgtMapPtr_(nullptr),
upToDate_(false),
cacheSize_(fineAMI.cacheSize_),
cacheComplete_(fineAMI.cacheComplete_),
cachedIndex0_(fineAMI.cachedIndex0_),
cachedIndex1_(fineAMI.cachedIndex1_),
cachedWeight_(fineAMI.cachedWeight_),
coordSysPtr_(nullptr),
cachedTheta_(fineAMI.cachedTheta_),
cachedSrcAddress_(fineAMI.cachedSrcAddress_.size()),
cachedSrcWeights_(fineAMI.cachedSrcWeights_.size()),
cachedSrcWeightsSum_(fineAMI.cachedSrcWeightsSum_.size()),
cachedSrcMapPtr_(fineAMI.cachedSrcMapPtr_.size()),
cachedTgtAddress_(fineAMI.cachedTgtAddress_.size()),
cachedTgtWeights_(fineAMI.cachedTgtWeights_.size()),
cachedTgtWeightsSum_(fineAMI.cachedTgtWeightsSum_.size()),
cachedTgtMapPtr_(fineAMI.cachedTgtMapPtr_.size())
cache_(fineAMI.cache(), fineAMI, sourceRestrictAddressing, targetRestrictAddressing)
{
const label sourceCoarseSize =
(
@ -1133,76 +901,6 @@ Foam::AMIInterpolation::AMIInterpolation
comm()
);
}
if (cacheSize_ > 0)
{
FixedList<label, 2> indices({cachedIndex0_, cachedIndex1_});
for (label cachei : indices)
{
if (cachei == -1) continue;
scalarField dummySrcMagSf;
labelListList cSrcAddress;
scalarListList cSrcWeights;
autoPtr<mapDistribute> cTgtMapPtr;
scalarField cSrcWeightsSum;
labelListList cTgtAddress;
scalarListList cTgtWeights;
autoPtr<mapDistribute> cSrcMapPtr;
scalarField cTgtWeightsSum;
agglomerate
(
fineAMI.cachedTgtMapPtr_[cachei],
fineAMI.srcMagSf(),
fineAMI.cachedSrcAddress_[cachei],
fineAMI.cachedSrcWeights_[cachei],
sourceRestrictAddressing,
targetRestrictAddressing,
dummySrcMagSf,
cSrcAddress,
cSrcWeights,
cSrcWeightsSum,
cTgtMapPtr,
comm()
);
scalarField dummyTgtMagSf;
agglomerate
(
fineAMI.cachedSrcMapPtr_[cachei],
fineAMI.tgtMagSf(),
fineAMI.cachedTgtAddress_[cachei],
fineAMI.cachedTgtWeights_[cachei],
targetRestrictAddressing,
sourceRestrictAddressing,
dummyTgtMagSf,
cTgtAddress,
cTgtWeights,
cTgtWeightsSum,
cSrcMapPtr,
comm()
);
cachedSrcAddress_[cachei] = cSrcAddress;
cachedSrcWeights_[cachei] = cSrcWeights;
cachedSrcWeightsSum_[cachei] = cSrcWeightsSum;
cachedSrcMapPtr_[cachei] = cSrcMapPtr.clone();
cachedTgtAddress_[cachei] = cTgtAddress;
cachedTgtWeights_[cachei] = cTgtWeights;
cachedTgtWeightsSum_[cachei] = cTgtWeightsSum;
cachedTgtMapPtr_[cachei] = cTgtMapPtr.clone();
}
}
}
@ -1227,32 +925,8 @@ Foam::AMIInterpolation::AMIInterpolation(const AMIInterpolation& ami)
tgtCentroids_(ami.tgtCentroids_),
tgtMapPtr_(ami.tgtMapPtr_.clone()),
upToDate_(ami.upToDate_),
cacheSize_(ami.cacheSize_),
cacheComplete_(ami.cacheComplete_),
cachedIndex0_(ami.cachedIndex0_),
cachedIndex1_(ami.cachedIndex1_),
cachedWeight_(ami.cachedWeight_),
coordSysPtr_(nullptr), // TODO: ami.coordSysPtr_.clone()),
cachedTheta_(ami.cachedTheta_),
cachedSrcAddress_(ami.cachedSrcAddress_),
cachedSrcWeights_(ami.cachedSrcWeights_),
cachedSrcWeightsSum_(ami.cachedSrcWeightsSum_),
cachedSrcMapPtr_(ami.cachedSrcMapPtr_.size()), // Need to clone
cachedTgtAddress_(ami.cachedTgtAddress_),
cachedTgtWeights_(ami.cachedTgtWeights_),
cachedTgtWeightsSum_(ami.cachedTgtWeightsSum_),
cachedTgtMapPtr_(ami.cachedTgtMapPtr_.size()) // Need to clone
{
forAll(cachedSrcMapPtr_, cachei)
{
cachedSrcMapPtr_[cachei].reset(ami.cachedSrcMapPtr_[cachei].clone());
}
forAll(cachedTgtMapPtr_, cachei)
{
cachedTgtMapPtr_[cachei].reset(ami.cachedTgtMapPtr_[cachei].clone());
}
}
cache_(ami.cache_)
{}
Foam::AMIInterpolation::AMIInterpolation(Istream& is)
@ -1281,22 +955,7 @@ Foam::AMIInterpolation::AMIInterpolation(Istream& is)
upToDate_(readBool(is)),
cacheSize_(readLabel(is)),
cacheComplete_(readBool(is)),
cachedIndex0_(-1),
cachedIndex1_(-1),
cachedWeight_(0),
coordSysPtr_(nullptr),
cachedTheta_(),
cachedSrcAddress_(),
cachedSrcWeights_(),
cachedSrcWeightsSum_(),
cachedSrcMapPtr_(),
cachedTgtAddress_(),
cachedTgtWeights_(),
cachedTgtWeightsSum_(),
cachedTgtMapPtr_()
cache_(is)
{
// Hopefully no need to stream geomComm_ since only used in processor
// agglomeration?
@ -1306,51 +965,6 @@ Foam::AMIInterpolation::AMIInterpolation(Istream& is)
srcMapPtr_.reset(new mapDistribute(is));
tgtMapPtr_.reset(new mapDistribute(is));
}
// Caching
const bitSet goodMap(is);
if (goodMap.size())
{
is >> cachedIndex0_
>> cachedIndex1_
>> cachedWeight_
>> cachedTheta_;
const bool goodCoord(readBool(is));
if (goodCoord)
{
coordSysPtr_.reset(new coordSystem::cylindrical(is));
}
is >> cachedSrcAddress_
>> cachedSrcWeights_
>> cachedSrcWeightsSum_;
cachedSrcMapPtr_.setSize(goodMap.size());
forAll(goodMap, cachei)
{
if (goodMap[cachei])
{
cachedSrcMapPtr_[cachei].reset(new mapDistribute(is));
}
}
is >> cachedTgtAddress_
>> cachedTgtWeights_
>> cachedTgtWeightsSum_;
cachedTgtMapPtr_.setSize(goodMap.size());
forAll(goodMap, cachei)
{
if (goodMap[cachei])
{
cachedTgtMapPtr_[cachei].reset(new mapDistribute(is));
}
}
}
}
@ -1950,10 +1564,7 @@ void Foam::AMIInterpolation::write(Ostream& os) const
os.writeEntry("lowWeightCorrection", lowWeightCorrection_);
}
if (cacheSize_ > 0)
{
os.writeEntry("cacheSize", cacheSize_);
}
cache_.write(os);
}
@ -1977,11 +1588,9 @@ bool Foam::AMIInterpolation::writeData(Ostream& os) const
<< token::SPACE<< tgtWeightsSum()
<< token::SPACE<< tgtCentroids_
<< token::SPACE<< upToDate()
<< token::SPACE<< cacheSize_
<< token::SPACE<< cacheComplete_;
<< token::SPACE<< upToDate();
cache_.writeData(os);
if (distributed() && comm() != -1)
{
@ -1989,45 +1598,6 @@ bool Foam::AMIInterpolation::writeData(Ostream& os) const
<< token::SPACE<< tgtMap();
}
bitSet goodMap(cachedSrcMapPtr_.size());
forAll(goodMap, cachei)
{
goodMap.set(cachei, cachedSrcMapPtr_[cachei].good());
}
os << token::SPACE << goodMap;
os << token::SPACE << cachedIndex0_
<< token::SPACE << cachedIndex1_
<< token::SPACE << cachedWeight_
<< token::SPACE << cachedTheta_;
os << token::SPACE << coordSysPtr_.good();
if (coordSysPtr_.good())
{
os << token::SPACE << coordSysPtr_();
}
os << token::SPACE << cachedSrcAddress_
<< token::SPACE << cachedSrcWeights_
<< token::SPACE << cachedSrcWeightsSum_;
for (const auto& index : goodMap)
{
os << token::SPACE << cachedSrcMapPtr_[index]();
}
os << token::SPACE << cachedTgtAddress_
<< token::SPACE << cachedTgtWeights_
<< token::SPACE << cachedTgtWeightsSum_;
for (const auto& index : goodMap)
{
os << token::SPACE << cachedTgtMapPtr_[index]();
}
return os.good();
}

View File

@ -61,7 +61,7 @@ SourceFiles
#include "indexedOctree.H"
#include "treeDataPrimitivePatch.H"
#include "runTimeSelectionTables.H"
#include "cylindricalCS.H"
#include "AMICache.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -181,27 +181,8 @@ protected:
//- Up-to-date flag
bool upToDate_;
// Cache
label cacheSize_;
bool cacheComplete_;
label cachedIndex0_;
label cachedIndex1_;
scalar cachedWeight_;
autoPtr<coordSystem::cylindrical> coordSysPtr_;
List<scalar> cachedTheta_;
//-
List<labelListList> cachedSrcAddress_;
List<scalarListList> cachedSrcWeights_;
List<scalarField> cachedSrcWeightsSum_;
List<autoPtr<mapDistribute>> cachedSrcMapPtr_;
List<labelListList> cachedTgtAddress_;
List<scalarListList> cachedTgtWeights_;
List<scalarField> cachedTgtWeightsSum_;
List<autoPtr<mapDistribute>> cachedTgtMapPtr_;
//- Cache
AMICache cache_;
// Protected Member Functions
@ -245,9 +226,6 @@ protected:
//- Return the original tgt patch with optionally updated points
inline const primitivePatch& tgtPatch0() const;
//- Get rotation angle for cached AMI cases
scalar getRotationAngle(const point& p) const;
// Evaluation
@ -270,27 +248,6 @@ protected:
);
// Constructor helpers
static void agglomerate
(
const autoPtr<mapDistribute>& targetMap,
const scalarList& fineSrcMagSf,
const labelListList& fineSrcAddress,
const scalarListList& fineSrcWeights,
const labelList& sourceRestrictAddressing,
const labelList& targetRestrictAddressing,
scalarList& srcMagSf,
labelListList& srcAddress,
scalarListList& srcWeights,
scalarField& srcWeightsSum,
autoPtr<mapDistribute>& tgtMap,
const label comm
);
public:
//- Runtime type information
@ -396,6 +353,26 @@ public:
// Member Functions
// Constructor helpers
static void agglomerate
(
const autoPtr<mapDistribute>& targetMap,
const scalarList& fineSrcMagSf,
const labelListList& fineSrcAddress,
const scalarListList& fineSrcWeights,
const labelList& sourceRestrictAddressing,
const labelList& targetRestrictAddressing,
scalarList& srcMagSf,
labelListList& srcAddress,
scalarListList& srcWeights,
scalarField& srcWeightsSum,
autoPtr<mapDistribute>& tgtMap,
const label comm
);
// Access
//- Is up-to-date?
@ -409,6 +386,10 @@ public:
return old;
}
//- Return a reference to the AMI cache
const AMICache& cache() const noexcept { return cache_; }
AMICache& cache() noexcept { return cache_; }
//- Distributed across processors (singlePatchProc == -1)
inline bool distributed() const noexcept;
@ -723,12 +704,7 @@ public:
bool restoreCache(const point& refPt);
//- Add AMI weights and addressing to the cache
void addToCache
(
const point& refPt,
const vector& rotationAxis,
const vector& rotationCentre
);
void addToCache(const point& refPt);
// Checks

View File

@ -122,9 +122,10 @@ inline Foam::label Foam::AMIInterpolation::comm(label communicator) noexcept
return old;
}
inline bool Foam::AMIInterpolation::cacheActive() const
{
return cacheSize_ > 0;
return cache_.active();
}

View File

@ -89,23 +89,15 @@ void Foam::AMIInterpolation::weightedSum
const UList<Type>& defaultValues
) const
{
const auto& cAddress = (toSource ? cachedSrcAddress_ : cachedTgtAddress_);
const auto& cWeights = (toSource ? cachedSrcWeights_ : cachedTgtWeights_);
const auto& cWeightsSum =
(
toSource
? cachedSrcWeightsSum_
: cachedTgtWeightsSum_
);
cache_.setDirection(toSource);
auto wsum = [&](List<Type>& res, const label i){
const auto wsum = [&](List<Type>& res, const label i){
weightedSum
(
lowWeightCorrection_,
cAddress[i],
cWeights[i],
cWeightsSum[i],
cache_.cSrcAddress(i),
cache_.cSrcWeights(i),
cache_.cSrcWeightsSum(i),
fld,
multiplyWeightedOp<Type, plusEqOp<Type>>(plusEqOp<Type>()),
res,
@ -113,28 +105,7 @@ void Foam::AMIInterpolation::weightedSum
);
};
if (cachedIndex0_ != -1 && cachedIndex1_ == -1)
{
wsum(result, cachedIndex0_);
}
else if (cachedIndex0_ == -1 && cachedIndex1_ != -1)
{
wsum(result, cachedIndex1_);
}
else if (cachedIndex0_ != -1 && cachedIndex1_ != -1)
{
List<Type> r0(result);
wsum(r0, cachedIndex0_);
List<Type> r1(result);
wsum(r1, cachedIndex1_);
//result = (r1 - r0)*cachedWeight_ + r0;
forAll(result, i)
{
result[i] = lerp(r0[i], r1[i], cachedWeight_);
}
}
else
if (!cache_.apply(result, wsum))
{
// Both -1 => equates to non-caching
weightedSum
@ -169,6 +140,8 @@ void Foam::AMIInterpolation::interpolate
addProfiling(ami, "AMIInterpolation::interpolate");
cache_.setDirection(toSource);
auto checkSizes = [&](
const UList<Type>& fld,
const labelListList& srcAddr,
@ -209,53 +182,27 @@ void Foam::AMIInterpolation::interpolate
// Work space for if distributed
List<Type> work;
List<Type> result0;
if (cachedIndex0_ != -1)
if (cache_.index0() != -1)
{
result0 = result;
const auto& srcAddress =
(
toSource
? cachedSrcAddress_[cachedIndex0_]
: cachedTgtAddress_[cachedIndex0_]
);
const auto& srcWeights =
(
toSource
? cachedSrcWeights_[cachedIndex0_]
: cachedTgtWeights_[cachedIndex0_]
);
const auto& srcWeightsSum =
(
toSource
? cachedSrcWeightsSum_[cachedIndex0_]
: cachedTgtWeightsSum_[cachedIndex0_]
);
const auto& tgtAddress =
(
toSource
? cachedTgtAddress_[cachedIndex0_]
: cachedSrcAddress_[cachedIndex0_]
);
const auto& srcAddress = cache_.cSrcAddress0();
const auto& srcWeights = cache_.cSrcWeights0();
const auto& srcWeightsSum = cache_.cSrcWeightsSum0();
const auto& tgtAddress = cache_.cTgtAddress0();
checkSizes(fld, srcAddress, tgtAddress, defaultValues);
if (distributed())
if (distributed() && cache_.cTgtMapPtr0())
{
const mapDistribute& map =
(
toSource
? cachedTgtMapPtr_[cachedIndex0_]()
: cachedSrcMapPtr_[cachedIndex0_]()
);
const mapDistribute& map = cache_.cTgtMapPtr0()();
if (map.comm() == -1)
{
return;
}
work.resize_nocopy(map.constructSize());
SubList<Type>(work, fld.size()) = fld; // deep copy
map.distribute(work);
@ -276,45 +223,20 @@ void Foam::AMIInterpolation::interpolate
}
List<Type> result1;
if (cachedIndex1_ != -1)
if (cache_.index1() != -1)
{
result1 = result;
const auto& srcAddress =
(
toSource
? cachedSrcAddress_[cachedIndex1_]
: cachedTgtAddress_[cachedIndex1_]
);
const auto& srcWeights =
(
toSource
? cachedSrcWeights_[cachedIndex1_]
: cachedTgtWeights_[cachedIndex1_]
);
const auto& srcWeightsSum =
(
toSource
? cachedSrcWeightsSum_[cachedIndex1_]
: cachedTgtWeightsSum_[cachedIndex1_]
);
const auto& tgtAddress =
(
toSource
? cachedTgtAddress_[cachedIndex1_]
: cachedSrcAddress_[cachedIndex1_]
);
const auto& srcAddress = cache_.cSrcAddress1();
const auto& srcWeights = cache_.cSrcWeights1();
const auto& srcWeightsSum = cache_.cSrcWeightsSum1();
const auto& tgtAddress = cache_.cTgtAddress1();
checkSizes(fld, srcAddress, tgtAddress, defaultValues);
if (distributed())
if (distributed() && cache_.cTgtMapPtr1())
{
const mapDistribute& map =
(
toSource
? cachedTgtMapPtr_[cachedIndex1_]()
: cachedSrcMapPtr_[cachedIndex1_]()
);
const mapDistribute& map = cache_.cTgtMapPtr1()();
if (map.comm() == -1)
{
@ -340,19 +262,19 @@ void Foam::AMIInterpolation::interpolate
);
}
if (cachedIndex0_ != -1 && cachedIndex1_ == -1)
if (cache_.applyLower())
{
result = result0;
}
else if (cachedIndex0_ == -1 && cachedIndex1_ != -1)
else if (cache_.applyUpper())
{
result = result1;
}
else if (cachedIndex0_ != -1 && cachedIndex1_ != -1)
else if (cache_.applyInterpolate())
{
forAll(result, i)
{
iop(result[i], i, i, result0[i], i, result1[i], cachedWeight_);
iop(result[i], i, i, result0[i], i, result1[i], cache_.weight());
}
}
else

View File

@ -386,6 +386,8 @@ void Foam::cyclicAMIPolyPatch::resetAMI(const UList<point>& points) const
bool restoredFromCache = false;
if (AMIPtr_->cacheActive())
{
const label comm = boundaryMesh().mesh().comm();
if (UPstream::parRun())
{
label refProci = -1;
@ -393,13 +395,13 @@ void Foam::cyclicAMIPolyPatch::resetAMI(const UList<point>& points) const
{
refProci = UPstream::myProcNo();
}
reduce(refProci, maxOp<label>());
reduce(refProci, maxOp<label>(), UPstream::msgType(), comm);
if (refProci == UPstream::myProcNo())
{
refPt = points[meshPoints()[0]];
}
reduce(refPt, minOp<point>());
reduce(refPt, minOp<point>(), UPstream::msgType(), comm);
}
else
{
@ -410,14 +412,13 @@ void Foam::cyclicAMIPolyPatch::resetAMI(const UList<point>& points) const
// Sets cache indices to use and time interpolation weight
restoredFromCache = AMIPtr_->restoreCache(refPt);
if (returnReduce(restoredFromCache, orOp<bool>()))
if (returnReduceOr(restoredFromCache, comm))
{
// Restored AMI weight and addressing from cache - all done
return;
}
}
const cyclicAMIPolyPatch& nbr = neighbPatch();
const pointField srcPoints(points, meshPoints());
pointField nbrPoints(points, nbr.meshPoints());
@ -484,7 +485,7 @@ void Foam::cyclicAMIPolyPatch::resetAMI(const UList<point>& points) const
AMIPtr_->checkSymmetricWeights(true);
}
AMIPtr_->addToCache(refPt, rotationAxis_, rotationCentre_);
AMIPtr_->addToCache(refPt);
}
@ -791,13 +792,6 @@ Foam::cyclicAMIPolyPatch::cyclicAMIPolyPatch
tgtFaceIDs_.setSize(dict.get<label>("tgtSize"));
moveFaceCentres_ = dict.getOrDefault("moveFaceCentres", true);
}
if (AMIPtr_->cacheActive() && transform() != ROTATIONAL)
{
FatalErrorInFunction
<< "AMI Caching is only available for rotational transforms"
<< exit(FatalError);
}
}

View File

@ -281,6 +281,7 @@ processorLOD/faceBox/faceBox.C
AMI=AMIInterpolation
$(AMI)/AMIInterpolation/AMIInterpolation.C
$(AMI)/AMIInterpolation/AMIInterpolationNew.C
$(AMI)/AMIInterpolation/AMICache.C
$(AMI)/AMIInterpolation/advancingFrontAMI/advancingFrontAMI.C
$(AMI)/AMIInterpolation/advancingFrontAMI/advancingFrontAMIParallelOps.C
$(AMI)/AMIInterpolation/faceAreaWeightAMI/faceAreaWeightAMI.C