Commit 50916145 authored by mattijs's avatar mattijs
Browse files

Merge branch 'master' of /home/noisy3/OpenFOAM/OpenFOAM-dev

parents 7dcb23c5 8a963cd7
......@@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2004-2010 OpenCFD Ltd.
\\ / A nd | Copyright (C) 2004-2011 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
......@@ -54,6 +54,7 @@ Foam::fvm::Su
return tfvm;
}
template<class Type>
Foam::tmp<Foam::fvMatrix<Type> >
Foam::fvm::Su
......@@ -67,6 +68,7 @@ Foam::fvm::Su
return tfvm;
}
template<class Type>
Foam::tmp<Foam::fvMatrix<Type> >
Foam::fvm::Su
......@@ -80,6 +82,7 @@ Foam::fvm::Su
return tfvm;
}
template<class Type>
Foam::zeroField
Foam::fvm::Su
......@@ -117,6 +120,7 @@ Foam::fvm::Sp
return tfvm;
}
template<class Type>
Foam::tmp<Foam::fvMatrix<Type> >
Foam::fvm::Sp
......@@ -130,6 +134,7 @@ Foam::fvm::Sp
return tfvm;
}
template<class Type>
Foam::tmp<Foam::fvMatrix<Type> >
Foam::fvm::Sp
......@@ -169,6 +174,7 @@ Foam::fvm::Sp
return tfvm;
}
template<class Type>
Foam::zeroField
Foam::fvm::Sp
......@@ -209,6 +215,7 @@ Foam::fvm::SuSp
return tfvm;
}
template<class Type>
Foam::tmp<Foam::fvMatrix<Type> >
Foam::fvm::SuSp
......@@ -222,6 +229,7 @@ Foam::fvm::SuSp
return tfvm;
}
template<class Type>
Foam::tmp<Foam::fvMatrix<Type> >
Foam::fvm::SuSp
......@@ -235,6 +243,7 @@ Foam::fvm::SuSp
return tfvm;
}
template<class Type>
Foam::zeroField
Foam::fvm::SuSp
......
......@@ -52,7 +52,47 @@ void Foam::FacePostProcessing<CloudType>::applyToFace
faceI = j;
return;
}
}
}
}
}
template<class CloudType>
void Foam::FacePostProcessing<CloudType>::makeLogFile
(
const word& zoneName,
const label zoneI,
const label nFaces,
const scalar totArea
)
{
// 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(outputDir_);
// Open new file at start up
outputFilePtr_.set
(
zoneI,
new OFstream(outputDir_/(type() + '_' + zoneName + ".dat"))
);
outputFilePtr_[zoneI]
<< "# Source : " << type() << nl
<< "# Face zone : " << zoneName << nl
<< "# Faces : " << nFaces << nl
<< "# Area : " << totArea << nl
<< "# Time" << tab << "mass" << tab << "massFlux" << endl;
}
}
}
......@@ -61,8 +101,9 @@ template<class CloudType>
void Foam::FacePostProcessing<CloudType>::write()
{
const fvMesh& mesh = this->owner().mesh();
const faceZoneMesh& fzm = this->owner().mesh().faceZones();
const scalar dt = this->owner().time().deltaTValue();
const Time& time = mesh.time();
const faceZoneMesh& fzm = mesh.faceZones();
const scalar dt = time.deltaTValue();
totalTime_ += dt;
......@@ -80,8 +121,11 @@ void Foam::FacePostProcessing<CloudType>::write()
Info<< "particleFaceFlux output:" << nl;
List<scalarField> zoneMassTotal(mass_.size());
forAll(zoneMassTotal, zoneI)
List<scalarField> zoneMassFlux(massFlux_.size());
forAll(faceZoneIDs_, zoneI)
{
const word& zoneName = fzm[faceZoneIDs_[zoneI]].name();
scalarListList allProcMass(Pstream::nProcs());
allProcMass[procI] = massTotal_[zoneI];
Pstream::gatherList(allProcMass);
......@@ -90,15 +134,8 @@ void Foam::FacePostProcessing<CloudType>::write()
(
allProcMass, accessOp<scalarList>()
);
const scalar sumMassTotal = sum(zoneMassTotal[zoneI]);
const word& zoneName = fzm[faceZoneIDs_[zoneI]].name();
Info<< " " << zoneName << " total mass = "
<< sum(zoneMassTotal[zoneI]) << nl;
}
List<scalarField> zoneMassFlux(massFlux_.size());
forAll(zoneMassFlux, zoneI)
{
scalarListList allProcMassFlux(Pstream::nProcs());
allProcMassFlux[procI] = massFlux_[zoneI];
Pstream::gatherList(allProcMassFlux);
......@@ -107,10 +144,19 @@ void Foam::FacePostProcessing<CloudType>::write()
(
allProcMassFlux, accessOp<scalarList>()
);
const scalar sumMassFlux = sum(zoneMassFlux[zoneI]);
const word& zoneName = fzm[faceZoneIDs_[zoneI]].name();
Info<< " " << zoneName << " average mass flux = "
<< sum(zoneMassFlux[zoneI]) << nl;
Info<< " " << zoneName
<< ": total mass = " << sumMassTotal
<< "; average mass flux = " << sumMassFlux
<< nl;
if (outputFilePtr_.set(zoneI))
{
OFstream& os = outputFilePtr_[zoneI];
os << time.timeName() << token::TAB << sumMassTotal << token::TAB
<< sumMassFlux<< endl;
}
}
Info<< endl;
......@@ -125,14 +171,12 @@ void Foam::FacePostProcessing<CloudType>::write()
// Put in undecomposed case (Note: gives problems for
// distributed data running)
outputDir =
outputDir/".."/"postProcessing"/cloud::prefix/
this->owner().name()/mesh.time().timeName();
outputDir/".."/"postProcessing"/cloud::prefix/time.timeName();
}
else
{
outputDir =
outputDir/"postProcessing"/cloud::prefix/
this->owner().name()/mesh.time().timeName();
outputDir/"postProcessing"/cloud::prefix/time.timeName();
}
forAll(faceZoneIDs_, zoneI)
......@@ -247,15 +291,36 @@ Foam::FacePostProcessing<CloudType>::FacePostProcessing
totalTime_(0.0),
mass_(),
massTotal_(),
massFlux_()
massFlux_(),
log_(this->coeffDict().lookup("log")),
outputFilePtr_(),
outputDir_(owner.mesh().time().path())
{
wordList faceZoneNames(this->coeffDict().lookup("faceZones"));
mass_.setSize(faceZoneNames.size());
massTotal_.setSize(faceZoneNames.size());
massFlux_.setSize(faceZoneNames.size());
outputFilePtr_.setSize(faceZoneNames.size());
if (Pstream::parRun())
{
// Put in undecomposed case (Note: gives problems for
// distributed data running)
outputDir_ =
outputDir_/".."/"postProcessing"/cloud::prefix/
owner.name()/owner.mesh().time().timeName();
}
else
{
outputDir_ =
outputDir_/"postProcessing"/cloud::prefix/
owner.name()/owner.mesh().time().timeName();
}
DynamicList<label> zoneIDs;
const faceZoneMesh& fzm = owner.mesh().faceZones();
const surfaceScalarField& magSf = owner.mesh().magSf();
forAll(faceZoneNames, i)
{
const word& zoneName = faceZoneNames[i];
......@@ -269,6 +334,15 @@ Foam::FacePostProcessing<CloudType>::FacePostProcessing
massTotal_[i].setSize(nFaces, 0.0);
massFlux_[i].setSize(nFaces, 0.0);
Info<< " " << zoneName << " faces: " << nFaces;
scalar totArea = 0.0;
forAll(fz, j)
{
totArea += magSf[fz[j]];
}
totArea = returnReduce(totArea, sumOp<scalar>());
makeLogFile(zoneName, i, nFaces, totArea);
}
}
......@@ -291,7 +365,10 @@ Foam::FacePostProcessing<CloudType>::FacePostProcessing
totalTime_(pff.totalTime_),
mass_(pff.mass_),
massTotal_(pff.massTotal_),
massFlux_(pff.massFlux_)
massFlux_(pff.massFlux_),
log_(pff.log_),
outputFilePtr_(),
outputDir_(pff.outputDir_)
{}
......
......@@ -85,9 +85,27 @@ class FacePostProcessing
//- Mass flux storage
List<scalarField> massFlux_;
//- Flag to indicate whether data should be written to file
Switch log_;
//- Output file pointer per zone
PtrList<OFstream> outputFilePtr_;
//- Output directory
fileName outputDir_;
// Private Member Functions
//- Helper function to create log files
void makeLogFile
(
const word& zoneName,
const label zoneI,
const label nFaces,
const scalar totArea
);
//- Return index into storage lists if valid zone and face
void applyToFace
(
......
......@@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2008-2010 OpenCFD Ltd.
\\ / A nd | Copyright (C) 2008-2011 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
......@@ -92,12 +92,14 @@ Foam::PairSpringSliderDashpot<CloudType>::PairSpringSliderDashpot
alpha_(readScalar(this->coeffDict().lookup("alpha"))),
b_(readScalar(this->coeffDict().lookup("b"))),
mu_(readScalar(this->coeffDict().lookup("mu"))),
cohesionEnergyDensity_
(
readScalar(this->coeffDict().lookup("cohesionEnergyDensity"))
),
cohesion_(false),
collisionResolutionSteps_
(
readScalar
(
this->coeffDict().lookup("collisionResolutionSteps")
)
readScalar(this->coeffDict().lookup("collisionResolutionSteps"))
),
volumeFactor_(1.0),
useEquivalentSize_(Switch(this->coeffDict().lookup("useEquivalentSize")))
......@@ -116,6 +118,8 @@ Foam::PairSpringSliderDashpot<CloudType>::PairSpringSliderDashpot
scalar G = E/(2.0*(1.0 + nu));
Gstar_ = G/(2.0*(2.0 - nu));
cohesion_ = (mag(cohesionEnergyDensity_) > VSMALL);
}
......@@ -183,13 +187,15 @@ void Foam::PairSpringSliderDashpot<CloudType>::evaluatePair
dBEff *= cbrt(pB.nParticle()*volumeFactor_);
}
scalar normalOverlapMag = 0.5*(dAEff + dBEff) - mag(r_AB);
scalar r_AB_mag = mag(r_AB);
scalar normalOverlapMag = 0.5*(dAEff + dBEff) - r_AB_mag;
if (normalOverlapMag > 0)
{
//Particles in collision
vector rHat_AB = r_AB/(mag(r_AB) + VSMALL);
vector rHat_AB = r_AB/(r_AB_mag + VSMALL);
vector U_AB = pA.U() - pB.U();
......@@ -208,6 +214,15 @@ void Foam::PairSpringSliderDashpot<CloudType>::evaluatePair
rHat_AB
*(kN*pow(normalOverlapMag, b_) - etaN*(U_AB & rHat_AB));
// Cohesion force
if (cohesion_)
{
fN_AB +=
-cohesionEnergyDensity_
*overlapArea(dAEff/2.0, dBEff/2.0, r_AB_mag)
*rHat_AB;
}
pA.f() += fN_AB;
pB.f() += -fN_AB;
......
......@@ -34,6 +34,7 @@ Description
#include "PairModel.H"
#include "CollisionRecordList.H"
#include "mathematicalConstants.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
......@@ -67,6 +68,12 @@ class PairSpringSliderDashpot
//- Coefficient of friction in for tangential sliding
scalar mu_;
//- Cohesion energy density [J/m^3]
scalar cohesionEnergyDensity_;
// Switch cohesion on and off
bool cohesion_;
//- The number of steps over which to resolve the minimum
// harmonic approximation of the collision period
scalar collisionResolutionSteps_;
......@@ -129,6 +136,23 @@ public:
return volumeFactor_;
}
// Return the area of overlap between two spheres of radii rA and rB,
// centres separated by a distance rAB. Assumes rAB < (rA + rB).
inline scalar overlapArea(scalar rA, scalar rB, scalar rAB) const
{
// From:
// http://mathworld.wolfram.com/Sphere-SphereIntersection.html
return
mathematical::pi/4.0
/sqr(rAB)
*(
(-rAB + rA - rB)
*(-rAB - rA + rB)
*(-rAB + rA + rB)
*( rAB + rA + rA)
);
}
//- Whether the PairModel has a timestep limit that will
// require subCycling
virtual bool controlsTimestep() const;
......
......@@ -6,6 +6,6 @@ derivedFvPatchFields/temperatureCoupledBase/temperatureCoupledBase.C
derivedFvPatchFields/turbulentTemperatureCoupledBaffle/turbulentTemperatureCoupledBaffleFvPatchScalarField.C
derivedFvPatchFields/turbulentTemperatureCoupledBaffleMixed/turbulentTemperatureCoupledBaffleMixedFvPatchScalarField.C
derivedFvPatchFields/turbulentTemperatureCoupledBaffle/regionProperties.C
derivedFvPatchFields/temperatureThermoBaffle1D/temperatureThermoBaffle1DFvPatchScalarFields.C
LIB = $(FOAM_LIBBIN)/libcompressibleTurbulenceModel
......@@ -4,12 +4,14 @@ EXE_INC = \
-I$(LIB_SRC)/turbulenceModels \
-I$(LIB_SRC)/thermophysicalModels/basic/lnInclude \
-I$(LIB_SRC)/thermophysicalModels/specie/lnInclude \
-I$(LIB_SRC)/thermophysicalModels/basicSolidThermo/lnInclude
-I$(LIB_SRC)/thermophysicalModels/basicSolidThermo/lnInclude \
-I$(LIB_SRC)/thermophysicalModels/solid/lnInclude
LIB_LIBS = \
-lbasicSolidThermo \
-lbasicThermophysicalModels \
-lspecie \
-lfiniteVolume \
-lmeshTools
-lmeshTools \
-lsolid
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2011 OpenCFD Ltd.
\\/ 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 "volFields.H"
#include "surfaceFields.H"
#include "directMappedPatchBase.H"
#include "turbulenceModel.H"
#include "mapDistribute.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
namespace compressible
{
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
template<class solidType>
temperatureThermoBaffle1DFvPatchScalarField<solidType>::
temperatureThermoBaffle1DFvPatchScalarField
(
const fvPatch& p,
const DimensionedField<scalar, volMesh>& iF
)
:
mixedFvPatchScalarField(p, iF),
TName_("T"),
baffleActivated_(true),
thickness_(p.size()),
Qs_(p.size()),
solid_(NULL)
{}
template<class solidType>
temperatureThermoBaffle1DFvPatchScalarField<solidType>::
temperatureThermoBaffle1DFvPatchScalarField
(
const temperatureThermoBaffle1DFvPatchScalarField& ptf,
const fvPatch& p,
const DimensionedField<scalar, volMesh>& iF,
const fvPatchFieldMapper& mapper
)
:
mixedFvPatchScalarField(ptf, p, iF, mapper),
TName_(ptf.TName_),
baffleActivated_(ptf.baffleActivated_),
thickness_(ptf.thickness_),
Qs_(ptf.Qs_),
solid_(ptf.solid_)
{}
template<class solidType>
temperatureThermoBaffle1DFvPatchScalarField<solidType>::
temperatureThermoBaffle1DFvPatchScalarField
(
const fvPatch& p,
const DimensionedField<scalar, volMesh>& iF,
const dictionary& dict
)
:
mixedFvPatchScalarField(p, iF),
TName_("T"),
baffleActivated_(readBool(dict.lookup("baffleActivated"))),
thickness_(scalarField("thickness", dict, p.size())),
Qs_(scalarField("Qs", dict, p.size())),
solid_(new solidThermoData(dict))
{
if (!isA<directMappedPatchBase>(this->patch().patch()))
{
FatalErrorIn
(
"temperatureThermoBaffle1DFvPatchScalarField::"
"temperatureThermoBaffle1DFvPatchScalarField\n"
"(\n"
" const fvPatch& p,\n"
" const DimensionedField<scalar, volMesh>& iF,\n"
" const dictionary& dict\n"
")\n"
) << "\n patch type '" << patch().type()
<< "' not type '" << directMappedPatchBase::typeName << "'"
<< "\n for patch " << patch().name()
<< " of field " << dimensionedInternalField().name()
<< " in file " << dimensionedInternalField().objectPath()
<< exit(FatalError);
}
fvPatchScalarField::operator=(scalarField("value", dict, p.size()));
if (dict.found("refValue") && baffleActivated_)
{
// Full restart
refValue() = scalarField("refValue", dict, p.size());
refGrad() = scalarField("refGradient", dict, p.size());
valueFraction() = scalarField("valueFraction", dict, p.size());
}
else
{
// Start from user entered data. Assume zeroGradient.