Add the OpenFOAM source tree
This commit is contained in:
@ -0,0 +1,3 @@
|
||||
applyBoundaryLayer.C
|
||||
|
||||
EXE = $(FOAM_APPBIN)/applyBoundaryLayer
|
||||
@ -0,0 +1,15 @@
|
||||
EXE_INC = \
|
||||
-I$(LIB_SRC)/finiteVolume/lnInclude \
|
||||
-I$(LIB_SRC)/turbulenceModels \
|
||||
-I$(LIB_SRC)/turbulenceModels/incompressible/RAS/RASModel \
|
||||
-I$(LIB_SRC)/transportModels \
|
||||
-I$(LIB_SRC)/transportModels/incompressible/singlePhaseTransportModel \
|
||||
-I$(LIB_SRC)/meshTools/lnInclude
|
||||
|
||||
EXE_LIBS = \
|
||||
-lfiniteVolume \
|
||||
-lincompressibleRASModels \
|
||||
-lincompressibleLESModels \
|
||||
-lincompressibleTransportModels \
|
||||
-lgenericPatchFields \
|
||||
-lmeshTools
|
||||
@ -0,0 +1,238 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2011-2014 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
|
||||
applyBoundaryLayer
|
||||
|
||||
Description
|
||||
Apply a simplified boundary-layer model to the velocity and
|
||||
turbulence fields based on the 1/7th power-law.
|
||||
|
||||
The uniform boundary-layer thickness is either provided via the -ybl option
|
||||
or calculated as the average of the distance to the wall scaled with
|
||||
the thickness coefficient supplied via the option -Cbl. If both options
|
||||
are provided -ybl is used.
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "fvCFD.H"
|
||||
#include "singlePhaseTransportModel.H"
|
||||
#include "RASModel.H"
|
||||
#include "wallDist.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
// turbulence constants - file-scope
|
||||
static const scalar Cmu(0.09);
|
||||
static const scalar kappa(0.41);
|
||||
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
argList::addNote
|
||||
(
|
||||
"apply a simplified boundary-layer model to the velocity and\n"
|
||||
"turbulence fields based on the 1/7th power-law."
|
||||
);
|
||||
|
||||
argList::addOption
|
||||
(
|
||||
"ybl",
|
||||
"scalar",
|
||||
"specify the boundary-layer thickness"
|
||||
);
|
||||
argList::addOption
|
||||
(
|
||||
"Cbl",
|
||||
"scalar",
|
||||
"boundary-layer thickness as Cbl * mean distance to wall"
|
||||
);
|
||||
argList::addBoolOption
|
||||
(
|
||||
"writenut",
|
||||
"write nut field"
|
||||
);
|
||||
|
||||
#include "setRootCase.H"
|
||||
|
||||
if (!args.optionFound("ybl") && !args.optionFound("Cbl"))
|
||||
{
|
||||
FatalErrorIn(args.executable())
|
||||
<< "Neither option 'ybl' or 'Cbl' have been provided to calculate "
|
||||
<< "the boundary-layer thickness.\n"
|
||||
<< "Please choose either 'ybl' OR 'Cbl'."
|
||||
<< exit(FatalError);
|
||||
}
|
||||
else if (args.optionFound("ybl") && args.optionFound("Cbl"))
|
||||
{
|
||||
FatalErrorIn(args.executable())
|
||||
<< "Both 'ybl' and 'Cbl' have been provided to calculate "
|
||||
<< "the boundary-layer thickness.\n"
|
||||
<< "Please choose either 'ybl' OR 'Cbl'."
|
||||
<< exit(FatalError);
|
||||
}
|
||||
|
||||
#include "createTime.H"
|
||||
#include "createMesh.H"
|
||||
#include "createFields.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
// Modify velocity by applying a 1/7th power law boundary-layer
|
||||
// u/U0 = (y/ybl)^(1/7)
|
||||
// assumes U0 is the same as the current cell velocity
|
||||
|
||||
Info<< "Setting boundary layer velocity" << nl << endl;
|
||||
scalar yblv = ybl.value();
|
||||
forAll(U, cellI)
|
||||
{
|
||||
if (y[cellI] <= yblv)
|
||||
{
|
||||
mask[cellI] = 1;
|
||||
U[cellI] *= ::pow(y[cellI]/yblv, (1.0/7.0));
|
||||
}
|
||||
}
|
||||
mask.correctBoundaryConditions();
|
||||
|
||||
Info<< "Writing U\n" << endl;
|
||||
U.write();
|
||||
|
||||
// Update/re-write phi
|
||||
#include "createPhi.H"
|
||||
phi.write();
|
||||
|
||||
singlePhaseTransportModel laminarTransport(U, phi);
|
||||
|
||||
autoPtr<incompressible::turbulenceModel> turbulence
|
||||
(
|
||||
incompressible::turbulenceModel::New(U, phi, laminarTransport)
|
||||
);
|
||||
|
||||
if (isA<incompressible::RASModel>(turbulence()))
|
||||
{
|
||||
// Calculate nut - reference nut is calculated by the turbulence model
|
||||
// on its construction
|
||||
tmp<volScalarField> tnut = turbulence->nut();
|
||||
volScalarField& nut = tnut();
|
||||
volScalarField S(mag(dev(symm(fvc::grad(U)))));
|
||||
nut = (1 - mask)*nut + mask*sqr(kappa*min(y, ybl))*::sqrt(2)*S;
|
||||
|
||||
// do not correct BC - wall functions will 'undo' manipulation above
|
||||
// by using nut from turbulence model
|
||||
|
||||
if (args.optionFound("writenut"))
|
||||
{
|
||||
Info<< "Writing nut" << endl;
|
||||
nut.write();
|
||||
}
|
||||
|
||||
|
||||
//--- Read and modify turbulence fields
|
||||
|
||||
// Turbulence k
|
||||
tmp<volScalarField> tk = turbulence->k();
|
||||
volScalarField& k = tk();
|
||||
scalar ck0 = pow025(Cmu)*kappa;
|
||||
k = (1 - mask)*k + mask*sqr(nut/(ck0*min(y, ybl)));
|
||||
|
||||
// do not correct BC - operation may use inconsistent fields wrt these
|
||||
// local manipulations
|
||||
// k.correctBoundaryConditions();
|
||||
|
||||
Info<< "Writing k\n" << endl;
|
||||
k.write();
|
||||
|
||||
|
||||
// Turbulence epsilon
|
||||
tmp<volScalarField> tepsilon = turbulence->epsilon();
|
||||
volScalarField& epsilon = tepsilon();
|
||||
scalar ce0 = ::pow(Cmu, 0.75)/kappa;
|
||||
epsilon = (1 - mask)*epsilon + mask*ce0*k*sqrt(k)/min(y, ybl);
|
||||
|
||||
// do not correct BC - wall functions will use non-updated k from
|
||||
// turbulence model
|
||||
// epsilon.correctBoundaryConditions();
|
||||
|
||||
Info<< "Writing epsilon\n" << endl;
|
||||
epsilon.write();
|
||||
|
||||
// Turbulence omega
|
||||
IOobject omegaHeader
|
||||
(
|
||||
"omega",
|
||||
runTime.timeName(),
|
||||
mesh,
|
||||
IOobject::MUST_READ,
|
||||
IOobject::NO_WRITE,
|
||||
false
|
||||
);
|
||||
|
||||
if (omegaHeader.headerOk())
|
||||
{
|
||||
volScalarField omega(omegaHeader, mesh);
|
||||
dimensionedScalar k0("VSMALL", k.dimensions(), VSMALL);
|
||||
omega = (1 - mask)*omega + mask*epsilon/(Cmu*k + k0);
|
||||
|
||||
// do not correct BC - wall functions will use non-updated k from
|
||||
// turbulence model
|
||||
// omega.correctBoundaryConditions();
|
||||
|
||||
Info<< "Writing omega\n" << endl;
|
||||
omega.write();
|
||||
}
|
||||
|
||||
// Turbulence nuTilda
|
||||
IOobject nuTildaHeader
|
||||
(
|
||||
"nuTilda",
|
||||
runTime.timeName(),
|
||||
mesh,
|
||||
IOobject::MUST_READ,
|
||||
IOobject::NO_WRITE,
|
||||
false
|
||||
);
|
||||
|
||||
if (nuTildaHeader.headerOk())
|
||||
{
|
||||
volScalarField nuTilda(nuTildaHeader, mesh);
|
||||
nuTilda = nut;
|
||||
|
||||
// do not correct BC
|
||||
// nuTilda.correctBoundaryConditions();
|
||||
|
||||
Info<< "Writing nuTilda\n" << endl;
|
||||
nuTilda.write();
|
||||
}
|
||||
}
|
||||
|
||||
Info<< nl << "ExecutionTime = " << runTime.elapsedCpuTime() << " s"
|
||||
<< " ClockTime = " << runTime.elapsedClockTime() << " s"
|
||||
<< nl << endl;
|
||||
|
||||
Info<< "End\n" << endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,77 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2011-2014 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/>.
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
Info<< "Reading field U\n" << endl;
|
||||
volVectorField U
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
"U",
|
||||
runTime.timeName(),
|
||||
mesh,
|
||||
IOobject::MUST_READ,
|
||||
IOobject::NO_WRITE
|
||||
),
|
||||
mesh
|
||||
);
|
||||
|
||||
Info<< "Calculating wall distance field" << endl;
|
||||
volScalarField y(wallDist(mesh).y());
|
||||
|
||||
// Set the mean boundary-layer thickness
|
||||
dimensionedScalar ybl("ybl", dimLength, 0);
|
||||
|
||||
if (args.optionFound("ybl"))
|
||||
{
|
||||
// If the boundary-layer thickness is provided use it
|
||||
ybl.value() = args.optionRead<scalar>("ybl");
|
||||
}
|
||||
else if (args.optionFound("Cbl"))
|
||||
{
|
||||
// Calculate boundary layer thickness as Cbl*mean distance to wall
|
||||
ybl.value() = gAverage(y)*args.optionRead<scalar>("Cbl");
|
||||
}
|
||||
|
||||
Info<< "\nCreating boundary-layer for U of thickness "
|
||||
<< ybl.value() << " m" << nl << endl;
|
||||
|
||||
Info<< "Creating mask field" << endl;
|
||||
volScalarField mask
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
"mask",
|
||||
runTime.timeName(),
|
||||
mesh,
|
||||
IOobject::NO_READ,
|
||||
IOobject::NO_WRITE
|
||||
),
|
||||
mesh,
|
||||
dimensionedScalar("zero", dimless, 0.0),
|
||||
zeroGradientFvPatchScalarField::typeName
|
||||
);
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,3 @@
|
||||
applyWallFunctionBoundaryConditions.C
|
||||
|
||||
EXE = $(FOAM_APPBIN)/applyWallFunctionBoundaryConditions
|
||||
@ -0,0 +1,13 @@
|
||||
EXE_INC = \
|
||||
-I$(LIB_SRC)/finiteVolume/lnInclude \
|
||||
-I$(LIB_SRC)/turbulenceModels \
|
||||
-I$(LIB_SRC)/turbulenceModels/incompressible/RAS/lnInclude \
|
||||
-I$(LIB_SRC)/turbulenceModels/compressible/RAS/lnInclude
|
||||
|
||||
EXE_LIBS = \
|
||||
-lincompressibleRASModels \
|
||||
-lfluidThermophysicalModels \
|
||||
-lspecie \
|
||||
-lcompressibleRASModels \
|
||||
-lfiniteVolume \
|
||||
-lgenericPatchFields
|
||||
@ -0,0 +1,363 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / 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/>.
|
||||
|
||||
Application
|
||||
applyWallFunctionBounaryConditions
|
||||
|
||||
Description
|
||||
Updates OpenFOAM RAS cases to use the new (v1.6) wall function framework.
|
||||
|
||||
Attempts to determine whether case is compressible or incompressible, or
|
||||
can be supplied with -compressible command line argument.
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "argList.H"
|
||||
#include "fvMesh.H"
|
||||
#include "Time.H"
|
||||
#include "volFields.H"
|
||||
#include "surfaceFields.H"
|
||||
|
||||
#include "wallPolyPatch.H"
|
||||
|
||||
#include "incompressible/RAS/derivedFvPatchFields/wallFunctions/epsilonWallFunctions/epsilonWallFunction/epsilonWallFunctionFvPatchScalarField.H"
|
||||
#include "incompressible/RAS/derivedFvPatchFields/wallFunctions/kqRWallFunctions/kqRWallFunction/kqRWallFunctionFvPatchField.H"
|
||||
#include "incompressible/RAS/derivedFvPatchFields/wallFunctions/nutWallFunctions/nutkWallFunction/nutkWallFunctionFvPatchScalarField.H"
|
||||
#include "incompressible/RAS/derivedFvPatchFields/wallFunctions/omegaWallFunctions/omegaWallFunction/omegaWallFunctionFvPatchScalarField.H"
|
||||
|
||||
#include "compressible/RAS/derivedFvPatchFields/wallFunctions/epsilonWallFunctions/epsilonWallFunction/epsilonWallFunctionFvPatchScalarField.H"
|
||||
#include "compressible/RAS/derivedFvPatchFields/wallFunctions/kqRWallFunctions/kqRWallFunction/kqRWallFunctionFvPatchField.H"
|
||||
#include "compressible/RAS/derivedFvPatchFields/wallFunctions/mutWallFunctions/mutkWallFunction/mutkWallFunctionFvPatchScalarField.H"
|
||||
#include "compressible/RAS/derivedFvPatchFields/wallFunctions/omegaWallFunctions/omegaWallFunction/omegaWallFunctionFvPatchScalarField.H"
|
||||
|
||||
using namespace Foam;
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
bool caseIsCompressible(const fvMesh& mesh)
|
||||
{
|
||||
// Attempt flux field
|
||||
IOobject phiHeader
|
||||
(
|
||||
"phi",
|
||||
mesh.time().timeName(),
|
||||
mesh,
|
||||
IOobject::MUST_READ,
|
||||
IOobject::NO_WRITE
|
||||
);
|
||||
|
||||
if (phiHeader.headerOk())
|
||||
{
|
||||
surfaceScalarField phi(phiHeader, mesh);
|
||||
if (phi.dimensions() == dimDensity*dimVelocity*dimArea)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// Attempt density field
|
||||
IOobject rhoHeader
|
||||
(
|
||||
"rho",
|
||||
mesh.time().timeName(),
|
||||
mesh,
|
||||
IOobject::MUST_READ,
|
||||
IOobject::NO_WRITE
|
||||
);
|
||||
|
||||
if (rhoHeader.headerOk())
|
||||
{
|
||||
volScalarField rho(rhoHeader, mesh);
|
||||
if (rho.dimensions() == dimDensity)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// Attempt pressure field
|
||||
IOobject pHeader
|
||||
(
|
||||
"p",
|
||||
mesh.time().timeName(),
|
||||
mesh,
|
||||
IOobject::MUST_READ,
|
||||
IOobject::NO_WRITE
|
||||
);
|
||||
|
||||
if (pHeader.headerOk())
|
||||
{
|
||||
volScalarField p(pHeader, mesh);
|
||||
if (p.dimensions() == dimMass/sqr(dimTime)/dimLength)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// If none of the above are true, assume that the case is incompressible
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void createVolScalarField
|
||||
(
|
||||
const fvMesh& mesh,
|
||||
const word& fieldName,
|
||||
const dimensionSet& dims
|
||||
)
|
||||
{
|
||||
IOobject fieldHeader
|
||||
(
|
||||
fieldName,
|
||||
mesh.time().timeName(),
|
||||
mesh,
|
||||
IOobject::MUST_READ,
|
||||
IOobject::NO_WRITE
|
||||
);
|
||||
|
||||
if (!fieldHeader.headerOk())
|
||||
{
|
||||
Info<< "Creating field " << fieldName << nl << endl;
|
||||
|
||||
volScalarField field
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
fieldName,
|
||||
mesh.time().timeName(),
|
||||
mesh,
|
||||
IOobject::NO_READ,
|
||||
IOobject::NO_WRITE
|
||||
),
|
||||
mesh,
|
||||
dimensionedScalar("zero", dims, 0.0)
|
||||
);
|
||||
|
||||
field.write();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void replaceBoundaryType
|
||||
(
|
||||
const fvMesh& mesh,
|
||||
const word& fieldName,
|
||||
const word& boundaryType,
|
||||
const string& boundaryValue
|
||||
)
|
||||
{
|
||||
IOobject header
|
||||
(
|
||||
fieldName,
|
||||
mesh.time().timeName(),
|
||||
mesh,
|
||||
IOobject::MUST_READ,
|
||||
IOobject::NO_WRITE
|
||||
);
|
||||
|
||||
if (!header.headerOk())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Info<< "Updating boundary types for field " << header.name() << endl;
|
||||
|
||||
const word oldTypeName = IOdictionary::typeName;
|
||||
const_cast<word&>(IOdictionary::typeName) = word::null;
|
||||
|
||||
IOdictionary dict(header);
|
||||
|
||||
const_cast<word&>(IOdictionary::typeName) = oldTypeName;
|
||||
const_cast<word&>(dict.type()) = dict.headerClassName();
|
||||
|
||||
// Make a backup of the old file
|
||||
if (mvBak(dict.objectPath(), "old"))
|
||||
{
|
||||
Info<< " Backup original file to "
|
||||
<< (dict.objectPath() + ".old") << endl;
|
||||
}
|
||||
|
||||
// Loop through boundary patches and update
|
||||
const polyBoundaryMesh& bMesh = mesh.boundaryMesh();
|
||||
dictionary& boundaryDict = dict.subDict("boundaryField");
|
||||
forAll(bMesh, patchI)
|
||||
{
|
||||
if (isA<wallPolyPatch>(bMesh[patchI]))
|
||||
{
|
||||
word patchName = bMesh[patchI].name();
|
||||
dictionary& oldPatch = boundaryDict.subDict(patchName);
|
||||
|
||||
dictionary newPatch(dictionary::null);
|
||||
newPatch.add("type", boundaryType);
|
||||
newPatch.add("value", ("uniform " + boundaryValue).c_str());
|
||||
|
||||
oldPatch = newPatch;
|
||||
}
|
||||
}
|
||||
|
||||
Info<< " writing updated " << dict.name() << nl << endl;
|
||||
dict.regIOobject::write();
|
||||
}
|
||||
|
||||
|
||||
void updateCompressibleCase(const fvMesh& mesh)
|
||||
{
|
||||
Info<< "Case treated as compressible" << nl << endl;
|
||||
createVolScalarField
|
||||
(
|
||||
mesh,
|
||||
"mut",
|
||||
dimArea/dimTime*dimDensity
|
||||
);
|
||||
replaceBoundaryType
|
||||
(
|
||||
mesh,
|
||||
"mut",
|
||||
compressible::mutkWallFunctionFvPatchScalarField::typeName,
|
||||
"0"
|
||||
);
|
||||
replaceBoundaryType
|
||||
(
|
||||
mesh,
|
||||
"epsilon",
|
||||
compressible::epsilonWallFunctionFvPatchScalarField::typeName,
|
||||
"0"
|
||||
);
|
||||
replaceBoundaryType
|
||||
(
|
||||
mesh,
|
||||
"omega",
|
||||
compressible::omegaWallFunctionFvPatchScalarField::typeName,
|
||||
"0"
|
||||
);
|
||||
replaceBoundaryType
|
||||
(
|
||||
mesh,
|
||||
"k",
|
||||
compressible::kqRWallFunctionFvPatchField<scalar>::typeName,
|
||||
"0"
|
||||
);
|
||||
replaceBoundaryType
|
||||
(
|
||||
mesh,
|
||||
"q",
|
||||
compressible::kqRWallFunctionFvPatchField<scalar>::typeName,
|
||||
"0"
|
||||
);
|
||||
replaceBoundaryType
|
||||
(
|
||||
mesh,
|
||||
"R",
|
||||
compressible::kqRWallFunctionFvPatchField<symmTensor>::
|
||||
typeName,
|
||||
"(0 0 0 0 0 0)"
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
void updateIncompressibleCase(const fvMesh& mesh)
|
||||
{
|
||||
Info<< "Case treated as incompressible" << nl << endl;
|
||||
createVolScalarField(mesh, "nut", dimArea/dimTime);
|
||||
|
||||
replaceBoundaryType
|
||||
(
|
||||
mesh,
|
||||
"nut",
|
||||
incompressible::nutkWallFunctionFvPatchScalarField::typeName,
|
||||
"0"
|
||||
);
|
||||
replaceBoundaryType
|
||||
(
|
||||
mesh,
|
||||
"epsilon",
|
||||
incompressible::epsilonWallFunctionFvPatchScalarField::
|
||||
typeName,
|
||||
"0"
|
||||
);
|
||||
replaceBoundaryType
|
||||
(
|
||||
mesh,
|
||||
"omega",
|
||||
incompressible::omegaWallFunctionFvPatchScalarField::
|
||||
typeName,
|
||||
"0"
|
||||
);
|
||||
replaceBoundaryType
|
||||
(
|
||||
mesh,
|
||||
"k",
|
||||
incompressible::kqRWallFunctionFvPatchField<scalar>::typeName,
|
||||
"0"
|
||||
);
|
||||
replaceBoundaryType
|
||||
(
|
||||
mesh,
|
||||
"q",
|
||||
incompressible::kqRWallFunctionFvPatchField<scalar>::typeName,
|
||||
"0"
|
||||
);
|
||||
replaceBoundaryType
|
||||
(
|
||||
mesh,
|
||||
"R",
|
||||
incompressible::kqRWallFunctionFvPatchField<symmTensor>::typeName,
|
||||
"(0 0 0 0 0 0)"
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
#include "addTimeOptions.H"
|
||||
argList::addBoolOption
|
||||
(
|
||||
"compressible",
|
||||
"force use of compressible wall functions. Default is auto-detect."
|
||||
);
|
||||
|
||||
#include "setRootCase.H"
|
||||
#include "createTime.H"
|
||||
#include "createMesh.H"
|
||||
|
||||
const bool compressible = args.optionFound("compressible");
|
||||
|
||||
Info<< "Updating turbulence fields to operate using new run time "
|
||||
<< "selectable" << nl << "wall functions"
|
||||
<< nl << endl;
|
||||
|
||||
if (compressible || caseIsCompressible(mesh))
|
||||
{
|
||||
updateCompressibleCase(mesh);
|
||||
}
|
||||
else
|
||||
{
|
||||
updateIncompressibleCase(mesh);
|
||||
}
|
||||
|
||||
Info<< "End\n" << endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
3
applications/utilities/preProcessing/boxTurb/Make/files
Normal file
3
applications/utilities/preProcessing/boxTurb/Make/files
Normal file
@ -0,0 +1,3 @@
|
||||
boxTurb.C
|
||||
|
||||
EXE = $(FOAM_APPBIN)/boxTurb
|
||||
@ -0,0 +1,7 @@
|
||||
EXE_INC = \
|
||||
-I$(LIB_SRC)/randomProcesses/lnInclude \
|
||||
-I$(LIB_SRC)/finiteVolume/lnInclude
|
||||
|
||||
EXE_LIBS = \
|
||||
-lrandomProcesses \
|
||||
-lfiniteVolume
|
||||
83
applications/utilities/preProcessing/boxTurb/boxTurb.C
Normal file
83
applications/utilities/preProcessing/boxTurb/boxTurb.C
Normal file
@ -0,0 +1,83 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / 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/>.
|
||||
|
||||
Application
|
||||
boxTurb
|
||||
|
||||
Description
|
||||
Makes a box of turbulence which conforms to a given energy
|
||||
spectrum and is divergence free.
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "fvCFD.H"
|
||||
#include "graph.H"
|
||||
#include "OFstream.H"
|
||||
#include "Kmesh.H"
|
||||
#include "turbGen.H"
|
||||
#include "calcEk.H"
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
argList::noParallel();
|
||||
#include "setRootCase.H"
|
||||
|
||||
#include "createTime.H"
|
||||
#include "createMesh.H"
|
||||
#include "createFields.H"
|
||||
#include "readBoxTurbDict.H"
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
Kmesh K(mesh);
|
||||
|
||||
turbGen Ugen(K, Ea, k0);
|
||||
|
||||
U.internalField() = Ugen.U();
|
||||
U.correctBoundaryConditions();
|
||||
|
||||
Info<< "k("
|
||||
<< runTime.timeName()
|
||||
<< ") = "
|
||||
<< 3.0/2.0*average(magSqr(U)).value() << endl;
|
||||
|
||||
U.write();
|
||||
|
||||
calcEk(U, K).write
|
||||
(
|
||||
runTime.path()/"graphs"/runTime.timeName(),
|
||||
"Ek",
|
||||
runTime.graphFormat()
|
||||
);
|
||||
|
||||
Info<< "end" << endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
14
applications/utilities/preProcessing/boxTurb/createFields.H
Normal file
14
applications/utilities/preProcessing/boxTurb/createFields.H
Normal file
@ -0,0 +1,14 @@
|
||||
Info<< "Reading field U\n" << endl;
|
||||
|
||||
volVectorField U
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
"U",
|
||||
runTime.timeName(),
|
||||
mesh,
|
||||
IOobject::MUST_READ,
|
||||
IOobject::AUTO_WRITE
|
||||
),
|
||||
mesh
|
||||
);
|
||||
@ -0,0 +1,17 @@
|
||||
Info<< "Reading boxTurbDict\n" << endl;
|
||||
|
||||
IOdictionary boxTurbDict
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
"boxTurbDict",
|
||||
runTime.constant(),
|
||||
mesh,
|
||||
IOobject::MUST_READ_IF_MODIFIED,
|
||||
IOobject::NO_WRITE
|
||||
)
|
||||
);
|
||||
|
||||
scalar Ea(readScalar(boxTurbDict.lookup("Ea")));
|
||||
|
||||
scalar k0(readScalar(boxTurbDict.lookup("k0")));
|
||||
@ -0,0 +1,3 @@
|
||||
changeDictionary.C
|
||||
|
||||
EXE = $(FOAM_APPBIN)/changeDictionary
|
||||
@ -0,0 +1,9 @@
|
||||
EXE_INC = \
|
||||
-I$(LIB_SRC)/finiteVolume/lnInclude \
|
||||
-I$(LIB_SRC)/dynamicMesh/lnInclude \
|
||||
-I$(LIB_SRC)/meshTools/lnInclude
|
||||
|
||||
EXE_LIBS = \
|
||||
-lfiniteVolume \
|
||||
-ldynamicMesh \
|
||||
-lmeshTools
|
||||
@ -0,0 +1,663 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / 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/>.
|
||||
|
||||
Application
|
||||
changeDictionary
|
||||
|
||||
Description
|
||||
Utility to change dictionary entries, e.g. can be used to change the patch
|
||||
type in the field and polyMesh/boundary files.
|
||||
|
||||
Reads dictionaries (fields) and entries to change from a dictionary.
|
||||
E.g. to make the \em movingWall a \em fixedValue for \em p but all other
|
||||
\em Walls a zeroGradient boundary condition, the
|
||||
\c system/changeDictionaryDict would contain the following:
|
||||
\verbatim
|
||||
dictionaryReplacement
|
||||
{
|
||||
p // field to change
|
||||
{
|
||||
boundaryField
|
||||
{
|
||||
".*Wall" // entry to change
|
||||
{
|
||||
type zeroGradient;
|
||||
}
|
||||
movingWall // entry to change
|
||||
{
|
||||
type fixedValue;
|
||||
value uniform 123.45;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
\endverbatim
|
||||
Replacement entries starting with '~' will remove the entry.
|
||||
|
||||
Usage
|
||||
|
||||
- changeDictionary [OPTION]
|
||||
|
||||
\param -literalRE \n
|
||||
Do not interpret regular expressions or patchGroups;
|
||||
treat them as any other keyword.
|
||||
|
||||
\param -enableFunctionEntries \n
|
||||
By default all dictionary preprocessing of fields is disabled
|
||||
|
||||
\param -disablePatchGroups \n
|
||||
By default all keys are also checked for being patchGroups
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "argList.H"
|
||||
#include "IOobjectList.H"
|
||||
#include "IOPtrList.H"
|
||||
#include "volFields.H"
|
||||
#include "stringListOps.H"
|
||||
#include "timeSelector.H"
|
||||
|
||||
using namespace Foam;
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
defineTemplateTypeNameAndDebug(IOPtrList<entry>, 0);
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
// Extract groupPatch (= shortcut) info from boundary file info
|
||||
HashTable<wordList, word> extractPatchGroups(const dictionary& boundaryDict)
|
||||
{
|
||||
HashTable<wordList, word> groupToPatch;
|
||||
|
||||
forAllConstIter(dictionary, boundaryDict, iter)
|
||||
{
|
||||
const word& patchName = iter().keyword();
|
||||
const dictionary& patchDict = iter().dict();
|
||||
|
||||
wordList groups;
|
||||
if (patchDict.readIfPresent("inGroups", groups))
|
||||
{
|
||||
forAll(groups, i)
|
||||
{
|
||||
HashTable<wordList, word>::iterator fndGroup = groupToPatch.find
|
||||
(
|
||||
groups[i]
|
||||
);
|
||||
if (fndGroup == groupToPatch.end())
|
||||
{
|
||||
groupToPatch.insert(groups[i], wordList(1, patchName));
|
||||
}
|
||||
else
|
||||
{
|
||||
fndGroup().append(patchName);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return groupToPatch;
|
||||
}
|
||||
|
||||
|
||||
bool merge
|
||||
(
|
||||
dictionary&,
|
||||
const dictionary&,
|
||||
const bool,
|
||||
const HashTable<wordList, word>&
|
||||
);
|
||||
|
||||
|
||||
// Add thisEntry to dictionary thisDict.
|
||||
bool addEntry
|
||||
(
|
||||
dictionary& thisDict,
|
||||
entry& thisEntry,
|
||||
const entry& mergeEntry,
|
||||
const bool literalRE,
|
||||
const HashTable<wordList, word>& shortcuts
|
||||
)
|
||||
{
|
||||
bool changed = false;
|
||||
|
||||
// Recursively merge sub-dictionaries
|
||||
// TODO: merge without copying
|
||||
if (thisEntry.isDict() && mergeEntry.isDict())
|
||||
{
|
||||
if
|
||||
(
|
||||
merge
|
||||
(
|
||||
const_cast<dictionary&>(thisEntry.dict()),
|
||||
mergeEntry.dict(),
|
||||
literalRE,
|
||||
shortcuts
|
||||
)
|
||||
)
|
||||
{
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Should use in-place modification instead of adding
|
||||
thisDict.add(mergeEntry.clone(thisDict).ptr(), true);
|
||||
changed = true;
|
||||
}
|
||||
|
||||
return changed;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// List of indices into thisKeys
|
||||
labelList findMatches
|
||||
(
|
||||
const HashTable<wordList, word>& shortcuts,
|
||||
const wordList& shortcutNames,
|
||||
const wordList& thisKeys,
|
||||
const keyType& key
|
||||
)
|
||||
{
|
||||
labelList matches;
|
||||
|
||||
if (key.isPattern())
|
||||
{
|
||||
// Wildcard match
|
||||
matches = findStrings(key, thisKeys);
|
||||
|
||||
}
|
||||
else if (shortcuts.size())
|
||||
{
|
||||
// See if patchGroups expand to valid thisKeys
|
||||
labelList indices = findStrings(key, shortcutNames);
|
||||
forAll(indices, i)
|
||||
{
|
||||
const word& name = shortcutNames[indices[i]];
|
||||
const wordList& keys = shortcuts[name];
|
||||
forAll(keys, j)
|
||||
{
|
||||
label index = findIndex(thisKeys, keys[j]);
|
||||
if (index != -1)
|
||||
{
|
||||
matches.append(index);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return matches;
|
||||
}
|
||||
|
||||
|
||||
// Dictionary merging/editing.
|
||||
// literalRE:
|
||||
// - true: behave like dictionary::merge, i.e. add regexps just like
|
||||
// any other key.
|
||||
// - false : interpret wildcard as a rule for items to be matched.
|
||||
bool merge
|
||||
(
|
||||
dictionary& thisDict,
|
||||
const dictionary& mergeDict,
|
||||
const bool literalRE,
|
||||
const HashTable<wordList, word>& shortcuts
|
||||
)
|
||||
{
|
||||
const wordList shortcutNames(shortcuts.toc());
|
||||
|
||||
bool changed = false;
|
||||
|
||||
// Save current (non-wildcard) keys before adding items.
|
||||
HashSet<word> thisKeysSet;
|
||||
{
|
||||
List<keyType> keys = thisDict.keys(false);
|
||||
forAll(keys, i)
|
||||
{
|
||||
thisKeysSet.insert(keys[i]);
|
||||
}
|
||||
}
|
||||
|
||||
// Pass 1. All literal matches
|
||||
|
||||
forAllConstIter(IDLList<entry>, mergeDict, mergeIter)
|
||||
{
|
||||
const keyType& key = mergeIter().keyword();
|
||||
|
||||
if (key[0] == '~')
|
||||
{
|
||||
word eraseKey = key(1, key.size()-1);
|
||||
if (thisDict.remove(eraseKey))
|
||||
{
|
||||
// Mark thisDict entry as having been match for wildcard
|
||||
// handling later on.
|
||||
thisKeysSet.erase(eraseKey);
|
||||
}
|
||||
changed = true;
|
||||
}
|
||||
else if (literalRE || !(key.isPattern() || shortcuts.found(key)))
|
||||
{
|
||||
entry* entryPtr = thisDict.lookupEntryPtr
|
||||
(
|
||||
key,
|
||||
false, // recursive
|
||||
false // patternMatch
|
||||
);
|
||||
|
||||
if (entryPtr)
|
||||
{
|
||||
|
||||
// Mark thisDict entry as having been match for wildcard
|
||||
// handling later on.
|
||||
thisKeysSet.erase(entryPtr->keyword());
|
||||
|
||||
if
|
||||
(
|
||||
addEntry
|
||||
(
|
||||
thisDict,
|
||||
*entryPtr,
|
||||
mergeIter(),
|
||||
literalRE,
|
||||
shortcuts
|
||||
)
|
||||
)
|
||||
{
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// not found - just add
|
||||
thisDict.add(mergeIter().clone(thisDict).ptr());
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Pass 2. Wildcard or shortcut matches (if any) on any non-match keys.
|
||||
|
||||
if (!literalRE && thisKeysSet.size() > 0)
|
||||
{
|
||||
// Pick up remaining dictionary entries
|
||||
wordList thisKeys(thisKeysSet.toc());
|
||||
|
||||
forAllConstIter(IDLList<entry>, mergeDict, mergeIter)
|
||||
{
|
||||
const keyType& key = mergeIter().keyword();
|
||||
|
||||
if (key[0] == '~')
|
||||
{
|
||||
word eraseKey = key(1, key.size()-1);
|
||||
|
||||
// List of indices into thisKeys
|
||||
labelList matches
|
||||
(
|
||||
findMatches
|
||||
(
|
||||
shortcuts,
|
||||
shortcutNames,
|
||||
thisKeys,
|
||||
eraseKey
|
||||
)
|
||||
);
|
||||
|
||||
// Remove all matches
|
||||
forAll(matches, i)
|
||||
{
|
||||
const word& thisKey = thisKeys[matches[i]];
|
||||
thisKeysSet.erase(thisKey);
|
||||
}
|
||||
changed = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// List of indices into thisKeys
|
||||
labelList matches
|
||||
(
|
||||
findMatches
|
||||
(
|
||||
shortcuts,
|
||||
shortcutNames,
|
||||
thisKeys,
|
||||
key
|
||||
)
|
||||
);
|
||||
|
||||
// Add all matches
|
||||
forAll(matches, i)
|
||||
{
|
||||
const word& thisKey = thisKeys[matches[i]];
|
||||
|
||||
entry& thisEntry = const_cast<entry&>
|
||||
(
|
||||
thisDict.lookupEntry(thisKey, false, false)
|
||||
);
|
||||
|
||||
if
|
||||
(
|
||||
addEntry
|
||||
(
|
||||
thisDict,
|
||||
thisEntry,
|
||||
mergeIter(),
|
||||
literalRE,
|
||||
HashTable<wordList, word>(0) // no shortcuts
|
||||
// at deeper levels
|
||||
)
|
||||
)
|
||||
{
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return changed;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
#include "addDictOption.H"
|
||||
argList::addOption
|
||||
(
|
||||
"instance",
|
||||
"name",
|
||||
"override instance setting (default is the time name)"
|
||||
);
|
||||
|
||||
// Add explicit time option
|
||||
timeSelector::addOptions();
|
||||
|
||||
argList::addBoolOption
|
||||
(
|
||||
"literalRE",
|
||||
"treat regular expressions literally (i.e., as a keyword)"
|
||||
);
|
||||
argList::addBoolOption
|
||||
(
|
||||
"enableFunctionEntries",
|
||||
"enable expansion of dictionary directives - #include, #codeStream etc"
|
||||
);
|
||||
argList::addBoolOption
|
||||
(
|
||||
"disablePatchGroups",
|
||||
"disable matching keys to patch groups"
|
||||
);
|
||||
|
||||
#include "addRegionOption.H"
|
||||
|
||||
#include "setRootCase.H"
|
||||
#include "createTime.H"
|
||||
|
||||
// Optionally override controlDict time with -time options
|
||||
instantList times = timeSelector::selectIfPresent(runTime, args);
|
||||
if (times.size() < 1)
|
||||
{
|
||||
FatalErrorIn(args.executable())
|
||||
<< "No times selected." << exit(FatalError);
|
||||
}
|
||||
runTime.setTime(times[0], 0);
|
||||
word instance = args.optionLookupOrDefault("instance", runTime.timeName());
|
||||
|
||||
#include "createNamedMesh.H"
|
||||
|
||||
const bool literalRE = args.optionFound("literalRE");
|
||||
if (literalRE)
|
||||
{
|
||||
Info<< "Not interpreting any regular expressions (RE)"
|
||||
<< " in the changeDictionaryDict." << endl
|
||||
<< "Instead they are handled as any other entry, i.e. added if"
|
||||
<< " not present." << endl;
|
||||
}
|
||||
|
||||
const bool enableEntries = args.optionFound("enableFunctionEntries");
|
||||
if (enableEntries)
|
||||
{
|
||||
Info<< "Allowing dictionary preprocessing ('#include', '#codeStream')."
|
||||
<< endl;
|
||||
}
|
||||
|
||||
int oldFlag = entry::disableFunctionEntries;
|
||||
if (!enableEntries)
|
||||
{
|
||||
// By default disable dictionary expansion for fields
|
||||
entry::disableFunctionEntries = 1;
|
||||
}
|
||||
|
||||
|
||||
const bool disablePatchGroups = args.optionFound("disablePatchGroups");
|
||||
if (disablePatchGroups)
|
||||
{
|
||||
Info<< "Not interpreting any keys in the changeDictionary"
|
||||
<< " as patchGroups"
|
||||
<< endl;
|
||||
}
|
||||
|
||||
|
||||
fileName regionPrefix = "";
|
||||
if (regionName != fvMesh::defaultRegion)
|
||||
{
|
||||
regionPrefix = regionName;
|
||||
}
|
||||
|
||||
|
||||
// Make sure we do not use the master-only reading since we read
|
||||
// fields (different per processor) as dictionaries.
|
||||
regIOobject::fileModificationChecking = regIOobject::timeStamp;
|
||||
|
||||
|
||||
// Get the replacement rules from a dictionary
|
||||
|
||||
const word dictName("changeDictionaryDict");
|
||||
#include "setSystemMeshDictionaryIO.H"
|
||||
IOdictionary dict(dictIO);
|
||||
|
||||
const dictionary& replaceDicts = dict.subDict("dictionaryReplacement");
|
||||
Info<< "Read dictionary " << dict.name()
|
||||
<< " with replacements for dictionaries "
|
||||
<< replaceDicts.toc() << endl;
|
||||
|
||||
|
||||
|
||||
// Always read boundary to get patch groups
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Info<< "Reading polyMesh/boundary file to extract patch names"
|
||||
<< endl;
|
||||
|
||||
// Read PtrList of dictionary as dictionary.
|
||||
const word oldTypeName = IOPtrList<entry>::typeName;
|
||||
const_cast<word&>(IOPtrList<entry>::typeName) = word::null;
|
||||
IOPtrList<entry> dictList
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
"boundary",
|
||||
runTime.findInstance
|
||||
(
|
||||
regionPrefix/polyMesh::meshSubDir,
|
||||
"boundary",
|
||||
IOobject::READ_IF_PRESENT
|
||||
),
|
||||
polyMesh::meshSubDir,
|
||||
mesh,
|
||||
IOobject::READ_IF_PRESENT,
|
||||
IOobject::NO_WRITE,
|
||||
false
|
||||
)
|
||||
);
|
||||
const_cast<word&>(IOPtrList<entry>::typeName) = oldTypeName;
|
||||
// Fake type back to what was in field
|
||||
const_cast<word&>(dictList.type()) = dictList.headerClassName();
|
||||
|
||||
// Temporary convert to dictionary
|
||||
dictionary fieldDict;
|
||||
forAll(dictList, i)
|
||||
{
|
||||
fieldDict.add(dictList[i].keyword(), dictList[i].dict());
|
||||
}
|
||||
|
||||
if (dictList.size())
|
||||
{
|
||||
Info<< "Loaded dictionary " << dictList.name()
|
||||
<< " with entries " << fieldDict.toc() << endl;
|
||||
}
|
||||
|
||||
// Extract any patchGroups information (= shortcut for set of
|
||||
// patches)
|
||||
HashTable<wordList, word> patchGroups;
|
||||
if (!disablePatchGroups)
|
||||
{
|
||||
patchGroups = extractPatchGroups(fieldDict);
|
||||
if (patchGroups.size())
|
||||
{
|
||||
Info<< "Extracted patch groups:" << endl;
|
||||
wordList groups(patchGroups.sortedToc());
|
||||
forAll(groups, i)
|
||||
{
|
||||
Info<< " group " << groups[i] << " with patches "
|
||||
<< patchGroups[groups[i]] << endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Every replacement is a dictionary name and a keyword in this
|
||||
|
||||
forAllConstIter(dictionary, replaceDicts, fieldIter)
|
||||
{
|
||||
const word& fieldName = fieldIter().keyword();
|
||||
Info<< "Replacing entries in dictionary " << fieldName << endl;
|
||||
|
||||
// Handle 'boundary' specially:
|
||||
// - is PtrList of dictionaries
|
||||
// - is in polyMesh/
|
||||
if (fieldName == "boundary")
|
||||
{
|
||||
Info<< "Special handling of " << fieldName
|
||||
<< " as polyMesh/boundary file." << endl;
|
||||
|
||||
// Get the replacement dictionary for the field
|
||||
const dictionary& replaceDict = fieldIter().dict();
|
||||
Info<< "Merging entries from " << replaceDict.toc() << endl;
|
||||
|
||||
// Merge the replacements in
|
||||
merge(fieldDict, replaceDict, literalRE, patchGroups);
|
||||
|
||||
Info<< "fieldDict:" << fieldDict << endl;
|
||||
|
||||
// Convert back into dictList
|
||||
wordList doneKeys(dictList.size());
|
||||
|
||||
label nEntries = fieldDict.size();
|
||||
|
||||
forAll(dictList, i)
|
||||
{
|
||||
doneKeys[i] = dictList[i].keyword();
|
||||
dictList.set
|
||||
(
|
||||
i,
|
||||
fieldDict.lookupEntry
|
||||
(
|
||||
doneKeys[i],
|
||||
false,
|
||||
true
|
||||
).clone()
|
||||
);
|
||||
fieldDict.remove(doneKeys[i]);
|
||||
}
|
||||
|
||||
// Add remaining entries
|
||||
label sz = dictList.size();
|
||||
dictList.setSize(nEntries);
|
||||
forAllConstIter(dictionary, fieldDict, iter)
|
||||
{
|
||||
dictList.set(sz++, iter().clone());
|
||||
}
|
||||
|
||||
Info<< "Writing modified " << fieldName << endl;
|
||||
dictList.writeObject
|
||||
(
|
||||
runTime.writeFormat(),
|
||||
runTime.writeFormat(),
|
||||
IOstream::UNCOMPRESSED
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Read dictionary. (disable class type checking so we can load
|
||||
// field)
|
||||
Info<< "Loading dictionary " << fieldName << endl;
|
||||
const word oldTypeName = IOdictionary::typeName;
|
||||
const_cast<word&>(IOdictionary::typeName) = word::null;
|
||||
|
||||
IOdictionary fieldDict
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
fieldName,
|
||||
instance,
|
||||
mesh,
|
||||
IOobject::MUST_READ_IF_MODIFIED,
|
||||
IOobject::NO_WRITE,
|
||||
false
|
||||
)
|
||||
);
|
||||
|
||||
const_cast<word&>(IOdictionary::typeName) = oldTypeName;
|
||||
// Fake type back to what was in field
|
||||
const_cast<word&>(fieldDict.type()) = fieldDict.headerClassName();
|
||||
|
||||
Info<< "Loaded dictionary " << fieldName
|
||||
<< " with entries " << fieldDict.toc() << endl;
|
||||
|
||||
// Get the replacement dictionary for the field
|
||||
const dictionary& replaceDict = fieldIter().dict();
|
||||
Info<< "Merging entries from " << replaceDict.toc() << endl;
|
||||
|
||||
// Merge the replacements in
|
||||
merge(fieldDict, replaceDict, literalRE, patchGroups);
|
||||
|
||||
Info<< "Writing modified fieldDict " << fieldName << endl;
|
||||
fieldDict.regIOobject::write();
|
||||
}
|
||||
}
|
||||
|
||||
entry::disableFunctionEntries = oldFlag;
|
||||
|
||||
Info<< endl;
|
||||
|
||||
Info<< "End\n" << endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,89 @@
|
||||
/*--------------------------------*- 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;
|
||||
object changeDictionaryDict;
|
||||
}
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
dictionaryReplacement
|
||||
{
|
||||
boundary
|
||||
{
|
||||
".*"
|
||||
{
|
||||
type mappedPatch;
|
||||
}
|
||||
}
|
||||
|
||||
T
|
||||
{
|
||||
internalField uniform 300;
|
||||
|
||||
boundaryField
|
||||
{
|
||||
".*"
|
||||
{
|
||||
type zeroGradient;
|
||||
}
|
||||
|
||||
minY
|
||||
{
|
||||
type fixedValue;
|
||||
value uniform 500;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
rho
|
||||
{
|
||||
internalField uniform 8000;
|
||||
|
||||
boundaryField
|
||||
{
|
||||
".*"
|
||||
{
|
||||
type zeroGradient;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
K
|
||||
{
|
||||
internalField uniform 80;
|
||||
|
||||
boundaryField
|
||||
{
|
||||
".*"
|
||||
{
|
||||
type zeroGradient;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
cp
|
||||
{
|
||||
internalField uniform 450;
|
||||
|
||||
boundaryField
|
||||
{
|
||||
".*"
|
||||
{
|
||||
type zeroGradient;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,3 @@
|
||||
createExternalCoupledPatchGeometry.C
|
||||
|
||||
EXE = $(FOAM_APPBIN)/createExternalCoupledPatchGeometry
|
||||
@ -0,0 +1,6 @@
|
||||
EXE_INC = \
|
||||
-I$(LIB_SRC)/finiteVolume/lnInclude
|
||||
|
||||
EXE_LIBS = \
|
||||
-lfiniteVolume \
|
||||
-lcompressibleTurbulenceModel
|
||||
@ -0,0 +1,87 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2013-2014 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
|
||||
createExternalCoupledPatchGeometry.
|
||||
|
||||
Description
|
||||
Application to generate the patch geometry (points and faces) for use
|
||||
with the externalCoupled boundary condition.
|
||||
|
||||
Usage:
|
||||
|
||||
createExternalCoupledPatchGeometry \<fieldName\>
|
||||
|
||||
On execution, the field \<fieldName\> is read, and its boundary conditions
|
||||
interrogated for the presence of an \c externalCoupled type. If found,
|
||||
the patch geometry (points and faces) for the coupled patches are output
|
||||
to the communications directory.
|
||||
|
||||
Note:
|
||||
The addressing is patch-local, i.e. point indices for each patch point
|
||||
used for face addressing starts at index 0.
|
||||
|
||||
SeeAlso
|
||||
externalCoupledMixedFvPatchField
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "fvCFD.H"
|
||||
#include "createExternalCoupledPatchGeometryTemplates.H"
|
||||
#include "IOobjectList.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
#include "addRegionOption.H"
|
||||
argList::validArgs.append("fieldName");
|
||||
#include "setRootCase.H"
|
||||
#include "createTime.H"
|
||||
#include "createNamedMesh.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
const word fieldName = args[1];
|
||||
|
||||
IOobjectList objects(IOobjectList(mesh, mesh.time().timeName()));
|
||||
|
||||
label processed = -1;
|
||||
processField<scalar>(mesh, objects, fieldName, processed);
|
||||
processField<vector>(mesh, objects, fieldName, processed);
|
||||
processField<sphericalTensor>(mesh, objects, fieldName, processed);
|
||||
processField<symmTensor>(mesh, objects, fieldName, processed);
|
||||
processField<tensor>(mesh, objects, fieldName, processed);
|
||||
|
||||
if (processed == -1)
|
||||
{
|
||||
Info<< "Field " << fieldName << " not found" << endl;
|
||||
}
|
||||
|
||||
Info<< "\nEnd\n" << endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,90 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / 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 "createExternalCoupledPatchGeometryTemplates.H"
|
||||
#include "externalCoupledMixedFvPatchField.H"
|
||||
#include "IOobjectList.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
template<class Type>
|
||||
void processField
|
||||
(
|
||||
const fvMesh& mesh,
|
||||
const IOobjectList& objects,
|
||||
const word& fieldName,
|
||||
label& processed
|
||||
)
|
||||
{
|
||||
if (processed != -1)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
typedef GeometricField<Type, fvPatchField, volMesh> fieldType;
|
||||
|
||||
const word timeName(mesh.time().timeName());
|
||||
|
||||
IOobjectList fieldObjbjects(objects.lookupClass(fieldType::typeName));
|
||||
|
||||
if (fieldObjbjects.lookup(fieldName) != NULL)
|
||||
{
|
||||
fieldType vtf(*fieldObjbjects.lookup(fieldName), mesh);
|
||||
const typename fieldType::GeometricBoundaryField& bf =
|
||||
vtf.boundaryField();
|
||||
|
||||
forAll(bf, patchI)
|
||||
{
|
||||
if (isA<externalCoupledMixedFvPatchField<Type> >(bf[patchI]))
|
||||
{
|
||||
Info<< "Generating external coupled geometry for field "
|
||||
<< fieldName << endl;
|
||||
|
||||
const externalCoupledMixedFvPatchField<Type>& pf =
|
||||
refCast<const externalCoupledMixedFvPatchField<Type> >
|
||||
(
|
||||
bf[patchI]
|
||||
);
|
||||
|
||||
pf.writeGeometry();
|
||||
processed = 1;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (processed != 1)
|
||||
{
|
||||
processed = 0;
|
||||
|
||||
Info<< "Field " << fieldName << " found, but does not have any "
|
||||
<< externalCoupledMixedFvPatchField<Type>::typeName
|
||||
<< " boundary conditions" << endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,49 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / 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/>.
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef createExternalCoupledPatchGeometryTemplates_H
|
||||
#define createExternalCoupledPatchGeometryTemplates_H
|
||||
|
||||
#include "word.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
template<class Type>
|
||||
void processField(bool& processed, const word& fieldName);
|
||||
}
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#ifdef NoRepository
|
||||
# include "createExternalCoupledPatchGeometryTemplates.C"
|
||||
#endif
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,3 @@
|
||||
dsmcInitialise.C
|
||||
|
||||
EXE = $(FOAM_APPBIN)/dsmcInitialise
|
||||
@ -0,0 +1,11 @@
|
||||
EXE_INC = \
|
||||
-I$(LIB_SRC)/finiteVolume/lnInclude \
|
||||
-I$(LIB_SRC)/lagrangian/basic/lnInclude \
|
||||
-I$(LIB_SRC)/lagrangian/dsmc/lnInclude \
|
||||
-I$(LIB_SRC)/meshTools/lnInclude
|
||||
|
||||
EXE_LIBS = \
|
||||
-lmeshTools \
|
||||
-lfiniteVolume \
|
||||
-llagrangian \
|
||||
-ldsmc
|
||||
@ -0,0 +1,90 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / 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/>.
|
||||
|
||||
Application
|
||||
dsmcInitialise
|
||||
|
||||
Description
|
||||
Initialise a case for dsmcFoam by reading the initialisation dictionary
|
||||
system/dsmcInitialise.
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "fvCFD.H"
|
||||
#include "dsmcCloud.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
#include "setRootCase.H"
|
||||
#include "createTime.H"
|
||||
#include "createMesh.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
IOdictionary dsmcInitialiseDict
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
"dsmcInitialiseDict",
|
||||
mesh.time().system(),
|
||||
mesh,
|
||||
IOobject::MUST_READ_IF_MODIFIED,
|
||||
IOobject::NO_WRITE
|
||||
)
|
||||
);
|
||||
|
||||
Info<< "Initialising dsmc for Time = " << runTime.timeName() << nl << endl;
|
||||
|
||||
dsmcCloud dsmc("dsmc", mesh, dsmcInitialiseDict);
|
||||
|
||||
label totalMolecules = dsmc.size();
|
||||
|
||||
if (Pstream::parRun())
|
||||
{
|
||||
reduce(totalMolecules, sumOp<label>());
|
||||
}
|
||||
|
||||
Info<< nl << "Total number of molecules added: " << totalMolecules
|
||||
<< nl << endl;
|
||||
|
||||
IOstream::defaultPrecision(15);
|
||||
|
||||
if (!mesh.write())
|
||||
{
|
||||
FatalErrorIn(args.executable())
|
||||
<< "Failed writing dsmcCloud."
|
||||
<< nl << exit(FatalError);
|
||||
}
|
||||
|
||||
Info<< nl << "ClockTime = " << runTime.elapsedClockTime() << " s"
|
||||
<< nl << endl;
|
||||
|
||||
Info<< "End\n" << endl;
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,3 @@
|
||||
engineSwirl.C
|
||||
|
||||
EXE = $(FOAM_APPBIN)/engineSwirl
|
||||
@ -0,0 +1,7 @@
|
||||
EXE_INC = \
|
||||
-I$(LIB_SRC)/finiteVolume/lnInclude
|
||||
|
||||
EXE_LIBS = \
|
||||
-lfiniteVolume \
|
||||
-lgenericPatchFields
|
||||
|
||||
@ -0,0 +1,79 @@
|
||||
Info<< "Reading combustion properties\n" << endl;
|
||||
|
||||
IOdictionary engineGeometry
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
"engineGeometry",
|
||||
runTime.constant(),
|
||||
mesh,
|
||||
IOobject::MUST_READ_IF_MODIFIED,
|
||||
IOobject::NO_WRITE
|
||||
)
|
||||
);
|
||||
|
||||
vector swirlAxis
|
||||
(
|
||||
engineGeometry.lookup("swirlAxis")
|
||||
);
|
||||
|
||||
vector swirlCenter
|
||||
(
|
||||
engineGeometry.lookup("swirlCenter")
|
||||
);
|
||||
|
||||
dimensionedScalar swirlRPMRatio
|
||||
(
|
||||
engineGeometry.lookup("swirlRPMRatio")
|
||||
);
|
||||
|
||||
dimensionedScalar swirlProfile
|
||||
(
|
||||
engineGeometry.lookup("swirlProfile")
|
||||
);
|
||||
|
||||
dimensionedScalar bore
|
||||
(
|
||||
engineGeometry.lookup("bore")
|
||||
);
|
||||
|
||||
dimensionedScalar rpm
|
||||
(
|
||||
engineGeometry.lookup("rpm")
|
||||
);
|
||||
|
||||
|
||||
Info<< "Reading field U\n" << endl;
|
||||
volVectorField U
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
"U",
|
||||
runTime.timeName(),
|
||||
mesh,
|
||||
IOobject::MUST_READ,
|
||||
IOobject::AUTO_WRITE
|
||||
),
|
||||
mesh
|
||||
);
|
||||
|
||||
vector zT = swirlAxis;
|
||||
vector yT = vector(0, zT.z(), -zT.y());
|
||||
vector xT = vector
|
||||
(
|
||||
zT.y()*zT.y() + zT.z()*zT.z(),
|
||||
-zT.x()*zT.y(),
|
||||
-zT.x()*zT.z()
|
||||
);
|
||||
|
||||
// if swirl is around (1, 0, 0) we have to find another transformation
|
||||
if (mag(yT) < SMALL)
|
||||
{
|
||||
yT = vector(zT.y(), -zT.x(), 0);
|
||||
xT = vector(-zT.x()*zT.z(), -zT.y()*zT.z(), zT.x()*zT.x() + zT.y()*zT.y());
|
||||
}
|
||||
|
||||
//swirlAxis doesn't have to be of unit length.
|
||||
xT /= mag(xT);
|
||||
yT /= mag(yT);
|
||||
zT /= mag(zT);
|
||||
@ -0,0 +1,81 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / 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/>.
|
||||
|
||||
Application
|
||||
engineSwirl
|
||||
|
||||
Description
|
||||
Generates a swirling flow for engine calulations.
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "fvCFD.H"
|
||||
#include "mathematicalConstants.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
|
||||
# include "setRootCase.H"
|
||||
# include "createTime.H"
|
||||
# include "createMesh.H"
|
||||
# include "createFields.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
scalar Vphi = (constant::mathematical::pi*swirlRPMRatio*rpm/30).value();
|
||||
scalar b1 = j1(swirlProfile).value();
|
||||
scalar b2 = 2.0*b1/swirlProfile.value() - j0(swirlProfile).value();
|
||||
|
||||
scalar omega = 0.125*(Vphi*bore*swirlProfile/b2).value();
|
||||
|
||||
scalar cylinderRadius = 0.5*bore.value();
|
||||
|
||||
scalar Umax = 0.0;
|
||||
forAll(mesh.C(), celli)
|
||||
{
|
||||
vector c = mesh.C()[celli] - swirlCenter;
|
||||
scalar r = ::pow(sqr(c & xT) + sqr(c & yT), 0.5);
|
||||
|
||||
if (r <= cylinderRadius)
|
||||
{
|
||||
scalar b = j1(swirlProfile*r/cylinderRadius).value();
|
||||
scalar vEff = omega*b;
|
||||
r = max(r, SMALL);
|
||||
U[celli] = ((vEff/r)*(c & yT))*xT + (-(vEff/r)*(c & xT))*yT;
|
||||
Umax = max(Umax, mag(U[celli]));
|
||||
}
|
||||
}
|
||||
|
||||
Info<< "Umax = " << Umax << endl;
|
||||
|
||||
U.write();
|
||||
|
||||
Info<< "\n end\n";
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,3 @@
|
||||
faceAgglomerate.C
|
||||
|
||||
EXE = $(FOAM_APPBIN)/faceAgglomerate
|
||||
@ -0,0 +1,11 @@
|
||||
EXE_INC = \
|
||||
-I$(LIB_SRC)/finiteVolume/lnInclude \
|
||||
-I$(LIB_SRC)/OpenFOAM/lnInclude \
|
||||
-I$(LIB_SRC)/fvAgglomerationMethods/pairPatchAgglomeration/lnInclude
|
||||
|
||||
EXE_LIBS = \
|
||||
-lOpenFOAM \
|
||||
-lfiniteVolume \
|
||||
-lpairPatchAgglomeration \
|
||||
-ltriSurface \
|
||||
-lmeshTools
|
||||
@ -0,0 +1,204 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / 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/>.
|
||||
|
||||
Application
|
||||
faceAgglomerate
|
||||
|
||||
Description
|
||||
|
||||
Agglomerate boundary faces using the pairPatchAgglomeration algorithm.
|
||||
It writes a map from the fine to coarse grid.
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "argList.H"
|
||||
#include "fvMesh.H"
|
||||
#include "Time.H"
|
||||
#include "volFields.H"
|
||||
#include "CompactListList.H"
|
||||
#include "unitConversion.H"
|
||||
#include "pairPatchAgglomeration.H"
|
||||
#include "labelListIOList.H"
|
||||
#include "syncTools.H"
|
||||
#include "globalIndex.H"
|
||||
|
||||
using namespace Foam;
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
#include "addRegionOption.H"
|
||||
#include "addDictOption.H"
|
||||
#include "setRootCase.H"
|
||||
#include "createTime.H"
|
||||
#include "createNamedMesh.H"
|
||||
|
||||
const word dictName("viewFactorsDict");
|
||||
|
||||
#include "setConstantMeshDictionaryIO.H"
|
||||
|
||||
// Read control dictionary
|
||||
const IOdictionary agglomDict(dictIO);
|
||||
|
||||
bool writeAgglom = readBool(agglomDict.lookup("writeFacesAgglomeration"));
|
||||
|
||||
|
||||
const polyBoundaryMesh& boundary = mesh.boundaryMesh();
|
||||
|
||||
labelListIOList finalAgglom
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
"finalAgglom",
|
||||
mesh.facesInstance(),
|
||||
mesh,
|
||||
IOobject::NO_READ,
|
||||
IOobject::NO_WRITE,
|
||||
false
|
||||
),
|
||||
boundary.size()
|
||||
);
|
||||
|
||||
label nCoarseFaces = 0;
|
||||
|
||||
forAllConstIter(dictionary, agglomDict, iter)
|
||||
{
|
||||
labelList patchIds = boundary.findIndices(iter().keyword());
|
||||
forAll(patchIds, i)
|
||||
{
|
||||
label patchI = patchIds[i];
|
||||
const polyPatch& pp = boundary[patchI];
|
||||
if (!pp.coupled())
|
||||
{
|
||||
Info << "\nAgglomerating patch : " << pp.name() << endl;
|
||||
pairPatchAgglomeration agglomObject
|
||||
(
|
||||
pp,
|
||||
agglomDict.subDict(pp.name())
|
||||
);
|
||||
agglomObject.agglomerate();
|
||||
finalAgglom[patchI] =
|
||||
agglomObject.restrictTopBottomAddressing();
|
||||
|
||||
if (finalAgglom[patchI].size())
|
||||
{
|
||||
nCoarseFaces += max(finalAgglom[patchI] + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// - All patches which are not agglomarated are identity for finalAgglom
|
||||
forAll(boundary, patchId)
|
||||
{
|
||||
if (finalAgglom[patchId].size() == 0)
|
||||
{
|
||||
finalAgglom[patchId] = identity(boundary[patchId].size());
|
||||
}
|
||||
}
|
||||
|
||||
// Sync agglomeration across coupled patches
|
||||
labelList nbrAgglom(mesh.nFaces() - mesh.nInternalFaces(), -1);
|
||||
|
||||
forAll(boundary, patchId)
|
||||
{
|
||||
const polyPatch& pp = boundary[patchId];
|
||||
if (pp.coupled())
|
||||
{
|
||||
finalAgglom[patchId] = identity(pp.size());
|
||||
forAll(pp, i)
|
||||
{
|
||||
nbrAgglom[pp.start() - mesh.nInternalFaces() + i] =
|
||||
finalAgglom[patchId][i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
syncTools::swapBoundaryFaceList(mesh, nbrAgglom);
|
||||
forAll(boundary, patchId)
|
||||
{
|
||||
const polyPatch& pp = boundary[patchId];
|
||||
if (pp.coupled() && !refCast<const coupledPolyPatch>(pp).owner())
|
||||
{
|
||||
forAll(pp, i)
|
||||
{
|
||||
finalAgglom[patchId][i] =
|
||||
nbrAgglom[pp.start() - mesh.nInternalFaces() + i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
finalAgglom.write();
|
||||
|
||||
if (writeAgglom)
|
||||
{
|
||||
globalIndex index(nCoarseFaces);
|
||||
volScalarField facesAgglomeration
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
"facesAgglomeration",
|
||||
mesh.time().timeName(),
|
||||
mesh,
|
||||
IOobject::NO_READ,
|
||||
IOobject::NO_WRITE
|
||||
),
|
||||
mesh,
|
||||
dimensionedScalar("facesAgglomeration", dimless, 0)
|
||||
);
|
||||
|
||||
label coarsePatchIndex = 0;
|
||||
forAll(boundary, patchId)
|
||||
{
|
||||
const polyPatch& pp = boundary[patchId];
|
||||
if (pp.size() > 0)
|
||||
{
|
||||
fvPatchScalarField& bFacesAgglomeration =
|
||||
facesAgglomeration.boundaryField()[patchId];
|
||||
|
||||
forAll(bFacesAgglomeration, j)
|
||||
{
|
||||
bFacesAgglomeration[j] =
|
||||
index.toGlobal
|
||||
(
|
||||
Pstream::myProcNo(),
|
||||
finalAgglom[patchId][j] + coarsePatchIndex
|
||||
);
|
||||
}
|
||||
|
||||
coarsePatchIndex += max(finalAgglom[patchId]) + 1;
|
||||
}
|
||||
}
|
||||
|
||||
Info<< "\nWriting facesAgglomeration" << endl;
|
||||
facesAgglomeration.write();
|
||||
}
|
||||
|
||||
Info<< "End\n" << endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,34 @@
|
||||
/*--------------------------------*- 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;
|
||||
object viewFactorsDict;
|
||||
}
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
// Write agglomeration as a volScalarField with calculated boundary values
|
||||
writeFacesAgglomeration true;
|
||||
|
||||
//Debug option
|
||||
debug 0;
|
||||
|
||||
//Dump connectivity rays
|
||||
dumpRays false;
|
||||
|
||||
// Per patch (wildcard possible) the coarsening level
|
||||
bottomAir_to_heater
|
||||
{
|
||||
nFacesInCoarsestLevel 30;
|
||||
featureAngle 10;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,3 @@
|
||||
foamUpgradeCyclics.C
|
||||
|
||||
EXE = $(FOAM_APPBIN)/foamUpgradeCyclics
|
||||
@ -0,0 +1,6 @@
|
||||
EXE_INC = \
|
||||
-I$(LIB_SRC)/finiteVolume/lnInclude
|
||||
|
||||
EXE_LIBS = \
|
||||
-lfiniteVolume \
|
||||
-lgenericPatchFields
|
||||
@ -0,0 +1,647 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / 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/>.
|
||||
|
||||
Application
|
||||
foamUpgradeCyclics
|
||||
|
||||
Description
|
||||
Tool to upgrade mesh and fields for split cyclics.
|
||||
|
||||
Usage
|
||||
|
||||
- foamUpgradeCyclics [OPTION]
|
||||
|
||||
\param -test \n
|
||||
Suppress writing the updated files with split cyclics
|
||||
|
||||
\param -enableFunctionEntries \n
|
||||
By default all dictionary preprocessing of fields is disabled
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "argList.H"
|
||||
#include "Time.H"
|
||||
#include "timeSelector.H"
|
||||
#include "IOdictionary.H"
|
||||
#include "polyMesh.H"
|
||||
#include "entry.H"
|
||||
#include "IOPtrList.H"
|
||||
#include "cyclicPolyPatch.H"
|
||||
#include "dictionaryEntry.H"
|
||||
#include "IOobjectList.H"
|
||||
#include "volFields.H"
|
||||
#include "pointFields.H"
|
||||
#include "surfaceFields.H"
|
||||
#include "string.H"
|
||||
|
||||
using namespace Foam;
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
defineTemplateTypeNameAndDebug(IOPtrList<entry>, 0);
|
||||
}
|
||||
|
||||
|
||||
// Read boundary file without reading mesh
|
||||
void rewriteBoundary
|
||||
(
|
||||
const bool isTestRun,
|
||||
const IOobject& io,
|
||||
const fileName& regionPrefix,
|
||||
HashTable<word>& thisNames,
|
||||
HashTable<word>& nbrNames
|
||||
)
|
||||
{
|
||||
Info<< "Reading boundary from " << io.filePath() << endl;
|
||||
|
||||
// Read PtrList of dictionary.
|
||||
const word oldTypeName = IOPtrList<entry>::typeName;
|
||||
const_cast<word&>(IOPtrList<entry>::typeName) = word::null;
|
||||
IOPtrList<entry> patches(io);
|
||||
const_cast<word&>(IOPtrList<entry>::typeName) = oldTypeName;
|
||||
// Fake type back to what was in field
|
||||
const_cast<word&>(patches.type()) = patches.headerClassName();
|
||||
|
||||
|
||||
// Replace any 'cyclic'
|
||||
label nOldCyclics = 0;
|
||||
forAll(patches, patchI)
|
||||
{
|
||||
const dictionary& patchDict = patches[patchI].dict();
|
||||
|
||||
if (word(patchDict["type"]) == cyclicPolyPatch::typeName)
|
||||
{
|
||||
if (!patchDict.found("neighbourPatch"))
|
||||
{
|
||||
Info<< "Patch " << patches[patchI].keyword()
|
||||
<< " does not have 'neighbourPatch' entry; assuming it"
|
||||
<< " is of the old type." << endl;
|
||||
nOldCyclics++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Info<< "Detected " << nOldCyclics << " old cyclics." << nl << endl;
|
||||
|
||||
|
||||
// Save old patches.
|
||||
PtrList<entry> oldPatches(patches);
|
||||
|
||||
// Extend
|
||||
label nOldPatches = patches.size();
|
||||
patches.setSize(nOldPatches+nOldCyclics);
|
||||
|
||||
// Create reordering map
|
||||
labelList oldToNew(patches.size());
|
||||
|
||||
|
||||
// Add new entries
|
||||
label addedPatchI = nOldPatches;
|
||||
label newPatchI = 0;
|
||||
forAll(oldPatches, patchI)
|
||||
{
|
||||
const dictionary& patchDict = oldPatches[patchI].dict();
|
||||
|
||||
if
|
||||
(
|
||||
word(patchDict["type"]) == cyclicPolyPatch::typeName
|
||||
)
|
||||
{
|
||||
const word& name = oldPatches[patchI].keyword();
|
||||
|
||||
if (patchDict.found("neighbourPatch"))
|
||||
{
|
||||
patches.set(patchI, oldPatches.set(patchI, NULL));
|
||||
oldToNew[patchI] = newPatchI++;
|
||||
|
||||
// Check if patches come from automatic conversion
|
||||
word oldName;
|
||||
|
||||
string::size_type i = name.rfind("_half0");
|
||||
if (i != string::npos)
|
||||
{
|
||||
oldName = name.substr(0, i);
|
||||
thisNames.insert(oldName, name);
|
||||
Info<< "Detected converted cyclic patch " << name
|
||||
<< " ; assuming it originates from " << oldName
|
||||
<< endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
i = name.rfind("_half1");
|
||||
if (i != string::npos)
|
||||
{
|
||||
oldName = name.substr(0, i);
|
||||
nbrNames.insert(oldName, name);
|
||||
Info<< "Detected converted cyclic patch " << name
|
||||
<< " ; assuming it originates from " << oldName
|
||||
<< endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
label nFaces = readLabel(patchDict["nFaces"]);
|
||||
label startFace = readLabel(patchDict["startFace"]);
|
||||
|
||||
Info<< "Detected old style " << word(patchDict["type"])
|
||||
<< " patch " << name << " with" << nl
|
||||
<< " nFaces : " << nFaces << nl
|
||||
<< " startFace : " << startFace << endl;
|
||||
|
||||
word thisName = name + "_half0";
|
||||
word nbrName = name + "_half1";
|
||||
|
||||
thisNames.insert(name, thisName);
|
||||
nbrNames.insert(name, nbrName);
|
||||
|
||||
// Save current dictionary
|
||||
const dictionary patchDict(patches[patchI].dict());
|
||||
|
||||
// Change entry on this side
|
||||
patches.set(patchI, oldPatches.set(patchI, NULL));
|
||||
oldToNew[patchI] = newPatchI++;
|
||||
dictionary& thisPatchDict = patches[patchI].dict();
|
||||
thisPatchDict.add("neighbourPatch", nbrName);
|
||||
thisPatchDict.set("nFaces", nFaces/2);
|
||||
patches[patchI].keyword() = thisName;
|
||||
|
||||
// Add entry on other side
|
||||
patches.set
|
||||
(
|
||||
addedPatchI,
|
||||
new dictionaryEntry
|
||||
(
|
||||
nbrName,
|
||||
dictionary::null,
|
||||
patchDict
|
||||
)
|
||||
);
|
||||
oldToNew[addedPatchI] = newPatchI++;
|
||||
dictionary& nbrPatchDict = patches[addedPatchI].dict();
|
||||
nbrPatchDict.set("neighbourPatch", thisName);
|
||||
nbrPatchDict.set("nFaces", nFaces/2);
|
||||
nbrPatchDict.set("startFace", startFace+nFaces/2);
|
||||
patches[addedPatchI].keyword() = nbrName;
|
||||
|
||||
Info<< "Replaced with patches" << nl
|
||||
<< patches[patchI].keyword() << " with" << nl
|
||||
<< " nFaces : "
|
||||
<< readLabel(thisPatchDict.lookup("nFaces"))
|
||||
<< nl
|
||||
<< " startFace : "
|
||||
<< readLabel(thisPatchDict.lookup("startFace")) << nl
|
||||
<< patches[addedPatchI].keyword() << " with" << nl
|
||||
<< " nFaces : "
|
||||
<< readLabel(nbrPatchDict.lookup("nFaces"))
|
||||
<< nl
|
||||
<< " startFace : "
|
||||
<< readLabel(nbrPatchDict.lookup("startFace"))
|
||||
<< nl << endl;
|
||||
|
||||
addedPatchI++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
patches.set(patchI, oldPatches.set(patchI, NULL));
|
||||
oldToNew[patchI] = newPatchI++;
|
||||
}
|
||||
}
|
||||
|
||||
patches.reorder(oldToNew);
|
||||
|
||||
if (returnReduce(nOldCyclics, sumOp<label>()) > 0)
|
||||
{
|
||||
if (isTestRun)
|
||||
{
|
||||
//Info<< "-test option: no changes made" << nl << endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (mvBak(patches.objectPath(), "old"))
|
||||
{
|
||||
Info<< "Backup to "
|
||||
<< (patches.objectPath() + ".old") << nl;
|
||||
}
|
||||
|
||||
Info<< "Write to "
|
||||
<< patches.objectPath() << nl << endl;
|
||||
patches.write();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Info<< "No changes made to boundary file." << nl << endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void rewriteField
|
||||
(
|
||||
const bool isTestRun,
|
||||
const Time& runTime,
|
||||
const word& fieldName,
|
||||
const HashTable<word>& thisNames,
|
||||
const HashTable<word>& nbrNames
|
||||
)
|
||||
{
|
||||
// Read dictionary. (disable class type checking so we can load
|
||||
// field)
|
||||
Info<< "Loading field " << fieldName << endl;
|
||||
const word oldTypeName = IOdictionary::typeName;
|
||||
const_cast<word&>(IOdictionary::typeName) = word::null;
|
||||
|
||||
IOdictionary fieldDict
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
fieldName,
|
||||
runTime.timeName(),
|
||||
runTime,
|
||||
IOobject::MUST_READ_IF_MODIFIED,
|
||||
IOobject::NO_WRITE,
|
||||
false
|
||||
)
|
||||
);
|
||||
const_cast<word&>(IOdictionary::typeName) = oldTypeName;
|
||||
// Fake type back to what was in field
|
||||
const_cast<word&>(fieldDict.type()) = fieldDict.headerClassName();
|
||||
|
||||
|
||||
|
||||
dictionary& boundaryField = fieldDict.subDict("boundaryField");
|
||||
|
||||
label nChanged = 0;
|
||||
|
||||
forAllConstIter(HashTable<word>, thisNames, iter)
|
||||
{
|
||||
const word& patchName = iter.key();
|
||||
const word& newName = iter();
|
||||
|
||||
Info<< "Looking for entry for patch " << patchName << endl;
|
||||
|
||||
// Find old patch name either direct or through wildcards
|
||||
// Find new patch name direct only
|
||||
|
||||
if
|
||||
(
|
||||
boundaryField.found(patchName)
|
||||
&& !boundaryField.found(newName, false, false)
|
||||
)
|
||||
{
|
||||
Info<< " Changing entry " << patchName << " to " << newName
|
||||
<< endl;
|
||||
|
||||
dictionary& patchDict = boundaryField.subDict(patchName);
|
||||
|
||||
if (patchDict.found("value"))
|
||||
{
|
||||
// Remove any value field since wrong size.
|
||||
patchDict.remove("value");
|
||||
}
|
||||
|
||||
|
||||
boundaryField.changeKeyword(patchName, newName);
|
||||
boundaryField.add
|
||||
(
|
||||
nbrNames[patchName],
|
||||
patchDict
|
||||
);
|
||||
Info<< " Adding entry " << nbrNames[patchName] << endl;
|
||||
|
||||
nChanged++;
|
||||
}
|
||||
}
|
||||
|
||||
//Info<< "New boundaryField:" << boundaryField << endl;
|
||||
|
||||
if (returnReduce(nChanged, sumOp<label>()) > 0)
|
||||
{
|
||||
if (isTestRun)
|
||||
{
|
||||
//Info<< "-test option: no changes made" << endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (mvBak(fieldDict.objectPath(), "old"))
|
||||
{
|
||||
Info<< "Backup to "
|
||||
<< (fieldDict.objectPath() + ".old") << nl;
|
||||
}
|
||||
|
||||
Info<< "Write to "
|
||||
<< fieldDict.objectPath() << endl;
|
||||
fieldDict.regIOobject::write();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Info<< "No changes made to field " << fieldName << endl;
|
||||
}
|
||||
Info<< endl;
|
||||
}
|
||||
|
||||
|
||||
void rewriteFields
|
||||
(
|
||||
const bool isTestRun,
|
||||
const Time& runTime,
|
||||
const wordList& fieldNames,
|
||||
const HashTable<word>& thisNames,
|
||||
const HashTable<word>& nbrNames
|
||||
)
|
||||
{
|
||||
forAll(fieldNames, i)
|
||||
{
|
||||
rewriteField
|
||||
(
|
||||
isTestRun,
|
||||
runTime,
|
||||
fieldNames[i],
|
||||
thisNames,
|
||||
nbrNames
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
timeSelector::addOptions();
|
||||
|
||||
argList::addBoolOption("test", "test only; do not change any files");
|
||||
argList::addBoolOption
|
||||
(
|
||||
"enableFunctionEntries",
|
||||
"enable expansion of dictionary directives - #include, #codeStream etc"
|
||||
);
|
||||
# include "addRegionOption.H"
|
||||
|
||||
# include "setRootCase.H"
|
||||
# include "createTime.H"
|
||||
|
||||
|
||||
// Make sure we do not use the master-only reading since we read
|
||||
// fields (different per processor) as dictionaries.
|
||||
regIOobject::fileModificationChecking = regIOobject::timeStamp;
|
||||
|
||||
|
||||
instantList timeDirs = timeSelector::select0(runTime, args);
|
||||
|
||||
const bool isTestRun = args.optionFound("test");
|
||||
if (isTestRun)
|
||||
{
|
||||
Info<< "-test option: no changes made" << nl << endl;
|
||||
}
|
||||
const bool enableEntries = args.optionFound("enableFunctionEntries");
|
||||
|
||||
|
||||
Foam::word regionName = polyMesh::defaultRegion;
|
||||
args.optionReadIfPresent("region", regionName);
|
||||
|
||||
fileName regionPrefix = "";
|
||||
if (regionName != polyMesh::defaultRegion)
|
||||
{
|
||||
regionPrefix = regionName;
|
||||
}
|
||||
|
||||
|
||||
// Per cyclic patch the new name for this side and the other side
|
||||
HashTable<word> thisNames;
|
||||
HashTable<word> nbrNames;
|
||||
|
||||
// Rewrite constant boundary file. Return any patches that have been split.
|
||||
IOobject io
|
||||
(
|
||||
"boundary",
|
||||
runTime.constant(),
|
||||
polyMesh::meshSubDir,
|
||||
runTime,
|
||||
IOobject::MUST_READ,
|
||||
IOobject::NO_WRITE,
|
||||
false
|
||||
);
|
||||
|
||||
if (io.headerOk())
|
||||
{
|
||||
rewriteBoundary
|
||||
(
|
||||
isTestRun,
|
||||
io,
|
||||
regionPrefix,
|
||||
thisNames,
|
||||
nbrNames
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Convert any fields
|
||||
|
||||
forAll(timeDirs, timeI)
|
||||
{
|
||||
runTime.setTime(timeDirs[timeI], timeI);
|
||||
|
||||
Info<< "Time: " << runTime.timeName() << endl;
|
||||
|
||||
// See if mesh in time directory
|
||||
IOobject io
|
||||
(
|
||||
"boundary",
|
||||
runTime.timeName(),
|
||||
polyMesh::meshSubDir,
|
||||
runTime,
|
||||
IOobject::MUST_READ,
|
||||
IOobject::NO_WRITE,
|
||||
false
|
||||
);
|
||||
|
||||
if (io.headerOk())
|
||||
{
|
||||
rewriteBoundary
|
||||
(
|
||||
isTestRun,
|
||||
io,
|
||||
regionPrefix,
|
||||
thisNames,
|
||||
nbrNames
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
IOobjectList objects(runTime, runTime.timeName());
|
||||
|
||||
|
||||
int oldFlag = entry::disableFunctionEntries;
|
||||
if (!enableEntries)
|
||||
{
|
||||
// By default disable dictionary expansion for fields
|
||||
entry::disableFunctionEntries = 1;
|
||||
}
|
||||
|
||||
// volFields
|
||||
// ~~~~~~~~~
|
||||
|
||||
rewriteFields
|
||||
(
|
||||
isTestRun,
|
||||
runTime,
|
||||
objects.names(volScalarField::typeName),
|
||||
thisNames,
|
||||
nbrNames
|
||||
);
|
||||
rewriteFields
|
||||
(
|
||||
isTestRun,
|
||||
runTime,
|
||||
objects.names(volVectorField::typeName),
|
||||
thisNames,
|
||||
nbrNames
|
||||
);
|
||||
rewriteFields
|
||||
(
|
||||
isTestRun,
|
||||
runTime,
|
||||
objects.names(volSphericalTensorField::typeName),
|
||||
thisNames,
|
||||
nbrNames
|
||||
);
|
||||
rewriteFields
|
||||
(
|
||||
isTestRun,
|
||||
runTime,
|
||||
objects.names(volSymmTensorField::typeName),
|
||||
thisNames,
|
||||
nbrNames
|
||||
);
|
||||
rewriteFields
|
||||
(
|
||||
isTestRun,
|
||||
runTime,
|
||||
objects.names(volTensorField::typeName),
|
||||
thisNames,
|
||||
nbrNames
|
||||
);
|
||||
|
||||
|
||||
// pointFields
|
||||
// ~~~~~~~~~~~
|
||||
|
||||
rewriteFields
|
||||
(
|
||||
isTestRun,
|
||||
runTime,
|
||||
objects.names(pointScalarField::typeName),
|
||||
thisNames,
|
||||
nbrNames
|
||||
);
|
||||
rewriteFields
|
||||
(
|
||||
isTestRun,
|
||||
runTime,
|
||||
objects.names(pointVectorField::typeName),
|
||||
thisNames,
|
||||
nbrNames
|
||||
);
|
||||
rewriteFields
|
||||
(
|
||||
isTestRun,
|
||||
runTime,
|
||||
objects.names(pointSphericalTensorField::typeName),
|
||||
thisNames,
|
||||
nbrNames
|
||||
);
|
||||
rewriteFields
|
||||
(
|
||||
isTestRun,
|
||||
runTime,
|
||||
objects.names(pointSymmTensorField::typeName),
|
||||
thisNames,
|
||||
nbrNames
|
||||
);
|
||||
rewriteFields
|
||||
(
|
||||
isTestRun,
|
||||
runTime,
|
||||
objects.names(pointTensorField::typeName),
|
||||
thisNames,
|
||||
nbrNames
|
||||
);
|
||||
|
||||
|
||||
// surfaceFields
|
||||
// ~~~~~~~~~~~
|
||||
|
||||
rewriteFields
|
||||
(
|
||||
isTestRun,
|
||||
runTime,
|
||||
objects.names(surfaceScalarField::typeName),
|
||||
thisNames,
|
||||
nbrNames
|
||||
);
|
||||
rewriteFields
|
||||
(
|
||||
isTestRun,
|
||||
runTime,
|
||||
objects.names(surfaceVectorField::typeName),
|
||||
thisNames,
|
||||
nbrNames
|
||||
);
|
||||
rewriteFields
|
||||
(
|
||||
isTestRun,
|
||||
runTime,
|
||||
objects.names(surfaceSphericalTensorField::typeName),
|
||||
thisNames,
|
||||
nbrNames
|
||||
);
|
||||
rewriteFields
|
||||
(
|
||||
isTestRun,
|
||||
runTime,
|
||||
objects.names(surfaceSymmTensorField::typeName),
|
||||
thisNames,
|
||||
nbrNames
|
||||
);
|
||||
rewriteFields
|
||||
(
|
||||
isTestRun,
|
||||
runTime,
|
||||
objects.names(surfaceTensorField::typeName),
|
||||
thisNames,
|
||||
nbrNames
|
||||
);
|
||||
|
||||
entry::disableFunctionEntries = oldFlag;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,3 @@
|
||||
foamUpgradeFvSolution.C
|
||||
|
||||
EXE = $(FOAM_APPBIN)/foamUpgradeFvSolution
|
||||
@ -0,0 +1,115 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / 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/>.
|
||||
|
||||
Application
|
||||
foamUpgradeFvSolution
|
||||
|
||||
Description
|
||||
Simple tool to upgrade the syntax of system/fvSolution.solvers.
|
||||
|
||||
Usage
|
||||
foamUpgradeFvSolution [OPTION]
|
||||
|
||||
\param -test \n
|
||||
Suppress writing the updated fvSolution file
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "argList.H"
|
||||
#include "Time.H"
|
||||
#include "IOdictionary.H"
|
||||
#include "solution.H"
|
||||
|
||||
using namespace Foam;
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
argList::addNote
|
||||
(
|
||||
"upgrade the syntax of system/fvSolution::solvers"
|
||||
);
|
||||
|
||||
argList::noParallel();
|
||||
argList::addBoolOption
|
||||
(
|
||||
"test",
|
||||
"suppress writing the updated system/fvSolution file"
|
||||
);
|
||||
|
||||
#include "setRootCase.H"
|
||||
#include "createTime.H"
|
||||
|
||||
IOdictionary solutionDict
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
"fvSolution",
|
||||
runTime.system(),
|
||||
runTime,
|
||||
IOobject::MUST_READ_IF_MODIFIED,
|
||||
IOobject::NO_WRITE,
|
||||
false
|
||||
)
|
||||
);
|
||||
|
||||
label nChanged = 0;
|
||||
entry* e = solutionDict.lookupEntryPtr("solvers", false, false);
|
||||
if (e && e->isDict())
|
||||
{
|
||||
nChanged = solution::upgradeSolverDict(e->dict(), true);
|
||||
}
|
||||
|
||||
Info<< nChanged << " solver settings changed" << nl << endl;
|
||||
if (nChanged)
|
||||
{
|
||||
if (args.optionFound("test"))
|
||||
{
|
||||
Info<< "-test option: no changes made" << nl << endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (mvBak(solutionDict.objectPath(), "old"))
|
||||
{
|
||||
Info<< "Backup to "
|
||||
<< (solutionDict.objectPath() + ".old") << nl;
|
||||
}
|
||||
|
||||
solutionDict.writeObject
|
||||
(
|
||||
IOstream::ASCII,
|
||||
IOstream::currentVersion,
|
||||
IOstream::UNCOMPRESSED
|
||||
);
|
||||
|
||||
Info<< "Write to "
|
||||
<< solutionDict.objectPath() << nl << endl;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,4 @@
|
||||
mapLagrangian.C
|
||||
mapFields.C
|
||||
|
||||
EXE = $(FOAM_APPBIN)/mapFields
|
||||
12
applications/utilities/preProcessing/mapFields/Make/options
Normal file
12
applications/utilities/preProcessing/mapFields/Make/options
Normal file
@ -0,0 +1,12 @@
|
||||
EXE_INC = \
|
||||
-I$(LIB_SRC)/meshTools/lnInclude \
|
||||
-I$(LIB_SRC)/lagrangian/basic/lnInclude \
|
||||
-I$(LIB_SRC)/finiteVolume/lnInclude \
|
||||
-I$(LIB_SRC)/sampling/lnInclude
|
||||
|
||||
EXE_LIBS = \
|
||||
-lsampling \
|
||||
-lmeshTools \
|
||||
-llagrangian \
|
||||
-lfiniteVolume \
|
||||
-lgenericPatchFields
|
||||
@ -0,0 +1,184 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2011-2014 OpenFOAM Foundation
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
|
||||
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
InNamespace
|
||||
Foam
|
||||
|
||||
Description
|
||||
Gets the indices of (source)particles that have been appended to the
|
||||
target cloud and maps the lagrangian fields accordingly.
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef MapLagrangianFields_H
|
||||
#define MapLagrangianFields_H
|
||||
|
||||
#include "cloud.H"
|
||||
#include "GeometricField.H"
|
||||
#include "meshToMesh.H"
|
||||
#include "IOobjectList.H"
|
||||
#include "CompactIOField.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
//- Gets the indices of (source)particles that have been appended to the
|
||||
// target cloud and maps the lagrangian fields accordingly.
|
||||
template<class Type>
|
||||
void MapLagrangianFields
|
||||
(
|
||||
const string& cloudName,
|
||||
const IOobjectList& objects,
|
||||
const polyMesh& meshTarget,
|
||||
const labelList& addParticles
|
||||
)
|
||||
{
|
||||
{
|
||||
IOobjectList fields = objects.lookupClass(IOField<Type>::typeName);
|
||||
|
||||
forAllIter(IOobjectList, fields, fieldIter)
|
||||
{
|
||||
const word& fieldName = fieldIter()->name();
|
||||
|
||||
Info<< " mapping lagrangian field " << fieldName << endl;
|
||||
|
||||
// Read field (does not need mesh)
|
||||
IOField<Type> fieldSource(*fieldIter());
|
||||
|
||||
// Map
|
||||
IOField<Type> fieldTarget
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
fieldName,
|
||||
meshTarget.time().timeName(),
|
||||
cloud::prefix/cloudName,
|
||||
meshTarget,
|
||||
IOobject::NO_READ,
|
||||
IOobject::NO_WRITE,
|
||||
false
|
||||
),
|
||||
addParticles.size()
|
||||
);
|
||||
|
||||
forAll(addParticles, i)
|
||||
{
|
||||
fieldTarget[i] = fieldSource[addParticles[i]];
|
||||
}
|
||||
|
||||
// Write field
|
||||
fieldTarget.write();
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
IOobjectList fieldFields =
|
||||
objects.lookupClass(IOField<Field<Type> >::typeName);
|
||||
|
||||
forAllIter(IOobjectList, fieldFields, fieldIter)
|
||||
{
|
||||
const word& fieldName = fieldIter()->name();
|
||||
|
||||
Info<< " mapping lagrangian fieldField " << fieldName << endl;
|
||||
|
||||
// Read field (does not need mesh)
|
||||
IOField<Field<Type> > fieldSource(*fieldIter());
|
||||
|
||||
// Map - use CompactIOField to automatically write in
|
||||
// compact form for binary format.
|
||||
CompactIOField<Field<Type>, Type> fieldTarget
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
fieldName,
|
||||
meshTarget.time().timeName(),
|
||||
cloud::prefix/cloudName,
|
||||
meshTarget,
|
||||
IOobject::NO_READ,
|
||||
IOobject::NO_WRITE,
|
||||
false
|
||||
),
|
||||
addParticles.size()
|
||||
);
|
||||
|
||||
forAll(addParticles, i)
|
||||
{
|
||||
fieldTarget[i] = fieldSource[addParticles[i]];
|
||||
}
|
||||
|
||||
// Write field
|
||||
fieldTarget.write();
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
IOobjectList fieldFields =
|
||||
objects.lookupClass(CompactIOField<Field<Type>, Type>::typeName);
|
||||
|
||||
forAllIter(IOobjectList, fieldFields, fieldIter)
|
||||
{
|
||||
Info<< " mapping lagrangian fieldField "
|
||||
<< fieldIter()->name() << endl;
|
||||
|
||||
// Read field (does not need mesh)
|
||||
CompactIOField<Field<Type>, Type> fieldSource(*fieldIter());
|
||||
|
||||
// Map
|
||||
CompactIOField<Field<Type>, Type> fieldTarget
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
fieldIter()->name(),
|
||||
meshTarget.time().timeName(),
|
||||
cloud::prefix/cloudName,
|
||||
meshTarget,
|
||||
IOobject::NO_READ,
|
||||
IOobject::NO_WRITE,
|
||||
false
|
||||
),
|
||||
addParticles.size()
|
||||
);
|
||||
|
||||
forAll(addParticles, i)
|
||||
{
|
||||
fieldTarget[i] = fieldSource[addParticles[i]];
|
||||
}
|
||||
|
||||
// Write field
|
||||
fieldTarget.write();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
||||
131
applications/utilities/preProcessing/mapFields/MapMeshes.H
Normal file
131
applications/utilities/preProcessing/mapFields/MapMeshes.H
Normal file
@ -0,0 +1,131 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2011-2014 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/>.
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef MapMeshes_H
|
||||
#define MapMeshes_H
|
||||
|
||||
#include "MapVolFields.H"
|
||||
#include "mapLagrangian.H"
|
||||
#include "UnMapped.H"
|
||||
#include "pointMesh.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
template<template<class> class CombineOp>
|
||||
void MapMesh
|
||||
(
|
||||
const meshToMesh& interp,
|
||||
const HashSet<word>& selectedFields,
|
||||
const bool noLagrangian
|
||||
)
|
||||
{
|
||||
{
|
||||
const polyMesh& meshSource = interp.srcRegion();
|
||||
|
||||
// Search for list of objects for this time
|
||||
IOobjectList objects(meshSource, meshSource.time().timeName());
|
||||
|
||||
// Map volFields
|
||||
// ~~~~~~~~~~~~~
|
||||
MapVolFields<scalar>
|
||||
(
|
||||
objects,
|
||||
selectedFields,
|
||||
interp,
|
||||
CombineOp<scalar>()
|
||||
);
|
||||
|
||||
MapVolFields<vector>
|
||||
(
|
||||
objects,
|
||||
selectedFields,
|
||||
interp,
|
||||
CombineOp<vector>()
|
||||
);
|
||||
MapVolFields<sphericalTensor>
|
||||
(
|
||||
objects,
|
||||
selectedFields,
|
||||
interp,
|
||||
CombineOp<sphericalTensor>()
|
||||
);
|
||||
MapVolFields<symmTensor>
|
||||
(
|
||||
objects,
|
||||
selectedFields,
|
||||
interp,
|
||||
CombineOp<symmTensor>()
|
||||
);
|
||||
MapVolFields<tensor>
|
||||
(
|
||||
objects,
|
||||
selectedFields,
|
||||
interp,
|
||||
CombineOp<tensor>()
|
||||
);
|
||||
}
|
||||
|
||||
{
|
||||
const polyMesh& meshTarget = interp.tgtRegion();
|
||||
|
||||
// Search for list of target objects for this time
|
||||
IOobjectList objects(meshTarget, meshTarget.time().timeName());
|
||||
|
||||
// Mark surfaceFields as unmapped
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
UnMapped<surfaceScalarField>(objects);
|
||||
UnMapped<surfaceVectorField>(objects);
|
||||
UnMapped<surfaceSphericalTensorField>(objects);
|
||||
UnMapped<surfaceSymmTensorField>(objects);
|
||||
UnMapped<surfaceTensorField>(objects);
|
||||
|
||||
// Mark pointFields as unmapped
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
UnMapped<pointScalarField>(objects);
|
||||
UnMapped<pointVectorField>(objects);
|
||||
UnMapped<pointSphericalTensorField>(objects);
|
||||
UnMapped<pointSymmTensorField>(objects);
|
||||
UnMapped<pointTensorField>(objects);
|
||||
}
|
||||
|
||||
if (!noLagrangian)
|
||||
{
|
||||
mapLagrangian(interp);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
||||
104
applications/utilities/preProcessing/mapFields/MapVolFields.H
Normal file
104
applications/utilities/preProcessing/mapFields/MapVolFields.H
Normal file
@ -0,0 +1,104 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2011-2014 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/>.
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef MapConsistentVolFields_H
|
||||
#define MapConsistentVolFields_H
|
||||
|
||||
#include "GeometricField.H"
|
||||
#include "meshToMesh.H"
|
||||
#include "IOobjectList.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
template<class Type, class CombineOp>
|
||||
void MapVolFields
|
||||
(
|
||||
const IOobjectList& objects,
|
||||
const HashSet<word>& selectedFields,
|
||||
const meshToMesh& interp,
|
||||
const CombineOp& cop
|
||||
)
|
||||
{
|
||||
typedef GeometricField<Type, fvPatchField, volMesh> fieldType;
|
||||
|
||||
const fvMesh& meshSource = static_cast<const fvMesh&>(interp.srcRegion());
|
||||
const fvMesh& meshTarget = static_cast<const fvMesh&>(interp.tgtRegion());
|
||||
|
||||
IOobjectList fields = objects.lookupClass(fieldType::typeName);
|
||||
|
||||
forAllIter(IOobjectList, fields, fieldIter)
|
||||
{
|
||||
const word& fieldName = fieldIter()->name();
|
||||
|
||||
if (selectedFields.empty() || selectedFields.found(fieldName))
|
||||
{
|
||||
Info<< " interpolating " << fieldName << endl;
|
||||
|
||||
const fieldType fieldSource(*fieldIter(), meshSource);
|
||||
|
||||
IOobject targetIO
|
||||
(
|
||||
fieldName,
|
||||
meshTarget.time().timeName(),
|
||||
meshTarget,
|
||||
IOobject::MUST_READ
|
||||
);
|
||||
|
||||
if (targetIO.headerOk())
|
||||
{
|
||||
fieldType fieldTarget(targetIO, meshTarget);
|
||||
|
||||
interp.mapSrcToTgt(fieldSource, cop, fieldTarget);
|
||||
|
||||
fieldTarget.write();
|
||||
}
|
||||
else
|
||||
{
|
||||
targetIO.readOpt() = IOobject::NO_READ;
|
||||
|
||||
tmp<fieldType>
|
||||
tfieldTarget(interp.mapSrcToTgt(fieldSource, cop));
|
||||
|
||||
fieldType fieldTarget(targetIO, tfieldTarget);
|
||||
|
||||
fieldTarget.write();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
||||
57
applications/utilities/preProcessing/mapFields/UnMapped.H
Normal file
57
applications/utilities/preProcessing/mapFields/UnMapped.H
Normal file
@ -0,0 +1,57 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2011-2014 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/>.
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef UnMapped_H
|
||||
#define UnMapped_H
|
||||
|
||||
#include "IOobjectList.H"
|
||||
#include "OSspecific.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
template<class Type>
|
||||
void UnMapped(const IOobjectList& objects)
|
||||
{
|
||||
IOobjectList fields = objects.lookupClass(Type::typeName);
|
||||
|
||||
forAllConstIter(IOobjectList, fields, fieldIter)
|
||||
{
|
||||
mvBak(fieldIter()->objectPath(), "unmapped");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
||||
11
applications/utilities/preProcessing/mapFields/createTimes.H
Normal file
11
applications/utilities/preProcessing/mapFields/createTimes.H
Normal file
@ -0,0 +1,11 @@
|
||||
Info<< "\nCreate databases as time" << endl;
|
||||
|
||||
HashTable<string> srcOptions(args.options());
|
||||
srcOptions.erase("case");
|
||||
srcOptions.insert("case", fileName(rootDirSource/caseDirSource));
|
||||
|
||||
argList argsSrc(args, srcOptions, false, false, false);
|
||||
|
||||
Time runTimeSource(Time::controlDictName, argsSrc);
|
||||
|
||||
Time runTimeTarget(Time::controlDictName, args);
|
||||
387
applications/utilities/preProcessing/mapFields/mapFields.C
Normal file
387
applications/utilities/preProcessing/mapFields/mapFields.C
Normal file
@ -0,0 +1,387 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2011-2014 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
|
||||
mapFields
|
||||
|
||||
Description
|
||||
Maps volume fields from one mesh to another, reading and
|
||||
interpolating all fields present in the time directory of both cases.
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "fvCFD.H"
|
||||
#include "meshToMesh.H"
|
||||
#include "processorPolyPatch.H"
|
||||
#include "MapMeshes.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
void mapConsistentMesh
|
||||
(
|
||||
const fvMesh& meshSource,
|
||||
const fvMesh& meshTarget,
|
||||
const word& mapMethod,
|
||||
const word& AMIMapMethod,
|
||||
const bool subtract,
|
||||
const HashSet<word>& selectedFields,
|
||||
const bool noLagrangian
|
||||
)
|
||||
{
|
||||
Info<< nl << "Consistently creating and mapping fields for time "
|
||||
<< meshSource.time().timeName() << nl << endl;
|
||||
|
||||
meshToMesh interp(meshSource, meshTarget, mapMethod, AMIMapMethod);
|
||||
|
||||
if (subtract)
|
||||
{
|
||||
MapMesh<minusEqOp>
|
||||
(
|
||||
interp,
|
||||
selectedFields,
|
||||
noLagrangian
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
MapMesh<plusEqOp>
|
||||
(
|
||||
interp,
|
||||
selectedFields,
|
||||
noLagrangian
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void mapSubMesh
|
||||
(
|
||||
const fvMesh& meshSource,
|
||||
const fvMesh& meshTarget,
|
||||
const HashTable<word>& patchMap,
|
||||
const wordList& cuttingPatches,
|
||||
const word& mapMethod,
|
||||
const word& AMIMapMethod,
|
||||
const bool subtract,
|
||||
const HashSet<word>& selectedFields,
|
||||
const bool noLagrangian
|
||||
)
|
||||
{
|
||||
Info<< nl << "Creating and mapping fields for time "
|
||||
<< meshSource.time().timeName() << nl << endl;
|
||||
|
||||
meshToMesh interp
|
||||
(
|
||||
meshSource,
|
||||
meshTarget,
|
||||
mapMethod,
|
||||
AMIMapMethod,
|
||||
patchMap,
|
||||
cuttingPatches
|
||||
);
|
||||
|
||||
if (subtract)
|
||||
{
|
||||
MapMesh<minusEqOp>
|
||||
(
|
||||
interp,
|
||||
selectedFields,
|
||||
noLagrangian
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
MapMesh<plusEqOp>
|
||||
(
|
||||
interp,
|
||||
selectedFields,
|
||||
noLagrangian
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
wordList addProcessorPatches
|
||||
(
|
||||
const fvMesh& meshTarget,
|
||||
const wordList& cuttingPatches
|
||||
)
|
||||
{
|
||||
// Add the processor patches to the cutting list
|
||||
HashSet<word> cuttingPatchTable;
|
||||
forAll(cuttingPatches, i)
|
||||
{
|
||||
cuttingPatchTable.insert(cuttingPatches[i]);
|
||||
}
|
||||
|
||||
const polyBoundaryMesh& pbm = meshTarget.boundaryMesh();
|
||||
|
||||
forAll(pbm, patchI)
|
||||
{
|
||||
if (isA<processorPolyPatch>(pbm[patchI]))
|
||||
{
|
||||
const word& patchName = pbm[patchI].name();
|
||||
cuttingPatchTable.insert(patchName);
|
||||
}
|
||||
}
|
||||
|
||||
return cuttingPatchTable.toc();
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
argList::addNote
|
||||
(
|
||||
"map volume fields from one mesh to another"
|
||||
);
|
||||
|
||||
argList::validArgs.append("sourceCase");
|
||||
|
||||
argList::addOption
|
||||
(
|
||||
"sourceTime",
|
||||
"scalar|'latestTime'",
|
||||
"specify the source time"
|
||||
);
|
||||
argList::addOption
|
||||
(
|
||||
"sourceRegion",
|
||||
"word",
|
||||
"specify the source region"
|
||||
);
|
||||
argList::addOption
|
||||
(
|
||||
"targetRegion",
|
||||
"word",
|
||||
"specify the target region"
|
||||
);
|
||||
argList::addBoolOption
|
||||
(
|
||||
"consistent",
|
||||
"source and target geometry and boundary conditions identical"
|
||||
);
|
||||
argList::addOption
|
||||
(
|
||||
"mapMethod",
|
||||
"word",
|
||||
"specify the mapping method (direct|mapNearest|cellVolumeWeight)"
|
||||
);
|
||||
argList::addOption
|
||||
(
|
||||
"patchMapMethod",
|
||||
"word",
|
||||
"specify the patch mapping method (direct|mapNearest|faceAreaWeight)"
|
||||
);
|
||||
argList::addBoolOption
|
||||
(
|
||||
"subtract",
|
||||
"subtract mapped source from target"
|
||||
);
|
||||
argList::addOption
|
||||
(
|
||||
"fields",
|
||||
"list",
|
||||
"specify a list of fields to be mapped. Eg, '(U T p)' - "
|
||||
"regular expressions not currently supported"
|
||||
);
|
||||
argList::addBoolOption
|
||||
(
|
||||
"noLagrangian",
|
||||
"skip mapping lagrangian positions and fields"
|
||||
);
|
||||
|
||||
argList args(argc, argv);
|
||||
|
||||
fileName rootDirTarget(args.rootPath());
|
||||
fileName caseDirTarget(args.globalCaseName());
|
||||
|
||||
const fileName casePath = args[1];
|
||||
const fileName rootDirSource = casePath.path();
|
||||
const fileName caseDirSource = casePath.name();
|
||||
|
||||
Info<< "Source: " << rootDirSource << " " << caseDirSource << endl;
|
||||
word sourceRegion = fvMesh::defaultRegion;
|
||||
if (args.optionFound("sourceRegion"))
|
||||
{
|
||||
sourceRegion = args["sourceRegion"];
|
||||
Info<< "Source region: " << sourceRegion << endl;
|
||||
}
|
||||
|
||||
Info<< "Target: " << rootDirTarget << " " << caseDirTarget << endl;
|
||||
word targetRegion = fvMesh::defaultRegion;
|
||||
if (args.optionFound("targetRegion"))
|
||||
{
|
||||
targetRegion = args["targetRegion"];
|
||||
Info<< "Target region: " << targetRegion << endl;
|
||||
}
|
||||
|
||||
const bool consistent = args.optionFound("consistent");
|
||||
|
||||
|
||||
word mapMethod = meshToMesh::interpolationMethodNames_
|
||||
[
|
||||
meshToMesh::imCellVolumeWeight
|
||||
];
|
||||
|
||||
if (args.optionReadIfPresent("mapMethod", mapMethod))
|
||||
{
|
||||
Info<< "Mapping method: " << mapMethod << endl;
|
||||
}
|
||||
|
||||
|
||||
word patchMapMethod;
|
||||
if (meshToMesh::interpolationMethodNames_.found(mapMethod))
|
||||
{
|
||||
// Lookup corresponding AMI method
|
||||
meshToMesh::interpolationMethod method =
|
||||
meshToMesh::interpolationMethodNames_[mapMethod];
|
||||
|
||||
patchMapMethod = AMIPatchToPatchInterpolation::interpolationMethodToWord
|
||||
(
|
||||
meshToMesh::interpolationMethodAMI(method)
|
||||
);
|
||||
}
|
||||
|
||||
// Optionally override
|
||||
if (args.optionFound("patchMapMethod"))
|
||||
{
|
||||
patchMapMethod = args["patchMapMethod"];
|
||||
|
||||
Info<< "Patch mapping method: " << patchMapMethod << endl;
|
||||
}
|
||||
|
||||
|
||||
if (patchMapMethod.empty())
|
||||
{
|
||||
FatalErrorIn(args.executable())
|
||||
<< "No valid patchMapMethod for method " << mapMethod
|
||||
<< ". Please supply one through the 'patchMapMethod' option"
|
||||
<< exit(FatalError);
|
||||
}
|
||||
|
||||
|
||||
|
||||
const bool subtract = args.optionFound("subtract");
|
||||
if (subtract)
|
||||
{
|
||||
Info<< "Subtracting mapped source field from target" << endl;
|
||||
}
|
||||
|
||||
HashSet<word> selectedFields;
|
||||
if (args.optionFound("fields"))
|
||||
{
|
||||
args.optionLookup("fields")() >> selectedFields;
|
||||
}
|
||||
|
||||
const bool noLagrangian = args.optionFound("noLagrangian");
|
||||
|
||||
#include "createTimes.H"
|
||||
|
||||
HashTable<word> patchMap;
|
||||
wordList cuttingPatches;
|
||||
|
||||
if (!consistent)
|
||||
{
|
||||
IOdictionary mapFieldsDict
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
"mapFieldsDict",
|
||||
runTimeTarget.system(),
|
||||
runTimeTarget,
|
||||
IOobject::MUST_READ_IF_MODIFIED,
|
||||
IOobject::NO_WRITE,
|
||||
false
|
||||
)
|
||||
);
|
||||
|
||||
mapFieldsDict.lookup("patchMap") >> patchMap;
|
||||
mapFieldsDict.lookup("cuttingPatches") >> cuttingPatches;
|
||||
}
|
||||
|
||||
#include "setTimeIndex.H"
|
||||
|
||||
Info<< "\nCreate meshes\n" << endl;
|
||||
|
||||
fvMesh meshSource
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
sourceRegion,
|
||||
runTimeSource.timeName(),
|
||||
runTimeSource
|
||||
)
|
||||
);
|
||||
|
||||
fvMesh meshTarget
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
targetRegion,
|
||||
runTimeTarget.timeName(),
|
||||
runTimeTarget
|
||||
)
|
||||
);
|
||||
|
||||
Info<< "Source mesh size: " << meshSource.nCells() << tab
|
||||
<< "Target mesh size: " << meshTarget.nCells() << nl << endl;
|
||||
|
||||
if (consistent)
|
||||
{
|
||||
mapConsistentMesh
|
||||
(
|
||||
meshSource,
|
||||
meshTarget,
|
||||
mapMethod,
|
||||
patchMapMethod,
|
||||
subtract,
|
||||
selectedFields,
|
||||
noLagrangian
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
mapSubMesh
|
||||
(
|
||||
meshSource,
|
||||
meshTarget,
|
||||
patchMap,
|
||||
addProcessorPatches(meshTarget, cuttingPatches),
|
||||
mapMethod,
|
||||
patchMapMethod,
|
||||
subtract,
|
||||
selectedFields,
|
||||
noLagrangian
|
||||
);
|
||||
}
|
||||
|
||||
Info<< "\nEnd\n" << endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
36
applications/utilities/preProcessing/mapFields/mapFieldsDict
Normal file
36
applications/utilities/preProcessing/mapFields/mapFieldsDict
Normal file
@ -0,0 +1,36 @@
|
||||
/*--------------------------------*- 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;
|
||||
object mapFieldsDict;
|
||||
}
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
// Specify how to map patches. There are three different options:
|
||||
// - patch exists in the source case: specify mapping (patchMap)
|
||||
// - patch should be interpolated from internal values in source case
|
||||
// (cuttingPatches)
|
||||
// - patch should not be mapped. Default if not in patchMap or cuttingPatches
|
||||
|
||||
// List of pairs of target/source patches for mapping
|
||||
patchMap
|
||||
(
|
||||
lid movingWall
|
||||
);
|
||||
|
||||
// List of target patches cutting the source domain (these need to be
|
||||
// handled specially e.g. interpolated from internal values)
|
||||
cuttingPatches
|
||||
(
|
||||
fixedWalls
|
||||
);
|
||||
|
||||
// ************************************************************************* //
|
||||
303
applications/utilities/preProcessing/mapFields/mapLagrangian.C
Normal file
303
applications/utilities/preProcessing/mapFields/mapLagrangian.C
Normal file
@ -0,0 +1,303 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2011-2014 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 "MapLagrangianFields.H"
|
||||
#include "passiveParticleCloud.H"
|
||||
#include "meshSearch.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
static const scalar perturbFactor = 1e-6;
|
||||
|
||||
|
||||
// Special version of findCell that generates a cell guaranteed to be
|
||||
// compatible with tracking.
|
||||
static label findCell(const Cloud<passiveParticle>& cloud, const point& pt)
|
||||
{
|
||||
label cellI = -1;
|
||||
label tetFaceI = -1;
|
||||
label tetPtI = -1;
|
||||
|
||||
const polyMesh& mesh = cloud.pMesh();
|
||||
|
||||
mesh.findCellFacePt(pt, cellI, tetFaceI, tetPtI);
|
||||
|
||||
if (cellI >= 0)
|
||||
{
|
||||
return cellI;
|
||||
}
|
||||
else
|
||||
{
|
||||
// See if particle on face by finding nearest face and shifting
|
||||
// particle.
|
||||
|
||||
meshSearch meshSearcher
|
||||
(
|
||||
mesh,
|
||||
polyMesh::FACEPLANES // no decomposition needed
|
||||
);
|
||||
|
||||
label faceI = meshSearcher.findNearestBoundaryFace(pt);
|
||||
|
||||
if (faceI >= 0)
|
||||
{
|
||||
const point& cc = mesh.cellCentres()[mesh.faceOwner()[faceI]];
|
||||
|
||||
const point perturbPt = (1-perturbFactor)*pt+perturbFactor*cc;
|
||||
|
||||
mesh.findCellFacePt(perturbPt, cellI, tetFaceI, tetPtI);
|
||||
|
||||
return cellI;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
void mapLagrangian(const meshToMesh& interp)
|
||||
{
|
||||
// Determine which particles are in meshTarget
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
const polyMesh& meshSource = interp.srcRegion();
|
||||
const polyMesh& meshTarget = interp.tgtRegion();
|
||||
const labelListList& sourceToTarget = interp.srcToTgtCellAddr();
|
||||
|
||||
const pointField& targetCc = meshTarget.cellCentres();
|
||||
|
||||
fileNameList cloudDirs
|
||||
(
|
||||
readDir
|
||||
(
|
||||
meshSource.time().timePath()/cloud::prefix,
|
||||
fileName::DIRECTORY
|
||||
)
|
||||
);
|
||||
|
||||
forAll(cloudDirs, cloudI)
|
||||
{
|
||||
// Search for list of lagrangian objects for this time
|
||||
IOobjectList objects
|
||||
(
|
||||
meshSource,
|
||||
meshSource.time().timeName(),
|
||||
cloud::prefix/cloudDirs[cloudI]
|
||||
);
|
||||
|
||||
IOobject* positionsPtr = objects.lookup(word("positions"));
|
||||
|
||||
if (positionsPtr)
|
||||
{
|
||||
Info<< nl << " processing cloud " << cloudDirs[cloudI] << endl;
|
||||
|
||||
// Read positions & cell
|
||||
passiveParticleCloud sourceParcels
|
||||
(
|
||||
meshSource,
|
||||
cloudDirs[cloudI],
|
||||
false
|
||||
);
|
||||
Info<< " read " << sourceParcels.size()
|
||||
<< " parcels from source mesh." << endl;
|
||||
|
||||
// Construct empty target cloud
|
||||
passiveParticleCloud targetParcels
|
||||
(
|
||||
meshTarget,
|
||||
cloudDirs[cloudI],
|
||||
IDLList<passiveParticle>()
|
||||
);
|
||||
|
||||
particle::TrackingData<passiveParticleCloud> td(targetParcels);
|
||||
|
||||
label sourceParticleI = 0;
|
||||
|
||||
// Indices of source particles that get added to targetParcels
|
||||
DynamicList<label> addParticles(sourceParcels.size());
|
||||
|
||||
// Unmapped particles
|
||||
labelHashSet unmappedSource(sourceParcels.size());
|
||||
|
||||
|
||||
// Initial: track from fine-mesh cell centre to particle position
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// This requires there to be no boundary in the way.
|
||||
|
||||
|
||||
forAllConstIter(Cloud<passiveParticle>, sourceParcels, iter)
|
||||
{
|
||||
bool foundCell = false;
|
||||
|
||||
// Assume that cell from read parcel is the correct one...
|
||||
if (iter().cell() >= 0)
|
||||
{
|
||||
const labelList& targetCells =
|
||||
sourceToTarget[iter().cell()];
|
||||
|
||||
// Particle probably in one of the targetcells. Try
|
||||
// all by tracking from their cell centre to the parcel
|
||||
// position.
|
||||
|
||||
forAll(targetCells, i)
|
||||
{
|
||||
// Track from its cellcentre to position to make sure.
|
||||
autoPtr<passiveParticle> newPtr
|
||||
(
|
||||
new passiveParticle
|
||||
(
|
||||
meshTarget,
|
||||
targetCc[targetCells[i]],
|
||||
targetCells[i]
|
||||
)
|
||||
);
|
||||
passiveParticle& newP = newPtr();
|
||||
|
||||
label faceI = newP.track(iter().position(), td);
|
||||
|
||||
if (faceI < 0 && newP.cell() >= 0)
|
||||
{
|
||||
// Hit position.
|
||||
foundCell = true;
|
||||
addParticles.append(sourceParticleI);
|
||||
targetParcels.addParticle(newPtr.ptr());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!foundCell)
|
||||
{
|
||||
// Store for closer analysis
|
||||
unmappedSource.insert(sourceParticleI);
|
||||
}
|
||||
|
||||
sourceParticleI++;
|
||||
}
|
||||
|
||||
Info<< " after meshToMesh addressing found "
|
||||
<< targetParcels.size()
|
||||
<< " parcels in target mesh." << endl;
|
||||
|
||||
|
||||
// Do closer inspection for unmapped particles
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
if (unmappedSource.size())
|
||||
{
|
||||
sourceParticleI = 0;
|
||||
|
||||
forAllIter(Cloud<passiveParticle>, sourceParcels, iter)
|
||||
{
|
||||
if (unmappedSource.found(sourceParticleI))
|
||||
{
|
||||
label targetCell =
|
||||
findCell(targetParcels, iter().position());
|
||||
|
||||
if (targetCell >= 0)
|
||||
{
|
||||
unmappedSource.erase(sourceParticleI);
|
||||
addParticles.append(sourceParticleI);
|
||||
iter().cell() = targetCell;
|
||||
targetParcels.addParticle
|
||||
(
|
||||
sourceParcels.remove(&iter())
|
||||
);
|
||||
}
|
||||
}
|
||||
sourceParticleI++;
|
||||
}
|
||||
}
|
||||
addParticles.shrink();
|
||||
|
||||
Info<< " after additional mesh searching found "
|
||||
<< targetParcels.size() << " parcels in target mesh." << endl;
|
||||
|
||||
if (addParticles.size())
|
||||
{
|
||||
IOPosition<passiveParticleCloud>(targetParcels).write();
|
||||
|
||||
// addParticles now contains the indices of the sourceMesh
|
||||
// particles that were appended to the target mesh.
|
||||
|
||||
// Map lagrangian fields
|
||||
// ~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
MapLagrangianFields<label>
|
||||
(
|
||||
cloudDirs[cloudI],
|
||||
objects,
|
||||
meshTarget,
|
||||
addParticles
|
||||
);
|
||||
MapLagrangianFields<scalar>
|
||||
(
|
||||
cloudDirs[cloudI],
|
||||
objects,
|
||||
meshTarget,
|
||||
addParticles
|
||||
);
|
||||
MapLagrangianFields<vector>
|
||||
(
|
||||
cloudDirs[cloudI],
|
||||
objects,
|
||||
meshTarget,
|
||||
addParticles
|
||||
);
|
||||
MapLagrangianFields<sphericalTensor>
|
||||
(
|
||||
cloudDirs[cloudI],
|
||||
objects,
|
||||
meshTarget,
|
||||
addParticles
|
||||
);
|
||||
MapLagrangianFields<symmTensor>
|
||||
(
|
||||
cloudDirs[cloudI],
|
||||
objects,
|
||||
meshTarget,
|
||||
addParticles
|
||||
);
|
||||
MapLagrangianFields<tensor>
|
||||
(
|
||||
cloudDirs[cloudI],
|
||||
objects,
|
||||
meshTarget,
|
||||
addParticles
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,56 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2011-2014 OpenFOAM Foundation
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
|
||||
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
InNamespace
|
||||
Foam
|
||||
|
||||
Description
|
||||
Maps lagrangian positions and fields
|
||||
|
||||
SourceFiles
|
||||
mapLagrangian.C
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef mapLagrangian_H
|
||||
#define mapLagrangian_H
|
||||
|
||||
#include "meshToMesh.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
//- Maps lagrangian positions and fields
|
||||
void mapLagrangian(const meshToMesh& interp);
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,33 @@
|
||||
{
|
||||
instantList sourceTimes = runTimeSource.times();
|
||||
label sourceTimeIndex = runTimeSource.timeIndex();
|
||||
if (args.optionFound("sourceTime"))
|
||||
{
|
||||
if (args["sourceTime"] == "latestTime")
|
||||
{
|
||||
sourceTimeIndex = sourceTimes.size() - 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
sourceTimeIndex = Time::findClosestTimeIndex
|
||||
(
|
||||
sourceTimes,
|
||||
args.optionRead<scalar>("sourceTime")
|
||||
);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
sourceTimeIndex = Time::findClosestTimeIndex
|
||||
(
|
||||
sourceTimes,
|
||||
runTimeTarget.time().value()
|
||||
);
|
||||
}
|
||||
|
||||
runTimeSource.setTime(sourceTimes[sourceTimeIndex], sourceTimeIndex);
|
||||
|
||||
Info<< "\nSource time: " << runTimeSource.value()
|
||||
<< "\nTarget time: " << runTimeTarget.value()
|
||||
<< endl;
|
||||
}
|
||||
@ -0,0 +1,3 @@
|
||||
mdInitialise.C
|
||||
|
||||
EXE = $(FOAM_APPBIN)/mdInitialise
|
||||
@ -0,0 +1,18 @@
|
||||
EXE_INC = \
|
||||
-I$(LIB_SRC)/meshTools/lnInclude \
|
||||
-I$(LIB_SRC)/dynamicMesh/lnInclude \
|
||||
-I$(LIB_SRC)/lagrangian/molecularDynamics/molecule/lnInclude \
|
||||
-I$(LIB_SRC)/lagrangian/molecularDynamics/potential/lnInclude \
|
||||
-I$(LIB_SRC)/lagrangian/molecularDynamics/molecularMeasurements/lnInclude \
|
||||
-I$(LIB_SRC)/lagrangian/basic/lnInclude \
|
||||
-I$(LIB_SRC)/finiteVolume/lnInclude
|
||||
|
||||
EXE_LIBS = \
|
||||
-lmeshTools \
|
||||
-ldynamicMesh \
|
||||
-lfiniteVolume \
|
||||
-llagrangian \
|
||||
-lmolecule \
|
||||
-lpotential \
|
||||
-lmolecularMeasurements
|
||||
|
||||
@ -0,0 +1,97 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2011 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/>.
|
||||
|
||||
Description
|
||||
Initialises fields for a molecular dynamics (MD) simulation.
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "md.H"
|
||||
#include "fvCFD.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
# include "setRootCase.H"
|
||||
# include "createTime.H"
|
||||
# include "createMesh.H"
|
||||
|
||||
IOdictionary mdInitialiseDict
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
"mdInitialiseDict",
|
||||
runTime.system(),
|
||||
runTime,
|
||||
IOobject::MUST_READ_IF_MODIFIED,
|
||||
IOobject::NO_WRITE,
|
||||
false
|
||||
)
|
||||
);
|
||||
|
||||
IOdictionary idListDict
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
"idList",
|
||||
mesh.time().constant(),
|
||||
mesh,
|
||||
IOobject::NO_READ,
|
||||
IOobject::AUTO_WRITE
|
||||
)
|
||||
);
|
||||
|
||||
potential pot(mesh, mdInitialiseDict, idListDict);
|
||||
|
||||
moleculeCloud molecules(mesh, pot, mdInitialiseDict);
|
||||
|
||||
label totalMolecules = molecules.size();
|
||||
|
||||
if (Pstream::parRun())
|
||||
{
|
||||
reduce(totalMolecules, sumOp<label>());
|
||||
}
|
||||
|
||||
Info<< nl << "Total number of molecules added: " << totalMolecules
|
||||
<< nl << endl;
|
||||
|
||||
IOstream::defaultPrecision(15);
|
||||
|
||||
if (!mesh.write())
|
||||
{
|
||||
FatalErrorIn(args.executable())
|
||||
<< "Failed writing moleculeCloud."
|
||||
<< nl << exit(FatalError);
|
||||
}
|
||||
|
||||
Info<< nl << "ClockTime = " << runTime.elapsedClockTime() << " s"
|
||||
<< nl << endl;
|
||||
|
||||
Info<< "\nEnd\n" << endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,3 @@
|
||||
setFields.C
|
||||
|
||||
EXE = $(FOAM_APPBIN)/setFields
|
||||
@ -0,0 +1,8 @@
|
||||
EXE_INC = \
|
||||
-I$(LIB_SRC)/finiteVolume/lnInclude \
|
||||
-I$(LIB_SRC)/meshTools/lnInclude
|
||||
|
||||
EXE_LIBS = \
|
||||
-lfiniteVolume \
|
||||
-lgenericPatchFields \
|
||||
-lmeshTools
|
||||
485
applications/utilities/preProcessing/setFields/setFields.C
Normal file
485
applications/utilities/preProcessing/setFields/setFields.C
Normal file
@ -0,0 +1,485 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / 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/>.
|
||||
|
||||
Description
|
||||
Set values on a selected set of cells/patchfaces through a dictionary.
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "argList.H"
|
||||
#include "Time.H"
|
||||
#include "fvMesh.H"
|
||||
#include "topoSetSource.H"
|
||||
#include "cellSet.H"
|
||||
#include "faceSet.H"
|
||||
#include "volFields.H"
|
||||
|
||||
using namespace Foam;
|
||||
|
||||
template<class Type>
|
||||
bool setCellFieldType
|
||||
(
|
||||
const word& fieldTypeDesc,
|
||||
const fvMesh& mesh,
|
||||
const labelList& selectedCells,
|
||||
Istream& fieldValueStream
|
||||
)
|
||||
{
|
||||
typedef GeometricField<Type, fvPatchField, volMesh> fieldType;
|
||||
|
||||
if (fieldTypeDesc != fieldType::typeName + "Value")
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
word fieldName(fieldValueStream);
|
||||
|
||||
// Check the current time directory
|
||||
IOobject fieldHeader
|
||||
(
|
||||
fieldName,
|
||||
mesh.time().timeName(),
|
||||
mesh,
|
||||
IOobject::MUST_READ
|
||||
);
|
||||
|
||||
// Check the "constant" directory
|
||||
if (!fieldHeader.headerOk())
|
||||
{
|
||||
fieldHeader = IOobject
|
||||
(
|
||||
fieldName,
|
||||
mesh.time().constant(),
|
||||
mesh,
|
||||
IOobject::MUST_READ
|
||||
);
|
||||
}
|
||||
|
||||
// Check field exists
|
||||
if (fieldHeader.headerOk())
|
||||
{
|
||||
Info<< " Setting internal values of "
|
||||
<< fieldHeader.headerClassName()
|
||||
<< " " << fieldName << endl;
|
||||
|
||||
fieldType field(fieldHeader, mesh);
|
||||
|
||||
const Type& value = pTraits<Type>(fieldValueStream);
|
||||
|
||||
if (selectedCells.size() == field.size())
|
||||
{
|
||||
field.internalField() = value;
|
||||
}
|
||||
else
|
||||
{
|
||||
forAll(selectedCells, celli)
|
||||
{
|
||||
field[selectedCells[celli]] = value;
|
||||
}
|
||||
}
|
||||
|
||||
forAll(field.boundaryField(), patchi)
|
||||
{
|
||||
field.boundaryField()[patchi] =
|
||||
field.boundaryField()[patchi].patchInternalField();
|
||||
}
|
||||
|
||||
if (!field.write())
|
||||
{
|
||||
FatalErrorIn
|
||||
(
|
||||
"void setCellFieldType"
|
||||
"(const fvMesh& mesh, const labelList& selectedCells,"
|
||||
"Istream& fieldValueStream)"
|
||||
) << "Failed writing field " << fieldName << endl;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
WarningIn
|
||||
(
|
||||
"void setCellFieldType"
|
||||
"(const fvMesh& mesh, const labelList& selectedCells,"
|
||||
"Istream& fieldValueStream)"
|
||||
) << "Field " << fieldName << " not found" << endl;
|
||||
|
||||
// Consume value
|
||||
(void)pTraits<Type>(fieldValueStream);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
class setCellField
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
setCellField()
|
||||
{}
|
||||
|
||||
autoPtr<setCellField> clone() const
|
||||
{
|
||||
return autoPtr<setCellField>(new setCellField());
|
||||
}
|
||||
|
||||
class iNew
|
||||
{
|
||||
const fvMesh& mesh_;
|
||||
const labelList& selectedCells_;
|
||||
|
||||
public:
|
||||
|
||||
iNew(const fvMesh& mesh, const labelList& selectedCells)
|
||||
:
|
||||
mesh_(mesh),
|
||||
selectedCells_(selectedCells)
|
||||
{}
|
||||
|
||||
autoPtr<setCellField> operator()(Istream& fieldValues) const
|
||||
{
|
||||
word fieldType(fieldValues);
|
||||
|
||||
if
|
||||
(
|
||||
!(
|
||||
setCellFieldType<scalar>
|
||||
(fieldType, mesh_, selectedCells_, fieldValues)
|
||||
|| setCellFieldType<vector>
|
||||
(fieldType, mesh_, selectedCells_, fieldValues)
|
||||
|| setCellFieldType<sphericalTensor>
|
||||
(fieldType, mesh_, selectedCells_, fieldValues)
|
||||
|| setCellFieldType<symmTensor>
|
||||
(fieldType, mesh_, selectedCells_, fieldValues)
|
||||
|| setCellFieldType<tensor>
|
||||
(fieldType, mesh_, selectedCells_, fieldValues)
|
||||
)
|
||||
)
|
||||
{
|
||||
WarningIn("setCellField::iNew::operator()(Istream& is)")
|
||||
<< "field type " << fieldType << " not currently supported"
|
||||
<< endl;
|
||||
}
|
||||
|
||||
return autoPtr<setCellField>(new setCellField());
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
template<class Type>
|
||||
bool setFaceFieldType
|
||||
(
|
||||
const word& fieldTypeDesc,
|
||||
const fvMesh& mesh,
|
||||
const labelList& selectedFaces,
|
||||
Istream& fieldValueStream
|
||||
)
|
||||
{
|
||||
typedef GeometricField<Type, fvPatchField, volMesh> fieldType;
|
||||
|
||||
if (fieldTypeDesc != fieldType::typeName + "Value")
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
word fieldName(fieldValueStream);
|
||||
|
||||
// Check the current time directory
|
||||
IOobject fieldHeader
|
||||
(
|
||||
fieldName,
|
||||
mesh.time().timeName(),
|
||||
mesh,
|
||||
IOobject::MUST_READ
|
||||
);
|
||||
|
||||
// Check the "constant" directory
|
||||
if (!fieldHeader.headerOk())
|
||||
{
|
||||
fieldHeader = IOobject
|
||||
(
|
||||
fieldName,
|
||||
mesh.time().constant(),
|
||||
mesh,
|
||||
IOobject::MUST_READ
|
||||
);
|
||||
}
|
||||
|
||||
// Check field exists
|
||||
if (fieldHeader.headerOk())
|
||||
{
|
||||
Info<< " Setting patchField values of "
|
||||
<< fieldHeader.headerClassName()
|
||||
<< " " << fieldName << endl;
|
||||
|
||||
fieldType field(fieldHeader, mesh);
|
||||
|
||||
const Type& value = pTraits<Type>(fieldValueStream);
|
||||
|
||||
// Create flat list of selected faces and their value.
|
||||
Field<Type> allBoundaryValues(mesh.nFaces()-mesh.nInternalFaces());
|
||||
forAll(field.boundaryField(), patchi)
|
||||
{
|
||||
SubField<Type>
|
||||
(
|
||||
allBoundaryValues,
|
||||
field.boundaryField()[patchi].size(),
|
||||
field.boundaryField()[patchi].patch().start()
|
||||
- mesh.nInternalFaces()
|
||||
).assign(field.boundaryField()[patchi]);
|
||||
}
|
||||
|
||||
// Override
|
||||
bool hasWarned = false;
|
||||
labelList nChanged
|
||||
(
|
||||
returnReduce(field.boundaryField().size(), maxOp<label>()),
|
||||
0
|
||||
);
|
||||
forAll(selectedFaces, i)
|
||||
{
|
||||
label facei = selectedFaces[i];
|
||||
if (mesh.isInternalFace(facei))
|
||||
{
|
||||
if (!hasWarned)
|
||||
{
|
||||
hasWarned = true;
|
||||
WarningIn("setFaceFieldType(..)")
|
||||
<< "Ignoring internal face " << facei
|
||||
<< ". Suppressing further warnings." << endl;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
label bFaceI = facei-mesh.nInternalFaces();
|
||||
allBoundaryValues[bFaceI] = value;
|
||||
nChanged[mesh.boundaryMesh().patchID()[bFaceI]]++;
|
||||
}
|
||||
}
|
||||
|
||||
Pstream::listCombineGather(nChanged, plusEqOp<label>());
|
||||
Pstream::listCombineScatter(nChanged);
|
||||
|
||||
// Reassign.
|
||||
forAll(field.boundaryField(), patchi)
|
||||
{
|
||||
if (nChanged[patchi] > 0)
|
||||
{
|
||||
Info<< " On patch "
|
||||
<< field.boundaryField()[patchi].patch().name()
|
||||
<< " set " << nChanged[patchi] << " values" << endl;
|
||||
field.boundaryField()[patchi] == SubField<Type>
|
||||
(
|
||||
allBoundaryValues,
|
||||
field.boundaryField()[patchi].size(),
|
||||
field.boundaryField()[patchi].patch().start()
|
||||
- mesh.nInternalFaces()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (!field.write())
|
||||
{
|
||||
FatalErrorIn
|
||||
(
|
||||
"void setFaceFieldType"
|
||||
"(const fvMesh& mesh, const labelList& selectedFaces,"
|
||||
"Istream& fieldValueStream)"
|
||||
) << "Failed writing field " << field.name() << exit(FatalError);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
WarningIn
|
||||
(
|
||||
"void setFaceFieldType"
|
||||
"(const fvMesh& mesh, const labelList& selectedFaces,"
|
||||
"Istream& fieldValueStream)"
|
||||
) << "Field " << fieldName << " not found" << endl;
|
||||
|
||||
// Consume value
|
||||
(void)pTraits<Type>(fieldValueStream);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
class setFaceField
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
setFaceField()
|
||||
{}
|
||||
|
||||
autoPtr<setFaceField> clone() const
|
||||
{
|
||||
return autoPtr<setFaceField>(new setFaceField());
|
||||
}
|
||||
|
||||
class iNew
|
||||
{
|
||||
const fvMesh& mesh_;
|
||||
const labelList& selectedFaces_;
|
||||
|
||||
public:
|
||||
|
||||
iNew(const fvMesh& mesh, const labelList& selectedFaces)
|
||||
:
|
||||
mesh_(mesh),
|
||||
selectedFaces_(selectedFaces)
|
||||
{}
|
||||
|
||||
autoPtr<setFaceField> operator()(Istream& fieldValues) const
|
||||
{
|
||||
word fieldType(fieldValues);
|
||||
|
||||
if
|
||||
(
|
||||
!(
|
||||
setFaceFieldType<scalar>
|
||||
(fieldType, mesh_, selectedFaces_, fieldValues)
|
||||
|| setFaceFieldType<vector>
|
||||
(fieldType, mesh_, selectedFaces_, fieldValues)
|
||||
|| setFaceFieldType<sphericalTensor>
|
||||
(fieldType, mesh_, selectedFaces_, fieldValues)
|
||||
|| setFaceFieldType<symmTensor>
|
||||
(fieldType, mesh_, selectedFaces_, fieldValues)
|
||||
|| setFaceFieldType<tensor>
|
||||
(fieldType, mesh_, selectedFaces_, fieldValues)
|
||||
)
|
||||
)
|
||||
{
|
||||
WarningIn("setFaceField::iNew::operator()(Istream& is)")
|
||||
<< "field type " << fieldType << " not currently supported"
|
||||
<< endl;
|
||||
}
|
||||
|
||||
return autoPtr<setFaceField>(new setFaceField());
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
#include "addRegionOption.H"
|
||||
#include "setRootCase.H"
|
||||
#include "createTime.H"
|
||||
#include "createNamedMesh.H"
|
||||
|
||||
Info<< "Reading setFieldsDict\n" << endl;
|
||||
|
||||
IOdictionary setFieldsDict
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
"setFieldsDict",
|
||||
runTime.system(),
|
||||
mesh,
|
||||
IOobject::MUST_READ_IF_MODIFIED,
|
||||
IOobject::NO_WRITE
|
||||
)
|
||||
);
|
||||
|
||||
if (setFieldsDict.found("defaultFieldValues"))
|
||||
{
|
||||
Info<< "Setting field default values" << endl;
|
||||
PtrList<setCellField> defaultFieldValues
|
||||
(
|
||||
setFieldsDict.lookup("defaultFieldValues"),
|
||||
setCellField::iNew(mesh, labelList(mesh.nCells()))
|
||||
);
|
||||
Info<< endl;
|
||||
}
|
||||
|
||||
|
||||
Info<< "Setting field region values" << endl;
|
||||
|
||||
PtrList<entry> regions(setFieldsDict.lookup("regions"));
|
||||
|
||||
forAll(regions, regionI)
|
||||
{
|
||||
const entry& region = regions[regionI];
|
||||
|
||||
autoPtr<topoSetSource> source =
|
||||
topoSetSource::New(region.keyword(), mesh, region.dict());
|
||||
|
||||
if (source().setType() == topoSetSource::CELLSETSOURCE)
|
||||
{
|
||||
cellSet selectedCellSet
|
||||
(
|
||||
mesh,
|
||||
"cellSet",
|
||||
mesh.nCells()/10+1 // Reasonable size estimate.
|
||||
);
|
||||
|
||||
source->applyToSet
|
||||
(
|
||||
topoSetSource::NEW,
|
||||
selectedCellSet
|
||||
);
|
||||
|
||||
PtrList<setCellField> fieldValues
|
||||
(
|
||||
region.dict().lookup("fieldValues"),
|
||||
setCellField::iNew(mesh, selectedCellSet.toc())
|
||||
);
|
||||
}
|
||||
else if (source().setType() == topoSetSource::FACESETSOURCE)
|
||||
{
|
||||
faceSet selectedFaceSet
|
||||
(
|
||||
mesh,
|
||||
"faceSet",
|
||||
(mesh.nFaces()-mesh.nInternalFaces())/10+1
|
||||
);
|
||||
|
||||
source->applyToSet
|
||||
(
|
||||
topoSetSource::NEW,
|
||||
selectedFaceSet
|
||||
);
|
||||
|
||||
PtrList<setFaceField> fieldValues
|
||||
(
|
||||
region.dict().lookup("fieldValues"),
|
||||
setFaceField::iNew(mesh, selectedFaceSet.toc())
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Info<< "\nEnd\n" << endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
49
applications/utilities/preProcessing/setFields/setFieldsDict
Normal file
49
applications/utilities/preProcessing/setFields/setFieldsDict
Normal file
@ -0,0 +1,49 @@
|
||||
/*--------------------------------*- 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;
|
||||
object setFieldsDict;
|
||||
}
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
defaultFieldValues
|
||||
(
|
||||
volScalarFieldValue alpha1 0
|
||||
volVectorFieldValue U (0 0 0)
|
||||
);
|
||||
|
||||
regions
|
||||
(
|
||||
// Set cell values
|
||||
// (does zerogradient on boundaries)
|
||||
boxToCell
|
||||
{
|
||||
box (0 0 -1) (0.1461 0.292 1);
|
||||
|
||||
fieldValues
|
||||
(
|
||||
volScalarFieldValue alpha1 1
|
||||
);
|
||||
}
|
||||
|
||||
// Set patch values (using ==)
|
||||
boxToFace
|
||||
{
|
||||
box (0 0 -1) (0.1461 0.292 1);
|
||||
|
||||
fieldValues
|
||||
(
|
||||
volScalarFieldValue alpha1 1
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,3 @@
|
||||
viewFactorsGen.C
|
||||
|
||||
EXE = $(FOAM_APPBIN)/viewFactorsGen
|
||||
@ -0,0 +1,15 @@
|
||||
EXE_INC = \
|
||||
-I$(LIB_SRC)/triSurface/lnInclude \
|
||||
-I$(LIB_SRC)/parallel/distributed/lnInclude \
|
||||
-I$(LIB_SRC)/meshTools/lnInclude \
|
||||
-I$(LIB_SRC)/finiteVolume/lnInclude \
|
||||
-I$(LIB_SRC)/OpenFOAM/lnInclude
|
||||
|
||||
EXE_LIBS = \
|
||||
-lmeshTools \
|
||||
-lfiniteVolume \
|
||||
-lOpenFOAM \
|
||||
-lmeshTools \
|
||||
-ltriSurface \
|
||||
-ldistributed \
|
||||
-lradiationModels
|
||||
@ -0,0 +1,69 @@
|
||||
Random rndGen(653213);
|
||||
|
||||
// Determine mesh bounding boxes:
|
||||
List<treeBoundBox> meshBb
|
||||
(
|
||||
1,
|
||||
treeBoundBox
|
||||
(
|
||||
boundBox(coarseMesh.points(), false)
|
||||
).extend(rndGen, 1e-3)
|
||||
);
|
||||
|
||||
// Dummy bounds dictionary
|
||||
dictionary dict;
|
||||
dict.add("bounds", meshBb);
|
||||
dict.add
|
||||
(
|
||||
"distributionType",
|
||||
distributedTriSurfaceMesh::distributionTypeNames_
|
||||
[
|
||||
distributedTriSurfaceMesh::FROZEN
|
||||
]
|
||||
);
|
||||
dict.add("mergeDistance", SMALL);
|
||||
|
||||
labelHashSet includePatches;
|
||||
forAll(patches, patchI)
|
||||
{
|
||||
const polyPatch& pp = patches[patchI];
|
||||
if (!pp.coupled() && !isA<cyclicAMIPolyPatch>(pp))
|
||||
{
|
||||
includePatches.insert(patchI);
|
||||
}
|
||||
}
|
||||
|
||||
labelList triSurfaceToAgglom(5*nFineFaces);
|
||||
|
||||
const triSurface localSurface = triangulate
|
||||
(
|
||||
patches,
|
||||
includePatches,
|
||||
finalAgglom,
|
||||
triSurfaceToAgglom,
|
||||
globalNumbering,
|
||||
coarsePatches
|
||||
);
|
||||
|
||||
|
||||
distributedTriSurfaceMesh surfacesMesh
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
"wallSurface.stl",
|
||||
runTime.constant(), // directory
|
||||
"triSurface", // instance
|
||||
runTime, // registry
|
||||
IOobject::NO_READ,
|
||||
IOobject::NO_WRITE
|
||||
),
|
||||
localSurface,
|
||||
dict
|
||||
);
|
||||
|
||||
|
||||
triSurfaceToAgglom.resize(surfacesMesh.size());
|
||||
|
||||
//surfacesMesh.searchableSurface::write();
|
||||
|
||||
surfacesMesh.setField(triSurfaceToAgglom);
|
||||
176
applications/utilities/preProcessing/viewFactorsGen/shootRays.H
Normal file
176
applications/utilities/preProcessing/viewFactorsGen/shootRays.H
Normal file
@ -0,0 +1,176 @@
|
||||
// All rays expressed as start face (local) index end end face (global)
|
||||
// Pre-size by assuming a certain percentage is visible.
|
||||
|
||||
// Maximum lenght for dynamicList
|
||||
const label maxDynListLength = 100000;
|
||||
|
||||
for (label procI = 0; procI < Pstream::nProcs(); procI++)
|
||||
{
|
||||
// Shoot rays from me to procI. Note that even if processor has
|
||||
// 0 faces we still need to call findLine to keep calls synced.
|
||||
|
||||
DynamicField<point> start(coarseMesh.nFaces());
|
||||
DynamicField<point> end(start.size());
|
||||
DynamicList<label> startIndex(start.size());
|
||||
DynamicList<label> endIndex(start.size());
|
||||
|
||||
DynamicList<label> startAgg(start.size());
|
||||
DynamicList<label> endAgg(start.size());
|
||||
|
||||
|
||||
const pointField& myFc = remoteCoarseCf[Pstream::myProcNo()];
|
||||
const vectorField& myArea = remoteCoarseSf[Pstream::myProcNo()];
|
||||
const labelField& myAgg = remoteCoarseAgg[Pstream::myProcNo()];
|
||||
|
||||
const pointField& remoteArea = remoteCoarseSf[procI];
|
||||
const pointField& remoteFc = remoteCoarseCf[procI];
|
||||
const labelField& remoteAgg = remoteCoarseAgg[procI];
|
||||
|
||||
label i = 0;
|
||||
label j = 0;
|
||||
do
|
||||
{
|
||||
for (; i < myFc.size(); i++)
|
||||
{
|
||||
const point& fc = myFc[i];
|
||||
const vector& fA = myArea[i];
|
||||
const label& fAgg = myAgg[i];
|
||||
|
||||
for (; j < remoteFc.size(); j++)//
|
||||
{
|
||||
if (procI != Pstream::myProcNo() || i != j)
|
||||
{
|
||||
const point& remFc = remoteFc[j];
|
||||
const vector& remA = remoteArea[j];
|
||||
const label& remAgg = remoteAgg[j];
|
||||
|
||||
const vector& d = remFc - fc;
|
||||
|
||||
if (((d & fA) < 0.) && ((d & remA) > 0))
|
||||
{
|
||||
start.append(fc + 0.001*d);
|
||||
startIndex.append(i);
|
||||
startAgg.append(globalNumbering.toGlobal(procI, fAgg));
|
||||
end.append(fc + 0.999*d);
|
||||
label globalI = globalNumbering.toGlobal(procI, j);
|
||||
endIndex.append(globalI);
|
||||
endAgg.append(globalNumbering.toGlobal(procI, remAgg));
|
||||
if (startIndex.size() > maxDynListLength)
|
||||
{
|
||||
FatalErrorIn
|
||||
(
|
||||
"shootRays"
|
||||
) << "Dynamic list need from capacity."
|
||||
<< "Actual size maxDynListLength : "
|
||||
<< maxDynListLength
|
||||
<< abort(FatalError);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (j == remoteFc.size())
|
||||
{
|
||||
j = 0;
|
||||
}
|
||||
}
|
||||
|
||||
}while (returnReduce(i < myFc.size(), orOp<bool>()));
|
||||
|
||||
List<pointIndexHit> hitInfo(startIndex.size());
|
||||
surfacesMesh.findLine(start, end, hitInfo);
|
||||
|
||||
// Return hit global agglo index
|
||||
labelList aggHitIndex;
|
||||
surfacesMesh.getField(hitInfo, aggHitIndex);
|
||||
|
||||
DynamicList<label> dRayIs;
|
||||
|
||||
// Collect the rays which has not abstacle in bettween in rayStartFace
|
||||
// and rayEndFace. If the ray hit itself get stored in dRayIs
|
||||
forAll (hitInfo, rayI)
|
||||
{
|
||||
if (!hitInfo[rayI].hit())
|
||||
{
|
||||
rayStartFace.append(startIndex[rayI]);
|
||||
rayEndFace.append(endIndex[rayI]);
|
||||
}
|
||||
else if (aggHitIndex[rayI] == startAgg[rayI])
|
||||
{
|
||||
dRayIs.append(rayI);
|
||||
}
|
||||
}
|
||||
|
||||
start.clear();
|
||||
|
||||
|
||||
// Continue rays which hit themself. If they hit the target
|
||||
// agglomeration are added to rayStartFace and rayEndFace
|
||||
|
||||
bool firstLoop = true;
|
||||
DynamicField<point> startHitItself;
|
||||
DynamicField<point> endHitItself;
|
||||
label iter = 0;
|
||||
|
||||
do
|
||||
{
|
||||
labelField rayIs;
|
||||
rayIs.transfer(dRayIs);
|
||||
dRayIs.clear();
|
||||
forAll (rayIs, rayI)
|
||||
{
|
||||
const label rayID = rayIs[rayI];
|
||||
label hitIndex = -1;
|
||||
|
||||
if (firstLoop)
|
||||
{
|
||||
hitIndex = rayIs[rayI];
|
||||
}
|
||||
else
|
||||
{
|
||||
hitIndex = rayI;
|
||||
}
|
||||
|
||||
if (hitInfo[hitIndex].hit())
|
||||
{
|
||||
if (aggHitIndex[hitIndex] == startAgg[rayID])
|
||||
{
|
||||
const vector& endP = end[rayID];
|
||||
const vector& startP = hitInfo[hitIndex].hitPoint();
|
||||
const vector& d = endP - startP;
|
||||
|
||||
startHitItself.append(startP + 0.01*d);
|
||||
endHitItself.append(startP + 1.01*d);
|
||||
|
||||
dRayIs.append(rayID);
|
||||
}
|
||||
else if (aggHitIndex[hitIndex] == endAgg[rayID])
|
||||
{
|
||||
rayStartFace.append(startIndex[rayID]);
|
||||
rayEndFace.append(endIndex[rayID]);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
hitInfo.clear();
|
||||
hitInfo.resize(dRayIs.size());
|
||||
|
||||
surfacesMesh.findLine(startHitItself, endHitItself, hitInfo);
|
||||
|
||||
surfacesMesh.getField(hitInfo, aggHitIndex);
|
||||
|
||||
|
||||
endHitItself.clear();
|
||||
startHitItself.clear();
|
||||
firstLoop = false;
|
||||
iter ++;
|
||||
|
||||
}while (returnReduce(hitInfo.size(), orOp<bool>()) > 0 && iter < 10);
|
||||
|
||||
startIndex.clear();
|
||||
end.clear();
|
||||
endIndex.clear();
|
||||
startAgg.clear();
|
||||
endAgg.clear();
|
||||
}
|
||||
@ -0,0 +1,960 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2011-2014 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
|
||||
viewFactorsGen
|
||||
|
||||
Description
|
||||
View factors are calculated based on a face agglomeration array
|
||||
(finalAgglom generated by faceAgglomerate utility).
|
||||
|
||||
Each view factor between the agglomerated faces i and j (Fij) is calculated
|
||||
using a double integral of the sub-areas composing the agglomaration.
|
||||
|
||||
The patches involved in the view factor calculation are taken from the Qr
|
||||
volScalarField (radiative flux) when is greyDiffusiveRadiationViewFactor
|
||||
otherwise they are not included.
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
#include "argList.H"
|
||||
#include "fvMesh.H"
|
||||
#include "Time.H"
|
||||
#include "volFields.H"
|
||||
#include "surfaceFields.H"
|
||||
#include "distributedTriSurfaceMesh.H"
|
||||
#include "cyclicAMIPolyPatch.H"
|
||||
#include "triSurfaceTools.H"
|
||||
#include "mapDistribute.H"
|
||||
|
||||
#include "OFstream.H"
|
||||
#include "meshTools.H"
|
||||
#include "plane.H"
|
||||
#include "uindirectPrimitivePatch.H"
|
||||
#include "DynamicField.H"
|
||||
#include "IFstream.H"
|
||||
#include "unitConversion.H"
|
||||
|
||||
#include "mathematicalConstants.H"
|
||||
#include "scalarMatrices.H"
|
||||
#include "CompactListList.H"
|
||||
#include "labelIOList.H"
|
||||
#include "labelListIOList.H"
|
||||
#include "scalarListIOList.H"
|
||||
|
||||
#include "singleCellFvMesh.H"
|
||||
#include "IOdictionary.H"
|
||||
#include "fixedValueFvPatchFields.H"
|
||||
|
||||
using namespace Foam;
|
||||
|
||||
|
||||
triSurface triangulate
|
||||
(
|
||||
const polyBoundaryMesh& bMesh,
|
||||
const labelHashSet& includePatches,
|
||||
const labelListIOList& finalAgglom,
|
||||
labelList& triSurfaceToAgglom,
|
||||
const globalIndex& globalNumbering,
|
||||
const polyBoundaryMesh& coarsePatches
|
||||
)
|
||||
{
|
||||
const polyMesh& mesh = bMesh.mesh();
|
||||
|
||||
// Storage for surfaceMesh. Size estimate.
|
||||
DynamicList<labelledTri> triangles
|
||||
(
|
||||
mesh.nFaces() - mesh.nInternalFaces()
|
||||
);
|
||||
|
||||
label newPatchI = 0;
|
||||
label localTriFaceI = 0;
|
||||
|
||||
forAllConstIter(labelHashSet, includePatches, iter)
|
||||
{
|
||||
const label patchI = iter.key();
|
||||
const polyPatch& patch = bMesh[patchI];
|
||||
const pointField& points = patch.points();
|
||||
|
||||
label nTriTotal = 0;
|
||||
|
||||
forAll(patch, patchFaceI)
|
||||
{
|
||||
const face& f = patch[patchFaceI];
|
||||
|
||||
faceList triFaces(f.nTriangles(points));
|
||||
|
||||
label nTri = 0;
|
||||
|
||||
f.triangles(points, nTri, triFaces);
|
||||
|
||||
forAll(triFaces, triFaceI)
|
||||
{
|
||||
const face& f = triFaces[triFaceI];
|
||||
|
||||
triangles.append(labelledTri(f[0], f[1], f[2], newPatchI));
|
||||
|
||||
nTriTotal++;
|
||||
|
||||
triSurfaceToAgglom[localTriFaceI++] = globalNumbering.toGlobal
|
||||
(
|
||||
Pstream::myProcNo(),
|
||||
finalAgglom[patchI][patchFaceI]
|
||||
+ coarsePatches[patchI].start()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
newPatchI++;
|
||||
}
|
||||
|
||||
triSurfaceToAgglom.resize(localTriFaceI-1);
|
||||
|
||||
triangles.shrink();
|
||||
|
||||
// Create globally numbered tri surface
|
||||
triSurface rawSurface(triangles, mesh.points());
|
||||
|
||||
// Create locally numbered tri surface
|
||||
triSurface surface
|
||||
(
|
||||
rawSurface.localFaces(),
|
||||
rawSurface.localPoints()
|
||||
);
|
||||
|
||||
// Add patch names to surface
|
||||
surface.patches().setSize(newPatchI);
|
||||
|
||||
newPatchI = 0;
|
||||
|
||||
forAllConstIter(labelHashSet, includePatches, iter)
|
||||
{
|
||||
const label patchI = iter.key();
|
||||
const polyPatch& patch = bMesh[patchI];
|
||||
|
||||
surface.patches()[newPatchI].index() = patchI;
|
||||
surface.patches()[newPatchI].name() = patch.name();
|
||||
surface.patches()[newPatchI].geometricType() = patch.type();
|
||||
|
||||
newPatchI++;
|
||||
}
|
||||
|
||||
return surface;
|
||||
}
|
||||
|
||||
|
||||
void writeRays
|
||||
(
|
||||
const fileName& fName,
|
||||
const pointField& compactCf,
|
||||
const pointField& myFc,
|
||||
const labelListList& visibleFaceFaces
|
||||
)
|
||||
{
|
||||
OFstream str(fName);
|
||||
label vertI = 0;
|
||||
|
||||
Pout<< "Dumping rays to " << str.name() << endl;
|
||||
|
||||
forAll(myFc, faceI)
|
||||
{
|
||||
const labelList visFaces = visibleFaceFaces[faceI];
|
||||
forAll(visFaces, faceRemote)
|
||||
{
|
||||
label compactI = visFaces[faceRemote];
|
||||
const point& remoteFc = compactCf[compactI];
|
||||
|
||||
meshTools::writeOBJ(str, myFc[faceI]);
|
||||
vertI++;
|
||||
meshTools::writeOBJ(str, remoteFc);
|
||||
vertI++;
|
||||
str << "l " << vertI-1 << ' ' << vertI << nl;
|
||||
}
|
||||
}
|
||||
string cmd("objToVTK " + fName + " " + fName.lessExt() + ".vtk");
|
||||
Pout<< "cmd:" << cmd << endl;
|
||||
system(cmd);
|
||||
}
|
||||
|
||||
|
||||
scalar calculateViewFactorFij
|
||||
(
|
||||
const vector& i,
|
||||
const vector& j,
|
||||
const vector& dAi,
|
||||
const vector& dAj
|
||||
)
|
||||
{
|
||||
vector r = i - j;
|
||||
scalar rMag = mag(r);
|
||||
scalar dAiMag = mag(dAi);
|
||||
scalar dAjMag = mag(dAj);
|
||||
|
||||
vector ni = dAi/dAiMag;
|
||||
vector nj = dAj/dAjMag;
|
||||
scalar cosThetaJ = mag(nj & r)/rMag;
|
||||
scalar cosThetaI = mag(ni & r)/rMag;
|
||||
|
||||
return
|
||||
(
|
||||
(cosThetaI*cosThetaJ*dAjMag*dAiMag)
|
||||
/(sqr(rMag)*constant::mathematical::pi)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
void insertMatrixElements
|
||||
(
|
||||
const globalIndex& globalNumbering,
|
||||
const label fromProcI,
|
||||
const labelListList& globalFaceFaces,
|
||||
const scalarListList& viewFactors,
|
||||
scalarSquareMatrix& matrix
|
||||
)
|
||||
{
|
||||
forAll(viewFactors, faceI)
|
||||
{
|
||||
const scalarList& vf = viewFactors[faceI];
|
||||
const labelList& globalFaces = globalFaceFaces[faceI];
|
||||
|
||||
label globalI = globalNumbering.toGlobal(fromProcI, faceI);
|
||||
forAll(globalFaces, i)
|
||||
{
|
||||
matrix[globalI][globalFaces[i]] = vf[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
#include "addRegionOption.H"
|
||||
#include "setRootCase.H"
|
||||
#include "createTime.H"
|
||||
#include "createNamedMesh.H"
|
||||
|
||||
// Read view factor dictionary
|
||||
IOdictionary viewFactorDict
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
"viewFactorsDict",
|
||||
runTime.constant(),
|
||||
mesh,
|
||||
IOobject::MUST_READ_IF_MODIFIED,
|
||||
IOobject::NO_WRITE
|
||||
)
|
||||
);
|
||||
|
||||
const bool writeViewFactors =
|
||||
viewFactorDict.lookupOrDefault<bool>("writeViewFactorMatrix", false);
|
||||
|
||||
const bool dumpRays =
|
||||
viewFactorDict.lookupOrDefault<bool>("dumpRays", false);
|
||||
|
||||
const label debug = viewFactorDict.lookupOrDefault<label>("debug", 0);
|
||||
|
||||
volScalarField Qr
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
"Qr",
|
||||
runTime.timeName(),
|
||||
mesh,
|
||||
IOobject::MUST_READ,
|
||||
IOobject::NO_WRITE
|
||||
),
|
||||
mesh
|
||||
);
|
||||
|
||||
// Read agglomeration map
|
||||
labelListIOList finalAgglom
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
"finalAgglom",
|
||||
mesh.facesInstance(),
|
||||
mesh,
|
||||
IOobject::MUST_READ,
|
||||
IOobject::NO_WRITE,
|
||||
false
|
||||
)
|
||||
);
|
||||
|
||||
// Create the coarse mesh using agglomeration
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
if (debug)
|
||||
{
|
||||
Pout << "\nCreating single cell mesh..." << endl;
|
||||
}
|
||||
|
||||
singleCellFvMesh coarseMesh
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
mesh.name(),
|
||||
runTime.timeName(),
|
||||
runTime,
|
||||
IOobject::NO_READ,
|
||||
IOobject::NO_WRITE
|
||||
),
|
||||
mesh,
|
||||
finalAgglom
|
||||
);
|
||||
|
||||
if (debug)
|
||||
{
|
||||
Pout << "\nCreated single cell mesh..." << endl;
|
||||
}
|
||||
|
||||
|
||||
// Calculate total number of fine and coarse faces
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
label nCoarseFaces = 0; //total number of coarse faces
|
||||
label nFineFaces = 0; //total number of fine faces
|
||||
|
||||
const polyBoundaryMesh& patches = mesh.boundaryMesh();
|
||||
const polyBoundaryMesh& coarsePatches = coarseMesh.boundaryMesh();
|
||||
|
||||
labelList viewFactorsPatches(patches.size());
|
||||
|
||||
const volScalarField::GeometricBoundaryField& Qrb = Qr.boundaryField();
|
||||
|
||||
label count = 0;
|
||||
forAll(Qrb, patchI)
|
||||
{
|
||||
const polyPatch& pp = patches[patchI];
|
||||
const fvPatchScalarField& QrpI = Qrb[patchI];
|
||||
|
||||
if ((isA<fixedValueFvPatchScalarField>(QrpI)) && (pp.size() > 0))
|
||||
{
|
||||
viewFactorsPatches[count] = QrpI.patch().index();
|
||||
nCoarseFaces += coarsePatches[patchI].size();
|
||||
nFineFaces += patches[patchI].size();
|
||||
count ++;
|
||||
}
|
||||
}
|
||||
|
||||
viewFactorsPatches.resize(count--);
|
||||
|
||||
// total number of coarse faces
|
||||
label totalNCoarseFaces = nCoarseFaces;
|
||||
|
||||
reduce(totalNCoarseFaces, sumOp<label>());
|
||||
|
||||
if (Pstream::master())
|
||||
{
|
||||
Info << "\nTotal number of coarse faces: "<< totalNCoarseFaces << endl;
|
||||
}
|
||||
|
||||
if (Pstream::master() && debug)
|
||||
{
|
||||
Pout << "\nView factor patches included in the calculation : "
|
||||
<< viewFactorsPatches << endl;
|
||||
}
|
||||
|
||||
// Collect local Cf and Sf on coarse mesh
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
DynamicList<point> localCoarseCf(nCoarseFaces);
|
||||
DynamicList<point> localCoarseSf(nCoarseFaces);
|
||||
|
||||
DynamicList<label> localAgg(nCoarseFaces);
|
||||
|
||||
forAll (viewFactorsPatches, i)
|
||||
{
|
||||
const label patchID = viewFactorsPatches[i];
|
||||
|
||||
const polyPatch& pp = patches[patchID];
|
||||
const labelList& agglom = finalAgglom[patchID];
|
||||
label nAgglom = max(agglom)+1;
|
||||
labelListList coarseToFine(invertOneToMany(nAgglom, agglom));
|
||||
const labelList& coarsePatchFace = coarseMesh.patchFaceMap()[patchID];
|
||||
|
||||
const pointField& coarseCf = coarseMesh.Cf().boundaryField()[patchID];
|
||||
const pointField& coarseSf = coarseMesh.Sf().boundaryField()[patchID];
|
||||
|
||||
labelHashSet includePatches;
|
||||
includePatches.insert(patchID);
|
||||
|
||||
forAll(coarseCf, faceI)
|
||||
{
|
||||
point cf = coarseCf[faceI];
|
||||
|
||||
const label coarseFaceI = coarsePatchFace[faceI];
|
||||
const labelList& fineFaces = coarseToFine[coarseFaceI];
|
||||
const label agglomI =
|
||||
agglom[fineFaces[0]] + coarsePatches[patchID].start();
|
||||
|
||||
// Construct single face
|
||||
uindirectPrimitivePatch upp
|
||||
(
|
||||
UIndirectList<face>(pp, fineFaces),
|
||||
pp.points()
|
||||
);
|
||||
|
||||
|
||||
List<point> availablePoints
|
||||
(
|
||||
upp.faceCentres().size()
|
||||
+ upp.localPoints().size()
|
||||
);
|
||||
|
||||
SubList<point>
|
||||
(
|
||||
availablePoints,
|
||||
upp.faceCentres().size()
|
||||
).assign(upp.faceCentres());
|
||||
|
||||
SubList<point>
|
||||
(
|
||||
availablePoints,
|
||||
upp.localPoints().size(),
|
||||
upp.faceCentres().size()
|
||||
).assign(upp.localPoints());
|
||||
|
||||
point cfo = cf;
|
||||
scalar dist = GREAT;
|
||||
forAll(availablePoints, iPoint)
|
||||
{
|
||||
point cfFine = availablePoints[iPoint];
|
||||
if (mag(cfFine-cfo) < dist)
|
||||
{
|
||||
dist = mag(cfFine-cfo);
|
||||
cf = cfFine;
|
||||
}
|
||||
}
|
||||
|
||||
point sf = coarseSf[faceI];
|
||||
localCoarseCf.append(cf);
|
||||
localCoarseSf.append(sf);
|
||||
localAgg.append(agglomI);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Distribute local coarse Cf and Sf for shooting rays
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
List<pointField> remoteCoarseCf(Pstream::nProcs());
|
||||
List<pointField> remoteCoarseSf(Pstream::nProcs());
|
||||
List<labelField> remoteCoarseAgg(Pstream::nProcs());
|
||||
|
||||
remoteCoarseCf[Pstream::myProcNo()] = localCoarseCf;
|
||||
remoteCoarseSf[Pstream::myProcNo()] = localCoarseSf;
|
||||
remoteCoarseAgg[Pstream::myProcNo()] = localAgg;
|
||||
|
||||
Pstream::gatherList(remoteCoarseCf);
|
||||
Pstream::scatterList(remoteCoarseCf);
|
||||
Pstream::gatherList(remoteCoarseSf);
|
||||
Pstream::scatterList(remoteCoarseSf);
|
||||
Pstream::gatherList(remoteCoarseAgg);
|
||||
Pstream::scatterList(remoteCoarseAgg);
|
||||
|
||||
|
||||
globalIndex globalNumbering(nCoarseFaces);
|
||||
|
||||
// Set up searching engine for obstacles
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
#include "searchingEngine.H"
|
||||
|
||||
|
||||
// Determine rays between coarse face centres
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
DynamicList<label> rayStartFace(nCoarseFaces + 0.01*nCoarseFaces);
|
||||
|
||||
DynamicList<label> rayEndFace(rayStartFace.size());
|
||||
|
||||
|
||||
// Return rayStartFace in local index andrayEndFace in global index
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
#include "shootRays.H"
|
||||
|
||||
// Calculate number of visible faces from local index
|
||||
labelList nVisibleFaceFaces(nCoarseFaces, 0);
|
||||
|
||||
forAll(rayStartFace, i)
|
||||
{
|
||||
nVisibleFaceFaces[rayStartFace[i]]++;
|
||||
}
|
||||
|
||||
labelListList visibleFaceFaces(nCoarseFaces);
|
||||
|
||||
label nViewFactors = 0;
|
||||
forAll(nVisibleFaceFaces, faceI)
|
||||
{
|
||||
visibleFaceFaces[faceI].setSize(nVisibleFaceFaces[faceI]);
|
||||
nViewFactors += nVisibleFaceFaces[faceI];
|
||||
}
|
||||
|
||||
|
||||
// - Construct compact numbering
|
||||
// - return map from remote to compact indices
|
||||
// (per processor (!= myProcNo) a map from remote index to compact index)
|
||||
// - construct distribute map
|
||||
// - renumber rayEndFace into compact addressing
|
||||
|
||||
List<Map<label> > compactMap(Pstream::nProcs());
|
||||
|
||||
mapDistribute map(globalNumbering, rayEndFace, compactMap);
|
||||
|
||||
labelListIOList IOsubMap
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
"subMap",
|
||||
mesh.facesInstance(),
|
||||
mesh,
|
||||
IOobject::NO_READ,
|
||||
IOobject::NO_WRITE,
|
||||
false
|
||||
),
|
||||
map.subMap()
|
||||
);
|
||||
IOsubMap.write();
|
||||
|
||||
|
||||
labelListIOList IOconstructMap
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
"constructMap",
|
||||
mesh.facesInstance(),
|
||||
mesh,
|
||||
IOobject::NO_READ,
|
||||
IOobject::NO_WRITE,
|
||||
false
|
||||
),
|
||||
map.constructMap()
|
||||
);
|
||||
IOconstructMap.write();
|
||||
|
||||
|
||||
IOList<label> consMapDim
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
"constructMapDim",
|
||||
mesh.facesInstance(),
|
||||
mesh,
|
||||
IOobject::NO_READ,
|
||||
IOobject::NO_WRITE,
|
||||
false
|
||||
),
|
||||
List<label>(1, map.constructSize())
|
||||
);
|
||||
consMapDim.write();
|
||||
|
||||
|
||||
// visibleFaceFaces has:
|
||||
// (local face, local viewed face) = compact viewed face
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
nVisibleFaceFaces = 0;
|
||||
forAll(rayStartFace, i)
|
||||
{
|
||||
label faceI = rayStartFace[i];
|
||||
label compactI = rayEndFace[i];
|
||||
visibleFaceFaces[faceI][nVisibleFaceFaces[faceI]++] = compactI;
|
||||
}
|
||||
|
||||
|
||||
// Construct data in compact addressing
|
||||
// I need coarse Sf (Ai), fine Sf (dAi) and fine Cf(r) to calculate Fij
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
pointField compactCoarseCf(map.constructSize(), pTraits<vector>::zero);
|
||||
pointField compactCoarseSf(map.constructSize(), pTraits<vector>::zero);
|
||||
List<List<point> > compactFineSf(map.constructSize());
|
||||
List<List<point> > compactFineCf(map.constructSize());
|
||||
|
||||
DynamicList<label> compactPatchId(map.constructSize());
|
||||
|
||||
// Insert my coarse local values
|
||||
SubList<point>(compactCoarseSf, nCoarseFaces).assign(localCoarseSf);
|
||||
SubList<point>(compactCoarseCf, nCoarseFaces).assign(localCoarseCf);
|
||||
|
||||
// Insert my fine local values
|
||||
label compactI = 0;
|
||||
forAll(viewFactorsPatches, i)
|
||||
{
|
||||
label patchID = viewFactorsPatches[i];
|
||||
const labelList& agglom = finalAgglom[patchID];
|
||||
label nAgglom = max(agglom)+1;
|
||||
labelListList coarseToFine(invertOneToMany(nAgglom, agglom));
|
||||
const labelList& coarsePatchFace = coarseMesh.patchFaceMap()[patchID];
|
||||
|
||||
forAll(coarseToFine, coarseI)
|
||||
{
|
||||
compactPatchId.append(patchID);
|
||||
List<point>& fineCf = compactFineCf[compactI];
|
||||
List<point>& fineSf = compactFineSf[compactI++];
|
||||
|
||||
const label coarseFaceI = coarsePatchFace[coarseI];
|
||||
const labelList& fineFaces = coarseToFine[coarseFaceI];
|
||||
|
||||
fineCf.setSize(fineFaces.size());
|
||||
fineSf.setSize(fineFaces.size());
|
||||
|
||||
fineCf = UIndirectList<point>
|
||||
(
|
||||
mesh.Cf().boundaryField()[patchID],
|
||||
coarseToFine[coarseFaceI]
|
||||
);
|
||||
fineSf = UIndirectList<point>
|
||||
(
|
||||
mesh.Sf().boundaryField()[patchID],
|
||||
coarseToFine[coarseFaceI]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Do all swapping
|
||||
map.distribute(compactCoarseSf);
|
||||
map.distribute(compactCoarseCf);
|
||||
map.distribute(compactFineCf);
|
||||
map.distribute(compactFineSf);
|
||||
|
||||
map.distribute(compactPatchId);
|
||||
|
||||
|
||||
// Plot all rays between visible faces.
|
||||
if (dumpRays)
|
||||
{
|
||||
writeRays
|
||||
(
|
||||
runTime.path()/"allVisibleFaces.obj",
|
||||
compactCoarseCf,
|
||||
remoteCoarseCf[Pstream::myProcNo()],
|
||||
visibleFaceFaces
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
// Fill local view factor matrix
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
scalarListIOList F
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
"F",
|
||||
mesh.facesInstance(),
|
||||
mesh,
|
||||
IOobject::NO_READ,
|
||||
IOobject::NO_WRITE,
|
||||
false
|
||||
),
|
||||
nCoarseFaces
|
||||
);
|
||||
|
||||
label totalPatches = coarsePatches.size();
|
||||
reduce(totalPatches, maxOp<label>());
|
||||
|
||||
// Matrix sum in j(Fij) for each i (if enclosure sum = 1)
|
||||
scalarSquareMatrix sumViewFactorPatch
|
||||
(
|
||||
totalPatches,
|
||||
totalPatches,
|
||||
0.0
|
||||
);
|
||||
|
||||
scalarList patchArea(totalPatches, 0.0);
|
||||
|
||||
if (Pstream::master())
|
||||
{
|
||||
Info<< "\nCalculating view factors..." << endl;
|
||||
}
|
||||
|
||||
if (mesh.nSolutionD() == 3)
|
||||
{
|
||||
forAll (localCoarseSf, coarseFaceI)
|
||||
{
|
||||
const List<point>& localFineSf = compactFineSf[coarseFaceI];
|
||||
const vector Ai = sum(localFineSf);
|
||||
const List<point>& localFineCf = compactFineCf[coarseFaceI];
|
||||
const label fromPatchId = compactPatchId[coarseFaceI];
|
||||
patchArea[fromPatchId] += mag(Ai);
|
||||
|
||||
const labelList& visCoarseFaces = visibleFaceFaces[coarseFaceI];
|
||||
|
||||
forAll(visCoarseFaces, visCoarseFaceI)
|
||||
{
|
||||
F[coarseFaceI].setSize(visCoarseFaces.size());
|
||||
label compactJ = visCoarseFaces[visCoarseFaceI];
|
||||
const List<point>& remoteFineSj = compactFineSf[compactJ];
|
||||
const List<point>& remoteFineCj = compactFineCf[compactJ];
|
||||
|
||||
const label toPatchId = compactPatchId[compactJ];
|
||||
|
||||
scalar Fij = 0;
|
||||
forAll (localFineSf, i)
|
||||
{
|
||||
const vector& dAi = localFineSf[i];
|
||||
const vector& dCi = localFineCf[i];
|
||||
|
||||
forAll (remoteFineSj, j)
|
||||
{
|
||||
const vector& dAj = remoteFineSj[j];
|
||||
const vector& dCj = remoteFineCj[j];
|
||||
|
||||
scalar dIntFij = calculateViewFactorFij
|
||||
(
|
||||
dCi,
|
||||
dCj,
|
||||
dAi,
|
||||
dAj
|
||||
);
|
||||
|
||||
Fij += dIntFij;
|
||||
}
|
||||
}
|
||||
F[coarseFaceI][visCoarseFaceI] = Fij/mag(Ai);
|
||||
sumViewFactorPatch[fromPatchId][toPatchId] += Fij;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (mesh.nSolutionD() == 2)
|
||||
{
|
||||
const boundBox& box = mesh.bounds();
|
||||
const Vector<label>& dirs = mesh.geometricD();
|
||||
vector emptyDir = vector::zero;
|
||||
forAll(dirs, i)
|
||||
{
|
||||
if (dirs[i] == -1)
|
||||
{
|
||||
emptyDir[i] = 1.0;
|
||||
}
|
||||
}
|
||||
|
||||
scalar wideBy2 = (box.span() & emptyDir)*2.0;
|
||||
|
||||
forAll(localCoarseSf, coarseFaceI)
|
||||
{
|
||||
const vector& Ai = localCoarseSf[coarseFaceI];
|
||||
const vector& Ci = localCoarseCf[coarseFaceI];
|
||||
vector Ain = Ai/mag(Ai);
|
||||
vector R1i = Ci + (mag(Ai)/wideBy2)*(Ain ^ emptyDir);
|
||||
vector R2i = Ci - (mag(Ai)/wideBy2)*(Ain ^ emptyDir) ;
|
||||
|
||||
const label fromPatchId = compactPatchId[coarseFaceI];
|
||||
patchArea[fromPatchId] += mag(Ai);
|
||||
|
||||
const labelList& visCoarseFaces = visibleFaceFaces[coarseFaceI];
|
||||
forAll (visCoarseFaces, visCoarseFaceI)
|
||||
{
|
||||
F[coarseFaceI].setSize(visCoarseFaces.size());
|
||||
label compactJ = visCoarseFaces[visCoarseFaceI];
|
||||
const vector& Aj = compactCoarseSf[compactJ];
|
||||
const vector& Cj = compactCoarseCf[compactJ];
|
||||
|
||||
const label toPatchId = compactPatchId[compactJ];
|
||||
|
||||
vector Ajn = Aj/mag(Aj);
|
||||
vector R1j = Cj + (mag(Aj)/wideBy2)*(Ajn ^ emptyDir);
|
||||
vector R2j = Cj - (mag(Aj)/wideBy2)*(Ajn ^ emptyDir);
|
||||
|
||||
scalar d1 = mag(R1i - R2j);
|
||||
scalar d2 = mag(R2i - R1j);
|
||||
scalar s1 = mag(R1i - R1j);
|
||||
scalar s2 = mag(R2i - R2j);
|
||||
|
||||
scalar Fij = mag((d1 + d2) - (s1 + s2))/(4.0*mag(Ai)/wideBy2);
|
||||
|
||||
F[coarseFaceI][visCoarseFaceI] = Fij;
|
||||
sumViewFactorPatch[fromPatchId][toPatchId] += Fij*mag(Ai);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (Pstream::master())
|
||||
{
|
||||
Info << "Writing view factor matrix..." << endl;
|
||||
}
|
||||
|
||||
// Write view factors matrix in listlist form
|
||||
F.write();
|
||||
|
||||
reduce(sumViewFactorPatch, sumOp<scalarSquareMatrix>());
|
||||
reduce(patchArea, sumOp<scalarList>());
|
||||
|
||||
|
||||
if (Pstream::master() && debug)
|
||||
{
|
||||
forAll(viewFactorsPatches, i)
|
||||
{
|
||||
label patchI = viewFactorsPatches[i];
|
||||
forAll(viewFactorsPatches, i)
|
||||
{
|
||||
label patchJ = viewFactorsPatches[i];
|
||||
Info << "F" << patchI << patchJ << ": "
|
||||
<< sumViewFactorPatch[patchI][patchJ]/patchArea[patchI]
|
||||
<< endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (writeViewFactors)
|
||||
{
|
||||
volScalarField viewFactorField
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
"viewFactorField",
|
||||
mesh.time().timeName(),
|
||||
mesh,
|
||||
IOobject::NO_READ,
|
||||
IOobject::NO_WRITE
|
||||
),
|
||||
mesh,
|
||||
dimensionedScalar("viewFactorField", dimless, 0)
|
||||
);
|
||||
|
||||
label compactI = 0;
|
||||
forAll(viewFactorsPatches, i)
|
||||
{
|
||||
label patchID = viewFactorsPatches[i];
|
||||
const labelList& agglom = finalAgglom[patchID];
|
||||
label nAgglom = max(agglom)+1;
|
||||
labelListList coarseToFine(invertOneToMany(nAgglom, agglom));
|
||||
const labelList& coarsePatchFace =
|
||||
coarseMesh.patchFaceMap()[patchID];
|
||||
|
||||
forAll(coarseToFine, coarseI)
|
||||
{
|
||||
const scalar Fij = sum(F[compactI]);
|
||||
const label coarseFaceID = coarsePatchFace[coarseI];
|
||||
const labelList& fineFaces = coarseToFine[coarseFaceID];
|
||||
forAll (fineFaces, fineId)
|
||||
{
|
||||
const label faceID = fineFaces[fineId];
|
||||
viewFactorField.boundaryField()[patchID][faceID] = Fij;
|
||||
}
|
||||
compactI++;
|
||||
}
|
||||
}
|
||||
viewFactorField.write();
|
||||
}
|
||||
|
||||
|
||||
// Invert compactMap (from processor+localface to compact) to go
|
||||
// from compact to processor+localface (expressed as a globalIndex)
|
||||
// globalIndex globalCoarFaceNum(coarseMesh.nFaces());
|
||||
labelList compactToGlobal(map.constructSize());
|
||||
|
||||
// Local indices first (note: are not in compactMap)
|
||||
for (label i = 0; i < globalNumbering.localSize(); i++)
|
||||
{
|
||||
compactToGlobal[i] = globalNumbering.toGlobal(i);
|
||||
}
|
||||
|
||||
|
||||
forAll(compactMap, procI)
|
||||
{
|
||||
const Map<label>& localToCompactMap = compactMap[procI];
|
||||
|
||||
forAllConstIter(Map<label>, localToCompactMap, iter)
|
||||
{
|
||||
compactToGlobal[iter()] = globalNumbering.toGlobal
|
||||
(
|
||||
procI,
|
||||
iter.key()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (Pstream::master())
|
||||
{
|
||||
scalarSquareMatrix Fmatrix(totalNCoarseFaces, totalNCoarseFaces, 0.0);
|
||||
|
||||
labelListList globalFaceFaces(visibleFaceFaces.size());
|
||||
|
||||
// Create globalFaceFaces needed to insert view factors
|
||||
// in F to the global matrix Fmatrix
|
||||
forAll(globalFaceFaces, faceI)
|
||||
{
|
||||
globalFaceFaces[faceI] = renumber
|
||||
(
|
||||
compactToGlobal,
|
||||
visibleFaceFaces[faceI]
|
||||
);
|
||||
}
|
||||
|
||||
labelListIOList IOglobalFaceFaces
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
"globalFaceFaces",
|
||||
mesh.facesInstance(),
|
||||
mesh,
|
||||
IOobject::NO_READ,
|
||||
IOobject::NO_WRITE,
|
||||
false
|
||||
),
|
||||
globalFaceFaces
|
||||
);
|
||||
IOglobalFaceFaces.write();
|
||||
}
|
||||
else
|
||||
{
|
||||
labelListList globalFaceFaces(visibleFaceFaces.size());
|
||||
forAll(globalFaceFaces, faceI)
|
||||
{
|
||||
globalFaceFaces[faceI] = renumber
|
||||
(
|
||||
compactToGlobal,
|
||||
visibleFaceFaces[faceI]
|
||||
);
|
||||
}
|
||||
|
||||
labelListIOList IOglobalFaceFaces
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
"globalFaceFaces",
|
||||
mesh.facesInstance(),
|
||||
mesh,
|
||||
IOobject::NO_READ,
|
||||
IOobject::NO_WRITE,
|
||||
false
|
||||
),
|
||||
globalFaceFaces
|
||||
);
|
||||
|
||||
IOglobalFaceFaces.write();
|
||||
}
|
||||
|
||||
Info<< "End\n" << endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
5
applications/utilities/preProcessing/wallFunctionTable/Allwclean
Executable file
5
applications/utilities/preProcessing/wallFunctionTable/Allwclean
Executable file
@ -0,0 +1,5 @@
|
||||
#!/bin/sh
|
||||
|
||||
wclean libso tabulatedWallFunction
|
||||
wclean
|
||||
|
||||
8
applications/utilities/preProcessing/wallFunctionTable/Allwmake
Executable file
8
applications/utilities/preProcessing/wallFunctionTable/Allwmake
Executable file
@ -0,0 +1,8 @@
|
||||
#!/bin/sh
|
||||
cd ${0%/*} || exit 1 # run from this directory
|
||||
set -x
|
||||
|
||||
wmake libso tabulatedWallFunction
|
||||
wmake
|
||||
|
||||
# ----------------------------------------------------------------- end-of-file
|
||||
@ -0,0 +1,3 @@
|
||||
wallFunctionTableApp.C
|
||||
|
||||
EXE = $(FOAM_APPBIN)/wallFunctionTable
|
||||
@ -0,0 +1,8 @@
|
||||
EXE_INC = \
|
||||
-I./tabulatedWallFunction/lnInclude \
|
||||
-I$(LIB_SRC)/turbulenceModels/incompressible/RAS/lnInclude \
|
||||
-I$(LIB_SRC)/finiteVolume/lnInclude
|
||||
|
||||
EXE_LIBS = \
|
||||
-ltabulatedWallFunctions \
|
||||
-lfiniteVolume
|
||||
@ -0,0 +1,7 @@
|
||||
tabulatedWallFunction/tabulatedWallFunction.C
|
||||
tabulatedWallFunction/tabulatedWallFunctionNew.C
|
||||
|
||||
SpaldingsLaw/SpaldingsLaw.C
|
||||
general/general.C
|
||||
|
||||
LIB = $(FOAM_LIBBIN)/libtabulatedWallFunctions
|
||||
@ -0,0 +1,9 @@
|
||||
|
||||
EXE_INC = \
|
||||
-I$(LIB_SRC)/finiteVolume/lnInclude \
|
||||
-I$(LIB_SRC)/turbulenceModels \
|
||||
-I$(LIB_SRC)/turbulenceModels/incompressible/RAS/lnInclude \
|
||||
-I$(LIB_SRC)/transportModels
|
||||
|
||||
LIB_LIBS = \
|
||||
-lfiniteVolume
|
||||
@ -0,0 +1,196 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2011 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 "SpaldingsLaw.H"
|
||||
#include "addToRunTimeSelectionTable.H"
|
||||
|
||||
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
namespace tabulatedWallFunctions
|
||||
{
|
||||
defineTypeNameAndDebug(SpaldingsLaw, 0);
|
||||
addToRunTimeSelectionTable
|
||||
(
|
||||
tabulatedWallFunction,
|
||||
SpaldingsLaw,
|
||||
dictionary
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const Foam::label Foam::tabulatedWallFunctions::SpaldingsLaw::maxIters_ = 1000;
|
||||
|
||||
const Foam::scalar
|
||||
Foam::tabulatedWallFunctions::SpaldingsLaw::tolerance_ = 1e-4;
|
||||
|
||||
|
||||
// * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * * //
|
||||
|
||||
void Foam::tabulatedWallFunctions::SpaldingsLaw::invertFunction()
|
||||
{
|
||||
// Initialise u+ and R
|
||||
scalar Re = 0.0;
|
||||
scalar uPlus = 1;
|
||||
|
||||
// Populate the table
|
||||
forAll(invertedTable_, i)
|
||||
{
|
||||
if (invertedTable_.log10())
|
||||
{
|
||||
Re = pow(10, (i*invertedTable_.dx() + invertedTable_.x0()));
|
||||
}
|
||||
else
|
||||
{
|
||||
Re = i*invertedTable_.dx() + invertedTable_.x0();
|
||||
}
|
||||
|
||||
// Use latest available u+ estimate
|
||||
if (i > 0)
|
||||
{
|
||||
uPlus = invertedTable_[i-1];
|
||||
}
|
||||
|
||||
// Newton iterations to determine u+
|
||||
label iter = 0;
|
||||
scalar error = GREAT;
|
||||
do
|
||||
{
|
||||
scalar kUPlus = min(kappa_*uPlus, 50);
|
||||
scalar A =
|
||||
E_*sqr(uPlus)
|
||||
+ uPlus
|
||||
*(exp(kUPlus) - pow3(kUPlus)/6 - 0.5*sqr(kUPlus) - kUPlus - 1);
|
||||
|
||||
scalar f = - Re + A/E_;
|
||||
|
||||
scalar df =
|
||||
(
|
||||
2*E_*uPlus
|
||||
+ exp(kUPlus)*(kUPlus + 1)
|
||||
- 2/3*pow3(kUPlus)
|
||||
- 1.5*sqr(kUPlus)
|
||||
- 2*kUPlus
|
||||
- 1
|
||||
)/E_;
|
||||
|
||||
scalar uPlusNew = uPlus - f/(df + ROOTVSMALL);
|
||||
error = mag((uPlus - uPlusNew)/uPlusNew);
|
||||
uPlus = uPlusNew;
|
||||
} while (error > tolerance_ && ++iter < maxIters_);
|
||||
|
||||
if (iter == maxIters_)
|
||||
{
|
||||
WarningIn("SpaldingsLaw::invertFunction()")
|
||||
<< "Newton iterations not converged:" << nl
|
||||
<< " iters = " << iter << ", error = " << error << endl;
|
||||
}
|
||||
|
||||
// Set new values - constrain u+ >= 0
|
||||
invertedTable_[i] = max(0, uPlus);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
Foam::tabulatedWallFunctions::SpaldingsLaw::SpaldingsLaw
|
||||
(
|
||||
const dictionary& dict,
|
||||
const polyMesh& mesh
|
||||
)
|
||||
:
|
||||
tabulatedWallFunction(dict, mesh, typeName),
|
||||
kappa_(readScalar(coeffDict_.lookup("kappa"))),
|
||||
E_(readScalar(coeffDict_.lookup("E")))
|
||||
{
|
||||
invertFunction();
|
||||
|
||||
if (debug)
|
||||
{
|
||||
writeData(Info);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
|
||||
|
||||
Foam::tabulatedWallFunctions::SpaldingsLaw::~SpaldingsLaw()
|
||||
{}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
|
||||
|
||||
Foam::scalar Foam::tabulatedWallFunctions::SpaldingsLaw::yPlus
|
||||
(
|
||||
const scalar uPlus
|
||||
) const
|
||||
{
|
||||
scalar kUPlus = min(kappa_*uPlus, 50);
|
||||
|
||||
return
|
||||
uPlus
|
||||
+ 1/E_*(exp(kUPlus) - pow3(kUPlus)/6 - 0.5*sqr(kUPlus) - kUPlus - 1);
|
||||
}
|
||||
|
||||
|
||||
Foam::scalar Foam::tabulatedWallFunctions::SpaldingsLaw::Re
|
||||
(
|
||||
const scalar uPlus
|
||||
) const
|
||||
{
|
||||
return uPlus*yPlus(uPlus);
|
||||
}
|
||||
|
||||
|
||||
void Foam::tabulatedWallFunctions::SpaldingsLaw::writeData(Ostream& os) const
|
||||
{
|
||||
if (invertedTable_.log10())
|
||||
{
|
||||
os << "log10(Re), y+, u+:" << endl;
|
||||
forAll(invertedTable_, i)
|
||||
{
|
||||
scalar uPlus = invertedTable_[i];
|
||||
scalar Re = ::log10(this->Re(uPlus));
|
||||
scalar yPlus = this->yPlus(uPlus);
|
||||
os << Re << ", " << yPlus << ", " << uPlus << endl;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
os << "Re, y+, u+:" << endl;
|
||||
forAll(invertedTable_, i)
|
||||
{
|
||||
scalar uPlus = invertedTable_[i];
|
||||
scalar Re = this->Re(uPlus);
|
||||
scalar yPlus = this->yPlus(uPlus);
|
||||
os << Re << ", " << yPlus << ", " << uPlus << endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,139 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2011 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::tabulatedWallFunctions::SpaldingsLaw
|
||||
|
||||
Description
|
||||
Computes U+ as a function of Reynolds number by inverting Spaldings law.
|
||||
|
||||
Example dictionary specification:
|
||||
|
||||
tabulatedWallFunction SpaldingsLaw;
|
||||
|
||||
// Output table info
|
||||
tableName uPlusWallFunctionData; // Output table name
|
||||
log10 yes; // Rey interpreted as log10(Rey)
|
||||
dx 0.2; // Interval log10(Rey)
|
||||
x0 -3; // Minimum log10(Rey)
|
||||
xMax 7; // Maximum log10(Rey)
|
||||
|
||||
SpaldingsLawCoeffs
|
||||
{
|
||||
kappa 0.41; // Von Karman constant
|
||||
E 9.8; // Law-of-the-wall E coefficient
|
||||
}
|
||||
|
||||
|
||||
SourceFiles
|
||||
SpaldingsLaw.C
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef SpaldingsLaw_H
|
||||
#define SpaldingsLaw_H
|
||||
|
||||
#include "tabulatedWallFunction.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
namespace tabulatedWallFunctions
|
||||
{
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class SpaldingsLaw Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
class SpaldingsLaw
|
||||
:
|
||||
public tabulatedWallFunction
|
||||
{
|
||||
protected:
|
||||
|
||||
// Protected data
|
||||
|
||||
//- Von Karman constant
|
||||
scalar kappa_;
|
||||
|
||||
//- Law-of-the-wall E coefficient
|
||||
scalar E_;
|
||||
|
||||
|
||||
// Newton iteration solution properties
|
||||
|
||||
//- Maximum number of iterations
|
||||
static const label maxIters_;
|
||||
|
||||
//- Tolerance
|
||||
static const scalar tolerance_;
|
||||
|
||||
|
||||
// Protected Member Functions
|
||||
|
||||
//- Invert the function
|
||||
virtual void invertFunction();
|
||||
|
||||
|
||||
public:
|
||||
|
||||
//- Run-time type information
|
||||
TypeName("SpaldingsLaw");
|
||||
|
||||
|
||||
// Constructors
|
||||
SpaldingsLaw(const dictionary& dict, const polyMesh& mesh);
|
||||
|
||||
//- Destructor
|
||||
virtual ~SpaldingsLaw();
|
||||
|
||||
|
||||
// Member Functions
|
||||
|
||||
// Access
|
||||
|
||||
//- Return y+ as a function of u+
|
||||
virtual scalar yPlus(const scalar uPlus) const;
|
||||
|
||||
//- Return Reynolds number as a function of u+
|
||||
virtual scalar Re(const scalar uPlus) const;
|
||||
|
||||
|
||||
// I-O
|
||||
|
||||
//- Write to Ostream
|
||||
virtual void writeData(Ostream& os) const;
|
||||
};
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace tabulatedWallFunctions
|
||||
} // End namespace Foam
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,256 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2011 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 "general.H"
|
||||
#include "addToRunTimeSelectionTable.H"
|
||||
#include "Tuple2.H"
|
||||
|
||||
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
namespace tabulatedWallFunctions
|
||||
{
|
||||
defineTypeNameAndDebug(general, 0);
|
||||
addToRunTimeSelectionTable
|
||||
(
|
||||
tabulatedWallFunction,
|
||||
general,
|
||||
dictionary
|
||||
);
|
||||
}
|
||||
|
||||
template<>
|
||||
const char* Foam::NamedEnum
|
||||
<
|
||||
Foam::tabulatedWallFunctions::general::interpolationType,
|
||||
1
|
||||
>::names[] =
|
||||
{
|
||||
"linear"
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
const
|
||||
Foam::NamedEnum<Foam::tabulatedWallFunctions::general::interpolationType, 1>
|
||||
Foam::tabulatedWallFunctions::general::interpolationTypeNames_;
|
||||
|
||||
|
||||
// * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * * //
|
||||
|
||||
void Foam::tabulatedWallFunctions::general::invertTable()
|
||||
{
|
||||
scalarList Rey(uPlus_.size(), 0.0);
|
||||
|
||||
// Calculate Reynolds number
|
||||
forAll(uPlus_, i)
|
||||
{
|
||||
Rey[i] = yPlus_[i]*uPlus_[i];
|
||||
if (invertedTable_.log10())
|
||||
{
|
||||
Rey[i] = ::log10(max(ROOTVSMALL, Rey[i]));
|
||||
}
|
||||
}
|
||||
|
||||
// Populate the U+ vs Re table
|
||||
forAll(invertedTable_, i)
|
||||
{
|
||||
scalar Re = i*invertedTable_.dx() + invertedTable_.x0();
|
||||
invertedTable_[i] = max(0, interpolate(Re, Rey, uPlus_));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Foam::scalar Foam::tabulatedWallFunctions::general::interpolate
|
||||
(
|
||||
const scalar xi,
|
||||
const scalarList& x,
|
||||
const scalarList& fx
|
||||
) const
|
||||
{
|
||||
switch (interpType_)
|
||||
{
|
||||
case itLinear:
|
||||
{
|
||||
if (xi <= x[0])
|
||||
{
|
||||
return fx[0];
|
||||
}
|
||||
else if (xi >= x.last())
|
||||
{
|
||||
return fx.last();
|
||||
}
|
||||
else
|
||||
{
|
||||
label i2 = 0;
|
||||
while (x[i2] < xi)
|
||||
{
|
||||
i2++;
|
||||
}
|
||||
label i1 = i2 - 1;
|
||||
|
||||
return (xi - x[i1])/(x[i2] - x[i1])*(fx[i2] - fx[i1]) + fx[i1];
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
FatalErrorIn
|
||||
(
|
||||
"tabulatedWallFunctions::general::interpolate"
|
||||
"("
|
||||
"const scalar, "
|
||||
"const scalarList&, "
|
||||
"const scalarList&"
|
||||
")"
|
||||
) << "Unknown interpolation method" << nl
|
||||
<< abort(FatalError);
|
||||
}
|
||||
}
|
||||
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
Foam::tabulatedWallFunctions::general::general
|
||||
(
|
||||
const dictionary& dict,
|
||||
const polyMesh& mesh
|
||||
)
|
||||
:
|
||||
tabulatedWallFunction(dict, mesh, typeName),
|
||||
interpType_(interpolationTypeNames_[coeffDict_.lookup("interpType")]),
|
||||
yPlus_(),
|
||||
uPlus_(),
|
||||
log10YPlus_(coeffDict_.lookup("log10YPlus")),
|
||||
log10UPlus_(coeffDict_.lookup("log10UPlus"))
|
||||
{
|
||||
List<Tuple2<scalar, scalar> > inputTable = coeffDict_.lookup("inputTable");
|
||||
if (inputTable.size() < 2)
|
||||
{
|
||||
FatalErrorIn
|
||||
(
|
||||
"tabulatedWallFunctions::general::general"
|
||||
"("
|
||||
"const dictionary&, "
|
||||
"const polyMesh&"
|
||||
")"
|
||||
) << "Input table must have at least 2 values" << nl
|
||||
<< exit(FatalError);
|
||||
}
|
||||
|
||||
yPlus_.setSize(inputTable.size());
|
||||
uPlus_.setSize(inputTable.size());
|
||||
|
||||
forAll(inputTable, i)
|
||||
{
|
||||
if (log10YPlus_)
|
||||
{
|
||||
yPlus_[i] = pow(10, inputTable[i].first());
|
||||
}
|
||||
else
|
||||
{
|
||||
yPlus_[i] = inputTable[i].first();
|
||||
}
|
||||
|
||||
if (log10UPlus_)
|
||||
{
|
||||
uPlus_[i] = pow(10, inputTable[i].second());
|
||||
}
|
||||
else
|
||||
{
|
||||
uPlus_[i] = inputTable[i].second();
|
||||
}
|
||||
}
|
||||
|
||||
invertTable();
|
||||
|
||||
if (debug)
|
||||
{
|
||||
writeData(Info);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
|
||||
|
||||
Foam::tabulatedWallFunctions::general::~general()
|
||||
{}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
|
||||
|
||||
Foam::scalar Foam::tabulatedWallFunctions::general::yPlus
|
||||
(
|
||||
const scalar uPlus
|
||||
) const
|
||||
{
|
||||
return interpolate(uPlus, uPlus_, yPlus_);
|
||||
}
|
||||
|
||||
|
||||
Foam::scalar Foam::tabulatedWallFunctions::general::Re
|
||||
(
|
||||
const scalar uPlus
|
||||
) const
|
||||
{
|
||||
return uPlus*yPlus(uPlus);
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * * //
|
||||
|
||||
void Foam::tabulatedWallFunctions::general::writeData(Ostream& os) const
|
||||
{
|
||||
if (invertedTable_.log10())
|
||||
{
|
||||
os << "log10(Re), y+, u+:" << endl;
|
||||
forAll(invertedTable_, i)
|
||||
{
|
||||
scalar uPlus = invertedTable_[i];
|
||||
scalar Re = ::log10(this->Re(uPlus));
|
||||
scalar yPlus = this->yPlus(uPlus);
|
||||
os << Re << ", " << yPlus << ", " << uPlus << endl;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
os << "Re, y+, u+:" << endl;
|
||||
forAll(invertedTable_, i)
|
||||
{
|
||||
scalar uPlus = invertedTable_[i];
|
||||
scalar Re = this->Re(uPlus);
|
||||
scalar yPlus = this->yPlus(uPlus);
|
||||
os << Re << ", " << yPlus << ", " << uPlus << endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,171 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2011 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::tabulatedWallFunctions::general
|
||||
|
||||
Description
|
||||
Computes U+ as a function of Reynolds number by inverting table of
|
||||
y+ vs U+
|
||||
|
||||
Example dictionary specification:
|
||||
|
||||
tabulatedWallFunction general;
|
||||
|
||||
// Output table info
|
||||
tableName uPlusWallFunctionData; // Output table name
|
||||
log10 yes; // Re interpreted as log10(Rey)
|
||||
dx 0.2; // Interval log10(Rey)
|
||||
x0 -3; // Minimum log10(Rey)
|
||||
xMax 7; // Maximum log10(Rey)
|
||||
|
||||
generalCoeffs
|
||||
{
|
||||
interpType linear; // Interpolation method
|
||||
log10YPlus true; // y+ values defined as log10(y+)
|
||||
log10UPlus true; // U+ values defined as log10(y+)
|
||||
inputTable
|
||||
(
|
||||
(yPlusValue0 uPlusValue0)
|
||||
...
|
||||
(yPlusValueN uPlusValueN)
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
|
||||
SourceFiles
|
||||
general.C
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef general_H
|
||||
#define general_H
|
||||
|
||||
#include "tabulatedWallFunction.H"
|
||||
#include "NamedEnum.H"
|
||||
#include "Switch.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
namespace tabulatedWallFunctions
|
||||
{
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class general Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
class general
|
||||
:
|
||||
public tabulatedWallFunction
|
||||
{
|
||||
public:
|
||||
|
||||
// Public data types
|
||||
|
||||
//- Enumeration listing available interpolation types
|
||||
enum interpolationType
|
||||
{
|
||||
itLinear
|
||||
};
|
||||
|
||||
static const NamedEnum<interpolationType, 1> interpolationTypeNames_;
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
// Protected data
|
||||
|
||||
//- Type of interpolation to apply when inverting the data set
|
||||
interpolationType interpType_;
|
||||
|
||||
//- Input y+ values
|
||||
List<scalar> yPlus_;
|
||||
|
||||
//- Input U+ values
|
||||
List<scalar> uPlus_;
|
||||
|
||||
//- Are y+ values entered as log10(y+)?
|
||||
Switch log10YPlus_;
|
||||
|
||||
//- Are U+ values entered as log10(U+)?
|
||||
Switch log10UPlus_;
|
||||
|
||||
|
||||
// Protected Member Functions
|
||||
|
||||
//- Invert the table
|
||||
virtual void invertTable();
|
||||
|
||||
//- Interpolate
|
||||
virtual scalar interpolate
|
||||
(
|
||||
const scalar xi,
|
||||
const scalarList& x,
|
||||
const scalarList& fx
|
||||
) const;
|
||||
|
||||
|
||||
public:
|
||||
|
||||
//- Run-time type information
|
||||
TypeName("general");
|
||||
|
||||
|
||||
// Constructors
|
||||
general(const dictionary& dict, const polyMesh& mesh);
|
||||
|
||||
//- Destructor
|
||||
virtual ~general();
|
||||
|
||||
|
||||
// Member Functions
|
||||
|
||||
// Access
|
||||
|
||||
//- Return y+ as a function of u+
|
||||
virtual scalar yPlus(const scalar uPlus) const;
|
||||
|
||||
//- Return Reynolds number as a function of u+
|
||||
virtual scalar Re(const scalar uPlus) const;
|
||||
|
||||
|
||||
// I-O
|
||||
|
||||
//- Write to Ostream
|
||||
virtual void writeData(Ostream& os) const;
|
||||
};
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace tabulatedWallFunctions
|
||||
} // End namespace Foam
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,86 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2011 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 "tabulatedWallFunction.H"
|
||||
#include "Time.H"
|
||||
|
||||
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
namespace tabulatedWallFunctions
|
||||
{
|
||||
defineTypeNameAndDebug(tabulatedWallFunction, 0);
|
||||
defineRunTimeSelectionTable(tabulatedWallFunction, dictionary);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
Foam::tabulatedWallFunctions::tabulatedWallFunction::tabulatedWallFunction
|
||||
(
|
||||
const dictionary& dict,
|
||||
const polyMesh& mesh,
|
||||
const word& name
|
||||
)
|
||||
:
|
||||
dict_(dict),
|
||||
mesh_(mesh),
|
||||
coeffDict_(dict.subDict(name + "Coeffs")),
|
||||
invertedTableName_(dict.lookup("invertedTableName")),
|
||||
invertedTable_(invertedTableName_, mesh_, dict, true)
|
||||
{}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
|
||||
|
||||
Foam::tabulatedWallFunctions::tabulatedWallFunction::~tabulatedWallFunction()
|
||||
{}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
|
||||
|
||||
void Foam::tabulatedWallFunctions::tabulatedWallFunction::write()
|
||||
{
|
||||
if (invertedTable_.log10())
|
||||
{
|
||||
invertedTable_.note() =
|
||||
"U+ as a function of log10(Re) computed using " + type();
|
||||
}
|
||||
else
|
||||
{
|
||||
invertedTable_.note() =
|
||||
"U+ as a function of Re computed using " + type();
|
||||
}
|
||||
|
||||
Info<< "Writing inverted table to\n " << invertedTable_.objectPath()
|
||||
<< endl;
|
||||
|
||||
invertedTable_.write();
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,147 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2011 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::tabulatedWallFunctions::tabulatedWallFunction
|
||||
|
||||
Description
|
||||
Base class for models that generate tabulated wall function data.
|
||||
|
||||
SourceFiles
|
||||
tabulatedWallFunction.C
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef tabulatedWallFunction_H
|
||||
#define tabulatedWallFunction_H
|
||||
|
||||
#include "dictionary.H"
|
||||
#include "polyMesh.H"
|
||||
#include "runTimeSelectionTables.H"
|
||||
#include "Switch.H"
|
||||
#include "uniformInterpolationTable.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
namespace tabulatedWallFunctions
|
||||
{
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class tabulatedWallFunction Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
class tabulatedWallFunction
|
||||
{
|
||||
protected:
|
||||
|
||||
// Proteced data
|
||||
|
||||
//- Main dictionary
|
||||
const dictionary dict_;
|
||||
|
||||
//- Reference to the mesh database
|
||||
const polyMesh& mesh_;
|
||||
|
||||
//- Coefficients dictionary
|
||||
const dictionary coeffDict_;
|
||||
|
||||
//- Name of inverted table
|
||||
word invertedTableName_;
|
||||
|
||||
//- Inverted table
|
||||
uniformInterpolationTable<scalar> invertedTable_;
|
||||
|
||||
|
||||
public:
|
||||
|
||||
//- Run-time type information
|
||||
TypeName("tabulatedWallFunction");
|
||||
|
||||
//- Declare runtime constructor selection table
|
||||
declareRunTimeSelectionTable
|
||||
(
|
||||
autoPtr,
|
||||
tabulatedWallFunction,
|
||||
dictionary,
|
||||
(
|
||||
const dictionary& dict,
|
||||
const polyMesh& mesh
|
||||
),
|
||||
(dict, mesh)
|
||||
);
|
||||
|
||||
//- Constructor
|
||||
tabulatedWallFunction
|
||||
(
|
||||
const dictionary& dict,
|
||||
const polyMesh& mesh,
|
||||
const word& name
|
||||
);
|
||||
|
||||
//- Destructor
|
||||
virtual ~tabulatedWallFunction();
|
||||
|
||||
|
||||
//- Selector
|
||||
static autoPtr<tabulatedWallFunction> New
|
||||
(
|
||||
const dictionary& dict,
|
||||
const polyMesh& mesh
|
||||
);
|
||||
|
||||
|
||||
// Member Functions
|
||||
|
||||
// Access
|
||||
|
||||
//- Return the inverted table name
|
||||
inline const word& invertedTableName() const;
|
||||
|
||||
//- Return the inverted table
|
||||
inline const uniformInterpolationTable<scalar>&
|
||||
invertedTable() const;
|
||||
|
||||
|
||||
// I-O
|
||||
|
||||
//- Write
|
||||
virtual void write();
|
||||
};
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace tabulatedWallFunctions
|
||||
} // End namespace Foam
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#include "tabulatedWallFunctionI.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,44 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2011 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 "tabulatedWallFunction.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
inline const Foam::word&
|
||||
Foam::tabulatedWallFunctions::tabulatedWallFunction::invertedTableName() const
|
||||
{
|
||||
return invertedTableName_;
|
||||
}
|
||||
|
||||
|
||||
inline const Foam::uniformInterpolationTable<Foam::scalar>&
|
||||
Foam::tabulatedWallFunctions::tabulatedWallFunction::invertedTable() const
|
||||
{
|
||||
return invertedTable_;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,70 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2011 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 "tabulatedWallFunction.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
namespace tabulatedWallFunctions
|
||||
{
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
autoPtr<tabulatedWallFunction> tabulatedWallFunction::New
|
||||
(
|
||||
const dictionary& dict,
|
||||
const polyMesh& mesh
|
||||
)
|
||||
{
|
||||
word twfTypeName = dict.lookup("tabulatedWallFunction");
|
||||
|
||||
Info<< "Selecting tabulatedWallFunction " << twfTypeName << endl;
|
||||
|
||||
dictionaryConstructorTable::iterator cstrIter =
|
||||
dictionaryConstructorTablePtr_->find(twfTypeName);
|
||||
|
||||
if (cstrIter == dictionaryConstructorTablePtr_->end())
|
||||
{
|
||||
FatalErrorIn
|
||||
(
|
||||
"tabulatedWallFunction::New(const dictionary&, const polyMesh&)"
|
||||
) << "Unknown tabulatedWallFunction type " << twfTypeName
|
||||
<< nl << nl << "Valid tabulatedWallFunction types are:" << nl
|
||||
<< dictionaryConstructorTablePtr_->toc()
|
||||
<< exit(FatalError);
|
||||
}
|
||||
|
||||
return autoPtr<tabulatedWallFunction>(cstrIter()(dict, mesh));
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace tabulatedWallFunctions
|
||||
} // End namespace Foam
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,37 @@
|
||||
/*--------------------------------*- 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;
|
||||
object wallFunctionDict;
|
||||
}
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
tabulatedWallFunction SpaldingsLaw;
|
||||
|
||||
invertedTableName uPlusWallFunctionData;
|
||||
|
||||
dx 0.2;
|
||||
|
||||
x0 -3;
|
||||
|
||||
xMax 7;
|
||||
|
||||
log10 yes;
|
||||
|
||||
bound yes;
|
||||
|
||||
SpaldingsLawCoeffs
|
||||
{
|
||||
kappa 0.41;
|
||||
E 9.8;
|
||||
}
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,67 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / 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/>.
|
||||
|
||||
Application
|
||||
wallFunctionTable
|
||||
|
||||
Description
|
||||
Generates a table suitable for use by tabulated wall functions.
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "fvCFD.H"
|
||||
#include "tabulatedWallFunction.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
#include "setRootCase.H"
|
||||
#include "createTime.H"
|
||||
#include "createMesh.H"
|
||||
|
||||
IOdictionary dict
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
"wallFunctionDict",
|
||||
runTime.constant(),
|
||||
mesh,
|
||||
IOobject::MUST_READ_IF_MODIFIED
|
||||
)
|
||||
);
|
||||
|
||||
autoPtr<tabulatedWallFunctions::tabulatedWallFunction>
|
||||
twf(tabulatedWallFunctions::tabulatedWallFunction::New(dict, mesh));
|
||||
|
||||
// twf->writeData(Info);
|
||||
|
||||
twf->write();
|
||||
|
||||
Info<< "End\n" << endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
Reference in New Issue
Block a user