Commit ba771d19 authored by Mark Olesen's avatar Mark Olesen
Browse files

sampling reworking

- write geometry file if no fields would be sampled
- write geometry file only once for obj, stl formats and use MeshedSurfaceProxy
  for writing
parent fadf4280
......@@ -81,7 +81,7 @@ public:
const coordSet&,
const wordList&,
const List<const Field<Type>*>&,
Ostream& os
Ostream&
) const;
};
......
......@@ -32,7 +32,7 @@ License
namespace Foam
{
makeSetWriters(gnuplotSetWriter)
makeSetWriters(gnuplotSetWriter);
}
// ************************************************************************* //
......@@ -54,7 +54,7 @@ class jplotSetWriter
// Private Member Functions
//- Write header
Ostream& writeHeader(Ostream& os) const;
Ostream& writeHeader(Ostream&) const;
public:
......@@ -85,7 +85,7 @@ public:
const coordSet&,
const wordList&,
const List<const Field<Type>*>&,
Ostream& os
Ostream&
) const;
};
......
......@@ -32,7 +32,7 @@ License
namespace Foam
{
makeSetWriters(jplotSetWriter)
makeSetWriters(jplotSetWriter);
}
// ************************************************************************* //
......@@ -81,7 +81,7 @@ public:
const coordSet&,
const wordList&,
const List<const Field<Type>*>&,
Ostream& os
Ostream&
) const;
};
......
......@@ -32,7 +32,7 @@ License
namespace Foam
{
makeSetWriters(rawSetWriter)
makeSetWriters(rawSetWriter);
}
// ************************************************************************* //
......@@ -91,22 +91,12 @@ protected:
//- Generates filename from coordSet and sampled fields
fileName getBaseName(const coordSet&, const wordList&) const;
void writeCoord
(
const coordSet& samples,
const label sampleI,
Ostream& os
) const;
void writeCoord(const coordSet&, const label sampleI, Ostream&) const;
//- Writes single-column ascii write. Column 1 is coordSet coordinate,
// columns 2 is the value. Uses write() function
// to write coordinate in correct format.
void writeTable
(
const coordSet&,
const List<Type>&,
Ostream& os
) const;
void writeTable(const coordSet&, const List<Type>&, Ostream&) const;
//- Writes multi-column ascii write. Column 1 is coordSet coordinate,
// columns 2..n are the values. Uses write() function
......@@ -139,10 +129,7 @@ public:
// Selectors
//- Return a reference to the selected writer
static autoPtr<writer> New
(
const word& writeFormat
);
static autoPtr<writer> New(const word& writeFormat);
// Constructors
......@@ -165,8 +152,8 @@ public:
) const = 0;
//- General entry point for writing.
// The data is organized in a set of point with one or
// more values per point
// The data is organized in a set of point with one or more values
// per point
virtual void write
(
const coordSet&,
......@@ -179,7 +166,7 @@ public:
virtual Ostream& write(const scalar, Ostream&) const;
template<class VSType>
Ostream& writeVS(const VSType& value, Ostream& os) const;
Ostream& writeVS(const VSType&, Ostream&) const;
//- Write vector. Tab separated ascii
virtual Ostream& write(const vector&, Ostream&) const;
......
......@@ -40,27 +40,27 @@ SourceFiles
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// Only used internally
#define makeTypeSetWritersTypeName(typeWriter, dataType) \
\
defineNamedTemplateTypeNameAndDebug(typeWriter<dataType >, 0);
#define makeTypeSetWritersTypeName(typeWriter, dataType) \
\
defineNamedTemplateTypeNameAndDebug(typeWriter< dataType >, 0)
// Sometimes used externally
#define makeSetWritersTypeName(typeWriter) \
\
makeTypeSetWritersTypeName(typeWriter, scalar); \
makeTypeSetWritersTypeName(typeWriter, vector); \
makeTypeSetWritersTypeName(typeWriter, sphericalTensor); \
makeTypeSetWritersTypeName(typeWriter, symmTensor); \
makeTypeSetWritersTypeName(typeWriter, tensor);
#define makeSetWritersTypeName(typeWriter) \
\
makeTypeSetWritersTypeName(typeWriter, scalar); \
makeTypeSetWritersTypeName(typeWriter, vector); \
makeTypeSetWritersTypeName(typeWriter, sphericalTensor); \
makeTypeSetWritersTypeName(typeWriter, symmTensor); \
makeTypeSetWritersTypeName(typeWriter, tensor)
// Define type info for single dataType template instantiation (eg, vector)
#define makeSetWriterType(typeWriter, dataType) \
\
defineNamedTemplateTypeNameAndDebug(typeWriter<dataType >, 0); \
addTemplatedToRunTimeSelectionTable \
( \
writer, typeWriter, dataType, word \
);
#define makeSetWriterType(typeWriter, dataType) \
\
defineNamedTemplateTypeNameAndDebug(typeWriter< dataType >, 0); \
addTemplatedToRunTimeSelectionTable \
( \
writer, typeWriter, dataType, word \
)
// Define type info for scalar, vector etc. instantiations
......@@ -70,7 +70,7 @@ SourceFiles
makeSetWriterType(typeWriter, vector); \
makeSetWriterType(typeWriter, sphericalTensor); \
makeSetWriterType(typeWriter, symmTensor); \
makeSetWriterType(typeWriter, tensor);
makeSetWriterType(typeWriter, tensor)
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
......
......@@ -81,7 +81,7 @@ public:
const coordSet&,
const wordList&,
const List<const Field<Type>*>&,
Ostream& os
Ostream&
) const;
};
......
......@@ -32,7 +32,7 @@ License
namespace Foam
{
makeSetWriters(xmgraceSetWriter)
makeSetWriters(xmgraceSetWriter);
}
// ************************************************************************* //
......@@ -70,18 +70,27 @@ Foam::scalar Foam::sampledSurfaces::mergeTol_(1e-10);
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
bool Foam::sampledSurfaces::checkFieldTypes()
Foam::label Foam::sampledSurfaces::classifyFieldTypes()
{
wordList fieldTypes(fieldNames_.size());
label nFields = 0;
scalarFields_.clear();
vectorFields_.clear();
sphericalTensorFields_.clear();
symmTensorFields_.clear();
tensorFields_.clear();
// check files for a particular time
if (loadFromFiles_)
forAll(fieldNames_, fieldI)
{
forAll(fieldNames_, fieldI)
const word& fieldName = fieldNames_[fieldI];
word fieldType = "";
// check files for a particular time
if (loadFromFiles_)
{
IOobject io
(
fieldNames_[fieldI],
fieldName,
mesh_.time().timeName(),
mesh_,
IOobject::MUST_READ,
......@@ -91,69 +100,96 @@ bool Foam::sampledSurfaces::checkFieldTypes()
if (io.headerOk())
{
fieldTypes[fieldI] = io.headerClassName();
fieldType = io.headerClassName();
}
else
{
fieldTypes[fieldI] = "(notFound)";
continue;
}
}
}
else
{
// check objectRegistry
forAll(fieldNames_, fieldI)
else
{
objectRegistry::const_iterator iter =
mesh_.find(fieldNames_[fieldI]);
// check objectRegistry
objectRegistry::const_iterator iter = mesh_.find(fieldName);
if (iter != mesh_.objectRegistry::end())
{
fieldTypes[fieldI] = iter()->type();
fieldType = iter()->type();
}
else
{
fieldTypes[fieldI] = "(notFound)";
continue;
}
}
if (fieldType == volScalarField::typeName)
{
scalarFields_.append(fieldName);
nFields++;
}
else if (fieldType == volVectorField::typeName)
{
vectorFields_.append(fieldName);
nFields++;
}
else if (fieldType == volSphericalTensorField::typeName)
{
sphericalTensorFields_.append(fieldName);
nFields++;
}
else if (fieldType == volSymmTensorField::typeName)
{
symmTensorFields_.append(fieldName);
nFields++;
}
else if (fieldType == volTensorField::typeName)
{
tensorFields_.append(fieldName);
nFields++;
}
}
return nFields;
}
label nFields = 0;
// classify fieldTypes
nFields += grep(scalarFields_, fieldTypes);
nFields += grep(vectorFields_, fieldTypes);
nFields += grep(sphericalTensorFields_, fieldTypes);
nFields += grep(symmTensorFields_, fieldTypes);
nFields += grep(tensorFields_, fieldTypes);
void Foam::sampledSurfaces::writeGeometry() const
{
// Write to time directory under outputPath_
// skip surface without faces (eg, a failed cut-plane)
if (Pstream::master())
const fileName outputDir = outputPath_/mesh_.time().timeName();
forAll(*this, surfI)
{
if (debug)
{
Pout<< "timeName = " << mesh_.time().timeName() << nl
<< "scalarFields " << scalarFields_ << nl
<< "vectorFields " << vectorFields_ << nl
<< "sphTensorFields " << sphericalTensorFields_ << nl
<< "symTensorFields " << symmTensorFields_ <<nl
<< "tensorFields " << tensorFields_ <<nl;
}
const sampledSurface& s = operator[](surfI);
if (nFields > 0)
if (Pstream::parRun())
{
if (debug)
if (Pstream::master() && mergeList_[surfI].faces.size())
{
Pout<< "Creating directory "
<< outputPath_/mesh_.time().timeName()
<< nl << endl;
genericFormatter_->write
(
outputDir,
s.name(),
mergeList_[surfI].points,
mergeList_[surfI].faces
);
}
mkDir(outputPath_/mesh_.time().timeName());
}
else if (s.faces().size())
{
genericFormatter_->write
(
outputDir,
s.name(),
s.points(),
s.faces()
);
}
}
return nFields > 0;
}
......@@ -176,6 +212,7 @@ Foam::sampledSurfaces::sampledSurfaces
interpolationScheme_(word::null),
writeFormat_(word::null),
mergeList_(),
genericFormatter_(NULL),
scalarFields_(),
vectorFields_(),
sphericalTensorFields_(),
......@@ -223,11 +260,39 @@ void Foam::sampledSurfaces::end()
void Foam::sampledSurfaces::write()
{
if (size() && checkFieldTypes())
if (size())
{
// finalize surfaces, merge points etc.
update();
const label nFields = classifyFieldTypes();
if (Pstream::master())
{
if (debug)
{
Pout<< "timeName = " << mesh_.time().timeName() << nl
<< "scalarFields " << scalarFields_ << nl
<< "vectorFields " << vectorFields_ << nl
<< "sphTensorFields " << sphericalTensorFields_ << nl
<< "symTensorFields " << symmTensorFields_ <<nl
<< "tensorFields " << tensorFields_ <<nl;
Pout<< "Creating directory "
<< outputPath_/mesh_.time().timeName() << nl << endl;
}
mkDir(outputPath_/mesh_.time().timeName());
}
// write geometry first if required, or when no fields would otherwise
// be written
if (nFields == 0 || genericFormatter_->separateFiles())
{
writeGeometry();
}
sampleAndWrite(scalarFields_);
sampleAndWrite(vectorFields_);
sampleAndWrite(sphericalTensorFields_);
......@@ -241,6 +306,14 @@ void Foam::sampledSurfaces::read(const dictionary& dict)
{
fieldNames_ = wordList(dict.lookup("fields"));
const label nFields = fieldNames_.size();
scalarFields_.reset(nFields);
vectorFields_.reset(nFields);
sphericalTensorFields_.reset(nFields);
symmTensorFields_.reset(nFields);
tensorFields_.reset(nFields);
interpolationScheme_ = dict.lookupOrDefault<word>
(
"interpolationScheme",
......@@ -252,6 +325,11 @@ void Foam::sampledSurfaces::read(const dictionary& dict)
"null"
);
// define the generic (geometry) writer
genericFormatter_ = surfaceWriter<bool>::New(writeFormat_);
PtrList<sampledSurface> newList
(
dict.lookup("surfaces"),
......
......@@ -64,24 +64,24 @@ class sampledSurfaces
template<class Type>
class fieldGroup
:
public wordList
public DynamicList<word>
{
public:
//- Surface formatter
autoPtr<surfaceWriter<Type> > formatter;
autoPtr< surfaceWriter<Type> > formatter;
//- Construct null
fieldGroup()
:
wordList(0),
DynamicList<word>(0),
formatter(NULL)
{}
//- Construct for a particular surface format
fieldGroup(const word& writeFormat)
:
wordList(0),
DynamicList<word>(0),
formatter(surfaceWriter<Type>::New(writeFormat))
{}
......@@ -93,10 +93,17 @@ class sampledSurfaces
const wordList& fieldNames
)
:
wordList(fieldNames),
DynamicList<word>(fieldNames),
formatter(surfaceWriter<Type>::New(writeFormat))
{}
void reset(const label nElem)
{
formatter.clear();
DynamicList<word>::setCapacity(nElem);
DynamicList<word>::clear();
}
void operator=(const word& writeFormat)
{
formatter = surfaceWriter<Type>::New(writeFormat);
......@@ -104,7 +111,7 @@ class sampledSurfaces
void operator=(const wordList& fieldNames)
{
wordList::operator=(fieldNames);
DynamicList<word>::operator=(fieldNames);
}
};
......@@ -171,6 +178,9 @@ class sampledSurfaces
// Calculated
//- Generic surface formatter
autoPtr< surfaceWriter<bool> > genericFormatter_;
//- Categorized scalar/vector/tensor fields
fieldGroup<scalar> scalarFields_;
fieldGroup<vector> vectorFields_;
......@@ -181,16 +191,11 @@ class sampledSurfaces
// Private Member Functions
//- Classify field types, return true if nFields > 0
bool checkFieldTypes();
//- Classify field types, returns the number of fields
label classifyFieldTypes();
//- Find the fields in the list of the given type, return count
template<class Type>
label grep
(
fieldGroup<Type>& fieldList,
const wordList& fieldTypes
) const;
//- Write geometry only
void writeGeometry() const;
//- Sample and write a particular volume field
template<class Type>
......
......@@ -30,35 +30,6 @@ License
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
template<class Type>
Foam::label Foam::sampledSurfaces::grep
(
fieldGroup<Type>& fieldList,
const wordList& fieldTypes
) const
{
fieldList.setSize(fieldNames_.size());
label nFields = 0;
forAll(fieldNames_, fieldI)
{
if
(
fieldTypes[fieldI]
== GeometricField<Type, fvPatchField, volMesh>::typeName
)
{
fieldList[nFields] = fieldNames_[fieldI];
nFields++;
}
}
fieldList.setSize(nFields);
return nFields;
}
template<class Type>
void Foam::sampledSurfaces::sampleAndWrite
(
......@@ -67,10 +38,10 @@ void Foam::sampledSurfaces::sampleAndWrite
)
{
// interpolator for this field
autoPtr<interpolation<Type> > interpolator;
autoPtr< interpolation<Type> > interpolator;
const word& fieldName = vField.name();
const fileName& timeDir = vField.time().timeName();
const fileName outputDir = outputPath_/vField.time().timeName();
forAll(*this, surfI)
{
......@@ -128,8 +99,7 @@ void Foam::sampledSurfaces::sampleAndWrite
{
formatter.write
(
outputPath_,
timeDir,
outputDir,
s.name(),
mergeList_[surfI].points,
mergeList_[surfI].faces,
......@@ -147,8 +117,7 @@ void Foam::sampledSurfaces::sampleAndWrite
{
formatter.write
(
outputPath_,
timeDir,
outputDir,
s.name(),
s.points(),
s.faces(),
......@@ -217,7 +186,7 @@ void Foam::sampledSurfaces::sampleAndWrite