sampledSets, streamlines: Various improvements

Sampled sets and streamlines now write all their fields to the same
file. This prevents excessive duplication of the geometry and makes
post-processing tasks more convenient.

"axis" entries are now optional in sampled sets and streamlines. When
omitted, a default entry will be used, which is chosen appropriately for
the coordinate set and the write format. Some combinations are not
supported. For example, a scalar ("x", "y", "z" or "distance") axis
cannot be used to write in the vtk format, as vtk requires 3D locations
with which to associate data. Similarly, a point ("xyz") axis cannot be
used with the gnuplot format, as gnuplot needs a single scalar to
associate with the x-axis.

Streamlines can now write out fields of any type, not just scalars and
vectors, and there is no longer a strict requirement for velocity to be
one of the fields.

Streamlines now output to postProcessing/<functionName>/time/<file> in
the same way as other functions. The additional "sets" subdirectory has
been removed.

The raw set writer now aligns columns correctly.

The handling of segments in coordSet and sampledSet has been
fixed/completed. Segments mean that a coordinate set can represent a
number of contiguous lines, disconnected points, or some combination
thereof. This works in parallel; segments remain contiguous across
processor boundaries. Set writers now only need one write method, as the
previous "writeTracks" functionality is now handled by streamlines
providing the writer with the appropriate segment structure.

Coordinate sets and set writers now have a convenient programmatic
interface. To write a graph of A and B against some coordinate X, in
gnuplot format, we can call the following:

    setWriter::New("gnuplot")->write
    (
        directoryName,
        graphName,
        coordSet(true, "X", X), // <-- "true" indicates a contiguous
        "A",                    //     line, "false" would mean
        A,                      //     disconnected points
        "B",
        B
    );

This write function is variadic. It supports any number of
field-name-field pairs, and they can be of any primitive type.

Support for Jplot and Xmgrace formats has been removed. Raw, CSV,
Gnuplot, VTK and Ensight formats are all still available.

The old "graph" functionality has been removed from the code, with the
exception of the randomProcesses library and associated applications
(noise, DNSFoam and boxTurb). The intention is that these should also
eventually be converted to use the setWriters. For now, so that it is
clear that the "graph" functionality is not to be used elsewhere, it has
been moved into a subdirectory of the randomProcesses library.
This commit is contained in:
Will Bainbridge
2021-11-25 09:42:19 +00:00
parent 50fb2477bd
commit 25a6d068f0
185 changed files with 4727 additions and 6308 deletions

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2011-2019 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2011-2021 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
@ -30,8 +30,9 @@ Description
\*---------------------------------------------------------------------------*/
#include "fvCFD.H"
#include "writeCellGraph.H"
#include "OSspecific.H"
#include "setWriter.H"
#include "writeFile.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -73,8 +74,20 @@ int main(int argc, char *argv[])
if (runTime.writeTime())
{
writeCellGraph(V, runTime.graphFormat());
writeCellGraph(delta, runTime.graphFormat());
setWriter::New(runTime.graphFormat())->write
(
runTime.globalPath()
/functionObjects::writeFile::outputPrefix
/args.executable()
/runTime.timeName(),
args.executable(),
coordSet(true, word::null, mesh.C().primitiveField(), "x"),
"V", V.primitiveField(),
"delta", delta.primitiveField()
);
}
Info<< "ExecutionTime = " << runTime.elapsedCpuTime() << " s"

View File

@ -41,7 +41,8 @@ Description
#include "fvModels.H"
#include "fvConstraints.H"
#include "wallFvPatch.H"
#include "makeGraph.H"
#include "setWriter.H"
#include "writeFile.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View File

@ -13,21 +13,32 @@ volSymmTensorField R
runTime.write();
const word& gFormat = runTime.graphFormat();
setWriter::New(runTime.graphFormat())->write
(
runTime.globalPath()
/functionObjects::writeFile::outputPrefix
/args.executable()
/runTime.timeName(),
makeGraph(y, flowDirection & U, "Uf", gFormat);
args.executable(),
makeGraph(y, turbulence->nu(), gFormat);
makeGraph(y, turbulence->k(), gFormat);
makeGraph(y, turbulence->epsilon(), gFormat);
coordSet(true, "y", y),
makeGraph(y, flowDirection & R & flowDirection, "Rff", gFormat);
makeGraph(y, wallNormal & R & wallNormal, "Rww", gFormat);
makeGraph(y, flowDirection & R & wallNormal, "Rfw", gFormat);
"Uf", (flowDirection & U)().primitiveField(),
makeGraph(y, sqrt(mag(R.component(symmTensor::XX))), "u", gFormat);
makeGraph(y, sqrt(mag(R.component(symmTensor::YY))), "v", gFormat);
makeGraph(y, sqrt(mag(R.component(symmTensor::ZZ))), "w", gFormat);
makeGraph(y, R.component(symmTensor::XY), "uv", gFormat);
"nu", turbulence->nu()().primitiveField(),
"k", turbulence->nu()().primitiveField(),
"epsilon", turbulence->nu()().primitiveField(),
makeGraph(y, mag(fvc::grad(U)), "gammaDot", gFormat);
"Rff", (flowDirection & R & flowDirection)().primitiveField(),
"Rww", (wallNormal & R & wallNormal)().primitiveField(),
"Rfw", (flowDirection & R & wallNormal)().primitiveField(),
"u", sqrt(mag(R.component(symmTensor::XX)))().primitiveField(),
"v", sqrt(mag(R.component(symmTensor::YY)))().primitiveField(),
"w", sqrt(mag(R.component(symmTensor::ZZ)))().primitiveField(),
"uv", R.component(symmTensor::XY)().primitiveField(),
"gammaDot", mag(fvc::grad(U))().primitiveField()
);

View File

@ -130,16 +130,10 @@ void Foam::functionObjects::sizeDistribution::correctVolAverages()
}
N_[i] = gSum(V*Ni)/this->V();
V_[i] = fi.x().value();
a_[i] = gSum(V*ai)/this->V();
d_[i] = gSum(V*di)/this->V();
}
forAll(bins_, i)
{
const Foam::diameterModels::sizeGroup& fi = popBal_.sizeGroups()[i];
bins_[i] = point(fi.x().value(), a_[i], d_[i]);
}
}
@ -154,13 +148,15 @@ void Foam::functionObjects::sizeDistribution::writeMoments()
writeTime(file());
}
const scalarField& bin = this->bin();
for (label k = 0; k <= maxOrder_; k++)
{
scalar result = 0;
forAll(N_, i)
{
result += pow(bins_[i][binCmpt_], k)*N_[i];
result += pow(bin[i], k)*N_[i];
}
if (Pstream::master())
@ -192,23 +188,25 @@ void Foam::functionObjects::sizeDistribution::writeStdDev()
scalar mean = 0;
scalar var = 0;
if(sum(N_) != 0)
const scalarField& bin = this->bin();
if (sum(N_) != 0)
{
if (geometric_)
{
mean = exp(sum(Foam::log(bins_.component(binCmpt_))*N_/sum(N_)));
mean = exp(sum(Foam::log(bin)*N_/sum(N_)));
var =
sum(sqr(Foam::log(bins_.component(binCmpt_)) - Foam::log(mean))
sum(sqr(Foam::log(bin) - Foam::log(mean))
*N_/sum(N_));
stdDev = exp(sqrt(var));
}
else
{
mean = sum(bins_.component(binCmpt_)*N_/sum(N_));
mean = sum(bin*N_/sum(N_));
var = sum(sqr(bins_.component(binCmpt_) - mean)*N_/sum(N_));
var = sum(sqr(bin - mean)*N_/sum(N_));
stdDev = sqrt(var);
}
@ -225,6 +223,8 @@ void Foam::functionObjects::sizeDistribution::writeDistribution()
{
scalarField result(N_);
const scalarField& bin = this->bin();
switch (functionType_)
{
case ftNumber:
@ -239,7 +239,7 @@ void Foam::functionObjects::sizeDistribution::writeDistribution()
Log << " writing volume distribution. "
<< endl;
result *= bins_.component(0);
result *= V_;
break;
}
@ -263,12 +263,12 @@ void Foam::functionObjects::sizeDistribution::writeDistribution()
{
List<scalar> bndrs(N_.size() + 1);
bndrs.first() = bins_.first()[binCmpt_];
bndrs.last() = bins_.last()[binCmpt_];
bndrs.first() = bin.first();
bndrs.last() = bin.last();
for (label i = 1; i < N_.size(); i++)
{
bndrs[i] = (bins_[i][binCmpt_] + bins_[i-1][binCmpt_])/2.0;
bndrs[i] = (bin[i]+ bin[i-1])/2.0;
}
forAll(result, i)
@ -287,15 +287,19 @@ void Foam::functionObjects::sizeDistribution::writeDistribution()
if (Pstream::master())
{
const coordSet coords
formatterPtr_->write
(
"sizeDistribution",
"xyz",
bins_,
mag(bins_)
file_.baseTimeDir(),
name(),
coordSet(true, "volume", V_),
"area",
a_,
"diameter",
d_,
word(functionTypeNames_[functionType_])
+ (densityFunction_ ? "Density" : "Concentration"),
result
);
writeGraph(coords, functionTypeNames_[functionType_], result);
}
}
@ -347,44 +351,6 @@ void Foam::functionObjects::sizeDistribution::writeFileHeader
}
void Foam::functionObjects::sizeDistribution::writeGraph
(
const coordSet& coords,
const word& functionTypeName,
const scalarField& values
)
{
const wordList functionTypeNames(1, functionTypeName);
fileName outputPath = file_.baseTimeDir();
mkDir(outputPath);
OFstream graphFile
(
outputPath/(this->name() + ".dat")
);
volRegion::writeFileHeader(file_, graphFile);
file_.writeCommented(graphFile, "Volume area diameter " + functionTypeName);
if (densityFunction_)
{
graphFile << "Density";
}
else
{
graphFile << "Concentration";
}
graphFile << endl;
List<const scalarField*> yPtrs(1);
yPtrs[0] = &values;
scalarFormatter_().write(coords, functionTypeNames, yPtrs, graphFile);
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::functionObjects::sizeDistribution::sizeDistribution
@ -409,42 +375,11 @@ Foam::functionObjects::sizeDistribution::sizeDistribution
functionType_(functionTypeNames_.read(dict.lookup("functionType"))),
coordinateType_(coordinateTypeNames_.read(dict.lookup("coordinateType"))),
N_(popBal_.sizeGroups().size(), 0),
V_(popBal_.sizeGroups().size(), 0),
a_(popBal_.sizeGroups().size(), 0),
d_(popBal_.sizeGroups().size(), 0),
bins_(N_.size()),
binCmpt_(0)
d_(popBal_.sizeGroups().size(), 0)
{
read(dict);
switch (coordinateType_)
{
case ctVolume:
{
binCmpt_ = 0;
break;
}
case ctArea:
{
binCmpt_ = 1;
break;
}
case ctDiameter:
{
binCmpt_ = 2;
break;
}
case ctProjectedAreaDiameter:
{
binCmpt_ = 2;
break;
}
}
scalarFormatter_ = setWriter<scalar>::New("raw");
}
@ -465,6 +400,8 @@ bool Foam::functionObjects::sizeDistribution::read(const dictionary& dict)
geometric_ = dict.lookupOrDefault<Switch>("geometric", false);
maxOrder_ = dict.lookupOrDefault("maxOrder", 3);
formatterPtr_ = setWriter::New(dict.lookup("setFormat"), dict);
resetName(name());
return false;

View File

@ -134,8 +134,8 @@ protected:
//- File containing data for all functionTypes except moments
writeFile file_;
//- Output formatter, set to raw
autoPtr<setWriter<scalar>> scalarFormatter_;
//- Output formatter
autoPtr<setWriter> formatterPtr_;
//- Reference to populationBalanceModel
const Foam::diameterModels::populationBalanceModel& popBal_;
@ -149,6 +149,9 @@ protected:
//- List of volume-averaged number concentrations
scalarField N_;
//- ???
scalarField V_;
//- List of volume-averaged surface areas
scalarField a_;
@ -167,18 +170,29 @@ protected:
//- Highest moment order
label maxOrder_;
//- Bins (representative volume/area/diameter)
pointField bins_;
//- Bin component used according to chosen coordinate type
label binCmpt_;
// Protected Member Functions
//- Filter field according to cellIds
tmp<scalarField> filterField(const scalarField& field) const;
//- Bin component used according to chosen coordinate type
inline const scalarField& bin() const
{
switch (coordinateType_)
{
case ctVolume:
return V_;
case ctArea:
return a_;
case ctDiameter:
return d_;
case ctProjectedAreaDiameter:
return d_;
}
return scalarField::null();
}
//- Correct volume averages
void correctVolAverages();
@ -194,14 +208,6 @@ protected:
//- Output file header information for functionType moments
virtual void writeFileHeader(const label i);
//- Output function for all functionType number/volume
void writeGraph
(
const coordSet& coords,
const word& functionTypeName,
const scalarField& values
);
public:

View File

@ -1,3 +0,0 @@
Test-graph.C
EXE = $(FOAM_USER_APPBIN)/Test-graph

View File

@ -1,7 +0,0 @@
EXE_INC = \
-I$(LIB_SRC)/sampling/lnInclude \
-I$(LIB_SRC)/meshTools/lnInclude
EXE_LIBS = \
-lsampling \
-lmeshTools

View File

@ -1,70 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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/>.
Application
graphTest
Description
Test program for making graphs
\*---------------------------------------------------------------------------*/
#include "graph.H"
using namespace Foam;
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
int main()
{
scalarField alpha(200);
scalarField phie(alpha.size());
scalarField phic(alpha.size());
forAll(alpha, i)
{
alpha[i] = scalar(i)/50.0;
}
scalar R = 5.0;
phie = (R - 1)/(sqrt(R/(alpha + 1.0e-6)) + 1.0) + 1.0;
phic = (R - 1)/(sqrt(R*alpha) + 1.0) + 1.0;
graph phi("@f! (R = 5)", "@a!", "@f!", alpha);
phi.insert
(
"@f!&e!", new curve("@f!&e!", curve::curveStyle::CONTINUOUS, phie)
);
phi.insert
(
"@f!&c!", new curve("@f!&c!", curve::curveStyle::CONTINUOUS, phic)
);
phi.write("phi", "xmgr");
Info<< "end" << endl;
}
// ************************************************************************* //

View File

@ -1,64 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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/>.
Application
graphTest
Description
Test program for making graphs
\*---------------------------------------------------------------------------*/
#include "graph.H"
using namespace Foam;
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
int main()
{
scalarField eta(200);
scalarField C1mR(eta.size());
forAll(eta, i)
{
eta[i] = scalar(i)/10.0;
}
scalar C1 = 1.42;
scalar eta0 = 4.38;
scalar beta = 0.012;
C1mR = C1 - ((eta*(1.0 - eta/eta0))/(1.0 + beta*pow(eta, 3.0)));
graph("C&1! - R", "C&1! - R", "@h!", eta, C1mR).write
(
"C1mR",
"xmgr"
);
Info<< "end" << endl;
}
// ************************************************************************* //

View File

@ -1,3 +0,0 @@
Test-graphXi.C
EXE = $(FOAM_USER_APPBIN)/Test-graphXi

View File

@ -1,7 +0,0 @@
EXE_INC = \
-I$(LIB_SRC)/sampling/lnInclude \
-I$(LIB_SRC)/meshTools/lnInclude
EXE_LIBS = \
-lsampling \
-lmeshTools

View File

@ -1,66 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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/>.
Application
graphTest
Description
Test program for making graphs
\*---------------------------------------------------------------------------*/
#include "graph.H"
#include "OFstream.H"
#include "mathematicalConstants.H"
using namespace Foam;
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
int main()
{
scalarField x(100);
scalarField r(x.size());
forAll(x, i)
{
x[i] = -3 + 0.06*i;
}
scalarField b(0.5*(1.0 + erf(x)));
scalarField c(1.0 - b);
scalarField gradb((1/::sqrt(constant::mathematical::pi))*exp(-sqr(x)));
scalarField lapb(-2*x*gradb);
r = lapb*b*c/(gradb*gradb);
graph("r", "x", "r", x, r).write("r", "xmgr");
Info<< "end" << endl;
return 0;
}
// ************************************************************************* //

View File

@ -1,107 +0,0 @@
@title "r"
@xaxis label "x"
@yaxis label "r"
@s0 legend "r"
@target G0.S0
@type xy
-3 0.951803
-2.94 0.950065
-2.88 0.948234
-2.82 0.946302
-2.76 0.944261
-2.7 0.942103
-2.64 0.939817
-2.58 0.937392
-2.52 0.934816
-2.46 0.932074
-2.4 0.929149
-2.34 0.926023
-2.28 0.922673
-2.22 0.919075
-2.16 0.915199
-2.1 0.911012
-2.04 0.906476
-1.98 0.901547
-1.92 0.896176
-1.86 0.890307
-1.8 0.883875
-1.74 0.87681
-1.68 0.869032
-1.62 0.860453
-1.56 0.850978
-1.5 0.840503
-1.44 0.828916
-1.38 0.8161
-1.32 0.801931
-1.26 0.786282
-1.2 0.769024
-1.14 0.750029
-1.08 0.729172
-1.02 0.706337
-0.96 0.681414
-0.9 0.654311
-0.84 0.624951
-0.78 0.59328
-0.72 0.559268
-0.66 0.522911
-0.6 0.48424
-0.54 0.443314
-0.48 0.40023
-0.42 0.355116
-0.36 0.308137
-0.3 0.259489
-0.24 0.2094
-0.18 0.158121
-0.12 0.10593
-0.06 0.0531214
-1.11022e-16 9.8391e-17
0.06 -0.0531214
0.12 -0.10593
0.18 -0.158121
0.24 -0.2094
0.3 -0.259489
0.36 -0.308137
0.42 -0.355116
0.48 -0.40023
0.54 -0.443314
0.6 -0.48424
0.66 -0.522911
0.72 -0.559268
0.78 -0.59328
0.84 -0.624951
0.9 -0.654311
0.96 -0.681414
1.02 -0.706337
1.08 -0.729172
1.14 -0.750029
1.2 -0.769024
1.26 -0.786282
1.32 -0.801931
1.38 -0.8161
1.44 -0.828916
1.5 -0.840503
1.56 -0.850978
1.62 -0.860453
1.68 -0.869032
1.74 -0.87681
1.8 -0.883875
1.86 -0.890307
1.92 -0.896176
1.98 -0.901547
2.04 -0.906476
2.1 -0.911012
2.16 -0.915199
2.22 -0.919075
2.28 -0.922673
2.34 -0.926023
2.4 -0.929149
2.46 -0.932074
2.52 -0.934816
2.58 -0.937392
2.64 -0.939817
2.7 -0.942103
2.76 -0.944261
2.82 -0.946302
2.88 -0.948234
2.94 -0.950065

View File

@ -1,103 +0,0 @@
# JPlot file
# column 1: x
# column 2: r
-3 0.951803
-2.94 0.950065
-2.88 0.948234
-2.82 0.946302
-2.76 0.944261
-2.7 0.942103
-2.64 0.939817
-2.58 0.937392
-2.52 0.934816
-2.46 0.932074
-2.4 0.929149
-2.34 0.926023
-2.28 0.922673
-2.22 0.919075
-2.16 0.915199
-2.1 0.911012
-2.04 0.906476
-1.98 0.901547
-1.92 0.896176
-1.86 0.890307
-1.8 0.883875
-1.74 0.87681
-1.68 0.869032
-1.62 0.860453
-1.56 0.850978
-1.5 0.840503
-1.44 0.828916
-1.38 0.8161
-1.32 0.801931
-1.26 0.786282
-1.2 0.769024
-1.14 0.750029
-1.08 0.729172
-1.02 0.706337
-0.96 0.681414
-0.9 0.654311
-0.84 0.624951
-0.78 0.59328
-0.72 0.559268
-0.66 0.522911
-0.6 0.48424
-0.54 0.443314
-0.48 0.40023
-0.42 0.355116
-0.36 0.308137
-0.3 0.259489
-0.24 0.2094
-0.18 0.158121
-0.12 0.10593
-0.06 0.0531214
-1.11022e-16 9.8391e-17
0.06 -0.0531214
0.12 -0.10593
0.18 -0.158121
0.24 -0.2094
0.3 -0.259489
0.36 -0.308137
0.42 -0.355116
0.48 -0.40023
0.54 -0.443314
0.6 -0.48424
0.66 -0.522911
0.72 -0.559268
0.78 -0.59328
0.84 -0.624951
0.9 -0.654311
0.96 -0.681414
1.02 -0.706337
1.08 -0.729172
1.14 -0.750029
1.2 -0.769024
1.26 -0.786282
1.32 -0.801931
1.38 -0.8161
1.44 -0.828916
1.5 -0.840503
1.56 -0.850978
1.62 -0.860453
1.68 -0.869032
1.74 -0.87681
1.8 -0.883875
1.86 -0.890307
1.92 -0.896176
1.98 -0.901547
2.04 -0.906476
2.1 -0.911012
2.16 -0.915199
2.22 -0.919075
2.28 -0.922673
2.34 -0.926023
2.4 -0.929149
2.46 -0.932074
2.52 -0.934816
2.58 -0.937392
2.64 -0.939817
2.7 -0.942103
2.76 -0.944261
2.82 -0.946302
2.88 -0.948234
2.94 -0.950065

View File

@ -1,110 +0,0 @@
#set term postscript color
set output "r.ps"
set title "r" 0,0
show title
set xlabel "x" 0,0
show xlabel
set ylabel "r" 0,0
show ylabel
plot'-' title "r" with lines; pause -1
-3 0.951803
-2.94 0.950065
-2.88 0.948234
-2.82 0.946302
-2.76 0.944261
-2.7 0.942103
-2.64 0.939817
-2.58 0.937392
-2.52 0.934816
-2.46 0.932074
-2.4 0.929149
-2.34 0.926023
-2.28 0.922673
-2.22 0.919075
-2.16 0.915199
-2.1 0.911012
-2.04 0.906476
-1.98 0.901547
-1.92 0.896176
-1.86 0.890307
-1.8 0.883875
-1.74 0.87681
-1.68 0.869032
-1.62 0.860453
-1.56 0.850978
-1.5 0.840503
-1.44 0.828916
-1.38 0.8161
-1.32 0.801931
-1.26 0.786282
-1.2 0.769024
-1.14 0.750029
-1.08 0.729172
-1.02 0.706337
-0.96 0.681414
-0.9 0.654311
-0.84 0.624951
-0.78 0.59328
-0.72 0.559268
-0.66 0.522911
-0.6 0.48424
-0.54 0.443314
-0.48 0.40023
-0.42 0.355116
-0.36 0.308137
-0.3 0.259489
-0.24 0.2094
-0.18 0.158121
-0.12 0.10593
-0.06 0.0531214
-1.11022e-16 9.8391e-17
0.06 -0.0531214
0.12 -0.10593
0.18 -0.158121
0.24 -0.2094
0.3 -0.259489
0.36 -0.308137
0.42 -0.355116
0.48 -0.40023
0.54 -0.443314
0.6 -0.48424
0.66 -0.522911
0.72 -0.559268
0.78 -0.59328
0.84 -0.624951
0.9 -0.654311
0.96 -0.681414
1.02 -0.706337
1.08 -0.729172
1.14 -0.750029
1.2 -0.769024
1.26 -0.786282
1.32 -0.801931
1.38 -0.8161
1.44 -0.828916
1.5 -0.840503
1.56 -0.850978
1.62 -0.860453
1.68 -0.869032
1.74 -0.87681
1.8 -0.883875
1.86 -0.890307
1.92 -0.896176
1.98 -0.901547
2.04 -0.906476
2.1 -0.911012
2.16 -0.915199
2.22 -0.919075
2.28 -0.922673
2.34 -0.926023
2.4 -0.929149
2.46 -0.932074
2.52 -0.934816
2.58 -0.937392
2.64 -0.939817
2.7 -0.942103
2.76 -0.944261
2.82 -0.946302
2.88 -0.948234
2.94 -0.950065

View File

@ -1,100 +0,0 @@
-3 0.951803
-2.94 0.950065
-2.88 0.948234
-2.82 0.946302
-2.76 0.944261
-2.7 0.942103
-2.64 0.939817
-2.58 0.937392
-2.52 0.934816
-2.46 0.932074
-2.4 0.929149
-2.34 0.926023
-2.28 0.922673
-2.22 0.919075
-2.16 0.915199
-2.1 0.911012
-2.04 0.906476
-1.98 0.901547
-1.92 0.896176
-1.86 0.890307
-1.8 0.883875
-1.74 0.87681
-1.68 0.869032
-1.62 0.860453
-1.56 0.850978
-1.5 0.840503
-1.44 0.828916
-1.38 0.8161
-1.32 0.801931
-1.26 0.786282
-1.2 0.769024
-1.14 0.750029
-1.08 0.729172
-1.02 0.706337
-0.96 0.681414
-0.9 0.654311
-0.84 0.624951
-0.78 0.59328
-0.72 0.559268
-0.66 0.522911
-0.6 0.48424
-0.54 0.443314
-0.48 0.40023
-0.42 0.355116
-0.36 0.308137
-0.3 0.259489
-0.24 0.2094
-0.18 0.158121
-0.12 0.10593
-0.06 0.0531214
-1.11022e-16 9.8391e-17
0.06 -0.0531214
0.12 -0.10593
0.18 -0.158121
0.24 -0.2094
0.3 -0.259489
0.36 -0.308137
0.42 -0.355116
0.48 -0.40023
0.54 -0.443314
0.6 -0.48424
0.66 -0.522911
0.72 -0.559268
0.78 -0.59328
0.84 -0.624951
0.9 -0.654311
0.96 -0.681414
1.02 -0.706337
1.08 -0.729172
1.14 -0.750029
1.2 -0.769024
1.26 -0.786282
1.32 -0.801931
1.38 -0.8161
1.44 -0.828916
1.5 -0.840503
1.56 -0.850978
1.62 -0.860453
1.68 -0.869032
1.74 -0.87681
1.8 -0.883875
1.86 -0.890307
1.92 -0.896176
1.98 -0.901547
2.04 -0.906476
2.1 -0.911012
2.16 -0.915199
2.22 -0.919075
2.28 -0.922673
2.34 -0.926023
2.4 -0.929149
2.46 -0.932074
2.52 -0.934816
2.58 -0.937392
2.64 -0.939817
2.7 -0.942103
2.76 -0.944261
2.82 -0.946302
2.88 -0.948234
2.94 -0.950065

View File

@ -300,7 +300,8 @@ Foam::tmp<Foam::triSurfacePointScalarField> Foam::automatic::load()
vtkSurfaceWriter
(
surface_.searchableSurface::time().writeFormat()
surface_.searchableSurface::time().writeFormat(),
surface_.searchableSurface::time().writeCompression()
).write
(
surface_.searchableSurface::time().constant()/

View File

@ -523,7 +523,11 @@ void Foam::writeAMIWeightsSum
// Write the surface
if (Pstream::master())
{
vtkSurfaceWriter(mesh.time().writeFormat()).write
vtkSurfaceWriter
(
mesh.time().writeFormat(),
mesh.time().writeCompression()
).write
(
file.path(),
"weightsSum_" + file.name(),
@ -581,7 +585,7 @@ Foam::label Foam::checkGeometry
const polyMesh& mesh,
const bool allGeometry,
const autoPtr<surfaceWriter>& surfWriter,
const autoPtr<Foam::setWriter<scalar>>& setWriter
const autoPtr<Foam::setWriter>& setWriter
)
{
label noFailedChecks = 0;

View File

@ -40,6 +40,6 @@ namespace Foam
const polyMesh& mesh,
const bool allGeometry,
const autoPtr<surfaceWriter>&,
const autoPtr<setWriter<scalar>>&
const autoPtr<setWriter>&
);
}

View File

@ -160,17 +160,20 @@ int main(int argc, char *argv[])
autoPtr<surfaceWriter> surfWriter;
autoPtr<Foam::setWriter<scalar>> setWriter;
autoPtr<Foam::setWriter> setWriter;
if (writeSets)
{
surfWriter = surfaceWriter::New
(
surfaceFormat,
mesh.time().writeFormat()
mesh.time().writeFormat(),
mesh.time().writeCompression()
);
setWriter = Foam::setWriter<scalar>::New
setWriter = Foam::setWriter::New
(
vtkSetWriter<scalar>::typeName
vtkSetWriter::typeName,
mesh.time().writeFormat(),
mesh.time().writeCompression()
);
}

View File

@ -42,6 +42,7 @@ License
#include "globalIndex.H"
#include "PatchTools.H"
#include "writeFile.H"
#include "coordSet.H"
void Foam::printMeshStats(const polyMesh& mesh, const bool allTopology)
@ -377,7 +378,7 @@ void Foam::mergeAndWrite
void Foam::mergeAndWrite
(
const setWriter<scalar>& writer,
const setWriter& writer,
const pointSet& set
)
{
@ -447,41 +448,19 @@ void Foam::mergeAndWrite
mergedPts = pointField(mesh.points(), mergedIDs);
}
// Write with scalar pointID
if (Pstream::master())
{
scalarField scalarPointIDs(mergedIDs.size());
forAll(mergedIDs, i)
{
scalarPointIDs[i] = 1.0*mergedIDs[i];
}
coordSet points(set.name(), "distance", mergedPts, mag(mergedPts));
List<const scalarField*> flds(1, &scalarPointIDs);
wordList fldNames(1, "pointID");
// Output e.g. pointSet p0 to
// postProcessing/<time>/p0.vtk
fileName outputDir
writer.write
(
set.time().path()
/ (Pstream::parRun() ? ".." : "")
/ "postProcessing"
/ mesh.pointsInstance()
// set.name()
set.time().globalPath()
/functionObjects::writeFile::outputPrefix
/mesh.pointsInstance(),
set.name(),
coordSet(false, word::null, mergedPts),
"pointID",
scalarField(scalarList(mergedIDs))
);
outputDir.clean();
mkDir(outputDir);
fileName outputFile(outputDir/writer.getFileName(points, wordList()));
// fileName outputFile(outputDir/set.name());
OFstream os(outputFile);
writer.write(points, fldNames, flds, os);
}
}

View File

@ -35,7 +35,7 @@ namespace Foam
//- Write vtk representation of (assembled) pointSet to 'set' file in
// postProcessing/ directory
void mergeAndWrite(const setWriter<scalar>&, const pointSet&);
void mergeAndWrite(const setWriter&, const pointSet&);
}

View File

@ -44,7 +44,7 @@ Foam::label Foam::checkTopology
const bool allTopology,
const bool allGeometry,
const autoPtr<surfaceWriter>& surfWriter,
const autoPtr<Foam::setWriter<scalar>>& setWriter
const autoPtr<Foam::setWriter>& setWriter
)
{
label noFailedChecks = 0;

View File

@ -13,6 +13,6 @@ namespace Foam
const bool,
const bool,
const autoPtr<surfaceWriter>&,
const autoPtr<setWriter<scalar>>&
const autoPtr<setWriter>&
);
}

View File

@ -193,53 +193,24 @@ int main(int argc, char *argv[])
}
}
if (allTracks.size() && Pstream::master())
{
PtrList<coordSet> tracks(allTracks.size());
DynamicList<point> allTrack;
DynamicList<label> allTrackIDs;
forAll(allTracks, trackI)
{
tracks.set
(
trackI,
new coordSet
(
"track" + Foam::name(trackI),
"distance"
)
);
tracks[trackI].transfer(allTracks[trackI]);
allTrack.append(allTracks[trackI]);
allTrackIDs.append(labelList(allTracks[trackI].size(), trackI));
}
autoPtr<setWriter<scalar>> scalarFormatterPtr =
setWriter<scalar>::New(setFormat);
// OFstream vtkTracks(vtkPath/"particleTracks.vtk");
fileName vtkFile
(
scalarFormatterPtr().getFileName
(
tracks[0],
wordList(0)
)
);
OFstream vtkTracks
(
vtkPath/("particleTracks." + vtkFile.ext())
);
Info<< "\nWriting particle tracks in " << setFormat
<< " format to " << vtkTracks.name()
<< nl << endl;
<< " format to " << vtkPath << nl << endl;
scalarFormatterPtr().write
setWriter::New(setFormat, propsDict)->write
(
true,
tracks,
wordList(0),
List<List<scalarField>>(0),
vtkTracks
vtkPath,
"tracks",
coordSet(allTrackIDs, word::null, pointField(allTrack))
);
}

