Compare commits

..

1 Commits

Author SHA1 Message Date
7b7229fc13 ENH: integrate memory pool support for List allocations
- provides an optional memory management using a memory pool.
  Currently can support Umpire (https://github.com/LLNL/Umpire)

  When available, its use can be controlled by the FOAM_MEMORY_POOL
  environment variable, or the memory_pool Optimisation switch
  (etc/controlDict).

Notes:

  Use of the memory-pool is controlled by the 'is_aligned_type()' test
  and the minimum field size, controlled by the 'use_memory_pool()' test.

  If the memory-pool is not enabled or not required according to the two
  above tests, the allocation falls back to either an aligned or unaligned
  allocation (depending on the field size).

  The thresholds for aligned, unaligned, memory-pool allocation
  are still a compile-time option. Made by direct edit of the
  corrsponding functions.
2025-05-22 16:22:09 +02:00
122 changed files with 2235 additions and 1269 deletions

View File

@ -1,2 +1,2 @@
api=2502
api=2501
patch=0

View File

@ -210,7 +210,6 @@ autoPtr<labelIOList> faProcAddressing
// Return cached or read proc addressing from facesInstance
FOAM_NO_DANGLING_REFERENCE
const labelIOList& procAddressing
(
const PtrList<fvMesh>& procMeshList,

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2017 OpenFOAM Foundation
Copyright (C) 2018-2025 OpenCFD Ltd.
Copyright (C) 2018-2023 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -39,23 +39,74 @@ namespace Foam
{
template<class Type>
void evaluateConstraintTypes
(
GeometricField<Type, fvPatchField, volMesh>& fld
)
void evaluateConstraintTypes(GeometricField<Type, fvPatchField, volMesh>& fld)
{
fld.boundaryFieldRef().evaluate_if
auto& bfld = fld.boundaryFieldRef();
const UPstream::commsTypes commsType = UPstream::defaultCommsType;
if
(
[](const auto& pfld) -> bool
commsType == UPstream::commsTypes::buffered
|| commsType == UPstream::commsTypes::nonBlocking
)
{
const label startOfRequests = UPstream::nRequests();
for (auto& pfld : bfld)
{
return
if
(
pfld.type() == pfld.patch().patch().type()
&& polyPatch::constraintType(pfld.patch().patch().type())
);
},
UPstream::defaultCommsType
);
)
{
pfld.initEvaluate(commsType);
}
}
// Wait for outstanding requests (non-blocking)
UPstream::waitRequests(startOfRequests);
for (auto& pfld : bfld)
{
if
(
pfld.type() == pfld.patch().patch().type()
&& polyPatch::constraintType(pfld.patch().patch().type())
)
{
pfld.evaluate(commsType);
}
}
}
else if (commsType == UPstream::commsTypes::scheduled)
{
const lduSchedule& patchSchedule =
fld.mesh().globalData().patchSchedule();
for (const auto& schedEval : patchSchedule)
{
const label patchi = schedEval.patch;
auto& pfld = bfld[patchi];
if
(
pfld.type() == pfld.patch().patch().type()
&& polyPatch::constraintType(pfld.patch().patch().type())
)
{
if (schedEval.init)
{
pfld.initEvaluate(commsType);
}
else
{
pfld.evaluate(commsType);
}
}
}
}
}

View File

@ -132,6 +132,11 @@ projectDir="$HOME/OpenFOAM/OpenFOAM-$WM_PROJECT_VERSION"
# projectDir="@PROJECT_DIR@"
: # Safety statement (if the user removed all fallback values)
# [FOAM_MEMORY_POOL] - Optional memory management
# - overrides the 'memory_pool' etc/controlDict entry
# = "true | false | host [size=nn] [incr=nn]"
#export FOAM_MEMORY_POOL="host"
# [FOAM_SIGFPE] - Trap floating-point exceptions.
# - overrides the 'trapFpe' controlDict entry
# = true | false

View File

@ -221,6 +221,9 @@ OptimisationSwitches
// Other
// =====
// Optional memory management (sizing in MB)
// memory_pool "host; size=1024; incr=5"
// Trap floating point exception.
// Can override with FOAM_SIGFPE env variable (true|false)
trapFpe 1;

View File

