TEST: add standalone test application: Test-surface-sampling
This commit is contained in:
parent
1476de89ee
commit
870c6a6924
4
applications/test/surface-sampling/Make/files
Normal file
4
applications/test/surface-sampling/Make/files
Normal file
@ -0,0 +1,4 @@
|
||||
mydebugSurfaceWriter.C
|
||||
Test-surface-sampling.C
|
||||
|
||||
EXE = $(FOAM_USER_APPBIN)/Test-surface-sampling
|
22
applications/test/surface-sampling/Make/options
Normal file
22
applications/test/surface-sampling/Make/options
Normal file
@ -0,0 +1,22 @@
|
||||
EXE_INC = \
|
||||
-I$(LIB_SRC)/finiteVolume/lnInclude \
|
||||
-I$(LIB_SRC)/fileFormats/lnInclude \
|
||||
-I$(LIB_SRC)/surfMesh/lnInclude \
|
||||
-I$(LIB_SRC)/meshTools/lnInclude \
|
||||
-I$(LIB_SRC)/sampling/lnInclude \
|
||||
-I$(LIB_SRC)/TurbulenceModels/turbulenceModels/lnInclude \
|
||||
-I$(LIB_SRC)/TurbulenceModels/incompressible/lnInclude \
|
||||
-I$(LIB_SRC)/transportModels \
|
||||
-I$(LIB_SRC)/transportModels/incompressible/singlePhaseTransportModel
|
||||
|
||||
EXE_LIBS = \
|
||||
-lfiniteVolume \
|
||||
-lfvOptions \
|
||||
-lfileFormats \
|
||||
-lsurfMesh \
|
||||
-lmeshTools \
|
||||
-lsampling \
|
||||
-lturbulenceModels \
|
||||
-lincompressibleTurbulenceModels \
|
||||
-lincompressibleTransportModels \
|
||||
-latmosphericModels
|
275
applications/test/surface-sampling/Test-surface-sampling.C
Normal file
275
applications/test/surface-sampling/Test-surface-sampling.C
Normal file
@ -0,0 +1,275 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2023 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/>.
|
||||
|
||||
Application
|
||||
Test-surface-sampling
|
||||
|
||||
Description
|
||||
Simple test of surface sampling, including timings
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "argList.H"
|
||||
#include "profiling.H"
|
||||
#include "clockTime.H"
|
||||
|
||||
#include "fileName.H"
|
||||
#include "sampledSurfaces.H"
|
||||
#include "IOstreams.H"
|
||||
#include "OSspecific.H"
|
||||
#include "profiling.H"
|
||||
#include "ReadFields.H"
|
||||
#include "volFields.H"
|
||||
|
||||
using namespace Foam;
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
// Main program:
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
argList::addNote
|
||||
(
|
||||
"Loads mesh and fields from latest time and writes multiple times"
|
||||
);
|
||||
|
||||
argList::noFunctionObjects(); // Disallow function objects
|
||||
argList::addVerboseOption("additional verbosity");
|
||||
#include "addProfilingOption.H"
|
||||
|
||||
argList::addOption
|
||||
(
|
||||
"sample",
|
||||
"file",
|
||||
"Name of surface sampling to use (default: test-sample)"
|
||||
);
|
||||
argList::addOption("output", "Begin output iteration (default: 10000)");
|
||||
argList::addOption("count", "Number of writes (default: 1)");
|
||||
|
||||
#include "setRootCase.H"
|
||||
#include "createTime.H"
|
||||
|
||||
const int verbose = args.verbose();
|
||||
const label firstOutput = args.getOrDefault("output", 10000);
|
||||
const label nOutput = args.getOrDefault("count", 1);
|
||||
|
||||
// Select latestTime, including 0 and constant
|
||||
{
|
||||
const auto& times = runTime.times();
|
||||
const label timeIndex = (times.size()-1);
|
||||
|
||||
if (timeIndex < 0)
|
||||
{
|
||||
FatalErrorInFunction
|
||||
<< "No times!"
|
||||
<< exit(FatalError);
|
||||
}
|
||||
|
||||
runTime.setTime(times[timeIndex], timeIndex);
|
||||
}
|
||||
|
||||
// #include "createMesh.H"
|
||||
|
||||
Info << "Create mesh time = " << runTime.timeName() << nl;
|
||||
|
||||
fvMesh mesh
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
polyMesh::defaultRegion,
|
||||
runTime.timeName(),
|
||||
runTime,
|
||||
IOobject::MUST_READ
|
||||
),
|
||||
false
|
||||
);
|
||||
mesh.init(true); // initialise all (lower levels and current)
|
||||
Info<< endl;
|
||||
|
||||
// Like "setSystemMeshDictionaryIO.H"
|
||||
IOobject dictIO = IOobject::selectIO
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
"test-sample",
|
||||
runTime.system(),
|
||||
mesh,
|
||||
IOobject::MUST_READ,
|
||||
IOobject::NO_WRITE,
|
||||
IOobject::NO_REGISTER
|
||||
),
|
||||
args.getOrDefault<fileName>("sample", "")
|
||||
);
|
||||
|
||||
dictionary dictContents = IOdictionary(dictIO);
|
||||
const dictionary* sampleDict = nullptr;
|
||||
|
||||
if (!dictContents.empty())
|
||||
{
|
||||
// Either have 'regular form' (from functionObjects)
|
||||
// in which the sample surfaces are buried one layer deep
|
||||
// or a flattened dictionary
|
||||
|
||||
if (dictContents.front()->dictPtr())
|
||||
{
|
||||
// Appears to be a dictionary of contents
|
||||
// - get the first sub-dictionary with the correct "type"
|
||||
|
||||
for (const entry& e : dictContents)
|
||||
{
|
||||
const dictionary* dptr = e.dictPtr();
|
||||
|
||||
if
|
||||
(
|
||||
dptr
|
||||
&&
|
||||
(
|
||||
sampledSurfaces::typeName
|
||||
== dptr->getOrDefault<word>("type", word::null)
|
||||
)
|
||||
)
|
||||
{
|
||||
sampleDict = dptr;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Probably a flattened dictionary,
|
||||
// just check directly
|
||||
|
||||
if
|
||||
(
|
||||
sampledSurfaces::typeName
|
||||
== dictContents.getOrDefault<word>("type", word::null)
|
||||
)
|
||||
{
|
||||
sampleDict = &dictContents;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!sampleDict)
|
||||
{
|
||||
FatalErrorInFunction
|
||||
<< "Dictionary does not appear to contain type:"
|
||||
<< sampledSurfaces::typeName << nl
|
||||
<< " " << dictIO.objectRelPath() << nl
|
||||
<< exit(FatalError);
|
||||
}
|
||||
|
||||
// Construct from Time and dictionary, without loadFromFiles
|
||||
sampledSurfaces sampling("test-sample", runTime, *sampleDict);
|
||||
|
||||
Info<< "Loaded " << sampling.size() << " surface samplers" << nl;
|
||||
|
||||
if (sampling.empty())
|
||||
{
|
||||
FatalErrorInFunction
|
||||
<< "No surface samplers loaded" << nl
|
||||
<< " " << dictIO.objectRelPath() << nl
|
||||
<< exit(FatalError);
|
||||
}
|
||||
|
||||
|
||||
// Manually read and load files
|
||||
|
||||
// Read objects in time directory
|
||||
IOobjectList objects(mesh, runTime.timeName());
|
||||
|
||||
// Read GeometricFields
|
||||
Info<< nl << "Load fields" << nl;
|
||||
|
||||
#if (OPENFOAM <= 2306)
|
||||
// List of stored objects to clear after (as required)
|
||||
wordHashSet allFields(objects.names());
|
||||
LIFOStack<regIOobject*> storedObjects;
|
||||
|
||||
#undef ReadFields
|
||||
#define ReadFields(FieldType) \
|
||||
readFields<FieldType>(mesh, objects, allFields, storedObjects);
|
||||
#else
|
||||
// List of stored objects to clear after (as required)
|
||||
DynamicList<regIOobject*> storedObjects;
|
||||
|
||||
#undef ReadFields
|
||||
#define ReadFields(FieldType) \
|
||||
readFields<FieldType>(mesh, objects, predicates::always{}, storedObjects);
|
||||
#endif
|
||||
|
||||
// Read volFields
|
||||
ReadFields(volScalarField);
|
||||
ReadFields(volVectorField);
|
||||
ReadFields(volSphericalTensorField);
|
||||
ReadFields(volSymmTensorField);
|
||||
ReadFields(volTensorField);
|
||||
|
||||
// Set fields to AUTO_WRITE (not really necessary for sampling...)
|
||||
for (regIOobject* io : storedObjects)
|
||||
{
|
||||
io->writeOpt(IOobjectOption::AUTO_WRITE);
|
||||
}
|
||||
|
||||
Info<< nl
|
||||
<< "Start " << nOutput << " times starting at "
|
||||
<< firstOutput << nl;
|
||||
|
||||
clockTime timing;
|
||||
|
||||
if (verbose) Info<< "Time:";
|
||||
|
||||
for
|
||||
(
|
||||
label timeIndex = firstOutput, count = 0;
|
||||
count < nOutput;
|
||||
++timeIndex, ++count
|
||||
)
|
||||
{
|
||||
runTime.setTime(timeIndex, timeIndex);
|
||||
if (verbose) Info<< ' ' << runTime.timeName() << flush;
|
||||
sampling.write();
|
||||
}
|
||||
|
||||
if (verbose) Info<< nl;
|
||||
Info<< nl << "Writing took "
|
||||
<< timing.timeIncrement() << "s" << endl;
|
||||
|
||||
//TBD profiling::writeNow();
|
||||
|
||||
// Info<< nl
|
||||
// << "Cleanup newly generated files with" << nl << nl
|
||||
// << " foamListTimes -rm -time "
|
||||
// << firstOutput << ":" << nl
|
||||
// << " foamListTimes -processor -rm -time "
|
||||
// << firstOutput << ":" << nl;
|
||||
|
||||
|
||||
Info<< "\nEnd\n" << endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
473
applications/test/surface-sampling/mydebugSurfaceWriter.C
Normal file
473
applications/test/surface-sampling/mydebugSurfaceWriter.C
Normal file
@ -0,0 +1,473 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2022-2023 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 "mydebugSurfaceWriter.H"
|
||||
#include "globalIndex.H"
|
||||
#include "argList.H"
|
||||
#include "OFstream.H"
|
||||
#include "OSspecific.H"
|
||||
#include "IOmanip.H"
|
||||
#include "Time.H"
|
||||
#include "pointIOField.H"
|
||||
#include "primitivePatch.H"
|
||||
#include "profiling.H"
|
||||
#include "surfaceWriterMethods.H"
|
||||
#include "PrecisionAdaptor.H"
|
||||
#include "addToRunTimeSelectionTable.H"
|
||||
|
||||
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
namespace surfaceWriters
|
||||
{
|
||||
defineTypeName(mydebugWriter);
|
||||
addToRunTimeSelectionTable(surfaceWriter, mydebugWriter, word);
|
||||
addToRunTimeSelectionTable(surfaceWriter, mydebugWriter, wordDict);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
// Type narrowing - base implementation is pass-through
|
||||
template<class Type> struct narrowType
|
||||
{
|
||||
typedef Type type;
|
||||
};
|
||||
|
||||
template<> struct narrowType<double>
|
||||
{
|
||||
typedef float type;
|
||||
};
|
||||
|
||||
template<> struct narrowType<Vector<double>>
|
||||
{
|
||||
typedef Vector<float> type;
|
||||
};
|
||||
|
||||
template<> struct narrowType<SphericalTensor<double>>
|
||||
{
|
||||
typedef SphericalTensor<float> type;
|
||||
};
|
||||
|
||||
template<> struct narrowType<SymmTensor<double>>
|
||||
{
|
||||
typedef SymmTensor<float> type;
|
||||
};
|
||||
|
||||
// FIXME: Not sure why this one seems to be broken...
|
||||
//
|
||||
// template<> struct narrowType<Tensor<double>>
|
||||
// {
|
||||
// typedef Tensor<float> type;
|
||||
// };
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||
|
||||
template<class Type>
|
||||
Foam::tmp<Foam::Field<Type>>
|
||||
Foam::surfaceWriters::mydebugWriter::mergeField
|
||||
(
|
||||
const Field<Type>& fld
|
||||
) const
|
||||
{
|
||||
addProfiling(merge, "debugWriter::merge-field");
|
||||
|
||||
// This is largely identical to surfaceWriter::mergeField()
|
||||
// but with narrowing for communication
|
||||
if (narrowTransfer_ && parallel_ && UPstream::parRun())
|
||||
{
|
||||
// The narrowed type
|
||||
typedef typename narrowType<Type>::type narrowedType;
|
||||
|
||||
// Ensure geometry is also merged
|
||||
merge();
|
||||
|
||||
// Gather all values
|
||||
auto tfield = tmp<Field<Type>>::New();
|
||||
auto& allFld = tfield.ref();
|
||||
|
||||
// Update any expired global index (as required)
|
||||
|
||||
const globalIndex& globIndex =
|
||||
(
|
||||
this->isPointData()
|
||||
? mergedSurf_.pointGlobalIndex()
|
||||
: mergedSurf_.faceGlobalIndex()
|
||||
);
|
||||
|
||||
ConstPrecisionAdaptor<narrowedType, Type> input(fld);
|
||||
PrecisionAdaptor<narrowedType, Type> output(allFld);
|
||||
|
||||
globIndex.gather
|
||||
(
|
||||
input.cref(), // fld,
|
||||
output.ref(), // allFld,
|
||||
UPstream::msgType(),
|
||||
commType_,
|
||||
UPstream::worldComm
|
||||
);
|
||||
|
||||
// Commit adapted content changes
|
||||
input.commit();
|
||||
output.commit();
|
||||
|
||||
// Discard adaptors
|
||||
input.clear();
|
||||
output.clear();
|
||||
|
||||
// Renumber (point data) to correspond to merged points
|
||||
if
|
||||
(
|
||||
UPstream::master()
|
||||
&& this->isPointData()
|
||||
&& mergedSurf_.pointsMap().size()
|
||||
)
|
||||
{
|
||||
inplaceReorder(mergedSurf_.pointsMap(), allFld);
|
||||
allFld.resize(mergedSurf_.points().size());
|
||||
}
|
||||
|
||||
return tfield;
|
||||
}
|
||||
|
||||
return surfaceWriter::mergeField(fld);
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
Foam::surfaceWriters::mydebugWriter::mydebugWriter()
|
||||
:
|
||||
surfaceWriter(),
|
||||
enableMerge_(true),
|
||||
enableWrite_(false),
|
||||
header_(true),
|
||||
narrowTransfer_(false),
|
||||
streamOpt_(IOstreamOption::BINARY)
|
||||
{}
|
||||
|
||||
|
||||
Foam::surfaceWriters::mydebugWriter::mydebugWriter
|
||||
(
|
||||
const dictionary& options
|
||||
)
|
||||
:
|
||||
surfaceWriter(options),
|
||||
enableMerge_(options.getOrDefault("merge", true)),
|
||||
enableWrite_(options.getOrDefault("write", false)),
|
||||
header_(true),
|
||||
narrowTransfer_(options.getOrDefault("narrow", false)),
|
||||
streamOpt_(IOstreamOption::BINARY)
|
||||
{
|
||||
Info<< "Using debug surface writer ("
|
||||
<< (this->isPointData() ? "point" : "face") << " data):"
|
||||
<< " commsType=" << UPstream::commsTypeNames[commType_]
|
||||
<< " merge=" << Switch::name(enableMerge_)
|
||||
<< " write=" << Switch::name(enableWrite_)
|
||||
<< " narrow=" << Switch::name(narrowTransfer_)
|
||||
<< endl;
|
||||
}
|
||||
|
||||
|
||||
Foam::surfaceWriters::mydebugWriter::mydebugWriter
|
||||
(
|
||||
const meshedSurf& surf,
|
||||
const fileName& outputPath,
|
||||
bool parallel,
|
||||
const dictionary& options
|
||||
)
|
||||
:
|
||||
mydebugWriter(options)
|
||||
{
|
||||
open(surf, outputPath, parallel);
|
||||
}
|
||||
|
||||
|
||||
Foam::surfaceWriters::mydebugWriter::mydebugWriter
|
||||
(
|
||||
const pointField& points,
|
||||
const faceList& faces,
|
||||
const fileName& outputPath,
|
||||
bool parallel,
|
||||
const dictionary& options
|
||||
)
|
||||
:
|
||||
mydebugWriter(options)
|
||||
{
|
||||
open(points, faces, outputPath, parallel);
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
void Foam::surfaceWriters::mydebugWriter::serialWriteGeometry
|
||||
(
|
||||
const regIOobject& iopts,
|
||||
const meshedSurf& surf
|
||||
)
|
||||
{
|
||||
const pointField& points = surf.points();
|
||||
const faceList& faces = surf.faces();
|
||||
|
||||
if (verbose_)
|
||||
{
|
||||
if (this->isPointData())
|
||||
{
|
||||
Info<< "Writing points: " << iopts.objectPath() << endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
Info<< "Writing face centres: " << iopts.objectPath() << endl;
|
||||
}
|
||||
}
|
||||
|
||||
// Like regIOobject::writeObject without instance() adaptation
|
||||
// since this would write to e.g. 0/ instead of postProcessing/
|
||||
|
||||
autoPtr<primitivePatch> ppPtr;
|
||||
|
||||
{
|
||||
OFstream os(iopts.objectPath(), streamOpt_);
|
||||
|
||||
if (header_)
|
||||
{
|
||||
iopts.writeHeader(os);
|
||||
}
|
||||
|
||||
if (this->isPointData())
|
||||
{
|
||||
// Just like writeData, but without copying beforehand
|
||||
os << points;
|
||||
}
|
||||
else
|
||||
{
|
||||
ppPtr.reset(new primitivePatch(SubList<face>(faces), points));
|
||||
|
||||
// Just like writeData, but without copying beforehand
|
||||
os << ppPtr().faceCentres();
|
||||
}
|
||||
|
||||
if (header_)
|
||||
{
|
||||
IOobject::writeEndDivider(os);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Foam::fileName Foam::surfaceWriters::mydebugWriter::write()
|
||||
{
|
||||
checkOpen();
|
||||
|
||||
// Geometry: rootdir/surfaceName/"points"
|
||||
// Field: rootdir/surfaceName/<TIME>/field
|
||||
|
||||
fileName surfaceDir = outputPath_;
|
||||
|
||||
if (parallel_ && !enableMerge_)
|
||||
{
|
||||
if (verbose_)
|
||||
{
|
||||
Info<< "Not merging or writing" << nl;
|
||||
}
|
||||
|
||||
// Pretend to have succeeded
|
||||
wroteGeom_ = true;
|
||||
return surfaceDir;
|
||||
}
|
||||
|
||||
|
||||
const meshedSurf& surf = surface();
|
||||
// const meshedSurfRef& surf = adjustSurface();
|
||||
|
||||
// Dummy Time to use as objectRegistry
|
||||
autoPtr<Time> dummyTimePtr;
|
||||
|
||||
if (enableWrite_)
|
||||
{
|
||||
dummyTimePtr = Time::New(argList::envGlobalPath());
|
||||
}
|
||||
else if (verbose_)
|
||||
{
|
||||
Info<< "Not writing: " << surf.faces().size() << " faces" << nl;
|
||||
}
|
||||
|
||||
if (enableWrite_ && (UPstream::master() || !parallel_))
|
||||
{
|
||||
if (!isDir(surfaceDir))
|
||||
{
|
||||
mkDir(surfaceDir);
|
||||
}
|
||||
|
||||
// Write sample locations
|
||||
pointIOField iopts
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
surfaceDir/"points",
|
||||
*dummyTimePtr,
|
||||
IOobjectOption::NO_READ,
|
||||
IOobjectOption::NO_WRITE,
|
||||
IOobjectOption::NO_REGISTER
|
||||
)
|
||||
);
|
||||
iopts.note() = (this->isPointData() ? "point data" : "face data");
|
||||
|
||||
serialWriteGeometry(iopts, surf);
|
||||
}
|
||||
|
||||
wroteGeom_ = true;
|
||||
return surfaceDir;
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
template<class Type>
|
||||
Foam::fileName Foam::surfaceWriters::mydebugWriter::writeTemplate
|
||||
(
|
||||
const word& fieldName,
|
||||
const Field<Type>& localValues
|
||||
)
|
||||
{
|
||||
checkOpen();
|
||||
|
||||
// Geometry: rootdir/surfaceName/"points"
|
||||
// Field: rootdir/surfaceName/<TIME>/field
|
||||
|
||||
fileName surfaceDir = outputPath_;
|
||||
|
||||
const fileName outputFile(surfaceDir/timeName()/fieldName);
|
||||
|
||||
if (parallel_ && !enableMerge_)
|
||||
{
|
||||
if (verbose_)
|
||||
{
|
||||
Info<< "Not merging or writing" << nl;
|
||||
}
|
||||
|
||||
// Pretend to have succeeded
|
||||
wroteGeom_ = true;
|
||||
return surfaceDir;
|
||||
}
|
||||
|
||||
|
||||
// Implicit geometry merge()
|
||||
tmp<Field<Type>> tfield = mergeField(localValues);
|
||||
|
||||
// Dummy Time to use as objectRegistry
|
||||
autoPtr<Time> dummyTimePtr;
|
||||
|
||||
if (enableWrite_)
|
||||
{
|
||||
dummyTimePtr = Time::New(argList::envGlobalPath());
|
||||
}
|
||||
else if (verbose_)
|
||||
{
|
||||
Info<< "Not writing: " << tfield().size()
|
||||
<< ' ' << pTraits<Type>::typeName
|
||||
<< " values" << nl;
|
||||
}
|
||||
|
||||
const meshedSurf& surf = surface();
|
||||
// const meshedSurfRef& surf = adjustSurface();
|
||||
|
||||
if (enableWrite_ && (UPstream::master() || !parallel_))
|
||||
{
|
||||
if (!isDir(outputFile.path()))
|
||||
{
|
||||
mkDir(outputFile.path());
|
||||
}
|
||||
|
||||
// Write sample locations
|
||||
{
|
||||
pointIOField iopts
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
surfaceDir/"points",
|
||||
*dummyTimePtr,
|
||||
IOobjectOption::NO_READ,
|
||||
IOobjectOption::NO_WRITE,
|
||||
IOobjectOption::NO_REGISTER
|
||||
)
|
||||
);
|
||||
iopts.note() = (this->isPointData() ? "point data" : "face data");
|
||||
|
||||
serialWriteGeometry(iopts, surf);
|
||||
}
|
||||
|
||||
// Write field
|
||||
{
|
||||
IOField<Type> iofld
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
outputFile,
|
||||
*dummyTimePtr,
|
||||
IOobjectOption::NO_READ,
|
||||
IOobjectOption::NO_WRITE,
|
||||
IOobjectOption::NO_REGISTER
|
||||
)
|
||||
);
|
||||
iofld.note() = (this->isPointData() ? "point data" : "face data");
|
||||
|
||||
OFstream os(iofld.objectPath(), streamOpt_);
|
||||
|
||||
if (header_)
|
||||
{
|
||||
iofld.writeHeader(os);
|
||||
}
|
||||
|
||||
// Just like writeData, but without copying beforehand
|
||||
os << tfield();
|
||||
|
||||
if (header_)
|
||||
{
|
||||
IOobject::writeEndDivider(os);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
wroteGeom_ = true;
|
||||
return surfaceDir;
|
||||
}
|
||||
|
||||
|
||||
// Field writing methods
|
||||
defineSurfaceWriterWriteFields(Foam::surfaceWriters::mydebugWriter);
|
||||
|
||||
|
||||
// ************************************************************************* //
|
185
applications/test/surface-sampling/mydebugSurfaceWriter.H
Normal file
185
applications/test/surface-sampling/mydebugSurfaceWriter.H
Normal file
@ -0,0 +1,185 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2022-2023 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::surfaceWriters::mydebugWriter
|
||||
|
||||
Description
|
||||
A surfaceWriter for special purpose debugging.
|
||||
Its definition and behaviour are subject to change at any time.
|
||||
|
||||
\verbatim
|
||||
formatOptions
|
||||
{
|
||||
debug
|
||||
{
|
||||
merge true;
|
||||
write true;
|
||||
}
|
||||
}
|
||||
\endverbatim
|
||||
|
||||
Format options:
|
||||
\table
|
||||
Property | Description | Required | Default
|
||||
commsType | blocking/nonBlocking/scheduled | no | scheduled
|
||||
merge | Enable geometry/field merging | no | true
|
||||
write | Write file(s) | no | false
|
||||
narrow | Communicate with narrowed values | no | false
|
||||
\endtable
|
||||
|
||||
Note
|
||||
Disabling geometry/field merging (in parallel) implicitly deactivates
|
||||
writing as well.
|
||||
|
||||
Output files (if any) are written as boundaryData (binary + header).
|
||||
|
||||
SourceFiles
|
||||
mydebugSurfaceWriter.C
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef Foam_mydebugSurfaceWriter_H
|
||||
#define Foam_mydebugSurfaceWriter_H
|
||||
|
||||
#include "surfaceWriter.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
// Forward Declarations
|
||||
class regIOobject;
|
||||
|
||||
namespace surfaceWriters
|
||||
{
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class debugWriter Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
class mydebugWriter
|
||||
:
|
||||
public surfaceWriter
|
||||
{
|
||||
// Private Data
|
||||
|
||||
//- Enable/disable all merging in parallel
|
||||
bool enableMerge_;
|
||||
|
||||
//- Output writing?
|
||||
bool enableWrite_;
|
||||
|
||||
//- Output files with FoamFile header
|
||||
bool header_;
|
||||
|
||||
//- Communicate with narrowed values
|
||||
bool narrowTransfer_;
|
||||
|
||||
//- Output stream option
|
||||
IOstreamOption streamOpt_;
|
||||
|
||||
|
||||
// Private Member Functions
|
||||
|
||||
//- Write serial surface geometry to "points" file.
|
||||
void serialWriteGeometry(const regIOobject&, const meshedSurf& surf);
|
||||
|
||||
//- Gather (merge) fields with renumbering and shrinking for point data
|
||||
template<class Type>
|
||||
tmp<Field<Type>> mergeField(const Field<Type>& fld) const;
|
||||
|
||||
//- Templated write operation
|
||||
template<class Type>
|
||||
fileName writeTemplate
|
||||
(
|
||||
const word& fieldName, //!< Name of field
|
||||
const Field<Type>& localValues //!< Local field values to write
|
||||
);
|
||||
|
||||
|
||||
public:
|
||||
|
||||
//- Declare type-name, virtual type (without debug switch)
|
||||
TypeNameNoDebug("mydebug");
|
||||
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Default construct
|
||||
mydebugWriter();
|
||||
|
||||
//- Construct with some output options
|
||||
explicit mydebugWriter(const dictionary& options);
|
||||
|
||||
//- Construct from components
|
||||
mydebugWriter
|
||||
(
|
||||
const meshedSurf& surf,
|
||||
const fileName& outputPath,
|
||||
bool parallel = UPstream::parRun(),
|
||||
const dictionary& options = dictionary()
|
||||
);
|
||||
|
||||
//- Construct from components
|
||||
mydebugWriter
|
||||
(
|
||||
const pointField& points,
|
||||
const faceList& faces,
|
||||
const fileName& outputPath,
|
||||
bool parallel = UPstream::parRun(),
|
||||
const dictionary& options = dictionary()
|
||||
);
|
||||
|
||||
|
||||
//- Destructor
|
||||
virtual ~mydebugWriter() = default;
|
||||
|
||||
|
||||
// Member Functions
|
||||
|
||||
//- Write surface geometry to file.
|
||||
virtual fileName write(); // override
|
||||
|
||||
declareSurfaceWriterWriteMethod(label);
|
||||
declareSurfaceWriterWriteMethod(scalar);
|
||||
declareSurfaceWriterWriteMethod(vector);
|
||||
declareSurfaceWriterWriteMethod(sphericalTensor);
|
||||
declareSurfaceWriterWriteMethod(symmTensor);
|
||||
declareSurfaceWriterWriteMethod(tensor);
|
||||
};
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace surfaceWriters
|
||||
} // End namespace Foam
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
Loading…
Reference in New Issue
Block a user