Merge branch 'develop' of develop.openfoam.com:Development/OpenFOAM-plus into develop

This commit is contained in:
sergio
2018-12-06 09:06:31 -08:00
94 changed files with 5321 additions and 1427 deletions

View File

@ -16,7 +16,7 @@ cd ${0%/*} && wmakeCheckPwd "$WM_PROJECT_DIR/src" 2>/dev/null || {
#------------------------------------------------------------------------------
# Trigger update of version strings as required
wmakePrintBuild -check || wrmo OpenFOAM/global/global.o 2>/dev/null
wmakeBuildInfo -check || wrmo OpenFOAM/global/global.o 2>/dev/null
wmakeLnInclude -u OpenFOAM
wmakeLnInclude -u OSspecific/"${WM_OSTYPE:-POSIX}"

View File

@ -81,6 +81,7 @@ void Foam::dynamicCode::checkSecurity
<< " allowSystemOperations 1" << nl << nl
<< "to the InfoSwitches setting in the system controlDict." << nl
<< "The system controlDict is any of" << nl << nl
<< " ~/.OpenFOAM/" << OPENFOAM << "/controlDict" << nl
<< " ~/.OpenFOAM/controlDict" << nl
<< " $WM_PROJECT_DIR/etc/controlDict" << nl << endl
<< exit(FatalIOError);

View File

@ -46,18 +46,14 @@ void Foam::functionObjects::writeFile::initStream(Ostream& os) const
Foam::fileName Foam::functionObjects::writeFile::baseFileDir() const
{
fileName baseDir = fileObr_.time().path();
// Put in undecomposed case
// (Note: gives problems for distributed data running)
if (Pstream::parRun())
{
// Put in undecomposed case (Note: gives problems for
// distributed data running)
baseDir = baseDir/".."/functionObject::outputPrefix;
}
else
{
baseDir = baseDir/functionObject::outputPrefix;
}
fileName baseDir =
(
fileObr_.time().globalPath()
/ functionObject::outputPrefix
);
// Append mesh name if not default region
if (isA<polyMesh>(fileObr_))
@ -65,12 +61,11 @@ Foam::fileName Foam::functionObjects::writeFile::baseFileDir() const
const polyMesh& mesh = refCast<const polyMesh>(fileObr_);
if (mesh.name() != polyMesh::defaultRegion)
{
baseDir = baseDir/mesh.name();
baseDir /= mesh.name();
}
}
// Remove any ".."
baseDir.clean();
baseDir.clean(); // Remove unneeded ".."
return baseDir;
}
@ -85,15 +80,18 @@ Foam::fileName Foam::functionObjects::writeFile::baseTimeDir() const
Foam::autoPtr<Foam::OFstream> Foam::functionObjects::writeFile::createFile
(
const word& name,
const scalar time
const scalar time0
) const
{
autoPtr<OFstream> osPtr;
if (Pstream::master() && writeToFile_)
{
const scalar userTime = fileObr_.time().timeToUserTime(time);
const word timeName = Time::timeName(userTime);
const scalar time = useUserTime_ ?
fileObr_.time().timeToUserTime(time0)
: time0;
const word timeName = Time::timeName(time);
fileName outputDir(baseFileDir()/prefix_/timeName);
@ -164,6 +162,7 @@ Foam::functionObjects::writeFile::writeFile
writePrecision_(IOstream::defaultPrecision()),
writeToFile_(true),
writtenHeader_(false),
useUserTime_(true),
startTime_(obr.time().startTime().value())
{}
@ -183,6 +182,7 @@ Foam::functionObjects::writeFile::writeFile
writePrecision_(IOstream::defaultPrecision()),
writeToFile_(true),
writtenHeader_(false),
useUserTime_(true),
startTime_(obr.time().startTime().value())
{
read(dict);
@ -205,6 +205,9 @@ bool Foam::functionObjects::writeFile::read(const dictionary& dict)
writeToFile_ = dict.lookupOrDefault("writeToFile", true);
writeToFile_ = writeToFile_ && Pstream::master();
// Use user time, e.g. CA deg in preference to seconds
useUserTime_ = dict.lookupOrDefault("useUserTime", true);
return true;
}
@ -277,7 +280,10 @@ void Foam::functionObjects::writeFile::writeHeader
void Foam::functionObjects::writeFile::writeTime(Ostream& os) const
{
const scalar timeNow = fileObr_.time().timeOutputValue();
scalar timeNow = useUserTime_ ?
fileObr_.time().timeOutputValue()
: fileObr_.time().value();
os << setw(charWidth()) << Time::timeName(timeNow);
}

View File

@ -82,6 +82,10 @@ protected:
//- Flag to identify whether the header has been written
bool writtenHeader_;
//- Flag to use the specified user time, e.g. CA deg instead
//- of seconds. Default = true
bool useUserTime_;
//- Start time value
scalar startTime_;

View File

@ -119,18 +119,8 @@ Foam::fileNameList searchEtc
bool (*accept)(const Foam::fileName&)
)
{
Foam::fileName version(Foam::getEnv("WM_PROJECT_VERSION"));
// Fallback when WM_PROJECT_VERSION is unset
if (version.empty())
{
#if OPENFOAM
version.assign(std::to_string(OPENFOAM));
#else
version.assign(foamVersion::version);
#endif
}
// Could use foamVersion::api, but this more direct.
const Foam::fileName version(std::to_string(OPENFOAM));
Foam::fileNameList list;
Foam::fileName dir, candidate;

View File

@ -26,8 +26,8 @@ Description
It is important that these are constructed in the appropriate order to
avoid the use of unconstructed data in the global namespace.
This file has the extension .Cver to trigger a Makefile rule that converts
'VERSION\_STRING' and 'BUILD\_STRING' into the appropriate strings.
This file has a '.Cver' extension to trigger a Makefile rule to replace
'BUILD', 'VERSION' tags with the corresponding strings.
\*---------------------------------------------------------------------------*/
@ -48,14 +48,14 @@ const int Foam::foamVersion::api
// Value of PATCH generated by the build-script
const std::string Foam::foamVersion::patch
(
""
"@PATCH@"
);
// Value of the BUILD generated by the build-script
const std::string Foam::foamVersion::build
(
"BUILD_STRING"
"@BUILD@"
);
@ -78,7 +78,7 @@ const std::string Foam::foamVersion::buildArch
// Only required for compatibility
const std::string Foam::foamVersion::version
(
"VERSION_STRING"
"@VERSION@"
);

View File

@ -49,6 +49,7 @@ SourceFiles
#include "pointField.H"
#include "symmTensor.H"
// VTK includes
#include <vtkCellArray.h>
#include <vtkFloatArray.h>
#include <vtkDoubleArray.h>
@ -209,13 +210,36 @@ public:
//- Remapping for some OpenFOAM data types (eg, symmTensor)
// \param data[in,out] The data to be remapped in-place
template<class Type>
inline static void remapTuple(float data[]) {}
//- Remapping for some OpenFOAM data types (eg, symmTensor)
// \param data[in,out] The data to be remapped in-place
template<class Type>
inline static void remapTuple(double data[]) {}
//- Copy/transcribe OpenFOAM data types to VTK format
// This allows a change of data type (float vs double) as well as
// addressing any swapping issues (eg, symmTensor)
//
// \param output[out] The output scratch space. Must be long enough
// to hold the result.
// \param val[in] The input data to copy/transcribe
template<class Type>
inline static void foamToVtkTuple(float output[], const Type& val);
//- Copy/transcribe OpenFOAM data types to VTK format
// This allows a change of data type (float vs double) as well as
// addressing any swapping issues (eg, symmTensor)
//
// \param output[out] The output scratch space. Must be long enough
// to hold the result.
// \param val[in] The input data to copy/transcribe
template<class Type>
inline static void foamToVtkTuple(double output[], const Type& val);
// Field Conversion Functions
//- Copy list to pre-allocated vtk array.
@ -225,7 +249,7 @@ public:
(
vtkFloatArray* array,
const UList<Type>& input,
const label start = 0
vtkIdType start = 0 //!< The write offset into output array
);
//- Create named field initialized to zero
@ -270,7 +294,6 @@ inline void Foam::vtk::Tools::remapTuple<Foam::symmTensor>(double data[])
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace vtk

View File

@ -87,4 +87,34 @@ inline vtkSmartPointer<vtkCellArray> Foam::vtk::Tools::identityVertices
};
template<class Type>
inline void Foam::vtk::Tools::foamToVtkTuple
(
float output[],
const Type& val
)
{
for (direction cmpt=0; cmpt < pTraits<Type>::nComponents; ++cmpt)
{
output[cmpt] = component(val, cmpt);
}
remapTuple<Type>(output);
}
template<class Type>
inline void Foam::vtk::Tools::foamToVtkTuple
(
double output[],
const Type& val
)
{
for (direction cmpt=0; cmpt < pTraits<Type>::nComponents; ++cmpt)
{
output[cmpt] = component(val, cmpt);
}
remapTuple<Type>(output);
}
// ************************************************************************* //

View File