View File

@ -16,8 +16,12 @@
const bool writeData(readBool(pdfDictionary.lookup("writeData")));
const fileName pdfPath =
runTime.globalPath()
/functionObjects::writeFile::outputPrefix
/args.executable()
/runTime.timeName();
const fileName pdfPath = runTime.path()/"pdf";
mkDir(pdfPath);
Random rndGen(label(0));
@ -35,6 +39,7 @@
const scalar xMax = p->maxValue();
autoPtr<OFstream> filePtr(nullptr);
if (writeData)
{
fileName fName = pdfPath/(p->type() + ".data");

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2011-2018 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2011-2021 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
@ -31,7 +31,8 @@ Description
#include "fvCFD.H"
#include "distributionModel.H"
#include "makeGraph.H"
#include "setWriter.H"
#include "writeFile.H"
#include "OFstream.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -66,13 +67,19 @@ int main(int argc, char *argv[])
}
scalarField x(nIntervals);
forAll(x, i)
{
x[i] = xMin + i*(xMax - xMin)/(nIntervals - 1);
}
makeGraph(x, samples, p->type(), pdfPath, runTime.graphFormat());
setWriter::New(runTime.graphFormat())->write
(
pdfPath,
args.executable(),
coordSet(true, "x", x),
p->type(),
samples
);
Info<< "End\n" << endl;

View File

@ -1,13 +1,3 @@
fileName path
(
UMean.rootPath()
/UMean.caseName()
/functionObjects::writeFile::outputPrefix
/"graphs"
/UMean.instance()
);
mkDir(path);
scalarField UMeanXvalues
(
channelIndexing.collapse(UMean.component(vector::X)())
@ -49,22 +39,31 @@
0.5*(sqr(urmsValues) + sqr(vrmsValues) + sqr(wrmsValues))
);
setWriter::New(runTime.graphFormat())->write
(
runTime.globalPath()
/functionObjects::writeFile::outputPrefix
/args.executable()
/runTime.timeName(),
const scalarField& y = channelIndexing.y();
args.executable(),
makeGraph(y, UMeanXvalues, "Uf", path, gFormat);
makeGraph(y, urmsValues, "u", path, gFormat);
makeGraph(y, vrmsValues, "v", path, gFormat);
makeGraph(y, wrmsValues, "w", path, gFormat);
makeGraph(y, RxyValues, "uv", path, gFormat);
makeGraph(y, kValues, "k", path, gFormat);
coordSet(true, "y", channelIndexing.y()),
makeGraph(y, pPrime2MeanValues, "pPrime2Mean", path, gFormat);
"Uf", UMeanXvalues,
/*
makeGraph(y, epsilonValues, "epsilon", path, gFormat);
makeGraph(y, nuMeanValues, "nu", path, gFormat);
makeGraph(y, nuPrimeValues, "nuPrime", path, gFormat);
makeGraph(y, gammaDotMeanValues, "gammaDot", path, gFormat);
makeGraph(y, gammaDotPrimeValues, "gammaDotPrime", path, gFormat);
*/
"u", urmsValues,
"v", vrmsValues,
"w", wrmsValues,
"uv", RxyValues,
"k", kValues,
"pPrime2Mean", pPrime2MeanValues
// "epsilon", epsilonValues,
// "nu", nuMeanValues,
// "nuPrime", nuPrimeValues,
// "gammaDot", gammaDotMeanValues,
// "gammaDotPrime", gammaDotPrimeValues
);

View File

@ -38,7 +38,7 @@ Description
#include "timeSelector.H"
#include "volFields.H"
#include "channelIndex.H"
#include "makeGraph.H"
#include "setWriter.H"
#include "writeFile.H"
using namespace Foam;
@ -59,8 +59,6 @@ int main(int argc, char *argv[])
#include "createMeshNoChangers.H"
#include "readPhysicalProperties.H"
const word& gFormat = runTime.graphFormat();
// Setup channel indexing for averaging over channel down to a line
IOdictionary channelDict

View File

@ -629,7 +629,7 @@ int main(int argc, char *argv[])
faces[i] = surf[i].triFaceFace();
}
vtkSurfaceWriter(IOstream::ASCII).write
vtkSurfaceWriter(IOstream::ASCII, IOstream::UNCOMPRESSED).write
(
surfFileName.path(),
"zone_" + surfFileNameBase,

View File

@ -0,0 +1,26 @@
/*--------------------------------*- C++ -*----------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Version: dev
\\/ M anipulation |
-------------------------------------------------------------------------------
Description
Writes graph data for specified fields along a line, specified by start and
end points. One graph point is generated on each face and in each cell that
the line intersects.
\*---------------------------------------------------------------------------*/
start <point>;
end <point>;
fields (<fieldNames>);
axis distance; // The independent variable of the graph. Can be "x",
// "y", "z", "xyz" (all coordinates written out), or
// "distance" (from the start point).
#includeEtc "caseDicts/postProcessing/graphs/graphCellFace.cfg"
// ************************************************************************* //

View File

@ -0,0 +1,22 @@
/*--------------------------------*- C++ -*----------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Version: dev
\\/ M anipulation |
\*---------------------------------------------------------------------------*/
#includeEtc "caseDicts/postProcessing/graphs/graph.cfg"
sets
(
line
{
type lineCellFace;
axis $axis;
start $start;
end $end;
}
);
// ************************************************************************* //

View File

@ -0,0 +1,26 @@
/*--------------------------------*- C++ -*----------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Version: dev
\\/ M anipulation |
-------------------------------------------------------------------------------
Description
Writes graph data for specified fields along a line, specified by start and
end points. One graph point is generated on each face that the line
intersects.
\*---------------------------------------------------------------------------*/
start <point>;
end <point>;
fields (<fieldNames>);
axis distance; // The independent variable of the graph. Can be "x",
// "y", "z", "xyz" (all coordinates written out), or
// "distance" (from the start point).
#includeEtc "caseDicts/postProcessing/graphs/graphFace.cfg"
// ************************************************************************* //

View File

@ -0,0 +1,22 @@
/*--------------------------------*- C++ -*----------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Version: dev
\\/ M anipulation |
\*---------------------------------------------------------------------------*/
#includeEtc "caseDicts/postProcessing/graphs/graph.cfg"
sets
(
line
{
type lineFace;
axis $axis;
start $start;
end $end;
}
);
// ************************************************************************* //

View File

@ -21,7 +21,6 @@ sets
points
{
type boundaryPoints;
axis xyz;
points $points;
maxDistance $maxDistance;
patches $patches;

View File

@ -14,6 +14,8 @@ points (<points>);
fields (<fieldNames>);
ordered no;
#includeEtc "caseDicts/postProcessing/probes/internalProbes.cfg"
// ************************************************************************* //

View File

@ -21,8 +21,7 @@ sets
points
{
type points;
axis xyz;
ordered yes;
ordered $ordered;
points $points;
}
);

View File

@ -11,7 +11,6 @@
seedSampleSet
{
type lineUniform;
axis distance;
start $start;
end $end;
nPoints $nPoints;

View File

@ -11,7 +11,6 @@
seedSampleSet
{
type boundaryRandom;
axis xyz;
patches ($patch);
nPoints $nPoints;
}

View File

@ -13,7 +13,6 @@ seedSampleSet
type points;
points $points;
ordered yes;
axis xyz;
}
// ************************************************************************* //

View File

@ -11,7 +11,6 @@
seedSampleSet
{
type sphereRandom;
axis xyz;
centre $centre;
radius $radius;
nPoints $nPoints;

View File

@ -725,15 +725,6 @@ algorithms/polygonTriangulate/polygonTriangulate.C
algorithms/dynamicIndexedOctree/dynamicIndexedOctreeName.C
algorithms/dynamicIndexedOctree/dynamicTreeDataPoint.C
graph/curve/curve.C
graph/graph.C
writers = graph/writers
$(writers)/rawGraph/rawGraph.C
$(writers)/gnuplotGraph/gnuplotGraph.C
$(writers)/xmgrGraph/xmgrGraph.C
$(writers)/jplotGraph/jplotGraph.C
meshes/data/data.C
meshes/Residuals/residuals.C

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2011-2020 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2011-2021 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
@ -234,6 +234,23 @@ public:
//- Move assignment to List
inline void operator=(List<T>&&);
// IOstream Operators
// Write DynamicField to Ostream.
friend Ostream& operator<< <T, SizeInc, SizeMult, SizeDiv>
(
Ostream&,
const DynamicField<T, SizeInc, SizeMult, SizeDiv>&
);
//- Read from Istream, discarding contents of existing DynamicField.
friend Istream& operator>> <T, SizeInc, SizeMult, SizeDiv>
(
Istream&,
DynamicField<T, SizeInc, SizeMult, SizeDiv>&
);
};

View File

@ -24,6 +24,7 @@ License
\*---------------------------------------------------------------------------*/
#include "histogram.H"
#include "coordSet.H"
#include "volFields.H"
#include "addToRunTimeSelectionTable.H"
@ -39,33 +40,6 @@ namespace functionObjects
}
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
void Foam::functionObjects::histogram::writeGraph
(
const coordSet& coords,
const word& fieldName,
const scalarField& values
) const
{
const wordList fieldNames(1, fieldName);
fileName outputPath = file_.baseTimeDir();
mkDir(outputPath);
OFstream graphFile
(
outputPath/formatterPtr_().getFileName(coords, fieldNames)
);
Log << " Writing histogram of " << fieldName
<< " to " << graphFile.name() << endl;
List<const scalarField*> yPtrs(1);
yPtrs[0] = &values;
formatterPtr_().write(coords, fieldNames, yPtrs, graphFile);
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::functionObjects::histogram::histogram
@ -97,8 +71,7 @@ bool Foam::functionObjects::histogram::read(const dictionary& dict)
min_ = dict.lookupOrDefault<scalar>("min", 0);
dict.lookup("nBins") >> nBins_;
word format(dict.lookup("setFormat"));
formatterPtr_ = setWriter<scalar>::New(format);
formatterPtr_ = setWriter::New(dict.lookup("setFormat"), dict);
return true;
}
@ -153,13 +126,12 @@ bool Foam::functionObjects::histogram::write()
);
// Calculate the mid-points of bins for the graph axis
pointField xBin(nBins_);
scalarField xBin(nBins_);
const scalar delta = (max_- min_)/nBins_;
scalar x = min_ + 0.5*delta;
forAll(xBin, i)
{
xBin[i] = point(x, 0, 0);
xBin[i] = x;
x += delta;
}
@ -185,15 +157,14 @@ bool Foam::functionObjects::histogram::write()
{
volFrac /= sumVol;
const coordSet coords
formatterPtr_().write
(
"Volume_Fraction",
"x",
xBin,
mag(xBin)
file_.baseTimeDir(),
typeName,
coordSet(true, fieldName_, xBin),
field.name(),
volFrac
);
writeGraph(coords, field.name(), volFrac);
}
}

View File

@ -103,17 +103,7 @@ class histogram
label nBins_;
//- Output formatter to write
autoPtr<setWriter<scalar>> formatterPtr_;
// Private Member Functions
void writeGraph
(
const coordSet& coords,
const word& valueName,
const scalarField& values
) const;
autoPtr<setWriter> formatterPtr_;
public:

View File

@ -77,13 +77,16 @@ void Foam::functionObjects::interfaceHeight::writePositions()
"",
mesh_,
meshSearch(mesh_),
"xyz",
coordSet::axisTypeNames_[coordSet::axisType::XYZ],
locations_[li] + gHat*mesh_.bounds().mag(),
locations_[li] - gHat*mesh_.bounds().mag()
);
// Find the height of the location above the boundary
scalar hLB = set.size() ? - gHat & (locations_[li] - set[0]) : - vGreat;
scalar hLB =
set.size()
? - gHat & (locations_[li] - set.pointCoord(0))
: - vGreat;
reduce(hLB, maxOp<scalar>());
// Calculate the integrals of length and length*alpha along the sampling
@ -97,7 +100,7 @@ void Foam::functionObjects::interfaceHeight::writePositions()
continue;
}
const vector& p0 = set[si], p1 = set[si+1];
const vector& p0 = set.pointCoord(si), p1 = set.pointCoord(si+1);
const label c0 = set.cells()[si], c1 = set.cells()[si+1];
const label f0 = set.faces()[si], f1 = set.faces()[si+1];
const scalar a0 = interpolator->interpolate(p0, c0, f0);

