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

This commit is contained in:
Sergio Ferraris
2013-10-23 10:42:46 +01:00
305 changed files with 240731 additions and 2391 deletions

View File

@ -0,0 +1,8 @@
#!/bin/sh
cd ${0%/*} || exit 1 # run from this directory
set -x
wclean libso multiphaseMixtureThermo
wclean
# ----------------------------------------------------------------- end-of-file

View File

@ -0,0 +1,8 @@
#!/bin/sh
cd ${0%/*} || exit 1 # run from this directory
set -x
wmake libso multiphaseMixtureThermo
wmake
# ----------------------------------------------------------------- end-of-file

View File

@ -0,0 +1,3 @@
compressibleMultiphaseInterFoam.C
EXE = $(FOAM_APPBIN)/compressibleMultiphaseInterFoam

View File

@ -0,0 +1,17 @@
EXE_INC = \
-ImultiphaseMixtureThermo/lnInclude \
-I$(LIB_SRC)/thermophysicalModels/basic/lnInclude \
-I$(LIB_SRC)/transportModels/twoPhaseMixture/lnInclude \
-I$(LIB_SRC)/transportModels/interfaceProperties/lnInclude \
-I$(LIB_SRC)/turbulenceModels/compressible/turbulenceModel \
-I$(LIB_SRC)/finiteVolume/lnInclude
EXE_LIBS = \
-lmultiphaseMixtureThermo \
-lfluidThermophysicalModels \
-lspecie \
-linterfaceProperties \
-lcompressibleTurbulenceModel \
-lcompressibleRASModels \
-lcompressibleLESModels \
-lfiniteVolume

View File

@ -0,0 +1,17 @@
{
fvScalarMatrix TEqn
(
fvm::ddt(rho, T)
+ fvm::div(multiphaseProperties.rhoPhi(), T)
- fvm::laplacian(multiphaseProperties.alphaEff(turbulence->mut()), T)
+ (
fvc::div(fvc::absolute(phi, U), p)
+ fvc::ddt(rho, K) + fvc::div(multiphaseProperties.rhoPhi(), K)
)*multiphaseProperties.rCv()
);
TEqn.relax();
TEqn.solve();
multiphaseProperties.correct();
}

View File

@ -0,0 +1,27 @@
fvVectorMatrix UEqn
(
fvm::ddt(rho, U)
+ fvm::div(multiphaseProperties.rhoPhi(), U)
+ turbulence->divDevRhoReff(U)
);
UEqn.relax();
if (pimple.momentumPredictor())
{
solve
(
UEqn
==
fvc::reconstruct
(
(
multiphaseProperties.surfaceTensionForce()
- ghf*fvc::snGrad(rho)
- fvc::snGrad(p_rgh)
) * mesh.magSf()
)
);
K = 0.5*magSqr(U);
}

View File

@ -0,0 +1,57 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2013 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
CourantNo
Description
Calculates and outputs the mean and maximum Courant Numbers.
\*---------------------------------------------------------------------------*/
scalar maxAlphaCo
(
readScalar(runTime.controlDict().lookup("maxAlphaCo"))
);
scalar alphaCoNum = 0.0;
scalar meanAlphaCoNum = 0.0;
if (mesh.nInternalFaces())
{
scalarField sumPhi
(
multiphaseProperties.nearInterface()().internalField()
* fvc::surfaceSum(mag(phi))().internalField()
);
alphaCoNum = 0.5*gMax(sumPhi/mesh.V().field())*runTime.deltaTValue();
meanAlphaCoNum =
0.5*(gSum(sumPhi)/gSum(mesh.V().field()))*runTime.deltaTValue();
}
Info<< "Interface Courant Number mean: " << meanAlphaCoNum
<< " max: " << alphaCoNum << endl;
// ************************************************************************* //

View File

@ -0,0 +1,111 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2013 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
compressibleMultiphaseInterFoam
Description
Solver for n compressible, non-isothermal immiscible fluids using a VOF
(volume of fluid) phase-fraction based interface capturing approach.
The momentum and other fluid properties are of the "mixture" and a single
momentum equation is solved.
Turbulence modelling is generic, i.e. laminar, RAS or LES may be selected.
\*---------------------------------------------------------------------------*/
#include "fvCFD.H"
#include "multiphaseMixtureThermo.H"
#include "turbulenceModel.H"
#include "pimpleControl.H"
#include "fixedFluxPressureFvPatchScalarField.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
int main(int argc, char *argv[])
{
#include "setRootCase.H"
#include "createTime.H"
#include "createMesh.H"
#include "readGravitationalAcceleration.H"
pimpleControl pimple(mesh);
#include "readTimeControls.H"
#include "initContinuityErrs.H"
#include "createFields.H"
#include "CourantNo.H"
#include "setInitialDeltaT.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
Info<< "\nStarting time loop\n" << endl;
while (runTime.run())
{
#include "readTimeControls.H"
#include "CourantNo.H"
#include "alphaCourantNo.H"
#include "setDeltaT.H"
runTime++;
Info<< "Time = " << runTime.timeName() << nl << endl;
// --- Pressure-velocity PIMPLE corrector loop
while (pimple.loop())
{
multiphaseProperties.solve();
solve(fvm::ddt(rho) + fvc::div(multiphaseProperties.rhoPhi()));
#include "UEqn.H"
#include "TEqn.H"
// --- Pressure corrector loop
while (pimple.correct())
{
#include "pEqn.H"
}
if (pimple.turbCorr())
{
turbulence->correct();
}
}
runTime.write();
Info<< "ExecutionTime = " << runTime.elapsedCpuTime() << " s"
<< " ClockTime = " << runTime.elapsedClockTime() << " s"
<< nl << endl;
}
Info<< "End\n" << endl;
return 0;
}
// ************************************************************************* //

View File

@ -0,0 +1,71 @@
Info<< "Reading field p_rgh\n" << endl;
volScalarField p_rgh
(
IOobject
(
"p_rgh",
runTime.timeName(),
mesh,
IOobject::MUST_READ,
IOobject::AUTO_WRITE
),
mesh
);
Info<< "Reading field U\n" << endl;
volVectorField U
(
IOobject
(
"U",
runTime.timeName(),
mesh,
IOobject::MUST_READ,
IOobject::AUTO_WRITE
),
mesh
);
#include "createPhi.H"
Info<< "Constructing multiphaseMixtureThermo\n" << endl;
multiphaseMixtureThermo multiphaseProperties(U, phi);
volScalarField& p = multiphaseProperties.p();
volScalarField& T = multiphaseProperties.T();
volScalarField rho
(
IOobject
(
"rho",
runTime.timeName(),
mesh,
IOobject::READ_IF_PRESENT
),
multiphaseProperties.rho()
);
Info<< max(rho) << min(rho);
dimensionedScalar pMin(multiphaseProperties.lookup("pMin"));
Info<< "Calculating field g.h\n" << endl;
volScalarField gh("gh", g & mesh.C());
surfaceScalarField ghf("ghf", g & mesh.Cf());
// Construct compressible turbulence model
autoPtr<compressible::turbulenceModel> turbulence
(
compressible::turbulenceModel::New
(
rho,
U,
multiphaseProperties.rhoPhi(),
multiphaseProperties
)
);
Info<< "Creating field kinetic energy K\n" << endl;
volScalarField K("K", 0.5*magSqr(U));

View File

@ -0,0 +1,5 @@
phaseModel/phaseModel.C
alphaContactAngle/alphaContactAngleFvPatchScalarField.C
multiphaseMixtureThermo.C
LIB = $(FOAM_LIBBIN)/libmultiphaseMixtureThermo

View File

@ -0,0 +1,8 @@
EXE_INC = \
-I$(LIB_SRC)/thermophysicalModels/basic/lnInclude \
-I$(LIB_SRC)/finiteVolume/lnInclude
LIB_LIBS = \
-lfluidThermophysicalModels \
-lspecie \
-lfiniteVolume

View File

@ -0,0 +1,146 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2013 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 "alphaContactAngleFvPatchScalarField.H"
#include "addToRunTimeSelectionTable.H"
#include "fvPatchFieldMapper.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
alphaContactAngleFvPatchScalarField::interfaceThetaProps::interfaceThetaProps
(
Istream& is
)
:
theta0_(readScalar(is)),
uTheta_(readScalar(is)),
thetaA_(readScalar(is)),
thetaR_(readScalar(is))
{}
Istream& operator>>
(
Istream& is,
alphaContactAngleFvPatchScalarField::interfaceThetaProps& tp
)
{
is >> tp.theta0_ >> tp.uTheta_ >> tp.thetaA_ >> tp.thetaR_;
return is;
}
Ostream& operator<<
(
Ostream& os,
const alphaContactAngleFvPatchScalarField::interfaceThetaProps& tp
)
{
os << tp.theta0_ << token::SPACE
<< tp.uTheta_ << token::SPACE
<< tp.thetaA_ << token::SPACE
<< tp.thetaR_;
return os;
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
alphaContactAngleFvPatchScalarField::alphaContactAngleFvPatchScalarField
(
const fvPatch& p,
const DimensionedField<scalar, volMesh>& iF
)
:
zeroGradientFvPatchScalarField(p, iF)
{}
alphaContactAngleFvPatchScalarField::alphaContactAngleFvPatchScalarField
(
const alphaContactAngleFvPatchScalarField& gcpsf,
const fvPatch& p,
const DimensionedField<scalar, volMesh>& iF,
const fvPatchFieldMapper& mapper
)
:
zeroGradientFvPatchScalarField(gcpsf, p, iF, mapper),
thetaProps_(gcpsf.thetaProps_)
{}
alphaContactAngleFvPatchScalarField::alphaContactAngleFvPatchScalarField
(
const fvPatch& p,
const DimensionedField<scalar, volMesh>& iF,
const dictionary& dict
)
:
zeroGradientFvPatchScalarField(p, iF),
thetaProps_(dict.lookup("thetaProperties"))
{
evaluate();
}
alphaContactAngleFvPatchScalarField::alphaContactAngleFvPatchScalarField
(
const alphaContactAngleFvPatchScalarField& gcpsf,
const DimensionedField<scalar, volMesh>& iF
)
:
zeroGradientFvPatchScalarField(gcpsf, iF),
thetaProps_(gcpsf.thetaProps_)
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
void alphaContactAngleFvPatchScalarField::write(Ostream& os) const
{
fvPatchScalarField::write(os);
os.writeKeyword("thetaProperties")
<< thetaProps_ << token::END_STATEMENT << nl;
writeEntry("value", os);
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
makePatchTypeField
(
fvPatchScalarField,
alphaContactAngleFvPatchScalarField
);
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// ************************************************************************* //

View File

@ -0,0 +1,215 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2013 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/>.
Class
Foam::alphaContactAngleFvPatchScalarField
Description
Contact-angle boundary condition for multi-phase interface-capturing
simulations. Used in conjuction with multiphaseMixture.
SourceFiles
alphaContactAngleFvPatchScalarField.C
\*---------------------------------------------------------------------------*/
#ifndef alphaContactAngleFvPatchScalarField_H
#define alphaContactAngleFvPatchScalarField_H
#include "zeroGradientFvPatchFields.H"
#include "multiphaseMixtureThermo.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class alphaContactAngleFvPatch Declaration
\*---------------------------------------------------------------------------*/
class alphaContactAngleFvPatchScalarField
:
public zeroGradientFvPatchScalarField
{
public:
class interfaceThetaProps
{
//- Equilibrium contact angle
scalar theta0_;
//- Dynamic contact angle velocity scale
scalar uTheta_;
//- Limiting advancing contact angle
scalar thetaA_;
//- Limiting receeding contact angle
scalar thetaR_;
public:
// Constructors
interfaceThetaProps()
{}
interfaceThetaProps(Istream&);
// Member functions
//- Return the equilibrium contact angle theta0
scalar theta0(bool matched=true) const
{
if (matched) return theta0_;
else return 180.0 - theta0_;
}
//- Return the dynamic contact angle velocity scale
scalar uTheta() const
{
return uTheta_;
}
//- Return the limiting advancing contact angle
scalar thetaA(bool matched=true) const
{
if (matched) return thetaA_;
else return 180.0 - thetaA_;
}
//- Return the limiting receeding contact angle
scalar thetaR(bool matched=true) const
{
if (matched) return thetaR_;
else return 180.0 - thetaR_;
}
// IO functions
friend Istream& operator>>(Istream&, interfaceThetaProps&);
friend Ostream& operator<<(Ostream&, const interfaceThetaProps&);
};
typedef HashTable
<
interfaceThetaProps,
multiphaseMixtureThermo::interfacePair,
multiphaseMixtureThermo::interfacePair::hash
> thetaPropsTable;
private:
// Private data
thetaPropsTable thetaProps_;
public:
//- Runtime type information
TypeName("alphaContactAngle");
// Constructors
//- Construct from patch and internal field
alphaContactAngleFvPatchScalarField
(
const fvPatch&,
const DimensionedField<scalar, volMesh>&
);
//- Construct from patch, internal field and dictionary
alphaContactAngleFvPatchScalarField
(
const fvPatch&,
const DimensionedField<scalar, volMesh>&,
const dictionary&
);
//- Construct by mapping given alphaContactAngleFvPatchScalarField
// onto a new patch
alphaContactAngleFvPatchScalarField
(
const alphaContactAngleFvPatchScalarField&,
const fvPatch&,
const DimensionedField<scalar, volMesh>&,
const fvPatchFieldMapper&
);
//- Construct and return a clone
virtual tmp<fvPatchScalarField> clone() const
{
return tmp<fvPatchScalarField>
(
new alphaContactAngleFvPatchScalarField(*this)
);
}
//- Construct as copy setting internal field reference
alphaContactAngleFvPatchScalarField
(
const alphaContactAngleFvPatchScalarField&,
const DimensionedField<scalar, volMesh>&
);
//- Construct and return a clone setting internal field reference
virtual tmp<fvPatchScalarField> clone
(
const DimensionedField<scalar, volMesh>& iF
) const
{
return tmp<fvPatchScalarField>
(
new alphaContactAngleFvPatchScalarField(*this, iF)
);
}
// Member functions
//- Return the contact angle properties
const thetaPropsTable& thetaProps() const
{
return thetaProps_;
}
//- Write
virtual void write(Ostream&) const;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,434 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2013 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/>.
Class
Foam::multiphaseMixtureThermo
Description
SourceFiles
multiphaseMixtureThermo.C
\*---------------------------------------------------------------------------*/
#ifndef multiphaseMixtureThermo_H
#define multiphaseMixtureThermo_H
#include "phaseModel.H"
#include "PtrDictionary.H"
#include "volFields.H"
#include "surfaceFields.H"
#include "rhoThermo.H"
#include "psiThermo.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class multiphaseMixtureThermo Declaration
\*---------------------------------------------------------------------------*/
class multiphaseMixtureThermo
:
public psiThermo
{
public:
class interfacePair
:
public Pair<word>
{
public:
class hash
:
public Hash<interfacePair>
{
public:
hash()
{}
label operator()(const interfacePair& key) const
{
return word::hash()(key.first()) + word::hash()(key.second());
}
};
// Constructors
interfacePair()
{}
interfacePair(const word& alpha1Name, const word& alpha2Name)
:
Pair<word>(alpha1Name, alpha2Name)
{}
interfacePair(const phaseModel& alpha1, const phaseModel& alpha2)
:
Pair<word>(alpha1.name(), alpha2.name())
{}
// Friend Operators
friend bool operator==
(
const interfacePair& a,
const interfacePair& b
)
{
return
(
((a.first() == b.first()) && (a.second() == b.second()))
|| ((a.first() == b.second()) && (a.second() == b.first()))
);
}
friend bool operator!=
(
const interfacePair& a,
const interfacePair& b
)
{
return (!(a == b));
}
};
private:
// Private data
//- Dictionary of phases
PtrDictionary<phaseModel> phases_;
const fvMesh& mesh_;
const volVectorField& U_;
const surfaceScalarField& phi_;
surfaceScalarField rhoPhi_;
volScalarField alphas_;
typedef HashTable<scalar, interfacePair, interfacePair::hash>
sigmaTable;
sigmaTable sigmas_;
dimensionSet dimSigma_;
//- Stabilisation for normalisation of the interface normal
const dimensionedScalar deltaN_;
//- Conversion factor for degrees into radians
static const scalar convertToRad;
// Private member functions
void calcAlphas();
void solveAlphas(const scalar cAlpha);
tmp<surfaceVectorField> nHatfv
(
const volScalarField& alpha1,
const volScalarField& alpha2
) const;
tmp<surfaceScalarField> nHatf
(
const volScalarField& alpha1,
const volScalarField& alpha2
) const;
void correctContactAngle
(
const phaseModel& alpha1,
const phaseModel& alpha2,
surfaceVectorField::GeometricBoundaryField& nHatb
) const;
tmp<volScalarField> K
(
const phaseModel& alpha1,
const phaseModel& alpha2
) const;
public:
//- Runtime type information
TypeName("multiphaseMixtureThermo");
// Constructors
//- Construct from components
multiphaseMixtureThermo
(
const volVectorField& U,
const surfaceScalarField& phi
);
//- Destructor
virtual ~multiphaseMixtureThermo()
{}
// Member Functions
//- Return the phases
const PtrDictionary<phaseModel>& phases() const
{
return phases_;
}
//- Return non-const access to the phases
PtrDictionary<phaseModel>& phases()
{
return phases_;
}
//- Return the velocity
const volVectorField& U() const
{
return U_;
}
//- Return the volumetric flux
const surfaceScalarField& phi() const
{
return phi_;
}
const surfaceScalarField& rhoPhi() const
{
return rhoPhi_;
}
//- Update properties
virtual void correct();
//- Update densities for given pressure change
void correctRho(const volScalarField& dp);
//- Return true if the equation of state is incompressible
// i.e. rho != f(p)
virtual bool incompressible() const;
//- Return true if the equation of state is isochoric
// i.e. rho = const
virtual bool isochoric() const;
// Access to thermodynamic state variables
//- Enthalpy/Internal energy [J/kg]
// Non-const access allowed for transport equations
virtual volScalarField& he()
{
notImplemented("multiphaseMixtureThermo::he()");
return phases_[0]->thermo().he();
}
//- Enthalpy/Internal energy [J/kg]
virtual const volScalarField& he() const
{
notImplemented("multiphaseMixtureThermo::he() const");
return phases_[0]->thermo().he();
}
//- Enthalpy/Internal energy
// for given pressure and temperature [J/kg]
virtual tmp<volScalarField> he
(
const volScalarField& p,
const volScalarField& T
) const;
//- Enthalpy/Internal energy for cell-set [J/kg]
virtual tmp<scalarField> he
(
const scalarField& p,
const scalarField& T,
const labelList& cells
) const;
//- Enthalpy/Internal energy for patch [J/kg]
virtual tmp<scalarField> he
(
const scalarField& p,
const scalarField& T,
const label patchi
) const;
//- Chemical enthalpy [J/kg]
virtual tmp<volScalarField> hc() const;
//- Temperature from enthalpy/internal energy for cell-set
virtual tmp<scalarField> THE
(
const scalarField& h,
const scalarField& p,
const scalarField& T0, // starting temperature
const labelList& cells
) const;
//- Temperature from enthalpy/internal energy for patch
virtual tmp<scalarField> THE
(
const scalarField& h,
const scalarField& p,
const scalarField& T0, // starting temperature
const label patchi
) const;
// Fields derived from thermodynamic state variables
//- Density [kg/m^3]
virtual tmp<volScalarField> rho() const;
//- Heat capacity at constant pressure [J/kg/K]
virtual tmp<volScalarField> Cp() const;
//- Heat capacity at constant pressure for patch [J/kg/K]
virtual tmp<scalarField> Cp
(
const scalarField& p,
const scalarField& T,
const label patchi
) const;
//- Heat capacity at constant volume [J/kg/K]
virtual tmp<volScalarField> Cv() const;
//- Heat capacity at constant volume for patch [J/kg/K]
virtual tmp<scalarField> Cv
(
const scalarField& p,
const scalarField& T,
const label patchi
) const;
//- gamma = Cp/Cv []
virtual tmp<volScalarField> gamma() const;
//- gamma = Cp/Cv for patch []
virtual tmp<scalarField> gamma
(
const scalarField& p,
const scalarField& T,
const label patchi
) const;
//- Heat capacity at constant pressure/volume [J/kg/K]
virtual tmp<volScalarField> Cpv() const;
//- Heat capacity at constant pressure/volume for patch [J/kg/K]
virtual tmp<scalarField> Cpv
(
const scalarField& p,
const scalarField& T,
const label patchi
) const;
//- Heat capacity ratio []
virtual tmp<volScalarField> CpByCpv() const;
//- Heat capacity ratio for patch []
virtual tmp<scalarField> CpByCpv
(
const scalarField& p,
const scalarField& T,
const label patchi
) const;
// Fields derived from transport state variables
//- Thermal diffusivity for temperature of mixture [J/m/s/K]
virtual tmp<volScalarField> kappa() const;
//- Thermal diffusivity of mixture for patch [J/m/s/K]
virtual tmp<scalarField> kappa
(
const label patchi
) const;
//- Effective thermal diffusivity of mixture [J/m/s/K]
virtual tmp<volScalarField> kappaEff
(
const volScalarField& alphat
) const;
//- Effective thermal diffusivity of mixture for patch [J/m/s/K]
virtual tmp<scalarField> kappaEff
(
const scalarField& alphat,
const label patchi
) const;
//- Effective thermal diffusivity of mixture [J/m/s/K]
virtual tmp<volScalarField> alphaEff
(
const volScalarField& alphat
) const;
//- Effective thermal diffusivity of mixture for patch [J/m/s/K]
virtual tmp<scalarField> alphaEff
(
const scalarField& alphat,
const label patchi
) const;
//- Return the phase-averaged reciprocal Cv
tmp<volScalarField> rCv() const;
tmp<surfaceScalarField> surfaceTensionForce() const;
//- Indicator of the proximity of the interface
// Field values are 1 near and 0 away for the interface.
tmp<volScalarField> nearInterface() const;
//- Solve for the mixture phase-fractions
void solve();
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,95 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2013 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 "phaseModel.H"
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::phaseModel::phaseModel
(
const word& phaseName,
const volScalarField& p,
const volScalarField& T
)
:
volScalarField
(
IOobject
(
IOobject::groupName("alpha", phaseName),
p.mesh().time().timeName(),
p.mesh(),
IOobject::MUST_READ,
IOobject::AUTO_WRITE
),
p.mesh()
),
name_(phaseName),
p_(p),
T_(T),
thermo_(NULL),
dgdt_
(
IOobject
(
IOobject::groupName("dgdt", phaseName),
p.mesh().time().timeName(),
p.mesh(),
IOobject::READ_IF_PRESENT,
IOobject::AUTO_WRITE
),
p.mesh(),
dimensionedScalar("0", dimless/dimTime, 0)
)
{
{
volScalarField Tp(IOobject::groupName("T", phaseName), T);
Tp.write();
}
thermo_ = rhoThermo::New(p.mesh(), phaseName);
thermo_->validate(phaseName, "e");
correct();
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
Foam::autoPtr<Foam::phaseModel> Foam::phaseModel::clone() const
{
notImplemented("phaseModel::clone() const");
return autoPtr<phaseModel>(NULL);
}
void Foam::phaseModel::correct()
{
thermo_->he() = thermo_->he(p_, T_);
thermo_->correct();
}
// ************************************************************************* //

View File

@ -0,0 +1,156 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2013 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/>.
Class
Foam::phaseModel
Description
Single incompressible phase derived from the phase-fraction.
Used as part of the multiPhaseMixture for interface-capturing multi-phase
simulations.
SourceFiles
phaseModel.C
\*---------------------------------------------------------------------------*/
#ifndef phaseModel_H
#define phaseModel_H
#include "rhoThermo.H"
#include "volFields.H"
#include "dictionaryEntry.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class phaseModel Declaration
\*---------------------------------------------------------------------------*/
class phaseModel
:
public volScalarField
{
// Private data
word name_;
const volScalarField& p_;
const volScalarField& T_;
autoPtr<rhoThermo> thermo_;
volScalarField dgdt_;
public:
// Constructors
//- Construct from components
phaseModel
(
const word& phaseName,
const volScalarField& p,
const volScalarField& T
);
//- Return clone
autoPtr<phaseModel> clone() const;
//- Return a pointer to a new phaseModel created on freestore
// from Istream
class iNew
{
const volScalarField& p_;
const volScalarField& T_;
public:
iNew
(
const volScalarField& p,
const volScalarField& T
)
:
p_(p),
T_(T)
{}
autoPtr<phaseModel> operator()(Istream& is) const
{
return autoPtr<phaseModel>(new phaseModel(is, p_, T_));
}
};
// Member Functions
const word& name() const
{
return name_;
}
const word& keyword() const
{
return name();
}
//- Return const-access to phase rhoThermo
const rhoThermo& thermo() const
{
return thermo_();
}
//- Return access to phase rhoThermo
rhoThermo& thermo()
{
return thermo_();
}
//- Return const-access to phase divergence
const volScalarField& dgdt() const
{
return dgdt_;
}
//- Return access to phase divergence
volScalarField& dgdt()
{
return dgdt_;
}
void correct();
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,142 @@
{
volScalarField rAU("rAU", 1.0/UEqn.A());
surfaceScalarField rAUf("rAUf", fvc::interpolate(rAU));
volVectorField HbyA("HbyA", U);
HbyA = rAU*UEqn.H();
surfaceScalarField phiHbyA
(
"phiHbyA",
(fvc::interpolate(HbyA) & mesh.Sf())
+ fvc::interpolate(rho*rAU)*fvc::ddtCorr(U, phi)
);
surfaceScalarField phig
(
(
multiphaseProperties.surfaceTensionForce()
- ghf*fvc::snGrad(rho)
)*rAUf*mesh.magSf()
);
phiHbyA += phig;
// Update the fixedFluxPressure BCs to ensure flux consistency
setSnGrad<fixedFluxPressureFvPatchScalarField>
(
p_rgh.boundaryField(),
(
phiHbyA.boundaryField()
- (mesh.Sf().boundaryField() & U.boundaryField())
)/(mesh.magSf().boundaryField()*rAUf.boundaryField())
);
PtrList<fvScalarMatrix> p_rghEqnComps(multiphaseProperties.phases().size());
label phasei = 0;
forAllConstIter
(
PtrDictionary<phaseModel>,
multiphaseProperties.phases(),
phase
)
{
const rhoThermo& thermo = phase().thermo();
const volScalarField& rho = thermo.rho()();
p_rghEqnComps.set
(
phasei,
(
fvc::ddt(rho) + thermo.psi()*correction(fvm::ddt(p_rgh))
+ fvc::div(phi, rho) - fvc::Sp(fvc::div(phi), rho)
).ptr()
);
phasei++;
}
// Cache p_rgh prior to solve for density update
volScalarField p_rgh_0(p_rgh);
while (pimple.correctNonOrthogonal())
{
fvScalarMatrix p_rghEqnIncomp
(
fvc::div(phiHbyA)
- fvm::laplacian(rAUf, p_rgh)
);
tmp<fvScalarMatrix> p_rghEqnComp;
phasei = 0;
forAllConstIter
(
PtrDictionary<phaseModel>,
multiphaseProperties.phases(),
phase
)
{
tmp<fvScalarMatrix> hmm
(
(max(phase(), scalar(0))/phase().thermo().rho())
*p_rghEqnComps[phasei]
);
if (phasei == 0)
{
p_rghEqnComp = hmm;
}
else
{
p_rghEqnComp() += hmm;
}
phasei++;
}
solve
(
p_rghEqnComp
+ p_rghEqnIncomp,
mesh.solver(p_rgh.select(pimple.finalInnerIter()))
);
if (pimple.finalNonOrthogonalIter())
{
// p = max(p_rgh + multiphaseProperties.rho()*gh, pMin);
// p_rgh = p - multiphaseProperties.rho()*gh;
phasei = 0;
forAllIter
(
PtrDictionary<phaseModel>,
multiphaseProperties.phases(),
phase
)
{
phase().dgdt() =
pos(phase())
*(p_rghEqnComps[phasei] & p_rgh)/phase().thermo().rho();
}
phi = phiHbyA + p_rghEqnIncomp.flux();
U = HbyA
+ rAU*fvc::reconstruct((phig + p_rghEqnIncomp.flux())/rAUf);
U.correctBoundaryConditions();
}
}
p = max(p_rgh + multiphaseProperties.rho()*gh, pMin);
// Update densities from change in p_rgh
multiphaseProperties.correctRho(p_rgh - p_rgh_0);
rho = multiphaseProperties.rho();
K = 0.5*magSqr(U);
Info<< "max(U) " << max(mag(U)).value() << endl;
Info<< "min(p_rgh) " << min(p_rgh).value() << endl;
}

View File

@ -126,11 +126,25 @@ void Foam::multiphaseSystem::solveAlphas()
} }
// Ensure that the flux at inflow BCs is preserved // Ensure that the flux at inflow BCs is preserved
phiAlphaCorr.boundaryField() = min forAll(phiAlphaCorr.boundaryField(), patchi)
( {
phase1.phi().boundaryField()*alpha1.boundaryField(), fvsPatchScalarField& phiAlphaCorrp =
phiAlphaCorr.boundaryField() phiAlphaCorr.boundaryField()[patchi];
);
if (!phiAlphaCorrp.coupled())
{
const scalarField& phi1p = phase1.phi().boundaryField()[patchi];
const scalarField& alpha1p = alpha1.boundaryField()[patchi];
forAll(phiAlphaCorrp, facei)
{
if (phi1p[facei] < 0)
{
phiAlphaCorrp[facei] = alpha1p[facei]*phi1p[facei];
}
}
}
}
MULES::limit MULES::limit
( (

View File

@ -23,7 +23,7 @@
)/rho1 )/rho1
//***HGW- fvm::laplacian(alpha1*turbulence1->alphaEff(), he1) //***HGW- fvm::laplacian(alpha1*turbulence1->alphaEff(), he1)
- fvm::laplacian(alpha1*turbulence1->nuEff(), he1) - fvm::laplacian(alpha1*phase1.turbulence().nuEff(), he1)
== ==
heatTransferCoeff*(thermo2.T() - thermo1.T())/rho1 heatTransferCoeff*(thermo2.T() - thermo1.T())/rho1
+ heatTransferCoeff*he1/Cpv1/rho1 + heatTransferCoeff*he1/Cpv1/rho1
@ -46,7 +46,7 @@
)/rho2 )/rho2
//***HGW- fvm::laplacian(alpha2*turbulence2->alphaEff(), he2) //***HGW- fvm::laplacian(alpha2*turbulence2->alphaEff(), he2)
- fvm::laplacian(alpha2*turbulence2->nuEff(), he2) - fvm::laplacian(alpha2*phase2.turbulence().nuEff(), he2)
== ==
heatTransferCoeff*(thermo1.T() - thermo2.T())/rho2 heatTransferCoeff*(thermo1.T() - thermo2.T())/rho2
+ heatTransferCoeff*he2/Cpv2/rho2 + heatTransferCoeff*he2/Cpv2/rho2

View File

@ -26,7 +26,7 @@ volScalarField dragCoeff(fluid.dragCoeff());
- fvm::Sp(fvc::div(phi1), U1) - fvm::Sp(fvc::div(phi1), U1)
) )
+ turbulence1->divDevReff(U1) + phase1.turbulence().divDevReff(U1)
== ==
- fvm::Sp(dragCoeff/rho1, U1) - fvm::Sp(dragCoeff/rho1, U1)
- alpha1*alpha2/rho1*(liftForce - fluid.Cvm()*rho2*DDtU2) - alpha1*alpha2/rho1*(liftForce - fluid.Cvm()*rho2*DDtU2)
@ -50,7 +50,7 @@ volScalarField dragCoeff(fluid.dragCoeff());
+ fvm::div(phi2, U2) + fvm::div(phi2, U2)
- fvm::Sp(fvc::div(phi2), U2) - fvm::Sp(fvc::div(phi2), U2)
) )
+ turbulence2->divDevReff(U2) + phase2.turbulence().divDevReff(U2)
== ==
- fvm::Sp(dragCoeff/rho2, U2) - fvm::Sp(dragCoeff/rho2, U2)
+ alpha1*alpha2/rho2*(liftForce + fluid.Cvm()*rho2*DDtU1) + alpha1*alpha2/rho2*(liftForce + fluid.Cvm()*rho2*DDtU1)

