ENH: make creation of streamline seeds demand-driven

This commit is contained in:
Mark Olesen
2017-10-12 18:43:12 +02:00
parent f116217466
commit 9b2a25516e
4 changed files with 101 additions and 69 deletions

View File

@ -52,7 +52,7 @@ void Foam::functionObjects::streamLine::track()
initialParticles initialParticles
); );
const sampledSet& seedPoints = sampledSetPtr_(); const sampledSet& seedPoints = sampledSetPoints();
forAll(seedPoints, i) forAll(seedPoints, i)
{ {

View File

@ -47,6 +47,38 @@ namespace functionObjects
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
const Foam::word&
Foam::functionObjects::streamLineBase::sampledSetAxis() const
{
if (sampledSetPtr_.empty())
{
sampledSetPoints();
}
return sampledSetAxis_;
}
const Foam::sampledSet&
Foam::functionObjects::streamLineBase::sampledSetPoints() const
{
if (sampledSetPtr_.empty())
{
sampledSetPtr_ = sampledSet::New
(
"seedSampleSet",
mesh_,
meshSearchMeshObject::New(mesh_),
dict_.subDict("seedSampleSet")
);
sampledSetAxis_ = sampledSetPtr_->axis();
}
return sampledSetPtr_();
}
Foam::autoPtr<Foam::indirectPrimitivePatch> Foam::autoPtr<Foam::indirectPrimitivePatch>
Foam::functionObjects::streamLineBase::wallPatch() const Foam::functionObjects::streamLineBase::wallPatch() const
{ {
@ -54,12 +86,12 @@ Foam::functionObjects::streamLineBase::wallPatch() const
label nFaces = 0; label nFaces = 0;
forAll(patches, patchi) for (const polyPatch& pp : patches)
{ {
//if (!polyPatch::constraintType(patches[patchi].type())) //if (!polyPatch::constraintType(pp.type()))
if (isA<wallPolyPatch>(patches[patchi])) if (isA<wallPolyPatch>(pp))
{ {
nFaces += patches[patchi].size(); nFaces += pp.size();
} }
} }
@ -67,13 +99,11 @@ Foam::functionObjects::streamLineBase::wallPatch() const
nFaces = 0; nFaces = 0;
forAll(patches, patchi) for (const polyPatch& pp : patches)
{ {
//if (!polyPatch::constraintType(patches[patchi].type())) //if (!polyPatch::constraintType(pp.type()))
if (isA<wallPolyPatch>(patches[patchi])) if (isA<wallPolyPatch>(pp))
{ {
const polyPatch& pp = patches[patchi];
forAll(pp, i) forAll(pp, i)
{ {
addressing[nFaces++] = pp.start()+i; addressing[nFaces++] = pp.start()+i;
@ -110,24 +140,24 @@ void Foam::functionObjects::streamLineBase::initInterpolations
label nScalar = 0; label nScalar = 0;
label nVector = 0; label nVector = 0;
forAll(fields_, i) for (const word& fieldName : fields_)
{ {
if (foundObject<volScalarField>(fields_[i])) if (foundObject<volScalarField>(fieldName))
{ {
nScalar++; nScalar++;
} }
else if (foundObject<volVectorField>(fields_[i])) else if (foundObject<volVectorField>(fieldName))
{ {
nVector++; nVector++;
} }
else else
{ {
FatalErrorInFunction FatalErrorInFunction
<< "Cannot find field " << fields_[i] << nl << "Cannot find field " << fieldName << nl
<< "Valid scalar fields are:" << "Valid scalar fields are:"
<< mesh_.names(volScalarField::typeName) << nl << flatOutput(mesh_.names(volScalarField::typeName)) << nl
<< "Valid vector fields are:" << "Valid vector fields are:"
<< mesh_.names(volVectorField::typeName) << flatOutput(mesh_.names(volVectorField::typeName))
<< exit(FatalError); << exit(FatalError);
} }
} }
@ -136,12 +166,11 @@ void Foam::functionObjects::streamLineBase::initInterpolations
vvInterp.setSize(nVector); vvInterp.setSize(nVector);
nVector = 0; nVector = 0;
forAll(fields_, i) for (const word& fieldName : fields_)
{ {
if (foundObject<volScalarField>(fields_[i])) if (foundObject<volScalarField>(fieldName))
{ {
const volScalarField& f = const volScalarField& f = lookupObject<volScalarField>(fieldName);
lookupObject<volScalarField>(fields_[i]);
vsInterp.set vsInterp.set
( (
nScalar++, nScalar++,
@ -152,10 +181,9 @@ void Foam::functionObjects::streamLineBase::initInterpolations
) )
); );
} }
else if (foundObject<volVectorField>(fields_[i])) else if (foundObject<volVectorField>(fieldName))
{ {
const volVectorField& f = const volVectorField& f = lookupObject<volVectorField>(fieldName);
lookupObject<volVectorField>(fields_[i]);
if (f.name() == UName_) if (f.name() == UName_)
{ {
@ -231,7 +259,7 @@ void Foam::functionObjects::streamLineBase::storePoint
DynamicList<vectorList>& newVectors DynamicList<vectorList>& newVectors
) const ) const
{ {
label sz = newTrack.size(); const label sz = newTrack.size();
const List<point>& track = allTracks_[tracki]; const List<point>& track = allTracks_[tracki];
@ -274,6 +302,7 @@ void Foam::functionObjects::streamLineBase::trimToBox
) const ) const
{ {
const List<point>& track = allTracks_[tracki]; const List<point>& track = allTracks_[tracki];
if (track.size()) if (track.size())
{ {
for for
@ -287,7 +316,7 @@ void Foam::functionObjects::streamLineBase::trimToBox
const point& endPt = track[segmenti]; const point& endPt = track[segmenti];
const vector d(endPt-startPt); const vector d(endPt-startPt);
scalar magD = mag(d); const scalar magD = mag(d);
if (magD > ROOTVSMALL) if (magD > ROOTVSMALL)
{ {
if (bb.contains(startPt)) if (bb.contains(startPt))
@ -507,6 +536,12 @@ Foam::functionObjects::streamLineBase::~streamLineBase()
bool Foam::functionObjects::streamLineBase::read(const dictionary& dict) bool Foam::functionObjects::streamLineBase::read(const dictionary& dict)
{ {
if (&dict_ != &dict)
{
// Update local copy of dictionary:
dict_ = dict;
}
fvMeshFunctionObject::read(dict); fvMeshFunctionObject::read(dict);
Info<< type() << " " << name() << ":" << nl; Info<< type() << " " << name() << ":" << nl;
@ -536,10 +571,8 @@ bool Foam::functionObjects::streamLineBase::read(const dictionary& dict)
trackLength_ = VGREAT; trackLength_ = VGREAT;
if (dict.found("trackLength")) if (dict.readIfPresent("trackLength", trackLength_))
{ {
dict.lookup("trackLength") >> trackLength_;
Info<< type() << " : fixed track length specified : " Info<< type() << " : fixed track length specified : "
<< trackLength_ << nl << endl; << trackLength_ << nl << endl;
} }
@ -562,14 +595,8 @@ bool Foam::functionObjects::streamLineBase::read(const dictionary& dict)
cloudName_ = dict.lookupOrDefault<word>("cloud", type()); cloudName_ = dict.lookupOrDefault<word>("cloud", type());
sampledSetPtr_ = sampledSet::New sampledSetPtr_.clear();
( sampledSetAxis_.clear();
"seedSampleSet",
mesh_,
meshSearchMeshObject::New(mesh_),
dict.subDict("seedSampleSet")
);
sampledSetAxis_ = sampledSetPtr_->axis();
scalarFormatterPtr_ = writer<scalar>::New(dict.lookup("setFormat")); scalarFormatterPtr_ = writer<scalar>::New(dict.lookup("setFormat"));
vectorFormatterPtr_ = writer<vector>::New(dict.lookup("setFormat")); vectorFormatterPtr_ = writer<vector>::New(dict.lookup("setFormat"));
@ -756,7 +783,7 @@ bool Foam::functionObjects::streamLineBase::write()
new coordSet new coordSet
( (
"track" + Foam::name(nTracks), "track" + Foam::name(nTracks),
sampledSetAxis_ //"xyz" sampledSetAxis() // "xyz"
) )
); );
oldToNewTrack[tracki] = nTracks; oldToNewTrack[tracki] = nTracks;
@ -767,7 +794,7 @@ bool Foam::functionObjects::streamLineBase::write()
// Convert scalar values // Convert scalar values
if (allScalars_.size() > 0 && tracks.size() > 0) if (!allScalars_.empty() && !tracks.empty())
{ {
List<List<scalarField>> scalarValues(allScalars_.size()); List<List<scalarField>> scalarValues(allScalars_.size());
@ -781,7 +808,7 @@ bool Foam::functionObjects::streamLineBase::write()
scalarList& vals = allTrackVals[tracki]; scalarList& vals = allTrackVals[tracki];
if (vals.size()) if (vals.size())
{ {
label newTracki = oldToNewTrack[tracki]; const label newTracki = oldToNewTrack[tracki];
scalarValues[scalari][newTracki].transfer(vals); scalarValues[scalari][newTracki].transfer(vals);
} }
} }
@ -811,7 +838,7 @@ bool Foam::functionObjects::streamLineBase::write()
// Convert vector values // Convert vector values
if (allVectors_.size() > 0 && tracks.size() > 0) if (!allVectors_.empty() && !tracks.empty())
{ {
List<List<vectorField>> vectorValues(allVectors_.size()); List<List<vectorField>> vectorValues(allVectors_.size());
@ -825,7 +852,7 @@ bool Foam::functionObjects::streamLineBase::write()
vectorList& vals = allTrackVals[tracki]; vectorList& vals = allTrackVals[tracki];
if (vals.size()) if (vals.size())
{ {
label newTracki = oldToNewTrack[tracki]; const label newTracki = oldToNewTrack[tracki];
vectorValues[vectori][newTracki].transfer(vals); vectorValues[vectori][newTracki].transfer(vals);
} }
} }
@ -854,20 +881,18 @@ bool Foam::functionObjects::streamLineBase::write()
// File names are generated on the master but setProperty needs to // File names are generated on the master but setProperty needs to
// be across all procs // be across all procs
Pstream::scatter(scalarVtkFile); Pstream::scatter(scalarVtkFile);
forAll(scalarNames_, namei) for (const word& fieldName : scalarNames_)
{ {
dictionary propsDict; dictionary propsDict;
propsDict.add("file", scalarVtkFile); propsDict.add("file", scalarVtkFile);
const word& fieldName = scalarNames_[namei];
setProperty(fieldName, propsDict); setProperty(fieldName, propsDict);
} }
Pstream::scatter(vectorVtkFile); Pstream::scatter(vectorVtkFile);
forAll(vectorNames_, namei) for (const word& fieldName : vectorNames_)
{ {
dictionary propsDict; dictionary propsDict;
propsDict.add("file", vectorVtkFile); propsDict.add("file", vectorVtkFile);
const word& fieldName = vectorNames_[namei];
setProperty(fieldName, propsDict); setProperty(fieldName, propsDict);
} }

View File

@ -63,6 +63,14 @@ class streamLineBase
: :
public fvMeshFunctionObject public fvMeshFunctionObject
{ {
// Private data
//- Seed set engine
mutable autoPtr<sampledSet> sampledSetPtr_;
//- Axis of the sampled points to output
mutable word sampledSetAxis_;
protected: protected:
//- Input dictionary //- Input dictionary
@ -104,15 +112,6 @@ protected:
// Demand driven // Demand driven
//- Mesh searching enigne
autoPtr<meshSearch> meshSearchPtr_;
//- Seed set engine
autoPtr<sampledSet> sampledSetPtr_;
//- Axis of the sampled points to output
word sampledSetAxis_;
//- File writer for scalar data //- File writer for scalar data
autoPtr<writer<scalar>> scalarFormatterPtr_; autoPtr<writer<scalar>> scalarFormatterPtr_;
@ -132,6 +131,15 @@ protected:
List<DynamicList<vectorList>> allVectors_; List<DynamicList<vectorList>> allVectors_;
// Protected Member Functions
//- The axis of the sampledSet. Creates sampledSet if required.
const word& sampledSetAxis() const;
//- Demand driven construction of the sampledSet.
// Also updates sampledSetAxis_
const sampledSet& sampledSetPoints() const;
//- Construct patch out of all wall patch faces //- Construct patch out of all wall patch faces
autoPtr<indirectPrimitivePatch> wallPatch() const; autoPtr<indirectPrimitivePatch> wallPatch() const;

View File

@ -131,12 +131,11 @@ void Foam::functionObjects::wallBoundedStreamLine::track()
// Get the seed points // Get the seed points
// ~~~~~~~~~~~~~~~~~~~ // ~~~~~~~~~~~~~~~~~~~
const sampledSet& seedPoints = sampledSetPtr_(); const sampledSet& seedPoints = sampledSetPoints();
forAll(seedPoints, i) forAll(seedPoints, i)
{ {
label celli = seedPoints.cells()[i]; const label celli = seedPoints.cells()[i];
if (celli != -1) if (celli != -1)
{ {