View File

@ -65,29 +65,6 @@ namespace Foam
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
void Foam::functionObjects::regionSizeDistribution::writeGraph
(
const coordSet& coords,
const word& valueName,
const scalarField& values
) const
{
const wordList valNames(1, valueName);
fileName outputPath = file_.baseTimeDir();
mkDir(outputPath);
OFstream str(outputPath/formatterPtr_().getFileName(coords, valNames));
Info<< " Writing distribution of " << valueName << " to " << str.name()
<< endl;
List<const scalarField*> valPtrs(1);
valPtrs[0] = &values;
formatterPtr_().write(coords, valNames, valPtrs, str);
}
void Foam::functionObjects::regionSizeDistribution::writeAlphaFields
(
const regionSplit& regions,
@ -216,15 +193,16 @@ Foam::functionObjects::regionSizeDistribution::findPatchRegions
}
Foam::tmp<Foam::scalarField>
template<class Type>
Foam::tmp<Foam::Field<Type>>
Foam::functionObjects::regionSizeDistribution::divide
(
const scalarField& num,
const Field<Type>& num,
const scalarField& denom
)
{
tmp<scalarField> tresult(new scalarField(num.size()));
scalarField& result = tresult.ref();
tmp<Field<Type>> tresult(new Field<Type>(num.size()));
Field<Type>& result = tresult.ref();
forAll(denom, i)
{
@ -234,35 +212,71 @@ Foam::functionObjects::regionSizeDistribution::divide
}
else
{
result[i] = 0.0;
result[i] = Zero;
}
}
return tresult;
}
void Foam::functionObjects::regionSizeDistribution::writeGraphs
template<class Type>
void Foam::functionObjects::regionSizeDistribution::generateFields
(
const word& fieldName, // name of field
const labelList& indices, // index of bin for each region
const scalarField& sortedField, // per region field data
const Field<Type>& sortedField, // per region field data
const scalarField& binCount, // per bin number of regions
const coordSet& coords // graph data for bins
wordList& fieldNames,
PtrList<Field<Type>>& fields
) const
{
if (Pstream::master())
{
// Calculate per-bin average
scalarField binSum(nBins_, 0.0);
// Calculate per-bin sum
Field<Type> binSum(nBins_, Zero);
forAll(sortedField, i)
{
binSum[indices[i]] += sortedField[i];
}
// Calculate per-bin average
Field<Type> binAvg(divide(binSum, binCount));
// Append
fields.setSize(fieldNames.size());
fieldNames.append(fieldName + "_sum");
fields.append(binSum);
fieldNames.append(fieldName + "_avg");
fields.append(binAvg);
}
}
void Foam::functionObjects::regionSizeDistribution::generateFields
(
const word& fieldName, // name of field
const labelList& indices, // index of bin for each region
const scalarField& sortedField, // per region field data
const scalarField& binCount, // per bin number of regions
wordList& fieldNames,
PtrList<scalarField>& fields
) const
{
if (Pstream::master())
{
// Calculate per-bin sum
scalarField binSum(nBins_, Zero);
forAll(sortedField, i)
{
binSum[indices[i]] += sortedField[i];
}
// Calculate per-bin average
scalarField binAvg(divide(binSum, binCount));
// Per bin deviation
scalarField binSqrSum(nBins_, 0.0);
// Calculate per-bin deviation
scalarField binSqrSum(nBins_, Zero);
forAll(sortedField, i)
{
binSqrSum[indices[i]] += Foam::sqr(sortedField[i]);
@ -272,50 +286,50 @@ void Foam::functionObjects::regionSizeDistribution::writeGraphs
sqrt(divide(binSqrSum, binCount) - Foam::sqr(binAvg))
);
// Write average
writeGraph(coords, fieldName + "_sum", binSum);
// Write average
writeGraph(coords, fieldName + "_avg", binAvg);
// Write deviation
writeGraph(coords, fieldName + "_dev", binDev);
// Append
fields.setSize(fieldNames.size());
fieldNames.append(fieldName + "_sum");
fields.append(binSum);
fieldNames.append(fieldName + "_avg");
fields.append(binAvg);
fieldNames.append(fieldName + "_dev");
fields.append(binDev);
}
}
void Foam::functionObjects::regionSizeDistribution::writeGraphs
template<class Type>
void Foam::functionObjects::regionSizeDistribution::generateFields
(
const word& fieldName, // name of field
const scalarField& cellField, // per cell field data
const Field<Type>& cellField, // per cell field data
const regionSplit& regions, // per cell the region(=droplet)
const labelList& sortedRegions, // valid regions in sorted order
const scalarField& sortedNormalisation,
const labelList& indices, // per region index of bin
const labelList& indices, // index of bin for each region
const scalarField& binCount, // per bin number of regions
const coordSet& coords // graph data for bins
wordList& fieldNames,
PtrList<Field<Type>>& fields
) const
{
// Sum on a per-region basis. Parallel reduced.
Map<scalar> regionField(regionSum(regions, cellField));
Map<Type> regionField(regionSum(regions, cellField));
// Extract in region order
scalarField sortedField
Field<Type> sortedField
(
sortedNormalisation
* extractData
(
sortedRegions,
regionField
)
sortedNormalisation*extractData(sortedRegions, regionField)
);
writeGraphs
// Generate fields
generateFields
(
fieldName, // name of field
indices, // index of bin for each region
sortedField, // per region field data
binCount, // per bin number of regions
coords // graph data for bins
fieldNames,
fields
);
}
@ -348,7 +362,7 @@ Foam::functionObjects::regionSizeDistribution::~regionSizeDistribution()
bool Foam::functionObjects::regionSizeDistribution::read(const dictionary& dict)
{
dict.lookup("field") >> alphaName_;
dict.lookup("alpha") >> alphaName_;
dict.lookup("patches") >> patchNames_;
dict.lookup("threshold") >> threshold_;
dict.lookup("maxDiameter") >> maxDiam_;
@ -357,16 +371,7 @@ bool Foam::functionObjects::regionSizeDistribution::read(const dictionary& dict)
dict.lookup("nBins") >> nBins_;
dict.lookup("fields") >> fields_;
word format(dict.lookup("setFormat"));
formatterPtr_ = setWriter<scalar>::New(format);
if (dict.found("coordinateSystem"))
{
coordSysPtr_ = coordinateSystem::New(obr_, dict);
Info<< "Transforming all vectorFields with coordinate system "
<< coordSysPtr_().name() << endl;
}
formatterPtr_ = setWriter::New(dict.lookup("setFormat"), dict);
return true;
}
@ -664,18 +669,14 @@ bool Foam::functionObjects::regionSizeDistribution::write()
if (allRegionVolume.size())
{
// Construct mids of bins for plotting
pointField xBin(nBins_);
scalarField xBin(nBins_);
scalar x = 0.5*delta;
forAll(xBin, i)
{
xBin[i] = point(x, 0, 0);
xBin[i] = x;
x += delta;
}
const coordSet coords("diameter", "x", xBin, mag(xBin));
// Get in region order the alpha*volume and diameter
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@ -715,12 +716,6 @@ bool Foam::functionObjects::regionSizeDistribution::write()
binCount[indices[i]] += 1.0;
}
// Write counts
if (Pstream::master())
{
writeGraph(coords, "count", binCount);
}
// Write to log
{
Info<< " Bins:" << endl;
@ -740,103 +735,80 @@ bool Foam::functionObjects::regionSizeDistribution::write()
Info<< endl;
}
// Declare fields and field names
wordList fieldNames;
#define DeclareTypeFields(Type, nullArg) \
PtrList<Field<Type>> Type##Fields;
FOR_ALL_FIELD_TYPES(DeclareTypeFields);
#undef DeclareTypeFields
// Write average and deviation of droplet volume.
writeGraphs
// Add the bin count
fieldNames.append("binCount");
#define TypeFieldsAppend(Type, nullArg) \
appendFields(binCount, Type##Fields);
#undef TypeFieldsAppend
// Add the volumes
generateFields
(
"volume", // name of field
indices, // per region the bin index
sortedVols, // per region field data
binCount, // per bin number of regions
coords // graph data for bins
"volume",
indices,
sortedVols,
binCount,
fieldNames,
scalarFields
);
// Collect some more field
// Add other sampled fields
forAll(fields_, fieldi)
{
forAll(fields_, i)
{
if (obr_.foundObject<volScalarField>(fields_[i]))
{
Info<< " Scalar field " << fields_[i] << endl;
bool found = false;
const scalarField& fld =
obr_.lookupObject<volScalarField>(fields_[i])
.primitiveField();
writeGraphs
(
fields_[i], // name of field
alphaVol*fld, // per cell field data
regions, // per cell the region(=droplet)
sortedRegions, // valid regions in sorted order
1.0/sortedVols, // per region normalisation
indices, // index of bin for each region
binCount, // per bin number of regions
coords // graph data for bins
);
#define GenerateTypeFields(Type, nullArg) \
\
if (obr_.foundObject<VolField<Type>>(fields_[fieldi])) \
{ \
found = true; \
\
const VolField<Type>& field = \
obr_.lookupObject<VolField<Type>>(fields_[fieldi]); \
\
generateFields \
( \
fields_[fieldi], \
(alphaVol*field)(), \
regions, \
sortedRegions, \
1.0/sortedVols, \
indices, \
binCount, \
fieldNames, \
Type##Fields \
); \
}
}
FOR_ALL_FIELD_TYPES(GenerateTypeFields);
#undef GenerateTypeFields
if (!found) cannotFindObject(fields_[fieldi]);
}
{
forAll(fields_, i)
{
if (obr_.foundObject<volScalarField>(fields_[i]))
{
Info<< " Vector field " << fields_[i] << endl;
vectorField fld =
obr_.lookupObject<volVectorField>(fields_[i])
.primitiveField();
// Expand all field lists
#define TypeFieldsExpand(Type, nullArg) \
Type##Fields.setSize(fieldNames.size());
FOR_ALL_FIELD_TYPES(TypeFieldsExpand)
#undef TypeFieldsAppend
if (coordSysPtr_.valid())
{
Info<< "Transforming vector field " << fields_[i]
<< " with coordinate system "
<< coordSysPtr_().name()
<< endl;
fld = coordSysPtr_().localVector(fld);
}
// Components
for (direction cmp = 0; cmp < vector::nComponents; cmp++)
{
writeGraphs
(
fields_[i] + vector::componentNames[cmp],
alphaVol*fld.component(cmp),// per cell field data
regions, // per cell the region(=droplet)
sortedRegions, // valid regions in sorted order
1.0/sortedVols, // per region normalisation
indices, // index of bin for each region
binCount, // per bin number of regions
coords // graph data for bins
);
}
// Magnitude
writeGraphs
(
fields_[i] + "mag", // name of field
alphaVol*mag(fld), // per cell field data
regions, // per cell the region(=droplet)
sortedRegions, // valid regions in sorted order
1.0/sortedVols, // per region normalisation
indices, // index of bin for each region
binCount, // per bin number of regions
coords // graph data for bins
);
}
}
}
// Write
formatterPtr_().write
(
file_.baseTimeDir(),
typeName,
coordSet(true, "diameter", xBin),
fieldNames
#define TypeFieldsParameter(Type, nullArg) , Type##Fields
FOR_ALL_FIELD_TYPES(TypeFieldsParameter)
#undef TypeFieldsParameter
);
}
return true;

View File

@ -66,13 +66,6 @@ Description
maxDiameter 0.5e-4;
minDiameter 0;
setFormat gnuplot;
coordinateSystem
{
type cartesian;
origin (0 0 0);
e3 (0 1 1);
e1 (1 0 0);
}
}
\endverbatim
@ -88,7 +81,6 @@ Usage
maxDiameter | maximum region equivalent diameter | yes |
minDiameter | minimum region equivalent diameter | no | 0
setFormat | writing format | yes |
coordinateSystem | transformation for vector fields | no |
\endtable
See also
@ -157,10 +149,7 @@ class regionSizeDistribution
wordList fields_;
//- Output formatter to write
autoPtr<setWriter<scalar>> formatterPtr_;
//- Optional coordinate system
autoPtr<coordinateSystem> coordSysPtr_;
autoPtr<setWriter> formatterPtr_;
// Private Member Functions
@ -173,13 +162,6 @@ class regionSizeDistribution
List<Type> extractData(const UList<label>& keys, const Map<Type>&)
const;
void writeGraph
(
const coordSet& coords,
const word& valueName,
const scalarField& values
) const;
//- Write volfields with the parts of alpha which are not
// droplets (liquidCore, backGround)
void writeAlphaFields
@ -194,31 +176,46 @@ class regionSizeDistribution
Map<label> findPatchRegions(const regionSplit&) const;
//- Helper: divide if denom != 0
static tmp<scalarField> divide(const scalarField&, const scalarField&);
template<class Type>
static tmp<Field<Type>> divide(const Field<Type>&, const scalarField&);
//- Given per-region data calculate per-bin average/deviation and graph
void writeGraphs
//- Generate fields for writing
template<class Type>
void generateFields
(
const word& fieldName, // name of field
const labelList& indices, // index of bin for each region
const Field<Type>& sortedField, // per region field data
const scalarField& binCount, // per bin number of regions
wordList& fieldNames,
PtrList<Field<Type>>& fields
) const;
//- Generate fields for writing. Scalar overload. It is possible to
// generate more fields for scalar input.
void generateFields
(
const word& fieldName, // name of field
const labelList& indices, // index of bin for each region
const scalarField& sortedField, // per region field data
const scalarField& binCount, // per bin number of regions
const coordSet& coords // graph data for bins
wordList& fieldNames,
PtrList<scalarField>& fields
) const;
//- Given per-cell data calculate per-bin average/deviation and graph
void writeGraphs
//- Generate fields for writing
template<class Type>
void generateFields
(
const word& fieldName, // name of field
const scalarField& cellField, // per cell field data
const Field<Type>& cellField, // per cell field data
const regionSplit& regions, // per cell the region(=droplet)
const labelList& sortedRegions, // valid regions in sorted order
const scalarField& sortedNormalisation,
const labelList& indices, // index of bin for each region
const scalarField& binCount, // per bin number of regions
const coordSet& coords // graph data for bins
wordList& fieldNames,
PtrList<Field<Type>>& fields
) const;

View File