View File

@ -1,165 +0,0 @@
{
word alphaScheme("div(phi," + alpha1.name() + ')');
word alpharScheme("div(phir," + alpha1.name() + ')');
alpha1.correctBoundaryConditions();
surfaceScalarField phic("phic", phi);
surfaceScalarField phir("phir", phi1 - phi2);
surfaceScalarField alpha1f(fvc::interpolate(max(alpha1, scalar(0))));
tmp<surfaceScalarField> pPrimeByA;
if (implicitPhasePressure)
{
pPrimeByA =
fvc::interpolate((1.0/rho1)*rAU1*turbulence1().pPrime())
+ fvc::interpolate((1.0/rho2)*rAU2*turbulence2().pPrime());
surfaceScalarField phiP
(
pPrimeByA()*fvc::snGrad(alpha1, "bounded")*mesh.magSf()
);
phic += alpha1f*phiP;
phir += phiP;
}
for (int acorr=0; acorr<nAlphaCorr; acorr++)
{
volScalarField::DimensionedInternalField Sp
(
IOobject
(
"Sp",
runTime.timeName(),
mesh
),
mesh,
dimensionedScalar("Sp", dgdt.dimensions(), 0.0)
);
volScalarField::DimensionedInternalField Su
(
IOobject
(
"Su",
runTime.timeName(),
mesh
),
// Divergence term is handled explicitly to be
// consistent with the explicit transport solution
fvc::div(phi)*min(alpha1, scalar(1))
);
forAll(dgdt, celli)
{
if (dgdt[celli] > 0.0 && alpha1[celli] > 0.0)
{
Sp[celli] -= dgdt[celli]*alpha1[celli];
Su[celli] += dgdt[celli]*alpha1[celli];
}
else if (dgdt[celli] < 0.0 && alpha1[celli] < 1.0)
{
Sp[celli] += dgdt[celli]*(1.0 - alpha1[celli]);
}
}
dimensionedScalar totalDeltaT = runTime.deltaT();
if (nAlphaSubCycles > 1)
{
alphaPhi1 = dimensionedScalar("0", alphaPhi1.dimensions(), 0);
}
for
(
subCycle<volScalarField> alphaSubCycle(alpha1, nAlphaSubCycles);
!(++alphaSubCycle).end();
)
{
surfaceScalarField alphaPhic1
(
fvc::flux
(
phic,
alpha1,
alphaScheme
)
+ fvc::flux
(
-fvc::flux(-phir, scalar(1) - alpha1, alpharScheme),
alpha1,
alpharScheme
)
);
// Ensure that the flux at inflow BCs is preserved
forAll(alphaPhic1.boundaryField(), patchi)
{
fvsPatchScalarField& alphaPhic1p =
alphaPhic1.boundaryField()[patchi];
if (!alphaPhic1p.coupled())
{
const scalarField& phi1p = phi1.boundaryField()[patchi];
const scalarField& alpha1p = alpha1.boundaryField()[patchi];
forAll(alphaPhic1p, facei)
{
if (phi1p[facei] < 0)
{
alphaPhic1p[facei] = alpha1p[facei]*phi1p[facei];
}
}
}
}
MULES::explicitSolve
(
geometricOneField(),
alpha1,
phi,
alphaPhic1,
Sp,
Su,
1,
0
);
if (nAlphaSubCycles > 1)
{
alphaPhi1 += (runTime.deltaT()/totalDeltaT)*alphaPhic1;
}
else
{
alphaPhi1 = alphaPhic1;
}
}
if (implicitPhasePressure)
{
fvScalarMatrix alpha1Eqn
(
fvm::ddt(alpha1) - fvc::ddt(alpha1)
- fvm::laplacian(alpha1f*pPrimeByA, alpha1, "bounded")
);
alpha1Eqn.relax();
alpha1Eqn.solve();
alphaPhi1 += alpha1Eqn.flux();
}
alphaPhi2 = phi - alphaPhi1;
alpha2 = scalar(1) - alpha1;
Info<< "Dispersed phase volume fraction = "
<< alpha1.weightedAverage(mesh.V()).value()
<< " Min(alpha1) = " << min(alpha1).value()
<< " Max(alpha1) = " << max(alpha1).value()
<< endl;
}
}
rho = fluid.rho();

View File

