mirror of
https://develop.openfoam.com/Development/openfoam.git
synced 2025-11-28 03:28:01 +00:00
ENH: improve ensightWrite handling of moving mesh
- now treat all mesh geometries as moving, since we cannot know beforehand if this is the case.
This commit is contained in:
@ -103,14 +103,13 @@ Foam::label Foam::ensightCase::checkTimeset(const labelHashSet& lookup) const
|
||||
}
|
||||
else if (tsTimes.size() == timesUsed_.size())
|
||||
{
|
||||
forAllConstIter(Map<scalar>, timesUsed_, iter)
|
||||
forAllConstIters(timesUsed_, iter)
|
||||
{
|
||||
tsTimes.erase(iter.key());
|
||||
}
|
||||
|
||||
// OR
|
||||
// tsTimes -= timesUsed_.toc();
|
||||
// tsTimes -= timesUsed_;
|
||||
// tsTimes.unsetMany(timesUsed_.toc());
|
||||
|
||||
if (tsTimes.empty())
|
||||
{
|
||||
@ -489,17 +488,27 @@ void Foam::ensightCase::write() const
|
||||
const bool staticGeom = (geomTimes_.size() == 1 && geomTimes_.found(-1));
|
||||
label tsGeom = staticGeom ? 0 : checkTimeset(geomTimes_);
|
||||
|
||||
// geometry index, when mesh is not moving but stored under data/XXX/
|
||||
label meshIndex = -1;
|
||||
|
||||
// cloud timeset
|
||||
label tsCloud = checkTimeset(cloudTimes_);
|
||||
|
||||
// increment time-sets to the correct indices
|
||||
// Increment time-sets to the correct indices
|
||||
if (tsGeom < 0)
|
||||
{
|
||||
tsGeom = 2; // next available timeset
|
||||
tsGeom = 2; // Next available timeset
|
||||
|
||||
// Saved under data/XXX/geometry, but not actually moving
|
||||
if (geomTimes_.size() == 1)
|
||||
{
|
||||
tsGeom = 0;
|
||||
meshIndex = *(geomTimes_.begin());
|
||||
}
|
||||
}
|
||||
if (tsCloud < 0)
|
||||
{
|
||||
tsCloud = tsGeom + 1; // next available timeset
|
||||
tsCloud = 1 + std::max(1, tsGeom); // Next available timeset
|
||||
}
|
||||
|
||||
writeHeader();
|
||||
@ -521,27 +530,34 @@ void Foam::ensightCase::write() const
|
||||
|
||||
if (staticGeom)
|
||||
{
|
||||
// steady
|
||||
// Steady
|
||||
*os_
|
||||
<< setw(16) << "model:"
|
||||
<< geometryName
|
||||
<< nl;
|
||||
}
|
||||
else if (meshIndex >= 0)
|
||||
{
|
||||
// Not really moving, but stored under data/XXXX/geometry
|
||||
*os_
|
||||
<< setw(16) << "model:"
|
||||
<< (dataDirName/padded(meshIndex)/geometryName).c_str()
|
||||
<< nl;
|
||||
}
|
||||
else if (!geomTimes_.empty())
|
||||
{
|
||||
// moving
|
||||
// Moving
|
||||
*os_
|
||||
<< word::printf("model: %-9d", tsGeom) // width 16 (no quotes)
|
||||
<< (dataMask/geometryName).c_str()
|
||||
<< nl;
|
||||
}
|
||||
|
||||
// clouds and cloud variables
|
||||
const wordList cloudNames = cloudVars_.sortedToc();
|
||||
forAll(cloudNames, cloudNo)
|
||||
{
|
||||
const word& cloudName = cloudNames[cloudNo];
|
||||
// Clouds and cloud variables
|
||||
const wordList cloudNames(cloudVars_.sortedToc());
|
||||
|
||||
for (const word& cloudName : cloudNames)
|
||||
{
|
||||
const fileName masked =
|
||||
(
|
||||
separateCloud()
|
||||
@ -568,11 +584,11 @@ void Foam::ensightCase::write() const
|
||||
}
|
||||
|
||||
|
||||
// field variables (always use timeset 1)
|
||||
const wordList varNames = variables_.sortedToc();
|
||||
forAll(varNames, vari)
|
||||
// Field variables (always use timeset 1)
|
||||
const wordList varNames(variables_.sortedToc());
|
||||
|
||||
for (const word& varName : varNames)
|
||||
{
|
||||
const word& varName = varNames[vari];
|
||||
const string& ensType = variables_[varName];
|
||||
|
||||
*os_
|
||||
@ -588,13 +604,14 @@ void Foam::ensightCase::write() const
|
||||
}
|
||||
|
||||
|
||||
// clouds and cloud variables (using cloud timeset)
|
||||
// Clouds and cloud variables (using cloud timeset)
|
||||
// Write
|
||||
// as -> "data/********/lagrangian/<cloudName>/positions"
|
||||
// or -> "lagrangian/<cloudName>/********/positions"
|
||||
forAll(cloudNames, cloudNo)
|
||||
|
||||
label cloudNo = 0;
|
||||
for (const word& cloudName : cloudNames)
|
||||
{
|
||||
const word& cloudName = cloudNames[cloudNo];
|
||||
const fileName masked =
|
||||
(
|
||||
separateCloud()
|
||||
@ -603,11 +620,9 @@ void Foam::ensightCase::write() const
|
||||
);
|
||||
|
||||
const HashTable<string>& vars = cloudVars_[cloudName];
|
||||
const wordList tocVars = vars.sortedToc();
|
||||
|
||||
forAll(tocVars, vari)
|
||||
for (const word& varName : vars.sortedToc())
|
||||
{
|
||||
const word& varName = tocVars[vari];
|
||||
const string& ensType = vars[varName];
|
||||
|
||||
// prefix variables with 'c' (cloud) and cloud index
|
||||
@ -619,6 +634,8 @@ void Foam::ensightCase::write() const
|
||||
<< (masked/varName).c_str()
|
||||
<< nl;
|
||||
}
|
||||
|
||||
++cloudNo;
|
||||
}
|
||||
|
||||
|
||||
@ -665,7 +682,7 @@ Foam::ensightCase::newGeometry
|
||||
|
||||
if (Pstream::master())
|
||||
{
|
||||
// set the path of the ensight file
|
||||
// Set the path of the ensight file
|
||||
fileName path;
|
||||
|
||||
if (moving)
|
||||
@ -701,10 +718,10 @@ Foam::ensightCase::newCloud
|
||||
{
|
||||
output = createCloudFile(cloudName, "positions");
|
||||
|
||||
// tag binary format (just like geometry files)
|
||||
// Tag binary format (just like geometry files)
|
||||
output().writeBinaryHeader();
|
||||
|
||||
// description
|
||||
// Description
|
||||
output().write(cloud::prefix/cloudName);
|
||||
output().newline();
|
||||
|
||||
|
||||
@ -148,13 +148,13 @@ private:
|
||||
) const;
|
||||
|
||||
|
||||
//- Note geometry being used
|
||||
//- Note the geometry being used
|
||||
void noteGeometry(const bool moving) const;
|
||||
|
||||
//- Note cloud being used
|
||||
//- Note the cloud being used
|
||||
void noteCloud(const word& cloudName) const;
|
||||
|
||||
//- Note cloud/variable being used
|
||||
//- Note the cloud/variable being used
|
||||
void noteCloud
|
||||
(
|
||||
const word& cloudName,
|
||||
@ -162,7 +162,7 @@ private:
|
||||
const char* ensightType
|
||||
) const;
|
||||
|
||||
//- Note field variable being used
|
||||
//- Note the field variable being used
|
||||
void noteVariable
|
||||
(
|
||||
const word& varName,
|
||||
@ -172,7 +172,7 @@ private:
|
||||
|
||||
//- Open stream for new data file (on master), using the current index.
|
||||
// File is without initial description lines.
|
||||
autoPtr<ensightFile> createDataFile(const word&) const;
|
||||
autoPtr<ensightFile> createDataFile(const word& name) const;
|
||||
|
||||
//- Open stream for new cloud file (on master).
|
||||
// File is without initial description lines.
|
||||
@ -211,7 +211,6 @@ public:
|
||||
);
|
||||
|
||||
|
||||
|
||||
//- Destructor
|
||||
~ensightCase();
|
||||
|
||||
@ -223,7 +222,7 @@ public:
|
||||
//- Reference to the case options
|
||||
inline const ensightCase::options& option() const;
|
||||
|
||||
//- Ascii/Binary file output
|
||||
//- The output file format (ascii/binary)
|
||||
inline IOstream::streamFormat format() const;
|
||||
|
||||
//- The nominal path to the case file
|
||||
@ -256,12 +255,12 @@ public:
|
||||
|
||||
//- Set current index and time for time-set 1.
|
||||
// Create corresponding sub-directory
|
||||
// Do not mix between nextTime and setTime in an application.
|
||||
// \note do not mix between nextTime and setTime in an application.
|
||||
void setTime(const scalar t, const label index);
|
||||
|
||||
//- Set current index and time for time-set 1.
|
||||
// Create corresponding sub-directory
|
||||
// Do not mix between nextTime and setTime in an application.
|
||||
// \note do not mix between nextTime and setTime in an application.
|
||||
void setTime(const instant& t, const label index);
|
||||
|
||||
|
||||
@ -305,7 +304,7 @@ public:
|
||||
inline Ostream& operator()() const;
|
||||
|
||||
//- Print some general information.
|
||||
Ostream& printInfo(Ostream&) const;
|
||||
Ostream& printInfo(Ostream& os) const;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@ -90,7 +90,6 @@ void Foam::ensightCase::options::width(const label n)
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool Foam::ensightCase::options::overwrite() const
|
||||
{
|
||||
return overwrite_;
|
||||
|
||||
@ -26,8 +26,7 @@ License
|
||||
#include "cloud.H"
|
||||
#include "ensightPTraits.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
template<class Type>
|
||||
Foam::autoPtr<Foam::ensightFile>
|
||||
@ -54,7 +53,7 @@ Foam::ensightCase::newData
|
||||
);
|
||||
output().newline();
|
||||
|
||||
// note variable for later use
|
||||
// note field variable for later use
|
||||
noteVariable(varName, ensightPTraits<Type>::typeName);
|
||||
}
|
||||
|
||||
|
||||
@ -335,15 +335,15 @@ void Foam::ensightFile::writeList
|
||||
const UList<scalar>& field
|
||||
)
|
||||
{
|
||||
forAll(field, i)
|
||||
for (const scalar& val : field)
|
||||
{
|
||||
if (std::isnan(field[i]))
|
||||
if (std::isnan(val))
|
||||
{
|
||||
writeUndef();
|
||||
}
|
||||
else
|
||||
{
|
||||
write(field[i]);
|
||||
write(val);
|
||||
}
|
||||
|
||||
newline();
|
||||
@ -359,15 +359,15 @@ void Foam::ensightFile::writeList
|
||||
{
|
||||
if (notNull(idList))
|
||||
{
|
||||
forAll(idList, i)
|
||||
for (const label idx : idList)
|
||||
{
|
||||
if (idList[i] >= field.size() || std::isnan(field[idList[i]]))
|
||||
if (idx >= field.size() || std::isnan(field[idx]))
|
||||
{
|
||||
writeUndef();
|
||||
}
|
||||
else
|
||||
{
|
||||
write(field[idList[i]]);
|
||||
write(field[idx]);
|
||||
}
|
||||
|
||||
newline();
|
||||
@ -375,7 +375,7 @@ void Foam::ensightFile::writeList
|
||||
}
|
||||
else
|
||||
{
|
||||
// no idList => perNode
|
||||
// No idList => perNode
|
||||
writeList(field);
|
||||
}
|
||||
}
|
||||
|
||||
@ -187,30 +187,6 @@ bool Foam::functionObjects::ensightWrite::write()
|
||||
);
|
||||
}
|
||||
|
||||
if (!ensMesh_.valid())
|
||||
{
|
||||
ensMesh_.reset(new ensightMesh(mesh_, writeOpts_));
|
||||
|
||||
if (ensMesh_().needsUpdate())
|
||||
{
|
||||
ensMesh_().correct();
|
||||
}
|
||||
|
||||
// assume static geometry - need to fix later
|
||||
autoPtr<ensightGeoFile> os = ensCase_().newGeometry(false);
|
||||
ensMesh_().write(os);
|
||||
}
|
||||
else if (ensMesh_().needsUpdate())
|
||||
{
|
||||
// appears to have moved
|
||||
ensMesh_().correct();
|
||||
|
||||
autoPtr<ensightGeoFile> os = ensCase_().newGeometry(true);
|
||||
ensMesh_().write(os);
|
||||
}
|
||||
|
||||
Log << type() << " " << name() << " write: (";
|
||||
|
||||
if (consecutive_)
|
||||
{
|
||||
ensCase().nextTime(t.value());
|
||||
@ -220,6 +196,28 @@ bool Foam::functionObjects::ensightWrite::write()
|
||||
ensCase().setTime(t.value(), t.timeIndex());
|
||||
}
|
||||
|
||||
bool writeGeom = false;
|
||||
if (!ensMesh_.valid())
|
||||
{
|
||||
writeGeom = true;
|
||||
ensMesh_.reset(new ensightMesh(mesh_, writeOpts_));
|
||||
}
|
||||
if (ensMesh_().needsUpdate())
|
||||
{
|
||||
writeGeom = true;
|
||||
ensMesh_().correct();
|
||||
}
|
||||
|
||||
if (writeGeom)
|
||||
{
|
||||
// Treat all geometry as moving, since we do not know a priori
|
||||
// if the simulation has mesh motion later on.
|
||||
autoPtr<ensightGeoFile> os = ensCase_().newGeometry(true);
|
||||
ensMesh_().write(os);
|
||||
}
|
||||
|
||||
Log << type() << " " << name() << " write: (";
|
||||
|
||||
wordHashSet candidates(subsetStrings(selectFields_, mesh_.names()));
|
||||
DynamicList<word> missing(selectFields_.size());
|
||||
DynamicList<word> ignored(selectFields_.size());
|
||||
|
||||
@ -57,6 +57,8 @@ functions
|
||||
libs ("libsixDoFRigidBodyState.so");
|
||||
angleFormat degrees;
|
||||
}
|
||||
|
||||
#include "ensightWrite"
|
||||
}
|
||||
|
||||
// ************************************************************************* //
|
||||
|
||||
@ -0,0 +1,20 @@
|
||||
// -*- C++ -*-
|
||||
|
||||
ensightWrite
|
||||
{
|
||||
type ensightWrite;
|
||||
libs ("libutilityFunctionObjects.so");
|
||||
log true;
|
||||
|
||||
fields (U p);
|
||||
|
||||
format ascii;
|
||||
|
||||
overwrite true;
|
||||
|
||||
writeControl writeTime;
|
||||
|
||||
consecutive false;
|
||||
}
|
||||
|
||||
// ************************************************************************* //
|
||||
Reference in New Issue
Block a user