@ -50,12 +50,11 @@ Foam::vtk::Tools::Patch::points(const PatchType& p)
auto vtkpoints = vtkSmartPointer<vtkPoints>::New();
vtkpoints->SetNumberOfPoints(pts.size());
vtkIdType pointId = 0;
vtkIdType pointId = 0;
for (const point& p : pts)
{
vtkpoints->SetPoint(pointId, p.v_);
++pointId;
vtkpoints->SetPoint(pointId++, p.v_);
}
return vtkpoints;
@ -127,8 +126,7 @@ Foam::vtk::Tools::Patch::faceNormals(const PatchType& p)
vtkIdType faceId = 0;
for (const vector& n : norms)
{
array->SetTuple(faceId, n.v_);
++faceId;
array->SetTuple(faceId++, n.v_);
}
return array;
@ -145,7 +143,7 @@ Foam::label Foam::vtk::Tools::transcribeFloatData
(
vtkFloatArray* array,
const UList<Type>& input,
const label start
vtkIdType start
)
{
const int nComp(pTraits<Type>::nComponents);
@ -162,7 +160,7 @@ Foam::label Foam::vtk::Tools::transcribeFloatData
}
const vtkIdType maxSize = array->GetNumberOfTuples();
const vtkIdType endPos = vtkIdType(start) + vtkIdType(input.size());
const vtkIdType endPos = start + vtkIdType(input.size());
if (!maxSize)
{
@ -174,7 +172,7 @@ Foam::label Foam::vtk::Tools::transcribeFloatData
WarningInFunction
<< "vtk array '" << array->GetName()
<< "' copy with out-of-range [0," << long(maxSize) << ")"
<< " starting at " << start
<< " starting at " << long(start)
<< nl;
return 0;
@ -185,23 +183,18 @@ Foam::label Foam::vtk::Tools::transcribeFloatData
<< "vtk array '" << array->GetName()
<< "' copy ends out-of-range (" << long(maxSize) << ")"
<< " using sizing (start,size) = ("
<< start << "," << input.size() << ")"
<< long(start) << "," << input.size() << ")"
<< nl;
return 0;
}
float scratch[nComp];
forAll(input, idx)
{
const Type& t = input[idx];
for (direction d=0; d<nComp; ++d)
{
scratch[d] = component(t, d);
}
remapTuple<Type>(scratch);
float scratch[pTraits<Type>::nComponents];
array->SetTuple(start+idx, scratch);
for (const Type& val : input)
{
foamToVtkTuple(scratch, val);
array->SetTuple(start++, scratch);
}
return input.size();
@ -219,7 +212,7 @@ Foam::vtk::Tools::zeroField
auto data = vtkSmartPointer<vtkFloatArray>::New();
data->SetName(name.c_str());
data->SetNumberOfComponents(int(pTraits<Type>::nComponents));
data->SetNumberOfComponents(static_cast<int>(pTraits<Type>::nComponents));
data->SetNumberOfTuples(size);
data->Fill(0);
@ -239,7 +232,7 @@ Foam::vtk::Tools::convertFieldToVTK
auto data = vtkSmartPointer<vtkFloatArray>::New();
data->SetName(name.c_str());
data->SetNumberOfComponents(int(pTraits<Type>::nComponents));
data->SetNumberOfComponents(static_cast<int>(pTraits<Type>::nComponents));
data->SetNumberOfTuples(fld.size());
transcribeFloatData(data, fld);

View File

@ -123,10 +123,7 @@ void Foam::vtk::internalWriter::writePoints()
}
void Foam::vtk::internalWriter::writeCellsLegacy
(
const globalIndex& pointOffsets
)
void Foam::vtk::internalWriter::writeCellsLegacy(const label pointOffset)
{
const List<uint8_t>& cellTypes = vtuCells_.cellTypes();
const labelList& vertLabels = vtuCells_.vertLabels();
@ -165,7 +162,7 @@ void Foam::vtk::internalWriter::writeCellsLegacy
vtk::vtuSizing::copyVertLabelsLegacy
(
vertLabels,
pointOffsets.localStart()
pointOffset
)
);
}
@ -206,10 +203,7 @@ void Foam::vtk::internalWriter::writeCellsLegacy
}
void Foam::vtk::internalWriter::writeCellsConnectivity
(
const globalIndex& pointOffsets
)
void Foam::vtk::internalWriter::writeCellsConnectivity(const label pointOffset)
{
//
// 'connectivity'
@ -239,7 +233,7 @@ void Foam::vtk::internalWriter::writeCellsConnectivity
vtk::vtuSizing::copyVertLabelsXml
(
vertLabels,
pointOffsets.localStart()
pointOffset
)
);
}
@ -263,12 +257,6 @@ void Foam::vtk::internalWriter::writeCellsConnectivity
const labelList& vertOffsets = vtuCells_.vertOffsets();
label nOffs = vertOffsets.size();
// global connectivity offsets
const globalIndex procOffset
(
vertOffsets.empty() ? 0 : vertOffsets.last()
);
if (parallel_)
{
reduce(nOffs, sumOp<label>());
@ -285,6 +273,12 @@ void Foam::vtk::internalWriter::writeCellsConnectivity
if (parallel_)
{
// processor-local connectivity offsets
const globalIndex procOffset
(
vertOffsets.empty() ? 0 : vertOffsets.last()
);
vtk::writeListParallel(format_.ref(), vertOffsets, procOffset);
}
else
@ -347,10 +341,7 @@ void Foam::vtk::internalWriter::writeCellsConnectivity
}
void Foam::vtk::internalWriter::writeCellsFaces
(
const globalIndex& pointOffsets
)
void Foam::vtk::internalWriter::writeCellsFaces(const label pointOffset)
{
label nFaceLabels = vtuCells_.faceLabels().size();
@ -393,7 +384,7 @@ void Foam::vtk::internalWriter::writeCellsFaces
vtk::vtuSizing::copyFaceLabelsXml
(
faceLabels,
pointOffsets.localStart()
pointOffset
)
);
}
@ -578,12 +569,15 @@ bool Foam::vtk::internalWriter::writeGeometry()
writePoints();
// With addPointCellLabels for the point offsets
const globalIndex globalPointOffset(vtuCells_.nFieldPoints());
// Include addPointCellLabels for the point offsets
const label pointOffset =
(
parallel_ ? globalIndex(vtuCells_.nFieldPoints()).localStart() : 0
);
if (legacy())
{
writeCellsLegacy(globalPointOffset);
writeCellsLegacy(pointOffset);
return true;
}
@ -592,8 +586,8 @@ bool Foam::vtk::internalWriter::writeGeometry()
format().tag(vtk::fileTag::CELLS);
}
writeCellsConnectivity(globalPointOffset);
writeCellsFaces(globalPointOffset);
writeCellsConnectivity(pointOffset);
writeCellsFaces(pointOffset);
if (format_)
{

View File

@ -58,7 +58,6 @@ namespace Foam
{
// Forward declarations
class globalIndex;
class volPointInterpolation;
namespace vtk
@ -96,13 +95,16 @@ class internalWriter
void writePoints();
//- Write cells (connectivity and type), legacy format
void writeCellsLegacy(const globalIndex& pointOffsets);
// \param pointOffset processor-local point offset
void writeCellsLegacy(const label pointOffset);
//- Write cells connectivity
void writeCellsConnectivity(const globalIndex& pointOffsets);
// \param pointOffset processor-local point offset
void writeCellsConnectivity(const label pointOffset);
//- Write cells face streams
void writeCellsFaces(const globalIndex& pointOffsets);
// \param pointOffset processor-local point offset
void writeCellsFaces(const label pointOffset);
//- No copy construct

View File

@ -171,10 +171,7 @@ void Foam::vtk::patchWriter::writePoints()
}
void Foam::vtk::patchWriter::writePolysLegacy
(
const globalIndex& pointOffsets
)
void Foam::vtk::patchWriter::writePolysLegacy(const label pointOffset)
{
const polyBoundaryMesh& patches = mesh_.boundaryMesh();
@ -207,7 +204,7 @@ void Foam::vtk::patchWriter::writePolysLegacy
auto iter = vertLabels.begin();
label off = pointOffsets.localStart();
label off = pointOffset;
for (const label patchId : patchIDs_)
{
@ -245,10 +242,7 @@ void Foam::vtk::patchWriter::writePolysLegacy
}
void Foam::vtk::patchWriter::writePolys
(
const globalIndex& pointOffsets
)
void Foam::vtk::patchWriter::writePolys(const label pointOffset)
{
if (format_)
{
@ -285,7 +279,7 @@ void Foam::vtk::patchWriter::writePolys
auto iter = vertLabels.begin();
label off = pointOffsets.localStart();
label off = pointOffset;
for (const label patchId : patchIDs_)
{
@ -328,9 +322,6 @@ void Foam::vtk::patchWriter::writePolys
labelList vertOffsets(nLocalFaces_);
label nOffs = vertOffsets.size();
// global connectivity offsets
const globalIndex procOffset(nLocalVerts_);
if (parallel_)
{
reduce(nOffs, sumOp<label>());
@ -346,7 +337,12 @@ void Foam::vtk::patchWriter::writePolys
}
label off = procOffset.localStart();
// processor-local connectivity offsets
label off =
(
parallel_ ? globalIndex(nLocalVerts_).localStart() : 0
);
auto iter = vertOffsets.begin();
@ -517,15 +513,18 @@ bool Foam::vtk::patchWriter::writeGeometry()
writePoints();
const globalIndex globalPointOffset(nLocalPoints_);
const label pointOffset =
(
parallel_ ? globalIndex(nLocalPoints_).localStart() : 0
);
if (legacy())
{
writePolysLegacy(globalPointOffset);
writePolysLegacy(pointOffset);
}
else
{
writePolys(globalPointOffset);
writePolys(pointOffset);
}
return true;

View File

@ -55,10 +55,6 @@ SourceFiles
namespace Foam
{
// Forward declarations
class globalIndex;
namespace vtk
{
@ -107,10 +103,12 @@ class patchWriter
void writePoints();
//- Write patch faces, legacy format
void writePolysLegacy(const globalIndex& pointOffsets);
// \param pointOffset processor-local point offset
void writePolysLegacy(const label pointOffset);
//- Write patch faces
void writePolys(const globalIndex& pointOffsets);
// \param pointOffset processor-local point offset
void writePolys(const label pointOffset);
//- No copy construct

View File

@ -24,7 +24,6 @@ License
\*---------------------------------------------------------------------------*/
#include "foamVtkFileWriter.H"
#include "globalIndex.H"
#include "OSspecific.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //

View File

@ -286,7 +286,6 @@ Foam::faAreaMapper::faAreaMapper
:
mesh_(mesh),
mpm_(mpm),
insertedFaces_(false),
direct_(false),
hasUnmapped_(false),
sizeBeforeMapping_(mesh.nFaces()),

View File

@ -68,9 +68,6 @@ class faAreaMapper
//- Reference to mapPolyMesh
const mapPolyMesh& mpm_;
//- Are there any inserted (unmapped) faces
bool insertedFaces_;
//- Is the mapping direct
bool direct_;

View File

@ -65,7 +65,7 @@ Foam::faEdgeMapper::faEdgeMapper
)
:
mesh_(mesh),
mpm_(mpm),
// mpm_(mpm),
sizeBeforeMapping_(mesh.nInternalEdges()),
hasUnmapped_(false),
directAddrPtr_(nullptr)

View File

@ -67,7 +67,7 @@ class faEdgeMapper
const faMesh& mesh_;
//- Reference to mapPolyMesh
const mapPolyMesh& mpm_;
//const mapPolyMesh& mpm_;
//- Old mesh size
label sizeBeforeMapping_;

View File

@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2016 OpenFOAM Foundation
\\/ M anipulation | Copyright (C) 2016 OpenCFD Ltd.
\\/ M anipulation | Copyright (C) 2016-2018 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -25,6 +25,7 @@ License
#include "volRegion.H"
#include "volMesh.H"
#include "cellSet.H"
#include "globalMeshData.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
@ -44,8 +45,9 @@ const Foam::Enum
>
Foam::functionObjects::volRegion::regionTypeNames_
({
{ regionTypes::vrtCellZone, "cellZone" },
{ regionTypes::vrtAll, "all" },
{ regionTypes::vrtCellSet, "cellSet" },
{ regionTypes::vrtCellZone, "cellZone" },
});
@ -73,7 +75,7 @@ Foam::functionObjects::volRegion::volRegion
const dictionary& dict
)
:
mesh_(mesh),
volMesh_(mesh),
regionType_
(
regionTypeNames_.lookupOrDefault
@ -83,7 +85,7 @@ Foam::functionObjects::volRegion::volRegion
regionTypes::vrtAll
)
),
regionName_(polyMesh::defaultRegion),
regionName_(volMesh_.name()),
regionID_(-1)
{
read(dict);
@ -94,12 +96,6 @@ Foam::functionObjects::volRegion::volRegion
}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::functionObjects::volRegion::~volRegion()
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
bool Foam::functionObjects::volRegion::read
@ -107,19 +103,41 @@ bool Foam::functionObjects::volRegion::read
const dictionary& dict
)
{
regionID_ = -1;
cellIds_.clear();
switch (regionType_)
{
case vrtCellSet:
{
dict.readEntry("name", regionName_);
cellIds_ = cellSet(volMesh_, regionName_).sortedToc();
if (nCells() == 0)
{
FatalIOErrorInFunction(dict)
<< regionTypeNames_[regionType_]
<< "(" << regionName_ << "):" << nl
<< " Region has no cells"
<< exit(FatalIOError);
}
break;
}
case vrtCellZone:
{
dict.readEntry("name", regionName_);
regionID_ = mesh_.cellZones().findZoneID(regionName_);
regionID_ = volMesh_.cellZones().findZoneID(regionName_);
if (regionID_ < 0)
{
FatalIOErrorInFunction(dict)
<< "Unknown cell zone name: " << regionName_
<< ". Valid cell zones are: " << mesh_.cellZones().names()
<< ". Valid cell zones : "
<< flatOutput(volMesh_.cellZones().names())
<< exit(FatalIOError);
}
@ -137,6 +155,7 @@ bool Foam::functionObjects::volRegion::read
case vrtAll:
{
regionName_= volMesh_.name();
break;
}
@ -144,7 +163,7 @@ bool Foam::functionObjects::volRegion::read
{
FatalIOErrorInFunction(dict)
<< "Unknown region type. Valid region types are:"
<< regionTypeNames_.sortedToc()
<< flatOutput(regionTypeNames_.names()) << nl
<< exit(FatalIOError);
}
}
@ -155,14 +174,21 @@ bool Foam::functionObjects::volRegion::read
const Foam::labelList& Foam::functionObjects::volRegion::cellIDs() const
{
if (regionType_ == vrtAll)
switch (regionType_)
{
return labelList::null();
}
else
{
return mesh_.cellZones()[regionID_];
case vrtCellSet:
return cellIds_;
break;
case vrtCellZone:
return volMesh_.cellZones()[regionID_];
break;
default:
break;
}
return labelList::null();
}
@ -170,7 +196,7 @@ Foam::label Foam::functionObjects::volRegion::nCells() const
{
if (regionType_ == vrtAll)
{
return mesh_.globalData().nTotalCells();
return volMesh_.globalData().nTotalCells();
}
else
{
@ -183,11 +209,17 @@ Foam::scalar Foam::functionObjects::volRegion::V() const
{
if (regionType_ == vrtAll)
{
return gSum(mesh_.V());
return gSum(volMesh_.V());
}
else
{
return gSum(scalarField(mesh_.V(), cellIDs()));
scalar vol = 0;
for (const label celli : cellIDs())
{
vol += volMesh_.V()[celli];
}
return returnReduce(vol, sumOp<scalar>());
}
}

View File

@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2016 OpenFOAM Foundation
\\/ M anipulation | Copyright (C) 2016 OpenCFD Ltd.
\\/ M anipulation | Copyright (C) 2016-2018 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -54,9 +54,9 @@ Description
Usage
\table
Property | Description | Required | Default value
regionType | cellZone or all | no | all
name | Name of cellZone if required | no |
Property | Description | Required | Default
regionType | Selection type: all/cellSet/cellZone | no | all
name | Name of cellSet/cellZone if required | no |
\endtable
See also
@ -78,7 +78,7 @@ SourceFiles
namespace Foam
{
// Forward declaration of classes
// Forward declarations
class fvMesh;
namespace functionObjects
@ -90,12 +90,16 @@ namespace functionObjects
class volRegion
{
// Private member data
// Private Member Data
const fvMesh& mesh_;
const fvMesh& volMesh_;
//- The cell ids, from cellSet
labelList cellIds_;
// Cache integral properties of the region for writeFileHeader
label nCells_;
scalar V_;
@ -106,8 +110,9 @@ public:
//- Region type enumeration
enum regionTypes
{
vrtCellZone, //!< cell zone
vrtAll //!< all cells
vrtAll, //!< All cells
vrtCellSet, //!< A cellSet
vrtCellZone //!< A cellZone
};
//- Region type names
@ -116,15 +121,15 @@ public:
protected:
// Protected data
// Protected Data
//- Region type
regionTypes regionType_;
//- Region name (patch, zone, etc.)
//- Region name (cellSet, cellZone, ...)
word regionName_;
//- Region ID (patch ID, zone ID, etc.)
//- Region ID (zone ID, ...)
label regionID_;
@ -147,13 +152,13 @@ public:
//- Destructor
virtual ~volRegion();
virtual ~volRegion() = default;
// Public Member Functions
//- Read from dictionary
bool read(const dictionary&);
bool read(const dictionary& dict);
//- Return the region type
inline const regionTypes& regionType() const;
@ -161,7 +166,7 @@ public:
//- Return the local list of cell IDs
const labelList& cellIDs() const;
//- Return the number of cells in the region
//- Return the number of cells selected in the region
label nCells() const;
//- Return total volume of the region

View File

@ -968,15 +968,11 @@ void Foam::isoAdvection::writeIsoFaces
if (!writeIsoFacesToFile_ || !mesh_.time().writeTime()) return;
// Writing isofaces to obj file for inspection, e.g. in paraview
const fileName dirName
const fileName outputFile
(
Pstream::parRun() ?
mesh_.time().path()/".."/"isoFaces"
: mesh_.time().path()/"isoFaces"
);
const word fName
(
word::printf("isoFaces_%012d", mesh_.time().timeIndex())
mesh_.time().globalPath()
/ "isoFaces"
/ word::printf("isoFaces_%012d.obj", mesh_.time().timeIndex())
);
if (Pstream::parRun())
@ -988,8 +984,8 @@ void Foam::isoAdvection::writeIsoFaces
if (Pstream::master())
{
mkDir(dirName);
OBJstream os(dirName/fName + ".obj");
mkDir(outputFile.path());
OBJstream os(outputFile);
Info<< nl << "isoAdvection: writing iso faces to file: "
<< os.name() << nl << endl;
@ -1015,8 +1011,8 @@ void Foam::isoAdvection::writeIsoFaces
}
else
{
mkDir(dirName);
OBJstream os(dirName/fName + ".obj");
mkDir(outputFile.path());
OBJstream os(outputFile);
Info<< nl << "isoAdvection: writing iso faces to file: "
<< os.name() << nl << endl;

View File

@ -59,6 +59,7 @@ flowType/flowType.C
CourantNo/CourantNo.C
PecletNo/PecletNo.C
blendingFactor/blendingFactor.C
momentum/momentum.C
pressure/pressure.C
MachNo/MachNo.C
Curle/Curle.C

View File

@ -54,26 +54,6 @@ namespace functionObjects
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
Foam::fileName
Foam::functionObjects::extractEulerianParticles::dictBaseFileDir() const
{
fileName baseDir(".."); // = mesh_.time().path();
if (Pstream::parRun())
{
// Put in undecomposed case (Note: gives problems for
// distributed data running)
baseDir = baseDir/".."/functionObject::outputPrefix;
}
else
{
baseDir = baseDir/functionObject::outputPrefix;
}
return baseDir;
}
void Foam::functionObjects::extractEulerianParticles::checkFaceZone()
{
DebugInFunction << endl;

View File

@ -184,9 +184,6 @@ protected:
// Protected Member Functions
//- Return the base directory for dictionary output
virtual fileName dictBaseFileDir() const;
//- Check that the faceZone is valid
virtual void checkFaceZone();

View File

@ -0,0 +1,573 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2018 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "momentum.H"
#include "fvMesh.H"
#include "volFields.H"
#include "cellSet.H"
#include "cylindricalRotation.H"
#include "addToRunTimeSelectionTable.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
namespace functionObjects
{
defineTypeNameAndDebug(momentum, 0);
addToRunTimeSelectionTable(functionObject, momentum, dictionary);
}
}
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * * //
template<class GeoField>
Foam::autoPtr<GeoField>
Foam::functionObjects::momentum::newField
(
const word& baseName,
const dimensionSet& dims,
bool registerObject
) const
{
return
autoPtr<GeoField>::New
(
IOobject
(
scopedName(baseName),
time_.timeName(),
mesh_,
IOobject::NO_READ,
IOobject::NO_WRITE,
registerObject
),
mesh_,
dimensioned<typename GeoField::value_type>(dims, Zero)
);
}
void Foam::functionObjects::momentum::calc()
{
initialise();
// When field writing is not enabled we need our local storage
// for the momentum and angular velocity fields
autoPtr<volVectorField> tmomentum, tAngularMom, tAngularVel;
// The base fields required
const auto& U = lookupObject<volVectorField>(UName_);
const auto* rhoPtr = findObject<volScalarField>(rhoName_);
const dimensionedScalar rhoRef("rho", dimDensity, rhoRef_);
// For quantities such as the mass-averaged angular velocity,
// we would calculate the mass per-cell here.
// tmp<volScalarField::Internal> tmass =
// (
// rhoPtr
// ? (mesh_.V() * (*rhoPtr))
// : (mesh_.V() * rhoRef)
// );
// Linear momentum
// ~~~~~~~~~~~~~~~
auto* pmomentum = getObjectPtr<volVectorField>(scopedName("momentum"));
if (!pmomentum)
{
tmomentum = newField<volVectorField>("momentum", dimVelocity*dimMass);
pmomentum = tmomentum.get(); // get(), not release()
}
auto& momentum = *pmomentum;
if (rhoPtr)
{
momentum.ref() = (U * mesh_.V() * (*rhoPtr));
}
else
{
momentum.ref() = (U * mesh_.V() * rhoRef);
}
momentum.correctBoundaryConditions();
// Angular momentum
// ~~~~~~~~~~~~~~~~
auto* pAngularMom =
getObjectPtr<volVectorField>(scopedName("angularMomentum"));
if (hasCsys_ && !pAngularMom)
{
tAngularMom =
newField<volVectorField>("angularMomentum", dimVelocity*dimMass);
pAngularMom = tAngularMom.get(); // get(), not release()
}
else if (!pAngularMom)
{
// Angular momentum not requested, but alias to normal momentum
// to simplify logic when calculating the summations
pAngularMom = pmomentum;
}
auto& angularMom = *pAngularMom;
// Angular velocity
// ~~~~~~~~~~~~~~~~
auto* pAngularVel =
getObjectPtr<volVectorField>(scopedName("angularVelocity"));
if (hasCsys_)
{
if (!pAngularVel)
{
tAngularVel =
newField<volVectorField>("angularVelocity", dimVelocity);
pAngularVel = tAngularVel.get(); // get(), not release()
}
auto& angularVel = *pAngularVel;
// Global to local
angularVel.primitiveFieldRef() =
csys_.invTransform(mesh_.cellCentres(), U.internalField());
angularVel.correctBoundaryConditions();
if (rhoPtr)
{
angularMom.ref() = (angularVel * mesh_.V() * (*rhoPtr));
}
else
{
angularMom.ref() = (angularVel * mesh_.V() * rhoRef);
}
angularMom.correctBoundaryConditions();
}
// Integrate the selection
sumMomentum_ = Zero;
sumAngularMom_ = Zero;
switch (regionType_)
{
case vrtCellSet:
case vrtCellZone:
{
for (const label celli : cellIDs())
{
sumMomentum_ += momentum[celli];
sumAngularMom_ += angularMom[celli];
}
break;
}
case vrtAll:
{
for (label celli=0; celli < mesh_.nCells(); ++celli)
{
sumMomentum_ += momentum[celli];
sumAngularMom_ += angularMom[celli];
}
break;
}
}
reduce(sumMomentum_, sumOp<vector>());
reduce(sumAngularMom_, sumOp<vector>());
}
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
void Foam::functionObjects::momentum::writeFileHeader(Ostream& os)
{
if (!writeToFile() || writtenHeader_)
{
return;
}
if (hasCsys_)
{
writeHeader(os, "Momentum, Angular Momentum");
writeHeaderValue(os, "origin", csys_.origin());
writeHeaderValue(os, "axis", csys_.e3());
}
else
{
writeHeader(os, "Momentum");
}
if (regionType_ != vrtAll)
{
writeHeader
(
os,
"Selection " + regionTypeNames_[regionType_]
+ " = " + regionName_
);
}
writeHeader(os, "");
writeCommented(os, "Time");
writeTabbed(os, "(momentum_x momentum_y momentum_z)");
if (hasCsys_)
{
writeTabbed(os, "(momentum_r momentum_rtheta momentum_axis)");
}
os << endl;
writtenHeader_ = true;
}
void Foam::functionObjects::momentum::initialise()
{
if (initialised_)
{
return;
}
if (!foundObject<volVectorField>(UName_))
{
FatalErrorInFunction
<< "Could not find U: " << UName_ << " in database"
<< exit(FatalError);
}
const auto* pPtr = cfindObject<volScalarField>(pName_);
if (pPtr && pPtr->dimensions() == dimPressure)
{
// Compressible - rho is mandatory
if (!foundObject<volScalarField>(rhoName_))
{
FatalErrorInFunction
<< "Could not find rho:" << rhoName_
<< exit(FatalError);
}
}
initialised_ = true;
}
void Foam::functionObjects::momentum::writeValues(Ostream& os)
{
Log << type() << " " << name() << " write:" << nl;
Log << " Sum of Momentum";
if (regionType_ != vrtAll)
{
Log << ' ' << regionTypeNames_[regionType_]
<< ' ' << regionName_;
}
Log << nl
<< " linear : " << sumMomentum_ << nl;
if (hasCsys_)
{
Log << " angular : " << sumAngularMom_ << nl;
}
if (writeToFile())
{
writeTime(os);
os << tab << sumMomentum_;
if (hasCsys_)
{
os << tab << sumAngularMom_;
}
os << endl;
}
Log << endl;
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::functionObjects::momentum::momentum
(
const word& name,
const Time& runTime,
const dictionary& dict,
bool readFields
)
:
fvMeshFunctionObject(name, runTime, dict),
volRegion(fvMeshFunctionObject::mesh_, dict),
writeFile(mesh_, name, typeName, dict),
sumMomentum_(Zero),
sumAngularMom_(Zero),
UName_(),
pName_(),
rhoName_(),
rhoRef_(1.0),
csys_(),
hasCsys_(false),
writeMomentum_(false),
writeVelocity_(false),
writePosition_(false),
initialised_(false)
{
if (readFields)
{
read(dict);
Log << endl;
}
}
Foam::functionObjects::momentum::momentum
(
const word& name,
const objectRegistry& obr,
const dictionary& dict,
bool readFields
)
:
fvMeshFunctionObject(name, obr, dict),
volRegion(fvMeshFunctionObject::mesh_, dict),
writeFile(mesh_, name, typeName, dict),
sumMomentum_(Zero),
sumAngularMom_(Zero),
UName_(),
pName_(),
rhoName_(),
rhoRef_(1.0),
csys_(),
hasCsys_(false),
writeMomentum_(false),
writeVelocity_(false),
writePosition_(false),
initialised_(false)
{
if (readFields)
{
read(dict);
Log << endl;
}
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
bool Foam::functionObjects::momentum::read(const dictionary& dict)
{
fvMeshFunctionObject::read(dict);
volRegion::read(dict);
writeFile::read(dict);
initialised_ = false;
Info<< type() << " " << name() << ":" << nl;
// Optional entries U and p
UName_ = dict.lookupOrDefault<word>("U", "U");
pName_ = dict.lookupOrDefault<word>("p", "p");
rhoName_ = dict.lookupOrDefault<word>("rho", "rho");
rhoRef_ = dict.lookupOrDefault<scalar>("rhoRef", 1.0);
rhoRef_ = dict.lookupOrDefault<scalar>("rhoRef", 1.0);
hasCsys_ = dict.lookupOrDefault("cylindrical", false);
if (hasCsys_)
{
csys_ = coordSystem::cylindrical(dict);
}
writeMomentum_ = dict.lookupOrDefault("writeMomentum", false);
writeVelocity_ = dict.lookupOrDefault("writeVelocity", false);
writePosition_ = dict.lookupOrDefault("writePosition", false);
Info<<"Integrating for selection: "
<< regionTypeNames_[regionType_]
<< " (" << regionName_ << ")" << nl;
if (writeMomentum_)
{
Info<< " Momentum fields will be written" << endl;
mesh_.objectRegistry::store
(
newField<volVectorField>("momentum", dimVelocity*dimMass)
);
if (hasCsys_)
{
mesh_.objectRegistry::store
(
newField<volVectorField>("angularMomentum", dimVelocity*dimMass)
);
}
}
if (hasCsys_)
{
if (writeVelocity_)
{
Info<< " Angular velocity will be written" << endl;
mesh_.objectRegistry::store
(
newField<volVectorField>("angularVelocity", dimVelocity)
);
}
if (writePosition_)
{
Info<< " Angular position will be written" << endl;
}
}
return true;
}
bool Foam::functionObjects::momentum::execute()
{
calc();
if (Pstream::master())
{
writeFileHeader(file());
writeValues(file());
Log << endl;
}
// Write state/results information
setResult("momentum_x", sumMomentum_[0]);
setResult("momentum_y", sumMomentum_[1]);
setResult("momentum_z", sumMomentum_[2]);
setResult("momentum_r", sumAngularMom_[0]);
setResult("momentum_rtheta", sumAngularMom_[1]);
setResult("momentum_axis", sumAngularMom_[2]);
return true;
}
bool Foam::functionObjects::momentum::write()
{
if (writeMomentum_ || (hasCsys_ && (writeVelocity_ || writePosition_)))
{
Log <<"Writing fields" << nl;
const volVectorField* fieldPtr;
fieldPtr = findObject<volVectorField>(scopedName("momentum"));
if (fieldPtr) fieldPtr->write();
fieldPtr = findObject<volVectorField>(scopedName("angularMomentum"));
if (fieldPtr) fieldPtr->write();
fieldPtr = findObject<volVectorField>(scopedName("angularVelocity"));
if (fieldPtr) fieldPtr->write();
if (hasCsys_ && writePosition_)
{
// Clunky, but currently no simple means of handling
// component-wise conversion and output
auto cyl_r = newField<volScalarField>("cyl_r", dimLength);
auto cyl_t = newField<volScalarField>("cyl_theta", dimless);
auto cyl_z = newField<volScalarField>("cyl_z", dimLength);
// Internal
{
const auto& pts = mesh_.cellCentres();
const label len = pts.size();
UList<scalar>& r = cyl_r->primitiveFieldRef(false);
UList<scalar>& t = cyl_t->primitiveFieldRef(false);
UList<scalar>& z = cyl_z->primitiveFieldRef(false);
for (label i=0; i < len; ++i)
{
point p(csys_.localPosition(pts[i]));
r[i] = p.x();
t[i] = p.y();
z[i] = p.z();
}
}
// Boundary
const polyBoundaryMesh& pbm = mesh_.boundaryMesh();
forAll(pbm, patchi)
{
const auto& pts = pbm[patchi].faceCentres();
const label len = pts.size();
UList<scalar>& r = cyl_r->boundaryFieldRef(false)[patchi];
UList<scalar>& t = cyl_t->boundaryFieldRef(false)[patchi];
UList<scalar>& z = cyl_z->boundaryFieldRef(false)[patchi];
for (label i=0; i < len; ++i)
{
point p(csys_.localPosition(pts[i]));
r[i] = p.x();
t[i] = p.y();
z[i] = p.z();
}
}
cyl_r->write();
cyl_t->write();
cyl_z->write();
}
}
return true;
}
// ************************************************************************* //

View File

@ -0,0 +1,266 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2018 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Class
Foam::functionObjects::momentum
Group
grpFieldFunctionObjects
Description
Calculates linear/angular momentum, reporting integral values
and optionally writing the fields.
Data is written into momentum.dat in the
postProcessing/\<functionObjectName\> directory.
Usage
Example of function object specification:
\verbatim
momentum1
{
type momentum;
libs ("libfieldFunctionObjects.so");
...
log yes;
regionType all;
writeMomentum yes;
writePosition yes;
writeVelocity yes;
cylindrical true;
origin (0 0 0);
e1 (1 0 0);
e3 (0 0 1);
}
\endverbatim
Where the entries comprise:
\table
Property | Description | Required | Default
type | Type name: momentum | yes |
log | Log information to standard output | no | no
writeMomentum | Write (linear, angular) momentum fields | no | no
writePosition | Write angular position component fields | no | no
writeVelocity | Write angular velocity fields | no | no
p | Pressure field name | no | p
U | Velocity field name | no | U
rho | Density field name | no | rho
rhoRef | Reference density (incompressible) | no | 1.0
cylindrical | Use cylindrical coordinates | no | false
origin | Origin for cylindrical coordinates | no |
regionType | Selection type: all/cellSet/cellZone | no | all
name | Name of cellSet/cellZone if required | no |
\endtable
Note
- For incompressible cases, the value of \c rhoRef is used.
- When specifying the cylindrical coordinate system, the rotation
can be specified directly with e1/e2/e3 axes, or via a \c rotation
sub-dictionary
For example,
\verbatim
origin (0 0 0);
rotation
{
type cylindrical;
axis (0 0 1);
}
\endverbatim
See also
Foam::functionObject
Foam::functionObjects::fvMeshFunctionObject
Foam::functionObjects::volRegion
Foam::functionObjects::writeFile
Foam::functionObjects::timeControl
SourceFiles
momentum.C
\*---------------------------------------------------------------------------*/
#ifndef functionObjects_momentum_H
#define functionObjects_momentum_H
#include "fvMeshFunctionObject.H"
#include "writeFile.H"
#include "cylindricalCS.H"
#include "volFieldsFwd.H"
#include "volRegion.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// Forward declarations
class dimensionSet;
namespace functionObjects
{
/*---------------------------------------------------------------------------*\
Class momentum Declaration
\*---------------------------------------------------------------------------*/
class momentum
:
public fvMeshFunctionObject,
public volRegion,
public writeFile
{
// Private Member Functions
//- Calculate the fields and integral values
void calc();
//- Allocate a new zero geometric field
template<class GeoField>
autoPtr<GeoField> newField
(
const word& baseName,
const dimensionSet& dims,
bool registerObject=true
) const;
protected:
// Protected data
//- Integral (linear) momentum
vector sumMomentum_;
//- Integral angular momentum
vector sumAngularMom_;
// Read from dictionary
//- The velocity field name (optional)
word UName_;
//- The pressure field name (optional)
// Only used to determine incompressible/compressible
word pName_;
//- The density field name (optional)
word rhoName_;
//- Reference density (for incompressible)
scalar rhoRef_;
//- Coordinate system for evaluating angular momentum
coordSystem::cylindrical csys_;
//- Are we using the cylindrical coordinate system?
bool hasCsys_;
//- Write fields flag
bool writeMomentum_;
//- Write fields flag
bool writeVelocity_;
//- Write fields flag
bool writePosition_;
//- Initialised flag
bool initialised_;
// Protected Member Functions
//- Initialise the fields
void initialise();
//- Output file header information
virtual void writeFileHeader(Ostream& os);
//- Write momentum data
void writeValues(Ostream& os);
//- No copy construct
momentum(const momentum&) = delete;
//- No copy assignment
void operator=(const momentum&) = delete;
public:
//- Runtime type information
TypeName("momentum");
// Constructors
//- Construct from Time and dictionary
momentum
(
const word& name,
const Time& runTime,
const dictionary& dict,
const bool readFields = true
);
//- Construct from objectRegistry and dictionary
momentum
(
const word& name,
const objectRegistry& obr,
const dictionary& dict,
const bool readFields = true
);
//- Destructor
virtual ~momentum() = default;
// Member Functions
//- Read the momentum data
virtual bool read(const dictionary&);
//- Calculate and report the integral momentum
virtual bool execute();
//- Write the momentum, possibly angular momentum and velocity
virtual bool write();
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace functionObjects
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -646,9 +646,7 @@ bool Foam::functionObjects::streamLineBase::writeToFile()
fileName vtkPath
(
Pstream::parRun()
? time_.path()/".."/functionObject::outputPrefix/"sets"/name()
: time_.path()/functionObject::outputPrefix/"sets"/name()
time_.globalPath()/functionObject::outputPrefix/"sets"/name()
);
if (mesh_.name() != fvMesh::defaultRegion)
{

View File

@ -14,6 +14,7 @@ else()
endif()
include_directories(
${LIB_SRC}/OpenFOAM/include
${LIB_SRC}/OpenFOAM/lnInclude
${LIB_SRC}/OSspecific/${WM_OSTYPE}/lnInclude
${LIB_SRC}/finiteVolume/lnInclude

View File

@ -389,16 +389,12 @@ void Foam::functionObjects::runTimePostPro::scene::saveImage
const Time& runTime = obr_.time();
const fileName relPath
const fileName prefix
(
functionObject::outputPrefix/name_/obr_.time().timeName()
);
fileName prefix
(
Pstream::parRun() ?
runTime.path()/".."/relPath
: runTime.path()/relPath
runTime.globalPath()
/ functionObject::outputPrefix
/ name_
/ runTime.timeName()
);
mkDir(prefix);

View File

@ -127,6 +127,7 @@ bool Foam::functionObjects::systemCall::read(const dictionary& dict)
<< " allowSystemOperations 1" << nl << nl
<< "to the InfoSwitches setting in the system controlDict." << nl
<< "The system controlDict is any of" << nl << nl
<< " ~/.OpenFOAM/" << OPENFOAM << "/controlDict" << nl
<< " ~/.OpenFOAM/controlDict" << nl
<< " $WM_PROJECT_DIR/etc/controlDict" << nl << endl
<< exit(FatalError);

View File

@ -55,28 +55,21 @@ Foam::CloudFunctionObject<CloudType>::CloudFunctionObject
)
:
CloudSubModelBase<CloudType>(modelName, owner, dict, typeName, objectType),
outputDir_(owner.mesh().time().path())
outputDir_()
{
const fileName relPath
// Put in undecomposed case
// (Note: gives problems for distributed data running)
outputDir_ =
(
functionObject::outputPrefix
/cloud::prefix
/owner.name()
/this->modelName()
owner.mesh().time().globalPath()
/ functionObject::outputPrefix
/ cloud::prefix
/ owner.name()
/ this->modelName()
);
if (Pstream::parRun())
{
// Put in undecomposed case (Note: gives problems for
// distributed data running)
outputDir_ = outputDir_/".."/relPath;
}
else
{
outputDir_ = outputDir_/relPath;
}
outputDir_.clean();
outputDir_.clean(); // Remove unneeded ".."
}

View File

@ -2285,8 +2285,7 @@ Foam::label Foam::meshRefinement::findRegions
if (Pstream::master())
{
outputDir =
mesh.time().path()
/ (Pstream::parRun() ? ".." : "")
mesh.time().globalPath()
/ functionObject::outputPrefix
/ mesh.pointsInstance();
outputDir.clean();

View File

@ -148,10 +148,7 @@ void Foam::vtk::indirectPatchWriter::writePoints()
}
void Foam::vtk::indirectPatchWriter::writePolysLegacy
(
const globalIndex& pointOffsets
)
void Foam::vtk::indirectPatchWriter::writePolysLegacy(const label pointOffset)
{
// Connectivity count without additional storage (done internally)
@ -182,7 +179,7 @@ void Foam::vtk::indirectPatchWriter::writePolysLegacy
auto iter = vertLabels.begin();
label off = pointOffsets.localStart();
label off = pointOffset;
{
for (const face& f : pp_.localFaces())
@ -217,10 +214,7 @@ void Foam::vtk::indirectPatchWriter::writePolysLegacy
}
void Foam::vtk::indirectPatchWriter::writePolys
(
const globalIndex& pointOffsets
)
void Foam::vtk::indirectPatchWriter::writePolys(const label pointOffset)
{
if (format_)
{
@ -254,7 +248,7 @@ void Foam::vtk::indirectPatchWriter::writePolys
auto iter = vertLabels.begin();
label off = pointOffsets.localStart();
label off = pointOffset;
{
for (const face& f : pp_.localFaces())
@ -294,9 +288,6 @@ void Foam::vtk::indirectPatchWriter::writePolys
labelList vertOffsets(nLocalFaces_);
label nOffs = vertOffsets.size();
// global connectivity offsets
const globalIndex procOffset(nLocalVerts_);
if (parallel_)
{
reduce(nOffs, sumOp<label>());
@ -311,7 +302,11 @@ void Foam::vtk::indirectPatchWriter::writePolys
}
label off = procOffset.localStart();
// processor-local connectivity offsets
label off =
(
parallel_ ? globalIndex(nLocalVerts_).localStart() : 0
);
auto iter = vertOffsets.begin();
@ -419,15 +414,18 @@ bool Foam::vtk::indirectPatchWriter::writeGeometry()
writePoints();
const globalIndex globalPointOffset(nLocalPoints_);
const label pointOffset =
(
parallel_ ? globalIndex(nLocalPoints_).localStart() : 0
);
if (legacy())
{
writePolysLegacy(globalPointOffset);
writePolysLegacy(pointOffset);
}
else
{
writePolys(globalPointOffset);
writePolys(pointOffset);
}
return true;

View File

@ -54,10 +54,6 @@ SourceFiles
namespace Foam
{
// Forward declarations
class globalIndex;
namespace vtk
{
@ -100,10 +96,12 @@ class indirectPatchWriter
void writePoints();
//- Write patch faces, legacy format
void writePolysLegacy(const globalIndex& pointOffsets);
// \param pointOffset processor-local point offset
void writePolysLegacy(const label pointOffset);
//- Write patch faces
void writePolys(const globalIndex& pointOffsets);
// \param pointOffset processor-local point offset
void writePolys(const label pointOffset);
//- No copy construct

View File

@ -148,10 +148,7 @@ void Foam::vtk::surfaceWriter::writePoints()
}
void Foam::vtk::surfaceWriter::writePolysLegacy
(
const globalIndex& pointOffsets
)
void Foam::vtk::surfaceWriter::writePolysLegacy(const label pointOffset)
{
// Connectivity count without additional storage (done internally)
@ -182,7 +179,7 @@ void Foam::vtk::surfaceWriter::writePolysLegacy
auto iter = vertLabels.begin();
label off = pointOffsets.localStart();
label off = pointOffset;
{
for (const face& f : faces_)
@ -217,10 +214,7 @@ void Foam::vtk::surfaceWriter::writePolysLegacy
}
void Foam::vtk::surfaceWriter::writePolys
(
const globalIndex& pointOffsets
)
void Foam::vtk::surfaceWriter::writePolys(const label pointOffset)
{
if (format_)
{
@ -254,7 +248,7 @@ void Foam::vtk::surfaceWriter::writePolys
auto iter = vertLabels.begin();
label off = pointOffsets.localStart();
label off = pointOffset;
{
for (const face& f : faces_)
@ -294,9 +288,6 @@ void Foam::vtk::surfaceWriter::writePolys
labelList vertOffsets(nLocalFaces_);
label nOffs = vertOffsets.size();
// global connectivity offsets
const globalIndex procOffset(nLocalVerts_);
if (parallel_)
{
reduce(nOffs, sumOp<label>());
@ -311,7 +302,12 @@ void Foam::vtk::surfaceWriter::writePolys
}
label off = procOffset.localStart();
// processor-local connectivity offsets
label off =
(
parallel_ ? globalIndex(nLocalVerts_).localStart() : 0
);
auto iter = vertOffsets.begin();
@ -438,15 +434,18 @@ bool Foam::vtk::surfaceWriter::writeGeometry()
writePoints();
const globalIndex globalPointOffset(nLocalPoints_);
const label pointOffset =
(
parallel_ ? globalIndex(nLocalPoints_).localStart() : 0
);
if (legacy())
{
writePolysLegacy(globalPointOffset);
writePolysLegacy(pointOffset);
}
else
{
writePolys(globalPointOffset);
writePolys(pointOffset);
}
return true;

View File

@ -56,10 +56,6 @@ SourceFiles
namespace Foam
{
// Forward declarations
class globalIndex;
namespace vtk
{
@ -108,10 +104,12 @@ class surfaceWriter
void writePoints();
//- Write patch faces, legacy format
void writePolysLegacy(const globalIndex& pointOffsets);
// \param pointOffset processor-local point offset
void writePolysLegacy(const label pointOffset);
//- Write patch faces
void writePolys(const globalIndex& pointOffsets);
// \param pointOffset processor-local point offset
void writePolys(const label pointOffset);
//- No copy construct

View File

@ -42,8 +42,6 @@ bool Foam::vtk::writeCellSetFaces
{
typedef IndirectList<face> FaceListType;
const globalIndex cellIdOffset(mesh.nCells());
indirectPrimitivePatch pp
(
FaceListType(mesh.faces(), labelList()),
@ -88,22 +86,6 @@ bool Foam::vtk::writeCellSetFaces
// Use these faces
faces.resetAddressing(cellFaces.sortedToc());
// For each face, the corresponding cellID
labelList faceValues(faces.size());
// Cell ID
{
const labelList& faceIds = faces.addressing();
const label off = cellIdOffset.localStart();
forAll(faceValues, facei)
{
faceValues[facei] = cellFaces[faceIds[facei]] + off;
}
}
//-------------------------------------------------------------------------
indirectPatchWriter writer(pp, opts);
@ -115,15 +97,32 @@ bool Foam::vtk::writeCellSetFaces
//-------------------------------------------------------------------------
// CellData - cellID only
// CellData - faceID only
writer.beginCellData(1);
{
writer.beginCellData(1);
// For each face, the corresponding cellID
labelList faceValues(faces.size());
const labelList& faceIds = faces.addressing();
// processor-local cellID offset
const label cellIdOffset =
(
writer.parallel() ? globalIndex(mesh.nCells()).localStart() : 0
);
forAll(faceValues, facei)
{
faceValues[facei] = cellFaces[faceIds[facei]] + cellIdOffset;
}
writer.write("faceID", faceValues);
// End CellData/PointData is implicit
}
// End CellData/PointData is implicit
writer.close();
return true;

View File

@ -42,8 +42,6 @@ bool Foam::vtk::writeFaceSet
{
typedef IndirectList<face> FaceListType;
const globalIndex faceIdOffset(mesh.nFaces());
indirectPrimitivePatch pp
(
FaceListType(mesh.faces(), labelList()),
@ -69,7 +67,17 @@ bool Foam::vtk::writeFaceSet
writer.beginCellData(1);
labelField faceValues(faces.addressing());
faceValues += faceIdOffset.localStart();
// processor-local faceID offset
const label faceIdOffset =
(
writer.parallel() ? globalIndex(mesh.nFaces()).localStart() : 0
);
if (faceIdOffset)
{
faceValues += faceIdOffset;
}
writer.write("faceID", faceValues);

View File

@ -94,8 +94,6 @@ bool Foam::vtk::writePointSet
//-------------------------------------------------------------------------
const globalIndex pointIdOffset(mesh.nPoints());
labelField pointLabels(set.sortedToc());
label numberOfPoints = pointLabels.size();
@ -206,6 +204,8 @@ bool Foam::vtk::writePointSet
if (parallel)
{
const globalIndex pointIdOffset(mesh.nPoints());
vtk::writeListParallel(format.ref(), pointLabels, pointIdOffset);
}
else

View File

@ -29,6 +29,7 @@ surface/cutting/cuttingSurfaceBaseSelection.C
surface/distanceSurface/distanceSurface.C
surface/isoSurface/isoSurface.C
surface/isoSurface/isoSurfaceCell.C
surface/isoSurface/isoSurfaceTopo.C
surface/thresholdCellFaces/thresholdCellFaces.C
surface/triSurfaceMesh/discreteSurface.C
@ -44,6 +45,7 @@ sampledSurface/sampledPatchInternalField/sampledPatchInternalField.C
sampledSurface/sampledPlane/sampledPlane.C
sampledSurface/isoSurface/sampledIsoSurface.C
sampledSurface/isoSurface/sampledIsoSurfaceCell.C
sampledSurface/isoSurface/sampledIsoSurfaceTopo.C
sampledSurface/distanceSurface/sampledDistanceSurface.C
sampledSurface/sampledCuttingPlane/sampledCuttingPlane.C
sampledSurface/sampledCuttingSurface/sampledCuttingSurface.C

View File

@ -195,26 +195,24 @@ Foam::label Foam::probes::prepare()
<< endl;
fileName probeDir;
fileName probeSubDir = name();
if (mesh_.name() != polyMesh::defaultRegion)
{
probeSubDir = probeSubDir/mesh_.name();
}
probeSubDir =
functionObject::outputPrefix/probeSubDir/mesh_.time().timeName();
if (Pstream::parRun())
{
// Put in undecomposed case
// (Note: gives problems for distributed data running)
probeDir = mesh_.time().path()/".."/probeSubDir;
}
else
{
probeDir = mesh_.time().path()/probeSubDir;
}
// Put in undecomposed case
// (Note: gives problems for distributed data running)
fileName probeDir =
(
mesh_.time().globalPath()
/ functionObject::outputPrefix
/ probeSubDir
/ mesh_.time().timeName()
);
probeDir.clean(); // Remove unneeded ".."
// ignore known fields, close streams for fields that no longer exist

View File

@ -97,16 +97,10 @@ Foam::sampledSets::sampledSets
interpolationScheme_(word::null),
writeFormat_(word::null)
{
const fileName relPath(functionObject::outputPrefix/name);
if (Pstream::parRun())
{
outputPath_ = mesh_.time().path()/".."/relPath;
}
else
{
outputPath_ = mesh_.time().path()/relPath;
}
outputPath_ =
(
mesh_.time().globalPath()/functionObject::outputPrefix/name
);
if (mesh_.name() != fvMesh::defaultRegion)
{
@ -136,16 +130,10 @@ Foam::sampledSets::sampledSets
interpolationScheme_(word::null),
writeFormat_(word::null)
{
const fileName relPath(functionObject::outputPrefix/name);
if (Pstream::parRun())
{
outputPath_ = mesh_.time().path()/".."/relPath;
}
else
{
outputPath_ = mesh_.time().path()/relPath;
}
outputPath_ =
(
mesh_.time().globalPath()/functionObject::outputPrefix/name
);
if (mesh_.name() != fvMesh::defaultRegion)
{

View File

@ -844,8 +844,7 @@ Foam::shortestPathSet::shortestPathSet
if (Pstream::master())
{
outputDir =
mesh.time().path()
/ (Pstream::parRun() ? ".." : "")
mesh.time().globalPath()
/ functionObject::outputPrefix
/ mesh.pointsInstance();
outputDir.clean();

View File

@ -0,0 +1,328 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2018 OpenFOAM Foundation
\\/ M anipulation | Copyright (C) 2018 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 "sampledIsoSurfaceTopo.H"
#include "dictionary.H"
#include "volFields.H"
#include "volPointInterpolation.H"
#include "addToRunTimeSelectionTable.H"
#include "fvMesh.H"
#include "isoSurfaceTopo.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
defineTypeNameAndDebug(sampledIsoSurfaceTopo, 0);
addNamedToRunTimeSelectionTable
(
sampledSurface,
sampledIsoSurfaceTopo,
word,
isoSurfaceTopo
);
}
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
bool Foam::sampledIsoSurfaceTopo::updateGeometry() const
{
const fvMesh& fvm = static_cast<const fvMesh&>(mesh());
// No update needed
if (fvm.time().timeIndex() == prevTimeIndex_)
{
return false;
}
prevTimeIndex_ = fvm.time().timeIndex();
// Clear derived data
sampledSurface::clearGeom();
// Use field from database, or try to read it in
const auto* cellFldPtr = fvm.findObject<volScalarField>(isoField_);
if (debug)
{
if (cellFldPtr)
{
InfoInFunction << "Lookup " << isoField_ << endl;
}
else
{
InfoInFunction
<< "Reading " << isoField_
<< " from time " << fvm.time().timeName()
<< endl;
}
}
// For holding the volScalarField read in.
autoPtr<volScalarField> fieldReadPtr;
if (!cellFldPtr)
{
// Bit of a hack. Read field and store.
fieldReadPtr = autoPtr<volScalarField>::New
(
IOobject
(
isoField_,
fvm.time().timeName(),
fvm,
IOobject::MUST_READ,
IOobject::NO_WRITE,
false
),
fvm
);
}
const volScalarField& cellFld =
(fieldReadPtr.valid() ? *fieldReadPtr : *cellFldPtr);
auto tpointFld = volPointInterpolation::New(fvm).interpolate(cellFld);
//- Direct from cell field and point field. Gives bad continuity.
isoSurfaceTopo surf
(
fvm,
cellFld.primitiveField(),
tpointFld().primitiveField(),
isoVal_,
(regularise_ ? isoSurfaceTopo::DIAGCELL : isoSurfaceTopo::NONE)
);
MeshedSurface<face>& mySurface = const_cast<sampledIsoSurfaceTopo&>(*this);
mySurface.transfer(static_cast<meshedSurface&>(surf));
meshCells_ = std::move(surf.meshCells());
// triangulate uses remapFaces()
// - this is somewhat less efficient since it recopies the faces
// that we just created, but we probably don't want to do this
// too often anyhow.
if (triangulate_)
{
labelList faceMap;
mySurface.triangulate(faceMap);
meshCells_ = UIndirectList<label>(meshCells_, faceMap)();
}
if (debug)
{
Pout<< "sampledIsoSurfaceTopo::updateGeometry() : constructed iso:"
<< nl
<< " regularise : " << regularise_ << nl
<< " triangulate : " << triangulate_ << nl
<< " isoField : " << isoField_ << nl
<< " isoValue : " << isoVal_ << nl
<< " points : " << points().size() << nl
<< " faces : " << MeshStorage::size() << nl
<< " cut cells : " << meshCells_.size() << endl;
}
return true;
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::sampledIsoSurfaceTopo::sampledIsoSurfaceTopo
(
const word& name,
const polyMesh& mesh,
const dictionary& dict
)
:
sampledSurface(name, mesh, dict),
MeshStorage(),
isoField_(dict.get<word>("isoField")),
isoVal_(dict.get<scalar>("isoValue")),
regularise_(dict.lookupOrDefault("regularise", true)),
triangulate_(dict.lookupOrDefault("triangulate", false)),
prevTimeIndex_(-1),
meshCells_()
{
if (triangulate_ && !regularise_)
{
FatalIOErrorInFunction(dict) << "Cannot both use regularise"
<< " and triangulate" << exit(FatalIOError);
}
}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::sampledIsoSurfaceTopo::~sampledIsoSurfaceTopo()
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
bool Foam::sampledIsoSurfaceTopo::needsUpdate() const
{
const fvMesh& fvm = static_cast<const fvMesh&>(mesh());
return fvm.time().timeIndex() != prevTimeIndex_;
}
bool Foam::sampledIsoSurfaceTopo::expire()
{
// Clear derived data
sampledSurface::clearGeom();
// Already marked as expired
if (prevTimeIndex_ == -1)
{
return false;
}
// Force update
prevTimeIndex_ = -1;
return true;
}
bool Foam::sampledIsoSurfaceTopo::update()
{
return updateGeometry();
}
Foam::tmp<Foam::scalarField>
Foam::sampledIsoSurfaceTopo::sample
(
const interpolation<scalar>& sampler
) const
{
return sampleOnFaces(sampler);
}
Foam::tmp<Foam::vectorField>
Foam::sampledIsoSurfaceTopo::sample
(
const interpolation<vector>& sampler
) const
{
return sampleOnFaces(sampler);
}
Foam::tmp<Foam::sphericalTensorField>
Foam::sampledIsoSurfaceTopo::sample
(
const interpolation<sphericalTensor>& sampler
) const
{
return sampleOnFaces(sampler);
}
Foam::tmp<Foam::symmTensorField>
Foam::sampledIsoSurfaceTopo::sample
(
const interpolation<symmTensor>& sampler
) const
{
return sampleOnFaces(sampler);
}
Foam::tmp<Foam::tensorField>
Foam::sampledIsoSurfaceTopo::sample
(
const interpolation<tensor>& sampler
) const
{
return sampleOnFaces(sampler);
}
Foam::tmp<Foam::scalarField>
Foam::sampledIsoSurfaceTopo::interpolate
(
const interpolation<scalar>& interpolator
) const
{
return sampleOnPoints(interpolator);
}
Foam::tmp<Foam::vectorField>
Foam::sampledIsoSurfaceTopo::interpolate
(
const interpolation<vector>& interpolator
) const
{
return sampleOnPoints(interpolator);
}
Foam::tmp<Foam::sphericalTensorField>
Foam::sampledIsoSurfaceTopo::interpolate
(
const interpolation<sphericalTensor>& interpolator
) const
{
return sampleOnPoints(interpolator);
}
Foam::tmp<Foam::symmTensorField>
Foam::sampledIsoSurfaceTopo::interpolate
(
const interpolation<symmTensor>& interpolator
) const
{
return sampleOnPoints(interpolator);
}
Foam::tmp<Foam::tensorField>
Foam::sampledIsoSurfaceTopo::interpolate
(
const interpolation<tensor>& interpolator
) const
{
return sampleOnPoints(interpolator);
}
void Foam::sampledIsoSurfaceTopo::print(Ostream& os) const
{
os << "sampledIsoSurfaceTopo: " << name() << " :"
<< " field:" << isoField_
<< " value:" << isoVal_;
//<< " faces:" << faces().size() // possibly no geom yet
//<< " points:" << points().size();
}
// ************************************************************************* //

View File

@ -0,0 +1,291 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2018 OpenFOAM Foundation
\\/ M anipulation | Copyright (C) 2018 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::sampledIsoSurfaceTopo
Description
A sampledSurface defined by a surface of iso value.
To be used in sampleSurfaces / functionObjects. Recalculates iso surface
only if time changes.
This is often embedded as part of a sampled surfaces function object.
Usage
Example of function object partial specification:
\verbatim
surfaces
(
surface1
{
type isoSurfaceTopo;
isoField p;
isoValue 0.0;
}
);
\endverbatim
Where the sub-entries comprise:
\table
Property | Description | Required | Default
type | isoSurfaceTopo | yes |
isoField | field name for obtaining iso-surface | yes |
isoValue | value of iso-surface | yes |
regularise | filter faces | no | true
triangulate | triangulate faces (if regularise) | no | false
\endtable
Note
Does not currently support cell zones.
SourceFiles
sampledIsoSurfaceTopo.C
\*---------------------------------------------------------------------------*/
#ifndef sampledIsoSurfaceTopo_H
#define sampledIsoSurfaceTopo_H
#include "sampledSurface.H"
#include "MeshedSurface.H"
#include "MeshedSurfacesFwd.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class sampledIsoSurfaceTopo Declaration
\*---------------------------------------------------------------------------*/
class sampledIsoSurfaceTopo
:
public sampledSurface,
public MeshedSurface<face>
{
// Private typedefs for convenience
typedef MeshedSurface<face> MeshStorage;
// Private data
//- Field to get isoSurface of
const word isoField_;
//- Iso value
const scalar isoVal_;
//- Whether to coarse
const bool regularise_;
//- Whether to triangulate
const bool triangulate_;
// Recreated for every isoSurface
//- Time at last call, also track it surface needs an update
mutable label prevTimeIndex_;
//- For every triangle/face the original cell in mesh
mutable labelList meshCells_;
// Private Member Functions
//- Create iso surface (if time has changed)
// Do nothing (and return false) if no update was needed
bool updateGeometry() const;
//- Sample volume field onto surface faces
template<class Type>
tmp<Field<Type>> sampleOnFaces
(
const interpolation<Type>& sampler
) const;
//- Interpolate volume field onto surface points
template<class Type>
tmp<Field<Type>> sampleOnPoints
(
const interpolation<Type>& interpolator
) const;
public:
//- Runtime type information
TypeName("sampledIsoSurfaceTopo");
// Constructors
//- Construct from dictionary
sampledIsoSurfaceTopo
(
const word& name,
const polyMesh& mesh,
const dictionary& dict
);
//- Destructor
virtual ~sampledIsoSurfaceTopo();
// Member Functions
//- Does the surface need an update?
virtual bool needsUpdate() const;
//- Mark the surface as needing an update.
// May also free up unneeded data.
// Return false if surface was already marked as expired.
virtual bool expire();
//- Update the surface as required.
// Do nothing (and return false) if no update was needed
virtual bool update();
//- Points of surface
virtual const pointField& points() const
{
return MeshStorage::points();
}
//- Faces of surface
virtual const faceList& faces() const
{
return *this;
}
//- Const access to per-face zone/region information
virtual const labelList& zoneIds() const
{
return Foam::emptyLabelList;
}
//- Face area magnitudes
virtual const vectorField& Sf() const
{
return MeshStorage::Sf();
}
//- Face area magnitudes
virtual const scalarField& magSf() const
{
return MeshStorage::magSf();
}
//- Face centres
virtual const vectorField& Cf() const
{
return MeshStorage::Cf();
}
// Sample
//- Sample volume field onto surface faces
virtual tmp<scalarField> sample
(
const interpolation<scalar>& sampler
) const;
//- Sample volume field onto surface faces
virtual tmp<vectorField> sample
(
const interpolation<vector>& sampler
) const;
//- Sample volume field onto surface faces
virtual tmp<sphericalTensorField> sample
(
const interpolation<sphericalTensor>& sampler
) const;
//- Sample volume field onto surface faces
virtual tmp<symmTensorField> sample
(
const interpolation<symmTensor>& sampler
) const;
//- Sample volume field onto surface faces
virtual tmp<tensorField> sample
(
const interpolation<tensor>& sampler
) const;
// Interpolate
//- Interpolate volume field onto surface points
virtual tmp<scalarField> interpolate
(
const interpolation<scalar>& interpolator
) const;
//- Interpolate volume field onto surface points
virtual tmp<vectorField> interpolate
(
const interpolation<vector>& interpolator
) const;
//- Interpolate volume field onto surface points
virtual tmp<sphericalTensorField> interpolate
(
const interpolation<sphericalTensor>& interpolator
) const;
//- Interpolate volume field onto surface points
virtual tmp<symmTensorField> interpolate
(
const interpolation<symmTensor>& interpolator
) const;
//- Interpolate volume field onto surface points
virtual tmp<tensorField> interpolate
(
const interpolation<tensor>& interpolator
) const;
//- Write
virtual void print(Ostream&) const;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository
#include "sampledIsoSurfaceTopoTemplates.C"
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,95 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2018 OpenFOAM Foundation
\\/ M anipulation | Copyright (C) 2018 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 "sampledIsoSurfaceTopo.H"
#include "isoSurface.H"
#include "volFieldsFwd.H"
#include "pointFields.H"
#include "volPointInterpolation.H"
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
template<class Type>
Foam::tmp<Foam::Field<Type>>
Foam::sampledIsoSurfaceTopo::sampleOnFaces
(
const interpolation<Type>& sampler
) const
{
updateGeometry(); // Recreate geometry if time has changed
return sampledSurface::sampleOnFaces
(
sampler,
meshCells_,
faces(),
points()
);
}
template<class Type>
Foam::tmp<Foam::Field<Type>>
Foam::sampledIsoSurfaceTopo::sampleOnPoints
(
const interpolation<Type>& interpolator
) const
{
updateGeometry(); // Recreate geometry if time has changed
const labelList& elements = meshCells_;
// One value per point
auto tvalues = tmp<Field<Type>>::New(points().size());
auto& values = tvalues.ref();
const faceList& fcs = faces();
const pointField& pts = points();
bitSet pointDone(points().size());
forAll(faces(), cutFacei)
{
const face& f = fcs[cutFacei];
const label celli = elements[cutFacei];
for (const label pointi : f)
{
if (pointDone.set(pointi))
{
values[pointi] = interpolator.interpolate
(
pts[pointi],
celli
);
}
}
}
return tvalues;
}
// ************************************************************************* //

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,266 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2011-2018 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Class
Foam::isoSurfaceTopo
Description
Marching tet iso surface algorithm with optional filtering to keep only
points originating from mesh edges.
SourceFiles
isoSurfaceTopo.C
\*---------------------------------------------------------------------------*/
#ifndef isoSurfaceTopo_H
#define isoSurfaceTopo_H
#include "labelPair.H"
#include "pointIndexHit.H"
#include "PackedBoolList.H"
#include "MeshedSurface.H"
#include "edgeList.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
class polyMesh;
class tetMatcher;
/*---------------------------------------------------------------------------*\
Class isoSurfaceTopo Declaration
\*---------------------------------------------------------------------------*/
class isoSurfaceTopo
:
public MeshedSurface<face>
{
// Private typedefs for convenience
typedef MeshedSurface<face> MeshStorage;
public:
enum filterType
{
NONE, // No filtering
DIAGCELL, // Remove points from face-diagonal and pyramid
// (vertex to cell-centre) edges
CELL // Only remove points from pyramid edges
};
private:
// Private data
enum cellCutType
{
NOTCUT, // Not cut
SPHERE, // All edges to cell centre cut
CUT // Normal cut
};
//- Reference to mesh
const polyMesh& mesh_;
const scalarField& cVals_;
const scalarField& pVals_;
//- Iso value
const scalar iso_;
//- Per point: originating mesh vertex/cc. See encoding above
edgeList pointToVerts_;
//- For every face the original cell in mesh
labelList meshCells_;
//- For every point the originating face in mesh
labelList pointToFace_;
// Private Member Functions
//- Does any edge of triangle cross iso value?
bool isTriCut
(
const triFace& tri,
const scalarField& pointValues
) const;
//- Determine whether cell is cut
cellCutType calcCutType
(
const bool isTet,
const label
) const;
//- Determine for all mesh whether cell is cut
label calcCutTypes
(
tetMatcher& tet,
List<cellCutType>& cellCutTypes
);
//- Generate single point on edge
label generatePoint
(
const label facei,
const bool edgeIsDiag,
const edge& vertices,
DynamicList<edge>& pointToVerts,
DynamicList<label>& pointToFace,
DynamicList<bool>& pointFromDiag,
EdgeMap<label>& vertsToPoint
) const;
//- Generate triangles from tet
void generateTriPoints
(
const label facei,
const FixedList<scalar, 4>& s,
const FixedList<point, 4>& p,
const FixedList<label, 4>& pIndex,
const FixedList<bool, 6>& edgeIsDiag,
DynamicList<edge>& pointToVerts,
DynamicList<label>& pointToFace,
DynamicList<bool>& pointFromDiag,
EdgeMap<label>& vertsToPoint,
DynamicList<label>& verts
) const;
//- Generate triangles from cell
void generateTriPoints
(
const polyMesh& mesh,
const label celli,
const bool isTet,
DynamicList<edge>& pointToVerts,
DynamicList<label>& pointToFace,
DynamicList<bool>& pointFromDiag,
EdgeMap<label>& vertsToPoint,
DynamicList<label>& verts,
DynamicList<label>& faceLabels
) const;
// Simplification
void triangulateOutside
(
const bool filterDiag,
const PrimitivePatch<face, SubList, const pointField&>& pp,
const boolList& pointFromDiag,
const labelList& pointToFace,
const label cellID,
DynamicList<face>& compactFaces,
DynamicList<label>& compactCellIDs
) const;
MeshStorage removeInsidePoints
(
const bool filterDiag,
const MeshStorage& s,
const boolList& pointFromDiag,
const labelList& pointToFace,
const labelList& start, // Per cell:starting tri
DynamicList<label>& pointCompactMap, // Per point the original
DynamicList<label>& compactCellIDs // Per face the cellID
) const;
public:
//- Runtime type information
TypeName("isoSurfaceTopo");
// Constructors
//- Construct from dictionary
isoSurfaceTopo
(
const polyMesh& mesh,
const scalarField& cellValues,
const scalarField& pointValues,
const scalar iso,
const filterType filter = DIAGCELL
);
// Member Functions
//- For every face original cell in mesh
const labelList& meshCells() const
{
return meshCells_;
}
//- For every point originating face (pyramid) in mesh
const labelList& pointToFace() const
{
return pointToFace_;
}
//- Per point: originating mesh vertex/cc. See encoding above<76>
const edgeList& pointToVerts() const
{
return pointToVerts_;
}
//- Interpolates cCoords,pCoords.
template<class Type>
tmp<Field<Type>> interpolate
(
const Field<Type>& cCoords,
const Field<Type>& pCoords
) const;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository
#include "isoSurfaceTopoTemplates.C"
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,91 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2011-2018 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
template<class Type>
Foam::tmp<Foam::Field<Type>>
Foam::isoSurfaceTopo::interpolate
(
const Field<Type>& cellCoords,
const Field<Type>& pointCoords
) const
{
tmp<Field<Type>> tfld(new Field<Type>(pointToVerts_.size()));
Field<Type>& fld = tfld.ref();
forAll(pointToVerts_, i)
{
scalar s0;
Type p0;
{
label v0 = pointToVerts_[i][0];
if (v0 < mesh_.nPoints())
{
s0 = pVals_[v0];
p0 = pointCoords[v0];
}
else
{
label celli = v0-mesh_.nPoints();
s0 = cVals_[celli];
p0 = cellCoords[celli];
}
}
scalar s1;
Type p1;
{
label v1 = pointToVerts_[i][1];
if (v1 < mesh_.nPoints())
{
s1 = pVals_[v1];
p1 = pointCoords[v1];
}
else
{
label celli = v1-mesh_.nPoints();
s1 = cVals_[celli];
p1 = cellCoords[celli];
}
}
scalar d = s1-s0;
if (mag(d) > VSMALL)
{
scalar s = (iso_-s0)/d;
fld[i] = s*p1+(1.0-s)*p0;
}
else
{
fld[i] = 0.5*(p0+p1);
}
}
return tfld;
}
// ************************************************************************* //