@ -10,19 +10,13 @@
volVectorField& U1 = phase1.U(); volVectorField& U1 = phase1.U();
surfaceScalarField& phi1 = phase1.phi(); surfaceScalarField& phi1 = phase1.phi();
surfaceScalarField alphaPhi1 surfaceScalarField& alphaPhi1 = phase1.phiAlpha();
(
IOobject::groupName("alphaPhi", phase1.name()),
fvc::interpolate(alpha1)*phi1
);
volVectorField& U2 = phase2.U(); volVectorField& U2 = phase2.U();
surfaceScalarField& phi2 = phase2.phi(); surfaceScalarField& phi2 = phase2.phi();
surfaceScalarField alphaPhi2 surfaceScalarField& alphaPhi2 = phase2.phiAlpha();
(
IOobject::groupName("alphaPhi", phase2.name()), surfaceScalarField& phi = fluid.phi();
fvc::interpolate(alpha2)*phi2
);
dimensionedScalar pMin dimensionedScalar pMin
( (
@ -55,19 +49,6 @@
fluid.U() fluid.U()
); );
surfaceScalarField phi
(
IOobject
(
"phi",
runTime.timeName(),
mesh,
IOobject::NO_READ,
IOobject::AUTO_WRITE
),
fluid.phi()
);
volScalarField rho volScalarField rho
( (
IOobject IOobject
@ -97,10 +78,6 @@
- fvc::div(phi2)*U2 - fvc::div(phi2)*U2
); );
Info<< "Calculating field g.h\n" << endl;
volScalarField gh("gh", g & mesh.C());
volScalarField rAU1 volScalarField rAU1
( (
IOobject IOobject
@ -133,13 +110,6 @@
scalar pRefValue = 0.0; scalar pRefValue = 0.0;
setRefCell(p, mesh.solutionDict().subDict("PIMPLE"), pRefCell, pRefValue); setRefCell(p, mesh.solutionDict().subDict("PIMPLE"), pRefCell, pRefValue);
volScalarField dgdt
(
pos(alpha2)*fvc::div(phi)/max(alpha2, scalar(0.0001))
);
Info<< "Creating field dpdt\n" << endl; Info<< "Creating field dpdt\n" << endl;
volScalarField dpdt volScalarField dpdt
( (
@ -157,29 +127,3 @@
Info<< "Creating field kinetic energy K\n" << endl; Info<< "Creating field kinetic energy K\n" << endl;
volScalarField K1(IOobject::groupName("K", phase1.name()), 0.5*magSqr(U1)); volScalarField K1(IOobject::groupName("K", phase1.name()), 0.5*magSqr(U1));
volScalarField K2(IOobject::groupName("K", phase2.name()), 0.5*magSqr(U2)); volScalarField K2(IOobject::groupName("K", phase2.name()), 0.5*magSqr(U2));
autoPtr<PhaseIncompressibleTurbulenceModel<phaseModel> >
turbulence1
(
PhaseIncompressibleTurbulenceModel<phaseModel>::New
(
alpha1,
U1,
alphaPhi1,
phi1,
phase1
)
);
autoPtr<PhaseIncompressibleTurbulenceModel<phaseModel> >
turbulence2
(
PhaseIncompressibleTurbulenceModel<phaseModel>::New
(
alpha2,
U2,
alphaPhi2,
phi2,
phase2
)
);

View File

@ -31,17 +31,19 @@
surfaceScalarField phiP1 surfaceScalarField phiP1
( (
"phiP1", "phiP1",
fvc::interpolate((1.0/rho1)*rAU1*turbulence1().pPrime()) fvc::interpolate((1.0/rho1)*rAU1*phase1.turbulence().pPrime())
*fvc::snGrad(alpha1)*mesh.magSf() *fvc::snGrad(alpha1)*mesh.magSf()
); );
phiP1.boundaryField() == 0;
// Phase-2 pressure flux (e.g. due to particle-particle pressure) // Phase-2 pressure flux (e.g. due to particle-particle pressure)
surfaceScalarField phiP2 surfaceScalarField phiP2
( (
"phiP2", "phiP2",
fvc::interpolate((1.0/rho2)*rAU2*turbulence2().pPrime()) fvc::interpolate((1.0/rho2)*rAU2*phase2.turbulence().pPrime())
*fvc::snGrad(alpha2)*mesh.magSf() *fvc::snGrad(alpha2)*mesh.magSf()
); );
phiP2.boundaryField() == 0;
surfaceScalarField phiHbyA1 surfaceScalarField phiHbyA1
( (
@ -126,9 +128,11 @@
); );
pEqnComp1 = pEqnComp1 =
fvc::ddt(rho1) (
+ fvc::div(phi1, rho1) - fvc::Sp(fvc::div(phi1), rho1) fvc::ddt(alpha1, rho1) + fvc::div(alphaPhi1, rho1)
+ correction - fvc::Sp(fvc::ddt(alpha1) + fvc::div(alphaPhi1), rho1)
)/rho1
+ (alpha1/rho1)*correction
( (
psi1*fvm::ddt(p) psi1*fvm::ddt(p)
+ fvm::div(phid1, p) - fvm::Sp(fvc::div(phid1), p) + fvm::div(phid1, p) - fvm::Sp(fvc::div(phid1), p)
@ -137,9 +141,11 @@
pEqnComp1().relax(); pEqnComp1().relax();
pEqnComp2 = pEqnComp2 =
fvc::ddt(rho2) (
+ fvc::div(phi2, rho2) - fvc::Sp(fvc::div(phi2), rho2) fvc::ddt(alpha2, rho2) + fvc::div(alphaPhi2, rho2)
+ correction - fvc::Sp(fvc::ddt(alpha2) + fvc::div(alphaPhi2), rho2)
)/rho2
+ (alpha2/rho2)*correction
( (
psi2*fvm::ddt(p) psi2*fvm::ddt(p)
+ fvm::div(phid2, p) - fvm::Sp(fvc::div(phid2), p) + fvm::div(phid2, p) - fvm::Sp(fvc::div(phid2), p)
@ -150,12 +156,18 @@
else else
{ {
pEqnComp1 = pEqnComp1 =
fvc::ddt(rho1) + psi1*correction(fvm::ddt(p)) (
+ fvc::div(phi1, rho1) - fvc::Sp(fvc::div(phi1), rho1); fvc::ddt(alpha1, rho1) + fvc::div(alphaPhi1, rho1)
- fvc::Sp(fvc::ddt(alpha1) + fvc::div(alphaPhi1), rho1)
)/rho1
+ (alpha1*psi1/rho1)*correction(fvm::ddt(p));
pEqnComp2 = pEqnComp2 =
fvc::ddt(rho2) + psi2*correction(fvm::ddt(p)) (
+ fvc::div(phi2, rho2) - fvc::Sp(fvc::div(phi2), rho2); fvc::ddt(alpha2, rho2) + fvc::div(alphaPhi2, rho2)
- fvc::Sp(fvc::ddt(alpha2) + fvc::div(alphaPhi2), rho2)
)/rho2
+ (alpha2*psi2/rho2)*correction(fvm::ddt(p));
} }
// Cache p prior to solve for density update // Cache p prior to solve for density update
@ -171,11 +183,7 @@
solve solve
( (
( pEqnComp1() + pEqnComp2() + pEqnIncomp,
(alpha1/rho1)*pEqnComp1()
+ (alpha2/rho2)*pEqnComp2()
)
+ pEqnIncomp,
mesh.solver(p.select(pimple.finalInnerIter())) mesh.solver(p.select(pimple.finalInnerIter()))
); );
@ -199,10 +207,10 @@
phi = alpha1f*phi1 + alpha2f*phi2; phi = alpha1f*phi1 + alpha2f*phi2;
dgdt = fluid.dgdt() =
( (
pos(alpha2)*(pEqnComp2 & p)/rho2 pos(alpha2)*(pEqnComp2 & p)/max(alpha2, scalar(1e-3))
- pos(alpha1)*(pEqnComp1 & p)/rho1 - pos(alpha1)*(pEqnComp1 & p)/max(alpha1, scalar(1e-3))
); );
p.relax(); p.relax();

View File

@ -1,7 +0,0 @@
#include "readTimeControls.H"
#include "alphaControls.H"
Switch implicitPhasePressure
(
alphaControls.lookupOrDefault<Switch>("implicitPhasePressure", false)
);

View File

@ -31,13 +31,10 @@ Description
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#include "fvCFD.H" #include "fvCFD.H"
#include "MULES.H"
#include "subCycle.H"
#include "rhoThermo.H"
#include "twoPhaseSystem.H" #include "twoPhaseSystem.H"
#include "PhaseIncompressibleTurbulenceModel.H"
#include "dragModel.H" #include "dragModel.H"
#include "heatTransferModel.H" #include "heatTransferModel.H"
#include "PhaseIncompressibleTurbulenceModel.H"
#include "pimpleControl.H" #include "pimpleControl.H"
#include "IOMRFZoneList.H" #include "IOMRFZoneList.H"
#include "fixedFluxPressureFvPatchScalarField.H" #include "fixedFluxPressureFvPatchScalarField.H"
@ -66,7 +63,7 @@ int main(int argc, char *argv[])
while (runTime.run()) while (runTime.run())
{ {
#include "readTwoPhaseEulerFoamControls.H" #include "readTimeControls.H"
#include "CourantNos.H" #include "CourantNos.H"
#include "setDeltaT.H" #include "setDeltaT.H"
@ -76,7 +73,10 @@ int main(int argc, char *argv[])
// --- Pressure-velocity PIMPLE corrector loop // --- Pressure-velocity PIMPLE corrector loop
while (pimple.loop()) while (pimple.loop())
{ {
#include "alphaEqn.H" fluid.solve();
rho = fluid.rho();
fluid.correct();
#include "EEqns.H" #include "EEqns.H"
#include "UEqns.H" #include "UEqns.H"
@ -90,8 +90,7 @@ int main(int argc, char *argv[])
if (pimple.turbCorr()) if (pimple.turbCorr())
{ {
turbulence1->correct(); fluid.correctTurbulence();
turbulence2->correct();
} }
} }

View File

@ -4,6 +4,12 @@ diameterModels/diameterModel/newDiameterModel.C
diameterModels/constantDiameter/constantDiameter.C diameterModels/constantDiameter/constantDiameter.C
diameterModels/isothermalDiameter/isothermalDiameter.C diameterModels/isothermalDiameter/isothermalDiameter.C
diameterModels/IATE/IATE.C
diameterModels/IATE/IATEsources/IATEsource/IATEsource.C
diameterModels/IATE/IATEsources/wakeEntrainmentCoalescence/wakeEntrainmentCoalescence.C
diameterModels/IATE/IATEsources/turbulentBreakUp/turbulentBreakUp.C
diameterModels/IATE/IATEsources/randomCoalescence/randomCoalescence.C
twoPhaseSystem.C twoPhaseSystem.C
LIB = $(FOAM_LIBBIN)/libcompressibleTwoPhaseSystem LIB = $(FOAM_LIBBIN)/libcompressibleTwoPhaseSystem

View File

@ -3,7 +3,10 @@ EXE_INC = \
-I../interfacialModels/lnInclude \ -I../interfacialModels/lnInclude \
-I$(LIB_SRC)/finiteVolume/lnInclude \ -I$(LIB_SRC)/finiteVolume/lnInclude \
-I$(LIB_SRC)/thermophysicalModels/basic/lnInclude \ -I$(LIB_SRC)/thermophysicalModels/basic/lnInclude \
-I$(LIB_SRC)/transportModels/incompressible/lnInclude -I$(LIB_SRC)/transportModels/incompressible/lnInclude \
-I$(LIB_SRC)/TurbulenceModels/turbulenceModels/lnInclude \
-I$(LIB_SRC)/TurbulenceModels/incompressible/lnInclude \
-I$(LIB_SRC)/TurbulenceModels/phaseIncompressible/lnInclude
LIB_LIBS = \ LIB_LIBS = \
-lincompressibleTransportModels \ -lincompressibleTransportModels \

View File

@ -0,0 +1,188 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2013 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 "IATE.H"
#include "IATEsource.H"
#include "twoPhaseSystem.H"
#include "fvmDdt.H"
#include "fvmDiv.H"
#include "fvmSup.H"
#include "fvcDdt.H"
#include "fvcDiv.H"
#include "fvcAverage.H"
#include "mathematicalConstants.H"
#include "fundamentalConstants.H"
#include "addToRunTimeSelectionTable.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
namespace diameterModels
{
defineTypeNameAndDebug(IATE, 0);
addToRunTimeSelectionTable
(
diameterModel,
IATE,
dictionary
);
}
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::diameterModels::IATE::IATE
(
const dictionary& diameterProperties,
const phaseModel& phase
)
:
diameterModel(diameterProperties, phase),
kappai_
(
IOobject
(
IOobject::groupName("kappai", phase.name()),
phase_.U().time().timeName(),
phase_.U().mesh(),
IOobject::MUST_READ,
IOobject::AUTO_WRITE
),
phase_.U().mesh()
),
dMax_("dMax", dimLength, diameterProperties_.lookup("dMax")),
dMin_("dMin", dimLength, diameterProperties_.lookup("dMin")),
d_
(
IOobject
(
IOobject::groupName("d", phase.name()),
phase_.U().time().timeName(),
phase_.U().mesh(),
IOobject::NO_READ,
IOobject::AUTO_WRITE
),
dsm()
),
sources_
(
diameterProperties_.lookup("sources"),
IATEsource::iNew(*this)
)
{}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::diameterModels::IATE::~IATE()
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
Foam::tmp<Foam::volScalarField> Foam::diameterModels::IATE::dsm() const
{
return max(6/max(kappai_, 6/dMax_), dMin_);
}
// Placeholder for the nucleation/condensation model
// Foam::tmp<Foam::volScalarField> Foam::diameterModels::IATE::Rph() const
// {
// const volScalarField& T = phase_.thermo().T();
// const volScalarField& p = phase_.thermo().p();
//
// scalar A, B, C, sigma, vm, Rph;
//
// volScalarField ps(1e5*pow(10, A - B/(T + C)));
// volScalarField Dbc
// (
// 4*sigma*vm/(constant::physicoChemical::k*T*log(p/ps))
// );
//
// return constant::mathematical::pi*sqr(Dbc)*Rph;
// }
void Foam::diameterModels::IATE::correct()
{
// Initialise the accumulated source term to the dilatation effect
volScalarField R
(
(
(2.0/3.0)
/max
(
fvc::average(phase_ + phase_.oldTime()),
phase_.fluid().residualPhaseFraction()
)
)
*(fvc::ddt(phase_) + fvc::div(phase_.phiAlpha()))
);
// Accumulate the run-time selectable sources
forAll(sources_, j)
{
R -= sources_[j].R();
}
// Construct the interfacial curvature equation
fvScalarMatrix kappaiEqn
(
fvm::ddt(kappai_) + fvm::div(phase_.phi(), kappai_)
- fvm::Sp(fvc::div(phase_.phi()), kappai_)
==
- fvm::SuSp(R, kappai_)
//+ Rph() // Omit the nucleation/condensation term
);
kappaiEqn.relax();
kappaiEqn.solve();
// Update the Sauter-mean diameter
d_ = dsm();
}
bool Foam::diameterModels::IATE::read(const dictionary& phaseProperties)
{
diameterModel::read(phaseProperties);
diameterProperties_.lookup("dMax") >> dMax_;
diameterProperties_.lookup("dMin") >> dMin_;
// Re-create all the sources updating number, type and coefficients
PtrList<IATEsource>
(
diameterProperties_.lookup("sources"),
IATEsource::iNew(*this)
).transfer(sources_);
return true;
}
// ************************************************************************* //

View File

@ -0,0 +1,154 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2013 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/>.
Class
Foam::diameterModels::IATE
Description
IATE (Interfacial Area Transport Equation) bubble diameter model.
Solves for the interfacial curvature per unit volume of the phase rather
than interfacial area per unit volume to avoid stability issues relating to
the consistency requirements between the phase fraction and interfacial area
per unit volume. In every other respect this model is as presented in the
paper:
\verbatim
"Development of Interfacial Area Transport Equation"
M. Ishii,
S. Kim,
J Kelly,
Nuclear Engineering and Technology, Vol.37 No.6 December 2005
\endverbatim
SourceFiles
IATE.C
\*---------------------------------------------------------------------------*/
#ifndef IATE_H
#define IATE_H
#include "diameterModel.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
namespace diameterModels
{
// Forward declaration of classes
class IATEsource;
/*---------------------------------------------------------------------------*\
Class IATE Declaration
\*---------------------------------------------------------------------------*/
class IATE
:
public diameterModel
{
// Private data
//- Interfacial curvature (alpha*interfacial area)
volScalarField kappai_;
//- Maximum diameter used for stabilisation in the limit kappai->0
dimensionedScalar dMax_;
//- Minimum diameter used for stabilisation in the limit kappai->inf
dimensionedScalar dMin_;
//- The Sauter-mean diameter of the phase
volScalarField d_;
//- IATE sources
PtrList<IATEsource> sources_;
// Private member functions
tmp<volScalarField> dsm() const;
public:
friend class IATEsource;
//- Runtime type information
TypeName("IATE");
// Constructors
//- Construct from components
IATE
(
const dictionary& diameterProperties,
const phaseModel& phase
);
//- Destructor
virtual ~IATE();
// Member Functions
//- Return the interfacial curvature
const volScalarField& kappai() const
{
return kappai_;
}
//- Return the interfacial area
tmp<volScalarField> a() const
{
return phase_*kappai_;
}
//- Return the Sauter-mean diameter
virtual tmp<volScalarField> d() const
{
return d_;
}
//- Correct the diameter field
virtual void correct();
//- Read phaseProperties dictionary
virtual bool read(const dictionary& phaseProperties);
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace diameterModels
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,147 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2013 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 "IATEsource.H"
#include "twoPhaseSystem.H"
#include "fvMatrix.H"
#include "PhaseIncompressibleTurbulenceModel.H"
#include "uniformDimensionedFields.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
namespace diameterModels
{
defineTypeNameAndDebug(IATEsource, 0);
defineRunTimeSelectionTable(IATEsource, dictionary);
}
}
// * * * * * * * * * * * * * * * * * Selectors * * * * * * * * * * * * * * * //
Foam::autoPtr<Foam::diameterModels::IATEsource>
Foam::diameterModels::IATEsource::New
(
const word& type,
const IATE& iate,
const dictionary& dict
)
{
dictionaryConstructorTable::iterator cstrIter =
dictionaryConstructorTablePtr_->find(type);
if (cstrIter == dictionaryConstructorTablePtr_->end())
{
FatalErrorIn
(
"IATEsource::New"
"(const word& type, const IATE&, const dictionary&)"
) << "Unknown IATE source type "
<< type << nl << nl
<< "Valid IATE source types : " << endl
<< dictionaryConstructorTablePtr_->sortedToc()
<< exit(FatalError);
}
return autoPtr<IATEsource>(cstrIter()(iate, dict));
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
Foam::tmp<Foam::volScalarField> Foam::diameterModels::IATEsource::Ur() const
{
const uniformDimensionedVectorField& g =
phase().U().db().lookupObject<uniformDimensionedVectorField>("g");
return
sqrt(2.0)
*pow025
(
fluid().sigma()*mag(g)
*(otherPhase().rho() - phase().rho())
/sqr(otherPhase().rho())
)
*pow(max(1 - phase(), scalar(0)), 1.75);
}
Foam::tmp<Foam::volScalarField> Foam::diameterModels::IATEsource::Ut() const
{
return sqrt(2*otherPhase().turbulence().k());
}
Foam::tmp<Foam::volScalarField> Foam::diameterModels::IATEsource::Re() const
{
return max(Ur()*phase().d()/otherPhase().nu(), scalar(1.0e-3));
}
Foam::tmp<Foam::volScalarField> Foam::diameterModels::IATEsource::CD() const
{
const volScalarField Eo(this->Eo());
const volScalarField Re(this->Re());
return
max
(
min
(
(16/Re)*(1 + 0.15*pow(Re, 0.687)),
48/Re
),
8*Eo/(3*(Eo + 4))
);
}
Foam::tmp<Foam::volScalarField> Foam::diameterModels::IATEsource::Mo() const
{
const uniformDimensionedVectorField& g =
phase().U().db().lookupObject<uniformDimensionedVectorField>("g");
return
mag(g)*pow4(otherPhase().nu())*sqr(otherPhase().rho())
*(otherPhase().rho() - phase().rho())
/pow3(fluid().sigma());
}
Foam::tmp<Foam::volScalarField> Foam::diameterModels::IATEsource::Eo() const
{
const uniformDimensionedVectorField& g =
phase().U().db().lookupObject<uniformDimensionedVectorField>("g");
return
mag(g)*sqr(phase().d())
*(otherPhase().rho() - phase().rho())
/fluid().sigma();
}
Foam::tmp<Foam::volScalarField> Foam::diameterModels::IATEsource::We() const
{
return otherPhase().rho()*sqr(Ur())*phase().d()/fluid().sigma();
}
// ************************************************************************* //

View File

@ -0,0 +1,192 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2013 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/>.
Class
Foam::diameterModels::IATEsource
Description
IATE (Interfacial Area Transport Equation) bubble diameter model
run-time selectable sources.
SourceFiles
IATEsource.C
\*---------------------------------------------------------------------------*/
#ifndef IATEsource_H
#define IATEsource_H
#include "IATE.H"
#include "mathematicalConstants.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
namespace diameterModels
{
/*---------------------------------------------------------------------------*\
Class IATEsource Declaration
\*---------------------------------------------------------------------------*/
class IATEsource
{
protected:
// Protected data
//- Reference to the IATE this source applies to
const IATE& iate_;
public:
//- Runtime type information
TypeName("IATEsource");
// Declare run-time constructor selection table
declareRunTimeSelectionTable
(
autoPtr,
IATEsource,
dictionary,
(
const IATE& iate,
const dictionary& dict
),
(iate, dict)
);
//- Class used for the read-construction of
// PtrLists of IATE sources
class iNew
{
const IATE& iate_;
public:
iNew(const IATE& iate)
:
iate_(iate)
{}
autoPtr<IATEsource> operator()(Istream& is) const
{
word type(is);
dictionary dict(is);
return IATEsource::New(type, iate_, dict);
}
};
// Constructors
IATEsource(const IATE& iate)
:
iate_(iate)
{}
autoPtr<IATEsource> clone() const
{
notImplemented("autoPtr<IATEsource> clone() const");
return autoPtr<IATEsource>(NULL);
}
// Selectors
static autoPtr<IATEsource> New
(
const word& type,
const IATE& iate,
const dictionary& dict
);
//- Destructor
virtual ~IATEsource()
{}
// Member Functions
const phaseModel& phase() const
{
return iate_.phase();
}
const twoPhaseSystem& fluid() const
{
return iate_.phase().fluid();
}
const phaseModel& otherPhase() const
{
return phase().otherPhase();
}
scalar phi() const
{
return 1.0/(36*constant::mathematical::pi);
}
//- Return the bubble relative velocity
tmp<volScalarField> Ur() const;
//- Return the bubble turbulent velocity
tmp<volScalarField> Ut() const;
//- Return the bubble Reynolds number
tmp<volScalarField> Re() const;
//- Return the bubble drag coefficient
tmp<volScalarField> CD() const;
//- Return the bubble Morton number
tmp<volScalarField> Mo() const;
//- Return the bubble Eotvos number
tmp<volScalarField> Eo() const;
//- Return the bubble Webber number
tmp<volScalarField> We() const;
virtual tmp<volScalarField> R() const = 0;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace diameterModels
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,66 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2013 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 "dummy.H"
#include "addToRunTimeSelectionTable.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
namespace diameterModels
{
namespace IATEsources
{
defineTypeNameAndDebug(dummy, 0);
addToRunTimeSelectionTable(IATEsource, dummy, word);
}
}
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
Foam::tmp<Foam::volScalarField>
Foam::diameterModels::IATEsources::dummy::R() const
{
return tmp<volScalarField>
(
new volScalarField
(
IOobject
(
"R",
iate_.phase().U().time().timeName(),
iate_.phase().mesh()
),
iate_.phase().U().mesh(),
dimensionedScalar("R", dimless/dimTime, 0)
)
);
}
// ************************************************************************* //

View File

@ -0,0 +1,96 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2013 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/>.
Class
Foam::diameterModels::IATEsources::dummy
Description
SourceFiles
dummy.C
\*---------------------------------------------------------------------------*/
#ifndef dummy_H
#define dummy_H
#include "IATEsource.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
namespace diameterModels
{
namespace IATEsources
{
/*---------------------------------------------------------------------------*\
Class dummy Declaration
\*---------------------------------------------------------------------------*/
class dummy
:
public IATEsource
{
public:
//- Runtime type information
TypeName("dummy");
// Constructors
dummy
(
const word& name,
const IATE& iate,
const dictionary& dict
)
:
IATEsource(iate)
{}
//- Destructor
virtual ~dummy()
{}
// Member Functions
virtual tmp<volScalarField> R() const;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace IATEsources
} // End namespace diameterModels
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,109 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2013 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 "randomCoalescence.H"
#include "addToRunTimeSelectionTable.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
namespace diameterModels
{
namespace IATEsources
{
defineTypeNameAndDebug(randomCoalescence, 0);
addToRunTimeSelectionTable(IATEsource, randomCoalescence, dictionary);
}
}
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::diameterModels::IATEsources::randomCoalescence::
randomCoalescence
(
const IATE& iate,
const dictionary& dict
)
:
IATEsource(iate),
Crc_("Crc", dimless, dict.lookup("Crc")),
C_("C", dimless, dict.lookup("C")),
alphaMax_("alphaMax", dimless, dict.lookup("alphaMax"))
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
Foam::tmp<Foam::volScalarField>
Foam::diameterModels::IATEsources::randomCoalescence::R() const
{
tmp<volScalarField> tR
(
new volScalarField
(
IOobject
(
"R",
iate_.phase().U().time().timeName(),
iate_.phase().mesh()
),
iate_.phase().U().mesh(),
dimensionedScalar("R", dimless/dimTime, 0)
)
);
volScalarField R = tR();
scalar Crc = Crc_.value();
scalar C = C_.value();
scalar alphaMax = alphaMax_.value();
volScalarField Ut(this->Ut());
const volScalarField& alpha = phase();
const volScalarField& kappai = iate_.kappai();
scalar cbrtAlphaMax = cbrt(alphaMax);
forAll(R, celli)
{
if (alpha[celli] < alphaMax - SMALL)
{
scalar cbrtAlphaMaxMAlpha = cbrtAlphaMax - cbrt(alpha[celli]);
R[celli] =
12*phi()*kappai[celli]*alpha[celli]
*Crc
*Ut[celli]
*(1 - exp(-C*cbrt(alpha[celli]*alphaMax)/cbrtAlphaMaxMAlpha))
/(cbrtAlphaMax*cbrtAlphaMaxMAlpha);
}
}
return tR;
}
// ************************************************************************* //

View File

@ -0,0 +1,108 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2013 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/>.
Class
Foam::diameterModels::IATEsources::randomCoalescence
Description
Random coalescence IATE source as defined in paper:
\verbatim
"Development of Interfacial Area Transport Equation"
M. Ishii,
S. Kim,
J Kelly,
Nuclear Engineering and Technology, Vol.37 No.6 December 2005
\endverbatim
SourceFiles
randomCoalescence.C
\*---------------------------------------------------------------------------*/
#ifndef randomCoalescence_H
#define randomCoalescence_H
#include "IATEsource.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
namespace diameterModels
{
namespace IATEsources
{
/*---------------------------------------------------------------------------*\
Class randomCoalescence Declaration
\*---------------------------------------------------------------------------*/
class randomCoalescence
:
public IATEsource
{
// Private data
dimensionedScalar Crc_;
dimensionedScalar C_;
dimensionedScalar alphaMax_;
public:
//- Runtime type information
TypeName("randomCoalescence");
// Constructors
randomCoalescence
(
const IATE& iate,
const dictionary& dict
);
//- Destructor
virtual ~randomCoalescence()
{}
// Member Functions
virtual tmp<volScalarField> R() const;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace IATEsources
} // End namespace diameterModels
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,104 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2013 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 "turbulentBreakUp.H"
#include "addToRunTimeSelectionTable.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
namespace diameterModels
{
namespace IATEsources
{
defineTypeNameAndDebug(turbulentBreakUp, 0);
addToRunTimeSelectionTable(IATEsource, turbulentBreakUp, dictionary);
}
}
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::diameterModels::IATEsources::turbulentBreakUp::
turbulentBreakUp
(
const IATE& iate,
const dictionary& dict
)
:
IATEsource(iate),
Cti_("Cti", dimless, dict.lookup("Cti")),
WeCr_("WeCr", dimless, dict.lookup("WeCr"))
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
Foam::tmp<Foam::volScalarField>
Foam::diameterModels::IATEsources::turbulentBreakUp::R() const
{
tmp<volScalarField> tR
(
new volScalarField
(
IOobject
(
"R",
iate_.phase().U().time().timeName(),
iate_.phase().mesh()
),
iate_.phase().U().mesh(),
dimensionedScalar("R", dimless/dimTime, 0)
)
);
volScalarField R = tR();
scalar Cti = Cti_.value();
scalar WeCr = WeCr_.value();
volScalarField Ut(this->Ut());
volScalarField We(this->We());
const volScalarField& d(iate_.d()());
forAll(R, celli)
{
if (We[celli] > WeCr)
{
R[celli] =
(1.0/3.0)
*Cti/d[celli]
*Ut[celli]
*sqrt(1 - WeCr/We[celli])
*exp(-WeCr/We[celli]);
}
}
return tR;
}
// ************************************************************************* //

View File

@ -0,0 +1,106 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2013 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/>.
Class
Foam::diameterModels::IATEsources::turbulentBreakUp
Description
Turbulence-induced break-up IATE source as defined in paper:
\verbatim
"Development of Interfacial Area Transport Equation"
M. Ishii,
S. Kim,
J Kelly,
Nuclear Engineering and Technology, Vol.37 No.6 December 2005
\endverbatim
SourceFiles
turbulentBreakUp.C
\*---------------------------------------------------------------------------*/
#ifndef turbulentBreakUp_H
#define turbulentBreakUp_H
#include "IATEsource.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
namespace diameterModels
{
namespace IATEsources
{
/*---------------------------------------------------------------------------*\
Class turbulentBreakUp Declaration
\*---------------------------------------------------------------------------*/
class turbulentBreakUp
:
public IATEsource
{
// Private data
dimensionedScalar Cti_;
dimensionedScalar WeCr_;
public:
//- Runtime type information
TypeName("turbulentBreakUp");
// Constructors
turbulentBreakUp
(
const IATE& iate,
const dictionary& dict
);
//- Destructor
virtual ~turbulentBreakUp()
{}
// Member Functions
virtual tmp<volScalarField> R() const;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace IATEsources
} // End namespace diameterModels
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,72 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2013 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 "wakeEntrainmentCoalescence.H"
#include "addToRunTimeSelectionTable.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
namespace diameterModels
{
namespace IATEsources
{
defineTypeNameAndDebug(wakeEntrainmentCoalescence, 0);
addToRunTimeSelectionTable
(
IATEsource,
wakeEntrainmentCoalescence,
dictionary
);
}
}
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::diameterModels::IATEsources::wakeEntrainmentCoalescence::
wakeEntrainmentCoalescence
(
const IATE& iate,
const dictionary& dict
)
:
IATEsource(iate),
Cwe_("Cwe", dimless, dict.lookup("Cwe"))
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
Foam::tmp<Foam::volScalarField>
Foam::diameterModels::IATEsources::wakeEntrainmentCoalescence::R() const
{
return (-12)*phi()*Cwe_*cbrt(CD())*iate_.a()*Ur();
}
// ************************************************************************* //

View File

@ -0,0 +1,105 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2013 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/>.
Class
Foam::diameterModels::IATEsources::wakeEntrainmentCoalescence
Description
Bubble coalescence due to wake entrainment IATE source as defined in paper:
\verbatim
"Development of Interfacial Area Transport Equation"
M. Ishii,
S. Kim,
J Kelly,
Nuclear Engineering and Technology, Vol.37 No.6 December 2005
\endverbatim
SourceFiles
wakeEntrainmentCoalescence.C
\*---------------------------------------------------------------------------*/
#ifndef wakeEntrainmentCoalescence_H
#define wakeEntrainmentCoalescence_H
#include "IATEsource.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
namespace diameterModels
{
namespace IATEsources
{
/*---------------------------------------------------------------------------*\
Class wakeEntrainmentCoalescence Declaration
\*---------------------------------------------------------------------------*/
class wakeEntrainmentCoalescence
:
public IATEsource
{
// Private data
dimensionedScalar Cwe_;
public:
//- Runtime type information
TypeName("wakeEntrainmentCoalescence");
// Constructors
wakeEntrainmentCoalescence
(
const IATE& iate,
const dictionary& dict
);
//- Destructor
virtual ~wakeEntrainmentCoalescence()
{}
// Member Functions
virtual tmp<volScalarField> R() const;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace IATEsources
} // End namespace diameterModels
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -48,12 +48,12 @@ namespace diameterModels
Foam::diameterModels::constant::constant Foam::diameterModels::constant::constant
( (
const dictionary& dict, const dictionary& diameterProperties,
const phaseModel& phase const phaseModel& phase
) )
: :
diameterModel(dict, phase), diameterModel(diameterProperties, phase),
d_("d", dimLength, dict.lookup("d")) d_("d", dimLength, diameterProperties_.lookup("d"))
{} {}
@ -84,4 +84,14 @@ Foam::tmp<Foam::volScalarField> Foam::diameterModels::constant::d() const
} }
bool Foam::diameterModels::constant::read(const dictionary& phaseProperties)
{
diameterModel::read(phaseProperties);
diameterProperties_.lookup("d") >> d_;
return true;
}
// ************************************************************************* // // ************************************************************************* //

View File

@ -22,7 +22,7 @@ License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Class Class
Foam::constant Foam::diameterModels::constant
Description Description
Constant dispersed-phase particle diameter model. Constant dispersed-phase particle diameter model.
@ -69,7 +69,7 @@ public:
//- Construct from components //- Construct from components
constant constant
( (
const dictionary& dict, const dictionary& diameterProperties,
const phaseModel& phase const phaseModel& phase
); );
@ -80,7 +80,11 @@ public:
// Member Functions // Member Functions
tmp<volScalarField> d() const; //- Return the diameter as a field
virtual tmp<volScalarField> d() const;
//- Read diameterProperties dictionary
virtual bool read(const dictionary& diameterProperties);
}; };

View File

@ -38,11 +38,11 @@ namespace Foam
Foam::diameterModel::diameterModel Foam::diameterModel::diameterModel
( (
const dictionary& dict, const dictionary& diameterProperties,
const phaseModel& phase const phaseModel& phase
) )
: :
dict_(dict), diameterProperties_(diameterProperties),
phase_(phase) phase_(phase)
{} {}
@ -53,4 +53,18 @@ Foam::diameterModel::~diameterModel()
{} {}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
void Foam::diameterModel::correct()
{}
bool Foam::diameterModel::read(const dictionary& phaseProperties)
{
diameterProperties_ = phaseProperties.subDict(type() + "Coeffs");
return true;
}
// ************************************************************************* // // ************************************************************************* //

View File

@ -36,12 +36,12 @@ SourceFiles
#ifndef diameterModel_H #ifndef diameterModel_H
#define diameterModel_H #define diameterModel_H
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#include "dictionary.H" #include "dictionary.H"
#include "phaseModel.H" #include "phaseModel.H"
#include "runTimeSelectionTables.H" #include "runTimeSelectionTables.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam namespace Foam
{ {
@ -51,11 +51,12 @@ namespace Foam
class diameterModel class diameterModel
{ {
protected: protected:
// Protected data // Protected data
const dictionary& dict_; dictionary diameterProperties_;
const phaseModel& phase_; const phaseModel& phase_;
@ -73,10 +74,10 @@ public:
diameterModel, diameterModel,
dictionary, dictionary,
( (
const dictionary& dict, const dictionary& diameterProperties,
const phaseModel& phase const phaseModel& phase
), ),
(dict, phase) (diameterProperties, phase)
); );
@ -84,7 +85,7 @@ public:
diameterModel diameterModel
( (
const dictionary& dict, const dictionary& diameterProperties,
const phaseModel& phase const phaseModel& phase
); );
@ -97,15 +98,33 @@ public:
static autoPtr<diameterModel> New static autoPtr<diameterModel> New
( (
const dictionary& dict, const dictionary& diameterProperties,
const phaseModel& phase const phaseModel& phase
); );
// Member Functions // Member Functions
//- Return the phase diameter properties dictionary
const dictionary& diameterProperties() const
{
return diameterProperties_;
}
//- Return the phase
const phaseModel& phase() const
{
return phase_;
}
//- Return the phase mean diameter field //- Return the phase mean diameter field
virtual tmp<volScalarField> d() const = 0; virtual tmp<volScalarField> d() const = 0;
//- Correct the diameter field
virtual void correct();
//- Read phaseProperties dictionary
virtual bool read(const dictionary& phaseProperties) = 0;
}; };

View File

@ -48,13 +48,13 @@ namespace diameterModels
Foam::diameterModels::isothermal::isothermal Foam::diameterModels::isothermal::isothermal
( (
const dictionary& dict, const dictionary& diameterProperties,
const phaseModel& phase const phaseModel& phase
) )
: :
diameterModel(dict, phase), diameterModel(diameterProperties, phase),
d0_("d0", dimLength, dict.lookup("d0")), d0_("d0", dimLength, diameterProperties_.lookup("d0")),
p0_("p0", dimPressure, dict.lookup("p0")) p0_("p0", dimPressure, diameterProperties_.lookup("p0"))
{} {}
@ -77,4 +77,15 @@ Foam::tmp<Foam::volScalarField> Foam::diameterModels::isothermal::d() const
} }
bool Foam::diameterModels::isothermal::read(const dictionary& phaseProperties)
{
diameterModel::read(phaseProperties);
diameterProperties_.lookup("d0") >> d0_;
diameterProperties_.lookup("p0") >> p0_;
return true;
}
// ************************************************************************* // // ************************************************************************* //

View File

@ -22,7 +22,7 @@ License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Class Class
Foam::isothermal Foam::diameterModels::isothermal
Description Description
Isothermal dispersed-phase particle diameter model. Isothermal dispersed-phase particle diameter model.
@ -72,7 +72,7 @@ public:
//- Construct from components //- Construct from components
isothermal isothermal
( (
const dictionary& dict, const dictionary& diameterProperties,
const phaseModel& phase const phaseModel& phase
); );
@ -83,7 +83,11 @@ public:
// Member Functions // Member Functions
tmp<volScalarField> d() const; //- Return the diameter field
virtual tmp<volScalarField> d() const;
//- Read phaseProperties dictionary
virtual bool read(const dictionary& phaseProperties);
}; };

View File

@ -26,6 +26,8 @@ License
#include "phaseModel.H" #include "phaseModel.H"
#include "twoPhaseSystem.H" #include "twoPhaseSystem.H"
#include "diameterModel.H" #include "diameterModel.H"
#include "fvMatrix.H"
#include "PhaseIncompressibleTurbulenceModel.H"
#include "dragModel.H" #include "dragModel.H"
#include "heatTransferModel.H" #include "heatTransferModel.H"
#include "fixedValueFvPatchFields.H" #include "fixedValueFvPatchFields.H"
@ -73,6 +75,17 @@ Foam::phaseModel::phaseModel
IOobject::AUTO_WRITE IOobject::AUTO_WRITE
), ),
fluid.mesh() fluid.mesh()
),
phiAlpha_
(
IOobject
(
IOobject::groupName("alphaPhi", name_),
fluid.mesh().time().timeName(),
fluid.mesh()
),
fluid.mesh(),
dimensionedScalar("0", dimensionSet(0, 3, -1, 0, 0), 0)
) )
{ {
thermo_->validate("phaseModel " + name_, "h", "e"); thermo_->validate("phaseModel " + name_, "h", "e");
@ -153,6 +166,16 @@ Foam::phaseModel::phaseModel
phaseDict_, phaseDict_,
*this *this
); );
turbulence_ =
PhaseIncompressibleTurbulenceModel<phaseModel>::New
(
*this,
U_,
phiAlpha_,
phi(),
*this
);
} }
@ -164,10 +187,39 @@ Foam::phaseModel::~phaseModel()
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
const Foam::phaseModel& Foam::phaseModel::otherPhase() const
{
return fluid_.otherPhase(*this);
}
Foam::tmp<Foam::volScalarField> Foam::phaseModel::d() const Foam::tmp<Foam::volScalarField> Foam::phaseModel::d() const
{ {
return dPtr_().d(); return dPtr_().d();
} }
Foam::PhaseIncompressibleTurbulenceModel<Foam::phaseModel>&
Foam::phaseModel::turbulence()
{
return turbulence_();
}
const Foam::PhaseIncompressibleTurbulenceModel<Foam::phaseModel>&
Foam::phaseModel::turbulence() const
{
return turbulence_();
}
void Foam::phaseModel::correct()
{
return dPtr_->correct();
}
bool Foam::phaseModel::read(const dictionary& phaseProperties)
{
phaseDict_ = phaseProperties.subDict(name_);
return dPtr_->read(phaseDict_);
}
// ************************************************************************* // // ************************************************************************* //

View File

@ -48,6 +48,9 @@ namespace Foam
class twoPhaseSystem; class twoPhaseSystem;
class diameterModel; class diameterModel;
template<class Phase>
class PhaseIncompressibleTurbulenceModel;
/*---------------------------------------------------------------------------*\ /*---------------------------------------------------------------------------*\
Class phaseModel Declaration Class phaseModel Declaration
@ -74,12 +77,18 @@ class phaseModel
//- Velocity //- Velocity
volVectorField U_; volVectorField U_;
//- Fluxes //- Volumetric flux of the phase
surfaceScalarField phiAlpha_;
//- Volumetric flux of the phase
autoPtr<surfaceScalarField> phiPtr_; autoPtr<surfaceScalarField> phiPtr_;
//- Diameter model //- Diameter model
autoPtr<diameterModel> dPtr_; autoPtr<diameterModel> dPtr_;
//- turbulence model
autoPtr<PhaseIncompressibleTurbulenceModel<phaseModel> > turbulence_;
public: public:
@ -99,19 +108,47 @@ public:
// Member Functions // Member Functions
//- Return the name of this phase
const word& name() const
{
return name_;
}
//- Return the twoPhaseSystem to which this phase belongs //- Return the twoPhaseSystem to which this phase belongs
const twoPhaseSystem& fluid() const const twoPhaseSystem& fluid() const
{ {
return fluid_; return fluid_;
} }
const word& name() const //- Return the other phase in this two-phase system
{ const phaseModel& otherPhase() const;
return name_;
}
//- Return the Sauter-mean diameter
tmp<volScalarField> d() const; tmp<volScalarField> d() const;
//- Return the turbulence model
const PhaseIncompressibleTurbulenceModel<phaseModel>&
turbulence() const;
//- Return non-const access to the turbulence model
// for correction
PhaseIncompressibleTurbulenceModel<phaseModel>&
turbulence();
//- Return the thermophysical model
const rhoThermo& thermo() const
{
return thermo_();
}
//- Return non-const access to the thermophysical model
// for correction
rhoThermo& thermo()
{
return thermo_();
}
//- Return the laminar viscosity
tmp<volScalarField> nu() const tmp<volScalarField> nu() const
{ {
return thermo_->nu(); return thermo_->nu();
@ -123,57 +160,71 @@ public:
return thermo_->nu(patchi); return thermo_->nu(patchi);
} }
//- Return the thermal conductivity
tmp<volScalarField> kappa() const tmp<volScalarField> kappa() const
{ {
return thermo_->kappa(); return thermo_->kappa();
} }
//- Return the specific heat capacity
tmp<volScalarField> Cp() const tmp<volScalarField> Cp() const
{ {
return thermo_->Cp(); return thermo_->Cp();
} }
//- Return the density
const volScalarField& rho() const const volScalarField& rho() const
{ {
return thermo_->rho(); return thermo_->rho();
} }
const rhoThermo& thermo() const //- Return the velocity
{
return thermo_();
}
rhoThermo& thermo()
{
return thermo_();
}
const volVectorField& U() const const volVectorField& U() const
{ {
return U_; return U_;
} }
//- Return non-const access to the velocity
// Used in the momentum equation
volVectorField& U() volVectorField& U()
{ {
return U_; return U_;
} }
//- Return the volumetric flux
const surfaceScalarField& phi() const const surfaceScalarField& phi() const
{ {
return phiPtr_(); return phiPtr_();
} }
//- Return non-const access to the volumetric flux
surfaceScalarField& phi() surfaceScalarField& phi()
{ {
return phiPtr_(); return phiPtr_();
} }
//- Dummy correct //- Return the volumetric flux of the phase
void correct() const surfaceScalarField& phiAlpha() const
{} {
return phiAlpha_;
}
//- Dummy read //- Return non-const access to the volumetric flux of the phase
bool read() surfaceScalarField& phiAlpha()
{
return phiAlpha_;
}
//- Correct the phase properties
// other than the thermodynamics and turbulence
// which have special treatment
void correct();
//- Read phaseProperties dictionary
virtual bool read(const dictionary& phaseProperties);
//- Dummy Read for transportModel
virtual bool read()
{ {
return true; return true;
} }

View File

@ -24,9 +24,19 @@ License
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#include "twoPhaseSystem.H" #include "twoPhaseSystem.H"
#include "fvMatrix.H"
#include "PhaseIncompressibleTurbulenceModel.H"
#include "surfaceInterpolate.H" #include "surfaceInterpolate.H"
#include "fixedValueFvsPatchFields.H" #include "MULES.H"
#include "subCycle.H"
#include "fvcDdt.H"
#include "fvcDiv.H"
#include "fvcSnGrad.H"
#include "fvcFlux.H"
#include "fvcCurl.H" #include "fvcCurl.H"
#include "fvmDdt.H"
#include "fvmLaplacian.H"
#include "fixedValueFvsPatchFields.H"
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
@ -63,6 +73,37 @@ Foam::twoPhaseSystem::twoPhaseSystem
wordList(lookup("phases"))[1] wordList(lookup("phases"))[1]
), ),
phi_
(
IOobject
(
"phi",
mesh.time().timeName(),
mesh,
IOobject::NO_READ,
IOobject::AUTO_WRITE
),
this->calcPhi()
),
dgdt_
(
IOobject
(
"dgdt",
mesh.time().timeName(),
mesh
),
pos(phase2_)*fvc::div(phi_)/max(phase2_, scalar(0.0001))
),
sigma_
(
"sigma",
dimensionSet(1, 0, -2, 0, 0),
lookup("sigma")
),
Cvm_ Cvm_
( (
"Cvm", "Cvm",
@ -170,7 +211,7 @@ Foam::tmp<Foam::volVectorField> Foam::twoPhaseSystem::U() const
} }
Foam::tmp<Foam::surfaceScalarField> Foam::twoPhaseSystem::phi() const Foam::tmp<Foam::surfaceScalarField> Foam::twoPhaseSystem::calcPhi() const
{ {
return return
fvc::interpolate(phase1_)*phase1_.phi() fvc::interpolate(phase1_)*phase1_.phi()
@ -366,18 +407,242 @@ Foam::tmp<Foam::volScalarField> Foam::twoPhaseSystem::heatTransferCoeff() const
} }
void Foam::twoPhaseSystem::solve()
{
const Time& runTime = mesh_.time();
volScalarField& alpha1 = phase1_;
volScalarField& alpha2 = phase2_;
const surfaceScalarField& phi1 = phase1_.phi();
const surfaceScalarField& phi2 = phase2_.phi();
const dictionary& alphaControls = mesh_.solverDict
(
alpha1.name()
);
label nAlphaSubCycles(readLabel(alphaControls.lookup("nAlphaSubCycles")));
label nAlphaCorr(readLabel(alphaControls.lookup("nAlphaCorr")));
Switch implicitPhasePressure
(
alphaControls.lookupOrDefault<Switch>("implicitPhasePressure", false)
);
word alphaScheme("div(phi," + alpha1.name() + ')');
word alpharScheme("div(phir," + alpha1.name() + ')');
alpha1.correctBoundaryConditions();
surfaceScalarField phic("phic", phi_);
surfaceScalarField phir("phir", phi1 - phi2);
surfaceScalarField alpha1f(fvc::interpolate(max(alpha1, scalar(0))));
tmp<surfaceScalarField> pPrimeByA;
if (implicitPhasePressure)
{
const volScalarField& rAU1 = mesh_.lookupObject<volScalarField>
(
IOobject::groupName("rAU", phase1_.name())
);
const volScalarField& rAU2 = mesh_.lookupObject<volScalarField>
(
IOobject::groupName("rAU", phase2_.name())
);
pPrimeByA =
fvc::interpolate((1.0/phase1_.rho())
*rAU1*phase1_.turbulence().pPrime())
+ fvc::interpolate((1.0/phase2_.rho())
*rAU2*phase2_.turbulence().pPrime());
surfaceScalarField phiP
(
pPrimeByA()*fvc::snGrad(alpha1, "bounded")*mesh_.magSf()
);
phic += alpha1f*phiP;
phir += phiP;
}
for (int acorr=0; acorr<nAlphaCorr; acorr++)
{
volScalarField::DimensionedInternalField Sp
(
IOobject
(
"Sp",
runTime.timeName(),
mesh_
),
mesh_,
dimensionedScalar("Sp", dgdt_.dimensions(), 0.0)
);
volScalarField::DimensionedInternalField Su
(
IOobject
(
"Su",
runTime.timeName(),
mesh_
),
// Divergence term is handled explicitly to be
// consistent with the explicit transport solution
fvc::div(phi_)*min(alpha1, scalar(1))
);
forAll(dgdt_, celli)
{
if (dgdt_[celli] > 0.0 && alpha1[celli] > 0.0)
{
Sp[celli] -= dgdt_[celli]*alpha1[celli];
Su[celli] += dgdt_[celli]*alpha1[celli];
}
else if (dgdt_[celli] < 0.0 && alpha1[celli] < 1.0)
{
Sp[celli] += dgdt_[celli]*(1.0 - alpha1[celli]);
}
}
dimensionedScalar totalDeltaT = runTime.deltaT();
if (nAlphaSubCycles > 1)
{
phase1_.phiAlpha() =
dimensionedScalar("0", phase1_.phiAlpha().dimensions(), 0);
}
for
(
subCycle<volScalarField> alphaSubCycle(alpha1, nAlphaSubCycles);
!(++alphaSubCycle).end();
)
{
surfaceScalarField alphaPhic1
(
fvc::flux
(
phic,
alpha1,
alphaScheme
)
+ fvc::flux
(
-fvc::flux(-phir, scalar(1) - alpha1, alpharScheme),
alpha1,
alpharScheme
)
);
// Ensure that the flux at inflow BCs is preserved
forAll(alphaPhic1.boundaryField(), patchi)
{
fvsPatchScalarField& alphaPhic1p =
alphaPhic1.boundaryField()[patchi];
if (!alphaPhic1p.coupled())
{
const scalarField& phi1p = phi1.boundaryField()[patchi];
const scalarField& alpha1p = alpha1.boundaryField()[patchi];
forAll(alphaPhic1p, facei)
{
if (phi1p[facei] < 0)
{
alphaPhic1p[facei] = alpha1p[facei]*phi1p[facei];
}
}
}
}
MULES::explicitSolve
(
geometricOneField(),
alpha1,
phi_,
alphaPhic1,
Sp,
Su,
1,
0
);
if (nAlphaSubCycles > 1)
{
phase1_.phiAlpha() += (runTime.deltaT()/totalDeltaT)*alphaPhic1;
}
else
{
phase1_.phiAlpha() = alphaPhic1;
}
}
if (implicitPhasePressure)
{
fvScalarMatrix alpha1Eqn
(
fvm::ddt(alpha1) - fvc::ddt(alpha1)
- fvm::laplacian(alpha1f*pPrimeByA, alpha1, "bounded")
);
alpha1Eqn.relax();
alpha1Eqn.solve();
phase1_.phiAlpha() += alpha1Eqn.flux();
}
phase2_.phiAlpha() = phi_ - phase1_.phiAlpha();
alpha2 = scalar(1) - alpha1;
Info<< alpha1.name() << " volume fraction = "
<< alpha1.weightedAverage(mesh_.V()).value()
<< " Min(alpha1) = " << min(alpha1).value()
<< " Max(alpha1) = " << max(alpha1).value()
<< endl;
}
}
void Foam::twoPhaseSystem::correct()
{
phase1_.correct();
phase2_.correct();
}
void Foam::twoPhaseSystem::correctTurbulence()
{
phase1_.turbulence().correct();
phase2_.turbulence().correct();
}
bool Foam::twoPhaseSystem::read() bool Foam::twoPhaseSystem::read()
{ {
if (regIOobject::read()) if (regIOobject::read())
{ {
bool readOK = true; bool readOK = true;
readOK &= phase1_.read(); readOK &= phase1_.read(*this);
readOK &= phase2_.read(); readOK &= phase2_.read(*this);
lookup("sigma") >> sigma_;
lookup("Cvm") >> Cvm_; lookup("Cvm") >> Cvm_;
lookup("Cl") >> Cl_; lookup("Cl") >> Cl_;
// drag1_->read(*this);
// drag2_->read(*this);
// heatTransfer1_->read(*this);
// heatTransfer2_->read(*this);
lookup("dispersedPhase") >> dispersedPhase_;
lookup("residualPhaseFraction") >> residualPhaseFraction_;
lookup("residualSlip") >> residualSlip_;
return readOK; return readOK;
} }
else else

View File

@ -74,6 +74,12 @@ class twoPhaseSystem
phaseModel phase1_; phaseModel phase1_;
phaseModel phase2_; phaseModel phase2_;
surfaceScalarField phi_;
volScalarField dgdt_;
dimensionedScalar sigma_;
dimensionedScalar Cvm_; dimensionedScalar Cvm_;
dimensionedScalar Cl_; dimensionedScalar Cl_;
@ -88,6 +94,10 @@ class twoPhaseSystem
dimensionedScalar residualSlip_; dimensionedScalar residualSlip_;
//- Return the mixture flux
tmp<surfaceScalarField> calcPhi() const;
public: public:
// Constructors // Constructors
@ -140,6 +150,28 @@ public:
return phase2_; return phase2_;
} }
//- Return the mixture flux
const surfaceScalarField& phi() const
{
return phi_;
}
//- Return the mixture flux
surfaceScalarField& phi()
{
return phi_;
}
const volScalarField& dgdt() const
{
return dgdt_;
}
volScalarField& dgdt()
{
return dgdt_;
}
const dragModel& drag1() const const dragModel& drag1() const
{ {
return drag1_(); return drag1_();
@ -193,8 +225,11 @@ public:
//- Return the mixture velocity //- Return the mixture velocity
tmp<volVectorField> U() const; tmp<volVectorField> U() const;
//- Return the mixture flux //- Return the surface tension coefficient
tmp<surfaceScalarField> phi() const; dimensionedScalar sigma() const
{
return sigma_;
}
//- Return the virtual-mass coefficient //- Return the virtual-mass coefficient
dimensionedScalar Cvm() const dimensionedScalar Cvm() const
@ -208,9 +243,14 @@ public:
return Cl_; return Cl_;
} }
//- Dummy correct //- Solve for the two-phase-fractions
void correct() void solve();
{}
//- Correct two-phase properties other than turbulence
void correct();
//- Correct two-phase turbulence
void correctTurbulence();
//- Read base phaseProperties dictionary //- Read base phaseProperties dictionary
bool read(); bool read();

View File

@ -1016,7 +1016,6 @@ int i;
// found somewhere in the 2nd addition // found somewhere in the 2nd addition
uint32_t stroustrup (const char * s, int len) { uint32_t stroustrup (const char * s, int len) {
uint32_t h; uint32_t h;
int i;
for (register int i=0; i < len; ++s, ++i) for (register int i=0; i < len; ++s, ++i)
{ {

View File

@ -2,7 +2,7 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2011 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -137,7 +137,7 @@ int main(int argc, char *argv[])
Info<< " std::list constructed from Foam::List: "; Info<< " std::list constructed from Foam::List: ";
std::list<vector>::iterator it; std::list<vector>::iterator it;
for (it=stlList.begin(); it != stlList.end(); it++) for (it=stlList.begin(); it != stlList.end(); ++it)
{ {
Info<< *it << " "; Info<< *it << " ";
} }

View File

@ -2,7 +2,7 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2011 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -79,7 +79,7 @@ int main(int argc, char *argv[])
while (iter != iter2) while (iter != iter2)
{ {
Info<< *iter; Info<< *iter;
iter++; ++iter;
} }
Info<< "<\n"; Info<< "<\n";

View File

@ -477,7 +477,9 @@ meshQualityControls
// 0 : only write final meshes // 0 : only write final meshes
// 1 : write intermediate meshes // 1 : write intermediate meshes
// 2 : write volScalarField with cellLevel for postprocessing // 2 : write volScalarField with cellLevel for postprocessing
// 4 : write current intersections as .obj files // 4 : write current mesh intersections as .obj files
// 8 : write information about explicit feature edge refinement
// 16 : write information about layers
debug 0; debug 0;
// Merge tolerance. Is fraction of overall bounding box of initial mesh. // Merge tolerance. Is fraction of overall bounding box of initial mesh.

View File

@ -1,3 +1,28 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2013 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 "checkTopology.H" #include "checkTopology.H"
#include "polyMesh.H" #include "polyMesh.H"
#include "Time.H" #include "Time.H"
@ -9,6 +34,8 @@
#include "emptyPolyPatch.H" #include "emptyPolyPatch.H"
#include "processorPolyPatch.H" #include "processorPolyPatch.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
Foam::label Foam::checkTopology Foam::label Foam::checkTopology
( (
const polyMesh& mesh, const polyMesh& mesh,
@ -287,6 +314,37 @@ Foam::label Foam::checkTopology
rs rs
); );
ctr.write(); ctr.write();
// write cellSet for each region
PtrList<cellSet> cellRegions(rs.nRegions());
for (label i = 0; i < rs.nRegions(); i++)
{
cellRegions.set
(
i,
new cellSet
(
mesh,
"region" + Foam::name(i),
mesh.nCells()/100
)
);
}
forAll(rs, i)
{
cellRegions[rs[i]].insert(i);
}
for (label i = 0; i < rs.nRegions(); i++)
{
Info<< " <<Writing region " << i << " with "
<< returnReduce(cellRegions[i].size(), sumOp<scalar>())
<< " cells to cellSet " << cellRegions[i].name() << endl;
cellRegions[i].write();
}
} }
} }
@ -437,3 +495,6 @@ Foam::label Foam::checkTopology
return noFailedChecks; return noFailedChecks;
} }
// ************************************************************************* //

View File

@ -1,22 +0,0 @@
#!/bin/sh
cd ${0%/*} || exit 1 # run from this directory
# Source tutorial run functions
. $WM_PROJECT_DIR/bin/tools/RunFunctions
# Get application name
application=`getApplication`
runApplication blockMesh
# Make random cell numbering to get faceZone orientation random
runApplication renumberMesh -dict system/renumberMeshDict
# Construct faceZone
runApplication topoSet
runApplication decomposePar -force -cellDist
runParallel orientFaceZone 2 f0 '(10 0 0)'
runApplication reconstructParMesh -latestTime -mergeTol 1e-6
# ----------------------------------------------------------------- end-of-file

View File

@ -1 +0,0 @@
2013-09-16 To test orientFaceZone. Make random orientation. Orient afterwards.

View File

@ -1,135 +0,0 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: dev |
| \\ / A nd | Web: www.OpenFOAM.org |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class dictionary;
note "mesh decomposition control dictionary";
object decomposeParDict;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
numberOfSubdomains 2;
//- Keep owner and neighbour on same processor for faces in zones:
// preserveFaceZones (heater solid1 solid3);
//- Keep owner and neighbour on same processor for faces in patches:
// (makes sense only for cyclic patches)
//preservePatches (cyclic_half0 cyclic_half1);
//- Keep all of faceSet on a single processor. This puts all cells
// connected with a point, edge or face on the same processor.
// (just having face connected cells might not guarantee a balanced
// decomposition)
// The processor can be -1 (the decompositionMethod chooses the processor
// for a good load balance) or explicitly provided (upsets balance).
//singleProcessorFaceSets ((f0 -1));
//- Use the volScalarField named here as a weight for each cell in the
// decomposition. For example, use a particle population field to decompose
// for a balanced number of particles in a lagrangian simulation.
// weightField dsmcRhoNMean;
//method scotch;
method hierarchical;
// method simple;
// method metis;
// method manual;
// method multiLevel;
// method structured; // does 2D decomposition of structured mesh
multiLevelCoeffs
{
// Decomposition methods to apply in turn. This is like hierarchical but
// fully general - every method can be used at every level.
level0
{
numberOfSubdomains 64;
//method simple;
//simpleCoeffs
//{
// n (2 1 1);
// delta 0.001;
//}
method scotch;
}
level1
{
numberOfSubdomains 4;
method scotch;
}
}
// Desired output
simpleCoeffs
{
n (2 1 1);
delta 0.001;
}
hierarchicalCoeffs
{
n (2 1 1);
delta 0.001;
order xyz;
}
metisCoeffs
{
/*
processorWeights
(
1
1
1
1
);
*/
}
scotchCoeffs
{
//processorWeights
//(
// 1
// 1
// 1
// 1
//);
//writeGraph true;
//strategy "b";
}
manualCoeffs
{
dataFile "decompositionData";
}
structuredCoeffs
{
// Patches to do 2D decomposition on. Structured mesh only; cells have
// to be in 'columns' on top of patches.
patches (bottomPatch);
}
//// Is the case distributed? Note: command-line argument -roots takes
//// precedence
//distributed yes;
//// Per slave (so nProcs-1 entries) the directory above the case.
//roots
//(
// "/tmp"
// "/tmp"
//);
// ************************************************************************* //

View File

@ -1,110 +0,0 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: dev |
| \\ / A nd | Web: www.OpenFOAM.org |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class dictionary;
note "mesh renumbering dictionary";
object renumberMeshDict;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// Write maps from renumbered back to original mesh
writeMaps true;
// Optional entry: sort cells on coupled boundaries to last for use with
// e.g. nonBlockingGaussSeidel.
sortCoupledFaceCells false;
// Optional entry: renumber on a block-by-block basis. It uses a
// blockCoeffs dictionary to construct a decompositionMethod to do
// a block subdivision) and then applies the renumberMethod to each
// block in turn. This can be used in large cases to keep the blocks
// fitting in cache with all the the cache misses bunched at the end.
// This number is the approximate size of the blocks - this gets converted
// to a number of blocks that is the input to the decomposition method.
//blockSize 1000;
// Optional entry: sort points into internal and boundary points
//orderPoints false;
//method CuthillMcKee;
//method Sloan;
//method manual;
method random;
//method structured;
//method spring;
//method zoltan; // only if compiled with zoltan support
//CuthillMcKeeCoeffs
//{
// // Reverse CuthillMcKee (RCM) or plain
// reverse true;
//}
manualCoeffs
{
// In system directory: new-to-original (i.e. order) labelIOList
dataFile "cellMap";
}
// For extruded (i.e. structured in one direction) meshes
structuredCoeffs
{
// Patches that mesh was extruded from. These determine the starting
// layer of cells
patches (movingWall);
// Method to renumber the starting layer of cells
method random;
// Renumber in columns (depthFirst) or in layers
depthFirst true;
// Optional: reverse ordering
//reverse false;
}
springCoeffs
{
// Maximum jump of cell indices. Is fraction of number of cells
maxCo 0.01;
// Limit the amount of movement; the fraction maxCo gets decreased
// with every iteration
freezeFraction 0.999;
// Maximum number of iterations
maxIter 1000;
}
blockCoeffs
{
method scotch;
//method hierarchical;
//hierarchicalCoeffs
//{
// n (1 2 1);
// delta 0.001;
// order xyz;
//}
}
zoltanCoeffs
{
ORDER_METHOD LOCAL_HSFC;
}
// ************************************************************************* //

View File

@ -1,64 +0,0 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: 2.2.1 |
| \\ / A nd | Web: www.OpenFOAM.org |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class dictionary;
object topoSetDict;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
actions
(
// Get 'T' of faces
{
name f0;
type faceSet;
action new;
source boxToFace;
sourceInfo
{
boxes
(
(0.0499 -100 -100)(0.0501 100 100)
(0.03 0.0499 -100)(0.05 0.0501 100)
);
}
}
// // Pick up some cells
// {
// name c0;
// type cellSet;
// action new;
// source boxToCell;
// sourceInfo
// {
// boxes
// (
// (-100 -100 -100)(0.05 0.05 100)
// (0.05 0.05 -100)(100 100 100)
// );
// }
// }
// Convert faceSet to faceZone
{
name f0;
type faceZoneSet;
action new;
source setToFaceZone;
sourceInfo
{
faceSet f0;
}
}
);
// ************************************************************************* //

View File

@ -368,6 +368,8 @@ FoamFile
// { // {
// faceSet f0; // name of faceSet // faceSet f0; // name of faceSet
// cellSet c0; // name of cellSet of slave side // cellSet c0; // name of cellSet of slave side
// flip false; // optional: flip the faceZone (so now the cellSet
// // is the master side)
// } // }
// //
// // Select based on surface. Orientation from normals on surface // // Select based on surface. Orientation from normals on surface

View File

@ -46,8 +46,8 @@ int main(int argc, char *argv[])
); );
argList::noBanner(); argList::noBanner();
argList::noParallel();
argList::addBoolOption("times", "list available times"); argList::addBoolOption("times", "list available times");
argList::addBoolOption("latestTime", "list last time");
argList::addBoolOption argList::addBoolOption
( (
"keywords", "keywords",
@ -75,6 +75,15 @@ int main(int argc, char *argv[])
Info<< times[i].name() << endl; Info<< times[i].name() << endl;
} }
} }
else if (args.optionFound("latestTime"))
{
instantList times
(
Foam::Time::findTimes(args.rootPath()/args.caseName())
);
Info<< times.last().name() << endl;
}
if (args.optionFound("dict")) if (args.optionFound("dict"))
{ {

View File

@ -99,6 +99,40 @@ Usage
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
const labelIOList& procAddressing
(
const PtrList<fvMesh>& procMeshList,
const label procI,
const word& name,
PtrList<labelIOList>& procAddressingList
)
{
const fvMesh& procMesh = procMeshList[procI];
if (!procAddressingList.set(procI))
{
procAddressingList.set
(
procI,
new labelIOList
(
IOobject
(
name,
procMesh.facesInstance(),
procMesh.meshSubDir,
procMesh,
IOobject::MUST_READ,
IOobject::NO_WRITE
)
)
);
}
return procAddressingList[procI];
}
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
argList::addNote argList::addNote
@ -805,74 +839,29 @@ int main(int argc, char *argv[])
} }
const fvMesh& procMesh = procMeshList[procI]; const fvMesh& procMesh = procMeshList[procI];
const labelIOList& faceProcAddressing = procAddressing
if (!faceProcAddressingList.set(procI))
{
faceProcAddressingList.set
( (
procMeshList,
procI, procI,
new labelIOList
(
IOobject
(
"faceProcAddressing", "faceProcAddressing",
procMesh.facesInstance(), faceProcAddressingList
procMesh.meshSubDir,
procMesh,
IOobject::MUST_READ,
IOobject::NO_WRITE
)
)
); );
}
const labelIOList& faceProcAddressing =
faceProcAddressingList[procI];
const labelIOList& cellProcAddressing = procAddressing
if (!cellProcAddressingList.set(procI))
{
cellProcAddressingList.set
( (
procMeshList,
procI, procI,
new labelIOList
(
IOobject
(
"cellProcAddressing", "cellProcAddressing",
procMesh.facesInstance(), cellProcAddressingList
procMesh.meshSubDir,
procMesh,
IOobject::MUST_READ,
IOobject::NO_WRITE
)
)
); );
}
const labelIOList& cellProcAddressing =
cellProcAddressingList[procI];
const labelIOList& boundaryProcAddressing = procAddressing
if (!boundaryProcAddressingList.set(procI))
{
boundaryProcAddressingList.set
( (
procMeshList,
procI, procI,
new labelIOList
(
IOobject
(
"boundaryProcAddressing", "boundaryProcAddressing",
procMesh.facesInstance(), boundaryProcAddressingList
procMesh.meshSubDir,
procMesh,
IOobject::MUST_READ,
IOobject::NO_WRITE
)
)
); );
}
const labelIOList& boundaryProcAddressing =
boundaryProcAddressingList[procI];
// FV fields // FV fields
@ -959,27 +948,13 @@ int main(int argc, char *argv[])
|| pointTensorFields.size() || pointTensorFields.size()
) )
{ {
if (!pointProcAddressingList.set(procI)) const labelIOList& pointProcAddressing = procAddressing
{
pointProcAddressingList.set
( (
procMeshList,
procI, procI,
new labelIOList
(
IOobject
(
"pointProcAddressing", "pointProcAddressing",
procMesh.facesInstance(), pointProcAddressingList
procMesh.meshSubDir,
procMesh,
IOobject::MUST_READ,
IOobject::NO_WRITE
)
)
); );
}
const labelIOList& pointProcAddressing =
pointProcAddressingList[procI];
const pointMesh& procPMesh = pointMesh::New(procMesh); const pointMesh& procPMesh = pointMesh::New(procMesh);

View File

@ -38,6 +38,7 @@ License
#include "cellSet.H" #include "cellSet.H"
#include "faceSet.H" #include "faceSet.H"
#include "pointSet.H" #include "pointSet.H"
#include "uniformDimensionedFields.H"
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
@ -195,6 +196,60 @@ bool Foam::domainDecomposition::writeDecomposition(const bool decomposeSets)
} }
autoPtr<labelIOList> cellLevelPtr;
{
IOobject io
(
"cellLevel",
facesInstance(),
polyMesh::meshSubDir,
*this,
IOobject::MUST_READ,
IOobject::NO_WRITE
);
if (io.headerOk())
{
Info<< "Reading hexRef8 data : " << io.name() << endl;
cellLevelPtr.reset(new labelIOList(io));
}
}
autoPtr<labelIOList> pointLevelPtr;
{
IOobject io
(
"pointLevel",
facesInstance(),
polyMesh::meshSubDir,
*this,
IOobject::MUST_READ,
IOobject::NO_WRITE
);
if (io.headerOk())
{
Info<< "Reading hexRef8 data : " << io.name() << endl;
pointLevelPtr.reset(new labelIOList(io));
}
}
autoPtr<uniformDimensionedScalarField> level0EdgePtr;
{
IOobject io
(
"level0Edge",
facesInstance(),
polyMesh::meshSubDir,
*this,
IOobject::MUST_READ,
IOobject::NO_WRITE
);
if (io.headerOk())
{
Info<< "Reading hexRef8 data : " << io.name() << endl;
level0EdgePtr.reset(new uniformDimensionedScalarField(io));
}
}
label maxProcCells = 0; label maxProcCells = 0;
label totProcFaces = 0; label totProcFaces = 0;
label maxProcPatches = 0; label maxProcPatches = 0;
@ -767,8 +822,28 @@ bool Foam::domainDecomposition::writeDecomposition(const bool decomposeSets)
procMesh.write(); procMesh.write();
// Write points if pointsInstance differing from facesInstance
if (facesInstancePointsPtr_.valid())
{
pointIOField pointsInstancePoints
(
IOobject
(
"points",
pointsInstance(),
polyMesh::meshSubDir,
procMesh,
IOobject::NO_READ,
IOobject::NO_WRITE,
false
),
xferMove(procPoints)
);
pointsInstancePoints.write();
}
// Decompose any sets
if (decomposeSets) if (decomposeSets)
{ {
forAll(cellSets, i) forAll(cellSets, i)
@ -813,25 +888,67 @@ bool Foam::domainDecomposition::writeDecomposition(const bool decomposeSets)
} }
// Write points if pointsInstance differing from facesInstance // hexRef8 data
if (facesInstancePointsPtr_.valid()) if (cellLevelPtr.valid())
{ {
pointIOField pointsInstancePoints labelIOList
( (
IOobject IOobject
( (
"points", cellLevelPtr().name(),
pointsInstance(), facesInstance(),
polyMesh::meshSubDir, polyMesh::meshSubDir,
procMesh, procMesh,
IOobject::NO_READ, IOobject::NO_READ,
IOobject::NO_WRITE, IOobject::AUTO_WRITE
false
), ),
xferMove(procPoints) UIndirectList<label>
); (
pointsInstancePoints.write(); cellLevelPtr(),
procCellAddressing_[procI]
)()
).write();
} }
if (pointLevelPtr.valid())
{
labelIOList
(
IOobject
(
pointLevelPtr().name(),
facesInstance(),
polyMesh::meshSubDir,
procMesh,
IOobject::NO_READ,
IOobject::AUTO_WRITE
),
UIndirectList<label>
(
pointLevelPtr(),
procPointAddressing_[procI]
)()
).write();
}
if (level0EdgePtr.valid())
{
uniformDimensionedScalarField
(
IOobject
(
level0EdgePtr().name(),
facesInstance(),
polyMesh::meshSubDir,
procMesh,
IOobject::NO_READ,
IOobject::AUTO_WRITE
),
level0EdgePtr()
).write();
}
// Statistics
Info<< endl Info<< endl
<< "Processor " << procI << nl << "Processor " << procI << nl

View File

@ -2,7 +2,7 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2011 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -78,6 +78,26 @@ public:
hexes(nCells), hexes(nCells),
polys(nCells) polys(nCells)
{} {}
// Member Functions
void setSize(const label nCells)
{
nTets = 0;
nPyrs = 0;
nPrisms = 0;
nHexesWedges = 0;
nPolys = 0;
tets.setSize(nCells);
pyrs.setSize(nCells);
prisms.setSize(nCells);
wedges.setSize(nCells);
hexes.setSize(nCells);
polys.setSize(nCells);
}
}; };