@ -134,6 +134,11 @@ set projectDir=`lsof +p $$ |& sed -ne 's#^[^/]*##;\@/'"$projectName"'[^/]*/etc/c
# Or optionally hard-coded (eg, with autoconfig)
# set projectDir="@PROJECT_DIR@"
# [FOAM_MEMORY_POOL] - Optional memory management
# - overrides the 'memory_pool' etc/controlDict entry
# = "true | false | host [size=nn] [incr=nn]"
#setenv FOAM_MEMORY_POOL "host"
# [FOAM_SIGFPE] - Trap floating-point exceptions.
# - overrides the 'trapFpe' controlDict entry
# = true | false

View File

@ -3,6 +3,8 @@ MSwindows.C
cpuInfo/cpuInfo.C
memInfo/memInfo.C
memory/MemoryPool.cxx
signals/sigFpe.cxx
signals/sigInt.cxx
signals/sigQuit.cxx

View File

@ -0,0 +1,83 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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 "MemoryPool.H"
// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
// bool Foam::MemoryPool::create(const std::string& ctrl, bool verbose)
// {
// return false;
// }
bool Foam::MemoryPool::create(bool verbose)
{
// No banner information since it is currently never an option
return false;
}
void Foam::MemoryPool::destroy(bool verbose)
{}
bool Foam::MemoryPool::active() noexcept
{
return false;
}
bool Foam::MemoryPool::suspend() noexcept
{
return false;
}
void Foam::MemoryPool::resume() noexcept
{}
bool Foam::MemoryPool::is_pool(void* ptr)
{
return false;
}
void* Foam::MemoryPool::try_allocate(std::size_t nbytes)
{
return nullptr;
}
bool Foam::MemoryPool::try_deallocate(void* ptr)
{
return (!ptr);
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View File

@ -2,6 +2,7 @@
cd "${0%/*}" || exit # Run from this directory
targetType=libo # Preferred library type
. ${WM_PROJECT_DIR:?}/wmake/scripts/AllwmakeParseArguments $*
. ${WM_PROJECT_DIR:?}/wmake/scripts/have_umpire
#------------------------------------------------------------------------------
# Hack for MacOS (with Gcc).
@ -59,6 +60,47 @@ then
export COMP_FLAGS="-DFOAM_USE_INOTIFY"
fi
#------------------------------------------------------------------------------
# Have -lumpire, but also -lcamp etc.
# Also need to follow the link order
get_umpire_libs()
{
if [ -d "${UMPIRE_LIB_DIR}" ]
then
set -- $(
# Expected link order
for name in umpire fmt camp
do
[ -f "$UMPIRE_LIB_DIR/lib${name}.a" ] && echo "-l$name"
done
)
echo "$@"
else
echo
fi
}
if have_umpire
then
libNames="$(get_umpire_libs)"
if [ -n "$libNames" ]
then
echo " found umpire -- enabling memory pool interface" 1>&2
echo " umpire libs: $libNames" 1>&2
COMP_FLAGS="$COMP_FLAGS -DFOAM_USE_UMPIRE -I${UMPIRE_INC_DIR}"
LINK_FLAGS="$LINK_FLAGS -L${UMPIRE_LIB_DIR} $libNames"
export COMP_FLAGS LINK_FLAGS
else
echo " expecting umpire, but did not resolve the libraries" 1>&2
fi
fi
#------------------------------------------------------------------------------
# Make object (non-shared by default)
# Never want/need openmp, especially for static objects
wmake -no-openmp $targetType

View File

@ -4,6 +4,8 @@ cpuInfo/cpuInfo.C
cpuTime/cpuTimePosix.C
memInfo/memInfo.C
memory/MemoryPool.cxx
signals/sigFpe.cxx
signals/sigSegv.cxx
signals/sigInt.cxx

View File

@ -1 +1,4 @@
EXE_INC = $(COMP_FLAGS)
/* umpire uses old-style cast etc */
EXE_INC = $(COMP_FLAGS) $(c++LESSWARN)
LIBO_LIBS = $(LINK_FLAGS)

View File

@ -0,0 +1,510 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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 "MemoryPool.H"
#include "debug.H"
#include "dictionary.H"
#include "sigFpe.H"
#include "OSspecific.H" // For getEnv
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
#ifdef FOAM_USE_UMPIRE
// #include <cerrno>
#include <cinttypes>
#include <tuple>
#include "umpire/Allocator.hpp"
#include "umpire/ResourceManager.hpp"
#include "umpire/strategy/AlignedAllocator.hpp"
#include "umpire/strategy/DynamicPoolList.hpp"
static bool disabled_(false);
static umpire::Allocator aligned_allocator;
static umpire::Allocator pooled_allocator;
static umpire::ResourceManager* manager_(nullptr);
static umpire::ResourceManager* suspended_(nullptr);
#endif
// * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
#ifdef FOAM_USE_UMPIRE
namespace
{
// Different supported allocation types
enum class Types { undefined, none, host, device, managed };
typedef std::tuple<Types, std::size_t, std::size_t> ctrlTuple;
// Extract key=INT, the key includes the '='
int getIntParameter(const std::string& key, const std::string& ctrl)
{
int val(0);
const auto pos = ctrl.find(key);
if (pos == std::string::npos)
{
return val;
}
const char* buf = (ctrl.data() + pos + key.size());
char *endptr = nullptr;
errno = 0;
auto parsed = std::strtoimax(buf, &endptr, 10);
if (errno || endptr == buf)
{
// Some type of error OR no conversion
}
else
{
val = int(parsed);
}
return val;
}
ctrlTuple getControlValues(const std::string& ctrl)
{
ctrlTuple result(Types::undefined, 0, 0);
bool checkParam = false;
// Also find things that look like Switch constants.
// Unfortunately need to do this manually since Switch::find()
// itself would not manage to parse something like "true; size=10"
if (ctrl.empty())
{
// Nothing => undefined
}
else if
(
std::string::npos != ctrl.find("false") // ctrl.contains("false")
|| std::string::npos != ctrl.find("off") // ctrl.contains("off")
|| std::string::npos != ctrl.find("no") // ctrl.contains("no")
|| std::string::npos != ctrl.find("none") // ctrl.contains("none")
)
{
std::get<0>(result) = Types::none;
}
else if
(
std::string::npos != ctrl.find("true") // ctrl.contains("true")
|| std::string::npos != ctrl.find("on") // ctrl.contains("on")
|| std::string::npos != ctrl.find("yes") // ctrl.contains("yes")
|| std::string::npos != ctrl.find("host") // ctrl.contains("host")
|| std::string::npos != ctrl.find("system") // ctrl.contains("system")
)
{
std::get<0>(result) = Types::host;
checkParam = true;
}
// These need more testing
else if
(
std::string::npos != ctrl.find("device") // ctrl.contains("device")
)
{
std::get<0>(result) = Types::device;
checkParam = true;
}
else if
(
std::string::npos != ctrl.find("managed") // ctrl.contains("managed")
)
{
std::get<0>(result) = Types::managed;
checkParam = true;
}
if (checkParam)
{
std::get<1>(result) = getIntParameter("size=", ctrl);
std::get<2>(result) = getIntParameter("incr=", ctrl);
}
return result;
}
bool create_from(const ctrlTuple& controls, bool verbose)
{
using namespace Foam;
if (manager_ || suspended_)
{
// Already created
return true;
}
// Type, initial size, increment
auto [which, size, incr] = controls;
// std::cerr
// << "which=" << int(which)
// << ", size=" << int(size)
// << ", incr=" << int(incr) << '\n';
constexpr size_t MegaByte(1024*1024);
switch (which)
{
case Types::undefined :
{
if (verbose)
{
Info<< "memory pool : unused" << nl;
}
break;
}
case Types::none :
{
if (verbose)
{
Info<< "memory pool : disabled" << nl;
}
break;
}
case Types::host :
{
// Default sizing parameters
if (!size) size = 1024;
if (!incr) incr = 5;
auto& rm = umpire::ResourceManager::getInstance();
manager_ = &rm;
aligned_allocator =
rm.makeAllocator<umpire::strategy::AlignedAllocator>
(
"aligned_allocator",
rm.getAllocator("HOST"),
// alignment
256
);
pooled_allocator =
rm.makeAllocator<umpire::strategy::DynamicPoolList>
(
"openfoam_HOST_pool",
aligned_allocator,
// initial block allocation size
(size*MegaByte),
// incremental block allocation size
(incr*MegaByte)
);
if (verbose)
{
Info<< "memory pool : host (size="
<< int(size) << "MB, incr="
<< int(incr) << "MB)\n";
}
break;
}
case Types::device :
{
auto& rm = umpire::ResourceManager::getInstance();
manager_ = &rm;
aligned_allocator = rm.getAllocator("DEVICE");
pooled_allocator =
rm.makeAllocator<umpire::strategy::DynamicPoolList>
(
"openfoam_DEVICE_pool",
aligned_allocator
);
if (verbose)
{
Info<< "memory pool : device" << nl;
}
break;
}
case Types::managed :
{
// Default sizing parameters
if (!size) size = 10*1024;
if (!incr) incr = 10;
auto& rm = umpire::ResourceManager::getInstance();
manager_ = &rm;
aligned_allocator = rm.getAllocator("UM");
pooled_allocator =
rm.makeAllocator<umpire::strategy::DynamicPoolList>
(
"openfoam_UM_pool",
aligned_allocator,
// initial block allocation size
(size*MegaByte),
// incremental block allocation size
(incr*MegaByte)
);
if (verbose)
{
Info<< "memory pool : managed (size="
<< int(size) << "MB, incr="
<< int(incr) << "MB)\n";
}
break;
}
}
return (which != Types::undefined && which != Types::none);
}
} // End anonymous namespace
#endif // FOAM_USE_UMPIRE
// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
// bool Foam::MemoryPool::create(const std::string& ctrl, bool verbose)
// {
// #ifdef FOAM_USE_UMPIRE
// if (manager_ || suspended_)
// {
// // Already created
// return true;
// }
//
// auto controls = getControlValues(ctrl);
//
// return create_from(controls, verbose);
// #else
// return false;
// #endif
// }
bool Foam::MemoryPool::create(bool verbose)
{
#ifdef FOAM_USE_UMPIRE
if (disabled_)
{
// Disallowed
return false;
}
else if (manager_ || suspended_)
{
// Already created
return true;
}
// First check environment
auto controls = getControlValues(Foam::getEnv("FOAM_MEMORY_POOL"));
if (std::get<0>(controls) == Types::none)
{
// Disabled from environment - has highest priority
disabled_ = true;
}
// Currently no easy way to handle <system>/controlDict...
// Fallback from etc/controlDict
if (std::get<0>(controls) == Types::undefined)
{
// From central etc/controlDict
const auto& dict = Foam::debug::optimisationSwitches();
if (auto* eptr = dict.findStream("memory_pool", keyType::LITERAL))
{
const token& firstToken = eptr->front();
if (firstToken.isStringType())
{
controls = getControlValues(firstToken.stringToken());
}
}
}
return create_from(controls, verbose);
#else
if (verbose)
{
Info<< "memory pool : not available" << nl;
}
return false;
#endif
}
void Foam::MemoryPool::destroy(bool verbose)
{
// Nothing currently needed but could add in something like this:
// if (manager_ || suspended_)
// {
// pooled_allocator.release();
// }
// However, need to find the proper sequence within
// Foam::exit() or UPstream::exit() ...
}
bool Foam::MemoryPool::active() noexcept
{
#ifdef FOAM_USE_UMPIRE
return bool(manager_);
#else
return false;
#endif
}
bool Foam::MemoryPool::suspend() noexcept
{
#ifdef FOAM_USE_UMPIRE
bool status(suspended_);
if (manager_) // <- and (!suspended_)
{
std::swap(manager_, suspended_);
}
return status;
#else
return false;
#endif
}
void Foam::MemoryPool::resume() noexcept
{
#ifdef FOAM_USE_UMPIRE
if (suspended_) // <- and (!manager_)
{
std::swap(manager_, suspended_);
}
#endif
}
bool Foam::MemoryPool::is_pool(void* ptr)
{
#ifdef FOAM_USE_UMPIRE
if (ptr)
{
if (manager_)
{
return manager_->hasAllocator(ptr);
}
else if (suspended_)
{
return suspended_->hasAllocator(ptr);
}
}
#endif
return false;
}
void* Foam::MemoryPool::try_allocate(std::size_t nbytes)
{
void* ptr = nullptr;
#ifdef FOAM_USE_UMPIRE
if (manager_)
{
ptr = pooled_allocator.allocate(nbytes);
// std::cerr<< "allocate(" << int(nbytes) << ")\n";
// Optionally fill with NaN (depends on current flags)
Foam::sigFpe::fillNan_if(ptr, nbytes);
if (!ptr)
{
// Pout<< "umpire failed to allocate memory\n";
}
}
#endif
return ptr;
}
bool Foam::MemoryPool::try_deallocate(void* ptr)
{
#ifdef FOAM_USE_UMPIRE
if (ptr)
{
if (manager_)
{
if (manager_->hasAllocator(ptr)) // <- ie, is_pool()
{
// std::cerr<< "deallocate()\n";
manager_->deallocate(ptr);
return true;
}
}
else if (suspended_)
{
// Deallocate even if nominally suspended
if (suspended_->hasAllocator(ptr)) // <- ie, is_pool()
{
// std::cerr<< "deallocate()\n";
suspended_->deallocate(ptr);
return true;
}
}
}
#endif
return (!ptr);
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View File

@ -587,7 +587,7 @@ meshes/Identifiers/surface/geometricSurfacePatch.C
meshes/Identifiers/surface/surfZoneIdentifier.C
meshes/Identifiers/zone/zoneIdentifier.C
meshes/MeshObject/meshObject.cxx
meshes/MeshObject/meshObject.C
polyMesh = meshes/polyMesh

View File

@ -34,6 +34,7 @@ Description
#ifndef Foam_ListPolicy_H
#define Foam_ListPolicy_H
#include "MemoryPool.H" // Also includes <cstdint>
#include "contiguous.H" // Also includes <type_traits>
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -103,6 +104,18 @@ template<> struct no_linebreak<wordRe> : std::true_type {};
// - use_offload(n) :
// Lower threshold for switching to device offloading
//
//
// Use of the memory-pool is controlled by the 'is_aligned_type()' test
// and the minimum field size, controlled by the 'use_memory_pool()' test.
//
// If the memory-pool is not enabled or not required according to the two
// above tests, the allocation falls back to either an aligned or unaligned
// allocation.
//
// The decision about when to choose aligned vs unaligned allocation
// is still a compile-time option. Made by direct edit of the
// appropriate functions.
//
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
//- Consider aligned allocation for the given type?
@ -146,27 +159,104 @@ inline constexpr bool use_offload(IntType n) noexcept
}
//- Default alignment for larger fields
inline constexpr std::align_val_t default_alignment() noexcept
{
return std::align_val_t(256);
}
//- Allocate from memory pool (if active), or aligned, or normal
template<class T, class IntType>
inline T* allocate(IntType n)
{
// Plain new
return new T[n];
if constexpr (ListPolicy::is_aligned_type<T>())
{
// Note: threshold for use_memory_pool() >= use_alignment()
if (ListPolicy::use_alignment(n))
{
if
(
void *pool_ptr
(
// Consider memory pool for large amounts of data
ListPolicy::use_memory_pool(n)
? Foam::MemoryPool::try_allocate(sizeof(T)*n)
: nullptr
);
pool_ptr
)
{
// Placement new
return new (pool_ptr) T[n];
}
else
{
return new (ListPolicy::default_alignment()) T[n];
}
}
else
{
// Plain new
return new T[n];
}
}
else
{
// Plain new
return new T[n];
}
}
//- Deallocate from memory pool, or normal
template<class T, class IntType>
inline void deallocate(T* ptr)
{
// Plain new
delete[] ptr;
if constexpr (ListPolicy::is_aligned_type<T>())
{
if (ptr && !Foam::MemoryPool::try_deallocate(ptr))
{
// Plain new
delete[] ptr;
}
}
else
{
// Plain new
delete[] ptr;
}
}
//- Deallocate from memory pool, or aligned, or normal
template<class T, class IntType>
inline void deallocate(T* ptr, [[maybe_unused]] IntType n)
{
// Plain new
delete[] ptr;
if constexpr (ListPolicy::is_aligned_type<T>())
{
// Note: threshold for use_memory_pool() >= use_alignment()
if (ListPolicy::use_alignment(n))
{
if (ptr && !Foam::MemoryPool::try_deallocate(ptr))
{
// Alignment depends on the number of elements
::operator delete[](ptr, ListPolicy::default_alignment());
}
}
else
{
// Plain new
delete[] ptr;
}
}
else
{
// Plain new
delete[] ptr;
}
}

View File

@ -373,33 +373,6 @@ public:
Field<Type>&& iField
);
//- Return tmp field (NO_READ, NO_WRITE)
//- from name, mesh, dimensions, primitive field (tmp).
//- [Takes current timeName from the mesh registry].
// For LEGACY_REGISTER, registration is determined by
// objectRegistry::is_cacheTemporaryObject().
static tmp<DimensionedField<Type, GeoMesh>> New
(
const word& name,
IOobjectOption::registerOption regOpt,
const Mesh& mesh,
const dimensionSet& dims,
const tmp<Field<Type>>& tfield
);
//- Return tmp field (NO_READ, NO_WRITE)
//- from name, mesh, dimensions, primitive field (tmp).
//- [Takes current timeName from the mesh registry].
// Registration/persistence determined by
// objectRegistry::is_cacheTemporaryObject().
static tmp<DimensionedField<Type, GeoMesh>> New
(
const word& name,
const Mesh& mesh,
const dimensionSet& dims,
const tmp<Field<Type>>& tfield
);
//- Return tmp field (NO_READ, NO_WRITE)
//- from name, mesh, dimensions.
//- [Takes current timeName from the mesh registry].

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2022-2025 OpenCFD Ltd.
Copyright (C) 2022-2024 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -163,49 +163,6 @@ Foam::DimensionedField<Type, GeoMesh>::New
}
template<class Type, class GeoMesh>
Foam::tmp<Foam::DimensionedField<Type, GeoMesh>>
Foam::DimensionedField<Type, GeoMesh>::New
(
const word& name,
IOobjectOption::registerOption regOpt,
const Mesh& mesh,
const dimensionSet& dims,
const tmp<Field<Type>>& tfield
)
{
return DimensionedField<Type, GeoMesh>::New_impl
(
regOpt,
name,
mesh,
dims,
tfield
);
}
template<class Type, class GeoMesh>
Foam::tmp<Foam::DimensionedField<Type, GeoMesh>>
Foam::DimensionedField<Type, GeoMesh>::New
(
const word& name,
const Mesh& mesh,
const dimensionSet& dims,
const tmp<Field<Type>>& tfield
)
{
return DimensionedField<Type, GeoMesh>::New_impl
(
IOobjectOption::LEGACY_REGISTER,
name,
mesh,
dims,
tfield
);
}
template<class Type, class GeoMesh>
Foam::tmp<Foam::DimensionedField<Type, GeoMesh>>
Foam::DimensionedField<Type, GeoMesh>::New

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2017,2022 OpenFOAM Foundation
Copyright (C) 2016-2025 OpenCFD Ltd.
Copyright (C) 2016-2024 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -64,8 +64,6 @@ bool Foam::GeometricBoundaryField<Type, PatchField, GeoMesh>::checkConsistency
//Note: areaFields (finiteArea) do not have manipulatedMatrix() flag. TBD.
//boolList oldManipulated(this->size());
label nEvaluated(0);
for (auto& pfld : bfld)
{
if (isA<CheckPatchFieldType>(pfld))
@ -74,24 +72,19 @@ bool Foam::GeometricBoundaryField<Type, PatchField, GeoMesh>::checkConsistency
oldUpdated[patchi] = pfld.updated();
oldBfld[patchi] = pfld;
//oldManipulated[patchi] = pfld.manipulatedMatrix();
++nEvaluated;
}
}
if (!nEvaluated) return true; // Early termination
// Re-evaluate
{
const label startOfRequests = UPstream::nRequests();
nEvaluated = 0;
for (auto& pfld : bfld)
{
if (isA<CheckPatchFieldType>(pfld))
{
pfld.initEvaluate(UPstream::commsTypes::nonBlocking);
++nEvaluated;
}
}
@ -103,15 +96,13 @@ bool Foam::GeometricBoundaryField<Type, PatchField, GeoMesh>::checkConsistency
if (isA<CheckPatchFieldType>(pfld))
{
pfld.evaluate(UPstream::commsTypes::nonBlocking);
if (--nEvaluated == 0) break; // Early termination
}
}
}
// Check
bool allOk(true);
bool ok = true;
for (auto& pfld : bfld)
{
if (isA<CheckPatchFieldType>(pfld))
@ -119,23 +110,16 @@ bool Foam::GeometricBoundaryField<Type, PatchField, GeoMesh>::checkConsistency
const label patchi = pfld.patch().index();
const auto& oldPfld = oldBfld[patchi];
bool localOk(true);
if (allOk)
forAll(pfld, facei)
{
// Only check once
forAll(pfld, facei)
if (mag(pfld[facei]-oldPfld[facei]) > tol)
{
if (mag(pfld[facei]-oldPfld[facei]) > tol)
{
allOk = false;
localOk = false;
break;
}
ok = false;
break;
}
}
if (!localOk)
if (!ok)
{
if (doExit)
{
@ -149,7 +133,7 @@ bool Foam::GeometricBoundaryField<Type, PatchField, GeoMesh>::checkConsistency
<< ". Average of evaluated field = "
<< average(pfld)
<< ". Difference:" << average(pfld-oldPfld)
<< ". Tolerance:" << tol << endl
<< ". Tolerance:" << tol
<< exit(FatalError);
}
else
@ -164,13 +148,25 @@ bool Foam::GeometricBoundaryField<Type, PatchField, GeoMesh>::checkConsistency
<< ". Average of evaluated field = "
<< average(pfld)
<< ". Difference:" << average(pfld-oldPfld)
<< ". Tolerance:" << tol << endl;
<< ". Tolerance:" << tol
<< endl;
// Skip other patches
break;
}
}
}
}
// Restore bfld, updated
// Restore bfld, updated
for (auto& pfld : bfld)
{
if (isA<CheckPatchFieldType>(pfld))
{
const label patchi = pfld.patch().index();
pfld.setUpdated(oldUpdated[patchi]);
static_cast<Field<Type>&>(pfld) = std::move(oldBfld[patchi]);
Field<Type>& vals = pfld;
vals = std::move(oldBfld[patchi]);
//pfld.setManipulated(oldManipulated[patchi]);
}
}
@ -180,10 +176,10 @@ bool Foam::GeometricBoundaryField<Type, PatchField, GeoMesh>::checkConsistency
const auto& pfld0 = this->operator[](0);
PoutInFunction
<< " Result of checking for field "
<< pfld0.internalField().name() << " : " << allOk << endl;
<< pfld0.internalField().name() << " : " << ok << endl;
}
return allOk;
return ok;
}
@ -630,7 +626,6 @@ void Foam::GeometricBoundaryField<Type, PatchField, GeoMesh>::evaluate_if
|| commsType == UPstream::commsTypes::nonBlocking
)
{
label nEvaluated(0);
const label startOfRequests = UPstream::nRequests();
for (auto& pfld : *this)
@ -638,21 +633,17 @@ void Foam::GeometricBoundaryField<Type, PatchField, GeoMesh>::evaluate_if
if (pred(pfld))
{
pfld.initEvaluate(commsType);
++nEvaluated;
}
}
// Wait for outstanding requests (non-blocking)
UPstream::waitRequests(startOfRequests);
if (!nEvaluated) return; // Early termination
for (auto& pfld : *this)
{
if (pred(pfld))
{
pfld.evaluate(commsType);
if (--nEvaluated == 0) break; // Early termination
}
}
}
@ -787,25 +778,81 @@ void Foam::GeometricBoundaryField<Type, PatchField, GeoMesh>::evaluateCoupled
const UPstream::commsTypes commsType
)
{
if constexpr (std::is_void_v<CoupledPatchType>)
// Alternative (C++14)
//
// this->evaluate_if
// (
// [](const auto& pfld) -> bool
// {
// const auto* cpp = isA<CoupledPatchType>(pfld.patch());
// return (cpp && cpp->coupled());
// },
// commsType
// );
// DebugInFunction << nl;
if
(
commsType == UPstream::commsTypes::buffered
|| commsType == UPstream::commsTypes::nonBlocking
)
{
this->evaluate_if
(
[](const auto& pfld) { return pfld.coupled(); },
commsType
);
const label startOfRequests = UPstream::nRequests();
for (auto& pfld : *this)
{
const auto* cpp = isA<CoupledPatchType>(pfld.patch());
if (cpp && cpp->coupled())
{
pfld.initEvaluate(commsType);
}
}
// Wait for outstanding requests (non-blocking)
UPstream::waitRequests(startOfRequests);
for (auto& pfld : *this)
{
const auto* cpp = isA<CoupledPatchType>(pfld.patch());
if (cpp && cpp->coupled())
{
pfld.evaluate(commsType);
}
}
}
else if (commsType == UPstream::commsTypes::scheduled)
{
const lduSchedule& patchSchedule =
bmesh_.mesh().globalData().patchSchedule();
for (const auto& schedEval : patchSchedule)
{
const label patchi = schedEval.patch;
auto& pfld = (*this)[patchi];
const auto* cpp = isA<CoupledPatchType>(pfld.patch());
if (cpp && cpp->coupled())
{
if (schedEval.init)
{
pfld.initEvaluate(commsType);
}
else
{
pfld.evaluate(commsType);
}
}
}
}
else
{
this->evaluate_if
(
[](const auto& pfld) -> bool
{
const auto* cpp = isA<CoupledPatchType>(pfld.patch());
return (cpp && cpp->coupled());
},
commsType
);
FatalErrorInFunction
<< "Unsupported communications type " << int(commsType) << nl
<< exit(FatalError);
}
}

View File

@ -205,12 +205,8 @@ public:
const UPstream::commsTypes commsType = UPstream::defaultCommsType
);
//- Evaluate boundary conditions on coupled patches of the given type,
//- using specified or default comms.
//
// \tparam CoupledPatchType The coupled \b patch type that should
// be evaluated. For a \c void type,
// all coupled patch fields will be evaluated.
//- Evaluate boundary conditions on coupled patches of given type.
//- Uses specified or default comms.
template<class CoupledPatchType>
void evaluateCoupled
(

View File

@ -63,10 +63,8 @@ void Foam::GeometricField<Type, PatchField, GeoMesh>::readFields
if (dict.readIfPresent("referenceLevel", refLevel))
{
// Add to internal (primitive) field
this->field() += refLevel;
Field<Type>::operator+=(refLevel);
// Add to boundary fields
forAll(boundaryField_, patchi)
{
boundaryField_[patchi] == boundaryField_[patchi] + refLevel;
@ -411,7 +409,7 @@ Foam::GeometricField<Type, PatchField, GeoMesh>::GeometricField
boundaryField_(mesh.boundary(), *this, patchFieldType)
{
DebugInFunction
<< "Copy construct from primitive field" << nl << this->info() << endl;
<< "Copy construct from internal field" << nl << this->info() << endl;
readIfPresent();
}
@ -432,28 +430,7 @@ Foam::GeometricField<Type, PatchField, GeoMesh>::GeometricField
boundaryField_(mesh.boundary(), *this, patchFieldType)
{
DebugInFunction
<< "Move construct from primitive field" << nl << this->info() << endl;
readIfPresent();
}
template<class Type, template<class> class PatchField, class GeoMesh>
Foam::GeometricField<Type, PatchField, GeoMesh>::GeometricField
(
const IOobject& io,
const Mesh& mesh,
const dimensionSet& dims,
const tmp<Field<Type>>& tfield,
const word& patchFieldType
)
:
Internal(io, mesh, dims, tfield),
timeIndex_(this->time().timeIndex()),
boundaryField_(mesh.boundary(), *this, patchFieldType)
{
DebugInFunction
<< "Construct from tmp primitive field" << nl << this->info() << endl;
<< "Move construct from internal field" << nl << this->info() << endl;
readIfPresent();
}
@ -1414,7 +1391,10 @@ void Foam::GeometricField<Type, PatchField, GeoMesh>::operator=
// Make sure any e.g. jump-cyclic are updated.
boundaryFieldRef().evaluate_if
(
[](const auto& pfld) { return pfld.constraintOverride(); }
[](const auto& pfld) -> bool
{
return pfld.constraintOverride();
}
);
}
@ -1456,7 +1436,10 @@ void Foam::GeometricField<Type, PatchField, GeoMesh>::operator=
// Make sure any e.g. jump-cyclic are updated.
boundaryFieldRef().evaluate_if
(
[](const auto& pfld) { return pfld.constraintOverride(); }
[](const auto& pfld) -> bool
{
return pfld.constraintOverride();
}
);
}
@ -1473,7 +1456,10 @@ void Foam::GeometricField<Type, PatchField, GeoMesh>::operator=
// Make sure any e.g. jump-cyclic are updated.
boundaryFieldRef().evaluate_if
(
[](const auto& pfld) { return pfld.constraintOverride(); }
[](const auto& pfld) -> bool
{
return pfld.constraintOverride();
}
);
}
@ -1498,7 +1484,10 @@ void Foam::GeometricField<Type, PatchField, GeoMesh>::operator==
// Make sure any e.g. jump-cyclic are updated.
boundaryFieldRef().evaluate_if
(
[](const auto& pfld) { return pfld.constraintOverride(); }
[](const auto& pfld) -> bool
{
return pfld.constraintOverride();
}
);
}
@ -1515,7 +1504,10 @@ void Foam::GeometricField<Type, PatchField, GeoMesh>::operator==
// Make sure any e.g. jump-cyclic are updated.
boundaryFieldRef().evaluate_if
(
[](const auto& pfld) { return pfld.constraintOverride(); }
[](const auto& pfld) -> bool
{
return pfld.constraintOverride();
}
);
}
@ -1535,7 +1527,10 @@ void Foam::GeometricField<Type, PatchField, GeoMesh>::operator op \
\
boundaryFieldRef().evaluate_if \
( \
[](const auto& pfld) { return pfld.constraintOverride(); } \
[](const auto& pfld) -> bool \
{ \
return pfld.constraintOverride(); \
} \
); \
} \
\
@ -1550,7 +1545,10 @@ void Foam::GeometricField<Type, PatchField, GeoMesh>::operator op \
\
boundaryFieldRef().evaluate_if \
( \
[](const auto& pfld) { return pfld.constraintOverride(); } \
[](const auto& pfld) -> bool \
{ \
return pfld.constraintOverride(); \
} \
); \
} \
\
@ -1565,7 +1563,10 @@ void Foam::GeometricField<Type, PatchField, GeoMesh>::operator op \
\
boundaryFieldRef().evaluate_if \
( \
[](const auto& pfld) { return pfld.constraintOverride(); } \
[](const auto& pfld) -> bool \
{ \
return pfld.constraintOverride(); \
} \
); \
}

View File

@ -251,7 +251,7 @@ public:
const PtrList<PatchField<Type>>& ptfl
);
//- Construct from internal field (tmp) and a patch list to clone
//- Move construct from internal field and a patch list to clone
GeometricField
(
const IOobject& io,
@ -273,7 +273,7 @@ public:
const PtrList<PatchField<Type>>& ptfl
);
//- Copy construct from primitive field, with specified patch type
//- Copy construct from internal field, with specified patch type
GeometricField
(
const IOobject& io,
@ -283,7 +283,7 @@ public:
const word& patchFieldType = PatchField<Type>::calculatedType()
);
//- Move construct from primitive field, with specified patch type
//- Move construct from internal field, with specified patch type
GeometricField
(
const IOobject& io,
@ -293,17 +293,7 @@ public:
const word& patchFieldType = PatchField<Type>::calculatedType()
);
//- Construct from primitive field (tmp), with specified patch type
GeometricField
(
const IOobject& io,
const Mesh& mesh,
const dimensionSet& dims,
const tmp<Field<Type>>& tfield,
const word& patchFieldType = PatchField<Type>::calculatedType()
);
//- Copy construct from primitive field and a patch list to clone
//- Copy construct from components
GeometricField
(
const IOobject& io,
@ -313,7 +303,7 @@ public:
const PtrList<PatchField<Type>>& ptfl
);
//- Move construct from primitive field and a patch list to clone
//- Move construct from internal field and a patch list to clone
GeometricField
(
const IOobject& io,
@ -329,7 +319,7 @@ public:
const IOobject& io,
const Mesh& mesh,
const dimensionSet& dims,
const tmp<Field<Type>>& tfield,
const tmp<Field<Type>>& tiField,
const PtrList<PatchField<Type>>& ptfl
);
@ -518,37 +508,6 @@ public:
const word& patchFieldType = PatchField<Type>::calculatedType()
);
//- Return tmp field (NO_READ, NO_WRITE)
//- from name, mesh, dimensions, tmp of primitive field
//- and patch type.
//- [Takes current timeName from the mesh registry].
// For LEGACY_REGISTER, registration is determined by
// objectRegistry::is_cacheTemporaryObject().
static tmp<GeometricField<Type, PatchField, GeoMesh>> New
(
const word& name,
IOobjectOption::registerOption regOpt,
const Mesh& mesh,
const dimensionSet& dims,
const tmp<Field<Type>>& tfield,
const word& patchFieldType = PatchField<Type>::calculatedType()
);
//- Return tmp field (NO_READ, NO_WRITE)
//- from name, mesh, dimensions, tmp of primitive field
//- and patch type.
//- [Takes current timeName from the mesh registry].
// Registration/persistence determined by
// objectRegistry::is_cacheTemporaryObject().
static tmp<GeometricField<Type, PatchField, GeoMesh>> New
(
const word& name,
const Mesh& mesh,
const dimensionSet& dims,
const tmp<Field<Type>>& tfield,
const word& patchFieldType = PatchField<Type>::calculatedType()
);
//- Return tmp field (NO_READ, NO_WRITE)
//- from name, mesh, dimensions, copy of internal field contents
//- and patch list to clone.

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2017 OpenFOAM Foundation
Copyright (C) 2019-2025 OpenCFD Ltd.
Copyright (C) 2019-2024 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -215,53 +215,6 @@ Foam::GeometricField<Type, PatchField, GeoMesh>::New
}
template<class Type, template<class> class PatchField, class GeoMesh>
Foam::tmp<Foam::GeometricField<Type, PatchField, GeoMesh>>
Foam::GeometricField<Type, PatchField, GeoMesh>::New
(
const word& name,
IOobjectOption::registerOption regOpt,
const Mesh& mesh,
const dimensionSet& dims,
const tmp<Field<Type>>& tfield,
const word& patchFieldType
)
{
return GeometricField<Type, PatchField, GeoMesh>::New_impl
(
regOpt,
name,
mesh,
dims,
tfield,
patchFieldType
);
}
template<class Type, template<class> class PatchField, class GeoMesh>
Foam::tmp<Foam::GeometricField<Type, PatchField, GeoMesh>>
Foam::GeometricField<Type, PatchField, GeoMesh>::New
(
const word& name,
const Mesh& mesh,
const dimensionSet& dims,
const tmp<Field<Type>>& tfield,
const word& patchFieldType
)
{
return GeometricField<Type, PatchField, GeoMesh>::New_impl
(
IOobjectOption::LEGACY_REGISTER,
name,
mesh,
dims,
tfield,
patchFieldType
);
}
template<class Type, template<class> class PatchField, class GeoMesh>
Foam::tmp<Foam::GeometricField<Type, PatchField, GeoMesh>>
Foam::GeometricField<Type, PatchField, GeoMesh>::New

View File

@ -6,7 +6,6 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2025 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -88,27 +87,20 @@ void Foam::basicSymmetryPointPatchField<Type>::evaluate
const Pstream::commsTypes
)
{
if constexpr (!is_rotational_vectorspace_v<Type>)
{
// Rotational-invariant type : no-op
}
else
{
const vectorField& nHat = this->patch().pointNormals();
const vectorField& nHat = this->patch().pointNormals();
const Field<Type> pif(this->patchInternalField());
// Could write as loop instead...
tmp<Field<Type>> tvalues
tmp<Field<Type>> tvalues =
(
(
0.5*(pif + transform(I - 2.0*sqr(nHat), pif))
);
this->patchInternalField()
+ transform(I - 2.0*sqr(nHat), this->patchInternalField())
)/2.0
);
// Get internal field to insert values into
auto& iF = const_cast<Field<Type>&>(this->primitiveField());
// Get internal field to insert values into
Field<Type>& iF = const_cast<Field<Type>&>(this->primitiveField());
this->setInInternalField(iF, tvalues());
}
this->setInInternalField(iF, tvalues());
}

View File

@ -27,6 +27,7 @@ License
\*---------------------------------------------------------------------------*/
#include "fixedValuePointPatchField.H"
#include "boolList.H"
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //

View File

@ -84,27 +84,20 @@ Foam::cyclicSlipPointPatchField<Type>::cyclicSlipPointPatchField
template<class Type>
void Foam::cyclicSlipPointPatchField<Type>::evaluate(const Pstream::commsTypes)
{
if constexpr (!is_rotational_vectorspace_v<Type>)
{
// Rotational-invariant type : no-op
}
else
{
const vectorField& nHat = this->patch().pointNormals();
const vectorField& nHat = this->patch().pointNormals();
const Field<Type> pif(this->patchInternalField());
// Could write as loop instead...
tmp<Field<Type>> tvalues
tmp<Field<Type>> tvalues =
(
(
0.5*(pif + transform(I - 2.0*sqr(nHat), pif))
);
this->patchInternalField()
+ transform(I - 2.0*sqr(nHat), this->patchInternalField())
)/2.0
);
// Get internal field to insert values into
auto& iF = const_cast<Field<Type>&>(this->primitiveField());
// Get internal field to insert values into
Field<Type>& iF = const_cast<Field<Type>&>(this->primitiveField());
this->setInInternalField(iF, tvalues());
}
this->setInInternalField(iF, tvalues());
}

View File

@ -91,27 +91,20 @@ void Foam::nonuniformTransformCyclicPointPatchField<Type>::evaluate
const Pstream::commsTypes
)
{
if constexpr (!is_rotational_vectorspace_v<Type>)
{
// Rotational-invariant type : no-op
}
else
{
const vectorField& nHat = this->patch().pointNormals();
const vectorField& nHat = this->patch().pointNormals();
const Field<Type> pif(this->patchInternalField());
// Could write as loop instead...
tmp<Field<Type>> tvalues
tmp<Field<Type>> tvalues =
(
(
0.5*(pif + transform(I - 2.0*sqr(nHat), pif))
);
this->patchInternalField()
+ transform(I - 2.0*sqr(nHat), this->patchInternalField())
)/2.0
);
// Get internal field to insert values into
auto& iF = const_cast<Field<Type>&>(this->primitiveField());
// Get internal field to insert values into
Field<Type>& iF = const_cast<Field<Type>&>(this->primitiveField());
this->setInInternalField(iF, tvalues());
}
this->setInInternalField(iF, tvalues());
}

View File

@ -106,27 +106,20 @@ void Foam::symmetryPlanePointPatchField<Type>::evaluate
const Pstream::commsTypes
)
{
if constexpr (!is_rotational_vectorspace_v<Type>)
{
// Rotational-invariant type : no-op
}
else
{
const symmTensor rot(I - 2.0*sqr(symmetryPlanePatch_.n()));
vector nHat = symmetryPlanePatch_.n();
const Field<Type> pif(this->patchInternalField());
// Could write as loop instead...
tmp<Field<Type>> tvalues
tmp<Field<Type>> tvalues =
(
(
0.5*(pif + transform(rot, pif))
);
this->patchInternalField()
+ transform(I - 2.0*sqr(nHat), this->patchInternalField())
)/2.0
);
// Get internal field to insert values into
auto& iF = const_cast<Field<Type>&>(this->primitiveField());
// Get internal field to insert values into
Field<Type>& iF = const_cast<Field<Type>&>(this->primitiveField());
this->setInInternalField(iF, tvalues());
}
this->setInInternalField(iF, tvalues());
}

View File

@ -6,7 +6,6 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2025 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -29,6 +28,7 @@ License
#include "wedgePointPatchField.H"
#include "transformField.H"
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
template<class Type>
@ -101,28 +101,17 @@ Foam::wedgePointPatchField<Type>::wedgePointPatchField
template<class Type>
void Foam::wedgePointPatchField<Type>::evaluate(const Pstream::commsTypes)
{
if constexpr (!is_rotational_vectorspace_v<Type>)
{
// Rotational-invariant type : no-op
}
else
{
// In order to ensure that the wedge patch is always flat, take the
// normal vector from the first point
// In order to ensure that the wedge patch is always flat, take the
// normal vector from the first point
const vector& nHat = this->patch().pointNormals()[0];
const symmTensor rot(I - 2.0*sqr(this->patch().pointNormals()[0]));
tmp<Field<Type>> tvalues =
transform(I - nHat*nHat, this->patchInternalField());
// Could write as loop instead...
tmp<Field<Type>> tvalues
(
transform(rot, this->patchInternalField())
);
// Get internal field to insert values into
Field<Type>& iF = const_cast<Field<Type>&>(this->primitiveField());
// Get internal field to insert values into
auto& iF = const_cast<Field<Type>&>(this->primitiveField());
this->setInInternalField(iF, tvalues());
}
this->setInInternalField(iF, tvalues());
}

View File

@ -6,7 +6,6 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2025 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -89,22 +88,13 @@ void Foam::fixedNormalSlipPointPatchField<Type>::evaluate
const Pstream::commsTypes
)
{
if constexpr (!is_rotational_vectorspace_v<Type>)
{
// Rotational-invariant type : no-op
}
else
{
tmp<Field<Type>> tvalues
(
transform(I - n_*n_, this->patchInternalField())
);
tmp<Field<Type>> tvalues =
transform(I - n_*n_, this->patchInternalField());
// Get internal field to insert values into
auto& iF = const_cast<Field<Type>&>(this->primitiveField());
// Get internal field to insert values into
Field<Type>& iF = const_cast<Field<Type>&>(this->primitiveField());
this->setInInternalField(iF, tvalues());
}
this->setInInternalField(iF, tvalues());
}

View File

@ -37,6 +37,7 @@ License
#include "IOobject.H"
#include "dynamicCode.H"
#include "simpleObjectRegistry.H"
#include "MemoryPool.H"
#include "sigFpe.H"
#include "sigInt.H"
#include "sigQuit.H"
@ -2182,6 +2183,9 @@ void Foam::argList::parse
sigQuit::set(bannerEnabled());
sigSegv::set(bannerEnabled());
// Create memory pool (if any) after MPI has been setup
MemoryPool::create(bannerEnabled());
if (UPstream::master() && bannerEnabled())
{
Info<< "fileModificationChecking : "

View File

@ -71,21 +71,6 @@ Description
# define FOAM_LIKELY(cond) (cond)
#endif
// Shadow macro for __GNUC__, excluding compilers masquerading as gcc
#undef FOAM_REAL_GNUC
#if defined(__GNUC__) && !defined(__llvm__)
# define FOAM_REAL_GNUC __GNUC__
#endif
// Suppress false positives from -Wdangling-reference (gcc >= 14)
#if (FOAM_REAL_GNUC >= 14)
# define FOAM_NO_DANGLING_REFERENCE [[gnu::no_dangling]]
#endif
#ifndef FOAM_NO_DANGLING_REFERENCE
#define FOAM_NO_DANGLING_REFERENCE
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View File

@ -0,0 +1,116 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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::MemoryPool
Description
Optional memory management using a memory pool such as Umpire
(https://github.com/LLNL/Umpire).
When compiled with Umpire, its use can be controlled by the
\c FOAM_MEMORY_POOL environment variable, or the
\c memory_pool Optimisation switch (etc/controlDict).
It currently looks for any of the following entries, in this order:
- true - same as \em "host"
- false/none - disabled.
- \em "host" - uses host memory pool
- \em "system" - same as \em "host"
- \em "device" - uses device memory pool
- \em "managed" - uses managed host/device memory pool
.
The parameters "size=nn" and "incr=nn" (in MegaBytes) can be used
to specify alternatives to the default sizing.
\*---------------------------------------------------------------------------*/
#ifndef Foam_MemoryPool_H
#define Foam_MemoryPool_H
#include <cstdint> // For size_t
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class MemoryPool Declaration
\*---------------------------------------------------------------------------*/
class MemoryPool
{
public:
// Constructors
//- Create a memory pool instance (if not already active).
// Uses environment or etc/controlDict entry
static bool create(bool verbose = false);
// Destructor
//- Remove the memory pool instance (currently does nothing)
static void destroy(bool verbose = false);
// Member Functions
//- True if pool is active (ie, created and not suspended)
static bool active() noexcept;
//- Suspend use of memory pool (for allocation).
// \return previous suspend status
static bool suspend() noexcept;
//- Resume use of memory pool (if previously active)
static void resume() noexcept;
//- Test if given pointer belongs to the pool
static bool is_pool(void *ptr);
//- Allocate from pool (if active).
// \returns nullptr if the pool is not active
static void* try_allocate(std::size_t nbytes);
//- Deallocate a pointer managed by the pool
// \returns True if a nullptr (no-op) or when the pointer was
// managed by the pool.
static bool try_deallocate(void *ptr);
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2018-2025 OpenCFD Ltd.
Copyright (C) 2018-2024 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -168,12 +168,10 @@ public:
//- Get existing or create MeshObject registered with typeName
template<class... Args>
FOAM_NO_DANGLING_REFERENCE //< Reference stored in registry
static const Type& New(const Mesh& mesh, Args&&... args);
//- Get existing or create MeshObject with given registration name
template<class... Args>
FOAM_NO_DANGLING_REFERENCE //< Reference stored in registry
static const Type& New
(
const word& objName,
@ -322,7 +320,7 @@ public:
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository
#include "MeshObject.txx"
#include "MeshObject.C"
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View File

@ -167,13 +167,13 @@ public:
}
//- Return processor number
int myProcNo() const noexcept
int myProcNo() const
{
return procPolyPatch_.myProcNo();
}
//- Return neighbour processor number
int neighbProcNo() const noexcept
int neighbProcNo() const
{
return procPolyPatch_.neighbProcNo();
}
@ -191,13 +191,13 @@ public:
}
//- Return the underlying processorPolyPatch
const processorPolyPatch& procPolyPatch() const noexcept
const processorPolyPatch& procPolyPatch() const
{
return procPolyPatch_;
}
//- Return mesh points in the correct order for the receiving side
const labelList& reverseMeshPoints() const noexcept
const labelList& reverseMeshPoints() const
{
return reverseMeshPoints_;
}

View File

@ -34,8 +34,8 @@ SourceFiles
\*---------------------------------------------------------------------------*/
#ifndef Foam_wedgePointPatch_H
#define Foam_wedgePointPatch_H
#ifndef wedgePointPatch_H
#define wedgePointPatch_H
#include "facePointPatch.H"
#include "wedgePolyPatch.H"
@ -53,9 +53,9 @@ class wedgePointPatch
:
public facePointPatch
{
// Private Data
// Private data
//- Local reference cast into the wedgePolyPatch patch
//- Local reference cast into the symmetryPlane patch
const wedgePolyPatch& wedgePolyPatch_;
@ -120,8 +120,8 @@ public:
pointConstraint&
) const;
//- Return the normal to the patch
const vector& n() const noexcept
//- Return symmetry plane normal
const vector& n() const
{
return wedgePolyPatch_.n();
}

View File

@ -34,8 +34,8 @@ SourceFiles
\*---------------------------------------------------------------------------*/
#ifndef Foam_wedgePolyPatch_H
#define Foam_wedgePolyPatch_H
#ifndef wedgePolyPatch_H
#define wedgePolyPatch_H
#include "polyPatch.H"
@ -52,7 +52,7 @@ class wedgePolyPatch
:
public polyPatch
{
// Private Data
// Private data
//- Axis of the wedge
vector axis_;
@ -173,27 +173,45 @@ public:
}
// Member Functions
// Member functions
// Access
// Access
//- Return axis of the wedge
const vector& axis() const noexcept { return axis_; }
//- Return axis of the wedge
const vector& axis() const
{
return axis_;
}
//- Return plane normal between the wedge boundaries
const vector& centreNormal() const noexcept { return centreNormal_; }
//- Return plane normal between the wedge boundaries
const vector& centreNormal() const
{
return centreNormal_;
}
//- Return the normal to the patch
const vector& n() const noexcept { return n_; }
//- Return the normal to the patch
const vector& n() const
{
return n_;
}
//- Return the cosine of the wedge angle
scalar cosAngle() const noexcept { return cosAngle_; }
//- Return the cosine of the wedge angle
scalar cosAngle() const
{
return cosAngle_;
}
//- Return face transformation tensor
const tensor& faceT() const noexcept { return faceT_; }
//- Return face transformation tensor
const tensor& faceT() const
{
return faceT_;
}
//- Return neighbour-cell transformation tensor
const tensor& cellT() const noexcept { return cellT_; }
//- Return neighbour-cell transformation tensor
const tensor& cellT() const
{
return cellT_;
}
};

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2019-2025 OpenCFD Ltd.
Copyright (C) 2019-2023 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -92,7 +92,7 @@ public:
// Constructors
//- Construct initialized to zero
inline DiagTensor(Foam::zero);
inline DiagTensor(const Foam::zero);
//- Construct given VectorSpace
template<class Cmpt2>
@ -123,9 +123,6 @@ public:
// Diagonal access and manipulation
//- Extract the diagonal as a vector
inline Vector<Cmpt> diag() const;
//- The L2-norm squared of the diagonal
inline scalar diagSqr() const;
};

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2020-2025 OpenCFD Ltd.
Copyright (C) 2020-2023 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -32,9 +32,9 @@ License
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
template<class Cmpt>
inline Foam::DiagTensor<Cmpt>::DiagTensor(Foam::zero)
inline Foam::DiagTensor<Cmpt>::DiagTensor(const Foam::zero)
:
VectorSpace<DiagTensor<Cmpt>, Cmpt, 3>(Foam::zero{})
VectorSpace<DiagTensor<Cmpt>, Cmpt, 3>(Zero)
{}
@ -81,13 +81,6 @@ inline Foam::DiagTensor<Cmpt>::DiagTensor(Istream& is)
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class Cmpt>
inline Foam::Vector<Cmpt> Foam::DiagTensor<Cmpt>::diag() const
{
return Vector<Cmpt>(this->xx(), this->yy(), this->zz());
}
template<class Cmpt>
inline Foam::scalar Foam::DiagTensor<Cmpt>::diagSqr() const
{

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2019-2025 OpenCFD Ltd.
Copyright (C) 2019-2023 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -94,7 +94,7 @@ public:
// Constructors
//- Construct initialized to zero
inline SymmTensor(Foam::zero);
inline SymmTensor(const Foam::zero);
//- Construct given VectorSpace of the same rank
template<class Cmpt2>
@ -234,12 +234,6 @@ public:
inline scalar diagSqr() const;
// Characteristics
//- Is identity tensor?
inline bool is_identity(const scalar tol = ROOTVSMALL) const;
// Tensor Operations
//- Return non-Hermitian transpose

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2019-2025 OpenCFD Ltd.
Copyright (C) 2019-2023 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -31,9 +31,9 @@ License
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
template<class Cmpt>
inline Foam::SymmTensor<Cmpt>::SymmTensor(Foam::zero)
inline Foam::SymmTensor<Cmpt>::SymmTensor(const Foam::zero)
:
SymmTensor::vsType(Foam::zero{})
SymmTensor::vsType(Zero)
{}
@ -238,21 +238,6 @@ inline Foam::scalar Foam::SymmTensor<Cmpt>::diagSqr() const
}
template<class Cmpt>
inline bool Foam::SymmTensor<Cmpt>::is_identity(const scalar tol) const
{
return
(
Foam::mag(xx() - pTraits<Cmpt>::one) < tol
&& Foam::mag(yy() - pTraits<Cmpt>::one) < tol
&& Foam::mag(zz() - pTraits<Cmpt>::one) < tol
&& Foam::mag(xy()) < tol
&& Foam::mag(xz()) < tol
&& Foam::mag(yz()) < tol
);
}
template<class Cmpt>
inline Cmpt Foam::SymmTensor<Cmpt>::det() const
{

View File

@ -410,12 +410,12 @@ inline bool Foam::Tensor<Cmpt>::is_identity(const scalar tol) const
{
return
(
Foam::mag(xx() - pTraits<Cmpt>::one) < tol
&& Foam::mag(yy() - pTraits<Cmpt>::one) < tol
&& Foam::mag(zz() - pTraits<Cmpt>::one) < tol
&& Foam::mag(xy()) < tol && Foam::mag(xz()) < tol
&& Foam::mag(yx()) < tol && Foam::mag(yz()) < tol
&& Foam::mag(zx()) < tol && Foam::mag(zy()) < tol
mag(xx() - pTraits<Cmpt>::one) < tol
&& mag(yy() - pTraits<Cmpt>::one) < tol
&& mag(zz() - pTraits<Cmpt>::one) < tol
&& mag(xy()) < tol && mag(xz()) < tol
&& mag(yx()) < tol && mag(yz()) < tol
&& mag(zx()) < tol && mag(zy()) < tol
);
}

View File

@ -43,8 +43,8 @@ template<class BasicTurbulenceModel>
void sigma<BasicTurbulenceModel>::correctNut()
{
this->nut_ =
sqr(this->delta()*Csigma_)
*DESModel<BasicTurbulenceModel>::Ssigma(fvc::grad(this->U_), scalar(1));
sqr(this->delta())
*DESModel<BasicTurbulenceModel>::Ssigma(fvc::grad(this->U_), Csigma_);
this->nut_.correctBoundaryConditions();
fv::options::New(this->mesh_).correct(this->nut_);

View File

@ -45,6 +45,7 @@ $(faPatchFields)/faPatchField/faPatchFieldBase.C
$(faPatchFields)/faPatchField/faPatchFields.C
basicFaPatchFields = $(faPatchFields)/basic
$(basicFaPatchFields)/basicSymmetry/basicSymmetryFaPatchFields.C
$(basicFaPatchFields)/calculated/calculatedFaPatchFields.C
$(basicFaPatchFields)/extrapolatedCalculated/extrapolatedCalculatedFaPatchFields.C
$(basicFaPatchFields)/coupled/coupledFaPatchFields.C

View File

@ -93,12 +93,16 @@ Foam::wedgeFaPatch::wedgeFaPatch
<< this->name() << exit(FatalError);
}
wedgePolyPatchPtr_ = isA<wedgePolyPatch>
const auto* wedgePtr = isA<wedgePolyPatch>
(
bm.mesh().mesh().boundaryMesh()[ngbPolyPatchIndex()]
);
if (!wedgePolyPatchPtr_)
if (wedgePtr)
{
wedgePolyPatchPtr_ = wedgePtr;
}
else
{
FatalErrorInFunction
<< "Neighbour polyPatch is not of type "

View File

@ -77,9 +77,7 @@ public:
//- Runtime type information
TypeName("wedge");
//- Construct from dictionary.
// Fatal if ngbPolyPatchIndex is not defined
// or does not correspond to a wedgePolyPatch
//- Construct from dictionary
wedgeFaPatch
(
const word& name,
@ -99,25 +97,25 @@ public:
// Access
//- Return axis of the wedge
const vector& axis() const noexcept
const vector& axis() const
{
return wedgePolyPatchPtr_->axis();
}
//- Return plane normal between the wedge boundaries
const vector& centreNormal() const noexcept
const vector& centreNormal() const
{
return wedgePolyPatchPtr_->centreNormal();
}
//- Return face transformation tensor
const tensor& edgeT() const noexcept
const tensor& edgeT() const
{
return wedgePolyPatchPtr_->faceT();
}
//- Return neighbour-cell transformation tensor
const tensor& faceT() const noexcept
const tensor& faceT() const
{
return wedgePolyPatchPtr_->cellT();
}

View File

@ -480,26 +480,25 @@ public:
const UList<Type>& internalData
) const;
//- Return the patch field of the GeometricField
//- corresponding to this patch.
template<class GeometricField, class AnyType = bool>
const typename GeometricField::Patch& patchField
(
const GeometricField& gf
) const;
// Lookup
//- Return the patch field of the GeometricField
//- corresponding to this patch.
template<class GeometricField, class AnyType = bool>
const typename GeometricField::Patch&
patchField(const GeometricField& gf) const;
//- Lookup the named field from the local registry and
//- return the patch field corresponding to this patch.
template<class GeometricField, class AnyType = bool>
const typename GeometricField::Patch&
lookupPatchField(const word& fldName) const;
//- Lookup the named field (if any) from the local registry and
//- return the patch field corresponding to this patch.
template<class GeometricField>
const typename GeometricField::Patch*
cfindPatchField(const word& fldName) const;
//- Lookup the named field from the local registry and
//- return the patch field corresponding to this patch.
// N.B. The dummy pointer arguments are used if this function is
// instantiated within a templated function to avoid a bug in gcc.
template<class GeometricField, class AnyType = bool>
const typename GeometricField::Patch& lookupPatchField
(
const word& name,
const GeometricField* = nullptr,
const AnyType* = nullptr
) const;
// Ostream Operator

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2016-2017 Wikki Ltd
Copyright (C) 2021-2025 OpenCFD Ltd.
Copyright (C) 2021-2022 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -31,33 +31,18 @@ License
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class GeometricField, class AnyType>
const typename GeometricField::Patch&
Foam::faPatch::lookupPatchField(const word& fldName) const
const typename GeometricField::Patch& Foam::faPatch::lookupPatchField
(
const word& name,
const GeometricField*,
const AnyType*
) const
{
return
boundaryMesh().mesh().thisDb().template
lookupObject<GeometricField>(fldName)
lookupObject<GeometricField>(name)
.boundaryField()[this->index()];
}
template<class GeometricField>
const typename GeometricField::Patch*
Foam::faPatch::cfindPatchField(const word& fldName) const
{
const auto* fldptr =
boundaryMesh().mesh().thisDb().template
cfindObject<GeometricField>(fldName);
if (fldptr)
{
return &(fldptr->boundaryField()[this->index()]);
}
else
{
return nullptr;
}
}
// ************************************************************************* //

View File

@ -6,7 +6,6 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2016-2017 Wikki Ltd
Copyright (C) 2025 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -86,25 +85,13 @@ template<class Type>
Foam::tmp<Foam::Field<Type>>
Foam::basicSymmetryFaPatchField<Type>::snGrad() const
{
if constexpr (!is_rotational_vectorspace_v<Type>)
{
// Rotational-invariant type : treat like zero-gradient
return tmp<Field<Type>>::New(this->size(), Foam::zero{});
}
else
{
tmp<vectorField> nHat = this->patch().edgeNormals();
const vectorField nHat(this->patch().edgeNormals());
const auto& dc = this->patch().deltaCoeffs();
const Field<Type> pif(this->patchInternalField());
return
(
(0.5*dc)
* (transform(I - 2.0*sqr(nHat), pif) - pif)
);
}
return
(
transform(I - 2.0*sqr(nHat), this->patchInternalField())
- this->patchInternalField()
)*(this->patch().deltaCoeffs()/2.0);
}
@ -116,22 +103,14 @@ void Foam::basicSymmetryFaPatchField<Type>::evaluate(const Pstream::commsTypes)
this->updateCoeffs();
}
if constexpr (!is_rotational_vectorspace_v<Type>)
{
// Rotational-invariant type : treat like zero-gradient
this->extrapolateInternal();
}
else
{
tmp<vectorField> nHat = this->patch().edgeNormals();
const Field<Type> pif(this->patchInternalField());
Field<Type>::operator=
const vectorField nHat(this->patch().edgeNormals());
Field<Type>::operator=
(
(
0.5*(pif + transform(I - 2.0*sqr(nHat), pif))
);
}
this->patchInternalField()
+ transform(I - 2.0*sqr(nHat), this->patchInternalField())
)/2.0
);
transformFaPatchField<Type>::evaluate();
}

View File

@ -143,6 +143,18 @@ public:
};
// * * * * * * * * * * * Template Specialisations * * * * * * * * * * * * * //
template<>
tmp<scalarField> basicSymmetryFaPatchField<scalar>::snGrad() const;
template<>
void basicSymmetryFaPatchField<scalar>::evaluate
(
const Pstream::commsTypes commsType
);
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam

View File

@ -0,0 +1,59 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2016-2017 Wikki 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 "basicSymmetryFaPatchField.H"
#include "areaFields.H"
// No run-time selection
// * * * * * * * * * * * * * * * Specialisations * * * * * * * * * * * * * * //
template<>
Foam::tmp<Foam::scalarField>
Foam::basicSymmetryFaPatchField<Foam::scalar>::snGrad() const
{
return tmp<scalarField>::New(size(), Zero);
}
template<>
void Foam::basicSymmetryFaPatchField<Foam::scalar>::evaluate
(
const Pstream::commsTypes
)
{
if (!updated())
{
updateCoeffs();
}
scalarField::operator=(patchInternalField());
transformFaPatchField<scalar>::evaluate();
}
// ************************************************************************* //

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2016-2017 Wikki Ltd
Copyright (C) 2019-2025 OpenCFD Ltd.
Copyright (C) 2019-2023 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -125,7 +125,7 @@ public:
) const = 0;
// Member Functions
// Member functions
// Access
@ -139,9 +139,6 @@ public:
//- Return neighbour field of internal field
virtual tmp<Field<Type>> patchNeighbourField() const = 0;
//- Retrieve neighbour coupled field
virtual void patchNeighbourField(UList<Type>&) const = 0;
// Evaluation functions

View File

@ -151,12 +151,24 @@ Foam::slicedFaPatchField<Type>::patchInternalField() const
template<class Type>
void Foam::slicedFaPatchField<Type>::patchInternalField(UList<Type>&) const
void Foam::slicedFaPatchField<Type>::patchInternalField(Field<Type>&) const
{
NotImplemented;
}
template<class Type>
Foam::tmp<Foam::Field<Type>>
Foam::slicedFaPatchField<Type>::patchNeighbourField
(
const Field<Type>& iField
) const
{
NotImplemented;
return nullptr;
}
template<class Type>
Foam::tmp<Foam::Field<Type>>
Foam::slicedFaPatchField<Type>::patchNeighbourField() const
@ -166,13 +178,6 @@ Foam::slicedFaPatchField<Type>::patchNeighbourField() const
}
template<class Type>
void Foam::slicedFaPatchField<Type>::patchNeighbourField(UList<Type>&) const
{
NotImplemented;
}
template<class Type>
Foam::tmp<Foam::Field<Type>>
Foam::slicedFaPatchField<Type>::valueInternalCoeffs

View File

@ -153,23 +153,27 @@ public:
virtual bool assignable() const { return false; }
// Evaluation Functions
// Evaluation functions
//- Return patch-normal gradient
virtual tmp<Field<Type>> snGrad() const;
//- Return internal field next to patch
//- Return internal field next to patch as patch field
virtual tmp<Field<Type>> patchInternalField() const;
//- Retrieve internal field next to patch
virtual void patchInternalField(UList<Type>&) const;
//- Return internal field next to patch as patch field
virtual void patchInternalField(Field<Type>&) const;
//- Return patchField on the opposite patch of a coupled patch
//- Return neighbour coupled given internal cell data
virtual tmp<Field<Type>> patchNeighbourField
(
const Field<Type>& iField
) const;
//- Return patchField of the values on the patch or on the
// opposite patch
virtual tmp<Field<Type>> patchNeighbourField() const;
//- Retrieve neighbour coupled field
virtual void patchNeighbourField(UList<Type>&) const;
//- Initialise the evaluation of the patch field
virtual void initEvaluate
(

View File

@ -37,7 +37,7 @@ Foam::transformFaPatchField<Type>::transformFaPatchField
const DimensionedField<Type, areaMesh>& iF
)
:
faPatchField<Type>(p, iF)
faPatchField<Type>(p, iF)
{}

View File

@ -148,6 +148,12 @@ public:
};
// * * * * * * * * * * * Template Specialisations * * * * * * * * * * * * * //
template<>
tmp<scalarField> transformFaPatchField<scalar>::gradientInternalCoeffs() const;
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam

View File

@ -37,4 +37,14 @@ namespace Foam
}
// * * * * * * * * * * * * * * * Specialisations * * * * * * * * * * * * * * //
template<>
Foam::tmp<Foam::scalarField>
Foam::transformFaPatchField<Foam::scalar>::gradientInternalCoeffs() const
{
return tmp<scalarField>::New(size(), Zero);
}
// ************************************************************************* //

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2016-2017 Wikki Ltd
Copyright (C) 2019-2025 OpenCFD Ltd.
Copyright (C) 2019-2023 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -124,15 +124,16 @@ Foam::cyclicFaPatchField<Type>::cyclicFaPatchField
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class Type>
void Foam::cyclicFaPatchField<Type>::patchNeighbourField
(
UList<Type>& pnf
) const
Foam::tmp<Foam::Field<Type>>
Foam::cyclicFaPatchField<Type>::patchNeighbourField() const
{
const Field<Type>& iField = this->primitiveField();
const labelUList& faceCells = cyclicPatch_.faceCells();
const label sizeby2 = pnf.size()/2;
auto tpnf = tmp<Field<Type>>::New(this->size());
auto& pnf = tpnf.ref();
const label sizeby2 = this->size()/2;
if (doTransform())
{
@ -157,15 +158,7 @@ void Foam::cyclicFaPatchField<Type>::patchNeighbourField
pnf[facei + sizeby2] = iField[faceCells[facei]];
}
}
}
template<class Type>
Foam::tmp<Foam::Field<Type>>
Foam::cyclicFaPatchField<Type>::patchNeighbourField() const
{
auto tpnf = tmp<Field<Type>>::New(this->size());
this->patchNeighbourField(tpnf.ref());
return tpnf;
}

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2016-2017 Wikki Ltd
Copyright (C) 2019-2025 OpenCFD Ltd.
Copyright (C) 2019 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -67,6 +67,17 @@ class cyclicFaPatchField
//- Local reference cast into the cyclic patch
const cyclicFaPatch& cyclicPatch_;
// Private Member Functions
//- Return neighbour side field given internal fields
template<class Type2>
tmp<Field<Type2>> neighbourSideField
(
const Field<Type2>&
) const;
public:
//- Runtime type information
@ -130,25 +141,22 @@ public:
}
// Member Functions
// Member functions
// Access
//- Return local reference cast into the cyclic patch
const cyclicFaPatch& cyclicPatch() const noexcept
const cyclicFaPatch& cyclicPatch() const
{
return cyclicPatch_;
}
// Evaluation Functions
// Evaluation functions
//- Return neighbour coupled given internal cell data
virtual tmp<Field<Type>> patchNeighbourField() const;
//- Retrieve neighbour coupled given internal cell data
virtual void patchNeighbourField(UList<Type>& pnf) const;
// Coupled interface functionality

View File

@ -207,22 +207,6 @@ Foam::processorFaPatchField<Type>::patchNeighbourField() const
}
template<class Type>
void Foam::processorFaPatchField<Type>::patchNeighbourField
(
UList<Type>& pnf
) const
{
if (debug && !this->ready())
{
FatalErrorInFunction
<< "Outstanding request on patch " << procPatch_.name()
<< abort(FatalError);
}
pnf.deepCopy(*this);
}
template<class Type>
void Foam::processorFaPatchField<Type>::initEvaluate
(
@ -231,7 +215,6 @@ void Foam::processorFaPatchField<Type>::initEvaluate
{
if (UPstream::parRun())
{
sendBuf_.resize_nocopy(this->patch().size());
this->patchInternalField(sendBuf_);
if (commsType == UPstream::commsTypes::nonBlocking)

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2016-2017 Wikki Ltd
Copyright (C) 2019-2025 OpenCFD Ltd.
Copyright (C) 2019-2023 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -177,9 +177,6 @@ public:
//- Return neighbour field given internal field
virtual tmp<Field<Type>> patchNeighbourField() const;
//- Retrieve neighbour field
virtual void patchNeighbourField(UList<Type>& pnf) const;
// Evaluation

View File

@ -29,6 +29,7 @@ License
#include "wedgeFaPatchField.H"
#include "transformField.H"
#include "symmTransform.H"
#include "diagTensor.H"
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
@ -104,25 +105,13 @@ Foam::wedgeFaPatchField<Type>::wedgeFaPatchField
template<class Type>
Foam::tmp<Foam::Field<Type>> Foam::wedgeFaPatchField<Type>::snGrad() const
{
if constexpr (!is_rotational_vectorspace_v<Type>)
{
// Rotational-invariant type: treat like zero-gradient
return tmp<Field<Type>>::New(this->size(), Foam::zero{});
}
else
{
const auto& rot = refCast<const wedgeFaPatch>(this->patch()).faceT();
const Field<Type> pif (this->patchInternalField());
const Field<Type> pif(this->patchInternalField());
const auto& dc = this->patch().deltaCoeffs();
return
(
(0.5*dc)
* (transform(rot, pif) - pif)
);
}
return
(
transform(refCast<const wedgeFaPatch>(this->patch()).faceT(), pif)
- pif
)*(0.5*this->patch().deltaCoeffs());
}
@ -134,20 +123,14 @@ void Foam::wedgeFaPatchField<Type>::evaluate(const Pstream::commsTypes)
this->updateCoeffs();
}
if constexpr (!is_rotational_vectorspace_v<Type>)
{
// Rotational-invariant type: treat like zero-gradient
this->extrapolateInternal();
}
else
{
const auto& rot = refCast<const wedgeFaPatch>(this->patch()).edgeT();
faPatchField<Type>::operator==
faPatchField<Type>::operator==
(
transform
(
transform(rot, this->patchInternalField())
);
}
refCast<const wedgeFaPatch>(this->patch()).edgeT(),
this->patchInternalField()
)
);
}
@ -155,9 +138,10 @@ template<class Type>
Foam::tmp<Foam::Field<Type>>
Foam::wedgeFaPatchField<Type>::snGradTransformDiag() const
{
const auto& rot = refCast<const wedgeFaPatch>(this->patch()).faceT();
const diagTensor diagT =
0.5*diag(I - refCast<const wedgeFaPatch>(this->patch()).faceT());
const vector diagV = 0.5*(I - rot).diag();
const vector diagV(diagT.xx(), diagT.yy(), diagT.zz());
return tmp<Field<Type>>::New
(

View File

@ -133,6 +133,18 @@ public:
};
// * * * * * * * * * * * Template Specialisations * * * * * * * * * * * * * //
template<>
tmp<scalarField> wedgeFaPatchField<scalar>::snGrad() const;
template<>
void wedgeFaPatchField<scalar>::evaluate
(
const Pstream::commsTypes commsType
);
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam

View File

@ -36,4 +36,26 @@ namespace Foam
makeFaPatchFields(wedge);
}
// * * * * * * * * * * * * * * * Specialisations * * * * * * * * * * * * * * //
template<>
Foam::tmp<Foam::scalarField>
Foam::wedgeFaPatchField<Foam::scalar>::snGrad() const
{
return tmp<scalarField>::New(size(), Zero);
}
template<>
void Foam::wedgeFaPatchField<Foam::scalar>::evaluate(const Pstream::commsTypes)
{
if (!updated())
{
updateCoeffs();
}
this->operator==(patchInternalField());
}
// ************************************************************************* //

View File

@ -215,9 +215,11 @@ Foam::faPatchField<Type>::patchInternalField() const
template<class Type>
void Foam::faPatchField<Type>::patchInternalField(UList<Type>& pfld) const
void Foam::faPatchField<Type>::patchInternalField(Field<Type>& pfld) const
{
patch().patchInternalField(internalField_, pfld);
const auto& p = faPatchFieldBase::patch();
pfld.resize_nocopy(p.size()); // In general this is a no-op
p.patchInternalField(internalField_, pfld);
}

View File

@ -543,7 +543,7 @@ public:
);
// Evaluation Functions
// Evaluation
//- Return patch-normal gradient
virtual tmp<Field<Type>> snGrad() const;
@ -551,9 +551,9 @@ public:
//- Return internal field next to patch
virtual tmp<Field<Type>> patchInternalField() const;
//- Retrieve internal field next to patch
//- Extract internal field next to patch
// \param [out] pfld The extracted patch field.
virtual void patchInternalField(UList<Type>& pfld) const;
virtual void patchInternalField(Field<Type>& pfld) const;
//- Return patchField on the opposite patch of a coupled patch
virtual tmp<Field<Type>> patchNeighbourField() const
@ -562,12 +562,6 @@ public:
return *this;
}
//- Retrieve patchField on the opposite patch of a coupled patch
virtual void patchNeighbourField(UList<Type>&) const
{
NotImplemented;
}
//- Update the coefficients associated with the patch field
// Sets Updated to true
virtual void updateCoeffs();

View File

@ -128,6 +128,7 @@ $(fvPatchFields)/fvPatchField/fvPatchFieldBase.C
$(fvPatchFields)/fvPatchField/fvPatchFields.C
basicFvPatchFields = $(fvPatchFields)/basic
$(basicFvPatchFields)/basicSymmetry/basicSymmetryFvPatchFields.C
$(basicFvPatchFields)/calculated/calculatedFvPatchFields.C
$(basicFvPatchFields)/extrapolatedCalculated/extrapolatedCalculatedFvPatchFields.C
$(basicFvPatchFields)/coupled/coupledFvPatchFields.C

View File

@ -6,7 +6,6 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2025 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -86,25 +85,13 @@ template<class Type>
Foam::tmp<Foam::Field<Type>>
Foam::basicSymmetryFvPatchField<Type>::snGrad() const
{
if constexpr (!is_rotational_vectorspace_v<Type>)
{
// Rotational-invariant type : treat like zero-gradient
return tmp<Field<Type>>::New(this->size(), Foam::zero{});
}
else
{
tmp<vectorField> nHat = this->patch().nf();
tmp<vectorField> nHat = this->patch().nf();
const auto& dc = this->patch().deltaCoeffs();
const Field<Type> iF(this->patchInternalField());
const Field<Type> pif(this->patchInternalField());
return
(
(0.5*dc)
* (transform(I - 2.0*sqr(nHat), pif) - pif)
);
}
return
(transform(I - 2.0*sqr(nHat), iF) - iF)
*(this->patch().deltaCoeffs()/2.0);
}
@ -116,22 +103,14 @@ void Foam::basicSymmetryFvPatchField<Type>::evaluate(const Pstream::commsTypes)
this->updateCoeffs();
}
if constexpr (!is_rotational_vectorspace_v<Type>)
{
// Rotational-invariant type : treat like zero-gradient
this->extrapolateInternal();
}
else
{
tmp<vectorField> nHat = this->patch().nf();
tmp<vectorField> nHat = this->patch().nf();
const Field<Type> pif(this->patchInternalField());
const Field<Type> iF(this->patchInternalField());
Field<Type>::operator=
(
0.5*(pif + transform(I - 2.0*sqr(nHat), pif))
);
}
Field<Type>::operator=
(
(iF + transform(I - 2.0*sqr(nHat), iF))/2.0
);
transformFvPatchField<Type>::evaluate();
}

View File

@ -139,6 +139,18 @@ public:
};
// * * * * * * * * * * * Template Specialisations * * * * * * * * * * * * * //
template<>
tmp<scalarField> basicSymmetryFvPatchField<scalar>::snGrad() const;
template<>
void basicSymmetryFvPatchField<scalar>::evaluate
(
const Pstream::commsTypes commsType
);
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam

View File

@ -0,0 +1,59 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2013 OpenFOAM Foundation
-------------------------------------------------------------------------------
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 "basicSymmetryFvPatchField.H"
#include "volFields.H"
// No run-time selection
// * * * * * * * * * * * * * * * Specialisations * * * * * * * * * * * * * * //
template<>
Foam::tmp<Foam::scalarField>
Foam::basicSymmetryFvPatchField<Foam::scalar>::snGrad() const
{
return tmp<scalarField>::New(size(), Zero);
}
template<>
void Foam::basicSymmetryFvPatchField<Foam::scalar>::evaluate
(
const Pstream::commsTypes
)
{
if (!updated())
{
updateCoeffs();
}
scalarField::operator=(patchInternalField());
transformFvPatchField<scalar>::evaluate();
}
// ************************************************************************* //

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2019-2025 OpenCFD Ltd.
Copyright (C) 2019-2023 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -142,7 +142,7 @@ public:
) const = 0;
// Member Functions
// Member functions
// Access
@ -155,11 +155,8 @@ public:
//- Return neighbour field of internal field
virtual tmp<Field<Type>> patchNeighbourField() const = 0;
//- Retrieve neighbour coupled data
virtual void patchNeighbourField(UList<Type>&) const = 0;
// Evaluation Functions
// Evaluation functions
//- Return patch-normal gradient
virtual tmp<Field<Type>> snGrad

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2017-2025 OpenCFD Ltd.
Copyright (C) 2017-2023 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -151,12 +151,24 @@ Foam::slicedFvPatchField<Type>::patchInternalField() const
template<class Type>
void Foam::slicedFvPatchField<Type>::patchInternalField(UList<Type>&) const
void Foam::slicedFvPatchField<Type>::patchInternalField(Field<Type>&) const
{
NotImplemented;
}
template<class Type>
Foam::tmp<Foam::Field<Type>>
Foam::slicedFvPatchField<Type>::patchNeighbourField
(
const Field<Type>& iField
) const
{
NotImplemented;
return nullptr;
}
template<class Type>
Foam::tmp<Foam::Field<Type>>
Foam::slicedFvPatchField<Type>::patchNeighbourField() const
@ -166,13 +178,6 @@ Foam::slicedFvPatchField<Type>::patchNeighbourField() const
}
template<class Type>
void Foam::slicedFvPatchField<Type>::patchNeighbourField(UList<Type>&) const
{
NotImplemented;
}
template<class Type>
Foam::tmp<Foam::Field<Type>>
Foam::slicedFvPatchField<Type>::valueInternalCoeffs

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2017 OpenFOAM Foundation
Copyright (C) 2017-2025 OpenCFD Ltd.
Copyright (C) 2017-2023 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -151,23 +151,27 @@ public:
virtual bool assignable() const { return false; }
// Evaluation Functions
// Evaluation functions
//- Return patch-normal gradient
virtual tmp<Field<Type>> snGrad() const;
//- Return internal field next to patch
//- Return internal field next to patch as patch field
virtual tmp<Field<Type>> patchInternalField() const;
//- Retrieve internal field next to patch
virtual void patchInternalField(UList<Type>&) const;
//- Return internal field next to patch as patch field
virtual void patchInternalField(Field<Type>&) const;
//- Return patchField on the opposite patch of a coupled patch
//- Return neighbour coupled given internal cell data
virtual tmp<Field<Type>> patchNeighbourField
(
const Field<Type>& iField
) const;
//- Return patchField of the values on the patch or on the
// opposite patch
virtual tmp<Field<Type>> patchNeighbourField() const;
//- Retrieve neighbour coupled field
virtual void patchNeighbourField(UList<Type>&) const;
//- Initialise the evaluation of the patch field
virtual void initEvaluate
(

View File

@ -157,6 +157,18 @@ public:
};
// * * * * * * * * * * * Template Specialisations * * * * * * * * * * * * * //
template<>
tmp<scalarField> transformFvPatchField<scalar>::valueInternalCoeffs
(
const tmp<scalarField>&
) const;
template<>
tmp<scalarField> transformFvPatchField<scalar>::gradientInternalCoeffs() const;
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam

View File

@ -37,4 +37,25 @@ namespace Foam
}
// * * * * * * * * * * * * * * * Specialisations * * * * * * * * * * * * * * //
template<>
Foam::tmp<Foam::scalarField>
Foam::transformFvPatchField<Foam::scalar>::valueInternalCoeffs
(
const tmp<scalarField>&
) const
{
return tmp<scalarField>::New(size(), 1.0);
}
template<>
Foam::tmp<Foam::scalarField>
Foam::transformFvPatchField<Foam::scalar>::gradientInternalCoeffs() const
{
return tmp<scalarField>::New(size(), Zero);
}
// ************************************************************************* //

View File

@ -110,25 +110,6 @@ Foam::calculatedProcessorFvPatchField<Type>::patchNeighbourField() const
}
template<class Type>
void Foam::calculatedProcessorFvPatchField<Type>::patchNeighbourField
(
UList<Type>& pnf
) const
{
if (!this->ready())
{
FatalErrorInFunction
<< "Outstanding request on patch of size "
<< procInterface_.faceCells().size()
<< " between proc " << procInterface_.myProcNo()
<< " and " << procInterface_.neighbProcNo()
<< abort(FatalError);
}
pnf.deepCopy(*this);
}
template<class Type>
void Foam::calculatedProcessorFvPatchField<Type>::initEvaluate
(

View File

@ -169,12 +169,9 @@ public:
//- Are all (receive) data available?
virtual bool ready() const;
//- Return neighbour field
//- Return neighbour field of internal field
virtual tmp<Field<Type>> patchNeighbourField() const;
//- Retrieve neighbour field
virtual void patchNeighbourField(UList<Type>& result) const;
// Evaluation

View File

@ -127,12 +127,17 @@ Foam::cyclicFvPatchField<Type>::cyclicFvPatchField
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class Type>
void Foam::cyclicFvPatchField<Type>::patchNeighbourField(UList<Type>& pnf) const
Foam::tmp<Foam::Field<Type>>
Foam::cyclicFvPatchField<Type>::patchNeighbourField() const
{
const Field<Type>& iField = this->primitiveField();
const labelUList& nbrFaceCells =
cyclicPatch().cyclicPatch().neighbPatch().faceCells();
auto tpnf = tmp<Field<Type>>::New(this->size());
auto& pnf = tpnf.ref();
if (doTransform())
{
forAll(pnf, facei)
@ -150,15 +155,7 @@ void Foam::cyclicFvPatchField<Type>::patchNeighbourField(UList<Type>& pnf) const
pnf[facei] = iField[nbrFaceCells[facei]];
}
}
}
template<class Type>
Foam::tmp<Foam::Field<Type>>
Foam::cyclicFvPatchField<Type>::patchNeighbourField() const
{
auto tpnf = tmp<Field<Type>>::New(this->size());
this->patchNeighbourField(tpnf.ref());
return tpnf;
}
@ -167,7 +164,7 @@ template<class Type>
const Foam::cyclicFvPatchField<Type>&
Foam::cyclicFvPatchField<Type>::neighbourPatchField() const
{
const auto& fld =
const GeometricField<Type, fvPatchField, volMesh>& fld =
static_cast<const GeometricField<Type, fvPatchField, volMesh>&>
(
this->primitiveField()

View File

@ -83,6 +83,16 @@ class cyclicFvPatchField
const cyclicFvPatch& cyclicPatch_;
// Private Member Functions
//- Return neighbour side field given internal fields
template<class Type2>
tmp<Field<Type2>> neighbourSideField
(
const Field<Type2>&
) const;
public:
@ -162,9 +172,6 @@ public:
//- Return neighbour coupled internal cell data
virtual tmp<Field<Type>> patchNeighbourField() const;
//- Retrieve neighbour coupled internal cell data
virtual void patchNeighbourField(UList<Type>& pnf) const;
//- Return reference to neighbour patchField
const cyclicFvPatchField<Type>& neighbourPatchField() const;

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2013-2017 OpenFOAM Foundation
Copyright (C) 2019-2025 OpenCFD Ltd.
Copyright (C) 2019-2024 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -91,12 +91,11 @@ Foam::cyclicACMIFvPatchField<Type>::cyclicACMIFvPatchField
// Extra check: make sure that the non-overlap patch is before
// this so it has actually been read - evaluate will crash otherwise
const auto& fld =
const GeometricField<Type, fvPatchField, volMesh>& fld =
static_cast<const GeometricField<Type, fvPatchField, volMesh>&>
(
this->primitiveField()
);
if (!fld.boundaryField().set(cyclicACMIPatch_.nonOverlapPatchID()))
{
FatalIOErrorInFunction(dict)
@ -285,27 +284,32 @@ bool Foam::cyclicACMIFvPatchField<Type>::ready() const
template<class Type>
Foam::tmp<Foam::Field<Type>>
Foam::cyclicACMIFvPatchField<Type>::getNeighbourField
Foam::cyclicACMIFvPatchField<Type>::patchNeighbourField
(
const UList<Type>& internalData
const Field<Type>& iField
) const
{
DebugPout
<< "cyclicACMIFvPatchField::getNeighbourField(const UList<Type>&) :"
<< "cyclicACMIFvPatchField::patchNeighbourField(const Field<Type>&) :"
<< " field:" << this->internalField().name()
<< " patch:" << this->patch().name()
<< endl;
// By pass polyPatch to get nbrId. Instead use cyclicACMIFvPatch virtual
// neighbPatch()
const auto& neighbPatch = cyclicACMIPatch_.neighbPatch();
const cyclicACMIFvPatch& neighbPatch = cyclicACMIPatch_.neighbPatch();
const labelUList& nbrFaceCells = neighbPatch.faceCells();
tmp<Field<Type>> tpnf
(
cyclicACMIPatch_.interpolate
(
Field<Type>(internalData, nbrFaceCells)
Field<Type>
(
iField,
nbrFaceCells
//cpp.neighbPatch().faceCells()
)
)
);
@ -330,18 +334,11 @@ bool Foam::cyclicACMIFvPatchField<Type>::cacheNeighbourField()
template<class Type>
Foam::tmp<Foam::Field<Type>>
Foam::cyclicACMIFvPatchField<Type>::getPatchNeighbourField
(
const bool checkCommunicator
) const
Foam::cyclicACMIFvPatchField<Type>::patchNeighbourField() const
{
const auto& AMI = this->ownerAMI();
if
(
AMI.distributed() && cacheNeighbourField()
&& (!checkCommunicator || AMI.comm() != -1)
)
if (AMI.distributed() && cacheNeighbourField() && AMI.comm() != -1)
{
if (!this->ready())
{
@ -365,7 +362,7 @@ Foam::cyclicACMIFvPatchField<Type>::getPatchNeighbourField
// Do interpolation and store result
patchNeighbourFieldPtr_.reset
(
getNeighbourField(this->primitiveField()).ptr()
patchNeighbourField(this->primitiveField()).ptr()
);
}
else
@ -389,36 +386,16 @@ Foam::cyclicACMIFvPatchField<Type>::getPatchNeighbourField
<< " calculating up-to-date patchNeighbourField"
<< endl;
return getNeighbourField(this->primitiveField());
return patchNeighbourField(this->primitiveField());
}
}
template<class Type>
Foam::tmp<Foam::Field<Type>>
Foam::cyclicACMIFvPatchField<Type>::patchNeighbourField() const
{
return this->getPatchNeighbourField(true); // checkCommunicator = true
}
template<class Type>
void Foam::cyclicACMIFvPatchField<Type>::patchNeighbourField
(
UList<Type>& pnf
) const
{
// checkCommunicator = false
auto tpnf = this->getPatchNeighbourField(false);
pnf.deepCopy(tpnf());
}
template<class Type>
const Foam::cyclicACMIFvPatchField<Type>&
Foam::cyclicACMIFvPatchField<Type>::neighbourPatchField() const
{
const auto& fld =
const GeometricField<Type, fvPatchField, volMesh>& fld =
static_cast<const GeometricField<Type, fvPatchField, volMesh>&>
(
this->primitiveField()
@ -435,7 +412,7 @@ template<class Type>
const Foam::fvPatchField<Type>&
Foam::cyclicACMIFvPatchField<Type>::nonOverlapPatchField() const
{
const auto& fld =
const GeometricField<Type, fvPatchField, volMesh>& fld =
static_cast<const GeometricField<Type, fvPatchField, volMesh>&>
(
this->primitiveField()
@ -554,11 +531,13 @@ void Foam::cyclicACMIFvPatchField<Type>::evaluate
// Receive requests all handled by last function call
recvRequests_.clear();
auto& patchNeighbourField = patchNeighbourFieldPtr_.ref();
if (doTransform())
{
// In-place transform
auto& pnf = *patchNeighbourFieldPtr_;
transform(pnf, forwardT(), pnf);
transform(patchNeighbourField, forwardT(), patchNeighbourField);
}
}

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2013-2016 OpenFOAM Foundation
Copyright (C) 2019-2025 OpenCFD Ltd.
Copyright (C) 2019,2023 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -126,13 +126,16 @@ class cyclicACMIFvPatchField
static bool cacheNeighbourField();
//- Return neighbour coupled internal cell data
tmp<Field<Type>> getNeighbourField(const UList<Type>&) const;
tmp<Field<Type>> patchNeighbourField(const Field<Type>&) const;
//- Return neighbour coupled internal cell data (cached or extracted),
//- with optional check that AMI.comm() is valid.
tmp<Field<Type>> getPatchNeighbourField(bool checkCommunicator) const;
//- Return neighbour side field given internal fields
template<class Type2>
tmp<Field<Type2>> neighbourSideField
(
const Field<Type2>&
) const;
//- Return new matrix coeffs
//- Return new matrix coeffs
tmp<Field<scalar>> coeffs
(
fvMatrix<Type>& matrix,
@ -141,6 +144,7 @@ class cyclicACMIFvPatchField
) const;
public:
//- Runtime type information
@ -242,9 +246,6 @@ public:
//- Return neighbour coupled internal cell data
virtual tmp<Field<Type>> patchNeighbourField() const;
//- Retrieve neighbour coupled internal cell data
virtual void patchNeighbourField(UList<Type>& pnf) const;
//- Return reference to neighbour patchField
const cyclicACMIFvPatchField<Type>& neighbourPatchField() const;

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2017 OpenFOAM Foundation
Copyright (C) 2019-2025 OpenCFD Ltd.
Copyright (C) 2019-2024 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -289,22 +289,22 @@ void Foam::cyclicAMIFvPatchField<Type>::rmap
template<class Type>
Foam::tmp<Foam::Field<Type>>
Foam::cyclicAMIFvPatchField<Type>::getNeighbourField
Foam::cyclicAMIFvPatchField<Type>::patchNeighbourField
(
const UList<Type>& internalData
const Field<Type>& iField
) const
{
// By pass polyPatch to get nbrId. Instead use cyclicAMIFvPatch virtual
// neighbPatch()
const auto& neighbPatch = cyclicAMIPatch_.neighbPatch();
const cyclicAMIFvPatch& neighbPatch = cyclicAMIPatch_.neighbPatch();
const labelUList& nbrFaceCells = neighbPatch.faceCells();
Field<Type> pnf(internalData, nbrFaceCells);
Field<Type> pnf(iField, nbrFaceCells);
Field<Type> defaultValues;
if (cyclicAMIPatch_.applyLowWeightCorrection())
{
defaultValues = Field<Type>(internalData, cyclicAMIPatch_.faceCells());
defaultValues = Field<Type>(iField, cyclicAMIPatch_.faceCells());
}
tmp<Field<Type>> tpnf = cyclicAMIPatch_.interpolate(pnf, defaultValues);
@ -327,18 +327,11 @@ bool Foam::cyclicAMIFvPatchField<Type>::cacheNeighbourField()
template<class Type>
Foam::tmp<Foam::Field<Type>>
Foam::cyclicAMIFvPatchField<Type>::getPatchNeighbourField
(
bool checkCommunicator
) const
Foam::cyclicAMIFvPatchField<Type>::patchNeighbourField() const
{
const auto& AMI = this->ownerAMI();
if
(
AMI.distributed() && cacheNeighbourField()
&& (!checkCommunicator || AMI.comm() != -1)
)
if (AMI.distributed() && cacheNeighbourField() && AMI.comm() != -1)
{
if (!this->ready())
{
@ -379,7 +372,7 @@ Foam::cyclicAMIFvPatchField<Type>::getPatchNeighbourField
// Do interpolation and store result
patchNeighbourFieldPtr_.reset
(
getNeighbourField(this->primitiveField()).ptr()
patchNeighbourField(this->primitiveField()).ptr()
);
}
else
@ -389,7 +382,7 @@ Foam::cyclicAMIFvPatchField<Type>::getPatchNeighbourField
//{
// tmp<Field<Type>> tpnf
// (
// getNeighbourField(this->primitiveField())
// patchNeighbourField(this->primitiveField())
// );
// if (tpnf() != patchNeighbourFieldPtr_())
// {
@ -409,36 +402,16 @@ Foam::cyclicAMIFvPatchField<Type>::getPatchNeighbourField
else
{
// Do interpolation
return getNeighbourField(this->primitiveField());
return patchNeighbourField(this->primitiveField());
}
}
template<class Type>
Foam::tmp<Foam::Field<Type>>
Foam::cyclicAMIFvPatchField<Type>::patchNeighbourField() const
{
return this->getPatchNeighbourField(true); // checkCommunicator = true
}
template<class Type>
void Foam::cyclicAMIFvPatchField<Type>::patchNeighbourField
(
UList<Type>& pnf
) const
{
// checkCommunicator = false
auto tpnf = this->getPatchNeighbourField(false);
pnf.deepCopy(tpnf());
}
template<class Type>
const Foam::cyclicAMIFvPatchField<Type>&
Foam::cyclicAMIFvPatchField<Type>::neighbourPatchField() const
{
const auto& fld =
const GeometricField<Type, fvPatchField, volMesh>& fld =
static_cast<const GeometricField<Type, fvPatchField, volMesh>&>
(
this->primitiveField()
@ -569,11 +542,12 @@ void Foam::cyclicAMIFvPatchField<Type>::evaluate
// Receive requests all handled by last function call
recvRequests_.clear();
auto& patchNeighbourField = patchNeighbourFieldPtr_.ref();
if (doTransform())
{
// In-place transform
auto& pnf = *patchNeighbourFieldPtr_;
transform(pnf, forwardT(), pnf);
transform(patchNeighbourField, forwardT(), patchNeighbourField);
}
}
@ -1008,7 +982,7 @@ void Foam::cyclicAMIFvPatchField<Type>::collectStencilData
forAll(stencil, facei)
{
const auto& slots = stencil[facei];
const labelList& slots = stencil[facei];
expandedData[facei].push_back
(
UIndirectList<typename Type2::value_type>(work, slots)
@ -1019,7 +993,7 @@ void Foam::cyclicAMIFvPatchField<Type>::collectStencilData
{
forAll(stencil, facei)
{
const auto& slots = stencil[facei];
const labelList& slots = stencil[facei];
expandedData[facei].push_back
(
UIndirectList<typename Type2::value_type>(data, slots)
@ -1059,21 +1033,31 @@ void Foam::cyclicAMIFvPatchField<Type>::operator=
// << endl;
const auto* cycPtr = isA<cyclicAMIFvPatchField<Type>>(ptf);
if
(
cycPtr
&& cycPtr->patchNeighbourFieldPtr_
&& cycPtr->patchNeighbourFieldPtr_->size() == this->size()
)
if (cycPtr)
{
if (!patchNeighbourFieldPtr_)
const auto& cyc = *cycPtr;
if
(
cyc.patchNeighbourFieldPtr_
&& cyc.patchNeighbourFieldPtr_->size() == this->size()
)
{
patchNeighbourFieldPtr_ = autoPtr<Field<Type>>::New();
const auto& cycPnf = cyc.patchNeighbourFieldPtr_();
if (patchNeighbourFieldPtr_)
{
// Copy values
patchNeighbourFieldPtr_() = cycPnf;
}
else
{
// Copy values
patchNeighbourFieldPtr_.reset(new Field<Type>(cycPnf));
}
}
else
{
patchNeighbourFieldPtr_.reset(nullptr);
}
// Copy values
*patchNeighbourFieldPtr_ = *(cycPtr->patchNeighbourFieldPtr_);
}
else
{
@ -1097,21 +1081,31 @@ void Foam::cyclicAMIFvPatchField<Type>::operator==
// << endl;
const auto* cycPtr = isA<cyclicAMIFvPatchField<Type>>(ptf);
if
(
cycPtr
&& cycPtr->patchNeighbourFieldPtr_
&& cycPtr->patchNeighbourFieldPtr_->size() == this->size()
)
if (cycPtr)
{
if (!patchNeighbourFieldPtr_)
const auto& cyc = *cycPtr;
if
(
cyc.patchNeighbourFieldPtr_
&& cyc.patchNeighbourFieldPtr_->size() == this->size()
)
{
patchNeighbourFieldPtr_ = autoPtr<Field<Type>>::New();
const auto& cycPnf = cyc.patchNeighbourFieldPtr_();
if (patchNeighbourFieldPtr_)
{
// Copy values
patchNeighbourFieldPtr_() = cycPnf;
}
else
{
// Copy values
patchNeighbourFieldPtr_.reset(new Field<Type>(cycPnf));
}
}
else
{
patchNeighbourFieldPtr_.reset(nullptr);
}
// Copy values
*patchNeighbourFieldPtr_ = *(cycPtr->patchNeighbourFieldPtr_);
}
else
{

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2019-2025 OpenCFD Ltd.
Copyright (C) 2019-2023 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -137,11 +137,15 @@ class cyclicAMIFvPatchField
static bool cacheNeighbourField();
//- Return neighbour coupled internal cell data
tmp<Field<Type>> getNeighbourField(const UList<Type>&) const;
tmp<Field<Type>> patchNeighbourField(const Field<Type>&) const;
//- Return neighbour side field given internal fields
template<class Type2>
tmp<Field<Type2>> neighbourSideField
(
const Field<Type2>&
) const;
//- Return neighbour coupled internal cell data (cached or extracted),
//- with optional check that AMI.comm() is valid.
tmp<Field<Type>> getPatchNeighbourField(bool checkCommunicator) const;
//- Return new matrix coeffs
tmp<Field<scalar>> coeffs
@ -240,9 +244,6 @@ public:
//- Return neighbour coupled internal cell data
virtual tmp<Field<Type>> patchNeighbourField() const;
//- Retrieve neighbour coupled internal cell data
virtual void patchNeighbourField(UList<Type>& pnf) const;
//- Return reference to neighbour patchField
const cyclicAMIFvPatchField<Type>& neighbourPatchField() const;

View File

@ -91,15 +91,16 @@ Foam::jumpCyclicFvPatchField<Type>::jumpCyclicFvPatchField
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class Type>
void Foam::jumpCyclicFvPatchField<Type>::patchNeighbourField
(
UList<Type>& pnf
) const
Foam::tmp<Foam::Field<Type>>
Foam::jumpCyclicFvPatchField<Type>::patchNeighbourField() const
{
const Field<Type>& iField = this->primitiveField();
const labelUList& nbrFaceCells =
this->cyclicPatch().neighbFvPatch().faceCells();
auto tpnf = tmp<Field<Type>>::New(this->size());
auto& pnf = tpnf.ref();
Field<Type> jf(this->jump());
if (!this->cyclicPatch().owner())
{
@ -108,29 +109,22 @@ void Foam::jumpCyclicFvPatchField<Type>::patchNeighbourField
if (this->doTransform())
{
const auto& rot = this->forwardT()[0];
forAll(pnf, i)
forAll(*this, facei)
{
pnf[i] = (transform(rot, iField[nbrFaceCells[i]]) - jf[i]);
pnf[facei] = transform
(
this->forwardT()[0], iField[nbrFaceCells[facei]]
) - jf[facei];
}
}
else
{
forAll(pnf, i)
forAll(*this, facei)
{
pnf[i] = (iField[nbrFaceCells[i]] - jf[i]);
pnf[facei] = iField[nbrFaceCells[facei]] - jf[facei];
}
}
}
template<class Type>
Foam::tmp<Foam::Field<Type>>
Foam::jumpCyclicFvPatchField<Type>::patchNeighbourField() const
{
auto tpnf = tmp<Field<Type>>::New(this->size());
this->patchNeighbourField(tpnf.ref());
return tpnf;
}
@ -182,14 +176,14 @@ void Foam::jumpCyclicFvPatchField<Type>::updateInterfaceMatrix
jf *= -1.0;
}
forAll(pnf, facei)
forAll(*this, facei)
{
pnf[facei] = psiInternal[nbrFaceCells[facei]] - jf[facei];
}
}
else
{
forAll(pnf, facei)
forAll(*this, facei)
{
pnf[facei] = psiInternal[nbrFaceCells[facei]];
}

View File

@ -127,12 +127,9 @@ public:
// Evaluation functions
//- Return neighbour coupled values
//- Return neighbour coupled given internal cell data
virtual tmp<Field<Type>> patchNeighbourField() const;
//- Retrieve neighbour coupled values
virtual void patchNeighbourField(UList<Type>& pnf) const;
//- Update result field based on interface functionality
virtual void updateInterfaceMatrix
(

View File

@ -208,22 +208,6 @@ Foam::processorFvPatchField<Type>::patchNeighbourField() const
}
template<class Type>
void Foam::processorFvPatchField<Type>::patchNeighbourField
(
UList<Type>& pnf
) const
{
if (debug && !this->ready())
{
FatalErrorInFunction
<< "Outstanding request on patch " << procPatch_.name()
<< abort(FatalError);
}
pnf.deepCopy(*this);
}
template<class Type>
void Foam::processorFvPatchField<Type>::initEvaluate
(
@ -232,7 +216,6 @@ void Foam::processorFvPatchField<Type>::initEvaluate
{
if (UPstream::parRun())
{
sendBuf_.resize_nocopy(this->patch().size());
this->patchInternalField(sendBuf_);
if

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2019-2025 OpenCFD Ltd.
Copyright (C) 2019-2023 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -182,12 +182,9 @@ public:
//- Are all (receive) data available?
virtual bool ready() const;
//- Return neighbour field
//- Return neighbour field given internal field
virtual tmp<Field<Type>> patchNeighbourField() const;
//- Retrieve neighbour field
virtual void patchNeighbourField(UList<Type>& pnf) const;
// Evaluation

View File

@ -6,7 +6,6 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2013-2016 OpenFOAM Foundation
Copyright (C) 2025 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -28,6 +27,7 @@ License
#include "symmetryPlaneFvPatchField.H"
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
template<class Type>
@ -120,25 +120,13 @@ template<class Type>
Foam::tmp<Foam::Field<Type>>
Foam::symmetryPlaneFvPatchField<Type>::snGrad() const
{
if constexpr (!is_rotational_vectorspace_v<Type>)
{
// Rotational-invariant type: treat like zero-gradient
return tmp<Field<Type>>::New(this->size(), Foam::zero{});
}
else
{
const symmTensor rot(I - 2.0*sqr(symmetryPlanePatch_.n()));
vector nHat(symmetryPlanePatch_.n());
const Field<Type> pif(this->patchInternalField());
const Field<Type> iF(this->patchInternalField());
const auto& dc = this->patch().deltaCoeffs();
return
(
(0.5*dc)
* (transform(rot, pif) - pif)
);
}
return
(transform(I - 2.0*sqr(nHat), iF) - iF)
*(this->patch().deltaCoeffs()/2.0);
}
@ -150,19 +138,14 @@ void Foam::symmetryPlaneFvPatchField<Type>::evaluate(const Pstream::commsTypes)
this->updateCoeffs();
}
if constexpr (!is_rotational_vectorspace_v<Type>)
{
// Rotational-invariant type: treat like zero-gradient
this->extrapolateInternal();
}
else
{
const symmTensor rot(I - 2.0*sqr(symmetryPlanePatch_.n()));
vector nHat(symmetryPlanePatch_.n());
const Field<Type> pif(this->patchInternalField());
const Field<Type> iF(this->patchInternalField());
Field<Type>::operator=(0.5*(pif + transform(rot, pif)));
}
Field<Type>::operator=
(
(iF + transform(I - 2.0*sqr(nHat), iF))/2.0
);
transformFvPatchField<Type>::evaluate();
}
@ -172,7 +155,9 @@ template<class Type>
Foam::tmp<Foam::Field<Type>>
Foam::symmetryPlaneFvPatchField<Type>::snGradTransformDiag() const
{
const vector diag(cmptMag(symmetryPlanePatch_.n()));
vector nHat(symmetryPlanePatch_.n());
const vector diag(mag(nHat.x()), mag(nHat.y()), mag(nHat.z()));
return tmp<Field<Type>>::New
(

View File

@ -49,8 +49,8 @@ SourceFiles
\*---------------------------------------------------------------------------*/
#ifndef Foam_symmetryPlaneFvPatchField_H
#define Foam_symmetryPlaneFvPatchField_H
#ifndef symmetryPlaneFvPatchField_H
#define symmetryPlaneFvPatchField_H
#include "basicSymmetryFvPatchField.H"
#include "symmetryPlaneFvPatch.H"
@ -61,7 +61,7 @@ namespace Foam
{
/*---------------------------------------------------------------------------*\
Class symmetryPlaneFvPatchField Declaration
Class symmetryPlaneFvPatchField Declaration
\*---------------------------------------------------------------------------*/
template<class Type>
@ -153,6 +153,18 @@ public:
};
// * * * * * * * * * * * Template Specialisations * * * * * * * * * * * * * //
template<>
tmp<scalarField> symmetryPlaneFvPatchField<scalar>::snGrad() const;
template<>
void symmetryPlaneFvPatchField<scalar>::evaluate
(
const Pstream::commsTypes commsType
);
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam

View File

@ -37,4 +37,30 @@ namespace Foam
}
// * * * * * * * * * * * * * * * Specialisations * * * * * * * * * * * * * * //
template<>
Foam::tmp<Foam::scalarField>
Foam::symmetryPlaneFvPatchField<Foam::scalar>::snGrad() const
{
return tmp<scalarField>::New(size(), Zero);
}
template<>
void Foam::symmetryPlaneFvPatchField<Foam::scalar>::evaluate
(
const Pstream::commsTypes
)
{
if (!updated())
{
updateCoeffs();
}
scalarField::operator=(patchInternalField());
transformFvPatchField<scalar>::evaluate();
}
// ************************************************************************* //

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2024-2025 OpenCFD Ltd.
Copyright (C) 2024 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -30,6 +30,7 @@ License
#include "wedgeFvPatchField.H"
#include "transformField.H"
#include "symmTransform.H"
#include "diagTensor.H"
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
@ -119,25 +120,12 @@ Foam::wedgeFvPatchField<Type>::wedgeFvPatchField
template<class Type>
Foam::tmp<Foam::Field<Type>> Foam::wedgeFvPatchField<Type>::snGrad() const
{
if constexpr (!is_rotational_vectorspace_v<Type>)
{
// Rotational-invariant type : treat like zero-gradient
return tmp<Field<Type>>::New(this->size(), Foam::zero{});
}
else
{
const auto& rot = refCast<const wedgeFvPatch>(this->patch()).cellT();
const Field<Type> pif(this->patchInternalField());
const Field<Type> pif(this->patchInternalField());
const auto& dc = this->patch().deltaCoeffs();
return
(
(0.5*dc)
* (transform(rot, pif) - pif)
);
}
return
(
transform(refCast<const wedgeFvPatch>(this->patch()).cellT(), pif) - pif
)*(0.5*this->patch().deltaCoeffs());
}
@ -149,20 +137,14 @@ void Foam::wedgeFvPatchField<Type>::evaluate(const Pstream::commsTypes)
this->updateCoeffs();
}
if constexpr (!is_rotational_vectorspace_v<Type>)
{
// Rotational-invariant type : treat like zero-gradient
this->extrapolateInternal();
}
else
{
const auto& rot = refCast<const wedgeFvPatch>(this->patch()).faceT();
fvPatchField<Type>::operator==
fvPatchField<Type>::operator==
(
transform
(
transform(rot, this->patchInternalField())
);
}
refCast<const wedgeFvPatch>(this->patch()).faceT(),
this->patchInternalField()
)
);
}
@ -170,9 +152,10 @@ template<class Type>
Foam::tmp<Foam::Field<Type>>
Foam::wedgeFvPatchField<Type>::snGradTransformDiag() const
{
const auto& rot = refCast<const wedgeFvPatch>(this->patch()).cellT();
const diagTensor diagT =
0.5*diag(I - refCast<const wedgeFvPatch>(this->patch()).cellT());
const vector diagV = 0.5*(I - rot).diag();
const vector diagV(diagT.xx(), diagT.yy(), diagT.zz());
return tmp<Field<Type>>::New
(

View File

@ -138,7 +138,7 @@ public:
}
// Member Functions
// Member functions
//- Return gradient at boundary
virtual tmp<Field<Type>> snGrad() const;
@ -154,6 +154,18 @@ public:
};
// * * * * * * * * * * * Template Specialisations * * * * * * * * * * * * * //
template<>
tmp<scalarField> wedgeFvPatchField<scalar>::snGrad() const;
template<>
void wedgeFvPatchField<scalar>::evaluate
(
const Pstream::commsTypes commsType
);
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam

View File

@ -37,4 +37,29 @@ namespace Foam
}
// * * * * * * * * * * * * * * * Specialisations * * * * * * * * * * * * * * //
template<>
Foam::tmp<Foam::scalarField>
Foam::wedgeFvPatchField<Foam::scalar>::snGrad() const
{
return tmp<scalarField>::New(size(), Zero);
}
template<>
void Foam::wedgeFvPatchField<Foam::scalar>::evaluate
(
const Pstream::commsTypes
)
{
if (!updated())
{
updateCoeffs();
}
this->operator==(patchInternalField());
}
// ************************************************************************* //

View File

@ -212,13 +212,12 @@ void Foam::flowRateInletVelocityFvPatchVectorField::updateCoeffs()
else
{
// Mass flow-rate
if
(
const auto* rhop
= patch().cfindPatchField<volScalarField>(rhoName_)
)
if (db().foundObject<volScalarField>(rhoName_))
{
updateValues(*rhop);
const auto& rhop =
patch().lookupPatchField<volScalarField>(rhoName_);
updateValues(rhop);
}
else
{

View File

@ -196,13 +196,12 @@ void Foam::flowRateOutletVelocityFvPatchVectorField::updateCoeffs()
else
{
// Mass flow-rate
if
(
const auto* rhop
= patch().cfindPatchField<volScalarField>(rhoName_)
)
if (db().foundObject<volScalarField>(rhoName_))
{
updateValues(*rhop);
const auto& rhop =
patch().lookupPatchField<volScalarField>(rhoName_);
updateValues(rhop);
}
else
{

View File

@ -234,9 +234,11 @@ Foam::fvPatchField<Type>::patchInternalField() const
template<class Type>
void Foam::fvPatchField<Type>::patchInternalField(UList<Type>& pfld) const
void Foam::fvPatchField<Type>::patchInternalField(Field<Type>& pfld) const
{
patch().patchInternalField(internalField_, pfld);
const auto& p = fvPatchFieldBase::patch();
pfld.resize_nocopy(p.size()); // In general this is a no-op
p.patchInternalField(internalField_, pfld);
}

View File

@ -626,9 +626,9 @@ public:
//- Return internal field next to patch
virtual tmp<Field<Type>> patchInternalField() const;
//- Retrieve internal field next to patch
// \param [out] pfld The extracted patch field.
virtual void patchInternalField(UList<Type>& pfld) const;
//- Extract internal field next to patch
// \param [out] pfld The extracted patch field.
virtual void patchInternalField(Field<Type>& pfld) const;
//- Return patchField on the opposite patch of a coupled patch
virtual tmp<Field<Type>> patchNeighbourField() const

View File

@ -33,23 +33,23 @@ License
namespace Foam
{
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
defineTypeNameAndDebug(wedgeFvPatch, 0);
addToRunTimeSelectionTable(fvPatch, wedgeFvPatch, polyPatch);
} // End namespace Foam
// * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * * * * * //
Foam::wedgeFvPatch::wedgeFvPatch
(
const polyPatch& patch,
const fvBoundaryMesh& bm
)
wedgeFvPatch::wedgeFvPatch(const polyPatch& patch, const fvBoundaryMesh& bm)
:
fvPatch(patch, bm),
wedgePolyPatch_(refCast<const wedgePolyPatch>(patch))
{}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// ************************************************************************* //

View File

@ -34,8 +34,8 @@ SourceFiles
\*---------------------------------------------------------------------------*/
#ifndef Foam_wedgeFvPatch_H
#define Foam_wedgeFvPatch_H
#ifndef wedgeFvPatch_H
#define wedgeFvPatch_H
#include "fvPatch.H"
#include "wedgePolyPatch.H"
@ -53,7 +53,7 @@ class wedgeFvPatch
:
public fvPatch
{
// Private Data
// Private data
const wedgePolyPatch& wedgePolyPatch_;
@ -70,21 +70,21 @@ public:
wedgeFvPatch(const polyPatch& patch, const fvBoundaryMesh& bm);
// Member Functions
// Member functions
// Access
// Access
//- Return face transformation tensor
const tensor& faceT() const noexcept
{
return wedgePolyPatch_.faceT();
}
//- Return face transformation tensor
const tensor& faceT() const
{
return wedgePolyPatch_.faceT();
}
//- Return neighbour-cell transformation tensor
const tensor& cellT() const noexcept
{
return wedgePolyPatch_.cellT();
}
//- Return neighbour-cell transformation tensor
const tensor& cellT() const
{
return wedgePolyPatch_.cellT();
}
};

View File

@ -325,26 +325,25 @@ public:
const UList<Type>& internalData
) const;
//- Return the patch field of the GeometricField
//- corresponding to this patch.
template<class GeometricField, class AnyType = bool>
const typename GeometricField::Patch& patchField
(
const GeometricField& gf
) const;
// Lookup
//- Return the patch field of the GeometricField
//- corresponding to this patch.
template<class GeometricField, class AnyType = bool>
const typename GeometricField::Patch&
patchField(const GeometricField& gf) const;
//- Lookup the named field from the local registry and
//- return the patch field corresponding to this patch.
template<class GeometricField, class AnyType = bool>
const typename GeometricField::Patch&
lookupPatchField(const word& name) const;
//- Find the named field (if any) from the local registry and
//- return the patch field corresponding to this patch.
template<class GeometricField>
const typename GeometricField::Patch*
cfindPatchField(const word& name) const;
//- Lookup the named field from the local registry and
//- return the patch field corresponding to this patch.
// N.B. The dummy pointer arguments are used if this function is
// instantiated within a templated function to avoid a bug in gcc.
template<class GeometricField, class AnyType = bool>
const typename GeometricField::Patch& lookupPatchField
(
const word& name,
const GeometricField* = nullptr,
const AnyType* = nullptr
) const;
};

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