/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2012-2017 OpenFOAM Foundation
\\/ M anipulation | Copyright (C) 2015-2016 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see .
\*---------------------------------------------------------------------------*/
#include "ParticleCollector.H"
#include "Pstream.H"
#include "surfaceWriter.H"
#include "unitConversion.H"
#include "Random.H"
#include "triangle.H"
#include "cloud.H"
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
template
void Foam::ParticleCollector::makeLogFile
(
const faceList& faces,
const Field& points,
const Field& area
)
{
// Create the output file if not already created
if (log_)
{
if (debug)
{
Info<< "Creating output file" << endl;
}
if (Pstream::master())
{
// Create directory if does not exist
mkDir(this->writeTimeDir());
// Open new file at start up
outputFilePtr_.reset
(
new OFstream(this->writeTimeDir()/(type() + ".dat"))
);
outputFilePtr_()
<< "# Source : " << type() << nl
<< "# Bins : " << faces.size() << nl
<< "# Total area : " << sum(area) << nl;
outputFilePtr_()
<< "# Geometry :" << nl
<< '#'
<< tab << "Bin"
<< tab << "(Centre_x Centre_y Centre_z)"
<< tab << "Area"
<< nl;
forAll(faces, i)
{
outputFilePtr_()
<< '#'
<< tab << i
<< tab << faces[i].centre(points)
<< tab << area[i]
<< nl;
}
outputFilePtr_()
<< '#' << nl
<< "# Output format:" << nl;
forAll(faces, i)
{
word id = Foam::name(i);
word binId = "bin_" + id;
outputFilePtr_()
<< '#'
<< tab << "Time"
<< tab << binId
<< tab << "mass[" << id << "]"
<< tab << "massFlowRate[" << id << "]"
<< endl;
}
}
}
}
template
void Foam::ParticleCollector::initPolygons
(
const List>& polygons
)
{
mode_ = mtPolygon;
label nPoints = 0;
forAll(polygons, polyI)
{
label np = polygons[polyI].size();
if (np < 3)
{
FatalIOErrorInFunction(this->coeffDict())
<< "polygons must consist of at least 3 points"
<< exit(FatalIOError);
}
nPoints += np;
}
label pointOffset = 0;
points_.setSize(nPoints);
faces_.setSize(polygons.size());
faceTris_.setSize(polygons.size());
area_.setSize(polygons.size());
forAll(faces_, facei)
{
const Field& polyPoints = polygons[facei];
face f(identity(polyPoints.size()) + pointOffset);
UIndirectList(points_, f) = polyPoints;
area_[facei] = f.mag(points_);
DynamicList tris;
f.triangles(points_, tris);
faceTris_[facei].transfer(tris);
faces_[facei].transfer(f);
pointOffset += polyPoints.size();
}
}
template
void Foam::ParticleCollector::initConcentricCircles()
{
mode_ = mtConcentricCircle;
vector origin(this->coeffDict().lookup("origin"));
this->coeffDict().lookup("radius") >> radius_;
nSector_ = readLabel(this->coeffDict().lookup("nSector"));
label nS = nSector_;
vector refDir;
if (nSector_ > 1)
{
refDir = this->coeffDict().lookup("refDir");
refDir -= normal_[0]*(normal_[0] & refDir);
refDir /= mag(refDir);
}
else
{
// Set 4 quadrants for single sector cases
nS = 4;
vector tangent = Zero;
scalar magTangent = 0.0;
Random& rnd = this->owner().rndGen();
while (magTangent < SMALL)
{
vector v = rnd.sample01();
tangent = v - (v & normal_[0])*normal_[0];
magTangent = mag(tangent);
}
refDir = tangent/magTangent;
}
scalar dTheta = 5.0;
scalar dThetaSector = 360.0/scalar(nS);
label intervalPerSector = max(1, ceil(dThetaSector/dTheta));
dTheta = dThetaSector/scalar(intervalPerSector);
label nPointPerSector = intervalPerSector + 1;
label nPointPerRadius = nS*(nPointPerSector - 1);
label nPoint = radius_.size()*nPointPerRadius;
label nFace = radius_.size()*nS;
// Add origin
nPoint++;
points_.setSize(nPoint);
faces_.setSize(nFace);
area_.setSize(nFace);
coordSys_ = cylindricalCS("coordSys", origin, normal_[0], refDir, false);
List