View File

@ -47,7 +47,8 @@ License
void Foam::ensightMesh::correct() void Foam::ensightMesh::correct()
{ {
patchPartOffset_ = 2; patchPartOffset_ = 2;
meshCellSets_ = mesh_.nCells(); meshCellSets_.setSize(mesh_.nCells());
boundaryFaceSets_.setSize(mesh_.boundary().size()); boundaryFaceSets_.setSize(mesh_.boundary().size());
allPatchNames_.clear(); allPatchNames_.clear();
patchNames_.clear(); patchNames_.clear();
@ -193,8 +194,6 @@ void Foam::ensightMesh::correct()
if (!noPatches_) if (!noPatches_)
{ {
forAll(mesh_.boundary(), patchi) forAll(mesh_.boundary(), patchi)
{
if (mesh_.boundary()[patchi].size())
{ {
const polyPatch& p = mesh_.boundaryMesh()[patchi]; const polyPatch& p = mesh_.boundaryMesh()[patchi];
@ -233,7 +232,6 @@ void Foam::ensightMesh::correct()
polys.setSize(nPolys); polys.setSize(nPolys);
} }
} }
}
forAll(allPatchNames_, patchi) forAll(allPatchNames_, patchi)
{ {
@ -241,14 +239,11 @@ void Foam::ensightMesh::correct()
nFacePrimitives nfp; nFacePrimitives nfp;
if (patchNames_.empty() || patchNames_.found(patchName)) if (patchNames_.empty() || patchNames_.found(patchName))
{
if (mesh_.boundary()[patchi].size())
{ {
nfp.nTris = boundaryFaceSets_[patchi].tris.size(); nfp.nTris = boundaryFaceSets_[patchi].tris.size();
nfp.nQuads = boundaryFaceSets_[patchi].quads.size(); nfp.nQuads = boundaryFaceSets_[patchi].quads.size();
nfp.nPolys = boundaryFaceSets_[patchi].polys.size(); nfp.nPolys = boundaryFaceSets_[patchi].polys.size();
} }
}
reduce(nfp.nTris, sumOp<label>()); reduce(nfp.nTris, sumOp<label>());
reduce(nfp.nQuads, sumOp<label>()); reduce(nfp.nQuads, sumOp<label>());
@ -1148,6 +1143,7 @@ void Foam::ensightMesh::write
if (nfp.nTris || nfp.nQuads || nfp.nPolys) if (nfp.nTris || nfp.nQuads || nfp.nPolys)
{ {
const polyPatch& p = mesh_.boundaryMesh()[patchi]; const polyPatch& p = mesh_.boundaryMesh()[patchi];
const labelList& tris = boundaryFaceSets_[patchi].tris; const labelList& tris = boundaryFaceSets_[patchi].tris;
const labelList& quads = boundaryFaceSets_[patchi].quads; const labelList& quads = boundaryFaceSets_[patchi].quads;
const labelList& polys = boundaryFaceSets_[patchi].polys; const labelList& polys = boundaryFaceSets_[patchi].polys;

View File

@ -2,7 +2,7 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -441,8 +441,6 @@ void pqPV3FoamReaderPanel::IncludeZonesToggled()
void pqPV3FoamReaderPanel::ExtrapolatePatchesToggled() void pqPV3FoamReaderPanel::ExtrapolatePatchesToggled()
{ {
vtkSMProperty* prop;
vtkSMIntVectorProperty::SafeDownCast vtkSMIntVectorProperty::SafeDownCast
( (
this->proxy()->GetProperty("UiExtrapolatePatches") this->proxy()->GetProperty("UiExtrapolatePatches")
@ -454,8 +452,6 @@ void pqPV3FoamReaderPanel::ExtrapolatePatchesToggled()
void pqPV3FoamReaderPanel::InterpolateVolFieldsToggled() void pqPV3FoamReaderPanel::InterpolateVolFieldsToggled()
{ {
vtkSMProperty* prop;
vtkSMIntVectorProperty::SafeDownCast vtkSMIntVectorProperty::SafeDownCast
( (
this->proxy()->GetProperty("UiInterpolateVolFields") this->proxy()->GetProperty("UiInterpolateVolFields")

View File

@ -133,7 +133,8 @@ namespace Foam
//- initialise inotify //- initialise inotify
inline fileMonitorWatcher(const bool useInotify, const label sz = 20) inline fileMonitorWatcher(const bool useInotify, const label sz = 20)
: :
useInotify_(useInotify) useInotify_(useInotify),
inotifyFd_(-1)
{ {
if (useInotify_) if (useInotify_)
{ {

View File

@ -179,7 +179,7 @@ bool Foam::OutputFilterFunctionObject<OutputFilter>::execute
template<class OutputFilter> template<class OutputFilter>
bool Foam::OutputFilterFunctionObject<OutputFilter>::end() bool Foam::OutputFilterFunctionObject<OutputFilter>::end()
{ {
if (active()) if (enabled_)
{ {
if (!storeFilter_) if (!storeFilter_)
{ {

View File

@ -358,6 +358,59 @@ Type sum(const UList<Type>& f)
TMP_UNARY_FUNCTION(Type, sum) TMP_UNARY_FUNCTION(Type, sum)
template<class Type>
Type maxMagSqr(const UList<Type>& f)
{
if (f.size())
{
Type Max(f[0]);
TFOR_ALL_S_OP_FUNC_F_S
(
Type,
Max,
=,
maxMagSqrOp<Type>(),
Type,
f,
Type,
Max
)
return Max;
}
else
{
return pTraits<Type>::min;
}
}
TMP_UNARY_FUNCTION(Type, maxMagSqr)
template<class Type>
Type minMagSqr(const UList<Type>& f)
{
if (f.size())
{
Type Min(f[0]);
TFOR_ALL_S_OP_FUNC_F_S
(
Type,
Min,
=,
minMagSqrOp<Type>(),
Type,
f,
Type,
Min
)
return Min;
}
else
{
return pTraits<Type>::max;
}
}
TMP_UNARY_FUNCTION(Type, minMagSqr)
template<class Type> template<class Type>
scalar sumProd(const UList<Type>& f1, const UList<Type>& f2) scalar sumProd(const UList<Type>& f1, const UList<Type>& f2)
@ -488,6 +541,8 @@ TMP_UNARY_FUNCTION(ReturnType, gFunc)
G_UNARY_FUNCTION(Type, gMax, max, max) G_UNARY_FUNCTION(Type, gMax, max, max)
G_UNARY_FUNCTION(Type, gMin, min, min) G_UNARY_FUNCTION(Type, gMin, min, min)
G_UNARY_FUNCTION(Type, gSum, sum, sum) G_UNARY_FUNCTION(Type, gSum, sum, sum)
G_UNARY_FUNCTION(Type, gMaxMagSqr, maxMagSqr, maxMagSqr)
G_UNARY_FUNCTION(Type, gMinMagSqr, minMagSqr, minMagSqr)
G_UNARY_FUNCTION(scalar, gSumSqr, sumSqr, sum) G_UNARY_FUNCTION(scalar, gSumSqr, sumSqr, sum)
G_UNARY_FUNCTION(scalar, gSumMag, sumMag, sum) G_UNARY_FUNCTION(scalar, gSumMag, sumMag, sum)
G_UNARY_FUNCTION(Type, gSumCmptMag, sumCmptMag, sum) G_UNARY_FUNCTION(Type, gSumCmptMag, sumCmptMag, sum)

View File

@ -171,6 +171,16 @@ Type sum(const UList<Type>& f);
TMP_UNARY_FUNCTION(Type, sum) TMP_UNARY_FUNCTION(Type, sum)
template<class Type>
Type maxMagSqr(const UList<Type>& f);
TMP_UNARY_FUNCTION(Type, maxMagSqr)
template<class Type>
Type minMagSqr(const UList<Type>& f);
TMP_UNARY_FUNCTION(Type, minMagSqr)
template<class Type> template<class Type>
scalar sumProd(const UList<Type>& f1, const UList<Type>& f2); scalar sumProd(const UList<Type>& f1, const UList<Type>& f2);
@ -208,6 +218,8 @@ TMP_UNARY_FUNCTION(ReturnType, gFunc)
G_UNARY_FUNCTION(Type, gMax, max, max) G_UNARY_FUNCTION(Type, gMax, max, max)
G_UNARY_FUNCTION(Type, gMin, min, min) G_UNARY_FUNCTION(Type, gMin, min, min)
G_UNARY_FUNCTION(Type, gSum, sum, sum) G_UNARY_FUNCTION(Type, gSum, sum, sum)
G_UNARY_FUNCTION(Type, gMaxMagSqr, maxMagSqr, maxMagSqr)
G_UNARY_FUNCTION(Type, gMinMagSqr, minMagSqr, minMagSqr)
G_UNARY_FUNCTION(scalar, gSumSqr, sumSqr, sum) G_UNARY_FUNCTION(scalar, gSumSqr, sumSqr, sum)
G_UNARY_FUNCTION(scalar, gSumMag, sumMag, sum) G_UNARY_FUNCTION(scalar, gSumMag, sumMag, sum)
G_UNARY_FUNCTION(Type, gSumCmptMag, sumCmptMag, sum) G_UNARY_FUNCTION(Type, gSumCmptMag, sumCmptMag, sum)

View File

@ -927,6 +927,19 @@ Foam::word Foam::GeometricField<Type, PatchField, GeoMesh>::select
} }
template<class Type, template<class> class PatchField, class GeoMesh>
void Foam::GeometricField<Type, PatchField, GeoMesh>::writeMinMax
(
Ostream& os
) const
{
os << "min/max(" << this->name() << ") = "
<< Foam::min(*this).value() << ", "
<< Foam::max(*this).value()
<< endl;
}
// writeData member function required by regIOobject // writeData member function required by regIOobject
template<class Type, template<class> class PatchField, class GeoMesh> template<class Type, template<class> class PatchField, class GeoMesh>
bool Foam::GeometricField<Type, PatchField, GeoMesh>:: bool Foam::GeometricField<Type, PatchField, GeoMesh>::

View File

@ -2,7 +2,7 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -488,6 +488,9 @@ public:
// otherwise the standard parameters by returning the field name // otherwise the standard parameters by returning the field name
word select(bool final) const; word select(bool final) const;
//- Helper function to write the min and max to an Ostream
void writeMinMax(Ostream& os) const;
// Member function *this operators // Member function *this operators

View File

@ -2,7 +2,7 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2011 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -55,7 +55,9 @@ timeVaryingUniformFixedValuePointPatchField
: :
fixedValuePointPatchField<Type>(ptf, p, iF, mapper), fixedValuePointPatchField<Type>(ptf, p, iF, mapper),
timeSeries_(ptf.timeSeries_) timeSeries_(ptf.timeSeries_)
{} {
updateCoeffs();
}
template<class Type> template<class Type>

View File

@ -1963,7 +1963,7 @@ Foam::pointField Foam::globalMeshData::geometricSharedPoints() const
pointField sharedPoints(mesh_.points(), sharedPointLabels()); pointField sharedPoints(mesh_.points(), sharedPointLabels());
// Append from all processors // Append from all processors
combineReduce(sharedPoints, plusEqOp<pointField>()); combineReduce(sharedPoints, ListPlusEqOp<pointField>());
// Merge tolerance // Merge tolerance
scalar tolDim = matchTol_ * mesh_.bounds().mag(); scalar tolDim = matchTol_ * mesh_.bounds().mag();

View File

@ -109,29 +109,6 @@ class globalMeshData
public processorTopology public processorTopology
{ {
// Private class
// To combineReduce a pointField. Just appends all lists.
template<class T>
class plusEqOp
{
public:
void operator()(T& x, const T& y) const
{
label n = x.size();
x.setSize(x.size() + y.size());
forAll(y, i)
{
x[n++] = y[i];
}
}
};
// Private data // Private data
//- Reference to mesh //- Reference to mesh
@ -337,6 +314,29 @@ class globalMeshData
public: public:
// Public class
// To combineReduce a List. Just appends all lists.
template<class T>
class ListPlusEqOp
{
public:
void operator()(T& x, const T& y) const
{
label n = x.size();
x.setSize(x.size() + y.size());
forAll(y, i)
{
x[n++] = y[i];
}
}
};
//- Runtime type information //- Runtime type information
ClassName("globalMeshData"); ClassName("globalMeshData");

View File

@ -251,27 +251,35 @@ public:
{ {
public: public:
template<class T> template<class Type>
void operator() void operator()
( (
const vectorTensorTransform& vt, const vectorTensorTransform& vt,
const bool forward, const bool forward,
List<T>& fld List<Type>& fld
) const ) const
{ {
if (forward) const tensor T(forward ? vt.R() : vt.R().T());
{ transformList(T, fld);
transformList(vt.R(), fld);
} }
else
template<class Type>
void operator()
(
const vectorTensorTransform& vt,
const bool forward,
List<List<Type> >& flds
) const
{ {
transformList(vt.R().T(), fld); forAll(flds, i)
{
operator()(vt, forward, flds[i]);
} }
} }
//- Transform patch-based field //- Transform patch-based field
template<class T> template<class Type>
void operator()(const coupledPolyPatch& cpp, UList<T>& fld) const void operator()(const coupledPolyPatch& cpp, UList<Type>& fld) const
{ {
if (!cpp.parallel()) if (!cpp.parallel())
{ {
@ -280,8 +288,8 @@ public:
} }
//- Transform sparse field //- Transform sparse field
template<class T, template<class> class Container> template<class Type, template<class> class Container>
void operator()(const coupledPolyPatch& cpp, Container<T>& map) void operator()(const coupledPolyPatch& cpp, Container<Type>& map)
const const
{ {
if (!cpp.parallel()) if (!cpp.parallel())
@ -313,6 +321,18 @@ public:
fld = vt.invTransformPosition(pfld); fld = vt.invTransformPosition(pfld);
} }
} }
void operator()
(
const vectorTensorTransform& vt,
const bool forward,
List<List<point> >& flds
) const
{
forAll(flds, i)
{
operator()(vt, forward, flds[i]);
}
}
//- Transform patch-based field //- Transform patch-based field
void operator()(const coupledPolyPatch& cpp, pointField& fld) const void operator()(const coupledPolyPatch& cpp, pointField& fld) const
{ {

View File

@ -28,43 +28,6 @@ License
#include "indirectPrimitivePatch.H" #include "indirectPrimitivePatch.H"
#include "globalMeshData.H" #include "globalMeshData.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
//- Transformation
class listTransform
{
public:
void operator()
(
const vectorTensorTransform& vt,
const bool forward,
List<List<point> >& fld
) const
{
const tensor T
(
forward
? vt.R()
: vt.R().T()
);
forAll(fld, i)
{
List<point>& elems = fld[i];
forAll(elems, elemI)
{
elems[elemI] = transform(T, elems[elemI]);
}
}
}
};
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template template
@ -141,7 +104,7 @@ Foam::PatchTools::pointNormals
( (
transforms, transforms,
pointFaceNormals, pointFaceNormals,
listTransform() mapDistribute::transform()
); );

View File

@ -161,6 +161,9 @@ void Foam::layerAdditionRemoval::addCellLayer
forAll(mf, faceI) forAll(mf, faceI)
{ {
label cellI = mc[faceI];
label zoneI = mesh.cellZones().whichZone(cellI);
addedCells[faceI] = addedCells[faceI] =
ref.setAction ref.setAction
( (
@ -170,7 +173,7 @@ void Foam::layerAdditionRemoval::addCellLayer
-1, // master edge -1, // master edge
mf[faceI], // master face mf[faceI], // master face
-1, // master cell -1, // master cell
-1 // zone for cell zoneI // zone for cell
) )
); );
} }

View File

@ -219,7 +219,7 @@ Foam::label Foam::removePoints::countPointUsage
pointCanBeDeleted.setSize(mesh_.nPoints()); pointCanBeDeleted.setSize(mesh_.nPoints());
pointCanBeDeleted = false; pointCanBeDeleted = false;
label nDeleted = 0; //label nDeleted = 0;
forAll(edge0, pointI) forAll(edge0, pointI)
{ {
@ -243,14 +243,14 @@ Foam::label Foam::removePoints::countPointUsage
if ((e0Vec & e1Vec) > minCos) if ((e0Vec & e1Vec) > minCos)
{ {
pointCanBeDeleted[pointI] = true; pointCanBeDeleted[pointI] = true;
nDeleted++; //nDeleted++;
} }
} }
else if (edge0[pointI] == -1) else if (edge0[pointI] == -1)
{ {
// point not used at all // point not used at all
pointCanBeDeleted[pointI] = true; pointCanBeDeleted[pointI] = true;
nDeleted++; //nDeleted++;
} }
} }
edge0.clear(); edge0.clear();
@ -300,6 +300,15 @@ Foam::label Foam::removePoints::countPointUsage
true // null value true // null value
); );
label nDeleted = 0;
forAll(pointCanBeDeleted, pointI)
{
if (pointCanBeDeleted[pointI])
{
nDeleted++;
}
}
return returnReduce(nDeleted, sumOp<label>()); return returnReduce(nDeleted, sumOp<label>());
} }

View File

@ -165,21 +165,6 @@ mappedPatchFieldBase<Type>::sampleField() const
} }
template<class Type>
const interpolation<Type>& mappedPatchFieldBase<Type>::interpolator() const
{
if (!interpolator_.valid())
{
interpolator_ = interpolation<Type>::New
(
interpolationScheme_,
sampleField()
);
}
return interpolator_();
}
template<class Type> template<class Type>
tmp<Field<Type> > mappedPatchFieldBase<Type>::mappedField() const tmp<Field<Type> > mappedPatchFieldBase<Type>::mappedField() const
{ {
@ -218,6 +203,14 @@ tmp<Field<Type> > mappedPatchFieldBase<Type>::mappedField() const
samples samples
); );
autoPtr<interpolation<Type> > interpolator
(
interpolation<Type>::New
(
interpolationScheme_,
sampleField()
)
);
const interpolation<Type>& interp = interpolator(); const interpolation<Type>& interp = interpolator();
newValues.setSize(samples.size(), pTraits<Type>::max); newValues.setSize(samples.size(), pTraits<Type>::max);

View File

@ -88,11 +88,6 @@ protected:
//- Interpolation scheme to use for nearestcell mode //- Interpolation scheme to use for nearestcell mode
word interpolationScheme_; word interpolationScheme_;
mutable autoPtr<interpolation<Type> > interpolator_;
// Protected Member Functions
public: public:
@ -149,9 +144,6 @@ public:
//- Field to sample. Either on my or nbr mesh //- Field to sample. Either on my or nbr mesh
const GeometricField<Type, fvPatchField, volMesh>& sampleField() const; const GeometricField<Type, fvPatchField, volMesh>& sampleField() const;
//- Access the interpolation method
const interpolation<Type>& interpolator() const;
//- Map sampleField onto *this patch //- Map sampleField onto *this patch
virtual tmp<Field<Type> > mappedField() const; virtual tmp<Field<Type> > mappedField() const;

View File

@ -2,7 +2,7 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -36,6 +36,7 @@ SourceFiles
#define fvScalarMatrix_H #define fvScalarMatrix_H
#include "fvMatrix.H" #include "fvMatrix.H"
#include "fvMatricesFwd.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View File

@ -2,7 +2,7 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2011 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -35,7 +35,15 @@ Foam::interpolationCellPoint<Type>::interpolationCellPoint
) )
: :
interpolation<Type>(psi), interpolation<Type>(psi),
psip_(volPointInterpolation::New(psi.mesh()).interpolate(psi)) psip_
(
volPointInterpolation::New(psi.mesh()).interpolate
(
psi,
"volPointInterpolate(" + psi.name() + ')',
true // use cache
)
)
{ {
// Uses cellPointWeight to do interpolation which needs tet decomposition // Uses cellPointWeight to do interpolation which needs tet decomposition
(void)psi.mesh().tetBasePtIs(); (void)psi.mesh().tetBasePtIs();

View File

@ -2,7 +2,7 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2011 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -45,7 +45,15 @@ interpolationCellPointFace<Type>::interpolationCellPointFace
) )
: :
interpolation<Type>(psi), interpolation<Type>(psi),
psip_(volPointInterpolation::New(psi.mesh()).interpolate(psi)), psip_
(
volPointInterpolation::New(psi.mesh()).interpolate
(
psi,
"volPointInterpolate(" + psi.name() + ')',
true // use cache
)
),
psis_(linearInterpolate(psi)) psis_(linearInterpolate(psi))
{} {}

View File

@ -2,7 +2,7 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2011 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -35,7 +35,15 @@ Foam::interpolationPointMVC<Type>::interpolationPointMVC
) )
: :
interpolation<Type>(psi), interpolation<Type>(psi),
psip_(volPointInterpolation::New(psi.mesh()).interpolate(psi)) psip_
(
volPointInterpolation::New(psi.mesh()).interpolate
(
psi,
"volPointInterpolate(" + psi.name() + ')',
true // use cache
)
)
{} {}

View File

@ -2,7 +2,7 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -28,33 +28,17 @@ License
#include "fvcGrad.H" #include "fvcGrad.H"
#include "coupledFvPatchFields.H" #include "coupledFvPatchFields.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * * //
template<class Type, class Limiter, template<class> class LimitFunc> template<class Type, class Limiter, template<class> class LimitFunc>
Foam::tmp<Foam::surfaceScalarField> void Foam::LimitedScheme<Type, Limiter, LimitFunc>::calcLimiter
Foam::LimitedScheme<Type, Limiter, LimitFunc>::limiter
( (
const GeometricField<Type, fvPatchField, volMesh>& phi const GeometricField<Type, fvPatchField, volMesh>& phi,
surfaceScalarField& limiterField
) const ) const
{ {
const fvMesh& mesh = this->mesh(); const fvMesh& mesh = this->mesh();
tmp<surfaceScalarField> tLimiter
(
new surfaceScalarField
(
IOobject
(
type() + "Limiter(" + phi.name() + ')',
mesh.time().timeName(),
mesh
),
mesh,
dimless
)
);
surfaceScalarField& lim = tLimiter();
tmp<GeometricField<typename Limiter::phiType, fvPatchField, volMesh> > tmp<GeometricField<typename Limiter::phiType, fvPatchField, volMesh> >
tlPhi = LimitFunc<Type>()(phi); tlPhi = LimitFunc<Type>()(phi);
@ -73,7 +57,7 @@ Foam::LimitedScheme<Type, Limiter, LimitFunc>::limiter
const vectorField& C = mesh.C(); const vectorField& C = mesh.C();
scalarField& pLim = lim.internalField(); scalarField& pLim = limiterField.internalField();
forAll(pLim, face) forAll(pLim, face)
{ {
@ -92,7 +76,8 @@ Foam::LimitedScheme<Type, Limiter, LimitFunc>::limiter
); );
} }
surfaceScalarField::GeometricBoundaryField& bLim = lim.boundaryField(); surfaceScalarField::GeometricBoundaryField& bLim =
limiterField.boundaryField();
forAll(bLim, patchi) forAll(bLim, patchi)
{ {
@ -143,8 +128,80 @@ Foam::LimitedScheme<Type, Limiter, LimitFunc>::limiter
pLim = 1.0; pLim = 1.0;
} }
} }
}
return tLimiter;
// * * * * * * * * * * * * Public Member Functions * * * * * * * * * * * * //
template<class Type, class Limiter, template<class> class LimitFunc>
Foam::tmp<Foam::surfaceScalarField>
Foam::LimitedScheme<Type, Limiter, LimitFunc>::limiter
(
const GeometricField<Type, fvPatchField, volMesh>& phi
) const
{
const fvMesh& mesh = this->mesh();
const word limiterFieldName(type() + "Limiter(" + phi.name() + ')');
if (this->mesh().cache("limiter"))
{
if (!mesh.foundObject<surfaceScalarField>(limiterFieldName))
{
surfaceScalarField* limiterField
(
new surfaceScalarField
(
IOobject
(
limiterFieldName,
mesh.time().timeName(),
mesh,
IOobject::NO_READ,
IOobject::NO_WRITE
),
mesh,
dimless
)
);
mesh.objectRegistry::store(limiterField);
}
surfaceScalarField& limiterField =
const_cast<surfaceScalarField&>
(
mesh.lookupObject<surfaceScalarField>
(
limiterFieldName
)
);
calcLimiter(phi, limiterField);
return limiterField;
}
else
{
tmp<surfaceScalarField> tlimiterField
(
new surfaceScalarField
(
IOobject
(
limiterFieldName,
mesh.time().timeName(),
mesh
),
mesh,
dimless
)
);
calcLimiter(phi, tlimiterField());
return tlimiterField;
}
} }

View File

@ -2,7 +2,7 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2011 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -68,6 +68,13 @@ class LimitedScheme
{ {
// Private Member Functions // Private Member Functions
//- Calculate the limiter
void calcLimiter
(
const GeometricField<Type, fvPatchField, volMesh>& phi,
surfaceScalarField& limiterField
) const;
//- Disallow default bitwise copy construct //- Disallow default bitwise copy construct
LimitedScheme(const LimitedScheme&); LimitedScheme(const LimitedScheme&);

View File

@ -82,6 +82,41 @@ Description
} }
\endverbatim \endverbatim
The effectiveness table is described in terms of the primary and secondary
mass flow rates. For example, the table:
secondary MFR
| 0.1 0.2 0.3
-----+-----------------
0.02 | A B C
primary MFR 0.04 | D E F
0.06 | G H I
Is specified by the following:
(
0.02
(
(0.1 A)
(0.2 B)
(0.3 C)
),
0.04
(
(0.1 D)
(0.2 E)
(0.3 F)
),
0.06
(
(0.1 G)
(0.2 H)
(0.3 I)
)
);
Note Note
- the table with name "fileName" should have the same units as the - the table with name "fileName" should have the same units as the
secondary mass flow rate and kg/s for phi secondary mass flow rate and kg/s for phi

View File

@ -189,7 +189,7 @@ void Foam::fv::SemiImplicitSource<Type>::addSup
UIndirectList<scalar>(Sp, cells_) = injectionRate_[fieldI].second()/VDash_; UIndirectList<scalar>(Sp, cells_) = injectionRate_[fieldI].second()/VDash_;
eqn += Su + fvm::Sp(Sp, psi); eqn += Su + fvm::SuSp(Sp, psi);
} }

View File

@ -110,7 +110,7 @@ void Foam::cloudSolution::read()
dict_.lookup("transient") >> transient_; dict_.lookup("transient") >> transient_;
dict_.lookup("coupled") >> coupled_; dict_.lookup("coupled") >> coupled_;
dict_.lookup("cellValueSourceCorrection") >> cellValueSourceCorrection_; dict_.lookup("cellValueSourceCorrection") >> cellValueSourceCorrection_;
dict_.lookup("maxCo") >> maxCo_; dict_.readIfPresent("maxCo", maxCo_);
if (steadyState()) if (steadyState())
{ {

View File

@ -2,7 +2,7 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -31,7 +31,7 @@ Description
- list of injector positions and directions (along injection axes) - list of injector positions and directions (along injection axes)
- number of parcels to inject per injector - number of parcels to inject per injector
- parcel velocities - parcel velocities
- inner and outer cone angles - inner and outer half-cone angles
- Parcel diameters obtained by distribution model - Parcel diameters obtained by distribution model
SourceFiles SourceFiles
@ -87,10 +87,10 @@ class ConeInjection
//- Parcel velocity magnitude relative to SOI [m/s] //- Parcel velocity magnitude relative to SOI [m/s]
const TimeDataEntry<scalar> Umag_; const TimeDataEntry<scalar> Umag_;
//- Inner cone angle relative to SOI [deg] //- Inner half-cone angle relative to SOI [deg]
const TimeDataEntry<scalar> thetaInner_; const TimeDataEntry<scalar> thetaInner_;
//- Outer cone angle relative to SOI [deg] //- Outer half-cone angle relative to SOI [deg]
const TimeDataEntry<scalar> thetaOuter_; const TimeDataEntry<scalar> thetaOuter_;
//- Parcel size distribution model //- Parcel size distribution model

View File

@ -2,7 +2,7 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -32,7 +32,7 @@ Description
- injector position - injector position
- direction (along injection axis) - direction (along injection axis)
- parcel flow rate - parcel flow rate
- inner and outer cone angles - inner and outer half-cone angles
- Parcel diameters obtained by size distribution model - Parcel diameters obtained by size distribution model
@ -134,10 +134,10 @@ private:
//- Flow rate profile relative to SOI [] //- Flow rate profile relative to SOI []
const TimeDataEntry<scalar> flowRateProfile_; const TimeDataEntry<scalar> flowRateProfile_;
//- Inner cone angle relative to SOI [deg] //- Inner half-cone angle relative to SOI [deg]
const TimeDataEntry<scalar> thetaInner_; const TimeDataEntry<scalar> thetaInner_;
//- Outer cone angle relative to SOI [deg] //- Outer half-cone angle relative to SOI [deg]
const TimeDataEntry<scalar> thetaOuter_; const TimeDataEntry<scalar> thetaOuter_;
//- Parcel size PDF model //- Parcel size PDF model

View File

@ -550,7 +550,7 @@ void Foam::InjectionModel<CloudType>::inject(TrackData& td)
if (cellI > -1) if (cellI > -1)
{ {
// Lagrangian timestep // Lagrangian timestep
scalar dt = time - timeInj; const scalar dt = time - timeInj;
// Apply corrections to position for 2-D cases // Apply corrections to position for 2-D cases
meshTools::constrainToMeshCentre(mesh, pos); meshTools::constrainToMeshCentre(mesh, pos);
@ -586,8 +586,11 @@ void Foam::InjectionModel<CloudType>::inject(TrackData& td)
pPtr->rho() pPtr->rho()
); );
const scalar mParcel0 = pPtr->nParticle()*pPtr->mass();
if (!pPtr->move(td, dt)) if (!pPtr->move(td, dt))
{ {
massAdded += mParcel0;
delete pPtr; delete pPtr;
} }
else else
@ -595,7 +598,7 @@ void Foam::InjectionModel<CloudType>::inject(TrackData& td)
if (pPtr->nParticle() >= 1.0) if (pPtr->nParticle() >= 1.0)
{ {
td.cloud().addParticle(pPtr); td.cloud().addParticle(pPtr);
massAdded += pPtr->nParticle()*pPtr->mass(); massAdded += mParcel0;
parcelsAdded++; parcelsAdded++;
} }
else else

View File

@ -1262,6 +1262,9 @@ void Foam::autoLayerDriver::calculateLayerThickness
<< setf(ios_base::left) << setw(maxPatchNameLen) << "-----" << setf(ios_base::left) << setw(maxPatchNameLen) << "-----"
<< setw(0) << " ----- ------ --------- -------" << endl; << setw(0) << " ----- ------ --------- -------" << endl;
const PackedBoolList isMasterPoint(syncTools::getMasterPoints(mesh));
forAll(patchIDs, i) forAll(patchIDs, i)
{ {
label patchI = patchIDs[i]; label patchI = patchIDs[i];
@ -1270,10 +1273,14 @@ void Foam::autoLayerDriver::calculateLayerThickness
scalar sumThickness = 0; scalar sumThickness = 0;
scalar sumNearWallThickness = 0; scalar sumNearWallThickness = 0;
label nMasterPoints = 0;
forAll(meshPoints, patchPointI) forAll(meshPoints, patchPointI)
{ {
label ppPointI = pp.meshPointMap()[meshPoints[patchPointI]]; label meshPointI = meshPoints[patchPointI];
if (isMasterPoint[meshPointI])
{
label ppPointI = pp.meshPointMap()[meshPointI];
sumThickness += thickness[ppPointI]; sumThickness += thickness[ppPointI];
sumNearWallThickness += layerParams.firstLayerThickness sumNearWallThickness += layerParams.firstLayerThickness
@ -1284,9 +1291,11 @@ void Foam::autoLayerDriver::calculateLayerThickness
thickness[ppPointI], thickness[ppPointI],
expansionRatio[ppPointI] expansionRatio[ppPointI]
); );
nMasterPoints++;
}
} }
label totNPoints = returnReduce(meshPoints.size(), sumOp<label>()); label totNPoints = returnReduce(nMasterPoints, sumOp<label>());
// For empty patches, totNPoints is 0. // For empty patches, totNPoints is 0.
scalar avgThickness = 0; scalar avgThickness = 0;
@ -1319,7 +1328,7 @@ void Foam::autoLayerDriver::calculateLayerThickness
// Synchronize displacement among coupled patches. // Synchronize displacement among coupled patches.
void Foam::autoLayerDriver::syncPatchDisplacement void Foam::autoLayerDriver::syncPatchDisplacement
( (
const motionSmoother& meshMover, const indirectPrimitivePatch& pp,
const scalarField& minThickness, const scalarField& minThickness,
pointField& patchDisp, pointField& patchDisp,
labelList& patchNLayers, labelList& patchNLayers,
@ -1327,7 +1336,7 @@ void Foam::autoLayerDriver::syncPatchDisplacement
) const ) const
{ {
const fvMesh& mesh = meshRefiner_.mesh(); const fvMesh& mesh = meshRefiner_.mesh();
const labelList& meshPoints = meshMover.patch().meshPoints(); const labelList& meshPoints = pp.meshPoints();
label nChangedTotal = 0; label nChangedTotal = 0;
@ -1437,9 +1446,9 @@ void Foam::autoLayerDriver::syncPatchDisplacement
} }
} }
Info<< "Prevented extrusion on " //Info<< "Prevented extrusion on "
<< returnReduce(nChangedTotal, sumOp<label>()) // << returnReduce(nChangedTotal, sumOp<label>())
<< " coupled patch points during syncPatchDisplacement." << endl; // << " coupled patch points during syncPatchDisplacement." << endl;
} }
@ -1569,7 +1578,7 @@ void Foam::autoLayerDriver::getPatchDisplacement
// Make sure displacement is equal on both sides of coupled patches. // Make sure displacement is equal on both sides of coupled patches.
syncPatchDisplacement syncPatchDisplacement
( (
meshMover, pp,
minThickness, minThickness,
patchDisp, patchDisp,
patchNLayers, patchNLayers,
@ -1767,7 +1776,7 @@ Foam::label Foam::autoLayerDriver::truncateDisplacement
{ {
syncPatchDisplacement syncPatchDisplacement
( (
meshMover, pp,
minThickness, minThickness,
patchDisp, patchDisp,
patchNLayers, patchNLayers,
@ -2856,7 +2865,7 @@ void Foam::autoLayerDriver::addLayers
// Make sure displacement is equal on both sides of coupled patches. // Make sure displacement is equal on both sides of coupled patches.
syncPatchDisplacement syncPatchDisplacement
( (
meshMover, pp,
minThickness, minThickness,
patchDisp, patchDisp,
patchNLayers, patchNLayers,

View File

@ -257,7 +257,7 @@ class autoLayerDriver
//- Synchronize displacement among coupled patches. //- Synchronize displacement among coupled patches.
void syncPatchDisplacement void syncPatchDisplacement
( (
const motionSmoother& meshMover, const indirectPrimitivePatch& pp,
const scalarField& minThickness, const scalarField& minThickness,
pointField& patchDisp, pointField& patchDisp,
labelList& patchNLayers, labelList& patchNLayers,
@ -403,6 +403,7 @@ class autoLayerDriver
void smoothField void smoothField
( (
const motionSmoother& meshMover, const motionSmoother& meshMover,
const PackedBoolList& isMasterPoint,
const PackedBoolList& isMasterEdge, const PackedBoolList& isMasterEdge,
const labelList& meshEdges, const labelList& meshEdges,
const scalarField& fieldMin, const scalarField& fieldMin,
@ -414,6 +415,7 @@ class autoLayerDriver
void smoothPatchNormals void smoothPatchNormals
( (
const motionSmoother& meshMover, const motionSmoother& meshMover,
const PackedBoolList& isMasterPoint,
const PackedBoolList& isMasterEdge, const PackedBoolList& isMasterEdge,
const labelList& meshEdges, const labelList& meshEdges,
const label nSmoothDisp, const label nSmoothDisp,
@ -424,6 +426,7 @@ class autoLayerDriver
void smoothNormals void smoothNormals
( (
const label nSmoothDisp, const label nSmoothDisp,
const PackedBoolList& isMasterPoint,
const PackedBoolList& isMasterEdge, const PackedBoolList& isMasterEdge,
const labelList& fixedPoints, const labelList& fixedPoints,
pointVectorField& normals pointVectorField& normals
@ -440,8 +443,11 @@ class autoLayerDriver
// large feature angle // large feature angle
void handleFeatureAngleLayerTerminations void handleFeatureAngleLayerTerminations
( (
const indirectPrimitivePatch& pp,
const scalar minCos, const scalar minCos,
const PackedBoolList& isMasterPoint,
const indirectPrimitivePatch& pp,
const labelList& meshEdges,
List<extrudeMode>& extrudeStatus, List<extrudeMode>& extrudeStatus,
pointField& patchDisp, pointField& patchDisp,
labelList& patchNLayers, labelList& patchNLayers,
@ -453,10 +459,13 @@ class autoLayerDriver
// in the layer mesh and stop any layer growth at these points. // in the layer mesh and stop any layer growth at these points.
void findIsolatedRegions void findIsolatedRegions
( (
const indirectPrimitivePatch& pp,
const PackedBoolList& isMasterEdge,
const labelList& meshEdges,
const scalar minCosLayerTermination, const scalar minCosLayerTermination,
const PackedBoolList& isMasterPoint,
const PackedBoolList& isMasterEdge,
const indirectPrimitivePatch& pp,
const labelList& meshEdges,
const scalarField& minThickness,
List<extrudeMode>& extrudeStatus, List<extrudeMode>& extrudeStatus,
pointField& patchDisp, pointField& patchDisp,
labelList& patchNLayers labelList& patchNLayers

View File

@ -103,6 +103,7 @@ void Foam::autoLayerDriver::sumWeights
void Foam::autoLayerDriver::smoothField void Foam::autoLayerDriver::smoothField
( (
const motionSmoother& meshMover, const motionSmoother& meshMover,
const PackedBoolList& isMasterPoint,
const PackedBoolList& isMasterEdge, const PackedBoolList& isMasterEdge,
const labelList& meshEdges, const labelList& meshEdges,
const scalarField& fieldMin, const scalarField& fieldMin,
@ -136,7 +137,7 @@ void Foam::autoLayerDriver::smoothField
isMasterEdge, isMasterEdge,
meshEdges, meshEdges,
meshPoints, meshPoints,
pp.edges(), edges,
invSumWeight, invSumWeight,
field, field,
average average
@ -162,10 +163,14 @@ void Foam::autoLayerDriver::smoothField
// Do residual calculation every so often. // Do residual calculation every so often.
if ((iter % 10) == 0) if ((iter % 10) == 0)
{ {
Info<< " Iteration " << iter << " residual " scalar resid = meshRefinement::gAverage
<< gSum(mag(field-average)) (
/returnReduce(average.size(), sumOp<label>()) meshMover.mesh(),
<< endl; isMasterPoint,
meshPoints,
mag(field-average)()
);
Info<< " Iteration " << iter << " residual " << resid << endl;
} }
} }
} }
@ -265,6 +270,7 @@ void Foam::autoLayerDriver::smoothField
void Foam::autoLayerDriver::smoothPatchNormals void Foam::autoLayerDriver::smoothPatchNormals
( (
const motionSmoother& meshMover, const motionSmoother& meshMover,
const PackedBoolList& isMasterPoint,
const PackedBoolList& isMasterEdge, const PackedBoolList& isMasterEdge,
const labelList& meshEdges, const labelList& meshEdges,
const label nSmoothDisp, const label nSmoothDisp,
@ -299,7 +305,7 @@ void Foam::autoLayerDriver::smoothPatchNormals
isMasterEdge, isMasterEdge,
meshEdges, meshEdges,
meshPoints, meshPoints,
pp.edges(), edges,
invSumWeight, invSumWeight,
normals, normals,
average average
@ -308,10 +314,14 @@ void Foam::autoLayerDriver::smoothPatchNormals
// Do residual calculation every so often. // Do residual calculation every so often.
if ((iter % 10) == 0) if ((iter % 10) == 0)
{ {
Info<< " Iteration " << iter << " residual " scalar resid = meshRefinement::gAverage
<< gSum(mag(normals-average)) (
/returnReduce(average.size(), sumOp<label>()) meshMover.mesh(),
<< endl; isMasterPoint,
meshPoints,
mag(normals-average)()
);
Info<< " Iteration " << iter << " residual " << resid << endl;
} }
// Transfer to normals vector field // Transfer to normals vector field
@ -330,6 +340,7 @@ void Foam::autoLayerDriver::smoothPatchNormals
void Foam::autoLayerDriver::smoothNormals void Foam::autoLayerDriver::smoothNormals
( (
const label nSmoothDisp, const label nSmoothDisp,
const PackedBoolList& isMasterPoint,
const PackedBoolList& isMasterEdge, const PackedBoolList& isMasterEdge,
const labelList& fixedPoints, const labelList& fixedPoints,
pointVectorField& normals pointVectorField& normals
@ -372,8 +383,6 @@ void Foam::autoLayerDriver::smoothNormals
invSumWeight invSumWeight
); );
Info<< "shrinkMeshDistance : Smoothing normals in interior ..." << endl;
for (label iter = 0; iter < nSmoothDisp; iter++) for (label iter = 0; iter < nSmoothDisp; iter++)
{ {
vectorField average(mesh.nPoints()); vectorField average(mesh.nPoints());
@ -392,10 +401,13 @@ void Foam::autoLayerDriver::smoothNormals
// Do residual calculation every so often. // Do residual calculation every so often.
if ((iter % 10) == 0) if ((iter % 10) == 0)
{ {
Info<< " Iteration " << iter << " residual " scalar resid = meshRefinement::gAverage
<< gSum(mag(normals-average)) (
/returnReduce(average.size(), sumOp<label>()) mesh,
<< endl; isMasterPoint,
mag(normals-average)()
);
Info<< " Iteration " << iter << " residual " << resid << endl;
} }
@ -479,14 +491,18 @@ bool Foam::autoLayerDriver::isMaxEdge
// large feature angle // large feature angle
void Foam::autoLayerDriver::handleFeatureAngleLayerTerminations void Foam::autoLayerDriver::handleFeatureAngleLayerTerminations
( (
const indirectPrimitivePatch& pp,
const scalar minCos, const scalar minCos,
const PackedBoolList& isMasterPoint,
const indirectPrimitivePatch& pp,
const labelList& meshEdges,
List<extrudeMode>& extrudeStatus, List<extrudeMode>& extrudeStatus,
pointField& patchDisp, pointField& patchDisp,
labelList& patchNLayers, labelList& patchNLayers,
label& nPointCounter label& nPointCounter
) const ) const
{ {
const fvMesh& mesh = meshRefiner_.mesh();
// Mark faces that have all points extruded // Mark faces that have all points extruded
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@ -507,15 +523,60 @@ void Foam::autoLayerDriver::handleFeatureAngleLayerTerminations
} }
//label nOldPointCounter = nPointCounter;
// Detect situation where two featureedge-neighbouring faces are partly or // Detect situation where two featureedge-neighbouring faces are partly or
// not extruded and the edge itself is extruded. In this case unmark the // not extruded and the edge itself is extruded. In this case unmark the
// edge for extrusion. // edge for extrusion.
forAll(pp.edgeFaces(), edgeI)
{
const labelList& eFaces = pp.edgeFaces()[edgeI];
if (eFaces.size() == 2) List<List<point> > edgeFaceNormals(pp.nEdges());
List<List<bool> > edgeFaceExtrude(pp.nEdges());
const labelListList& edgeFaces = pp.edgeFaces();
const vectorField& faceNormals = pp.faceNormals();
const labelList& meshPoints = pp.meshPoints();
forAll(edgeFaces, edgeI)
{
const labelList& eFaces = edgeFaces[edgeI];
edgeFaceNormals[edgeI].setSize(eFaces.size());
edgeFaceExtrude[edgeI].setSize(eFaces.size());
forAll(eFaces, i)
{
label faceI = eFaces[i];
edgeFaceNormals[edgeI][i] = faceNormals[faceI];
edgeFaceExtrude[edgeI][i] = extrudedFaces[faceI];
}
}
syncTools::syncEdgeList
(
mesh,
meshEdges,
edgeFaceNormals,
globalMeshData::ListPlusEqOp<List<point> >(), // combine operator
List<point>() // null value
);
syncTools::syncEdgeList
(
mesh,
meshEdges,
edgeFaceExtrude,
globalMeshData::ListPlusEqOp<List<bool> >(), // combine operator
List<bool>() // null value
);
forAll(edgeFaceNormals, edgeI)
{
const List<point>& eFaceNormals = edgeFaceNormals[edgeI];
const List<bool>& eFaceExtrude = edgeFaceExtrude[edgeI];
if (eFaceNormals.size() == 2)
{ {
const edge& e = pp.edges()[edgeI]; const edge& e = pp.edges()[edgeI];
label v0 = e[0]; label v0 = e[0];
@ -527,10 +588,10 @@ void Foam::autoLayerDriver::handleFeatureAngleLayerTerminations
|| extrudeStatus[v1] != NOEXTRUDE || extrudeStatus[v1] != NOEXTRUDE
) )
{ {
if (!extrudedFaces[eFaces[0]] || !extrudedFaces[eFaces[1]]) if (!eFaceExtrude[0] || !eFaceExtrude[1])
{ {
const vector& n0 = pp.faceNormals()[eFaces[0]]; const vector& n0 = eFaceNormals[0];
const vector& n1 = pp.faceNormals()[eFaces[1]]; const vector& n1 = eFaceNormals[1];
if ((n0 & n1) < minCos) if ((n0 & n1) < minCos)
{ {
@ -544,9 +605,12 @@ void Foam::autoLayerDriver::handleFeatureAngleLayerTerminations
extrudeStatus extrudeStatus
) )
) )
{
if (isMasterPoint[meshPoints[v0]])
{ {
nPointCounter++; nPointCounter++;
} }
}
if if
( (
unmarkExtrusion unmarkExtrusion
@ -557,6 +621,8 @@ void Foam::autoLayerDriver::handleFeatureAngleLayerTerminations
extrudeStatus extrudeStatus
) )
) )
{
if (isMasterPoint[meshPoints[v1]])
{ {
nPointCounter++; nPointCounter++;
} }
@ -565,6 +631,11 @@ void Foam::autoLayerDriver::handleFeatureAngleLayerTerminations
} }
} }
} }
}
//Info<< "Added "
// << returnReduce(nPointCounter-nOldPointCounter, sumOp<label>())
// << " point not to extrude." << endl;
} }
@ -572,10 +643,12 @@ void Foam::autoLayerDriver::handleFeatureAngleLayerTerminations
// in the layer mesh and stop any layer growth at these points. // in the layer mesh and stop any layer growth at these points.
void Foam::autoLayerDriver::findIsolatedRegions void Foam::autoLayerDriver::findIsolatedRegions
( (
const indirectPrimitivePatch& pp,
const PackedBoolList& isMasterEdge,
const labelList& meshEdges,
const scalar minCosLayerTermination, const scalar minCosLayerTermination,
const PackedBoolList& isMasterPoint,
const PackedBoolList& isMasterEdge,
const indirectPrimitivePatch& pp,
const labelList& meshEdges,
const scalarField& minThickness,
List<extrudeMode>& extrudeStatus, List<extrudeMode>& extrudeStatus,
pointField& patchDisp, pointField& patchDisp,
labelList& patchNLayers labelList& patchNLayers
@ -594,8 +667,10 @@ void Foam::autoLayerDriver::findIsolatedRegions
// large feature angle // large feature angle
handleFeatureAngleLayerTerminations handleFeatureAngleLayerTerminations
( (
pp,
minCosLayerTermination, minCosLayerTermination,
isMasterPoint,
pp,
meshEdges,
extrudeStatus, extrudeStatus,
patchDisp, patchDisp,
@ -603,6 +678,15 @@ void Foam::autoLayerDriver::findIsolatedRegions
nPointCounter nPointCounter
); );
syncPatchDisplacement
(
pp,
minThickness,
patchDisp,
patchNLayers,
extrudeStatus
);
// Do not extrude from point where all neighbouring // Do not extrude from point where all neighbouring
// faces are not grown // faces are not grown
@ -802,25 +886,18 @@ void Foam::autoLayerDriver::medialAxisSmoothingInfo
// Predetermine mesh edges // Predetermine mesh edges
// ~~~~~~~~~~~~~~~~~~~~~~~ // ~~~~~~~~~~~~~~~~~~~~~~~
// Precalulate master edge (only relevant for shared edges) // Precalulate master point/edge (only relevant for shared points/edges)
PackedBoolList isMasterEdge(syncTools::getMasterEdges(mesh)); const PackedBoolList isMasterPoint(syncTools::getMasterPoints(mesh));
const PackedBoolList isMasterEdge(syncTools::getMasterEdges(mesh));
// Precalculate meshEdge per pp edge // Precalculate meshEdge per pp edge
labelList meshEdges(pp.nEdges()); const labelList meshEdges
(
forAll(meshEdges, patchEdgeI) pp.meshEdges
{
const edge& e = pp.edges()[patchEdgeI];
label v0 = pp.meshPoints()[e[0]];
label v1 = pp.meshPoints()[e[1]];
meshEdges[patchEdgeI] = meshTools::findEdge
( (
mesh.edges(), mesh.edges(),
mesh.pointEdges()[v0], mesh.pointEdges()
v0, )
v1
); );
}
// Determine pointNormal // Determine pointNormal
@ -832,7 +909,7 @@ void Foam::autoLayerDriver::medialAxisSmoothingInfo
if (debug&meshRefinement::MESH || debug&meshRefinement::LAYERINFO) if (debug&meshRefinement::MESH || debug&meshRefinement::LAYERINFO)
{ {
pointField meshPointNormals(mesh.nPoints(), point(1, 0, 0)); pointField meshPointNormals(mesh.nPoints(), point(1, 0, 0));
UIndirectList<point>(meshPointNormals, pp.meshPoints()) = pointNormals; UIndirectList<point>(meshPointNormals, meshPoints) = pointNormals;
meshRefinement::testSyncPointList meshRefinement::testSyncPointList
( (
"pointNormals", "pointNormals",
@ -845,6 +922,7 @@ void Foam::autoLayerDriver::medialAxisSmoothingInfo
smoothPatchNormals smoothPatchNormals
( (
meshMover, meshMover,
isMasterPoint,
isMasterEdge, isMasterEdge,
meshEdges, meshEdges,
nSmoothSurfaceNormals, nSmoothSurfaceNormals,
@ -855,7 +933,7 @@ void Foam::autoLayerDriver::medialAxisSmoothingInfo
if (debug&meshRefinement::MESH || debug&meshRefinement::LAYERINFO) if (debug&meshRefinement::MESH || debug&meshRefinement::LAYERINFO)
{ {
pointField meshPointNormals(mesh.nPoints(), point(1, 0, 0)); pointField meshPointNormals(mesh.nPoints(), point(1, 0, 0));
UIndirectList<point>(meshPointNormals, pp.meshPoints()) = pointNormals; UIndirectList<point>(meshPointNormals, meshPoints) = pointNormals;
meshRefinement::testSyncPointList meshRefinement::testSyncPointList
( (
"smoothed pointNormals", "smoothed pointNormals",
@ -929,18 +1007,18 @@ void Foam::autoLayerDriver::medialAxisSmoothingInfo
{ {
pointField origin(pointWallDist.size()); pointField origin(pointWallDist.size());
scalarField distSqr(pointWallDist.size()); scalarField distSqr(pointWallDist.size());
scalarField passiveS(pointWallDist.size()); //NA scalarField passiveS(pointWallDist.size());
pointField passiveV(pointWallDist.size()); pointField passiveV(pointWallDist.size());
forAll(pointWallDist, pointI) forAll(pointWallDist, pointI)
{ {
origin[pointI] = pointWallDist[pointI].origin(); origin[pointI] = pointWallDist[pointI].origin();
distSqr[pointI] = pointWallDist[pointI].distSqr(); distSqr[pointI] = pointWallDist[pointI].distSqr();
passiveS[pointI] = pointWallDist[pointI].s(); //passiveS[pointI] = pointWallDist[pointI].s();
passiveV[pointI] = pointWallDist[pointI].v(); passiveV[pointI] = pointWallDist[pointI].v();
} }
meshRefinement::testSyncPointList("origin", mesh, origin); meshRefinement::testSyncPointList("origin", mesh, origin);
meshRefinement::testSyncPointList("distSqr", mesh, distSqr); meshRefinement::testSyncPointList("distSqr", mesh, distSqr);
meshRefinement::testSyncPointList("passiveS", mesh, passiveS); //meshRefinement::testSyncPointList("passiveS", mesh, passiveS);
meshRefinement::testSyncPointList("passiveV", mesh, passiveV); meshRefinement::testSyncPointList("passiveV", mesh, passiveV);
} }
@ -1186,7 +1264,14 @@ void Foam::autoLayerDriver::medialAxisSmoothingInfo
} }
// Smooth normal vectors. Do not change normals on pp.meshPoints // Smooth normal vectors. Do not change normals on pp.meshPoints
smoothNormals(nSmoothNormals, isMasterEdge, meshPoints, dispVec); smoothNormals
(
nSmoothNormals,
isMasterPoint,
isMasterEdge,
meshPoints,
dispVec
);
if (debug&meshRefinement::MESH || debug&meshRefinement::LAYERINFO) if (debug&meshRefinement::MESH || debug&meshRefinement::LAYERINFO)
{ {
@ -1288,25 +1373,18 @@ void Foam::autoLayerDriver::shrinkMeshMedialDistance
const indirectPrimitivePatch& pp = meshMover.patch(); const indirectPrimitivePatch& pp = meshMover.patch();
const labelList& meshPoints = pp.meshPoints(); const labelList& meshPoints = pp.meshPoints();
// Precalulate master edge (only relevant for shared edges) // Precalulate master points/edge (only relevant for shared points/edges)
PackedBoolList isMasterEdge(syncTools::getMasterEdges(mesh)); const PackedBoolList isMasterPoint(syncTools::getMasterPoints(mesh));
const PackedBoolList isMasterEdge(syncTools::getMasterEdges(mesh));
// Precalculate meshEdge per pp edge // Precalculate meshEdge per pp edge
labelList meshEdges(pp.nEdges()); const labelList meshEdges
(
forAll(meshEdges, patchEdgeI) pp.meshEdges
{
const edge& e = pp.edges()[patchEdgeI];
label v0 = pp.meshPoints()[e[0]];
label v1 = pp.meshPoints()[e[1]];
meshEdges[patchEdgeI] = meshTools::findEdge
( (
mesh.edges(), mesh.edges(),
mesh.pointEdges()[v0], mesh.pointEdges()
v0, )
v1
); );
}
scalarField thickness(layerThickness.size()); scalarField thickness(layerThickness.size());
@ -1405,7 +1483,10 @@ void Foam::autoLayerDriver::shrinkMeshMedialDistance
patchDisp[patchPointI] = thickness[patchPointI]*n; patchDisp[patchPointI] = thickness[patchPointI]*n;
if (isMasterPoint[pointI])
{
numThicknessRatioExclude++; numThicknessRatioExclude++;
}
if (str.valid()) if (str.valid())
{ {
@ -1433,14 +1514,17 @@ void Foam::autoLayerDriver::shrinkMeshMedialDistance
<< numThicknessRatioExclude << numThicknessRatioExclude
<< " nodes where thickness to medial axis distance is large " << endl; << " nodes where thickness to medial axis distance is large " << endl;
// find points where layer growth isolated to a lone point, edge or face // find points where layer growth isolated to a lone point, edge or face
findIsolatedRegions findIsolatedRegions
( (
pp,
isMasterEdge,
meshEdges,
minCosLayerTermination, minCosLayerTermination,
isMasterPoint,
isMasterEdge,
pp,
meshEdges,
minThickness,
extrudeStatus, extrudeStatus,
patchDisp, patchDisp,
@ -1461,6 +1545,7 @@ void Foam::autoLayerDriver::shrinkMeshMedialDistance
smoothField smoothField
( (
meshMover, meshMover,
isMasterPoint,
isMasterEdge, isMasterEdge,
meshEdges, meshEdges,
minThickness, minThickness,
@ -1608,9 +1693,13 @@ void Foam::autoLayerDriver::shrinkMeshMedialDistance
// Do residual calculation every so often. // Do residual calculation every so often.
if ((iter % 10) == 0) if ((iter % 10) == 0)
{ {
Info<< " Iteration " << iter << " residual " scalar resid = meshRefinement::gAverage
<< gSum(mag(displacement-average)) (
/returnReduce(average.size(), sumOp<label>()) mesh,
syncTools::getMasterPoints(mesh),
mag(displacement-average)()
);
Info<< " Iteration " << iter << " residual " << resid
<< endl; << endl;
} }
} }

View File

@ -33,6 +33,7 @@ Description
#include "fvMesh.H" #include "fvMesh.H"
#include "Time.H" #include "Time.H"
#include "OFstream.H" #include "OFstream.H"
#include "OBJstream.H"
#include "mapPolyMesh.H" #include "mapPolyMesh.H"
#include "pointEdgePoint.H" #include "pointEdgePoint.H"
#include "PointEdgeWave.H" #include "PointEdgeWave.H"
@ -909,6 +910,7 @@ void Foam::autoSnapDriver::detectNearSurfaces
Info<< "Detecting near surfaces ..." << endl; Info<< "Detecting near surfaces ..." << endl;
const pointField& localPoints = pp.localPoints(); const pointField& localPoints = pp.localPoints();
const labelList& meshPoints = pp.meshPoints();
const refinementSurfaces& surfaces = meshRefiner_.surfaces(); const refinementSurfaces& surfaces = meshRefiner_.surfaces();
const fvMesh& mesh = meshRefiner_.mesh(); const fvMesh& mesh = meshRefiner_.mesh();
@ -1193,15 +1195,33 @@ void Foam::autoSnapDriver::detectNearSurfaces
const pointField avgCc(avgCellCentres(mesh, pp)); const pointField avgCc(avgCellCentres(mesh, pp));
// Construct rays from localPoints to beyond cell centre // Construct rays through localPoints to beyond cell centre
pointField start(pp.nPoints());
pointField end(pp.nPoints()); pointField end(pp.nPoints());
forAll(localPoints, pointI) forAll(localPoints, pointI)
{ {
const point& pt = localPoints[pointI]; const point& pt = localPoints[pointI];
end[pointI] = pt + 2*(avgCc[pointI]-pt); const vector d = 2*(avgCc[pointI]-pt);
start[pointI] = pt - d;
end[pointI] = pt + d;
} }
autoPtr<OBJstream> gapStr;
if (debug&meshRefinement::OBJINTERSECTIONS)
{
gapStr.reset
(
new OBJstream
(
mesh.time().path()
/ "detectNearSurfaces_" + meshRefiner_.timeName() + ".obj"
)
);
}
const PackedBoolList isMasterPoint(syncTools::getMasterPoints(mesh));
label nOverride = 0; label nOverride = 0;
// 1. All points to non-interface surfaces // 1. All points to non-interface surfaces
@ -1226,7 +1246,7 @@ void Foam::autoSnapDriver::detectNearSurfaces
surfaces.findNearestIntersection surfaces.findNearestIntersection
( (
unzonedSurfaces, unzonedSurfaces,
localPoints, start,
end, end,
surface1, surface1,
@ -1248,44 +1268,73 @@ void Foam::autoSnapDriver::detectNearSurfaces
bool override = false; bool override = false;
if (hit1[pointI].hit()) //if (hit1[pointI].hit())
//{
// if
// (
// meshRefiner_.isGap
// (
// planarCos,
// nearestPoint[pointI],
// nearestNormal[pointI],
// hit1[pointI].hitPoint(),
// normal1[pointI]
// )
// )
// {
// disp[pointI] = hit1[pointI].hitPoint()-pt;
// override = true;
// }
//}
//if (hit2[pointI].hit())
//{
// if
// (
// meshRefiner_.isGap
// (
// planarCos,
// nearestPoint[pointI],
// nearestNormal[pointI],
// hit2[pointI].hitPoint(),
// normal2[pointI]
// )
// )
// {
// disp[pointI] = hit2[pointI].hitPoint()-pt;
// override = true;
// }
//}
if (hit1[pointI].hit() && hit2[pointI].hit())
{ {
if if
( (
meshRefiner_.isGap meshRefiner_.isGap
( (
planarCos, planarCos,
nearestPoint[pointI],
nearestNormal[pointI],
hit1[pointI].hitPoint(), hit1[pointI].hitPoint(),
normal1[pointI] normal1[pointI],
)
)
{
disp[pointI] = hit1[pointI].hitPoint()-pt;
override = true;
}
}
if (hit2[pointI].hit())
{
if
(
meshRefiner_.isGap
(
planarCos,
nearestPoint[pointI],
nearestNormal[pointI],
hit2[pointI].hitPoint(), hit2[pointI].hitPoint(),
normal2[pointI] normal2[pointI]
) )
) )
{ {
// TBD: check if the attraction (to nearest) would attract
// good enough and not override attraction
if (gapStr.valid())
{
const point& intPt = hit2[pointI].hitPoint();
gapStr().write(linePointRef(pt, intPt));
}
// Choose hit2 : nearest to end point (so inside the domain)
disp[pointI] = hit2[pointI].hitPoint()-pt; disp[pointI] = hit2[pointI].hitPoint()-pt;
override = true; override = true;
} }
} }
if (override) if (override && isMasterPoint[meshPoints[pointI]])
{ {
nOverride++; nOverride++;
} }
@ -1337,7 +1386,7 @@ void Foam::autoSnapDriver::detectNearSurfaces
surfaces.findNearestIntersection surfaces.findNearestIntersection
( (
surfacesToTest, surfacesToTest,
pointField(localPoints, zonePointIndices), pointField(start, zonePointIndices),
pointField(end, zonePointIndices), pointField(end, zonePointIndices),
surface1, surface1,
@ -1352,8 +1401,6 @@ void Foam::autoSnapDriver::detectNearSurfaces
); );
label nOverride = 0;
forAll(hit1, i) forAll(hit1, i)
{ {
label pointI = zonePointIndices[i]; label pointI = zonePointIndices[i];
@ -1363,44 +1410,69 @@ void Foam::autoSnapDriver::detectNearSurfaces
bool override = false; bool override = false;
if (hit1[i].hit()) //if (hit1[i].hit())
//{
// if
// (
// meshRefiner_.isGap
// (
// planarCos,
// nearestPoint[pointI],
// nearestNormal[pointI],
// hit1[i].hitPoint(),
// normal1[i]
// )
// )
// {
// disp[pointI] = hit1[i].hitPoint()-pt;
// override = true;
// }
//}
//if (hit2[i].hit())
//{
// if
// (
// meshRefiner_.isGap
// (
// planarCos,
// nearestPoint[pointI],
// nearestNormal[pointI],
// hit2[i].hitPoint(),
// normal2[i]
// )
// )
// {
// disp[pointI] = hit2[i].hitPoint()-pt;
// override = true;
// }
//}
if (hit1[i].hit() && hit2[i].hit())
{ {
if if
( (
meshRefiner_.isGap meshRefiner_.isGap
( (
planarCos, planarCos,
nearestPoint[pointI],
nearestNormal[pointI],
hit1[i].hitPoint(), hit1[i].hitPoint(),
normal1[i] normal1[i],
)
)
{
disp[pointI] = hit1[i].hitPoint()-pt;
override = true;
}
}
if (hit2[i].hit())
{
if
(
meshRefiner_.isGap
(
planarCos,
nearestPoint[pointI],
nearestNormal[pointI],
hit2[i].hitPoint(), hit2[i].hitPoint(),
normal2[i] normal2[i]
) )
) )
{ {
if (gapStr.valid())
{
const point& intPt = hit2[i].hitPoint();
gapStr().write(linePointRef(pt, intPt));
}
disp[pointI] = hit2[i].hitPoint()-pt; disp[pointI] = hit2[i].hitPoint()-pt;
override = true; override = true;
} }
} }
if (override) if (override && isMasterPoint[meshPoints[pointI]])
{ {
nOverride++; nOverride++;
} }
@ -1618,7 +1690,13 @@ Foam::vectorField Foam::autoSnapDriver::calcNearestSurface
scalarField magDisp(mag(patchDisp)); scalarField magDisp(mag(patchDisp));
Info<< "Wanted displacement : average:" Info<< "Wanted displacement : average:"
<< gSum(magDisp)/returnReduce(patchDisp.size(), sumOp<label>()) << meshRefinement::gAverage
(
mesh,
syncTools::getMasterPoints(mesh),
pp.meshPoints(),
magDisp
)
<< " min:" << gMin(magDisp) << " min:" << gMin(magDisp)
<< " max:" << gMax(magDisp) << endl; << " max:" << gMax(magDisp) << endl;
} }
@ -2476,25 +2554,30 @@ void Foam::autoSnapDriver::doSnap
adaptPatchIDs adaptPatchIDs
) )
); );
indirectPrimitivePatch& pp = ppPtr();
// Distance to attract to nearest feature on surface // Distance to attract to nearest feature on surface
const scalarField snapDist(calcSnapDistance(mesh, snapParams, pp)); const scalarField snapDist(calcSnapDistance(mesh, snapParams, ppPtr()));
// Construct iterative mesh mover. // Construct iterative mesh mover.
Info<< "Constructing mesh displacer ..." << endl; Info<< "Constructing mesh displacer ..." << endl;
Info<< "Using mesh parameters " << motionDict << nl << endl; Info<< "Using mesh parameters " << motionDict << nl << endl;
const pointMesh& pMesh = pointMesh::New(mesh); autoPtr<motionSmoother> meshMoverPtr
(
motionSmoother meshMover new motionSmoother
( (
mesh, mesh,
pp, ppPtr(),
adaptPatchIDs, adaptPatchIDs,
meshRefinement::makeDisplacementField(pMesh, adaptPatchIDs), meshRefinement::makeDisplacementField
(
pointMesh::New(mesh),
adaptPatchIDs
),
motionDict motionDict
)
); );
@ -2523,16 +2606,95 @@ void Foam::autoSnapDriver::doSnap
snapParams, snapParams,
nInitErrors, nInitErrors,
baffles, baffles,
meshMover meshMoverPtr()
); );
//- Only if in feature attraction mode:
// Nearest feature
vectorField patchAttraction;
// Constraints at feature
List<pointConstraint> patchConstraints;
for (label iter = 0; iter < nFeatIter; iter++) for (label iter = 0; iter < nFeatIter; iter++)
{ {
Info<< nl Info<< nl
<< "Morph iteration " << iter << nl << "Morph iteration " << iter << nl
<< "-----------------" << endl; << "-----------------" << endl;
//if (iter > 0 && iter == nFeatIter/2)
//{
// Info<< "Splitting diagonal attractions" << endl;
// const labelList& bFaces = ppPtr().addressing();
//
// DynamicList<label> splitFaces(bFaces.size());
// DynamicList<labelPair> splits(bFaces.size());
//
// forAll(bFaces, faceI)
// {
// const labelPair split
// (
// findDiagonalAttraction
// (
// ppPtr(),
// patchAttraction,
// patchConstraints,
// faceI
// )
// );
//
// if (split != labelPair(-1, -1))
// {
// splitFaces.append(bFaces[faceI]);
// splits.append(split);
// }
// }
//
// autoPtr<mapPolyMesh> mapPtr = meshRefiner_.splitFaces
// (
// splitFaces,
// splits
// );
//
// const labelList& faceMap = mapPtr().faceMap();
// meshRefinement::updateList(faceMap, -1, duplicateFace);
// const labelList& reverseFaceMap = mapPtr().reverseFaceMap();
// forAll(baffles, i)
// {
// labelPair& baffle = baffles[i];
// baffle.first() = reverseFaceMap[baffle.first()];
// baffle.second() = reverseFaceMap[baffle.second()];
// }
//
// meshMoverPtr.clear();
// ppPtr.clear();
//
// ppPtr = meshRefinement::makePatch(mesh, adaptPatchIDs);
// meshMoverPtr.reset
// (
// new motionSmoother
// (
// mesh,
// ppPtr(),
// adaptPatchIDs,
// meshRefinement::makeDisplacementField
// (
// pointMesh::New(mesh),
// adaptPatchIDs
// ),
// motionDict
// )
// );
//}
indirectPrimitivePatch& pp = ppPtr();
motionSmoother& meshMover = meshMoverPtr();
// Calculate displacement at every patch point. Insert into // Calculate displacement at every patch point. Insert into
// meshMover. // meshMover.
// Calculate displacement at every patch point // Calculate displacement at every patch point
@ -2580,7 +2742,9 @@ void Foam::autoSnapDriver::doSnap
scalar(iter+1)/nFeatIter, scalar(iter+1)/nFeatIter,
snapDist, snapDist,
disp, disp,
meshMover meshMover,
patchAttraction,
patchConstraints
); );
} }

View File

@ -125,7 +125,9 @@ class autoSnapDriver
void smoothAndConstrain void smoothAndConstrain
( (
const PackedBoolList& isMasterEdge,
const indirectPrimitivePatch& pp, const indirectPrimitivePatch& pp,
const labelList& meshEdges,
const List<pointConstraint>& constraints, const List<pointConstraint>& constraints,
vectorField& disp vectorField& disp
) const; ) const;
@ -196,6 +198,16 @@ class autoSnapDriver
List<pointConstraint>& patchConstraints List<pointConstraint>& patchConstraints
) const; ) const;
//- Detect any diagonal attraction. Returns indices in face
// or (-1, -1) if none
labelPair findDiagonalAttraction
(
const indirectPrimitivePatch& pp,
const vectorField& patchAttraction,
const List<pointConstraint>& patchConstraints,
const label faceI
) const;
//- Return hit if on multiple points //- Return hit if on multiple points
pointIndexHit findMultiPatchPoint pointIndexHit findMultiPatchPoint
( (
@ -371,7 +383,9 @@ class autoSnapDriver
const scalar featureAttract, const scalar featureAttract,
const scalarField& snapDist, const scalarField& snapDist,
const vectorField& nearestDisp, const vectorField& nearestDisp,
motionSmoother& meshMover motionSmoother& meshMover,
vectorField& patchAttraction,
List<pointConstraint>& patchConstraints
) const; ) const;

View File

@ -38,50 +38,18 @@ License
#include "treeDataPoint.H" #include "treeDataPoint.H"
#include "indexedOctree.H" #include "indexedOctree.H"
#include "snapParameters.H" #include "snapParameters.H"
#include "PatchTools.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam namespace Foam
{ {
class listTransform
{
public:
void operator()
(
const vectorTensorTransform& vt,
const bool forward,
List<List<point> >& fld
) const
{
const tensor T
(
forward
? vt.R()
: vt.R().T()
);
forAll(fld, i)
{
List<point>& elems = fld[i];
forAll(elems, elemI)
{
elems[elemI] = transform(T, elems[elemI]);
}
}
}
};
template<class T> template<class T>
class listPlusEqOp class listPlusEqOp
{ {
public: public:
void operator() void operator()(List<T>& x, const List<T>& y) const
(
List<T>& x,
const List<T>& y
) const
{ {
label sz = x.size(); label sz = x.size();
x.setSize(sz+y.size()); x.setSize(sz+y.size());
@ -159,7 +127,9 @@ bool Foam::autoSnapDriver::isFeaturePoint
void Foam::autoSnapDriver::smoothAndConstrain void Foam::autoSnapDriver::smoothAndConstrain
( (
const PackedBoolList& isMasterEdge,
const indirectPrimitivePatch& pp, const indirectPrimitivePatch& pp,
const labelList& meshEdges,
const List<pointConstraint>& constraints, const List<pointConstraint>& constraints,
vectorField& disp vectorField& disp
) const ) const
@ -196,6 +166,10 @@ void Foam::autoSnapDriver::smoothAndConstrain
if (nConstraints <= 1) if (nConstraints <= 1)
{ {
forAll(pEdges, i) forAll(pEdges, i)
{
label edgeI = pEdges[i];
if (isMasterEdge[meshEdges[edgeI]])
{ {
label nbrPointI = edges[pEdges[i]].otherVertex(pointI); label nbrPointI = edges[pEdges[i]].otherVertex(pointI);
if (constraints[nbrPointI].first() >= nConstraints) if (constraints[nbrPointI].first() >= nConstraints)
@ -206,6 +180,7 @@ void Foam::autoSnapDriver::smoothAndConstrain
} }
} }
} }
}
syncTools::syncPointList syncTools::syncPointList
( (
@ -564,6 +539,9 @@ void Foam::autoSnapDriver::calcNearestFacePointProperties
{ {
const fvMesh& mesh = meshRefiner_.mesh(); const fvMesh& mesh = meshRefiner_.mesh();
const PackedBoolList isMasterFace(syncTools::getMasterFaces(mesh));
// For now just get all surrounding face data. Expensive - should just // For now just get all surrounding face data. Expensive - should just
// store and sync data on coupled points only // store and sync data on coupled points only
// (see e.g PatchToolsNormals.C) // (see e.g PatchToolsNormals.C)
@ -583,7 +561,7 @@ void Foam::autoSnapDriver::calcNearestFacePointProperties
forAll(pFaces, i) forAll(pFaces, i)
{ {
label faceI = pFaces[i]; label faceI = pFaces[i];
if (faceSurfaceGlobalRegion[faceI] != -1) if (isMasterFace[faceI] && faceSurfaceGlobalRegion[faceI] != -1)
{ {
nFaces++; nFaces++;
} }
@ -605,7 +583,7 @@ void Foam::autoSnapDriver::calcNearestFacePointProperties
label faceI = pFaces[i]; label faceI = pFaces[i];
label globalRegionI = faceSurfaceGlobalRegion[faceI]; label globalRegionI = faceSurfaceGlobalRegion[faceI];
if (globalRegionI != -1) if (isMasterFace[faceI] && globalRegionI != -1)
{ {
pNormals[nFaces] = faceSurfaceNormal[faceI]; pNormals[nFaces] = faceSurfaceNormal[faceI];
pDisp[nFaces] = faceDisp[faceI]; pDisp[nFaces] = faceDisp[faceI];
@ -694,7 +672,7 @@ void Foam::autoSnapDriver::calcNearestFacePointProperties
pointFaceSurfNormals, pointFaceSurfNormals,
listPlusEqOp<point>(), listPlusEqOp<point>(),
List<point>(), List<point>(),
listTransform() mapDistribute::transform()
); );
syncTools::syncPointList syncTools::syncPointList
( (
@ -703,7 +681,7 @@ void Foam::autoSnapDriver::calcNearestFacePointProperties
pointFaceDisp, pointFaceDisp,
listPlusEqOp<point>(), listPlusEqOp<point>(),
List<point>(), List<point>(),
listTransform() mapDistribute::transform()
); );
syncTools::syncPointList syncTools::syncPointList
( (
@ -712,7 +690,7 @@ void Foam::autoSnapDriver::calcNearestFacePointProperties
pointFaceCentres, pointFaceCentres,
listPlusEqOp<point>(), listPlusEqOp<point>(),
List<point>(), List<point>(),
listTransform() mapDistribute::transformPosition()
); );
syncTools::syncPointList syncTools::syncPointList
( (
@ -722,6 +700,25 @@ void Foam::autoSnapDriver::calcNearestFacePointProperties
listPlusEqOp<label>(), listPlusEqOp<label>(),
List<label>() List<label>()
); );
// Sort the data according to the face centres. This is only so we get
// consistent behaviour serial and parallel.
labelList visitOrder;
forAll(pointFaceDisp, pointI)
{
List<point>& pNormals = pointFaceSurfNormals[pointI];
List<point>& pDisp = pointFaceDisp[pointI];
List<point>& pFc = pointFaceCentres[pointI];
labelList& pFid = pointFacePatchID[pointI];
sortedOrder(mag(pFc)(), visitOrder);
pNormals = List<point>(pNormals, visitOrder);
pDisp = List<point>(pDisp, visitOrder);
pFc = List<point>(pFc, visitOrder);
pFid = UIndirectList<label>(pFid, visitOrder);
}
} }
@ -1360,6 +1357,70 @@ void Foam::autoSnapDriver::stringFeatureEdges
} }
// If only two attractions and across face return the face indices
Foam::labelPair Foam::autoSnapDriver::findDiagonalAttraction
(
const indirectPrimitivePatch& pp,
const vectorField& patchAttraction,
const List<pointConstraint>& patchConstraints,
const label faceI
) const
{
const face& f = pp.localFaces()[faceI];
// For now just detect any attraction. Improve this to look at
// actual attraction position and orientation
labelPair attractIndices(-1, -1);
if (f.size() >= 4)
{
forAll(f, fp)
{
label pointI = f[fp];
if (patchConstraints[pointI].first() >= 2)
{
// Attract to feature edge or point
if (attractIndices[0] == -1)
{
// First attraction. Store
attractIndices[0] = fp;
}
else if (attractIndices[1] == -1)
{
// Second attraction. Check if not consecutive to first
// attraction
label fp0 = attractIndices[0];
if (f.fcIndex(fp0) == fp || f.fcIndex(fp) == fp0)
{
// Consecutive. Skip.
attractIndices = labelPair(-1, -1);
break;
}
else
{
attractIndices[1] = fp;
}
}
else
{
// More than two attractions. Skip.
attractIndices = labelPair(-1, -1);
break;
}
}
}
if (attractIndices[1] == -1)
{
// Found only one attraction. Skip.
attractIndices = labelPair(-1, -1);
}
}
return attractIndices;
}
Foam::pointIndexHit Foam::autoSnapDriver::findNearFeatureEdge Foam::pointIndexHit Foam::autoSnapDriver::findNearFeatureEdge
( (
const indirectPrimitivePatch& pp, const indirectPrimitivePatch& pp,
@ -1929,7 +1990,7 @@ void Foam::autoSnapDriver::featureAttractionUsingFeatureEdges
edgeFaceNormals, edgeFaceNormals,
listPlusEqOp<point>(), listPlusEqOp<point>(),
List<point>(), List<point>(),
listTransform() mapDistribute::transform()
); );
} }
@ -2778,7 +2839,9 @@ Foam::vectorField Foam::autoSnapDriver::calcNearestSurfaceFeature
const scalar featureAttract, const scalar featureAttract,
const scalarField& snapDist, const scalarField& snapDist,
const vectorField& nearestDisp, const vectorField& nearestDisp,
motionSmoother& meshMover motionSmoother& meshMover,
vectorField& patchAttraction,
List<pointConstraint>& patchConstraints
) const ) const
{ {
const Switch implicitFeatureAttraction = snapParams.implicitFeatureSnap(); const Switch implicitFeatureAttraction = snapParams.implicitFeatureSnap();
@ -2851,7 +2914,7 @@ Foam::vectorField Foam::autoSnapDriver::calcNearestSurfaceFeature
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// - faceSurfaceNormal // - faceSurfaceNormal
// - faceDisp // - faceDisp
// - faceCentres&faceNormal // - faceCentres
List<List<point> > pointFaceSurfNormals(pp.nPoints()); List<List<point> > pointFaceSurfNormals(pp.nPoints());
List<List<point> > pointFaceDisp(pp.nPoints()); List<List<point> > pointFaceDisp(pp.nPoints());
List<List<point> > pointFaceCentres(pp.nPoints()); List<List<point> > pointFaceCentres(pp.nPoints());
@ -2884,10 +2947,11 @@ Foam::vectorField Foam::autoSnapDriver::calcNearestSurfaceFeature
// here. // here.
// Nearest feature // Nearest feature
vectorField patchAttraction(localPoints.size(), vector::zero); patchAttraction.setSize(localPoints.size());
patchAttraction = vector::zero;
// Constraints at feature // Constraints at feature
List<pointConstraint> patchConstraints(localPoints.size()); patchConstraints.setSize(localPoints.size());
patchConstraints = pointConstraint();
if (implicitFeatureAttraction) if (implicitFeatureAttraction)
{ {
@ -2951,15 +3015,29 @@ Foam::vectorField Foam::autoSnapDriver::calcNearestSurfaceFeature
patchConstraints patchConstraints
); );
const PackedBoolList isMasterPoint(syncTools::getMasterPoints(mesh));
{
vector avgPatchDisp = meshRefinement::gAverage
(
mesh,
isMasterPoint,
pp.meshPoints(),
patchDisp
);
vector avgPatchAttr = meshRefinement::gAverage
(
mesh,
isMasterPoint,
pp.meshPoints(),
patchAttraction
);
Info<< "Attraction:" << endl Info<< "Attraction:" << endl
<< " linear : max:" << gMax(patchDisp) << " linear : max:" << gMaxMagSqr(patchDisp)
<< " avg:" << gAverage(patchDisp) << " avg:" << avgPatchDisp << endl
<< endl << " feature : max:" << gMaxMagSqr(patchAttraction)
<< " feature : max:" << gMax(patchAttraction) << " avg:" << avgPatchAttr << endl;
<< " avg:" << gAverage(patchAttraction) }
<< endl;
// So now we have: // So now we have:
// - patchDisp : point movement to go to nearest point on surface // - patchDisp : point movement to go to nearest point on surface
@ -2986,12 +3064,19 @@ Foam::vectorField Foam::autoSnapDriver::calcNearestSurfaceFeature
// Count // Count
{ {
const labelList& meshPoints = pp.meshPoints();
label nMasterPoints = 0;
label nPlanar = 0; label nPlanar = 0;
label nEdge = 0; label nEdge = 0;
label nPoint = 0; label nPoint = 0;
forAll(patchConstraints, pointI) forAll(patchConstraints, pointI)
{ {
if (isMasterPoint[meshPoints[pointI]])
{
nMasterPoints++;
if (patchConstraints[pointI].first() == 1) if (patchConstraints[pointI].first() == 1)
{ {
nPlanar++; nPlanar++;
@ -3005,18 +3090,19 @@ Foam::vectorField Foam::autoSnapDriver::calcNearestSurfaceFeature
nPoint++; nPoint++;
} }
} }
}
label nTotPoints = returnReduce(pp.nPoints(), sumOp<label>()); reduce(nMasterPoints, sumOp<label>());
reduce(nPlanar, sumOp<label>()); reduce(nPlanar, sumOp<label>());
reduce(nEdge, sumOp<label>()); reduce(nEdge, sumOp<label>());
reduce(nPoint, sumOp<label>()); reduce(nPoint, sumOp<label>());
Info<< "Feature analysis : total points:" Info<< "Feature analysis : total master points:"
<< nTotPoints << nMasterPoints
<< " attraction to :" << nl << " attraction to :" << nl
<< " feature point : " << nPoint << nl << " feature point : " << nPoint << nl
<< " feature edge : " << nEdge << nl << " feature edge : " << nEdge << nl
<< " nearest surface : " << nPlanar << nl << " nearest surface : " << nPlanar << nl
<< " rest : " << nTotPoints-nPoint-nEdge-nPlanar << " rest : " << nMasterPoints-nPoint-nEdge-nPlanar
<< nl << nl
<< endl; << endl;
} }
@ -3035,11 +3121,29 @@ Foam::vectorField Foam::autoSnapDriver::calcNearestSurfaceFeature
if (featureAttract < 1-0.001) if (featureAttract < 1-0.001)
{ {
const PackedBoolList isMasterEdge(syncTools::getMasterEdges(mesh));
const vectorField pointNormals
(
PatchTools::pointNormals
(
mesh,
pp
)
);
const labelList meshEdges
(
pp.meshEdges(mesh.edges(), mesh.pointEdges())
);
// 1. Smoothed all displacement // 1. Smoothed all displacement
vectorField smoothedPatchDisp = patchDisp; vectorField smoothedPatchDisp = patchDisp;
smoothAndConstrain smoothAndConstrain
( (
isMasterEdge,
pp, pp,
meshEdges,
patchConstraints, patchConstraints,
smoothedPatchDisp smoothedPatchDisp
); );
@ -3047,16 +3151,18 @@ Foam::vectorField Foam::autoSnapDriver::calcNearestSurfaceFeature
// 2. Smoothed tangential component // 2. Smoothed tangential component
vectorField tangPatchDisp = patchDisp; vectorField tangPatchDisp = patchDisp;
tangPatchDisp -= (pp.pointNormals() & patchDisp) * pp.pointNormals(); tangPatchDisp -= (pointNormals & patchDisp) * pointNormals;
smoothAndConstrain smoothAndConstrain
( (
isMasterEdge,
pp, pp,
meshEdges,
patchConstraints, patchConstraints,
tangPatchDisp tangPatchDisp
); );
// Re-add normal component // Re-add normal component
tangPatchDisp += (pp.pointNormals() & patchDisp) * pp.pointNormals(); tangPatchDisp += (pointNormals & patchDisp) * pointNormals;
if (debug&meshRefinement::OBJINTERSECTIONS) if (debug&meshRefinement::OBJINTERSECTIONS)
{ {

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