@ -38,6 +38,29 @@ License
#include "writeFile.H"
#include "addToRunTimeSelectionTable.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
template<class Type>
void gatherAndFlatten(DynamicField<Type>& field)
{
List<List<Type>> gatheredField(Pstream::nProcs());
gatheredField[Pstream::myProcNo()] = field;
Pstream::gatherList(gatheredField);
field =
ListListOps::combine<List<Type>>
(
gatheredField,
accessOp<List<Type>>()
);
}
}
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
@ -58,250 +81,6 @@ namespace Foam
}
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
Foam::autoPtr<Foam::indirectPrimitivePatch>
Foam::functionObjects::streamlines::wallPatch() const
{
const polyBoundaryMesh& patches = mesh_.boundaryMesh();
label nFaces = 0;
forAll(patches, patchi)
{
if (isA<wallPolyPatch>(patches[patchi]))
{
nFaces += patches[patchi].size();
}
}
labelList addressing(nFaces);
nFaces = 0;
forAll(patches, patchi)
{
if (isA<wallPolyPatch>(patches[patchi]))
{
const polyPatch& pp = patches[patchi];
forAll(pp, i)
{
addressing[nFaces++] = pp.start()+i;
}
}
}
return autoPtr<indirectPrimitivePatch>
(
new indirectPrimitivePatch
(
IndirectList<face>
(
mesh_.faces(),
addressing
),
mesh_.points()
)
);
}
void Foam::functionObjects::streamlines::track()
{
IDLList<streamlinesParticle> initialParticles;
streamlinesCloud particles
(
mesh_,
cloudName_,
initialParticles
);
const sampledSet& seedPoints = sampledSetPtr_();
forAll(seedPoints, i)
{
particles.addParticle
(
new streamlinesParticle
(
mesh_,
seedPoints[i],
seedPoints.cells()[i],
lifeTime_
)
);
}
label nSeeds = returnReduce(particles.size(), sumOp<label>());
Info << " seeded " << nSeeds << " particles" << endl;
// Read or lookup fields
PtrList<volScalarField> vsFlds;
PtrList<interpolation<scalar>> vsInterp;
PtrList<volVectorField> vvFlds;
PtrList<interpolation<vector>> vvInterp;
label UIndex = -1;
label nScalar = 0;
label nVector = 0;
forAll(fields_, i)
{
if (mesh_.foundObject<volScalarField>(fields_[i]))
{
nScalar++;
}
else if (mesh_.foundObject<volVectorField>(fields_[i]))
{
nVector++;
}
else
{
FatalErrorInFunction
<< "Cannot find field " << fields_[i] << nl
<< "Valid scalar fields are:"
<< mesh_.names(volScalarField::typeName) << nl
<< "Valid vector fields are:"
<< mesh_.names(volVectorField::typeName)
<< exit(FatalError);
}
}
vsInterp.setSize(nScalar);
nScalar = 0;
vvInterp.setSize(nVector);
nVector = 0;
forAll(fields_, i)
{
if (mesh_.foundObject<volScalarField>(fields_[i]))
{
const volScalarField& f = mesh_.lookupObject<volScalarField>
(
fields_[i]
);
vsInterp.set
(
nScalar++,
interpolation<scalar>::New
(
interpolationScheme_,
f
)
);
}
else if (mesh_.foundObject<volVectorField>(fields_[i]))
{
const volVectorField& f = mesh_.lookupObject<volVectorField>
(
fields_[i]
);
if (f.name() == UName_)
{
UIndex = nVector;
}
vvInterp.set
(
nVector++,
interpolation<vector>::New
(
interpolationScheme_,
f
)
);
}
}
// Store the names
scalarNames_.setSize(vsInterp.size());
forAll(vsInterp, i)
{
scalarNames_[i] = vsInterp[i].psi().name();
}
vectorNames_.setSize(vvInterp.size());
forAll(vvInterp, i)
{
vectorNames_[i] = vvInterp[i].psi().name();
}
// Check that we know the index of U in the interpolators.
if (UIndex == -1)
{
FatalErrorInFunction
<< "Cannot find field to move particles with : " << UName_ << nl
<< "This field has to be present in the sampled fields " << fields_
<< " and in the objectRegistry."
<< exit(FatalError);
}
// Sampled data
// ~~~~~~~~~~~~
// Size to maximum expected sizes.
allTracks_.clear();
allTracks_.setCapacity(nSeeds);
allAges_.clear();
allAges_.setCapacity(nSeeds);
allScalars_.setSize(vsInterp.size());
forAll(allScalars_, i)
{
allScalars_[i].clear();
allScalars_[i].setCapacity(nSeeds);
}
allVectors_.setSize(vvInterp.size());
forAll(allVectors_, i)
{
allVectors_[i].clear();
allVectors_[i].setCapacity(nSeeds);
}
// Additional particle info
streamlinesParticle::trackingData td
(
particles,
vsInterp,
vvInterp,
UIndex, // index of U in vvInterp
trackDirection_ == trackDirection::forward,
trackOutside_,
nSubCycle_, // automatic track control:step through cells in steps?
trackLength_, // fixed track length
allTracks_,
allAges_,
allScalars_,
allVectors_
);
// Set very large dt. Note: cannot use great since 1/great is small
// which is a trigger value for the tracking...
const scalar trackTime = Foam::sqrt(great);
// Track
if (trackDirection_ == trackDirection::both)
{
initialParticles = particles;
}
particles.move(particles, td, trackTime);
if (trackDirection_ == trackDirection::both)
{
particles.IDLList<streamlinesParticle>::operator=(initialParticles);
td.trackForward_ = !td.trackForward_;
particles.move(particles, td, trackTime);
}
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::functionObjects::streamlines::streamlines
@ -337,34 +116,17 @@ bool Foam::functionObjects::streamlines::read(const dictionary& dict)
Info<< type() << " " << name() << ":" << nl;
dict.lookup("fields") >> fields_;
UName_ = dict.lookupOrDefault("U", word("U"));
if (findIndex(fields_, UName_) == -1)
{
FatalIOErrorInFunction(dict)
<< "Velocity field for tracking " << UName_
<< " should be present in the list of fields " << fields_
<< exit(FatalIOError);
}
UName_ = dict.lookupOrDefault("U", word("U"));
writeAge_ = dict.lookupOrDefault<Switch>("writeAge", true);
// The trackForward entry is maintained here for backwards compatibility
if (!dict.found("direction") && dict.found("trackForward"))
{
trackDirection_ =
dict.lookup<bool>("trackForward")
? trackDirection::forward
: trackDirection::backward;
}
else
{
trackDirection_ = trackDirectionNames_[word(dict.lookup("direction"))];
}
trackDirection_ = trackDirectionNames_[word(dict.lookup("direction"))];
trackOutside_ = dict.lookupOrDefault<Switch>("outside", false);
dict.lookup("lifeTime") >> lifeTime_;
if (lifeTime_ < 1)
{
FatalErrorInFunction
@ -372,10 +134,8 @@ bool Foam::functionObjects::streamlines::read(const dictionary& dict)
<< exit(FatalError);
}
bool subCycling = dict.found("nSubCycle");
bool fixedLength = dict.found("trackLength");
if (subCycling && fixedLength)
{
FatalIOErrorInFunction(dict)
@ -384,33 +144,27 @@ bool Foam::functionObjects::streamlines::read(const dictionary& dict)
<< "trackLength')"
<< exit(FatalIOError);
}
nSubCycle_ = 1;
if (dict.readIfPresent("nSubCycle", nSubCycle_))
if (subCycling)
{
nSubCycle_ = max(dict.lookup<scalar>("nSubCycle"), 1);
trackLength_ = vGreat;
if (nSubCycle_ < 1)
{
nSubCycle_ = 1;
}
Info<< " automatic track length specified through"
<< " number of sub cycles : " << nSubCycle_ << nl << endl;
}
else
{
nSubCycle_ = 1;
dict.lookup("trackLength") >> trackLength_;
Info<< " fixed track length specified : "
<< trackLength_ << nl << endl;
}
interpolationScheme_ = dict.lookupOrDefault
(
"interpolationScheme",
interpolationCellPoint<scalar>::typeName
);
interpolationScheme_ =
dict.lookupOrDefault
(
"interpolationScheme",
interpolationCellPoint<scalar>::typeName
);
cloudName_ = dict.lookupOrDefault<word>("cloudName", "streamlines");
@ -423,10 +177,8 @@ bool Foam::functionObjects::streamlines::read(const dictionary& dict)
meshSearchPtr_(),
dict.subDict("seedSampleSet")
);
sampledSetAxis_ = sampledSetPtr_->axis();
scalarFormatterPtr_ = setWriter<scalar>::New(dict.lookup("setFormat"));
vectorFormatterPtr_ = setWriter<vector>::New(dict.lookup("setFormat"));
formatterPtr_ = setWriter::New(dict.lookup("setFormat"), dict);
return true;
}
@ -451,276 +203,382 @@ bool Foam::functionObjects::streamlines::write()
{
Info<< type() << " " << name() << " write:" << nl;
const Time& runTime = obr_.time();
// Create list of available fields
wordList fieldNames;
forAll(fields_, fieldi)
{
if
(
false
#define FoundTypeField(Type, nullArg) \
|| foundObject<VolField<Type>>(fields_[fieldi])
FOR_ALL_FIELD_TYPES(FoundTypeField)
#undef FoundTypeField
)
{
fieldNames.append(fields_[fieldi]);
}
else
{
cannotFindObject(fields_[fieldi]);
}
}
// Do all injection and tracking
track();
// Lookup fields and construct interpolators
#define DeclareTypeInterpolator(Type, nullArg) \
PtrList<interpolation<Type>> Type##Interp(fieldNames.size());
FOR_ALL_FIELD_TYPES(DeclareTypeInterpolator);
#undef DeclareTypeInterpolator
forAll(fieldNames, fieldi)
{
#define ConstructTypeInterpolator(Type, nullArg) \
if (mesh_.foundObject<VolField<Type>>(fieldNames[fieldi])) \
{ \
Type##Interp.set \
( \
fieldi, \
interpolation<Type>::New \
( \
interpolationScheme_, \
mesh_.lookupObject<VolField<Type>>(fieldNames[fieldi]) \
) \
); \
}
FOR_ALL_FIELD_TYPES(ConstructTypeInterpolator);
#undef ConstructTypeInterpolator
}
// Create a velocity interpolator if it is not already available
const label UIndex = findIndex(fieldNames, UName_);
tmpNrc<interpolation<vector>> UInterp(nullptr);
if (UIndex == -1)
{
UInterp =
tmpNrc<interpolation<vector>>
(
interpolation<vector>::New
(
interpolationScheme_,
mesh_.lookupObject<volVectorField>(UName_)
).ptr()
);
}
// Do tracking to create sampled data
DynamicField<point> allPositions;
DynamicField<label> allTracks;
DynamicField<label> allTrackParts;
DynamicField<scalar> allAges;
#define DeclareAllTypes(Type, nullArg) \
List<DynamicField<Type>> all##Type##s(fieldNames.size());
FOR_ALL_FIELD_TYPES(DeclareAllTypes);
#undef DeclareAllTypes
{
// Create a cloud and initialise with points from the sampled set
globalIndex gi(sampledSetPtr_().size());
streamlinesCloud particles
(
mesh_,
cloudName_,
IDLList<streamlinesParticle>()
);
forAll(sampledSetPtr_(), i)
{
particles.addParticle
(
new streamlinesParticle
(
mesh_,
sampledSetPtr_().positions()[i],
sampledSetPtr_().cells()[i],
lifeTime_,
gi.toGlobal(i)
)
);
}
// Report the number of successful seeds
const label nSeeds = returnReduce(particles.size(), sumOp<label>());
Info << " Seeded " << nSeeds << " particles" << endl;
// Create tracking data
streamlinesParticle::trackingData td
(
particles,
#define TypeInterpolatorParameter(Type, nullArg) \
Type##Interp,
FOR_ALL_FIELD_TYPES(TypeInterpolatorParameter)
#undef TypeInterpolatorParameter
UIndex != -1 ? vectorInterp[UIndex] : UInterp(),
trackDirection_ == trackDirection::forward,
trackOutside_,
nSubCycle_,
trackLength_,
allPositions,
allTracks,
allTrackParts,
allAges
#define AllTypesParameter(Type, nullArg) \
, all##Type##s
FOR_ALL_FIELD_TYPES(AllTypesParameter)
#undef AllTypesParameter
);
// Track
IDLList<streamlinesParticle> initialParticles;
if (trackDirection_ == trackDirection::both)
{
initialParticles = particles;
}
particles.move(particles, td, rootGreat);
if (trackDirection_ == trackDirection::both)
{
particles.IDLList<streamlinesParticle>::operator=(initialParticles);
td.trackForward_ = !td.trackForward_;
particles.move(particles, td, rootGreat);
}
}
// Gather data on the master
if (Pstream::parRun())
{
// Append slave tracks to master ones
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
globalIndex globalTrackIDs(allTracks_.size());
// Construct a distribution map to pull all to the master.
labelListList sendMap(Pstream::nProcs());
labelListList recvMap(Pstream::nProcs());
if (Pstream::master())
gatherAndFlatten(allPositions);
gatherAndFlatten(allTracks);
gatherAndFlatten(allTrackParts);
gatherAndFlatten(allAges);
forAll(fieldNames, fieldi)
{
// Master: receive all. My own first, then consecutive
// processors.
label trackI = 0;
forAll(recvMap, proci)
{
labelList& fromProc = recvMap[proci];
fromProc.setSize(globalTrackIDs.localSize(proci));
forAll(fromProc, i)
{
fromProc[i] = trackI++;
#define GatherAndFlattenAllTypes(Type, nullArg) \
if (Type##Interp.set(fieldi)) \
{ \
gatherAndFlatten(all##Type##s[fieldi]); \
}
FOR_ALL_FIELD_TYPES(GatherAndFlattenAllTypes);
#undef GatherAndFlattenAllTypes
}
}
// Report the total number of samples
Info<< " Sampled " << allPositions.size() << " locations" << endl;
// Bin-sort by track and trackPart to build an ordering
labelList order(allPositions.size());
if (Pstream::master())
{
const label nTracks = max(allTracks) + 1;
const label trackParti0 = min(allTrackParts);
const label trackParti1 = max(allTrackParts) + 1;
labelListList trackPartCounts
(
nTracks,
labelList(trackParti1 - trackParti0, 0)
);
forAll(allPositions, samplei)
{
const label tracki = allTracks[samplei];
const label trackParti = -trackParti0 + allTrackParts[samplei];
trackPartCounts[tracki][trackParti] ++;
}
label offset = 0;
labelListList trackPartOffsets
(
nTracks,
labelList(trackParti1 - trackParti0, 0)
);
forAll(trackPartOffsets, tracki)
{
forAll(trackPartOffsets[tracki], trackParti)
{
trackPartOffsets[tracki][trackParti] += offset;
offset += trackPartCounts[tracki][trackParti];
}
}
labelList& toMaster = sendMap[0];
toMaster.setSize(globalTrackIDs.localSize());
forAll(toMaster, i)
forAll(trackPartCounts, tracki)
{
toMaster[i] = i;
trackPartCounts[tracki] = 0;
}
const mapDistribute distMap
(
globalTrackIDs.size(),
move(sendMap),
move(recvMap)
);
// Distribute the track positions. Note: use scheduled comms
// to prevent buffering.
mapDistributeBase::distribute
(
Pstream::commsTypes::scheduled,
distMap.schedule(),
distMap.constructSize(),
distMap.subMap(),
false,
distMap.constructMap(),
false,
allTracks_,
flipOp()
);
// Distribute the ages
mapDistributeBase::distribute
(
Pstream::commsTypes::scheduled,
distMap.schedule(),
distMap.constructSize(),
distMap.subMap(),
false,
distMap.constructMap(),
false,
allAges_,
flipOp()
);
// Distribute the scalars
forAll(allScalars_, scalari)
forAll(allPositions, samplei)
{
allScalars_[scalari].shrink();
mapDistributeBase::distribute
(
Pstream::commsTypes::scheduled,
distMap.schedule(),
distMap.constructSize(),
distMap.subMap(),
false,
distMap.constructMap(),
false,
allScalars_[scalari],
flipOp()
);
allScalars_[scalari].setCapacity(allScalars_[scalari].size());
}
// Distribute the vectors
forAll(allVectors_, vectori)
{
allVectors_[vectori].shrink();
mapDistributeBase::distribute
(
Pstream::commsTypes::scheduled,
distMap.schedule(),
distMap.constructSize(),
distMap.subMap(),
false,
distMap.constructMap(),
false,
allVectors_[vectori],
flipOp()
);
allVectors_[vectori].setCapacity(allVectors_[vectori].size());
const label tracki = allTracks[samplei];
const label trackParti = -trackParti0 + allTrackParts[samplei];
order[samplei] =
trackPartOffsets[tracki][trackParti]
+ trackPartCounts[tracki][trackParti];
trackPartCounts[tracki][trackParti] ++;
}
}
//auto reportTrackParts = [&]()
//{
// Info<< nl;
// forAll(allPositions, samplei)
// {
// if
// (
// samplei == 0
// || allTracks[samplei] != allTracks[samplei - 1]
// || allTrackParts[samplei] != allTrackParts[samplei - 1]
// )
// {
// Info<< "track #" << allTracks[samplei]
// << " part #" << allTrackParts[samplei]
// << " from i=" << samplei << " to ";
// }
// if
// (
// samplei == allPositions.size() - 1
// || allTracks[samplei + 1] != allTracks[samplei]
// || allTrackParts[samplei + 1] != allTrackParts[samplei]
// )
// {
// Info<< "i=" << samplei << nl;
// }
// }
//};
label n = 0;
forAll(allTracks_, trackI)
//reportTrackParts();
// Reorder
if (Pstream::master())
{
n += allTracks_[trackI].size();
allPositions.rmap(allPositions, order);
allTracks.rmap(allTracks, order);
allTrackParts.rmap(allTrackParts, order);
allAges.rmap(allAges, order);
forAll(fieldNames, fieldi)
{
#define RMapAllTypes(Type, nullArg) \
if (Type##Interp.set(fieldi)) \
{ \
all##Type##s[fieldi].rmap(all##Type##s[fieldi], order); \
}
FOR_ALL_FIELD_TYPES(RMapAllTypes);
#undef RMapAllTypes
}
}
Info<< " Tracks:" << allTracks_.size() << nl
<< " Total samples:" << n
<< endl;
//reportTrackParts();
// Relabel tracks and track parts into track labels only, and join the
// forward and backward track parts that are connected to the seed
if (Pstream::master())
{
label samplei = 0, tracki = 0;
forAll(allPositions, samplej)
{
const label trackj = allTracks[samplej];
const label trackPartj = allTrackParts[samplej];
// Massage into form suitable for writers
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
allPositions[samplei] = allPositions[samplej];
allTracks[samplei] = tracki;
allTrackParts[samplei] = 0;
allAges[samplei] = allAges[samplej];
forAll(fieldNames, fieldi)
{
#define ShuffleUpAllTypes(Type, nullArg) \
if (Type##Interp.set(fieldi)) \
{ \
all##Type##s[fieldi][samplei] = \
all##Type##s[fieldi][samplej]; \
}
FOR_ALL_FIELD_TYPES(ShuffleUpAllTypes);
#undef ShuffleUpAllTypes
}
if (Pstream::master() && allTracks_.size())
const bool joinNewParts =
samplej != allPositions.size() - 1
&& trackPartj == -1
&& allTrackParts[samplej + 1] == 0;
if (!joinNewParts) samplei ++;
const bool newPart =
samplej == allPositions.size() - 1
|| trackj != allTracks[samplej + 1]
|| trackPartj != allTrackParts[samplej + 1];
if (!joinNewParts && newPart) tracki ++;
}
allPositions.resize(samplei);
allTracks.resize(samplei);
allTrackParts.resize(samplei);
allAges.resize(samplei);
forAll(fieldNames, fieldi)
{
#define ResizeAllTypes(Type, nullArg) \
if (Type##Interp.set(fieldi)) \
{ \
all##Type##s[fieldi].resize(samplei); \
}
FOR_ALL_FIELD_TYPES(ResizeAllTypes);
#undef ResizeAllTypes
}
}
//reportTrackParts();
// Write
if (Pstream::master() && allPositions.size())
{
// Make output directory
fileName vtkPath
fileName outputPath
(
runTime.globalPath()/writeFile::outputPrefix/"sets"/name()
mesh_.time().globalPath()/writeFile::outputPrefix/name()
);
if (mesh_.name() != fvMesh::defaultRegion)
{
vtkPath = vtkPath/mesh_.name();
outputPath = outputPath/mesh_.name();
}
vtkPath = vtkPath/mesh_.time().timeName();
mkDir(vtkPath);
outputPath = outputPath/mesh_.time().timeName();
mkDir(outputPath);
// Convert track positions
PtrList<coordSet> tracks(allTracks_.size());
forAll(allTracks_, trackI)
// Pass data to the formatter to write
const label nValueSets = fieldNames.size() + writeAge_;
wordList valueSetNames(nValueSets);
#define DeclareTypeValueSets(Type, nullArg) \
UPtrList<const Field<Type>> Type##ValueSets(nValueSets);
FOR_ALL_FIELD_TYPES(DeclareTypeValueSets);
#undef DeclareTypeValueSets
if (writeAge_)
{
tracks.set
(
trackI,
new coordSet
(
"track" + Foam::name(trackI),
sampledSetAxis_ //"xyz"
)
);
tracks[trackI].transfer(allTracks_[trackI]);
valueSetNames[0] = "age";
scalarValueSets.set(0, &allAges);
}
// Convert scalar values
if (allScalars_.size() > 0 || writeAge_)
forAll(fieldNames, fieldi)
{
List<List<scalarField>> ageAndScalarValues
(
allScalars_.size() + writeAge_
);
wordList ageAndScalarNames(allScalars_.size() + writeAge_);
valueSetNames[fieldi + writeAge_] = fieldNames[fieldi];
if (writeAge_)
{
DynamicList<scalarList>& allTrackAges = allAges_;
ageAndScalarValues[0].setSize(allTrackAges.size());
forAll(allTrackAges, trackI)
{
ageAndScalarValues[0][trackI].transfer
(
allTrackAges[trackI]
);
#define SetTypeValueSetPtr(Type, nullArg) \
if (Type##Interp.set(fieldi)) \
{ \
Type##ValueSets.set \
( \
fieldi + writeAge_, \
&all##Type##s[fieldi] \
); \
}
ageAndScalarNames[0] = "age";
}
forAll(allScalars_, scalari)
{
const label ageAndScalari = scalari + writeAge_;
DynamicList<scalarList>& allTrackVals = allScalars_[scalari];
ageAndScalarValues[ageAndScalari].setSize(allTrackVals.size());
forAll(allTrackVals, trackI)
{
ageAndScalarValues[ageAndScalari][trackI].transfer
(
allTrackVals[trackI]
);
}
ageAndScalarNames[ageAndScalari] = scalarNames_[scalari];
}
fileName vtkFile
(
vtkPath
/ scalarFormatterPtr_().getFileName
(
tracks[0],
ageAndScalarNames
)
);
Info<< " Writing data to " << vtkFile.path() << endl;
scalarFormatterPtr_().write
(
true, // writeTracks
tracks,
ageAndScalarNames,
ageAndScalarValues,
OFstream(vtkFile)()
);
}
// Convert vector values
if (allVectors_.size() > 0)
{
List<List<vectorField>> vectorValues(allVectors_.size());
forAll(allVectors_, vectori)
{
DynamicList<vectorList>& allTrackVals = allVectors_[vectori];
vectorValues[vectori].setSize(allTrackVals.size());
forAll(allTrackVals, trackI)
{
vectorValues[vectori][trackI].transfer
(
allTrackVals[trackI]
);
}
}
fileName vtkFile
(
vtkPath
/ vectorFormatterPtr_().getFileName
(
tracks[0],
vectorNames_
)
);
Info<< " Writing data to " << vtkFile.path() << endl;
vectorFormatterPtr_().write
(
true, // writeTracks
tracks,
vectorNames_,
vectorValues,
OFstream(vtkFile)()
);
FOR_ALL_FIELD_TYPES(SetTypeValueSetPtr);
#undef SetTypeValueSetPtr
}
formatterPtr_->write
(
outputPath,
"tracks",
coordSet(allTracks, word::null, allPositions),
valueSetNames
#define TypeValueSetsParameter(Type, nullArg) , Type##ValueSets
FOR_ALL_FIELD_TYPES(TypeValueSetsParameter)
#undef TypeValueSetsParameter
);
}
return true;

View File

@ -50,12 +50,11 @@ Description
lifeTime 10000;
trackLength 1e-3;
nSubCycle 5;
cloudName particleTracks;
seedSampleSet
{
type uniform;
axis x; // distance;
type lineUniform;
axis xyz;
start (-0.0205 0.0001 0.00001);
end (-0.0205 0.0005 0.00001);
nPoints 100;
@ -65,26 +64,27 @@ Description
Usage
\table
Property | Description | Required | Default value
type | Type name: streamlines | yes |
setFormat | Output data type | yes |
U | Tracking velocity field name | no | U
direction | Direction in which to track | yes |
outside | Track outside of periodic meshes | no | no
fields | Fields to sample | yes |
writeTime | Write the flow time along the streamlines | no | no
lifetime | Maximum number of particle tracking steps | yes |
trackLength | Tracking segment length | no |
nSubCycle | Number of tracking steps per cell | no |
cloudName | Cloud name to use | yes |
seedSampleSet| Seeding method (see below)| yes |
Property | Description | Required | Default value
type | Type name: streamlines | yes |
setFormat | Output data type | yes |
U | Tracking velocity field name | no | U
direction | Direction in which to track | yes |
outside | Track outside of periodic meshes | no | no
fields | Fields to sample | yes |
writeTime | Write the flow time along the streamlines | no | no
lifetime | Maximum number of particle tracking steps | yes |
trackLength | Tracking segment length | no |
nSubCycle | Number of tracking steps per cell | no |
cloudName | Cloud name to use | no |
seedSampleSet | Seeding method (see below) | yes |
\endtable
Where \c seedSampleSet \c type is typically one of
Where the \c seedSampleSet \c type is typically one of
\plaintable
uniform | uniform particle seeding
cloud | cloud of points
triSurfaceMeshPointSet | points according to a tri-surface mesh
lineUniform | uniform particle seeding along a line
sphereRandom | random particle seeding within a sphere
boundaryRandom | random particle seeding on a number of patches
points | a specified set of locations
\endplaintable
Note
@ -107,6 +107,7 @@ SourceFiles
#include "fvMeshFunctionObject.H"
#include "volFieldsFwd.H"
#include "DynamicList.H"
#include "DynamicField.H"
#include "scalarList.H"
#include "vectorList.H"
#include "setWriter.H"
@ -183,15 +184,6 @@ private:
//- Optional specified name of particles
word cloudName_;
//- Type of seed
word seedSet_;
//- Names of scalar fields
wordList scalarNames_;
//- Names of vector fields
wordList vectorNames_;
//- Write the streamlines ages
Switch writeAge_;
@ -204,36 +196,8 @@ private:
//- Seed set engine
autoPtr<sampledSet> sampledSetPtr_;
//- Axis of the sampled points to output
word sampledSetAxis_;
//- File writer for scalar data
autoPtr<setWriter<scalar>> scalarFormatterPtr_;
//- File writer for vector data
autoPtr<setWriter<vector>> vectorFormatterPtr_;
// Generated data
//- All tracks. Per particle the points it passed through
DynamicList<List<point>> allTracks_;
//- All ages. Per particle the age when it passed through the points
DynamicList<List<scalar>> allAges_;
//- Per scalarField, per particle, the sampled value.
List<DynamicList<scalarList>> allScalars_;
//- Per scalarField, per particle, the sampled value.
List<DynamicList<vectorList>> allVectors_;
//- Construct patch out of all wall patch faces
autoPtr<indirectPrimitivePatch> wallPatch() const;
//- Do all seeding and tracking
void track();
//- File writer
autoPtr<setWriter> formatterPtr_;
public:

View File

@ -45,35 +45,46 @@ Foam::vector Foam::streamlinesParticle::interpolateFields
<< "Cell:" << celli << abort(FatalError);
}
sampledScalars_.setSize(td.vsInterp_.size());
forAll(td.vsInterp_, scalarI)
{
const scalar s =
td.vsInterp_[scalarI].interpolate(position, celli, facei);
sampledScalars_[scalarI].append
(
td.trackOutside_ ? transform_.invTransform(s) : s
);
}
bool interpolatedU = false;
vector U = vector::uniform(NaN);
sampledVectors_.setSize(td.vvInterp_.size());
forAll(td.vvInterp_, vectorI)
forAll(td.scalarInterp_, fieldi)
{
const vector v =
td.vvInterp_[vectorI].interpolate(position, celli, facei);
#define InterpolateType(Type, nullArg) \
if (td.Type##Interp_.set(fieldi)) \
{ \
const Type s = \
td.Type##Interp_[fieldi].interpolate \
( \
position, \
celli, \
facei \
); \
\
sampled##Type##s_.setSize(td.Type##Interp_.size()); \
sampled##Type##s_[fieldi].append \
( \
td.trackOutside_ ? transform_.invTransform(s) : s \
); \
}
FOR_ALL_FIELD_TYPES(InterpolateType);
#undef InterpolateType
if (vectorI == td.UIndex_)
{
U = v;
}
sampledVectors_[vectorI].append
if
(
td.trackOutside_ ? transform_.invTransform(v) : v
);
td.vectorInterp_.set(fieldi)
&& &td.vectorInterp_[fieldi] == &td.UInterp_
)
{
interpolatedU = true;
U = sampledvectors_[fieldi].last();
}
}
// Interpolate the velocity if it has not already been done
if (!interpolatedU)
{
U = td.UInterp_.interpolate(position, celli, facei);
}
return U;
@ -82,30 +93,34 @@ Foam::vector Foam::streamlinesParticle::interpolateFields
void Foam::streamlinesParticle::endTrack(trackingData& td)
{
{
td.allPositions_.append(vectorList());
vectorList& top = td.allPositions_.last();
top.transfer(sampledPositions_);
}
const label n = sampledPositions_.size();
{
td.allTimes_.append(scalarList());
scalarList& top = td.allTimes_.last();
top.transfer(sampledTimes_);
}
const label trackPartIndex =
td.trackForward_ ? trackPartIndex_ : -1 - trackPartIndex_;
forAll(sampledScalars_, i)
{
td.allScalars_[i].append(scalarList());
scalarList& top = td.allScalars_[i].last();
top.transfer(sampledScalars_[i]);
}
if (!td.trackForward_) reverse(sampledPositions_);
td.allPositions_.append(sampledPositions_);
sampledPositions_.clear();
forAll(sampledVectors_, i)
td.allTracks_.append(List<label>(n, trackIndex_));
td.allTrackParts_.append(List<label>(n, trackPartIndex));
trackPartIndex_ ++;
if (!td.trackForward_) reverse(sampledAges_);
td.allAges_.append(sampledAges_);
sampledAges_.clear();
forAll(td.scalarInterp_, fieldi)
{
td.allVectors_[i].append(vectorList());
vectorList& top = td.allVectors_[i].last();
top.transfer(sampledVectors_[i]);
#define EndTrackType(Type, nullArg) \
if (td.Type##Interp_.set(fieldi)) \
{ \
if (!td.trackForward_) reverse(sampled##Type##s_[fieldi]); \
td.all##Type##s_[fieldi].append(sampled##Type##s_[fieldi]); \
sampled##Type##s_[fieldi].clear(); \
}
FOR_ALL_FIELD_TYPES(EndTrackType);
#undef EndTrackType
}
}
@ -117,13 +132,16 @@ Foam::streamlinesParticle::streamlinesParticle
const polyMesh& mesh,
const vector& position,
const label celli,
const label lifeTime
const label lifeTime,
const label trackIndex
)
:
particle(mesh, position, celli),
lifeTime_(lifeTime),
transform_(transformer::I),
age_(0)
trackIndex_(trackIndex),
trackPartIndex_(0),
age_(0),
transform_(transformer::I)
{}
@ -138,22 +156,19 @@ Foam::streamlinesParticle::streamlinesParticle
{
if (readFields)
{
List<scalarList> sampledScalars;
List<vectorList> sampledVectors;
is >> lifeTime_ >> trackIndex_ >> trackPartIndex_ >> age_
>> transform_ >> sampledPositions_ >> sampledAges_;
is >> lifeTime_ >> transform_ >> age_ >> sampledPositions_
>> sampledTimes_ >> sampledScalars >> sampledVectors;
sampledScalars_.setSize(sampledScalars.size());
forAll(sampledScalars, i)
{
sampledScalars_[i].transfer(sampledScalars[i]);
}
sampledVectors_.setSize(sampledVectors.size());
forAll(sampledVectors, i)
{
sampledVectors_[i].transfer(sampledVectors[i]);
}
#define ReadSampledTypes(Type, nullArg) \
List<List<Type>> sampled##Type##s; \
is >> sampled##Type##s; \
sampled##Type##s_.setSize(sampled##Type##s.size()); \
forAll(sampled##Type##s, i) \
{ \
sampled##Type##s_[i].transfer(sampled##Type##s[i]); \
}
FOR_ALL_FIELD_TYPES(ReadSampledTypes);
#undef ReadSampledTypes
}
// Check state of Istream
@ -172,12 +187,16 @@ Foam::streamlinesParticle::streamlinesParticle
:
particle(p),
lifeTime_(p.lifeTime_),
transform_(p.transform_),
trackIndex_(p.trackIndex_),
trackPartIndex_(p.trackPartIndex_),
age_(p.age_),
transform_(p.transform_),
sampledPositions_(p.sampledPositions_),
sampledTimes_(p.sampledTimes_),
sampledScalars_(p.sampledScalars_),
sampledVectors_(p.sampledVectors_)
sampledAges_(p.sampledAges_)
#define SampledTypesInit(Type, nullArg) \
, sampled##Type##s_(p.sampled##Type##s_)
FOR_ALL_FIELD_TYPES(SampledTypesInit)
#undef SampledTypesInit
{}
@ -213,7 +232,7 @@ bool Foam::streamlinesParticle::move
? transform_.invTransformPosition(position())
: position()
);
sampledTimes_.append(age_);
sampledAges_.append(age_);
vector U = interpolateFields(td, position(), cell(), face());
if (!td.trackForward_)
@ -284,7 +303,7 @@ bool Foam::streamlinesParticle::move
? transform_.invTransformPosition(position())
: position()
);
sampledTimes_.append(age_);
sampledAges_.append(age_);
interpolateFields(td, position(), cell(), face());
if (debug)
@ -464,11 +483,33 @@ void Foam::streamlinesParticle::readFields(Cloud<streamlinesParticle>& c)
);
c.checkFieldIOobject(c, lifeTime);
IOField<label> trackIndex
(
c.fieldIOobject("trackIndex", IOobject::MUST_READ),
valid
);
c.checkFieldIOobject(c, trackIndex);
IOField<label> trackPartIndex
(
c.fieldIOobject("trackPartIndex", IOobject::MUST_READ),
valid
);
c.checkFieldIOobject(c, trackPartIndex);
IOField<scalar> age
(
c.fieldIOobject("age", IOobject::MUST_READ),
valid
);
c.checkFieldIOobject(c, age);
transformerIOList transform
(
c.fieldIOobject("transform", IOobject::MUST_READ),
valid
);
//c.checkFieldIOobject(c, transform);
vectorFieldIOField sampledPositions
(
@ -477,20 +518,23 @@ void Foam::streamlinesParticle::readFields(Cloud<streamlinesParticle>& c)
);
c.checkFieldIOobject(c, sampledPositions);
scalarFieldIOField sampledTimes
scalarFieldIOField sampledAges
(
c.fieldIOobject("sampledTimes", IOobject::MUST_READ),
c.fieldIOobject("sampledAges", IOobject::MUST_READ),
valid
);
c.checkFieldIOobject(c, sampledTimes);
c.checkFieldIOobject(c, sampledAges);
label i = 0;
forAllIter(Cloud<streamlinesParticle>, c, iter)
{
iter().lifeTime_ = lifeTime[i];
iter().trackIndex_ = trackIndex[i];
iter().trackPartIndex_ = trackPartIndex[i];
iter().age_ = age[i];
iter().transform_ = transform[i];
iter().sampledPositions_.transfer(sampledPositions[i]);
iter().sampledTimes_.transfer(sampledTimes[i]);
iter().sampledAges_.transfer(sampledAges[i]);
i++;
}
}
@ -508,6 +552,24 @@ void Foam::streamlinesParticle::writeFields(const Cloud<streamlinesParticle>& c)
np
);
IOList<label> trackIndex
(
c.fieldIOobject("trackIndex", IOobject::NO_READ),
np
);
IOList<label> trackPartIndex
(
c.fieldIOobject("trackPartIndex", IOobject::NO_READ),
np
);
IOField<scalar> age
(
c.fieldIOobject("age", IOobject::NO_READ),
np
);
transformerIOList transform
(
c.fieldIOobject("transform", IOobject::NO_READ),
@ -520,9 +582,9 @@ void Foam::streamlinesParticle::writeFields(const Cloud<streamlinesParticle>& c)
np
);
scalarFieldIOField sampledTimes
scalarFieldIOField sampledAges
(
c.fieldIOobject("sampledTimes", IOobject::NO_READ),
c.fieldIOobject("sampledAges", IOobject::NO_READ),
np
);
@ -530,15 +592,22 @@ void Foam::streamlinesParticle::writeFields(const Cloud<streamlinesParticle>& c)
forAllConstIter(Cloud<streamlinesParticle>, c, iter)
{
lifeTime[i] = iter().lifeTime_;
trackIndex[i] = iter().trackIndex_;
trackPartIndex[i] = iter().trackPartIndex_;
age[i] = iter().age_;
transform[i] = iter().transform_;
sampledPositions[i] = iter().sampledPositions_;
sampledTimes[i] = iter().sampledTimes_;
sampledAges[i] = iter().sampledAges_;
i++;
}
lifeTime.write(np > 0);
trackIndex.write(np > 0);
trackPartIndex.write(np > 0);
age.write(np > 0);
transform.write(np > 0);
sampledPositions.write(np > 0);
sampledTimes.write(np > 0);
sampledAges.write(np > 0);
}
@ -546,14 +615,19 @@ void Foam::streamlinesParticle::writeFields(const Cloud<streamlinesParticle>& c)
Foam::Ostream& Foam::operator<<(Ostream& os, const streamlinesParticle& p)
{
os << static_cast<const particle&>(p)
<< token::SPACE << p.lifeTime_
<< token::SPACE << p.transform_
<< token::SPACE << p.trackIndex_
<< token::SPACE << p.trackPartIndex_
<< token::SPACE << p.age_
<< token::SPACE << p.transform_
<< token::SPACE << p.sampledPositions_
<< token::SPACE << p.sampledTimes_
<< token::SPACE << p.sampledScalars_
<< token::SPACE << p.sampledVectors_;
<< token::SPACE << p.sampledAges_
#define WriteSampledTypes(Type, nullArg) \
<< token::SPACE << p.sampled##Type##s_
FOR_ALL_FIELD_TYPES(WriteSampledTypes);
#undef WriteSampledTypes
// Check state of Ostream
os.check("Ostream& operator<<(Ostream&, const streamlinesParticle&)");

View File

@ -41,6 +41,7 @@ SourceFiles
#include "autoPtr.H"
#include "interpolation.H"
#include "vectorList.H"
#include "DynamicField.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -72,11 +73,12 @@ public:
// Public data
const PtrList<interpolation<scalar>>& vsInterp_;
#define DeclareTypeInterpolator(Type, nullArg) \
const PtrList<interpolation<Type>>& Type##Interp_;
FOR_ALL_FIELD_TYPES(DeclareTypeInterpolator);
#undef DeclareTypeInterpolator
const PtrList<interpolation<vector>>& vvInterp_;
const label UIndex_;
const interpolation<vector>& UInterp_;
bool trackForward_;
@ -86,13 +88,20 @@ public:
const scalar trackLength_;
DynamicList<vectorList>& allPositions_;
label tracki;
DynamicList<scalarList>& allTimes_;
DynamicField<point>& allPositions_;
List<DynamicList<scalarList>>& allScalars_;
DynamicField<label>& allTracks_;
List<DynamicList<vectorList>>& allVectors_;
DynamicField<label>& allTrackParts_;
DynamicField<scalar>& allAges_;
#define DeclareAllTypes(Type, nullArg) \
List<DynamicField<Type>>& all##Type##s_;
FOR_ALL_FIELD_TYPES(DeclareAllTypes);
#undef DeclareAllTypes
// Constructors
@ -101,31 +110,43 @@ public:
trackingData
(
streamlinesCloud& cloud,
const PtrList<interpolation<scalar>>& vsInterp,
const PtrList<interpolation<vector>>& vvInterp,
const label UIndex,
#define TypeInterpolatorArg(Type, nullArg) \
const PtrList<interpolation<Type>>& Type##Interp,
FOR_ALL_FIELD_TYPES(TypeInterpolatorArg)
#undef TypeInterpolatorArg
const interpolation<vector>& UInterp,
const bool trackForward,
const bool trackOutside,
const label nSubCycle,
const scalar trackLength,
DynamicList<List<point>>& allPositions,
DynamicList<List<scalar>>& allTimes,
List<DynamicList<scalarList>>& allScalars,
List<DynamicList<vectorList>>& allVectors
DynamicField<point>& allPositions,
DynamicField<label>& allTracks,
DynamicField<label>& allTrackParts,
DynamicField<scalar>& allAges
#define AllTypesArg(Type, nullArg) \
, List<DynamicField<Type>>& all##Type##s
FOR_ALL_FIELD_TYPES(AllTypesArg)
#undef AllTypesArg
)
:
particle::trackingData(cloud),
vsInterp_(vsInterp),
vvInterp_(vvInterp),
UIndex_(UIndex),
#define TypeInterpolatorInit(Type, nullArg) \
Type##Interp_(Type##Interp),
FOR_ALL_FIELD_TYPES(TypeInterpolatorInit)
#undef TypeInterpolatorInit
UInterp_(UInterp),
trackForward_(trackForward),
trackOutside_(trackOutside),
nSubCycle_(nSubCycle),
trackLength_(trackLength),
allPositions_(allPositions),
allTimes_(allTimes),
allScalars_(allScalars),
allVectors_(allVectors)
allTracks_(allTracks),
allTrackParts_(allTrackParts),
allAges_(allAges)
#define AllTypesInit(Type, nullArg) \
, all##Type##s_(all##Type##s)
FOR_ALL_FIELD_TYPES(AllTypesInit)
#undef AllTypesInit
{}
};
@ -137,23 +158,29 @@ private:
//- Lifetime of particle. Particle dies when reaches 0.
label lifeTime_;
//- Current compound transform
transformer transform_;
//- Index of the track
label trackIndex_;
//- Index of the part of the track
label trackPartIndex_;
//- Age of the particle
scalar age_;
//- Current compound transform
transformer transform_;
//- Sampled positions
DynamicList<point> sampledPositions_;
DynamicField<point> sampledPositions_;
//- Sampled times
DynamicList<scalar> sampledTimes_;
//- Sampled ages
DynamicField<scalar> sampledAges_;
//- Sampled scalars
List<DynamicList<scalar>> sampledScalars_;
//- Sampled vectors
List<DynamicList<vector>> sampledVectors_;
//- Sampled types
#define DeclareSampledTypes(Type, nullArg) \
List<DynamicField<Type>> sampled##Type##s_;
FOR_ALL_FIELD_TYPES(DeclareSampledTypes);
#undef DeclareSampledTypes
// Private Member Functions
@ -181,7 +208,8 @@ public:
const polyMesh& c,
const vector& position,
const label celli,
const label lifeTime
const label lifeTime,
const label trackIndex
);
//- Construct from Istream

View File

@ -814,7 +814,7 @@ Foam::scalar Foam::particle::trackToStationaryTri
// Accumulate fraction behind
if (muH*detA < small || nTracksBehind_ > 0)
{
stepFractionBehind_ += fraction*muH*detA;
stepFractionBehind_ += (fraction != 0 ? fraction : 1)*muH*detA;
if (stepFractionBehind_ > rootSmall)
{
@ -1011,7 +1011,7 @@ Foam::scalar Foam::particle::trackToMovingTri
// Accumulate fraction behind
if (muH*detA[0] < small || nTracksBehind_ > 0)
{
stepFractionBehind_ += fraction*muH*detA[0];
stepFractionBehind_ += (fraction != 0 ? fraction : 1)*muH*detA[0];
if (stepFractionBehind_ > rootSmall)
{

View File

@ -453,7 +453,7 @@ void Foam::ParticleCollector<CloudType>::write()
{
autoPtr<surfaceWriter> writer
(
surfaceWriter::New(surfaceFormat_, time.writeFormat())
surfaceWriter::New(surfaceFormat_, this->coeffDict())
);
writer->write

View File

@ -22,4 +22,13 @@ $(turbulence)/turbGen.C
$(noise)/noiseFFT.C
graph/curve/curve.C
graph/graph.C
writers = graph/writers
$(writers)/rawGraph/rawGraph.C
$(writers)/gnuplotGraph/gnuplotGraph.C
$(writers)/xmgrGraph/xmgrGraph.C
$(writers)/jplotGraph/jplotGraph.C
LIB = $(FOAM_LIBBIN)/librandomProcesses

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2011-2018 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2011-2021 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2011-2020 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2011-2021 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2011-2018 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2011-2021 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2011-2020 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2011-2021 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2011-2020 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2011-2021 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2011-2020 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2011-2021 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2011-2018 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2011-2021 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2011-2020 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2011-2021 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2011-2018 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2011-2021 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2011-2020 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2011-2021 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2011-2018 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2011-2021 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2011-2020 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2011-2021 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License

View File

@ -5,8 +5,10 @@ probes/probesGrouping.C
coordSet/coordSet.C
sampledSet/sampledSet/sampledSet.C
sampledSet/sampledSet/sampledSetParticle.C
sampledSet/sampledSet/sampledSetCloud.C
sampledSet/sampledSets/sampledSets.C
sampledSet/sampledSets/sampledSetsGrouping.C
sampledSet/arcUniform/arcUniform.C
sampledSet/boxUniform/boxUniform.C
sampledSet/circleRandom/circleRandom.C
@ -24,14 +26,12 @@ sampledSet/faceSetSampledSet/faceSetSampledSet.C
setWriters = sampledSet/writers
$(setWriters)/setWriters.C
$(setWriters)/ensight/ensightSetWriterRunTime.C
$(setWriters)/gnuplot/gnuplotSetWriterRunTime.C
$(setWriters)/jplot/jplotSetWriterRunTime.C
$(setWriters)/raw/rawSetWriterRunTime.C
$(setWriters)/vtk/vtkSetWriterRunTime.C
$(setWriters)/xmgrace/xmgraceSetWriterRunTime.C
$(setWriters)/csv/csvSetWriterRunTime.C
$(setWriters)/setWriter.C
$(setWriters)/ensight/ensightSetWriter.C
$(setWriters)/raw/rawSetWriter.C
$(setWriters)/vtk/vtkSetWriter.C
$(setWriters)/csv/csvSetWriter.C
$(setWriters)/gnuplot/gnuplotSetWriter.C
cuttingPlane/cuttingPlane.C
@ -59,10 +59,6 @@ $(surfWriters)/proxy/proxySurfaceWriter.C
$(surfWriters)/raw/rawSurfaceWriter.C
$(surfWriters)/vtk/vtkSurfaceWriter.C
graphField/writePatchGraph.C
graphField/writeCellGraph.C
graphField/makeGraph.C
meshToMesh/meshToMesh.C
meshToMesh/meshToMeshParallelOps.C
meshToMesh/distributedWeightedFvPatchFieldMapper.C

View File

@ -24,126 +24,494 @@ License
\*---------------------------------------------------------------------------*/
#include "coordSet.H"
#include "ListListOps.H"
// * * * * * * * * * * * * * Static Member Data * * * * * * * * * * * * * * //
namespace Foam
{
template<>
const char* Foam::NamedEnum
<
Foam::coordSet::coordFormat,
5
>::names[] =
const char* Foam::NamedEnum<Foam::coordSet::axisType, 6>::names[] =
{
"xyz",
"x",
"y",
"z",
"distance"
"distance",
"default"
};
}
const Foam::NamedEnum<Foam::coordSet::coordFormat, 5>
Foam::coordSet::coordFormatNames_;
const Foam::NamedEnum<Foam::coordSet::axisType, 6>
Foam::coordSet::axisTypeNames_;
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::coordSet::coordSet
(
const word& name,
const word& axis
)
Foam::coordSet::coordSet()
:
pointField(0),
name_(name),
axis_(coordFormatNames_[axis]),
curveDist_(0)
segments_(0),
positionName_(word::null),
positions_(nullptr),
distanceName_(word::null),
distances_(nullptr),
axis_(axisType::DEFAULT)
{}
Foam::coordSet::coordSet
(
const word& name,
const word& axis,
const List<point>& points,
const scalarList& curveDist
const labelList& segments,
const word& positionName,
const pointField& positions,
const word& distanceName,
const scalarField& distances,
const word& axis
)
:
pointField(points),
name_(name),
axis_(coordFormatNames_[axis]),
curveDist_(curveDist)
segments_(segments),
positionName_(positionName),
positions_
(
isNull<pointField>(positions)
? nullptr
: new pointField(positions)
),
distanceName_(distanceName),
distances_
(
isNull<scalarField>(distances)
? nullptr
: new scalarField(distances)
),
axis_(axisTypeNames_[axis])
{}
Foam::coordSet::coordSet
(
const bool contiguous,
const word& positionName,
const pointField& positions,
const word& axis
)
:
coordSet
(
contiguous
? labelList(positions.size(), 0)
: identity(positions.size()),
positionName,
positions,
word::null,
scalarField::null(),
axis
)
{}
Foam::coordSet::coordSet
(
const bool contiguous,
const word& distanceName,
const scalarField& distances,
const word& axis
)
:
coordSet
(
contiguous
? labelList(distances.size(), 0)
: identity(distances.size()),
word::null,
pointField::null(),
distanceName,
distances,
axis
)
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
bool Foam::coordSet::hasVectorAxis() const
bool Foam::coordSet::hasScalarAxis() const
{
return axis_ == XYZ;
// If axis is default and both positions and distances are valid, take
// scalar distances in preference
return
(axis_ == axisType::X && positions_.valid())
|| (axis_ == axisType::Y && positions_.valid())
|| (axis_ == axisType::Z && positions_.valid())
|| (axis_ == axisType::DISTANCE && distances_.valid())
|| (axis_ == axisType::DEFAULT && distances_.valid());
}
Foam::scalar Foam::coordSet::scalarCoord
(
const label index
) const
bool Foam::coordSet::hasPointAxis() const
{
const point& p = operator[](index);
// If axis is default and both positions and distances are valid, take
// scalar distances in preference
if (axis_ == X)
return
(axis_ == axisType::XYZ && positions_.valid())
|| (axis_ == axisType::DEFAULT && positions_.valid());
}
Foam::scalar Foam::coordSet::scalarCoord(const label index) const
{
switch (axis_)
{
return p.x();
case axisType::XYZ:
FatalErrorInFunction
<< "Scalar coordinate requested from coordinate set with "
<< axisTypeNames_[axis_] << " axis" << exit(FatalError);
break;
case axisType::X:
return positions_()[index].x();
case axisType::Y:
return positions_()[index].y();
case axisType::Z:
return positions_()[index].z();
case axisType::DISTANCE:
return distances_()[index];
case axisType::DEFAULT:
if (distances_.valid()) return distances_()[index];
FatalErrorInFunction
<< "Scalar coordinate requested from coordinate set with "
<< axisTypeNames_[axis_] << " axis, but with no valid distances"
<< exit(FatalError);
break;
}
else if (axis_ == Y)
return NaN;
}
Foam::tmp<Foam::scalarField> Foam::coordSet::scalarCoords() const
{
switch (axis_)
{
return p.y();
case axisType::XYZ:
FatalErrorInFunction
<< "Scalar coordinate requested from coordinate set with "
<< axisTypeNames_[axis_] << " axis" << exit(FatalError);
break;
case axisType::X:
return positions_().component(point::X);
case axisType::Y:
return positions_().component(point::Y);
case axisType::Z:
return positions_().component(point::Z);
case axisType::DISTANCE:
return distances_();
case axisType::DEFAULT:
if (distances_.valid()) return distances_();
FatalErrorInFunction
<< "Scalar coordinate requested from coordinate set with "
<< axisTypeNames_[axis_] << " axis, but with no valid distances"
<< exit(FatalError);
break;
}
else if (axis_ == Z)
return scalarField::null();
}
Foam::word Foam::coordSet::scalarName() const
{
switch (axis_)
{
return p.z();
case axisType::XYZ:
FatalErrorInFunction
<< "Scalar name requested from coordinate set with "
<< axisTypeNames_[axis_] << " axis" << exit(FatalError);
break;
case axisType::X:
case axisType::Y:
case axisType::Z:
return
positionName_
+ (positionName_ != word::null ? "_" : "")
+ axis();
case axisType::DISTANCE:
return distanceName_;
case axisType::DEFAULT:
if (distances_.valid()) return distanceName_;
FatalErrorInFunction
<< "Scalar coordinate requested from coordinate set with "
<< axisTypeNames_[axis_] << " axis, but with no valid distances"
<< exit(FatalError);
break;
}
else if (axis_ == DISTANCE)
return word::null;
}
Foam::point Foam::coordSet::pointCoord(const label index) const
{
switch (axis_)
{
// Use distance to reference point
return curveDist_[index];
case axisType::XYZ:
return positions_()[index];
case axisType::X:
case axisType::Y:
case axisType::Z:
case axisType::DISTANCE:
FatalErrorInFunction
<< "Point coordinate requested from coordinate set with "
<< axisTypeNames_[axis_] << " axis" << exit(FatalError);
break;
case axisType::DEFAULT:
if (positions_.valid()) return positions_()[index];
FatalErrorInFunction
<< "Point coordinate requested from coordinate set with "
<< axisTypeNames_[axis_] << " axis, but with no valid point"
<< exit(FatalError);
break;
}
return point::uniform(NaN);
}
Foam::tmp<Foam::pointField> Foam::coordSet::pointCoords() const
{
switch (axis_)
{
case axisType::XYZ:
return positions_();
case axisType::X:
case axisType::Y:
case axisType::Z:
case axisType::DISTANCE:
FatalErrorInFunction
<< "Point coordinate requested from coordinate set with "
<< axisTypeNames_[axis_] << " axis" << exit(FatalError);
break;
case axisType::DEFAULT:
if (positions_.valid()) return positions_();
FatalErrorInFunction
<< "Point coordinate requested from coordinate set with "
<< axisTypeNames_[axis_] << " axis, but with no valid point"
<< exit(FatalError);
break;
}
return pointField::null();
}
Foam::word Foam::coordSet::pointName() const
{
switch (axis_)
{
case axisType::XYZ:
return positionName_;
case axisType::X:
case axisType::Y:
case axisType::Z:
case axisType::DISTANCE:
FatalErrorInFunction
<< "Point name requested from coordinate set with "
<< axisTypeNames_[axis_] << " axis" << exit(FatalError);
break;
case axisType::DEFAULT:
if (positions_.valid()) return positionName_;
FatalErrorInFunction
<< "Point name requested from coordinate set with "
<< axisTypeNames_[axis_] << " axis, but with no valid point"
<< exit(FatalError);
break;
}
return word::null;
}
Foam::labelList Foam::coordSet::vertices() const
{
label nVertices = 0;
labelList vertices(size());
forAll(*this, pointi)
{
const label s = segments_[pointi];
if
(
(pointi == 0 || s != segments_[pointi - 1])
&& (pointi == size() - 1 || s != segments_[pointi + 1])
)
{
vertices[nVertices ++] = pointi;
}
}
vertices.resize(nVertices);
return vertices;
}
Foam::labelPairList Foam::coordSet::edges() const
{
label nEdges = 0;
labelPairList edges(size() - 1);
for (label pointi = 0; pointi < size() - 1; ++ pointi)
{
if (segments_[pointi] == segments_[pointi + 1])
{
edges[nEdges ++] = labelPair(pointi, pointi + 1);
}
}
edges.resize(nEdges);
return edges;
}
Foam::labelListList Foam::coordSet::lines() const
{
DynamicList<label> line;
DynamicList<labelList> lines;
forAll(*this, pointi)
{
line.append(pointi);
if
(
pointi == size() - 1
|| segments_[pointi] != segments_[pointi + 1]
)
{
if (line.size() > 1)
{
lines.append(line);
}
line.clear();
}
}
labelListList linesNonDynamic;
linesNonDynamic.transfer(lines);
return linesNonDynamic;
}
Foam::Tuple2<Foam::coordSet, Foam::labelList> Foam::coordSet::gather() const
{
// Collect data from all processors
List<List<point>> gatheredPositions;
if (positions_.valid())
{
gatheredPositions.resize(Pstream::nProcs());
gatheredPositions[Pstream::myProcNo()] = positions_();
Pstream::gatherList(gatheredPositions);
}
List<scalarList> gatheredDistances;
if (distances_.valid())
{
gatheredDistances.resize(Pstream::nProcs());
gatheredDistances[Pstream::myProcNo()] = distances_();
Pstream::gatherList(gatheredDistances);
}
List<labelField> gatheredSegments(Pstream::nProcs());
gatheredSegments[Pstream::myProcNo()] = segments_;
Pstream::gatherList(gatheredSegments);
// Combine processor lists into one big list.
List<point> allPositions;
if (positions_.valid())
{
allPositions =
ListListOps::combine<List<point>>
(
gatheredPositions,
accessOp<List<point>>()
);
};
scalarList allDistances;
if (distances_.valid())
{
allDistances =
ListListOps::combine<scalarList>
(
gatheredDistances,
accessOp<scalarList>()
);
}
labelList allSegments
(
ListListOps::combine<labelList>
(
gatheredSegments,
accessOp<labelList>()
)
);
// Construct a result tuple
Tuple2<coordSet, labelList> result
(
coordSet(),
identity(allSegments.size())
);
coordSet& set = result.first();
labelList& order = result.second();
// Sort by segment then by distance
if (distances_.valid())
{
stableSort
(
order,
[&](const label a, const label b)
{
return
allSegments[a] < allSegments[b] ? true
: allSegments[a] > allSegments[b] ? false
: allDistances[a] < allDistances[b];
}
);
}
else
{
FatalErrorInFunction
<< "Illegal axis specification " << axis_
<< " for sampling line " << name_
<< exit(FatalError);
return 0;
stableSort
(
order,
[&](const label a, const label b)
{
return allSegments[a] < allSegments[b];
}
);
}
}
Foam::point Foam::coordSet::vectorCoord(const label index) const
{
const point& p = operator[](index);
return p;
}
Foam::Ostream& Foam::coordSet::write(Ostream& os) const
{
os << "name:" << name_ << " axis:" << axis_
<< endl
<< endl << "\t(coord)"
<< endl;
forAll(*this, sampleI)
// Set the data in the coordinate set
set.segments_ = labelField(allSegments, order);
set.positionName_ = positionName_;
if (positions_.valid())
{
os << '\t' << operator[](sampleI) << endl;
set.positions_.set(new pointField(allPositions, order));
}
set.distanceName_ = distanceName_;
if (distances_.valid())
{
set.distances_.set(new scalarField(allDistances, order));
}
set.axis_ = axis_;
return os;
return result;
}

View File

@ -37,6 +37,7 @@ SourceFiles
#include "pointField.H"
#include "word.H"
#include "labelPair.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -48,94 +49,156 @@ namespace Foam
\*---------------------------------------------------------------------------*/
class coordSet
:
public pointField
{
public:
// Public data types
//- Enumeration defining the output format for coordinates
enum coordFormat
enum class axisType
{
XYZ,
X,
Y,
Z,
DISTANCE
DISTANCE,
DEFAULT
};
private:
//- String representation of coordFormat enums
static const NamedEnum<coordFormat, 5> coordFormatNames_;
//- String representation of axis enums
static const NamedEnum<axisType, 6> axisTypeNames_;
protected:
//- Name
const word name_;
// Protected Data
//- Axis write type
const coordFormat axis_;
//- Connected segments
labelList segments_;
//- Cumulative distance "distance" write specifier.
scalarList curveDist_;
//- Name of the positions
word positionName_;
//- Point positions
autoPtr<pointField> positions_;
//- Name of the distances
word distanceName_;
//- Scalar distances
autoPtr<scalarField> distances_;
//- Axis
axisType axis_;
public:
// Constructors
//- Construct null
coordSet();
//- Construct from components
coordSet
(
const word& name,
const word& axis
const labelList& segments,
const word& positionName = word::null,
const pointField& positions = pointField::null(),
const word& distanceName = word::null,
const scalarField& distances = scalarField::null(),
const word& axis = axisTypeNames_[axisType::DEFAULT]
);
//- Construct from components
//- Construct from positions
coordSet
(
const word& name,
const word& axis,
const List<point>& points,
const scalarList& curveDist
const bool contiguous,
const word& positionName,
const pointField& positions,
const word& axis = axisTypeNames_[axisType::DEFAULT]
);
//- Construct from distances
coordSet
(
const bool contiguous,
const word& distanceName,
const scalarField& distances,
const word& axis = axisTypeNames_[axisType::DEFAULT]
);
// Member Functions
const word& name() const
//- Return the size
inline label size() const
{
return name_;
return segments_.size();
}
word axis() const
//- Return the segments
inline const labelList& segments() const
{
return coordFormatNames_[axis_];
return segments_;
}
//- Cumulative distance
const scalarList& curveDist() const
//- Return the axis name
inline word axis() const
{
return curveDist_;
return axisTypeNames_[axis_];
}
//- Is axis specification a vector
bool hasVectorAxis() const;
//- Is the coordinate axis a scalar?
bool hasScalarAxis() const;
//- Get coordinate of point according to axis specification.
// If axis="distance" is the curveDist[index]
//- Is the coordinate axis a point?
bool hasPointAxis() const;
//- Get scalar coordinate (axis is x, y, z or distance)
scalar scalarCoord(const label index) const;
//- Get point according to axis="xyz" specification
vector vectorCoord(const label index) const;
//- Get scalar coordinates (axis is x, y, z or distance)
tmp<scalarField> scalarCoords() const;
Ostream& write(Ostream& os) const;
//- Return the name of the scalar coordinates
word scalarName() const;
//- Get vector coordinate (axis is xyz)
point pointCoord(const label index) const;
//- Get vector coordinate (axis is xyz)
tmp<pointField> pointCoords() const;
//- Return the name of the point coordinates
word pointName() const;
//- Return a list of isolated vertices. These are the points that are
// not adjacent to any points in the same segment.
labelList vertices() const;
//- Return a list of edges. These are adjacent pairs of points which
// are in the same segment.
labelPairList edges() const;
//- Return a list of lines. These are lists of points which are in the
// same segment.
labelListList lines() const;
//- Combine coordinate sets onto the master. Return both the combined
// coordinate set, and an ordering to be used for gathering associated
// fields
Tuple2<coordSet, labelList> gather() const;
//- Combine a field using the ordering obtained from the coordinate set
// gather operation
template<class Type>
static tmp<Field<Type>> gather
(
const Field<Type>& values,
const labelList& order
);
};
@ -145,6 +208,12 @@ public:
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository
#include "coordSetTemplates.C"
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2019 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2021 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
@ -23,38 +23,36 @@ License
\*---------------------------------------------------------------------------*/
#include "writePatchGraph.H"
#include "volFields.H"
#include "fvMesh.H"
#include "graph.H"
#include "coordSet.H"
#include "ListListOps.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
void writePatchGraph
template<class Type>
Foam::tmp<Foam::Field<Type>> Foam::coordSet::gather
(
const volScalarField& vsf,
const label patchLabel,
const direction d,
const word& graphFormat
const Field<Type>& values,
const labelList& order
)
{
graph
// Collect data from all processors
List<List<Type>> gatheredValues(Pstream::nProcs());
gatheredValues[Pstream::myProcNo()] = values;
Pstream::gatherList(gatheredValues);
// Combine processor lists into one big list
List<Type> allValues
(
vsf.name(),
"position",
vsf.name(),
vsf.mesh().boundary()[patchLabel].Cf().component(d),
vsf.boundaryField()[patchLabel]
).write(vsf.time().timePath()/vsf.name(), graphFormat);
ListListOps::combine<List<Type>>
(
gatheredValues,
accessOp<List<Type>>()
)
);
// Sort by order and overwrite
return tmp<Field<Type>>(new Field<Type>(allValues, order));
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// ************************************************************************* //

View File

@ -1,111 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2011-2020 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/>.
Global
makeGraph
Description
Write a graph file for a field given the data point locations field,
the field of interest and the name of the field to be used for the
graph file name.
\*---------------------------------------------------------------------------*/
#include "makeGraph.H"
#include "volFields.H"
#include "graph.H"
#include "writeFile.H"
#include "OSspecific.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
void makeGraph
(
const scalarField& x,
const volScalarField& vsf,
const word& graphFormat
)
{
makeGraph(x, vsf, vsf.name(), graphFormat);
}
void makeGraph
(
const scalarField& x,
const volScalarField& vsf,
const word& name,
const word& graphFormat
)
{
fileName path
(
vsf.rootPath()
/vsf.caseName()
/functionObjects::writeFile::outputPrefix
/"graphs"
/vsf.instance()
);
mkDir(path);
makeGraph
(
x,
vsf.primitiveField(),
name,
path,
graphFormat
);
}
void makeGraph
(
const scalarField& x,
const scalarField& sf,
const word& name,
const fileName& path,
const word& graphFormat
)
{
graph
(
name,
"x",
name,
x,
sf
).write(path/name, graphFormat);
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// ************************************************************************* //

View File

@ -1,84 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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/>.
Global
makeGraph
Description
SourceFiles
makeGraph.C
\*---------------------------------------------------------------------------*/
#ifndef makeGraph_H
#define makeGraph_H
#include "primitiveFieldsFwd.H"
#include "volFieldsFwd.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
class fileName;
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
void makeGraph
(
const scalarField& x,
const volScalarField& vsf,
const word& graphFormat
);
void makeGraph
(
const scalarField& x,
const volScalarField& vsf,
const word& name,
const word& graphFormat
);
void makeGraph
(
const scalarField& x,
const scalarField& sf,
const word& name,
const fileName& path,
const word& graphFormat
);
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -1,68 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2019-2020 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/>.
\*---------------------------------------------------------------------------*/
#include "writeCellGraph.H"
#include "volFields.H"
#include "graph.H"
#include "writeFile.H"
#include "OSspecific.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
void writeCellGraph
(
const volScalarField& vsf,
const word& graphFormat
)
{
fileName path
(
vsf.time().path()
/functionObjects::writeFile::outputPrefix
/"graphs"
/vsf.time().timeName()
);
mkDir(path);
graph
(
vsf.name(),
"x",
vsf.name(),
vsf.mesh().C().primitiveField().component(vector::X),
vsf.primitiveField()
).write(path/vsf.name(), graphFormat);
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// ************************************************************************* //

View File

@ -1,60 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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/>.
InNamespace
Foam::writeCellGraph
Description
SourceFiles
writeCellGraph.C
\*---------------------------------------------------------------------------*/
#ifndef writeCellGraph_H
#define writeCellGraph_H
#include "volFieldsFwd.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
void writeCellGraph
(
const volScalarField& vsf,
const word& graphFormat
);
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -1,61 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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/>.
InClass
Foam::writePatchGraph
Description
SourceFiles
writePatchGraph.C
\*---------------------------------------------------------------------------*/
#ifndef writePatchGraph_H
#define writePatchGraph_H
#include "volFieldsFwd.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
void writePatchGraph
(
const volScalarField& vsf,
const label patchLabel,
const direction d,
const word& graphFormat
);
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2011-2019 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2011-2021 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
@ -30,6 +30,7 @@ License
#include "polyMesh.H"
#include "addToRunTimeSelectionTable.H"
#include "word.H"
#include "points.H"
#include "unitConversion.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
@ -48,69 +49,77 @@ namespace sampledSets
void Foam::sampledSets::arcUniform::calcSamples
(
DynamicList<point>& samplingPts,
DynamicList<label>& samplingCells,
DynamicList<label>& samplingFaces,
DynamicList<point>& samplingPositions,
DynamicList<scalar>& samplingDistances,
DynamicList<label>& samplingSegments,
DynamicList<scalar>& samplingCurveDist
DynamicList<label>& samplingCells,
DynamicList<label>& samplingFaces
) const
{
// Get the coordinate system
const vector axis1 = radial_ - (radial_ & normal_)*normal_;
const vector axis2 = normal_ ^ axis1;
const scalar radius = mag(axis1);
for (label i = 0; i < nPoints_; ++ i)
// Compute all point locations
const scalarField ts(scalarList(identity(nPoints_))/(nPoints_ - 1));
const scalarField theta((1 - ts)*startAngle_ + ts*endAngle_);
const scalarField c(cos(theta)), s(sin(theta));
const pointField points(centre_ + c*axis1 + s*axis2);
// Calculate the sampling topology
points::calcSamples
(
mesh(),
searchEngine(),
points,
samplingPositions,
samplingDistances,
samplingSegments,
samplingCells,
samplingFaces
);
// Overwrite the distances
forAll(samplingPositions, i)
{
const scalar t = scalar(i)/(nPoints_ - 1);
const scalar theta = (1 - t)*startAngle_ + t*endAngle_;
const scalar c = cos(theta), s = sin(theta);
const point pt = centre_ + c*axis1 + s*axis2;
const label celli = searchEngine().findCell(pt);
if (celli != -1)
{
samplingPts.append(pt);
samplingCells.append(celli);
samplingFaces.append(-1);
samplingSegments.append(samplingSegments.size());
samplingCurveDist.append(radius*theta);
}
const vector v = samplingPositions[i] - centre_;
const scalar theta = atan2(v & axis2, v & axis1);
samplingDistances[i] = radius*theta;
}
}
void Foam::sampledSets::arcUniform::genSamples()
{
// Storage for sample points
DynamicList<point> samplingPts;
DynamicList<point> samplingPositions;
DynamicList<scalar> samplingDistances;
DynamicList<label> samplingSegments;
DynamicList<label> samplingCells;
DynamicList<label> samplingFaces;
DynamicList<label> samplingSegments;
DynamicList<scalar> samplingCurveDist;
calcSamples
(
samplingPts,
samplingCells,
samplingFaces,
samplingPositions,
samplingDistances,
samplingSegments,
samplingCurveDist
samplingCells,
samplingFaces
);
samplingPts.shrink();
samplingPositions.shrink();
samplingDistances.shrink();
samplingSegments.shrink();
samplingCells.shrink();
samplingFaces.shrink();
samplingSegments.shrink();
samplingCurveDist.shrink();
setSamples
(
samplingPts,
samplingCells,
samplingFaces,
samplingPositions,
samplingDistances,
samplingSegments,
samplingCurveDist
samplingCells,
samplingFaces
);
}
@ -134,11 +143,6 @@ Foam::sampledSets::arcUniform::arcUniform
nPoints_(dict.lookup<scalar>("nPoints"))
{
genSamples();
if (debug)
{
write(Info);
}
}

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2011-2020 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2011-2021 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
@ -108,11 +108,11 @@ class arcUniform
//- Calculate all the sampling points
void calcSamples
(
DynamicList<point>& samplingPts,
DynamicList<label>& samplingCells,
DynamicList<label>& samplingFaces,
DynamicList<point>& samplingPositions,
DynamicList<scalar>& samplingDistances,
DynamicList<label>& samplingSegments,
DynamicList<scalar>& samplingCurveDist
DynamicList<label>& samplingCells,
DynamicList<label>& samplingFaces
) const;
//- Uses calcSamples to obtain samples and copies them into *this

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2011-2020 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2011-2021 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
@ -48,11 +48,10 @@ namespace sampledSets
void Foam::sampledSets::boundaryPoints::calcSamples
(
DynamicList<point>& samplingPts,
DynamicList<label>& samplingCells,
DynamicList<label>& samplingFaces,
DynamicList<point>& samplingPositions,
DynamicList<label>& samplingSegments,
DynamicList<scalar>& samplingCurveDist
DynamicList<label>& samplingCells,
DynamicList<label>& samplingFaces
) const
{
// Get the patch IDs
@ -176,11 +175,10 @@ void Foam::sampledSets::boundaryPoints::calcSamples
{
label facei = nearHit.index();
samplingPts.append(nearHit.hitPoint());
samplingPositions.append(nearHit.hitPoint());
samplingSegments.append(sampleI);
samplingCells.append(mesh().faceOwner()[facei]);
samplingFaces.append(facei);
samplingSegments.append(0);
samplingCurveDist.append(sampleI);
}
}
else
@ -196,34 +194,30 @@ void Foam::sampledSets::boundaryPoints::calcSamples
void Foam::sampledSets::boundaryPoints::genSamples()
{
DynamicList<point> samplingPts;
DynamicList<point> samplingPositions;
DynamicList<label> samplingSegments;
DynamicList<label> samplingCells;
DynamicList<label> samplingFaces;
DynamicList<label> samplingSegments;
DynamicList<scalar> samplingCurveDist;
calcSamples
(
samplingPts,
samplingCells,
samplingFaces,
samplingPositions,
samplingSegments,
samplingCurveDist
samplingCells,
samplingFaces
);
samplingPts.shrink();
samplingPositions.shrink();
samplingSegments.shrink();
samplingCells.shrink();
samplingFaces.shrink();
samplingSegments.shrink();
samplingCurveDist.shrink();
setSamples
(
samplingPts,
samplingCells,
samplingFaces,
samplingPositions,
samplingSegments,
samplingCurveDist
samplingCells,
samplingFaces
);
}
@ -244,11 +238,6 @@ Foam::sampledSets::boundaryPoints::boundaryPoints
maxDistance_(dict.lookup<scalar>("maxDistance"))
{
genSamples();
if (debug)
{
write(Info);
}
}

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2011-2020 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2011-2021 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
@ -97,11 +97,10 @@ class boundaryPoints
//- Samples all points in sampleCoords
void calcSamples
(
DynamicList<point>& samplingPts,
DynamicList<label>& samplingCells,
DynamicList<label>& samplingFaces,
DynamicList<point>& samplingPositions,
DynamicList<label>& samplingSegments,
DynamicList<scalar>& samplingCurveDist
DynamicList<label>& samplingCells,
DynamicList<label>& samplingFaces
) const;
//- Uses calcSamples to obtain samples. Copies them into *this.

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2011-2020 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2011-2021 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
@ -52,11 +52,10 @@ namespace sampledSets
void Foam::sampledSets::boundaryRandom::calcSamples
(
DynamicList<point>& samplingPts,
DynamicList<label>& samplingCells,
DynamicList<label>& samplingFaces,
DynamicList<point>& samplingPositions,
DynamicList<label>& samplingSegments,
DynamicList<scalar>& samplingCurveDist
DynamicList<label>& samplingCells,
DynamicList<label>& samplingFaces
) const
{
// Get the patch IDs
@ -153,11 +152,10 @@ void Foam::sampledSets::boundaryRandom::calcSamples
(1 - rootSmall)*r2D.c()
);
samplingPts.append(tetIs.tet(mesh()).barycentricToPoint(r3D));
samplingPositions.append(tetIs.tet(mesh()).barycentricToPoint(r3D));
samplingSegments.append(i);
samplingCells.append(tetIs.cell());
samplingFaces.append(tetIs.face());
samplingSegments.append(0);
samplingCurveDist.append(scalar(i));
}
}
}
@ -165,35 +163,30 @@ void Foam::sampledSets::boundaryRandom::calcSamples
void Foam::sampledSets::boundaryRandom::genSamples()
{
// Storage for sample points
DynamicList<point> samplingPts;
DynamicList<point> samplingPositions;
DynamicList<label> samplingSegments;
DynamicList<label> samplingCells;
DynamicList<label> samplingFaces;
DynamicList<label> samplingSegments;
DynamicList<scalar> samplingCurveDist;
calcSamples
(
samplingPts,
samplingCells,
samplingFaces,
samplingPositions,
samplingSegments,
samplingCurveDist
samplingCells,
samplingFaces
);
samplingPts.shrink();
samplingPositions.shrink();
samplingSegments.shrink();
samplingCells.shrink();
samplingFaces.shrink();
samplingSegments.shrink();
samplingCurveDist.shrink();
setSamples
(
samplingPts,
samplingCells,
samplingFaces,
samplingPositions,
samplingSegments,
samplingCurveDist
samplingCells,
samplingFaces
);
}
@ -213,11 +206,6 @@ Foam::sampledSets::boundaryRandom::boundaryRandom
nPoints_(dict.lookup<label>("nPoints"))
{
genSamples();
if (debug)
{
write(Info);
}
}

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2011-2020 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2011-2021 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
@ -86,11 +86,10 @@ class boundaryRandom
//- Sample all points
void calcSamples
(
DynamicList<point>& samplingPts,
DynamicList<label>& samplingCells,
DynamicList<label>& samplingFaces,
DynamicList<point>& samplingPositions,
DynamicList<label>& samplingSegments,
DynamicList<scalar>& samplingCurveDist
DynamicList<label>& samplingCells,
DynamicList<label>& samplingFaces
) const;
//- Use calcSamples to obtain samples and copy them into *this

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2011-2018 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2011-2021 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
@ -48,11 +48,10 @@ namespace sampledSets
void Foam::sampledSets::boxUniform::calcSamples
(
DynamicList<point>& samplingPts,
DynamicList<label>& samplingCells,
DynamicList<label>& samplingFaces,
DynamicList<point>& samplingPositions,
DynamicList<label>& samplingSegments,
DynamicList<scalar>& samplingCurveDist
DynamicList<label>& samplingCells,
DynamicList<label>& samplingFaces
) const
{
for (label k = 0; k < nPoints_.z(); ++ k)
@ -72,11 +71,13 @@ void Foam::sampledSets::boxUniform::calcSamples
if (celli != -1)
{
samplingPts.append(pt);
samplingPositions.append(pt);
samplingSegments.append
(
i + j*nPoints_.x() + k*nPoints_.x()*nPoints_.y()
);
samplingCells.append(celli);
samplingFaces.append(-1);
samplingSegments.append(0);
samplingCurveDist.append(scalar(i));
}
}
}
@ -86,35 +87,30 @@ void Foam::sampledSets::boxUniform::calcSamples
void Foam::sampledSets::boxUniform::genSamples()
{
// Storage for sample points
DynamicList<point> samplingPts;
DynamicList<point> samplingPositions;
DynamicList<label> samplingSegments;
DynamicList<label> samplingCells;
DynamicList<label> samplingFaces;
DynamicList<label> samplingSegments;
DynamicList<scalar> samplingCurveDist;
calcSamples
(
samplingPts,
samplingCells,
samplingFaces,
samplingPositions,
samplingSegments,
samplingCurveDist
samplingCells,
samplingFaces
);
samplingPts.shrink();
samplingPositions.shrink();
samplingSegments.shrink();
samplingCells.shrink();
samplingFaces.shrink();
samplingSegments.shrink();
samplingCurveDist.shrink();
setSamples
(
samplingPts,
samplingCells,
samplingFaces,
samplingPositions,
samplingSegments,
samplingCurveDist
samplingCells,
samplingFaces
);
}
@ -134,11 +130,6 @@ Foam::sampledSets::boxUniform::boxUniform
nPoints_(dict.lookup("nPoints"))
{
genSamples();
if (debug)
{
write(Info);
}
}

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2011-2020 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2011-2021 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
@ -62,11 +62,6 @@ SourceFiles
namespace Foam
{
// Forward declaration of classes
class passiveParticle;
template<class Type> class particle;
namespace sampledSets
{
@ -92,11 +87,10 @@ class boxUniform
//- Samples all points in sampleCoords.
void calcSamples
(
DynamicList<point>& samplingPts,
DynamicList<label>& samplingCells,
DynamicList<label>& samplingFaces,
DynamicList<point>& samplingPositions,
DynamicList<label>& samplingSegments,
DynamicList<scalar>& samplingCurveDist
DynamicList<label>& samplingCells,
DynamicList<label>& samplingFaces
) const;
//- Uses calcSamples to obtain samples. Copies them into *this.

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2020 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2020-2021 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
@ -49,10 +49,9 @@ void Foam::sampledSets::cellSetSampledSet::genSamples()
setSamples
(
List<point>(IndirectList<point>(mesh().cellCentres(), cells)),
identity(cells.size()),
cells,
labelList(cells.size(), -1),
labelList(cells.size(), 0),
scalarList(identity(cells.size()))
labelList(cells.size(), -1)
);
}
@ -71,11 +70,6 @@ Foam::sampledSets::cellSetSampledSet::cellSetSampledSet
setName_(dict.lookup("set"))
{
genSamples();
if (debug)
{
write(Info);
}
}

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2011-2019 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2011-2021 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
@ -49,11 +49,10 @@ namespace sampledSets
void Foam::sampledSets::circleRandom::calcSamples
(
DynamicList<point>& samplingPts,
DynamicList<label>& samplingCells,
DynamicList<label>& samplingFaces,
DynamicList<point>& samplingPositions,
DynamicList<label>& samplingSegments,
DynamicList<scalar>& samplingCurveDist
DynamicList<label>& samplingCells,
DynamicList<label>& samplingFaces
) const
{
Random rndGen(261782);
@ -75,11 +74,10 @@ void Foam::sampledSets::circleRandom::calcSamples
if (celli != -1)
{
samplingPts.append(pt);
samplingPositions.append(pt);
samplingSegments.append(i);
samplingCells.append(celli);
samplingFaces.append(-1);
samplingSegments.append(0);
samplingCurveDist.append(scalar(i));
}
}
}
@ -87,35 +85,30 @@ void Foam::sampledSets::circleRandom::calcSamples
void Foam::sampledSets::circleRandom::genSamples()
{
// Storage for sample points
DynamicList<point> samplingPts;
DynamicList<point> samplingPositions;
DynamicList<label> samplingSegments;
DynamicList<label> samplingCells;
DynamicList<label> samplingFaces;
DynamicList<label> samplingSegments;
DynamicList<scalar> samplingCurveDist;
calcSamples
(
samplingPts,
samplingCells,
samplingFaces,
samplingPositions,
samplingSegments,
samplingCurveDist
samplingCells,
samplingFaces
);
samplingPts.shrink();
samplingPositions.shrink();
samplingSegments.shrink();
samplingCells.shrink();
samplingFaces.shrink();
samplingSegments.shrink();
samplingCurveDist.shrink();
setSamples
(
samplingPts,
samplingCells,
samplingFaces,
samplingPositions,
samplingSegments,
samplingCurveDist
samplingCells,
samplingFaces
);
}
@ -137,11 +130,6 @@ Foam::sampledSets::circleRandom::circleRandom
nPoints_(dict.lookup<label>("nPoints"))
{
genSamples();
if (debug)
{
write(Info);
}
}

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2011-2020 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2011-2021 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
@ -95,11 +95,10 @@ class circleRandom
//- Samples all points in sampleCoords
void calcSamples
(
DynamicList<point>& samplingPts,
DynamicList<label>& samplingCells,
DynamicList<label>& samplingFaces,
DynamicList<point>& samplingPositions,
DynamicList<label>& samplingSegments,
DynamicList<scalar>& samplingCurveDist
DynamicList<label>& samplingCells,
DynamicList<label>& samplingFaces
) const;
//- Uses calcSamples to obtain samples. Copies them into *this.

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2020 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2020-2021 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
@ -49,10 +49,9 @@ void Foam::sampledSets::faceSetSampledSet::genSamples()
setSamples
(
List<point>(IndirectList<point>(mesh().faceCentres(), faces)),
labelList(IndirectList<label>(mesh().faceOwner(), faces)),
faces,
labelList(faces.size(), 0),
scalarList(identity(faces.size()))
identity(faces.size()),
labelList(UIndirectList<label>(mesh().faceOwner(), faces)),
faces
);
}
@ -71,11 +70,6 @@ Foam::sampledSets::faceSetSampledSet::faceSetSampledSet
setName_(dict.lookup("set"))
{
genSamples();
if (debug)
{
write(Info);
}
}

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2011-2018 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2011-2021 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
@ -41,149 +41,64 @@ namespace sampledSets
}
// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
void Foam::sampledSets::lineCell::calcMidPointSample
(
const polyMesh& mesh,
const point& prevPt,
const label prevFace,
const label prevSegment,
const scalar prevCurveDist,
const point& nextPt,
const label nextFace,
const label nextSegment,
DynamicList<point>& samplingPts,
DynamicList<label>& samplingCells,
DynamicList<label>& samplingFaces,
DynamicList<label>& samplingSegments,
DynamicList<scalar>& samplingCurveDist
)
{
if (prevSegment == nextSegment)
{
const point pt = (prevPt + nextPt)/2;
const vector delta = nextPt - prevPt;
const label prevOwner = mesh.faceOwner()[prevFace];
const label prevNeighbour =
prevFace < mesh.faceNeighbour().size()
? mesh.faceNeighbour()[prevFace]
: -1;
const label nextOwner = mesh.faceOwner()[nextFace];
const label nextNeighbour =
nextFace < mesh.faceNeighbour().size()
? mesh.faceNeighbour()[nextFace]
: -2;
label celli = -1;
if (prevOwner == nextOwner || prevOwner == nextNeighbour)
{
celli = prevOwner;
}
else if (prevNeighbour == nextOwner || prevNeighbour == nextNeighbour)
{
celli = prevNeighbour;
}
else
{
FatalErrorInFunction
<< "Adjacent faces in the same segment do not share a cell. "
<< "This is a bug." << exit(FatalError);
}
samplingPts.append(pt);
samplingCells.append(celli);
samplingFaces.append(-1);
samplingCurveDist.append(prevCurveDist + mag(delta)/2);
samplingSegments.append(prevSegment);
}
}
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
void Foam::sampledSets::lineCell::calcSamples
(
DynamicList<point>& samplingPts,
DynamicList<label>& samplingCells,
DynamicList<label>& samplingFaces,
DynamicList<point>& samplingPositions,
DynamicList<scalar>& samplingDistances,
DynamicList<label>& samplingSegments,
DynamicList<scalar>& samplingCurveDist
DynamicList<label>& samplingCells,
DynamicList<label>& samplingFaces
) const
{
// Run the algorithm from lineFaceSet to get all the face intersections
DynamicList<point> facePts;
DynamicList<label> faceCells;
DynamicList<label> faceFaces;
DynamicList<label> faceSegments;
DynamicList<scalar> faceCurveDist;
lineFace::calcSamples
(
mesh(),
searchEngine(),
start_,
end_,
facePts,
faceCells,
faceFaces,
faceSegments,
faceCurveDist
false,
true,
samplingPositions,
samplingDistances,
samplingSegments,
samplingCells,
samplingFaces
);
// Append all mid points to the set
for (label facei = 1; facei < facePts.size(); ++ facei)
{
calcMidPointSample
(
mesh(),
facePts[facei - 1],
faceFaces[facei - 1],
faceSegments[facei - 1],
faceCurveDist[facei - 1],
facePts[facei],
faceFaces[facei],
faceSegments[facei],
samplingPts,
samplingCells,
samplingFaces,
samplingSegments,
samplingCurveDist
);
}
}
void Foam::sampledSets::lineCell::genSamples()
{
DynamicList<point> samplingPts;
DynamicList<point> samplingPositions;
DynamicList<scalar> samplingDistances;
DynamicList<label> samplingSegments;
DynamicList<label> samplingCells;
DynamicList<label> samplingFaces;
DynamicList<label> samplingSegments;
DynamicList<scalar> samplingCurveDist;
calcSamples
(
samplingPts,
samplingCells,
samplingFaces,
samplingPositions,
samplingDistances,
samplingSegments,
samplingCurveDist
samplingCells,
samplingFaces
);
samplingPts.shrink();
samplingPositions.shrink();
samplingDistances.shrink();
samplingSegments.shrink();
samplingCells.shrink();
samplingFaces.shrink();
samplingSegments.shrink();
samplingCurveDist.shrink();
setSamples
(
samplingPts,
samplingCells,
samplingFaces,
samplingPositions,
samplingDistances,
samplingSegments,
samplingCurveDist
samplingCells,
samplingFaces
);
}
@ -203,11 +118,6 @@ Foam::sampledSets::lineCell::lineCell
end_(dict.lookup("end"))
{
genSamples();
if (debug)
{
write(Info);
}
}

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2011-2020 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2011-2021 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
@ -84,11 +84,11 @@ class lineCell
//- Calculate all the sampling points
virtual void calcSamples
(
DynamicList<point>& samplingPts,
DynamicList<label>& samplingCells,
DynamicList<label>& samplingFaces,
DynamicList<point>& samplingPositions,
DynamicList<scalar>& samplingDistances,
DynamicList<label>& samplingSegments,
DynamicList<scalar>& samplingCurveDist
DynamicList<label>& samplingCells,
DynamicList<label>& samplingFaces
) const;
//- Uses calcSamples to obtain samples and copies them into *this
@ -101,27 +101,6 @@ public:
TypeName("lineCell");
// Static Member Functions
//- Calculate the next mid point sample
static void calcMidPointSample
(
const polyMesh& mesh,
const point& prevPt,
const label prevFace,
const label prevSegment,
const scalar prevCurveDist,
const point& nextPt,
const label nextFace,
const label nextSegment,
DynamicList<point>& samplingPts,
DynamicList<label>& samplingCells,
DynamicList<label>& samplingFaces,
DynamicList<label>& samplingSegments,
DynamicList<scalar>& samplingCurveDist
);
// Constructors
//- Construct from dictionary

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2011-2018 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2011-2021 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
@ -45,104 +45,60 @@ namespace sampledSets
void Foam::sampledSets::lineCellFace::calcSamples
(
DynamicList<point>& samplingPts,
DynamicList<label>& samplingCells,
DynamicList<label>& samplingFaces,
DynamicList<point>& samplingPositions,
DynamicList<scalar>& samplingDistances,
DynamicList<label>& samplingSegments,
DynamicList<scalar>& samplingCurveDist
DynamicList<label>& samplingCells,
DynamicList<label>& samplingFaces
) const
{
// Run the algorithm from lineFaceSet to get all the face intersections
DynamicList<point> facePts;
DynamicList<label> faceCells;
DynamicList<label> faceFaces;
DynamicList<label> faceSegments;
DynamicList<scalar> faceCurveDist;
lineFace::calcSamples
(
mesh(),
searchEngine(),
start_,
end_,
facePts,
faceCells,
faceFaces,
faceSegments,
faceCurveDist
true,
true,
samplingPositions,
samplingDistances,
samplingSegments,
samplingCells,
samplingFaces
);
// If there are no intersections then quit
if (!facePts.size())
{
return;
}
// Append all the face intersections to the set, additionally adding mid
// points when the segment is the same
samplingPts.append(facePts[0]);
samplingCells.append(faceCells[0]);
samplingFaces.append(faceFaces[0]);
samplingSegments.append(faceSegments[0]);
samplingCurveDist.append(faceCurveDist[0]);
for (label facei = 1; facei < facePts.size(); ++ facei)
{
lineCell::calcMidPointSample
(
mesh(),
samplingPts.last(),
samplingFaces.last(),
samplingSegments.last(),
samplingCurveDist.last(),
facePts[facei],
faceFaces[facei],
faceSegments[facei],
samplingPts,
samplingCells,
samplingFaces,
samplingSegments,
samplingCurveDist
);
samplingPts.append(facePts[facei]);
samplingCells.append(faceCells[facei]);
samplingFaces.append(faceFaces[facei]);
samplingSegments.append(faceSegments[facei]);
samplingCurveDist.append(faceCurveDist[facei]);
}
}
void Foam::sampledSets::lineCellFace::genSamples()
{
DynamicList<point> samplingPts;
DynamicList<point> samplingPositions;
DynamicList<scalar> samplingDistances;
DynamicList<label> samplingSegments;
DynamicList<label> samplingCells;
DynamicList<label> samplingFaces;
DynamicList<label> samplingSegments;
DynamicList<scalar> samplingCurveDist;
calcSamples
(
samplingPts,
samplingCells,
samplingFaces,
samplingPositions,
samplingDistances,
samplingSegments,
samplingCurveDist
samplingCells,
samplingFaces
);
samplingPts.shrink();
samplingPositions.shrink();
samplingDistances.shrink();
samplingSegments.shrink();
samplingCells.shrink();
samplingFaces.shrink();
samplingSegments.shrink();
samplingCurveDist.shrink();
setSamples
(
samplingPts,
samplingCells,
samplingFaces,
samplingPositions,
samplingDistances,
samplingSegments,
samplingCurveDist
samplingCells,
samplingFaces
);
}
@ -162,11 +118,6 @@ Foam::sampledSets::lineCellFace::lineCellFace
end_(dict.lookup("end"))
{
genSamples();
if (debug)
{
write(Info);
}
}
@ -185,11 +136,6 @@ Foam::sampledSets::lineCellFace::lineCellFace
end_(end)
{
genSamples();
if (debug)
{
write(Info);
}
}

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2011-2020 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2011-2021 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
@ -85,11 +85,11 @@ class lineCellFace
//- Calculate all the sampling points
virtual void calcSamples
(
DynamicList<point>& samplingPts,
DynamicList<label>& samplingCells,
DynamicList<label>& samplingFaces,
DynamicList<point>& samplingPositions,
DynamicList<scalar>& samplingDistances,
DynamicList<label>& samplingSegments,
DynamicList<scalar>& samplingCurveDist
DynamicList<label>& samplingCells,
DynamicList<label>& samplingFaces
) const;
//- Uses calcSamples to obtain samples and copies them into *this

View File

@ -27,6 +27,8 @@ License
#include "meshSearch.H"
#include "DynamicList.H"
#include "polyMesh.H"
#include "treeDataCell.H"
#include "sampledSetCloud.H"
#include "addToRunTimeSelectionTable.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
@ -49,176 +51,211 @@ void Foam::sampledSets::lineFace::calcSamples
const meshSearch& searchEngine,
const vector& start,
const vector& end,
DynamicList<point>& samplingPts,
DynamicList<label>& samplingCells,
DynamicList<label>& samplingFaces,
const bool storeFaces,
const bool storeCells,
DynamicList<point>& samplingPositions,
DynamicList<scalar>& samplingDistances,
DynamicList<label>& samplingSegments,
DynamicList<scalar>& samplingCurveDist
DynamicList<label>& samplingCells,
DynamicList<label>& samplingFaces
)
{
// Ask for the tetBasePtIs and oldCellCentres to trigger all processors to
// build them, otherwise, if some processors have no particles then there
// is a comms mismatch.
mesh.tetBasePtIs();
mesh.oldCellCentres();
// Create lists of initial positions from which to track, the faces and
// cells associated with those positions, and whether the track propagates
// forward (true) or backward (false) along the line from start to end
DynamicList<point> initialPts;
DynamicList<label> initialFaces, initialCells;
DynamicList<bool> initialDirections;
// Add boundary hits
const List<pointIndexHit> bHits = searchEngine.intersections(start, end);
forAll(bHits, bHiti)
// Get all candidates for starting the tracks
List<DynamicList<label>> procCandidateCells(Pstream::nProcs());
List<DynamicList<scalar>> procCandidateTs(Pstream::nProcs());
{
initialPts.append(bHits[bHiti].hitPoint());
const label facei = bHits[bHiti].index();
initialFaces.append(facei);
initialCells.append(mesh.faceOwner()[facei]);
initialDirections.append((mesh.faceAreas()[facei] & (end - start)) < 0);
}
// Add the start and end points if they can be found within the mesh
const label startCelli = searchEngine.findCell(start);
if (startCelli != -1)
{
initialPts.append(start);
initialFaces.append(-1);
initialCells.append(startCelli);
initialDirections.append(true);
}
const label endCelli = searchEngine.findCell(end);
if (endCelli != -1)
{
initialPts.append(end);
initialFaces.append(-1);
initialCells.append(endCelli);
initialDirections.append(false);
}
// Loop over the initial points, starting new segments each time
label sampleSegmenti = 0;
DynamicList<Pair<point>> lines;
forAll(initialPts, initiali)
{
// Get the sign
const scalar sign = initialDirections[initiali] ? +1 : -1;
// Create a particle. Track backwards into the boundary face so that
// the particle has the correct topology.
passiveParticle sampleParticle
(
mesh,
initialPts[initiali],
initialCells[initiali]
);
if (initialFaces[initiali] != -1)
const label startCelli = searchEngine.findCell(start);
if (startCelli != -1)
{
sampleParticle.track(sign*(start - end), 0);
if (!sampleParticle.onBoundaryFace())
{
FatalErrorInFunction
<< "Failed to associate with the starting boundary face"
<< exit(FatalError);
}
procCandidateCells[Pstream::myProcNo()].append(startCelli);
procCandidateTs[Pstream::myProcNo()].append(0);
}
// Track until a boundary is hit, appending the face intersections
// to the lists of samples, and storing the line
DynamicList<point> segmentPts;
DynamicList<label> segmentCells, segmentFaces;
Pair<point> line(sampleParticle.position(), sampleParticle.position());
while (true)
const label endCelli = searchEngine.findCell(end);
if (endCelli != -1)
{
const point pt = sampleParticle.position();
const scalar dist = mag(pt - (sign > 0 ? start : end));
const bool first = segmentPts.size() == 0;
if (sampleParticle.onFace())
{
segmentPts.append(pt);
segmentCells.append(sampleParticle.cell());
segmentFaces.append(sampleParticle.face());
}
const vector s =
sign*(end - start)*(1 - dist/mag(end - start));
sampleParticle.reset(1);
if
(
(!first && sampleParticle.onBoundaryFace())
|| sampleParticle.trackToCell(s, 0) == 0
)
{
break;
}
}
line[1] = sampleParticle.position();
// Reverse if going backwards
if (sign < 0)
{
inplaceReverseList(segmentPts);
inplaceReverseList(segmentCells);
inplaceReverseList(segmentFaces);
line = reverse(line);
procCandidateCells[Pstream::myProcNo()].append(endCelli);
procCandidateTs[Pstream::myProcNo()].append(1);
}
// Mark point as not to be kept if they fall within the bounds of
// previous lines
boolList segmentKeep(segmentPts.size(), true);
forAll(segmentPts, segmentPti)
const List<pointIndexHit> bHits =
searchEngine.intersections(start, end);
forAll(bHits, bHiti)
{
forAll(lines, linei)
for (label bHitj = bHiti + 1; bHitj < bHits.size(); ++ bHitj)
{
const Pair<point>& l = lines[linei];
const vector dlHat = normalised(l[1] - l[0]);
if (magSqr(dlHat) == 0)
const point midP =
(bHits[bHiti].hitPoint() + bHits[bHitj].hitPoint())/2;
const label midCelli = searchEngine.findCell(midP);
const scalar midT = mag(midP - start)/mag(end - start);
if (midCelli != -1)
{
continue;
}
const scalar dot0 = (segmentPts[segmentPti] - l[0]) & dlHat;
const scalar dot1 = (l[1] - segmentPts[segmentPti]) & dlHat;
if (dot0 > 0 && dot1 > 0)
{
segmentKeep[segmentPti] = false;
break;
procCandidateCells[Pstream::myProcNo()].append(midCelli);
procCandidateTs[Pstream::myProcNo()].append(midT);
}
}
}
}
Pstream::gatherList(procCandidateCells);
Pstream::scatterList(procCandidateCells);
Pstream::gatherList(procCandidateTs);
Pstream::scatterList(procCandidateTs);
// Store the line
lines.append(line);
// Tracking data
const List<point> startEnd({start, end});
const List<point> endStart({end, start});
DynamicList<point> halfSegmentPositions;
DynamicList<scalar> halfSegmentDistances;
DynamicList<label> halfSegmentCells;
DynamicList<label> halfSegmentFaces;
// Add new segments to the lists, breaking the segment anywhere that
// points are not kept
bool newSampleSegment = false;
forAll(segmentPts, segmentPti)
// Create a cloud with which to track segments
sampledSetCloud particles
(
mesh,
lineFace::typeName,
IDLList<sampledSetParticle>()
);
// Create each segment in turn
label segmenti = 0;
forAll(procCandidateCells, proci)
{
forAll(procCandidateCells[proci], candidatei)
{
if (segmentKeep[segmentPti])
const label celli = procCandidateCells[proci][candidatei];
if (celli == -1) continue;
const scalar t = procCandidateTs[proci][candidatei];
const point p = (1 - t)*start + t*end;
// Track in both directions to form parts of the segment either
// side of the candidate
Pair<scalar> segmentT;
forAll(segmentT, i)
{
samplingPts.append(segmentPts[segmentPti]);
samplingCells.append(segmentCells[segmentPti]);
samplingFaces.append(segmentFaces[segmentPti]);
samplingSegments.append(sampleSegmenti);
samplingCurveDist.append(mag(segmentPts[segmentPti] - start));
newSampleSegment = true;
sampledSetParticle::trackingData tdBwd
(
particles,
i == 0 ? endStart : startEnd,
false,
storeFaces,
storeCells,
halfSegmentPositions,
halfSegmentDistances,
halfSegmentCells,
halfSegmentFaces
);
particles.clear();
if (proci == Pstream::myProcNo())
{
particles.addParticle
(
new sampledSetParticle
(
mesh,
p,
celli,
0,
i == 0 ? t : 1 - t,
0
)
);
}
particles.move(particles, tdBwd, rootGreat);
segmentT[i] =
returnReduce
(
particles.size()
? mag(particles.first()->position() - start)
/mag(end - start)
: i == 0 ? vGreat : -vGreat,
[i](const scalar a, const scalar b)
{
return (i == 0) == (a < b) ? a : b;
}
);
if (i == 0)
{
reverse(halfSegmentPositions);
reverse(halfSegmentDistances);
reverse(halfSegmentCells);
reverse(halfSegmentFaces);
}
const label n = halfSegmentPositions.size();
samplingPositions.append(halfSegmentPositions);
samplingSegments.append(labelList(n, segmenti));
samplingCells.append(halfSegmentCells);
samplingFaces.append(halfSegmentFaces);
halfSegmentPositions.clear();
halfSegmentDistances.clear();
halfSegmentCells.clear();
halfSegmentFaces.clear();
// If storing cells we need to store the starting cells between
// the tracks
if (proci == Pstream::myProcNo() && i == 1 && storeCells)
{
particle trackBwd(mesh, p, celli), trackFwd(trackBwd);
trackBwd.trackToFace(start - p, 0);
trackFwd.trackToFace(end - p, 0);
if (trackBwd.onFace() && trackFwd.onFace())
{
samplingPositions.append
(
(trackBwd.position() + trackFwd.position())/2
);
samplingSegments.append(segmenti);
samplingCells.append(celli);
samplingFaces.append(-1);
}
}
}
else if (newSampleSegment)
// Disable all candidates that fall within the bounds of the
// computed segment
forAll(procCandidateCells, procj)
{
++ sampleSegmenti;
newSampleSegment = false;
forAll(procCandidateCells[procj], candidatej)
{
const label cellj = procCandidateCells[procj][candidatej];
if (cellj == -1) continue;
const scalar t = procCandidateTs[procj][candidatej];
if
(
t > segmentT.first() - rootSmall
&& t < segmentT.second() + rootSmall
)
{
procCandidateCells[procj][candidatej] = -1;
procCandidateTs[procj][candidatej] = NaN;
}
}
}
// Move onto the next segment
segmenti ++;
}
if (newSampleSegment)
{
++ sampleSegmenti;
newSampleSegment = false;
}
}
// Set the distances
samplingDistances.resize(samplingPositions.size());
forAll(samplingPositions, i)
{
samplingDistances[i] = mag(samplingPositions[i] - start);
}
}
@ -227,11 +264,11 @@ void Foam::sampledSets::lineFace::calcSamples
void Foam::sampledSets::lineFace::calcSamples
(
DynamicList<point>& samplingPts,
DynamicList<label>& samplingCells,
DynamicList<label>& samplingFaces,
DynamicList<point>& samplingPositions,
DynamicList<scalar>& samplingDistances,
DynamicList<label>& samplingSegments,
DynamicList<scalar>& samplingCurveDist
DynamicList<label>& samplingCells,
DynamicList<label>& samplingFaces
) const
{
calcSamples
@ -240,45 +277,47 @@ void Foam::sampledSets::lineFace::calcSamples
searchEngine(),
start_,
end_,
samplingPts,
samplingCells,
samplingFaces,
true,
false,
samplingPositions,
samplingDistances,
samplingSegments,
samplingCurveDist
samplingCells,
samplingFaces
);
}
void Foam::sampledSets::lineFace::genSamples()
{
DynamicList<point> samplingPts;
DynamicList<point> samplingPositions;
DynamicList<scalar> samplingDistances;
DynamicList<label> samplingSegments;
DynamicList<label> samplingCells;
DynamicList<label> samplingFaces;
DynamicList<label> samplingSegments;
DynamicList<scalar> samplingCurveDist;
calcSamples
(
samplingPts,
samplingCells,
samplingFaces,
samplingPositions,
samplingDistances,
samplingSegments,
samplingCurveDist
samplingCells,
samplingFaces
);
samplingPts.shrink();
samplingPositions.shrink();
samplingDistances.shrink();
samplingSegments.shrink();
samplingCells.shrink();
samplingFaces.shrink();
samplingSegments.shrink();
samplingCurveDist.shrink();
setSamples
(
samplingPts,
samplingCells,
samplingFaces,
samplingPositions,
samplingDistances,
samplingSegments,
samplingCurveDist
samplingCells,
samplingFaces
);
}
@ -298,11 +337,6 @@ Foam::sampledSets::lineFace::lineFace
end_(dict.lookup("end"))
{
genSamples();
if (debug)
{
write(Info);
}
}

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2011-2020 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2011-2021 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
@ -86,11 +86,11 @@ class lineFace
//- Calculate all the sampling points
void calcSamples
(
DynamicList<point>& samplingPts,
DynamicList<label>& samplingCells,
DynamicList<label>& samplingFaces,
DynamicList<point>& samplingPositions,
DynamicList<scalar>& samplingDistances,
DynamicList<label>& samplingSegments,
DynamicList<scalar>& samplingCurveDist
DynamicList<label>& samplingCells,
DynamicList<label>& samplingFaces
) const;
//- Uses calcSamples to obtain samples and copies them into *this
@ -112,11 +112,13 @@ public:
const meshSearch& searchEngine,
const vector& start,
const vector& end,
DynamicList<point>& samplingPts,
DynamicList<label>& samplingCells,
DynamicList<label>& samplingFaces,
const bool storeFaces,
const bool storeCells,
DynamicList<point>& samplingPositions,
DynamicList<scalar>& samplingDistances,
DynamicList<label>& samplingSegments,
DynamicList<scalar>& samplingCurveDist
DynamicList<label>& samplingCells,
DynamicList<label>& samplingFaces
);

View File

@ -27,6 +27,8 @@ License
#include "meshSearch.H"
#include "DynamicList.H"
#include "polyMesh.H"
#include "sampledSetCloud.H"
#include "points.H"
#include "addToRunTimeSelectionTable.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
@ -45,92 +47,68 @@ namespace sampledSets
void Foam::sampledSets::lineUniform::calcSamples
(
DynamicList<point>& samplingPts,
DynamicList<label>& samplingCells,
DynamicList<label>& samplingFaces,
DynamicList<point>& samplingPositions,
DynamicList<scalar>& samplingDistances,
DynamicList<label>& samplingSegments,
DynamicList<scalar>& samplingCurveDist
DynamicList<label>& samplingCells,
DynamicList<label>& samplingFaces
) const
{
// Ask for the tetBasePtIs and oldCellCentres to trigger all processors to
// build them, otherwise, if some processors have no particles then there
// is a comms mismatch.
mesh().tetBasePtIs();
mesh().oldCellCentres();
// Calculate all sampling points
const scalarField ts(scalarList(identity(nPoints_))/(nPoints_ - 1));
const pointField points((1 - ts)*start_ + ts*end_);
label sampleSegmentI = 0, sampleI = 0;
scalar sampleT = 0;
// Calculate the sampling topology
points::calcSamples
(
mesh(),
searchEngine(),
points,
samplingPositions,
samplingDistances,
samplingSegments,
samplingCells,
samplingFaces
);
while (sampleI < nPoints_)
// Overwrite the distances
forAll(samplingPositions, i)
{
const point pt = (1 - sampleT)*start_ + sampleT*end_;
const label sampleCellI = searchEngine().findCell(pt);
if (sampleCellI == -1)
{
if (++ sampleI < nPoints_)
{
sampleT = scalar(sampleI)/(nPoints_ - 1);
}
}
else
{
passiveParticle sampleParticle(mesh(), pt, sampleCellI);
do
{
samplingPts.append(sampleParticle.position());
samplingCells.append(sampleParticle.cell());
samplingFaces.append(-1);
samplingSegments.append(sampleSegmentI);
samplingCurveDist.append(sampleT*mag(end_ - start_));
if (++ sampleI < nPoints_)
{
sampleT = scalar(sampleI)/(nPoints_ - 1);
sampleParticle.reset(1);
sampleParticle.track((end_ - start_)/(nPoints_ - 1), 0);
}
}
while (sampleI < nPoints_ && !sampleParticle.onBoundaryFace());
++ sampleSegmentI;
}
samplingDistances[i] = mag(samplingPositions[i] - start_);
}
}
void Foam::sampledSets::lineUniform::genSamples()
{
DynamicList<point> samplingPts;
DynamicList<point> samplingPositions;
DynamicList<scalar> samplingDistances;
DynamicList<label> samplingSegments;
DynamicList<label> samplingCells;
DynamicList<label> samplingFaces;
DynamicList<label> samplingSegments;
DynamicList<scalar> samplingCurveDist;
calcSamples
(
samplingPts,
samplingCells,
samplingFaces,
samplingPositions,
samplingDistances,
samplingSegments,
samplingCurveDist
samplingCells,
samplingFaces
);
samplingPts.shrink();
samplingPositions.shrink();
samplingDistances.shrink();
samplingSegments.shrink();
samplingCells.shrink();
samplingFaces.shrink();
samplingSegments.shrink();
samplingCurveDist.shrink();
setSamples
(
samplingPts,
samplingCells,
samplingFaces,
samplingPositions,
samplingDistances,
samplingSegments,
samplingCurveDist
samplingCells,
samplingFaces
);
}
@ -151,11 +129,6 @@ Foam::sampledSets::lineUniform::lineUniform
nPoints_(dict.lookup<label>("nPoints"))
{
genSamples();
if (debug)
{
write(Pout);
}
}

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2011-2020 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2011-2021 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
@ -92,11 +92,11 @@ class lineUniform
// for each sample.
void calcSamples
(
DynamicList<point>& samplingPts,
DynamicList<label>& samplingCells,
DynamicList<label>& samplingFaces,
DynamicList<point>& samplingPositions,
DynamicList<scalar>& samplingDistances,
DynamicList<label>& samplingSegments,
DynamicList<scalar>& samplingCurveDist
DynamicList<label>& samplingCells,
DynamicList<label>& samplingFaces
) const;
//- Uses calcSamples to obtain samples. Copies them into *this.

View File

@ -27,6 +27,7 @@ License
#include "meshSearch.H"
#include "DynamicList.H"
#include "polyMesh.H"
#include "sampledSetCloud.H"
#include "addToRunTimeSelectionTable.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
@ -41,15 +42,137 @@ namespace sampledSets
}
// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
void Foam::sampledSets::points::calcSamples
(
const polyMesh& mesh,
const meshSearch& searchEngine,
const pointField& points,
DynamicList<point>& samplingPositions,
DynamicList<scalar>& samplingDistances,
DynamicList<label>& samplingSegments,
DynamicList<label>& samplingCells,
DynamicList<label>& samplingFaces
)
{
// Create a cloud with which to track segments
sampledSetCloud particles
(
mesh,
points::typeName,
IDLList<sampledSetParticle>()
);
// Consider each point
label segmenti = 0, samplei = 0, pointi0 = labelMax, pointi = 0;
scalar distance = 0;
while (pointi < points.size())
{
// Sum the distance to the start of the track
for (label pointj = pointi0; pointj < pointi; ++ pointj)
{
distance += mag(points[pointj + 1] - points[pointj]);
}
// Update the old point index
pointi0 = pointi;
// Get unique processor and cell that this sample point is in
const labelPair procAndCelli = returnReduce
(
labelPair
(
Pstream::myProcNo(),
searchEngine.findCell(points[pointi])
),
[](const labelPair& a, const labelPair& b)
{
return
a.second() != -1 && b.second() != -1
? a.first() < b.first() ? a : b
: a.second() != -1 ? a : b;
}
);
// Skip this point if it is not in the global mesh
if (procAndCelli.second() == -1)
{
++ pointi;
}
// If the point is in the global mesh then track to create a segment
else
{
sampledSetParticle::trackingData td
(
particles,
points,
true,
false,
false,
samplingPositions,
samplingDistances,
samplingCells,
samplingFaces
);
// Clear the cloud, then, if the point is in this local mesh,
// initialise a particle at the point
particles.clear();
if (procAndCelli.first() == Pstream::myProcNo())
{
particles.addParticle
(
new sampledSetParticle
(
mesh,
points[pointi],
procAndCelli.second(),
pointi,
1,
distance
)
);
particles.first()->store(particles, td);
}
// Track to create this segment
particles.move(particles, td, rootGreat);
// Set the segment indices
samplingSegments.append
(
labelList
(
samplingPositions.size() - samplingSegments.size(),
segmenti
)
);
// Move on to the next segment
++ segmenti;
// Determine the global number of samples completed
const label samplei0 = samplei;
samplei = returnReduce(samplingPositions.size(), sumOp<label>());
// Move to the next unsampled point
pointi += samplei - samplei0;
}
}
}
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
void Foam::sampledSets::points::calcSamplesUnordered
(
DynamicList<point>& samplingPts,
DynamicList<label>& samplingCells,
DynamicList<label>& samplingFaces,
DynamicList<point>& samplingPositions,
DynamicList<label>& samplingSegments,
DynamicList<scalar>& samplingCurveDist
DynamicList<label>& samplingCells,
DynamicList<label>& samplingFaces
) const
{
forAll(points_, i)
@ -59,122 +182,96 @@ void Foam::sampledSets::points::calcSamplesUnordered
if (celli != -1)
{
samplingPts.append(pt);
samplingPositions.append(pt);
samplingSegments.append(i);
samplingCells.append(celli);
samplingFaces.append(-1);
samplingSegments.append(samplingSegments.size());
samplingCurveDist.append(scalar(i));
}
}
}
void Foam::sampledSets::points::calcSamplesOrdered
(
DynamicList<point>& samplingPts,
DynamicList<label>& samplingCells,
DynamicList<label>& samplingFaces,
DynamicList<point>& samplingPositions,
DynamicList<scalar>& samplingDistances,
DynamicList<label>& samplingSegments,
DynamicList<scalar>& samplingCurveDist
DynamicList<label>& samplingCells,
DynamicList<label>& samplingFaces
) const
{
// Ask for the tetBasePtIs and oldCellCentres to trigger all processors to
// build them, otherwise, if some processors have no particles then there
// is a comms mismatch.
mesh().tetBasePtIs();
mesh().oldCellCentres();
const label n = points_.size();
label sampleSegmentI = 0;
label sampleI = 0;
scalar sampleDist = 0;
while (sampleI < n)
{
const point pt = points_[sampleI];
const label sampleCellI = searchEngine().findCell(pt);
if (sampleCellI == -1)
{
if (++ sampleI < n)
{
sampleDist += mag(points_[sampleI] - points_[sampleI - 1]);
}
}
else
{
passiveParticle sampleParticle(mesh(), pt, sampleCellI);
do
{
samplingPts.append(sampleParticle.position());
samplingCells.append(sampleParticle.cell());
samplingFaces.append(-1);
samplingSegments.append(sampleSegmentI);
samplingCurveDist.append(sampleDist);
if (++ sampleI < n)
{
const vector s = points_[sampleI] - points_[sampleI - 1];
sampleDist += mag(s);
sampleParticle.reset(1);
sampleParticle.track(s, 0);
}
}
while (sampleI < n && !sampleParticle.onBoundaryFace());
++ sampleSegmentI;
}
}
// Calculate the sampling topology
calcSamples
(
mesh(),
searchEngine(),
pointField(points_),
samplingPositions,
samplingDistances,
samplingSegments,
samplingCells,
samplingFaces
);
}
void Foam::sampledSets::points::genSamples()
{
DynamicList<point> samplingPts;
DynamicList<point> samplingPositions;
DynamicList<scalar> samplingDistances;
DynamicList<label> samplingSegments;
DynamicList<label> samplingCells;
DynamicList<label> samplingFaces;
DynamicList<label> samplingSegments;
DynamicList<scalar> samplingCurveDist;
if (!ordered_)
{
calcSamplesUnordered
(
samplingPts,
samplingCells,
samplingFaces,
samplingPositions,
samplingSegments,
samplingCurveDist
samplingCells,
samplingFaces
);
}
else
{
calcSamplesOrdered
(
samplingPts,
samplingCells,
samplingFaces,
samplingPositions,
samplingDistances,
samplingSegments,
samplingCurveDist
samplingCells,
samplingFaces
);
}
samplingPts.shrink();
samplingPositions.shrink();
samplingDistances.shrink();
samplingSegments.shrink();
samplingCells.shrink();
samplingFaces.shrink();
samplingSegments.shrink();
samplingCurveDist.shrink();
setSamples
(
samplingPts,
samplingCells,
samplingFaces,
samplingSegments,
samplingCurveDist
);
if (!ordered_)
{
setSamples
(
samplingPositions,
samplingSegments,
samplingCells,
samplingFaces
);
}
else
{
setSamples
(
samplingPositions,
samplingDistances,
samplingSegments,
samplingCells,
samplingFaces
);
}
}
@ -193,11 +290,6 @@ Foam::sampledSets::points::points
ordered_(dict.lookup("ordered"))
{
genSamples();
if (debug)
{
write(Info);
}
}

Some files were not shown because too many files have changed in this diff Show More