Merge branch 'develop' of develop.openfoam.com:Development/OpenFOAM-dev-OpenCFD into develop

This commit is contained in:
mattijs
2015-11-26 16:27:25 +00:00
98 changed files with 4191 additions and 2356 deletions

View File

@ -1,9 +0,0 @@
const dictionary& potentialFlow
(
mesh.solutionDict().subDict("potentialFlow")
);
const int nNonOrthCorr
(
potentialFlow.lookupOrDefault<int>("nNonOrthogonalCorrectors", 0)
);

View File

@ -12,6 +12,7 @@ volVectorField U
mesh mesh
); );
// Initialise the velocity internal field to zero
U = dimensionedVector("0", U.dimensions(), vector::zero); U = dimensionedVector("0", U.dimensions(), vector::zero);
surfaceScalarField phi surfaceScalarField phi
@ -34,7 +35,9 @@ if (args.optionFound("initialiseUBCs"))
} }
// Default name for the pressure field // Construct a pressure field
// If it is available read it otherwise construct from the velocity BCs
// converting fixed-value BCs to zero-gradient and vice versa.
word pName("p"); word pName("p");
// Update name of the pressure field from the command-line option // Update name of the pressure field from the command-line option
@ -55,6 +58,9 @@ forAll(U.boundaryField(), patchi)
} }
} }
// Note that registerObject is false for the pressure field. The pressure
// field in this solver doesn't have a physical value during the solution.
// It shouldn't be looked up and used by sub models or boundary conditions.
Info<< "Constructing pressure field " << pName << nl << endl; Info<< "Constructing pressure field " << pName << nl << endl;
volScalarField p volScalarField p
( (
@ -64,13 +70,28 @@ volScalarField p
runTime.timeName(), runTime.timeName(),
mesh, mesh,
IOobject::READ_IF_PRESENT, IOobject::READ_IF_PRESENT,
IOobject::NO_WRITE IOobject::NO_WRITE,
false
), ),
mesh, mesh,
dimensionedScalar(pName, sqr(dimVelocity), 0), dimensionedScalar(pName, sqr(dimVelocity), 0),
pBCTypes pBCTypes
); );
label pRefCell = 0;
scalar pRefValue = 0.0;
if (args.optionFound("writep"))
{
setRefCell
(
p,
potentialFlow.dict(),
pRefCell,
pRefValue
);
}
Info<< "Constructing velocity potential field Phi\n" << endl; Info<< "Constructing velocity potential field Phi\n" << endl;
volScalarField Phi volScalarField Phi
( (

View File

@ -24,13 +24,64 @@ License
Application Application
potentialFoam potentialFoam
Description Group
Potential flow solver which solves for the velocity potential grpBasicSolvers
from which the flux-field is obtained and velocity field by reconstructing
the flux.
This application is particularly useful to generate starting fields for Description
Navier-Stokes codes. Potential flow solver.
\heading Solver details
The potential flow solution is typically employed to generate initial fields
for full Navier-Stokes codes. The flow is evolved using the equation:
\f[
\laplacian \Phi = \div(\vec{U})
\f]
Where:
\vartable
\Phi | Velocity potential [m2/s]
\vec{U} | Velocity [m/s]
\endvartable
The corresponding pressure field could be calculated from the divergence
of the Euler equation:
\f[
\laplacian p + \div(\div(\vec{U}\otimes\vec{U})) = 0
\f]
but this generates excessive pressure variation in regions of large
velocity gradient normal to the flow direction. A better option is to
calculate the pressure field corresponding to velocity variation along the
stream-lines:
\f[
\laplacian p + \div(\vec{F}\cdot\div(\vec{U}\otimes\vec{U})) = 0
\f]
where the flow direction tensor \f$\vec{F}\f$ is obtained from
\f[
\vec{F} = \hat{\vec{U}}\otimes\hat{\vec{U}}
\f]
\heading Required fields
\plaintable
U | Velocity [m/s]
\endplaintable
\heading Optional fields
\plaintable
p | Kinematic pressure [m2/s2]
Phi | Velocity potential [m2/s]
| Generated from p (if present) or U if not present
\endplaintable
\heading Options
\plaintable
-writep | write the Euler pressure
-writePhi | Write the final velocity potential
-initialiseUBCs | Update the velocity boundaries before solving for Phi
\endplaintable
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
@ -58,19 +109,13 @@ int main(int argc, char *argv[])
argList::addBoolOption argList::addBoolOption
( (
"writePhi", "writePhi",
"Write the velocity potential field" "Write the final velocity potential field"
); );
argList::addBoolOption argList::addBoolOption
( (
"writep", "writep",
"Calculate and write the pressure field" "Calculate and write the Euler pressure field"
);
argList::addBoolOption
(
"withFunctionObjects",
"execute functionObjects"
); );
#include "setRootCase.H" #include "setRootCase.H"
@ -137,7 +182,7 @@ int main(int argc, char *argv[])
Phi.write(); Phi.write();
} }
// Calculate the pressure field // Calculate the pressure field from the Euler equation
if (args.optionFound("writep")) if (args.optionFound("writep"))
{ {
Info<< nl << "Calculating approximate pressure field" << endl; Info<< nl << "Calculating approximate pressure field" << endl;

View File

@ -31,18 +31,66 @@ setFormat raw;
// dx : DX scalar or vector format // dx : DX scalar or vector format
// vtk : VTK ascii format // vtk : VTK ascii format
// raw : x y z value format for use with e.g. gnuplot 'splot'. // raw : x y z value format for use with e.g. gnuplot 'splot'.
// boundaryData: written in a form that can be used with timeVaryingMapped
// boundary conditions (move to constant/boundaryData)
// starcd : Star-CD format (geometry in .cel/.vrt, data in .usr)
// nastran : Nastran (.nas) format
// //
// Note: // Note:
// other formats such as obj, stl, etc can also be written (by proxy) // - other formats such as obj, stl, etc can also be written (by proxy)
// but without any values! // but without any values!
// - boundaryData format: typical use:
// - use a surfaces functionObject to sample a patch:
// type surfaces;
// surfaceFormat boundaryData;
// fields ( p );
// surfaces
// (
// inlet
// {
// type patch;
// patches (inpletPatch);
// interpolate false;
// }
// );
// - the boundaryData writer will write postProcessing/surfaces/inlet/
// - move this to constant/boundaryData/inlet of the destination case
// - use a timeVaryingMappedFixedValue bc to read&interpolate and use
// as fixedValue.
// - boundaryData: 'interpolate false' writes face centres, 'interpolate true'
// writes points. For 2D case the face centres might only be a single column
// so cannot be used in timeVaryingMapped with standard mapping (since
// uses triangulation to do interpolation).
surfaceFormat vtk; surfaceFormat vtk;
// optionally define extra controls for the output formats // Optionally define extra controls for the output formats
formatOptions formatOptions
{ {
ensight ensight
{ {
// ascii/binary format
format ascii; format ascii;
//collateTimes true; // write single file containing multiple timesteps
// (only for static surfaces)
}
nastran
{
// From OpenFOAM field name to Nastran field name
fields
(
(U PLOAD4)
(p PLOAD2)
);
// Optional scale
scale 1.0;
// Optional format
// short/long/free format
// short: scalar field width 8. default.
// long : scalar field width 16
// free : comma separated, field width according to writePrecision
// setting
format short; // short/long/free
} }
} }
@ -143,9 +191,19 @@ sets
type patchSeed; type patchSeed;
axis xyz; axis xyz;
patches (".*Wall.*"); patches (".*Wall.*");
// Number of points to seed. Divided amongst all processors according
// to fraction of patches they hold. // Subset patch faces by:
// 1. Number of points to seed. Divided amongst all processors
// according to fraction of patches they hold.
maxPoints 100; maxPoints 100;
// 2. Specified set of locations. This selects for every the specified
// point the nearest patch face. (in addition the number of points
// is also truncated by the maxPoints setting)
// The difference with patchCloud is that this selects patch
// face centres, not an arbitrary location on the face.
points ((0.049 0.099 0.005)(0.051 0.054 0.005));
} }
); );
@ -249,8 +307,10 @@ surfaces
isoValue 0.5; isoValue 0.5;
interpolate true; interpolate true;
//zone ABC; // Optional: zone only // zone ABC; // Optional: zone only
//exposedPatchName fixedWalls; // Optional: zone only // exposedPatchName fixedWalls; // Optional: zone only
// bounds (1 1 1)(2 2 2); // Optional: limit extent
// regularise false; // Optional: do not simplify // regularise false; // Optional: do not simplify
// mergeTol 1e-10; // Optional: fraction of mesh bounding box // mergeTol 1e-10; // Optional: fraction of mesh bounding box
@ -265,6 +325,9 @@ surfaces
isoValue 0.5; isoValue 0.5;
interpolate false; interpolate false;
regularise false; // do not simplify regularise false; // do not simplify
// bounds (1 1 1)(2 2 2); // Optional: limit extent
// mergeTol 1e-10; // Optional: fraction of mesh bounding box // mergeTol 1e-10; // Optional: fraction of mesh bounding box
// to merge points (default=1e-6) // to merge points (default=1e-6)
} }
@ -281,8 +344,10 @@ surfaces
} }
interpolate true; interpolate true;
//zone ABC; // Optional: zone only // zone ABC; // Optional: zone only
//exposedPatchName fixedWalls; // Optional: zone only // exposedPatchName fixedWalls; // Optional: zone only
// bounds (1 1 1)(2 2 2); // Optional: limit extent
// regularise false; // Optional: do not simplify // regularise false; // Optional: do not simplify
// mergeTol 1e-10; // Optional: fraction of mesh bounding box // mergeTol 1e-10; // Optional: fraction of mesh bounding box
@ -305,6 +370,8 @@ surfaces
// of isoSurfaceCell // of isoSurfaceCell
interpolate false; interpolate false;
regularise false; // Optional: do not simplify regularise false; // Optional: do not simplify
// bounds (1 1 1)(2 2 2); // Optional: limit extent
// mergeTol 1e-10; // Optional: fraction of mesh bounding box // mergeTol 1e-10; // Optional: fraction of mesh bounding box
// to merge points (default=1e-6) // to merge points (default=1e-6)
} }

View File

@ -0,0 +1,10 @@
//
// addRegionOption.H
// ~~~~~~~~~~~~~~~~~
Foam::argList::addOption
(
"regions",
"(name1 .. nameN)",
"specify alternative mesh regions"
);

View File

@ -38,6 +38,11 @@ Usage
\param -region \<name\> \n \param -region \<name\> \n
Specify an alternative mesh region. Specify an alternative mesh region.
\param -regions (\<name1\> \<name2\> .. \<namen\>) \n
Specify alternative mesh regions. The region names will be sorted
alphabetically and a single composite name will be created
\<nameX\>_\<nameY\>.._\<nameZ\>
On execution, the combined patch geometry (points and faces) are output On execution, the combined patch geometry (points and faces) are output
to the communications directory. to the communications directory.
@ -59,6 +64,7 @@ SeeAlso
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
#include "addRegionOption.H" #include "addRegionOption.H"
#include "addRegionsOption.H"
argList::validArgs.append("patchGroup"); argList::validArgs.append("patchGroup");
argList::addOption argList::addOption
( (
@ -68,16 +74,52 @@ int main(int argc, char *argv[])
); );
#include "setRootCase.H" #include "setRootCase.H"
#include "createTime.H" #include "createTime.H"
#include "createNamedMesh.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // wordList regionNames(1, fvMesh::defaultRegion);
if (!args.optionReadIfPresent("region", regionNames[0]))
{
args.optionReadIfPresent("regions", regionNames);
}
const wordRe patchGroup(args[1]); const wordRe patchGroup(args.argRead<wordRe>(1));
fileName commsDir(runTime.path()/"comms"); fileName commsDir(runTime.path()/"comms");
args.optionReadIfPresent("commsDir", commsDir); args.optionReadIfPresent("commsDir", commsDir);
externalCoupledFunctionObject::writeGeometry(mesh, commsDir, patchGroup);
// Make sure region names are in canonical order
stableSort(regionNames);
PtrList<const fvMesh> meshes(regionNames.size());
forAll(regionNames, i)
{
Info<< "Create mesh " << regionNames[i] << " for time = "
<< runTime.timeName() << nl << endl;
meshes.set
(
i,
new fvMesh
(
Foam::IOobject
(
regionNames[i],
runTime.timeName(),
runTime,
Foam::IOobject::MUST_READ
)
)
);
}
externalCoupledFunctionObject::writeGeometry
(
UPtrList<const fvMesh>(meshes),
commsDir,
patchGroup
);
Info<< "\nEnd\n" << endl; Info<< "\nEnd\n" << endl;

View File

@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2011 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -174,7 +174,7 @@ void Foam::IOerror::exit(const int)
jobInfo.exit(); jobInfo.exit();
} }
if (abort_) if (env("FOAM_ABORT"))
{ {
abort(); abort();
} }
@ -215,7 +215,7 @@ void Foam::IOerror::abort()
jobInfo.abort(); jobInfo.abort();
} }
if (abort_) if (env("FOAM_ABORT"))
{ {
Perr<< endl << *this << endl Perr<< endl << *this << endl
<< "\nFOAM aborting (FOAM_ABORT set)\n" << endl; << "\nFOAM aborting (FOAM_ABORT set)\n" << endl;

View File

@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2011-2014 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2014 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -40,7 +40,6 @@ Foam::error::error(const string& title)
functionName_("unknown"), functionName_("unknown"),
sourceFileName_("unknown"), sourceFileName_("unknown"),
sourceFileLineNumber_(0), sourceFileLineNumber_(0),
abort_(env("FOAM_ABORT")),
throwExceptions_(false), throwExceptions_(false),
messageStreamPtr_(new OStringStream()) messageStreamPtr_(new OStringStream())
{ {
@ -61,7 +60,6 @@ Foam::error::error(const dictionary& errDict)
functionName_(errDict.lookup("functionName")), functionName_(errDict.lookup("functionName")),
sourceFileName_(errDict.lookup("sourceFileName")), sourceFileName_(errDict.lookup("sourceFileName")),
sourceFileLineNumber_(readLabel(errDict.lookup("sourceFileLineNumber"))), sourceFileLineNumber_(readLabel(errDict.lookup("sourceFileLineNumber"))),
abort_(env("FOAM_ABORT")),
throwExceptions_(false), throwExceptions_(false),
messageStreamPtr_(new OStringStream()) messageStreamPtr_(new OStringStream())
{ {
@ -83,7 +81,6 @@ Foam::error::error(const error& err)
functionName_(err.functionName_), functionName_(err.functionName_),
sourceFileName_(err.sourceFileName_), sourceFileName_(err.sourceFileName_),
sourceFileLineNumber_(err.sourceFileLineNumber_), sourceFileLineNumber_(err.sourceFileLineNumber_),
abort_(err.abort_),
throwExceptions_(err.throwExceptions_), throwExceptions_(err.throwExceptions_),
messageStreamPtr_(new OStringStream(*err.messageStreamPtr_)) messageStreamPtr_(new OStringStream(*err.messageStreamPtr_))
{ {
@ -173,7 +170,7 @@ void Foam::error::exit(const int errNo)
jobInfo.exit(); jobInfo.exit();
} }
if (abort_) if (env("FOAM_ABORT"))
{ {
abort(); abort();
} }
@ -214,7 +211,7 @@ void Foam::error::abort()
jobInfo.abort(); jobInfo.abort();
} }
if (abort_) if (env("FOAM_ABORT"))
{ {
Perr<< endl << *this << endl Perr<< endl << *this << endl
<< "\nFOAM aborting (FOAM_ABORT set)\n" << endl; << "\nFOAM aborting (FOAM_ABORT set)\n" << endl;

View File

@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -78,11 +78,10 @@ protected:
string sourceFileName_; string sourceFileName_;
label sourceFileLineNumber_; label sourceFileLineNumber_;
bool abort_;
bool throwExceptions_; bool throwExceptions_;
OStringStream* messageStreamPtr_; OStringStream* messageStreamPtr_;
public: public:
// Constructors // Constructors

View File

@ -0,0 +1,242 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2015 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 "triangle.H"
#include "triPoints.H"
#include "plane.H"
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class Point, class PointRef>
template<class AboveOp, class BelowOp>
inline void Foam::triangle<Point, PointRef>::triSliceWithPlane
(
const plane& pl,
const triPoints& tri,
AboveOp& aboveOp,
BelowOp& belowOp
)
{
// distance to cutting plane
FixedList<scalar, 3> d;
// determine how many of the points are above the cutting plane
label nPos = 0;
label posI = -1;
label negI = -1;
forAll(tri, i)
{
d[i] = ((tri[i] - pl.refPoint()) & pl.normal());
if (d[i] > 0)
{
nPos++;
posI = i;
}
else
{
negI = i;
}
}
if (nPos == 3)
{
aboveOp(tri);
}
else if (nPos == 2)
{
// point under the plane
label i0 = negI;
// indices of remaining points
label i1 = d.fcIndex(i0);
label i2 = d.fcIndex(i1);
// determine the two intersection points
point p01 = planeIntersection(d, tri, i0, i1);
point p02 = planeIntersection(d, tri, i0, i2);
aboveOp(triPoints(tri[i1], tri[i2], p02));
aboveOp(triPoints(tri[i1], p02, p01));
belowOp(triPoints(tri[i0], p01, p02));
}
else if (nPos == 1)
{
// point above the plane
label i0 = posI;
// indices of remaining points
label i1 = d.fcIndex(i0);
label i2 = d.fcIndex(i1);
// determine the two intersection points
point p01 = planeIntersection(d, tri, i0, i1);
point p02 = planeIntersection(d, tri, i0, i2);
belowOp(triPoints(tri[i1], tri[i2], p02));
belowOp(triPoints(tri[i1], p02, p01));
aboveOp(triPoints(tri[i0], p01, p02));
}
else
{
// All below
belowOp(tri);
}
}
template<class Point, class PointRef>
template<class AboveOp, class BelowOp>
inline void Foam::triangle<Point, PointRef>::sliceWithPlane
(
const plane& pl,
AboveOp& aboveOp,
BelowOp& belowOp
) const
{
triSliceWithPlane(pl, triPoints(a_, b_, c_), aboveOp, belowOp);
}
template<class Point, class PointRef>
template<class InsideOp, class OutsideOp>
inline void Foam::triangle<Point, PointRef>::triangleOverlap
(
const vector& n,
const triangle<Point, PointRef>& tgt,
InsideOp& insideOp,
OutsideOp& outsideOp
) const
{
// There are two possibilities with this algorithm - we either cut
// the outside triangles with all the edges or not (and keep them
// as disconnected triangles). In the first case
// we cannot do any evaluation short cut so we've chosen not to re-cut
// the outside triangles.
triIntersectionList insideTrisA;
label nInsideA = 0;
storeOp insideOpA(insideTrisA, nInsideA);
triIntersectionList outsideTrisA;
label nOutsideA = 0;
storeOp outsideOpA(outsideTrisA, nOutsideA);
const triPoints thisTri(a_, b_, c_);
// Cut original triangle with tgt edge 0.
// From *this to insideTrisA, outsideTrisA.
{
scalar s = Foam::mag(tgt.b() - tgt.a());
const plane pl0(tgt.a(), tgt.b(), tgt.b() + s*n);
triSliceWithPlane(pl0, thisTri, insideOpA, outsideOpA);
}
// Shortcut if nothing cut
if (insideOpA.nTris_ == 0)
{
outsideOp(thisTri);
return;
}
if (outsideOpA.nTris_ == 0)
{
insideOp(thisTri);
return;
}
// Cut all triangles with edge 1.
// From insideTrisA to insideTrisB, outsideTrisA
triIntersectionList insideTrisB;
label nInsideB = 0;
storeOp insideOpB(insideTrisB, nInsideB);
//triIntersectionList outsideTrisB;
//label nOutsideB = 0;
//storeOp outsideOpB(outsideTrisB, nOutsideB);
{
scalar s = Foam::mag(tgt.c() - tgt.b());
const plane pl0(tgt.b(), tgt.c(), tgt.c() + s*n);
for (label i = 0; i < insideOpA.nTris_; i++)
{
const triPoints& tri = insideOpA.tris_[i];
triSliceWithPlane(pl0, tri, insideOpB, outsideOpA);
}
//// Recut outside triangles (not necessary if only interested in
//// intersection properties)
//for (label i = 0; i < outsideOpA.nTris_; i++)
//{
// const triPoints& tri = outsideOpA.tris_[i];
// triSliceWithPlane(pl0, tri, outsideOpB, outsideOpB);
//}
}
// Cut all triangles with edge 2.
// From insideTrisB to insideTrisA, outsideTrisA
{
scalar s = Foam::mag(tgt.a() - tgt.c());
const plane pl0(tgt.c(), tgt.a(), tgt.a() + s*n);
insideOpA.nTris_ = 0;
//outsideOpA.nTris_ = 0;
for (label i = 0; i < insideOpB.nTris_; i++)
{
const triPoints& tri = insideOpB.tris_[i];
triSliceWithPlane(pl0, tri, insideOpA, outsideOpA);
}
//// Recut outside triangles (not necessary if only interested in
//// intersection properties)
//for (label i = 0; i < outsideOpB.nTris_; i++)
//{
// const triPoints& tri = outsideOpB.tris_[i];
// triSliceWithPlane(pl0, tri, outsideOpA, outsideOpA);
//}
}
// Transfer from A to argument
for (label i = 0; i < insideOpA.nTris_; i++)
{
insideOp(insideOpA.tris_[i]);
}
for (label i = 0; i < outsideOpA.nTris_; i++)
{
outsideOp(outsideOpA.tris_[i]);
}
}
// ************************************************************************* //

View File

@ -2,7 +2,7 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2015 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -52,6 +52,8 @@ namespace Foam
class Istream; class Istream;
class Ostream; class Ostream;
class triPoints;
class plane;
// Forward declaration of friend functions and operators // Forward declaration of friend functions and operators
@ -71,6 +73,8 @@ inline Ostream& operator<<
const triangle<Point, PointRef>& const triangle<Point, PointRef>&
); );
typedef triangle<point, const point&> triPointRef;
/*---------------------------------------------------------------------------*\ /*---------------------------------------------------------------------------*\
Class triangle Declaration Class triangle Declaration
@ -79,27 +83,98 @@ inline Ostream& operator<<
template<class Point, class PointRef> template<class Point, class PointRef>
class triangle class triangle
{ {
public:
// Public typedefs
//- Storage type for triangles originating from intersecting triangle
// with another triangle
typedef FixedList<triPoints, 27> triIntersectionList;
//- Return types for classify
enum proxType
{
NONE,
POINT, // Close to point
EDGE // Close to edge
};
// Public classes
// Classes for use in sliceWithPlane. What to do with decomposition
// of triangle.
//- Dummy
class dummyOp
{
public:
inline void operator()(const triPoints&);
};
//- Sum resulting areas
class sumAreaOp
{
public:
scalar area_;
inline sumAreaOp();
inline void operator()(const triPoints&);
};
//- Store resulting tris
class storeOp
{
public:
triIntersectionList& tris_;
label& nTris_;
inline storeOp(triIntersectionList&, label&);
inline void operator()(const triPoints&);
};
private:
// Private data // Private data
PointRef a_, b_, c_; PointRef a_, b_, c_;
// Private Member Functions
//- Helper: calculate intersection point
inline static point planeIntersection
(
const FixedList<scalar, 3>& d,
const triPoints& t,
const label negI,
const label posI
);
//- Helper: slice triangle with plane
template<class AboveOp, class BelowOp>
inline static void triSliceWithPlane
(
const plane& pl,
const triPoints& tri,
AboveOp& aboveOp,
BelowOp& belowOp
);
public: public:
//- Return types for classify
enum proxType
{
NONE,
POINT, // Close to point
EDGE // Close to edge
};
// Constructors // Constructors
//- Construct from three points //- Construct from three points
inline triangle(const Point& a, const Point& b, const Point& c); inline triangle(const Point& a, const Point& b, const Point& c);
//- Construct from three points
inline triangle(const FixedList<Point, 3>&);
//- Construct from three points in the list of points //- Construct from three points in the list of points
// The indices could be from triFace etc. // The indices could be from triFace etc.
inline triangle inline triangle
@ -237,6 +312,27 @@ public:
pointHit& edgePoint pointHit& edgePoint
) const; ) const;
//- Decompose triangle into triangles above and below plane
template<class AboveOp, class BelowOp>
inline void sliceWithPlane
(
const plane& pl,
AboveOp& aboveOp,
BelowOp& belowOp
) const;
//- Decompose triangle into triangles inside and outside
// (with respect to user provided normal) other
// triangle.
template<class InsideOp, class OutsideOp>
inline void triangleOverlap
(
const vector& n,
const triangle<Point, PointRef>& tri,
InsideOp& insideOp,
OutsideOp& outsideOp
) const;
// IOstream operators // IOstream operators
@ -264,6 +360,12 @@ public:
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository
# include "triangle.C"
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif #endif
// ************************************************************************* // // ************************************************************************* //

View File

@ -2,7 +2,7 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2015 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -25,6 +25,7 @@ License
#include "IOstreams.H" #include "IOstreams.H"
#include "pointHit.H" #include "pointHit.H"
#include "triPoints.H"
#include "mathematicalConstants.H" #include "mathematicalConstants.H"
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
@ -43,6 +44,18 @@ inline Foam::triangle<Point, PointRef>::triangle
{} {}
template<class Point, class PointRef>
inline Foam::triangle<Point, PointRef>::triangle
(
const FixedList<Point, 3>& tri
)
:
a_(tri[0]),
b_(tri[1]),
c_(tri[2])
{}
template<class Point, class PointRef> template<class Point, class PointRef>
inline Foam::triangle<Point, PointRef>::triangle inline Foam::triangle<Point, PointRef>::triangle
( (
@ -804,6 +817,66 @@ inline Foam::pointHit Foam::triangle<Point, PointRef>::nearestPoint
} }
template<class Point, class PointRef>
inline void Foam::triangle<Point, PointRef>::dummyOp::operator()
(
const triPoints&
)
{}
template<class Point, class PointRef>
inline Foam::triangle<Point, PointRef>::sumAreaOp::sumAreaOp()
:
area_(0.0)
{}
template<class Point, class PointRef>
inline void Foam::triangle<Point, PointRef>::sumAreaOp::operator()
(
const triPoints& tri
)
{
area_ += triangle<Point, const Point&>(tri).mag();
}
template<class Point, class PointRef>
inline Foam::triangle<Point, PointRef>::storeOp::storeOp
(
triIntersectionList& tris,
label& nTris
)
:
tris_(tris),
nTris_(nTris)
{}
template<class Point, class PointRef>
inline void Foam::triangle<Point, PointRef>::storeOp::operator()
(
const triPoints& tri
)
{
tris_[nTris_++] = tri;
}
template<class Point, class PointRef>
inline Foam::point Foam::triangle<Point, PointRef>::planeIntersection
(
const FixedList<scalar, 3>& d,
const triPoints& t,
const label negI,
const label posI
)
{
return (d[posI]*t[negI] - d[negI]*t[posI])/(-d[negI] + d[posI]);
}
// * * * * * * * * * * * * * * * Ostream Operator * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * Ostream Operator * * * * * * * * * * * * * //
template<class Point, class PointRef> template<class Point, class PointRef>

View File

@ -33,8 +33,8 @@ SeeAlso
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#ifndef plane_H #ifndef planeExtrusion_H
#define plane_H #define planeExtrusion_H
#include "linearNormal.H" #include "linearNormal.H"

View File

@ -31,6 +31,7 @@ License
#include "volFields.H" #include "volFields.H"
#include "globalIndex.H" #include "globalIndex.H"
#include "fvMesh.H" #include "fvMesh.H"
#include "DynamicField.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
@ -65,11 +66,16 @@ Foam::fileName Foam::externalCoupledFunctionObject::baseDir() const
Foam::fileName Foam::externalCoupledFunctionObject::groupDir Foam::fileName Foam::externalCoupledFunctionObject::groupDir
( (
const fileName& commsDir, const fileName& commsDir,
const word& regionName, const word& regionGroupName,
const wordRe& groupName const wordRe& groupName
) )
{ {
fileName result(commsDir/regionName/string::validate<fileName>(groupName)); fileName result
(
commsDir
/regionGroupName
/string::validate<fileName>(groupName)
);
result.clean(); result.clean();
return result; return result;
@ -126,11 +132,11 @@ void Foam::externalCoupledFunctionObject::removeReadFiles() const
if (log_) Info<< type() << ": removing all read files" << endl; if (log_) Info<< type() << ": removing all read files" << endl;
forAll(regionNames_, regionI) forAll(regionGroupNames_, regionI)
{ {
const word& regionName = regionNames_[regionI]; const word& compName = regionGroupNames_[regionI];
const fvMesh& mesh = time_.lookupObject<fvMesh>(regionName);
const labelList& groups = regionToGroups_[regionName]; const labelList& groups = regionToGroups_[compName];
forAll(groups, i) forAll(groups, i)
{ {
label groupI = groups[i]; label groupI = groups[i];
@ -141,7 +147,7 @@ void Foam::externalCoupledFunctionObject::removeReadFiles() const
const word& fieldName = groupReadFields_[groupI][fieldI]; const word& fieldName = groupReadFields_[groupI][fieldI];
rm rm
( (
groupDir(commsDir_, mesh.dbDir(), groupName) groupDir(commsDir_, compName, groupName)
/ fieldName + ".in" / fieldName + ".in"
); );
} }
@ -159,22 +165,22 @@ void Foam::externalCoupledFunctionObject::removeWriteFiles() const
if (log_) Info<< type() << ": removing all write files" << endl; if (log_) Info<< type() << ": removing all write files" << endl;
forAll(regionNames_, regionI) forAll(regionGroupNames_, regionI)
{ {
const word& regionName = regionNames_[regionI]; const word& compName = regionGroupNames_[regionI];
const fvMesh& mesh = time_.lookupObject<fvMesh>(regionName);
const labelList& groups = regionToGroups_[regionName]; const labelList& groups = regionToGroups_[compName];
forAll(groups, i) forAll(groups, i)
{ {
label groupI = groups[i]; label groupI = groups[i];
const wordRe& groupName = groupNames_[groupI]; const wordRe& groupName = groupNames_[groupI];
forAll(groupWriteFields_[groupI], fieldI) forAll(groupReadFields_[groupI], fieldI)
{ {
const word& fieldName = groupWriteFields_[groupI][fieldI]; const word& fieldName = groupReadFields_[groupI][fieldI];
rm rm
( (
groupDir(commsDir_, mesh.dbDir(), groupName) groupDir(commsDir_, compName, groupName)
/ fieldName + ".out" / fieldName + ".out"
); );
} }
@ -376,12 +382,21 @@ void Foam::externalCoupledFunctionObject::readLines
void Foam::externalCoupledFunctionObject::writeGeometry void Foam::externalCoupledFunctionObject::writeGeometry
( (
const fvMesh& mesh, const UPtrList<const fvMesh>& meshes,
const fileName& commsDir, const fileName& commsDir,
const wordRe& groupName const wordRe& groupName
) )
{ {
fileName dir(groupDir(commsDir, mesh.dbDir(), groupName)); wordList regionNames(meshes.size());
forAll(meshes, i)
{
regionNames[i] = meshes[i].dbDir();
}
// Make sure meshes are provided in sorted order
checkOrder(regionNames);
fileName dir(groupDir(commsDir, compositeName(regionNames), groupName));
//if (log_) //if (log_)
{ {
@ -397,99 +412,210 @@ void Foam::externalCoupledFunctionObject::writeGeometry
osFacesPtr.reset(new OFstream(dir/"patchFaces")); osFacesPtr.reset(new OFstream(dir/"patchFaces"));
} }
const labelList patchIDs
(
mesh.boundaryMesh().patchSet
(
List<wordRe>(1, groupName)
).sortedToc()
);
forAll(patchIDs, i) DynamicList<face> allMeshesFaces;
DynamicField<point> allMeshesPoints;
forAll(meshes, meshI)
{ {
label patchI = patchIDs[i]; const fvMesh& mesh = meshes[meshI];
const polyPatch& p = mesh.boundaryMesh()[patchI]; const labelList patchIDs
(
mesh.boundaryMesh().patchSet
(
List<wordRe>(1, groupName)
).sortedToc()
);
// Count faces
label nFaces = 0;
forAll(patchIDs, i)
{
nFaces += mesh.boundaryMesh()[patchIDs[i]].size();
}
// Collect faces
DynamicList<label> allFaceIDs(nFaces);
forAll(patchIDs, i)
{
const polyPatch& p = mesh.boundaryMesh()[patchIDs[i]];
forAll(p, pI)
{
allFaceIDs.append(p.start()+pI);
}
}
// Construct overall patch
indirectPrimitivePatch allPatch
(
IndirectList<face>(mesh.faces(), allFaceIDs),
mesh.points()
);
labelList pointToGlobal; labelList pointToGlobal;
labelList uniquePointIDs; labelList uniquePointIDs;
mesh.globalData().mergePoints mesh.globalData().mergePoints
( (
p.meshPoints(), allPatch.meshPoints(),
p.meshPointMap(), allPatch.meshPointMap(),
pointToGlobal, pointToGlobal,
uniquePointIDs uniquePointIDs
); );
label procI = Pstream::myProcNo(); label procI = Pstream::myProcNo();
List<pointField> allPoints(Pstream::nProcs()); List<pointField> collectedPoints(Pstream::nProcs());
allPoints[procI] = pointField(mesh.points(), uniquePointIDs); collectedPoints[procI] = pointField(mesh.points(), uniquePointIDs);
Pstream::gatherList(allPoints); Pstream::gatherList(collectedPoints);
List<faceList> allFaces(Pstream::nProcs()); List<faceList> collectedFaces(Pstream::nProcs());
faceList& patchFaces = allFaces[procI]; faceList& patchFaces = collectedFaces[procI];
patchFaces = p.localFaces(); patchFaces = allPatch.localFaces();
forAll(patchFaces, faceI) forAll(patchFaces, faceI)
{ {
inplaceRenumber(pointToGlobal, patchFaces[faceI]); inplaceRenumber(pointToGlobal, patchFaces[faceI]);
} }
Pstream::gatherList(allFaces); Pstream::gatherList(collectedFaces);
if (Pstream::master()) if (Pstream::master())
{ {
pointField pts // Append and renumber
( label nPoints = allMeshesPoints.size();
ListListOps::combine<pointField>
(
allPoints,
accessOp<pointField>()
)
);
//if (log_) forAll(collectedPoints, procI)
{ {
Info<< typeName << ": for patch " << p.name() allMeshesPoints.append(collectedPoints[procI]);
<< " writing " << pts.size() << " points to "
<< osPointsPtr().name() << endl;
} }
face newFace;
// Write points forAll(collectedFaces, procI)
osPointsPtr() << patchKey.c_str() << p.name() << pts << endl;
faceList fcs
(
ListListOps::combine<faceList>(allFaces, accessOp<faceList>())
);
//if (log_)
{ {
Info<< typeName << ": for patch " << p.name() const faceList& procFaces = collectedFaces[procI];
<< " writing " << fcs.size() << " faces to "
<< osFacesPtr().name() << endl;
}
// Write faces forAll(procFaces, faceI)
osFacesPtr() << patchKey.c_str() << p.name() << fcs << endl; {
const face& f = procFaces[faceI];
newFace.setSize(f.size());
forAll(f, fp)
{
newFace[fp] = f[fp]+nPoints;
}
allMeshesFaces.append(newFace);
}
nPoints += collectedPoints[procI].size();
}
} }
//if (log_)
{
Info<< typeName << ": for mesh " << mesh.name()
<< " writing " << allMeshesPoints.size() << " points to "
<< osPointsPtr().name() << endl;
Info<< typeName << ": for mesh " << mesh.name()
<< " writing " << allMeshesFaces.size() << " faces to "
<< osFacesPtr().name() << endl;
}
}
// Write points
if (osPointsPtr.valid())
{
osPointsPtr() << allMeshesPoints << endl;
}
// Write faces
if (osFacesPtr.valid())
{
osFacesPtr() << allMeshesFaces << endl;
}
}
Foam::word Foam::externalCoupledFunctionObject::compositeName
(
const wordList& regionNames
)
{
if (regionNames.size() == 0)
{
FatalErrorIn
(
"externalCoupledFunctionObject::compositeName(const wordList&)"
) << "Empty regionNames" << abort(FatalError);
return word::null;
}
else if (regionNames.size() == 1)
{
if (regionNames[0] == polyMesh::defaultRegion)
{
// For compatibility with single region cases suppress single
// region name
return word("");
}
else
{
return regionNames[0];
}
}
else
{
// Enforce lexical ordering
checkOrder(regionNames);
word composite(regionNames[0]);
for (label i = 1; i < regionNames.size(); i++)
{
composite += "_" + regionNames[i];
}
return composite;
}
}
void Foam::externalCoupledFunctionObject::checkOrder
(
const wordList& regionNames
)
{
labelList order;
sortedOrder(regionNames, order);
if (order != identity(regionNames.size()))
{
FatalErrorIn
(
"externalCoupledFunctionObject::checkOrder(const wordList&)"
) << "regionNames " << regionNames << " not in alphabetical order :"
<< order << exit(FatalError);
} }
} }
void Foam::externalCoupledFunctionObject::readData() void Foam::externalCoupledFunctionObject::readData()
{ {
forAll(regionNames_, regionI) forAll(regionGroupNames_, regionI)
{ {
const word& regionName = regionNames_[regionI]; const word& compName = regionGroupNames_[regionI];
const labelList& groups = regionToGroups_[regionName]; const wordList& regionNames = regionGroupRegions_[regionI];
const fvMesh& mesh = time_.lookupObject<fvMesh>(regionName); // Get the meshes for the region-group
UPtrList<const fvMesh> meshes(regionNames.size());
forAll(regionNames, j)
{
const word& regionName = regionNames[j];
meshes.set(j, &time_.lookupObject<fvMesh>(regionName));
}
const labelList& groups = regionToGroups_[compName];
forAll(groups, i) forAll(groups, i)
{ {
label groupI = groups[i]; label groupI = groups[i];
const wordRe& groupName = groupNames_[groupI]; const wordRe& groupName = groupNames_[groupI];
const labelList& patchIDs = groupPatchIDs_[groupI];
const wordList& fieldNames = groupReadFields_[groupI]; const wordList& fieldNames = groupReadFields_[groupI];
forAll(fieldNames, fieldI) forAll(fieldNames, fieldI)
@ -498,37 +624,32 @@ void Foam::externalCoupledFunctionObject::readData()
bool ok = readData<scalar> bool ok = readData<scalar>
( (
mesh, meshes,
groupName, groupName,
patchIDs,
fieldName fieldName
); );
ok = ok || readData<vector> ok = ok || readData<vector>
( (
mesh, meshes,
groupName, groupName,
patchIDs,
fieldName fieldName
); );
ok = ok || readData<sphericalTensor> ok = ok || readData<sphericalTensor>
( (
mesh, meshes,
groupName, groupName,
patchIDs,
fieldName fieldName
); );
ok = ok || readData<symmTensor> ok = ok || readData<symmTensor>
( (
mesh, meshes,
groupName, groupName,
patchIDs,
fieldName fieldName
); );
ok = ok || readData<tensor> ok = ok || readData<tensor>
( (
mesh, meshes,
groupName, groupName,
patchIDs,
fieldName fieldName
); );
@ -538,7 +659,7 @@ void Foam::externalCoupledFunctionObject::readData()
( (
"void Foam::externalCoupledFunctionObject::readData()" "void Foam::externalCoupledFunctionObject::readData()"
) )
<< "Field " << fieldName << " in region " << mesh.name() << "Field " << fieldName << " in regions " << compName
<< " was not found." << endl; << " was not found." << endl;
} }
} }
@ -549,56 +670,59 @@ void Foam::externalCoupledFunctionObject::readData()
void Foam::externalCoupledFunctionObject::writeData() const void Foam::externalCoupledFunctionObject::writeData() const
{ {
forAll(regionNames_, regionI) forAll(regionGroupNames_, regionI)
{ {
const word& regionName = regionNames_[regionI]; const word& compName = regionGroupNames_[regionI];
const labelList& groups = regionToGroups_[regionName]; const wordList& regionNames = regionGroupRegions_[regionI];
const fvMesh& mesh = time_.lookupObject<fvMesh>(regionName); // Get the meshes for the region-group
UPtrList<const fvMesh> meshes(regionNames.size());
forAll(regionNames, j)
{
const word& regionName = regionNames[j];
meshes.set(j, &time_.lookupObject<fvMesh>(regionName));
}
const labelList& groups = regionToGroups_[compName];
forAll(groups, i) forAll(groups, i)
{ {
label groupI = groups[i]; label groupI = groups[i];
const wordRe& groupName = groupNames_[groupI]; const wordRe& groupName = groupNames_[groupI];
const labelList& patchIDs = groupPatchIDs_[groupI];
const wordList& fieldNames = groupWriteFields_[groupI]; const wordList& fieldNames = groupWriteFields_[groupI];
forAll(fieldNames, fieldI) forAll(fieldNames, fieldI)
{ {
const word& fieldName = fieldNames[fieldI]; const word& fieldName = fieldNames[fieldI];
bool ok = writeData<scalar> bool ok = writeData<scalar>
( (
mesh, meshes,
groupName, groupName,
patchIDs,
fieldName fieldName
); );
ok = ok || writeData<vector> ok = ok || writeData<vector>
( (
mesh, meshes,
groupName, groupName,
patchIDs,
fieldName fieldName
); );
ok = ok || writeData<sphericalTensor> ok = ok || writeData<sphericalTensor>
( (
mesh, meshes,
groupName, groupName,
patchIDs,
fieldName fieldName
); );
ok = ok || writeData<symmTensor> ok = ok || writeData<symmTensor>
( (
mesh, meshes,
groupName, groupName,
patchIDs,
fieldName fieldName
); );
ok = ok || writeData<tensor> ok = ok || writeData<tensor>
( (
mesh, meshes,
groupName, groupName,
patchIDs,
fieldName fieldName
); );
@ -608,7 +732,7 @@ void Foam::externalCoupledFunctionObject::writeData() const
( (
"void Foam::externalCoupledFunctionObject::writeData()" "void Foam::externalCoupledFunctionObject::writeData()"
) )
<< "Field " << fieldName << " in region " << mesh.name() << "Field " << fieldName << " in regions " << compName
<< " was not found." << endl; << " was not found." << endl;
} }
} }
@ -625,12 +749,20 @@ void Foam::externalCoupledFunctionObject::initialise()
} }
// Write the geometry if not already there // Write the geometry if not already there
forAll(regionNames_, regionI) forAll(regionGroupRegions_, i)
{ {
const word& regionName = regionNames_[regionI]; const word& compName = regionGroupNames_[i];
const labelList& groups = regionToGroups_[regionName]; const wordList& regionNames = regionGroupRegions_[i];
const fvMesh& mesh = time_.lookupObject<fvMesh>(regionName); // Get the meshes for the region-group
UPtrList<const fvMesh> meshes(regionNames.size());
forAll(regionNames, j)
{
const word& regionName = regionNames[j];
meshes.set(j, &time_.lookupObject<fvMesh>(regionName));
}
const labelList& groups = regionToGroups_[compName];
forAll(groups, i) forAll(groups, i)
{ {
@ -640,14 +772,16 @@ void Foam::externalCoupledFunctionObject::initialise()
bool exists = false; bool exists = false;
if (Pstream::master()) if (Pstream::master())
{ {
fileName dir(groupDir(commsDir_, mesh.dbDir(), groupName)); fileName dir(groupDir(commsDir_, compName, groupName));
exists = isFile(dir/"patchPoints") || isFile(dir/"patchFaces"); exists =
isFile(dir/"patchPoints")
|| isFile(dir/"patchFaces");
} }
if (!returnReduce(exists, orOp<bool>())) if (!returnReduce(exists, orOp<bool>()))
{ {
writeGeometry(mesh, commsDir_, groupName); writeGeometry(meshes, commsDir_, groupName);
} }
} }
} }
@ -802,6 +936,12 @@ bool Foam::externalCoupledFunctionObject::read(const dictionary& dict)
initByExternal_ = readBool(dict.lookup("initByExternal")); initByExternal_ = readBool(dict.lookup("initByExternal"));
log_ = dict.lookupOrDefault("log", false); log_ = dict.lookupOrDefault("log", false);
// Get names of all fvMeshes (and derived types)
wordList allRegionNames(time_.lookupClass<fvMesh>().sortedToc());
const dictionary& allRegionsDict = dict.subDict("regions"); const dictionary& allRegionsDict = dict.subDict("regions");
forAllConstIter(dictionary, allRegionsDict, iter) forAllConstIter(dictionary, allRegionsDict, iter)
@ -818,9 +958,16 @@ bool Foam::externalCoupledFunctionObject::read(const dictionary& dict)
<< exit(FatalIOError); << exit(FatalIOError);
} }
const word& regionName = iter().keyword(); const wordRe regionGroupName(iter().keyword());
const dictionary& regionDict = iter().dict(); const dictionary& regionDict = iter().dict();
regionNames_.append(regionName);
labelList regionIDs = findStrings(regionGroupName, allRegionNames);
const wordList regionNames(allRegionNames, regionIDs);
regionGroupNames_.append(compositeName(regionNames));
regionGroupRegions_.append(regionNames);
forAllConstIter(dictionary, regionDict, regionIter) forAllConstIter(dictionary, regionDict, regionIter)
{ {
@ -844,7 +991,7 @@ bool Foam::externalCoupledFunctionObject::read(const dictionary& dict)
HashTable<labelList>::iterator fnd = regionToGroups_.find HashTable<labelList>::iterator fnd = regionToGroups_.find
( (
regionName regionGroupNames_.last()
); );
if (fnd != regionToGroups_.end()) if (fnd != regionToGroups_.end())
{ {
@ -852,21 +999,15 @@ bool Foam::externalCoupledFunctionObject::read(const dictionary& dict)
} }
else else
{ {
regionToGroups_.insert(regionName, labelList(1, nGroups)); regionToGroups_.insert
(
regionGroupNames_.last(),
labelList(1, nGroups)
);
} }
groupNames_.append(groupName); groupNames_.append(groupName);
groupReadFields_.append(readFields); groupReadFields_.append(readFields);
groupWriteFields_.append(writeFields); groupWriteFields_.append(writeFields);
// Pre-calculate the patchIDs
const fvMesh& mesh = time_.lookupObject<fvMesh>(regionName);
groupPatchIDs_.append
(
mesh.boundaryMesh().patchSet
(
List<wordRe>(1, groupName)
).sortedToc()
);
} }
} }
@ -875,25 +1016,26 @@ bool Foam::externalCoupledFunctionObject::read(const dictionary& dict)
if (log_) if (log_)
{ {
Info<< type() << ": Communicating with regions:" << endl; Info<< type() << ": Communicating with regions:" << endl;
forAll(regionNames_, regionI) forAll(regionGroupNames_, rgI)
{ {
const word& regionName = regionNames_[regionI]; //const wordList& regionNames = regionGroupRegions_[rgI];
const fvMesh& mesh = time_.lookupObject<fvMesh>(regionName); const word& compName = regionGroupNames_[rgI];
Info<< "Region: " << mesh.name() << endl << incrIndent; Info<< "Region: " << compName << endl << incrIndent;
const labelList& groups = regionToGroups_[regionName]; const labelList& groups = regionToGroups_[compName];
forAll(groups, i) forAll(groups, i)
{ {
label groupI = groups[i]; label groupI = groups[i];
const wordRe& groupName = groupNames_[groupI]; const wordRe& groupName = groupNames_[groupI];
const labelList& patchIDs = groupPatchIDs_[groupI];
Info<< indent << "Group: " << groupName << "\t" Info<< indent << "patchGroup: " << groupName << "\t"
<< " patches: " << patchIDs << endl
<< incrIndent
<< indent << "Reading fields: " << groupReadFields_[groupI]
<< endl << endl
<< indent << "Writing fields: " << groupWriteFields_[groupI] << incrIndent
<< indent << "Reading fields: "
<< groupReadFields_[groupI]
<< endl
<< indent << "Writing fields: "
<< groupWriteFields_[groupI]
<< endl << endl
<< decrIndent; << decrIndent;
} }
@ -907,25 +1049,24 @@ bool Foam::externalCoupledFunctionObject::read(const dictionary& dict)
// should already be written - but just make sure // should already be written - but just make sure
if (Pstream::master()) if (Pstream::master())
{ {
forAll(regionNames_, regionI) forAll(regionGroupNames_, rgI)
{ {
const word& regionName = regionNames_[regionI]; const word& compName = regionGroupNames_[rgI];
const fvMesh& mesh = time_.lookupObject<fvMesh>(regionName);
const labelList& groups = regionToGroups_[regionName]; const labelList& groups = regionToGroups_[compName];
forAll(groups, i) forAll(groups, i)
{ {
label groupI = groups[i]; label groupI = groups[i];
const wordRe& groupName = groupNames_[groupI]; const wordRe& groupName = groupNames_[groupI];
fileName dir(groupDir(commsDir_, mesh.dbDir(), groupName)); fileName dir(groupDir(commsDir_, compName, groupName));
if (!isDir(dir)) if (!isDir(dir))
{ {
if (log_) if (log_)
{ {
Info<< type() << ": creating communications directory " Info<< type() << ": creating communications directory "
<< dir << endl; << dir << endl;
} }
mkDir(dir); mkDir(dir);
} }
} }

View File

@ -48,7 +48,10 @@ Description
which gets read/written on the master processor only. In the which gets read/written on the master processor only. In the
communications directory the structure will be communications directory the structure will be
<regionName>/<patchGroup>/<fieldName>.[in|out] <regionsName>/<patchGroup>/<fieldName>.[in|out]
(where regionsName is either the name of a single region or a composite
of multiple region names)
At start-up, the boundary creates a lock file, i.e.. At start-up, the boundary creates a lock file, i.e..
@ -58,13 +61,13 @@ Description
execution the boundary values are written to files (one per region, execution the boundary values are written to files (one per region,
per patch(group), per field), e.g. per patch(group), per field), e.g.
<regionName>/<patchGroup>/<fieldName>.out <regionsName>/<patchGroup>/<fieldName>.out
The lock file is then removed, instructing the external source to take The lock file is then removed, instructing the external source to take
control of the program execution. When ready, the external program control of the program execution. When ready, the external program
should create the return values, e.g. to files should create the return values, e.g. to files
<regionName>/<patchGroup>/<fieldName>.in <regionsName>/<patchGroup>/<fieldName>.in
... and then re-instate the lock file. The functionObject will then ... and then re-instate the lock file. The functionObject will then
read these values, apply them to the boundary conditions and pass read these values, apply them to the boundary conditions and pass
@ -82,7 +85,7 @@ Description
regions regions
{ {
region0 "(region1|region0)" // Name of region(s)
{ {
TPatchGroup // Name of patch(group) TPatchGroup // Name of patch(group)
{ {
@ -95,7 +98,7 @@ Description
\endverbatim \endverbatim
This reads/writes (on the master processor) the directory: This reads/writes (on the master processor) the directory:
comms/region0/TPatchGroup/ comms/region0_region1/TPatchGroup/
with contents: with contents:
patchPoints (collected points) patchPoints (collected points)
patchFaces (collected faces) patchFaces (collected faces)
@ -120,6 +123,7 @@ SourceFiles
#include "wordReList.H" #include "wordReList.H"
#include "scalarField.H" #include "scalarField.H"
#include "Switch.H" #include "Switch.H"
#include "UPtrList.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -167,18 +171,18 @@ class externalCoupledFunctionObject
//- Log flag //- Log flag
bool log_; bool log_;
//- Names of regions //- Names of (composite) regions
DynamicList<word> regionNames_; DynamicList<word> regionGroupNames_;
// Per region the indices of the group information // Per (composite) region the names of the regions
DynamicList<wordList> regionGroupRegions_;
// Per (composite) region the indices of the group information
HashTable<labelList> regionToGroups_; HashTable<labelList> regionToGroups_;
// Per group the names of the patches/patchGroups // Per group the names of the patches/patchGroups
DynamicList<wordRe> groupNames_; DynamicList<wordRe> groupNames_;
// Per group the indices of the patches
DynamicList<labelList> groupPatchIDs_;
// Per group the names of the fields to read // Per group the names of the fields to read
DynamicList<wordList> groupReadFields_; DynamicList<wordList> groupReadFields_;
@ -195,7 +199,7 @@ class externalCoupledFunctionObject
static fileName groupDir static fileName groupDir
( (
const fileName& commsDir, const fileName& commsDir,
const word& regionName, const word& regionsName,
const wordRe& groupName const wordRe& groupName
); );
@ -225,9 +229,8 @@ class externalCoupledFunctionObject
template<class Type> template<class Type>
bool readData bool readData
( (
const fvMesh& mesh, const UPtrList<const fvMesh>& meshes,
const wordRe& groupName, const wordRe& groupName,
const labelList& patchIDs,
const word& fieldName const word& fieldName
); );
//- Read data for all regions, all fields //- Read data for all regions, all fields
@ -237,9 +240,8 @@ class externalCoupledFunctionObject
template<class Type> template<class Type>
bool writeData bool writeData
( (
const fvMesh& mesh, const UPtrList<const fvMesh>& meshes,
const wordRe& groupName, const wordRe& groupName,
const labelList& patchIDs,
const word& fieldName const word& fieldName
) const; ) const;
@ -275,6 +277,7 @@ class externalCoupledFunctionObject
template<class Type> template<class Type>
static tmp<Field<Type> > gatherAndCombine(const Field<Type>& fld); static tmp<Field<Type> > gatherAndCombine(const Field<Type>& fld);
static void checkOrder(const wordList&);
//- Disallow default bitwise copy construc //- Disallow default bitwise copy construc
externalCoupledFunctionObject(const externalCoupledFunctionObject&); externalCoupledFunctionObject(const externalCoupledFunctionObject&);
@ -356,10 +359,14 @@ public:
// Other // Other
//- Create single name by appending words (in sorted order),
// separated by '_'
static word compositeName(const wordList&);
//- Write geometry for the group/patch //- Write geometry for the group/patch
static void writeGeometry static void writeGeometry
( (
const fvMesh& mesh, const UPtrList<const fvMesh>& meshes,
const fileName& commsDir, const fileName& commsDir,
const wordRe& groupName const wordRe& groupName
); );

View File

@ -40,25 +40,20 @@ License
template<class Type> template<class Type>
bool Foam::externalCoupledFunctionObject::readData bool Foam::externalCoupledFunctionObject::readData
( (
const fvMesh& mesh, const UPtrList<const fvMesh>& meshes,
const wordRe& groupName, const wordRe& groupName,
const labelList& patchIDs,
const word& fieldName const word& fieldName
) )
{ {
typedef GeometricField<Type, fvPatchField, volMesh> volFieldType; typedef GeometricField<Type, fvPatchField, volMesh> volFieldType;
typedef externalCoupledMixedFvPatchField<Type> patchFieldType; typedef externalCoupledMixedFvPatchField<Type> patchFieldType;
if (!mesh.foundObject<volFieldType>(fieldName)) wordList regionNames(meshes.size());
forAll(meshes, i)
{ {
return false; regionNames[i] = meshes[i].dbDir();
} }
const volFieldType& cvf = mesh.lookupObject<volFieldType>(fieldName);
const typename volFieldType::GeometricBoundaryField& bf =
cvf.boundaryField();
// File only opened on master; contains data for all processors, for all // File only opened on master; contains data for all processors, for all
// patchIDs. // patchIDs.
autoPtr<IFstream> masterFilePtr; autoPtr<IFstream> masterFilePtr;
@ -66,7 +61,7 @@ bool Foam::externalCoupledFunctionObject::readData
{ {
const fileName transferFile const fileName transferFile
( (
groupDir(commsDir_, mesh.dbDir(), groupName) groupDir(commsDir_, compositeName(regionNames), groupName)
/ fieldName + ".in" / fieldName + ".in"
); );
@ -82,181 +77,234 @@ bool Foam::externalCoupledFunctionObject::readData
( (
"void externalCoupledFunctionObject::readData" "void externalCoupledFunctionObject::readData"
"(" "("
"const fvMesh&, " "const UPtrList<const fvMesh>&, "
"const wordRe&, " "const wordRe&, "
"const labelList&, "
"const word&" "const word&"
")", ")",
masterFilePtr() masterFilePtr()
) << "Cannot open file for region " << mesh.name() ) << "Cannot open file for region " << compositeName(regionNames)
<< ", field " << fieldName << ", patches " << patchIDs << ", field " << fieldName
<< exit(FatalIOError); << exit(FatalIOError);
} }
} }
// Handle column-wise reading of patch data. Supports most easy types
forAll(patchIDs, i) label nFound = 0;
forAll(meshes, i)
{ {
label patchI = patchIDs[i]; const fvMesh& mesh = meshes[i];
if (isA<patchFieldType>(bf[patchI])) if (!mesh.foundObject<volFieldType>(fieldName))
{ {
// Explicit handling of externalCoupledObjectMixed bcs - they have continue;
// specialised reading routines.
patchFieldType& pf = const_cast<patchFieldType&>
(
refCast<const patchFieldType>
(
bf[patchI]
)
);
// Read from master into local stream
OStringStream os;
readLines
(
bf[patchI].size(), // number of lines to read
masterFilePtr,
os
);
// Pass responsability for all reading over to bc
pf.readData(IStringStream(os.str())());
// Update the value from the read coefficicient. Bypass any
// additional processing by derived type.
pf.patchFieldType::evaluate();
} }
else if (isA<mixedFvPatchField<Type> >(bf[patchI]))
nFound++;
const volFieldType& cvf = mesh.lookupObject<volFieldType>(fieldName);
const typename volFieldType::GeometricBoundaryField& bf =
cvf.boundaryField();
// Get the patches
const labelList patchIDs
(
mesh.boundaryMesh().patchSet
(
List<wordRe>(1, groupName)
).sortedToc()
);
// Handle column-wise reading of patch data. Supports most easy types
forAll(patchIDs, i)
{ {
// Read columns from file for label patchI = patchIDs[i];
// value, snGrad, refValue, refGrad, valueFraction
List<scalarField> data;
readColumns
(
bf[patchI].size(), // number of lines to read
4*pTraits<Type>::nComponents+1, // nColumns: 4*Type + 1*scalar
masterFilePtr,
data
);
mixedFvPatchField<Type>& pf = const_cast<mixedFvPatchField<Type>&> if (isA<patchFieldType>(bf[patchI]))
( {
refCast<const mixedFvPatchField<Type> > // Explicit handling of externalCoupledMixed bcs - they
// have specialised reading routines.
patchFieldType& pf = const_cast<patchFieldType&>
( (
bf[patchI] refCast<const patchFieldType>
) (
); bf[patchI]
)
);
// Transfer read data to bc. // Read from master into local stream
// Skip value, snGrad OStringStream os;
direction columnI = 2*pTraits<Type>::nComponents; readLines
Field<Type>& refValue = pf.refValue();
for (direction cmpt = 0; cmpt < pTraits<Type>::nComponents; cmpt++)
{
refValue.replace(cmpt, data[columnI++]);
}
Field<Type>& refGrad = pf.refGrad();
for (direction cmpt = 0; cmpt < pTraits<Type>::nComponents; cmpt++)
{
refGrad.replace(cmpt, data[columnI++]);
}
pf.valueFraction() = data[columnI];
// Update the value from the read coefficicient. Bypass any
// additional processing by derived type.
pf.mixedFvPatchField<Type>::evaluate();
}
else if (isA<fixedGradientFvPatchField<Type> >(bf[patchI]))
{
// Read columns for value and gradient
List<scalarField> data;
readColumns
(
bf[patchI].size(), // number of lines to read
2*pTraits<Type>::nComponents, // nColumns: Type
masterFilePtr,
data
);
fixedGradientFvPatchField<Type>& pf =
const_cast<fixedGradientFvPatchField<Type>&>
(
refCast<const fixedGradientFvPatchField<Type> >
( (
bf[patchI] bf[patchI].size(), // number of lines to read
) masterFilePtr,
); os
);
// Transfer gradient to bc // Pass responsability for all reading over to bc
Field<Type>& gradient = pf.gradient(); pf.readData(IStringStream(os.str())());
for (direction cmpt = 0; cmpt < pTraits<Type>::nComponents; cmpt++)
// Update the value from the read coefficicient. Bypass any
// additional processing by derived type.
pf.patchFieldType::evaluate();
}
else if (isA<mixedFvPatchField<Type> >(bf[patchI]))
{ {
gradient.replace(cmpt, data[pTraits<Type>::nComponents+cmpt]); // Read columns from file for
// value, snGrad, refValue, refGrad, valueFraction
List<scalarField> data;
readColumns
(
bf[patchI].size(), // number of lines to read
4*pTraits<Type>::nComponents+1, // nColumns: 4*Type+1*scalar
masterFilePtr,
data
);
mixedFvPatchField<Type>& pf =
const_cast<mixedFvPatchField<Type>&>
(
refCast<const mixedFvPatchField<Type> >
(
bf[patchI]
)
);
// Transfer read data to bc.
// Skip value, snGrad
direction columnI = 2*pTraits<Type>::nComponents;
Field<Type>& refValue = pf.refValue();
for
(
direction cmpt = 0;
cmpt < pTraits<Type>::nComponents;
cmpt++
)
{
refValue.replace(cmpt, data[columnI++]);
}
Field<Type>& refGrad = pf.refGrad();
for
(
direction cmpt = 0;
cmpt < pTraits<Type>::nComponents;
cmpt++
)
{
refGrad.replace(cmpt, data[columnI++]);
}
pf.valueFraction() = data[columnI];
// Update the value from the read coefficicient. Bypass any
// additional processing by derived type.
pf.mixedFvPatchField<Type>::evaluate();
}
else if (isA<fixedGradientFvPatchField<Type> >(bf[patchI]))
{
// Read columns for value and gradient
List<scalarField> data;
readColumns
(
bf[patchI].size(), // number of lines to read
2*pTraits<Type>::nComponents, // nColumns: Type
masterFilePtr,
data
);
fixedGradientFvPatchField<Type>& pf =
const_cast<fixedGradientFvPatchField<Type>&>
(
refCast<const fixedGradientFvPatchField<Type> >
(
bf[patchI]
)
);
// Transfer gradient to bc
Field<Type>& gradient = pf.gradient();
for
(
direction cmpt = 0;
cmpt < pTraits<Type>::nComponents;
cmpt++
)
{
gradient.replace
(
cmpt,
data[pTraits<Type>::nComponents+cmpt]
);
}
// Update the value from the read coefficicient. Bypass any
// additional processing by derived type.
pf.fixedGradientFvPatchField<Type>::evaluate();
}
else if (isA<fixedValueFvPatchField<Type> >(bf[patchI]))
{
// Read columns for value only
List<scalarField> data;
readColumns
(
bf[patchI].size(), // number of lines to read
pTraits<Type>::nComponents, // number of columns to read
masterFilePtr,
data
);
// Transfer read value to bc
Field<Type> value(bf[patchI].size());
for
(
direction cmpt = 0;
cmpt < pTraits<Type>::nComponents;
cmpt++
)
{
value.replace(cmpt, data[cmpt]);
}
fixedValueFvPatchField<Type>& pf =
const_cast<fixedValueFvPatchField<Type>&>
(
refCast<const fixedValueFvPatchField<Type> >
(
bf[patchI]
)
);
pf == value;
// Update the value from the read coefficicient. Bypass any
// additional processing by derived type.
pf.fixedValueFvPatchField<Type>::evaluate();
}
else
{
FatalErrorIn
(
"void externalCoupledFunctionObject::readData"
"("
"const UPtrList<const fvMesh>&, "
"const wordRe&, "
"const word&"
")"
)
<< "Unsupported boundary condition " << bf[patchI].type()
<< " for patch " << bf[patchI].patch().name()
<< " in region " << mesh.name()
<< exit(FatalError);
} }
// Update the value from the read coefficicient. Bypass any initialised_ = true;
// additional processing by derived type.
pf.fixedGradientFvPatchField<Type>::evaluate();
} }
else if (isA<fixedValueFvPatchField<Type> >(bf[patchI]))
{
// Read columns for value only
List<scalarField> data;
readColumns
(
bf[patchI].size(), // number of lines to read
pTraits<Type>::nComponents, // number of columns to read
masterFilePtr,
data
);
// Transfer read value to bc
Field<Type> value(bf[patchI].size());
for (direction cmpt = 0; cmpt < pTraits<Type>::nComponents; cmpt++)
{
value.replace(cmpt, data[cmpt]);
}
fixedValueFvPatchField<Type>& pf =
const_cast<fixedValueFvPatchField<Type>&>
(
refCast<const fixedValueFvPatchField<Type> >
(
bf[patchI]
)
);
pf == value;
// Update the value from the read coefficicient. Bypass any
// additional processing by derived type.
pf.fixedValueFvPatchField<Type>::evaluate();
}
else
{
FatalErrorIn
(
"void externalCoupledFunctionObject::readData"
"("
"const fvMesh&, "
"const wordRe&, "
"const labelList&, "
"const word&"
")"
)
<< "Unsupported boundary condition " << bf[patchI].type()
<< " for patch " << bf[patchI].patch().name()
<< " in region " << mesh.name()
<< exit(FatalError);
}
initialised_ = true;
} }
return true; return nFound > 0;
} }
@ -308,25 +356,20 @@ Foam::externalCoupledFunctionObject::gatherAndCombine
template<class Type> template<class Type>
bool Foam::externalCoupledFunctionObject::writeData bool Foam::externalCoupledFunctionObject::writeData
( (
const fvMesh& mesh, const UPtrList<const fvMesh>& meshes,
const wordRe& groupName, const wordRe& groupName,
const labelList& patchIDs,
const word& fieldName const word& fieldName
) const ) const
{ {
typedef GeometricField<Type, fvPatchField, volMesh> volFieldType; typedef GeometricField<Type, fvPatchField, volMesh> volFieldType;
typedef externalCoupledMixedFvPatchField<Type> patchFieldType; typedef externalCoupledMixedFvPatchField<Type> patchFieldType;
if (!mesh.foundObject<volFieldType>(fieldName)) wordList regionNames(meshes.size());
forAll(meshes, i)
{ {
return false; regionNames[i] = meshes[i].dbDir();
} }
const volFieldType& cvf = mesh.lookupObject<volFieldType>(fieldName);
const typename volFieldType::GeometricBoundaryField& bf =
cvf.boundaryField();
// File only opened on master; contains data for all processors, for all // File only opened on master; contains data for all processors, for all
// patchIDs // patchIDs
autoPtr<OFstream> masterFilePtr; autoPtr<OFstream> masterFilePtr;
@ -334,7 +377,7 @@ bool Foam::externalCoupledFunctionObject::writeData
{ {
const fileName transferFile const fileName transferFile
( (
groupDir(commsDir_, mesh.dbDir(), groupName) groupDir(commsDir_, compositeName(regionNames), groupName)
/ fieldName + ".out" / fieldName + ".out"
); );
@ -350,14 +393,13 @@ bool Foam::externalCoupledFunctionObject::writeData
( (
"externalCoupledFunctionObject::writeData" "externalCoupledFunctionObject::writeData"
"(" "("
"const fvMesh&, " "const UPtrList<const fvMesh>&, "
"const wordRe&, " "const wordRe&, "
"const labelList&, "
"const word&" "const word&"
") const", ") const",
masterFilePtr() masterFilePtr()
) << "Cannot open file for region " << mesh.name() ) << "Cannot open file for region " << compositeName(regionNames)
<< ", field " << fieldName << ", patches " << patchIDs << ", field " << fieldName
<< exit(FatalIOError); << exit(FatalIOError);
} }
} }
@ -365,94 +407,122 @@ bool Foam::externalCoupledFunctionObject::writeData
bool headerDone = false; bool headerDone = false;
// Handle column-wise writing of patch data. Supports most easy types label nFound = 0;
forAll(patchIDs, i)
forAll(meshes, i)
{ {
label patchI = patchIDs[i]; const fvMesh& mesh = meshes[i];
const globalIndex globalFaces(bf[patchI].size()); if (!mesh.foundObject<volFieldType>(fieldName))
if (isA<patchFieldType>(bf[patchI]))
{ {
// Explicit handling of externalCoupledObjectMixed bcs - they have continue;
// specialised writing routines }
const patchFieldType& pf = refCast<const patchFieldType> nFound++;
const volFieldType& cvf = mesh.lookupObject<volFieldType>(fieldName);
const typename volFieldType::GeometricBoundaryField& bf =
cvf.boundaryField();
// Get the patches
const labelList patchIDs
(
mesh.boundaryMesh().patchSet
( (
bf[patchI] List<wordRe>(1, groupName)
); ).sortedToc()
OStringStream os; );
// Pass responsibility for all writing over to bc // Handle column-wise writing of patch data. Supports most easy types
pf.writeData(os); forAll(patchIDs, i)
{
label patchI = patchIDs[i];
// Collect contributions from all processors and output them on const globalIndex globalFaces(bf[patchI].size());
// master
if (Pstream::master()) if (isA<patchFieldType>(bf[patchI]))
{ {
// Output master data first // Explicit handling of externalCoupledMixed bcs - they
if (!headerDone) // have specialised writing routines
{
pf.writeHeader(masterFilePtr());
headerDone = true;
}
masterFilePtr() << os.str().c_str();
for (label procI = 1; procI < Pstream::nProcs(); procI++) const patchFieldType& pf = refCast<const patchFieldType>
(
bf[patchI]
);
OStringStream os;
// Pass responsibility for all writing over to bc
pf.writeData(os);
// Collect contributions from all processors and output them on
// master
if (Pstream::master())
{ {
IPstream fromSlave(Pstream::scheduled, procI); // Output master data first
string str(fromSlave); if (!headerDone)
masterFilePtr() << str.c_str(); {
pf.writeHeader(masterFilePtr());
headerDone = true;
}
masterFilePtr() << os.str().c_str();
for (label procI = 1; procI < Pstream::nProcs(); procI++)
{
IPstream fromSlave(Pstream::scheduled, procI);
string str(fromSlave);
masterFilePtr() << str.c_str();
}
}
else
{
OPstream toMaster(Pstream::scheduled, Pstream::masterNo());
toMaster << os.str();
}
}
else if (isA<mixedFvPatchField<Type> >(bf[patchI]))
{
const mixedFvPatchField<Type>& pf =
refCast<const mixedFvPatchField<Type> >(bf[patchI]);
Field<Type> value(gatherAndCombine(pf));
Field<Type> snGrad(gatherAndCombine(pf.snGrad()()));
Field<Type> refValue(gatherAndCombine(pf.refValue()));
Field<Type> refGrad(gatherAndCombine(pf.refGrad()));
scalarField valueFraction(gatherAndCombine(pf.valueFraction()));
if (Pstream::master())
{
forAll(refValue, faceI)
{
masterFilePtr()
<< value[faceI] << token::SPACE
<< snGrad[faceI] << token::SPACE
<< refValue[faceI] << token::SPACE
<< refGrad[faceI] << token::SPACE
<< valueFraction[faceI] << nl;
}
} }
} }
else else
{ {
OPstream toMaster(Pstream::scheduled, Pstream::masterNo()); // Output the value and snGrad
toMaster << os.str(); Field<Type> value(gatherAndCombine(bf[patchI]));
} Field<Type> snGrad(gatherAndCombine(bf[patchI].snGrad()()));
} if (Pstream::master())
else if (isA<mixedFvPatchField<Type> >(bf[patchI]))
{
const mixedFvPatchField<Type>& pf =
refCast<const mixedFvPatchField<Type> >(bf[patchI]);
Field<Type> value(gatherAndCombine(pf));
Field<Type> snGrad(gatherAndCombine(pf.snGrad()()));
Field<Type> refValue(gatherAndCombine(pf.refValue()));
Field<Type> refGrad(gatherAndCombine(pf.refGrad()));
scalarField valueFraction(gatherAndCombine(pf.valueFraction()));
if (Pstream::master())
{
forAll(refValue, faceI)
{ {
masterFilePtr() forAll(value, faceI)
<< value[faceI] << token::SPACE {
<< snGrad[faceI] << token::SPACE masterFilePtr()
<< refValue[faceI] << token::SPACE << value[faceI] << token::SPACE
<< refGrad[faceI] << token::SPACE << snGrad[faceI] << nl;
<< valueFraction[faceI] << nl; }
}
}
}
else
{
// Output the value and snGrad
Field<Type> value(gatherAndCombine(bf[patchI]));
Field<Type> snGrad(gatherAndCombine(bf[patchI].snGrad()()));
if (Pstream::master())
{
forAll(value, faceI)
{
masterFilePtr()
<< value[faceI] << token::SPACE
<< snGrad[faceI] << nl;
} }
} }
} }
} }
return true; return nFound > 0;
} }

View File

@ -30,9 +30,8 @@ License
#include "treeDataFace.H" #include "treeDataFace.H"
#include "Time.H" #include "Time.H"
#include "meshTools.H" #include "meshTools.H"
//#include "Random.H"
// For 'facePoint' helper function only
#include "mappedPatchBase.H" #include "mappedPatchBase.H"
#include "indirectPrimitivePatch.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
@ -85,19 +84,145 @@ void Foam::patchSeedSet::calcSamples
} }
label totalSize = returnReduce(sz, sumOp<label>()); if (!rndGenPtr_.valid())
{
rndGenPtr_.reset(new Random(0));
}
Random& rndGen = rndGenPtr_();
if (selectedLocations_.size())
{
DynamicList<label> newPatchFaces(patchFaces.size());
// Find the nearest patch face
{
// 1. All processors find nearest local patch face for all
// selectedLocations
// All the info for nearest. Construct to miss
List<mappedPatchBase::nearInfo> nearest(selectedLocations_.size());
const indirectPrimitivePatch pp
(
IndirectList<face>(mesh().faces(), patchFaces),
mesh().points()
);
treeBoundBox patchBb
(
treeBoundBox(pp.points(), pp.meshPoints()).extend
(
rndGen,
1e-4
)
);
patchBb.min() -= point(ROOTVSMALL, ROOTVSMALL, ROOTVSMALL);
patchBb.max() += point(ROOTVSMALL, ROOTVSMALL, ROOTVSMALL);
indexedOctree<treeDataFace> boundaryTree
(
treeDataFace // all information needed to search faces
(
false, // do not cache bb
mesh(),
patchFaces // boundary faces only
),
patchBb, // overall search domain
8, // maxLevel
10, // leafsize
3.0 // duplicity
);
// Get some global dimension so all points are equally likely
// to be found
const scalar globalDistSqr
(
//magSqr
//(
// boundBox
// (
// pp.points(),
// pp.meshPoints(),
// true
// ).span()
//)
GREAT
);
forAll(selectedLocations_, sampleI)
{
const point& sample = selectedLocations_[sampleI];
pointIndexHit& nearInfo = nearest[sampleI].first();
nearInfo = boundaryTree.findNearest
(
sample,
globalDistSqr
);
if (!nearInfo.hit())
{
nearest[sampleI].second().first() = Foam::sqr(GREAT);
nearest[sampleI].second().second() =
Pstream::myProcNo();
}
else
{
point fc(pp[nearInfo.index()].centre(pp.points()));
nearInfo.setPoint(fc);
nearest[sampleI].second().first() = magSqr(fc-sample);
nearest[sampleI].second().second() =
Pstream::myProcNo();
}
}
// 2. Reduce on master. Select nearest processor.
// Find nearest. Combine on master.
Pstream::listCombineGather(nearest, mappedPatchBase::nearestEqOp());
Pstream::listCombineScatter(nearest);
// 3. Pick up my local faces that have won
forAll(nearest, sampleI)
{
if (nearest[sampleI].first().hit())
{
label procI = nearest[sampleI].second().second();
label index = nearest[sampleI].first().index();
if (procI == Pstream::myProcNo())
{
newPatchFaces.append(pp.addressing()[index]);
}
}
}
}
if (debug)
{
Pout<< "Found " << newPatchFaces.size()
<< " out of " << selectedLocations_.size()
<< " on local processor" << endl;
}
patchFaces.transfer(newPatchFaces);
}
// Shuffle and truncate if in random mode // Shuffle and truncate if in random mode
label totalSize = returnReduce(patchFaces.size(), sumOp<label>());
if (maxPoints_ < totalSize) if (maxPoints_ < totalSize)
{ {
// Check what fraction of maxPoints_ I need to generate locally. // Check what fraction of maxPoints_ I need to generate locally.
label myMaxPoints = label(scalar(sz)/totalSize*maxPoints_); label myMaxPoints =
label(scalar(patchFaces.size())/totalSize*maxPoints_);
rndGenPtr_.reset(new Random(123456)); labelList subset = identity(patchFaces.size());
Random& rndGen = rndGenPtr_();
labelList subset = identity(sz);
for (label iter = 0; iter < 4; iter++) for (label iter = 0; iter < 4; iter++)
{ {
forAll(subset, i) forAll(subset, i)
@ -115,7 +240,7 @@ void Foam::patchSeedSet::calcSamples
if (debug) if (debug)
{ {
Pout<< "In random mode : selected " << patchFaces.size() Pout<< "In random mode : selected " << patchFaces.size()
<< " faces out of " << sz << endl; << " faces out of " << patchFaces.size() << endl;
} }
} }
@ -135,6 +260,9 @@ void Foam::patchSeedSet::calcSamples
forAll(patchFaces, i) forAll(patchFaces, i)
{ {
label faceI = patchFaces[i]; label faceI = patchFaces[i];
// Slightly shift point in since on warped face face-diagonal
// decomposition might be outside cell for face-centre decomposition!
pointIndexHit info = mappedPatchBase::facePoint pointIndexHit info = mappedPatchBase::facePoint
( (
mesh(), mesh(),
@ -217,9 +345,15 @@ Foam::patchSeedSet::patchSeedSet
wordReList(dict.lookup("patches")) wordReList(dict.lookup("patches"))
) )
), ),
//searchDist_(readScalar(dict.lookup("maxDistance"))), maxPoints_(readLabel(dict.lookup("maxPoints"))),
//offsetDist_(readScalar(dict.lookup("offsetDist"))), selectedLocations_
maxPoints_(readLabel(dict.lookup("maxPoints"))) (
dict.lookupOrDefault<pointField>
(
"points",
pointField(0)
)
)
{ {
genSamples(); genSamples();

View File

@ -2,7 +2,7 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2012 OpenFOAM Foundation \\ / A nd | Copyright (C) 2012-2014 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -58,18 +58,15 @@ class patchSeedSet
//- Patches to sample //- Patches to sample
const labelHashSet patchSet_; const labelHashSet patchSet_;
// //- Maximum distance to look for nearest //- Maximum number of patch faces to seed (if in random subset mode)
// const scalar searchDist_;
//
// //- Offset distance
// const scalar offsetDist_;
//- Maximum number of patch faces to seed
const label maxPoints_; const label maxPoints_;
//- Random number generator (if maxPoints < num patch faces) //- Random number generator (if maxPoints < num patch faces)
autoPtr<Random> rndGenPtr_; autoPtr<Random> rndGenPtr_;
//- Patch faces to seed selected based on nearness to supplied points
const pointField selectedLocations_;
// Private Member Functions // Private Member Functions

View File

@ -2,7 +2,7 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2015 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -278,7 +278,8 @@ void Foam::distanceSurface::createGeometry()
cellDistance, cellDistance,
pointDistance_, pointDistance_,
distance_, distance_,
regularise_ regularise_,
bounds_
) )
); );
} }
@ -291,7 +292,8 @@ void Foam::distanceSurface::createGeometry()
cellDistance, cellDistance,
pointDistance_, pointDistance_,
distance_, distance_,
regularise_ regularise_,
bounds_
) )
); );
} }
@ -336,6 +338,7 @@ Foam::distanceSurface::distanceSurface
cell_(dict.lookupOrDefault("cell", true)), cell_(dict.lookupOrDefault("cell", true)),
regularise_(dict.lookupOrDefault("regularise", true)), regularise_(dict.lookupOrDefault("regularise", true)),
average_(dict.lookupOrDefault("average", false)), average_(dict.lookupOrDefault("average", false)),
bounds_(dict.lookupOrDefault("bounds", boundBox::greatBox)),
zoneKey_(keyType::null), zoneKey_(keyType::null),
needsUpdate_(true), needsUpdate_(true),
isoSurfCellPtr_(NULL), isoSurfCellPtr_(NULL),
@ -364,7 +367,8 @@ Foam::distanceSurface::distanceSurface
const bool signedDistance, const bool signedDistance,
const bool cell, const bool cell,
const Switch regularise, const Switch regularise,
const Switch average const Switch average,
const boundBox& bounds
) )
: :
sampledSurface(name, mesh, interpolate), sampledSurface(name, mesh, interpolate),
@ -390,6 +394,7 @@ Foam::distanceSurface::distanceSurface
cell_(cell), cell_(cell),
regularise_(regularise), regularise_(regularise),
average_(average), average_(average),
bounds_(bounds),
zoneKey_(keyType::null), zoneKey_(keyType::null),
needsUpdate_(true), needsUpdate_(true),
isoSurfCellPtr_(NULL), isoSurfCellPtr_(NULL),

View File

@ -75,6 +75,9 @@ class distanceSurface
//- Whether to recalculate cell values as average of point values //- Whether to recalculate cell values as average of point values
const Switch average_; const Switch average_;
//- Optional bounding box to trim triangles against
const boundBox bounds_;
//- If restricted to zones, name of this zone or a regular expression //- If restricted to zones, name of this zone or a regular expression
keyType zoneKey_; keyType zoneKey_;
@ -144,7 +147,8 @@ public:
const bool signedDistance, const bool signedDistance,
const bool cell, const bool cell,
const Switch regularise, const Switch regularise,
const Switch average const Switch average,
const boundBox& bounds = boundBox::greatBox
); );

File diff suppressed because it is too large Load Diff

View File

@ -2,7 +2,7 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2015 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -76,6 +76,8 @@ namespace Foam
{ {
class fvMesh; class fvMesh;
class plane;
class treeBoundBox;
/*---------------------------------------------------------------------------*\ /*---------------------------------------------------------------------------*\
Class isoSurface Declaration Class isoSurface Declaration
@ -116,10 +118,12 @@ class isoSurface
//- Regularise? //- Regularise?
const Switch regularise_; const Switch regularise_;
//- Optional bounds
const boundBox bounds_;
//- When to merge points //- When to merge points
const scalar mergeDistance_; const scalar mergeDistance_;
//- Whether face might be cut //- Whether face might be cut
List<cellCutType> faceCutType_; List<cellCutType> faceCutType_;
@ -135,6 +139,15 @@ class isoSurface
//- For every unmerged triangle point the point in the triSurface //- For every unmerged triangle point the point in the triSurface
labelList triPointMergeMap_; labelList triPointMergeMap_;
//- triSurface points that have weighted interpolation
DynamicList<label> interpolatedPoints_;
//- corresponding original, unmerged points
DynamicList<FixedList<label, 3> > interpolatedOldPoints_;
//- corresponding weights
DynamicList<FixedList<scalar, 3> > interpolationWeights_;
// Private Member Functions // Private Member Functions
@ -193,20 +206,8 @@ class isoSurface
const scalarField& pVals const scalarField& pVals
); );
static labelPair findCommonPoints
(
const labelledTri&,
const labelledTri&
);
static point calcCentre(const triSurface&); static point calcCentre(const triSurface&);
static pointIndexHit collapseSurface
(
pointField& localPoints,
DynamicList<labelledTri, 64>& localTris
);
//- Determine per cc whether all near cuts can be snapped to single //- Determine per cc whether all near cuts can be snapped to single
// point. // point.
void calcSnappedCc void calcSnappedCc
@ -323,6 +324,17 @@ class isoSurface
DynamicList<label>& triMeshCells DynamicList<label>& triMeshCells
) const; ) const;
template<class Type>
static tmp<Field<Type> > interpolate
(
const label nPoints,
const labelList& triPointMergeMap,
const labelList& interpolatedPoints,
const List<FixedList<label, 3> >& interpolatedOldPoints,
const List<FixedList<scalar, 3> >& interpolationWeights,
const DynamicList<Type>& unmergedValues
);
triSurface stitchTriPoints triSurface stitchTriPoints
( (
const bool checkDuplicates, const bool checkDuplicates,
@ -331,57 +343,38 @@ class isoSurface
labelList& triMap // merged to unmerged triangle labelList& triMap // merged to unmerged triangle
) const; ) const;
//- Trim triangle to planes
static void trimToPlanes
(
const PtrList<plane>& planes,
const triPointRef& tri,
DynamicList<point>& newTriPoints
);
//- Trim all triangles to box
static void trimToBox
(
const treeBoundBox& bb,
DynamicList<point>& triPoints,
DynamicList<label>& triMeshCells
);
//- Trim all triangles to box. Determine interpolation
// for existing and new points
static void trimToBox
(
const treeBoundBox& bb,
DynamicList<point>& triPoints,
DynamicList<label>& triMap,
labelList& triPointMap,
labelList& interpolatedPoints,
List<FixedList<label, 3> >& interpolatedOldPoints,
List<FixedList<scalar, 3> >& interpolationWeights
);
//- Check single triangle for (topological) validity //- Check single triangle for (topological) validity
static bool validTri(const triSurface&, const label); static bool validTri(const triSurface&, const label);
//- Determine edge-face addressing
void calcAddressing
(
const triSurface& surf,
List<FixedList<label, 3> >& faceEdges,
labelList& edgeFace0,
labelList& edgeFace1,
Map<labelList>& edgeFacesRest
) const;
//- Determine orientation
static void walkOrientation
(
const triSurface& surf,
const List<FixedList<label, 3> >& faceEdges,
const labelList& edgeFace0,
const labelList& edgeFace1,
const label seedTriI,
labelList& flipState
);
//- Orient surface
static void orientSurface
(
triSurface&,
const List<FixedList<label, 3> >& faceEdges,
const labelList& edgeFace0,
const labelList& edgeFace1,
const Map<labelList>& edgeFacesRest
);
//- Is triangle (given by 3 edges) not fully connected?
static bool danglingTriangle
(
const FixedList<label, 3>& fEdges,
const labelList& edgeFace1
);
//- Mark all non-fully connected triangles
static label markDanglingTriangles
(
const List<FixedList<label, 3> >& faceEdges,
const labelList& edgeFace0,
const labelList& edgeFace1,
const Map<labelList>& edgeFacesRest,
boolList& keepTriangles
);
static triSurface subsetMesh static triSurface subsetMesh
( (
const triSurface& s, const triSurface& s,
@ -392,6 +385,10 @@ class isoSurface
public: public:
//- Declare friendship with isoSurfaceCell to share some functionality
friend class isoSurfaceCell;
//- Runtime type information //- Runtime type information
TypeName("isoSurface"); TypeName("isoSurface");
@ -407,24 +404,19 @@ public:
const scalarField& pointIsoVals, const scalarField& pointIsoVals,
const scalar iso, const scalar iso,
const bool regularise, const bool regularise,
const boundBox& bounds = boundBox::greatBox,
const scalar mergeTol = 1e-6 // fraction of bounding box const scalar mergeTol = 1e-6 // fraction of bounding box
); );
// Member Functions // Member Functions
//- For every face original cell in mesh //- For every triangle the original cell in mesh
const labelList& meshCells() const const labelList& meshCells() const
{ {
return meshCells_; return meshCells_;
} }
//- For every unmerged triangle point the point in the triSurface
const labelList& triPointMergeMap() const
{
return triPointMergeMap_;
}
//- Interpolates cCoords,pCoords. Uses the references to the original //- Interpolates cCoords,pCoords. Uses the references to the original
// fields used to create the iso surface. // fields used to create the iso surface.
template<class Type> template<class Type>

View File

@ -2,7 +2,7 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2015 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -30,6 +30,9 @@ License
#include "tetMatcher.H" #include "tetMatcher.H"
#include "syncTools.H" #include "syncTools.H"
#include "addToRunTimeSelectionTable.H" #include "addToRunTimeSelectionTable.H"
#include "Time.H"
#include "triPoints.H"
#include "isoSurface.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
@ -1222,144 +1225,6 @@ void Foam::isoSurfaceCell::calcAddressing
} }
//void Foam::isoSurfaceCell::walkOrientation
//(
// const triSurface& surf,
// const List<FixedList<label, 3> >& faceEdges,
// const labelList& edgeFace0,
// const labelList& edgeFace1,
// const label seedTriI,
// labelList& flipState
//)
//{
// // Do walk for consistent orientation.
// DynamicList<label> changedFaces(surf.size());
//
// changedFaces.append(seedTriI);
//
// while (changedFaces.size())
// {
// DynamicList<label> newChangedFaces(changedFaces.size());
//
// forAll(changedFaces, i)
// {
// label triI = changedFaces[i];
// const labelledTri& tri = surf[triI];
// const FixedList<label, 3>& fEdges = faceEdges[triI];
//
// forAll(fEdges, fp)
// {
// label edgeI = fEdges[fp];
//
// // my points:
// label p0 = tri[fp];
// label p1 = tri[tri.fcIndex(fp)];
//
// label nbrI =
// (
// edgeFace0[edgeI] != triI
// ? edgeFace0[edgeI]
// : edgeFace1[edgeI]
// );
//
// if (nbrI != -1 && flipState[nbrI] == -1)
// {
// const labelledTri& nbrTri = surf[nbrI];
//
// // nbr points
// label nbrFp = findIndex(nbrTri, p0);
// label nbrP1 = nbrTri[nbrTri.rcIndex(nbrFp)];
//
// bool sameOrientation = (p1 == nbrP1);
//
// if (flipState[triI] == 0)
// {
// flipState[nbrI] = (sameOrientation ? 0 : 1);
// }
// else
// {
// flipState[nbrI] = (sameOrientation ? 1 : 0);
// }
// newChangedFaces.append(nbrI);
// }
// }
// }
//
// changedFaces.transfer(newChangedFaces);
// }
//}
//
//
//void Foam::isoSurfaceCell::orientSurface
//(
// triSurface& surf,
// const List<FixedList<label, 3> >& faceEdges,
// const labelList& edgeFace0,
// const labelList& edgeFace1,
// const Map<labelList>& edgeFacesRest
//)
//{
// // -1 : unvisited
// // 0 : leave as is
// // 1 : flip
// labelList flipState(surf.size(), -1);
//
// label seedTriI = 0;
//
// while (true)
// {
// // Find first unvisited triangle
// for
// (
// ;
// seedTriI < surf.size() && flipState[seedTriI] != -1;
// seedTriI++
// )
// {}
//
// if (seedTriI == surf.size())
// {
// break;
// }
//
// // Note: Determine orientation of seedTriI?
// // for now assume it is ok
// flipState[seedTriI] = 0;
//
// walkOrientation
// (
// surf,
// faceEdges,
// edgeFace0,
// edgeFace1,
// seedTriI,
// flipState
// );
// }
//
// // Do actual flipping
// surf.clearOut();
// forAll(surf, triI)
// {
// if (flipState[triI] == 1)
// {
// labelledTri tri(surf[triI]);
//
// surf[triI][0] = tri[0];
// surf[triI][1] = tri[2];
// surf[triI][2] = tri[1];
// }
// else if (flipState[triI] == -1)
// {
// FatalErrorIn
// (
// "isoSurfaceCell::orientSurface(triSurface&, const label)"
// ) << "problem" << abort(FatalError);
// }
// }
//}
// Checks if triangle is connected through edgeI only. // Checks if triangle is connected through edgeI only.
bool Foam::isoSurfaceCell::danglingTriangle bool Foam::isoSurfaceCell::danglingTriangle
( (
@ -1517,6 +1382,7 @@ Foam::isoSurfaceCell::isoSurfaceCell
const scalarField& pVals, const scalarField& pVals,
const scalar iso, const scalar iso,
const bool regularise, const bool regularise,
const boundBox& bounds,
const scalar mergeTol const scalar mergeTol
) )
: :
@ -1524,6 +1390,7 @@ Foam::isoSurfaceCell::isoSurfaceCell
cVals_(cVals), cVals_(cVals),
pVals_(pVals), pVals_(pVals),
iso_(iso), iso_(iso),
bounds_(bounds),
mergeDistance_(mergeTol*mesh.bounds().mag()) mergeDistance_(mergeTol*mesh.bounds().mag())
{ {
if (debug) if (debug)
@ -1607,56 +1474,104 @@ Foam::isoSurfaceCell::isoSurfaceCell
} }
DynamicList<point> triPoints(nCutCells_);
DynamicList<label> triMeshCells(nCutCells_);
generateTriPoints
(
cVals,
pVals,
mesh_.cellCentres(),
mesh_.points(),
snappedPoints,
snappedCc,
snappedPoint,
triPoints,
triMeshCells
);
if (debug)
{ {
Pout<< "isoSurfaceCell : generated " << triMeshCells.size() DynamicList<point> triPoints(nCutCells_);
<< " unmerged triangles." << endl; DynamicList<label> triMeshCells(nCutCells_);
}
// Merge points and compact out non-valid triangles generateTriPoints
labelList triMap; // merged to unmerged triangle
triSurface::operator=
(
stitchTriPoints
( (
regularise, // check for duplicate tris cVals,
pVals,
mesh_.cellCentres(),
mesh_.points(),
snappedPoints,
snappedCc,
snappedPoint,
triPoints, triPoints,
triPointMergeMap_, // unmerged to merged point triMeshCells
triMap );
)
);
if (debug) if (debug)
{ {
Pout<< "isoSurfaceCell : generated " << triMap.size() Pout<< "isoSurfaceCell : generated " << triMeshCells.size()
<< " merged triangles." << endl; << " unmerged triangles." << endl;
}
label nOldPoints = triPoints.size();
// Trimmed to original triangle
DynamicList<label> trimTriMap;
// Trimmed to original point
labelList trimTriPointMap;
if (bounds_ != boundBox::greatBox)
{
isoSurface::trimToBox
(
treeBoundBox(bounds_),
triPoints, // new points
trimTriMap, // map from (new) triangle to original
trimTriPointMap, // map from (new) point to original
interpolatedPoints_, // labels of newly introduced points
interpolatedOldPoints_, // and their interpolation
interpolationWeights_
);
triMeshCells = labelField(triMeshCells, trimTriMap);
}
// Merge points and compact out non-valid triangles
labelList triMap;
triSurface::operator=
(
stitchTriPoints
(
regularise, // check for duplicate tris
triPoints,
triPointMergeMap_, // unmerged to merged point
triMap // merged to unmerged triangle
)
);
if (debug)
{
Pout<< "isoSurfaceCell : generated " << triMap.size()
<< " merged triangles." << endl;
}
if (bounds_ != boundBox::greatBox)
{
// Adjust interpolatedPoints_
inplaceRenumber(triPointMergeMap_, interpolatedPoints_);
// Adjust triPointMergeMap_
labelList newTriPointMergeMap(nOldPoints, -1);
forAll(trimTriPointMap, trimPointI)
{
label oldPointI = trimTriPointMap[trimPointI];
if (oldPointI >= 0)
{
label pointI = triPointMergeMap_[trimPointI];
if (pointI >= 0)
{
newTriPointMergeMap[oldPointI] = pointI;
}
}
}
triPointMergeMap_.transfer(newTriPointMergeMap);
}
meshCells_.setSize(triMap.size());
forAll(triMap, i)
{
meshCells_[i] = triMeshCells[triMap[i]];
}
} }
meshCells_.setSize(triMap.size());
forAll(triMap, i)
{
meshCells_[i] = triMeshCells[triMap[i]];
}
if (debug) if (debug)
{ {
@ -1730,8 +1645,6 @@ Foam::isoSurfaceCell::isoSurfaceCell
meshCells_ = labelField(meshCells_, subsetTriMap); meshCells_ = labelField(meshCells_, subsetTriMap);
inplaceRenumber(reversePointMap, triPointMergeMap_); inplaceRenumber(reversePointMap, triPointMergeMap_);
} }
//orientSurface(*this, faceEdges, edgeFace0, edgeFace1, edgeFacesRest);
} }
} }

View File

@ -2,7 +2,7 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2015 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -48,6 +48,7 @@ SourceFiles
#include "labelPair.H" #include "labelPair.H"
#include "pointIndexHit.H" #include "pointIndexHit.H"
#include "PackedBoolList.H" #include "PackedBoolList.H"
#include "boundBox.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -55,6 +56,7 @@ namespace Foam
{ {
class polyMesh; class polyMesh;
class plane;
/*---------------------------------------------------------------------------*\ /*---------------------------------------------------------------------------*\
Class isoSurfaceCell Declaration Class isoSurfaceCell Declaration
@ -91,6 +93,9 @@ class isoSurfaceCell
//- isoSurfaceCell value //- isoSurfaceCell value
const scalar iso_; const scalar iso_;
//- Optional bounds
const boundBox bounds_;
//- When to merge points //- When to merge points
const scalar mergeDistance_; const scalar mergeDistance_;
@ -106,6 +111,15 @@ class isoSurfaceCell
//- For every unmerged triangle point the point in the triSurface //- For every unmerged triangle point the point in the triSurface
labelList triPointMergeMap_; labelList triPointMergeMap_;
//- triSurface points that have weighted interpolation
DynamicList<label> interpolatedPoints_;
//- corresponding original, unmerged points
DynamicList<FixedList<label, 3> > interpolatedOldPoints_;
//- corresponding weights
DynamicList<FixedList<scalar, 3> > interpolationWeights_;
// Private Member Functions // Private Member Functions
@ -214,19 +228,15 @@ class isoSurfaceCell
void generateTriPoints void generateTriPoints
( (
const DynamicList<Type>& snapped, const DynamicList<Type>& snapped,
const scalar isoVal0,
const scalar s0, const scalar s0,
const Type& p0, const Type& p0,
const label p0Index, const label p0Index,
const scalar isoVal1,
const scalar s1, const scalar s1,
const Type& p1, const Type& p1,
const label p1Index, const label p1Index,
const scalar isoVal2,
const scalar s2, const scalar s2,
const Type& p2, const Type& p2,
const label p2Index, const label p2Index,
const scalar isoVal3,
const scalar s3, const scalar s3,
const Type& p3, const Type& p3,
const label p3Index, const label p3Index,
@ -271,27 +281,6 @@ class isoSurfaceCell
Map<labelList>& edgeFacesRest Map<labelList>& edgeFacesRest
) const; ) const;
////- Determine orientation
//static void walkOrientation
//(
// const triSurface& surf,
// const List<FixedList<label, 3> >& faceEdges,
// const labelList& edgeFace0,
// const labelList& edgeFace1,
// const label seedTriI,
// labelList& flipState
//);
////- Orient surface
//static void orientSurface
//(
// triSurface&,
// const List<FixedList<label, 3> >& faceEdges,
// const labelList& edgeFace0,
// const labelList& edgeFace1,
// const Map<labelList>& edgeFacesRest
//);
//- Is triangle (given by 3 edges) not fully connected? //- Is triangle (given by 3 edges) not fully connected?
static bool danglingTriangle static bool danglingTriangle
( (
@ -317,8 +306,6 @@ class isoSurfaceCell
labelList& newToOldPoints labelList& newToOldPoints
); );
//- Combine all triangles inside a cell into a minimal triangulation
void combineCellTriangles();
public: public:
@ -336,6 +323,7 @@ public:
const scalarField& pointValues, const scalarField& pointValues,
const scalar iso, const scalar iso,
const bool regularise, const bool regularise,
const boundBox& bounds = boundBox::greatBox,
const scalar mergeTol = 1e-6 // fraction of bounding box const scalar mergeTol = 1e-6 // fraction of bounding box
); );
@ -348,24 +336,6 @@ public:
return meshCells_; return meshCells_;
} }
//- For every unmerged triangle point the point in the triSurface
const labelList triPointMergeMap() const
{
return triPointMergeMap_;
}
//- Interpolates cCoords,pCoords. Takes the original fields
// used to create the iso surface.
template<class Type>
tmp<Field<Type> > interpolate
(
const scalarField& cVals,
const scalarField& pVals,
const Field<Type>& cCoords,
const Field<Type>& pCoords
) const;
//- Interpolates cCoords,pCoords. //- Interpolates cCoords,pCoords.
template<class Type> template<class Type>
tmp<Field<Type> > interpolate tmp<Field<Type> > interpolate

View File

@ -26,6 +26,7 @@ License
#include "isoSurfaceCell.H" #include "isoSurfaceCell.H"
#include "polyMesh.H" #include "polyMesh.H"
#include "tetMatcher.H" #include "tetMatcher.H"
#include "isoSurface.H"
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
@ -76,22 +77,18 @@ void Foam::isoSurfaceCell::generateTriPoints
( (
const DynamicList<Type>& snapped, const DynamicList<Type>& snapped,
const scalar isoVal0,
const scalar s0, const scalar s0,
const Type& p0, const Type& p0,
const label p0Index, const label p0Index,
const scalar isoVal1,
const scalar s1, const scalar s1,
const Type& p1, const Type& p1,
const label p1Index, const label p1Index,
const scalar isoVal2,
const scalar s2, const scalar s2,
const Type& p2, const Type& p2,
const label p2Index, const label p2Index,
const scalar isoVal3,
const scalar s3, const scalar s3,
const Type& p3, const Type& p3,
const label p3Index, const label p3Index,
@ -124,160 +121,196 @@ void Foam::isoSurfaceCell::generateTriPoints
case 0x0F: case 0x0F:
break; break;
case 0x0E:
case 0x01: case 0x01:
case 0x0E:
{ {
// 0 is common point. Orient such that normal points in positive pts.append
// gradient direction (
if (isoVal0 >= isoVal1) generatePoint(snapped,s0,p0,p0Index,s1,p1,p1Index)
);
pts.append
(
generatePoint(snapped,s0,p0,p0Index,s2,p2,p2Index)
);
pts.append
(
generatePoint(snapped,s0,p0,p0Index,s3,p3,p3Index)
);
if (triIndex == 0x0E)
{ {
pts.append(generatePoint(snapped,s0,p0,p0Index,s1,p1,p1Index)); // Flip normals
pts.append(generatePoint(snapped,s0,p0,p0Index,s2,p2,p2Index)); label sz = pts.size();
pts.append(generatePoint(snapped,s0,p0,p0Index,s3,p3,p3Index)); Swap(pts[sz-2], pts[sz-1]);
}
else
{
pts.append(generatePoint(snapped,s0,p0,p0Index,s2,p2,p2Index));
pts.append(generatePoint(snapped,s0,p0,p0Index,s1,p1,p1Index));
pts.append(generatePoint(snapped,s0,p0,p0Index,s3,p3,p3Index));
} }
} }
break; break;
case 0x0D:
case 0x02: case 0x02:
case 0x0D:
{ {
// 1 is common point pts.append
if (isoVal1 >= isoVal0) (
generatePoint(snapped,s1,p1,p1Index,s0,p0,p0Index)
);
pts.append
(
generatePoint(snapped,s1,p1,p1Index,s3,p3,p3Index)
);
pts.append
(
generatePoint(snapped,s1,p1,p1Index,s2,p2,p2Index)
);
if (triIndex == 0x0D)
{ {
pts.append(generatePoint(snapped,s1,p1,p1Index,s0,p0,p0Index)); // Flip normals
pts.append(generatePoint(snapped,s1,p1,p1Index,s3,p3,p3Index)); label sz = pts.size();
pts.append(generatePoint(snapped,s1,p1,p1Index,s2,p2,p2Index)); Swap(pts[sz-2], pts[sz-1]);
}
else
{
pts.append(generatePoint(snapped,s1,p1,p1Index,s3,p3,p3Index));
pts.append(generatePoint(snapped,s1,p1,p1Index,s0,p0,p0Index));
pts.append(generatePoint(snapped,s1,p1,p1Index,s2,p2,p2Index));
} }
} }
break; break;
case 0x0C:
case 0x03: case 0x03:
case 0x0C:
{ {
Type s02 = generatePoint(snapped,s0,p0,p0Index,s2,p2,p2Index); Type p0p2 =
Type s13 = generatePoint(snapped,s1,p1,p1Index,s3,p3,p3Index); generatePoint(snapped,s0,p0,p0Index,s2,p2,p2Index);
Type p1p3 =
generatePoint(snapped,s1,p1,p1Index,s3,p3,p3Index);
if (isoVal0 >= isoVal3) pts.append
(
generatePoint(snapped,s0,p0,p0Index,s3,p3,p3Index)
);
pts.append(p1p3);
pts.append(p0p2);
pts.append(p1p3);
pts.append
(
generatePoint(snapped,s1,p1,p1Index,s2,p2,p2Index)
);
pts.append(p0p2);
if (triIndex == 0x0C)
{ {
pts.append(generatePoint(snapped,s0,p0,p0Index,s3,p3,p3Index)); // Flip normals
pts.append(s02); label sz = pts.size();
pts.append(s13); Swap(pts[sz-5], pts[sz-4]);
pts.append(s13); Swap(pts[sz-2], pts[sz-1]);
pts.append(generatePoint(snapped,s1,p1,p1Index,s2,p2,p2Index));
pts.append(s02);
}
else
{
pts.append(s02);
pts.append(generatePoint(snapped,s0,p0,p0Index,s3,p3,p3Index));
pts.append(s13);
pts.append(generatePoint(snapped,s1,p1,p1Index,s2,p2,p2Index));
pts.append(s13);
pts.append(s02);
} }
} }
break; break;
case 0x0B:
case 0x04: case 0x04:
case 0x0B:
{ {
// 2 is common point pts.append
if (isoVal2 >= isoVal0) (
generatePoint(snapped,s2,p2,p2Index,s0,p0,p0Index)
);
pts.append
(
generatePoint(snapped,s2,p2,p2Index,s1,p1,p1Index)
);
pts.append
(
generatePoint(snapped,s2,p2,p2Index,s3,p3,p3Index)
);
if (triIndex == 0x0B)
{ {
pts.append(generatePoint(snapped,s2,p2,p2Index,s0,p0,p0Index)); // Flip normals
pts.append(generatePoint(snapped,s2,p2,p2Index,s1,p1,p1Index)); label sz = pts.size();
pts.append(generatePoint(snapped,s2,p2,p2Index,s3,p3,p3Index)); Swap(pts[sz-2], pts[sz-1]);
}
else
{
pts.append(generatePoint(snapped,s2,p2,p2Index,s1,p1,p1Index));
pts.append(generatePoint(snapped,s2,p2,p2Index,s0,p0,p0Index));
pts.append(generatePoint(snapped,s2,p2,p2Index,s3,p3,p3Index));
} }
} }
break; break;
case 0x0A:
case 0x05: case 0x05:
case 0x0A:
{ {
Type s01 = generatePoint(snapped,s0,p0,p0Index,s1,p1,p1Index); Type p0p1 =
Type s23 = generatePoint(snapped,s2,p2,p2Index,s3,p3,p3Index); generatePoint(snapped,s0,p0,p0Index,s1,p1,p1Index);
Type p2p3 =
generatePoint(snapped,s2,p2,p2Index,s3,p3,p3Index);
if (isoVal3 >= isoVal0) pts.append(p0p1);
pts.append(p2p3);
pts.append
(
generatePoint(snapped,s0,p0,p0Index,s3,p3,p3Index)
);
pts.append(p0p1);
pts.append
(
generatePoint(snapped,s1,p1,p1Index,s2,p2,p2Index)
);
pts.append(p2p3);
if (triIndex == 0x0A)
{ {
pts.append(s01); // Flip normals
pts.append(s23); label sz = pts.size();
pts.append(generatePoint(snapped,s0,p0,p0Index,s3,p3,p3Index)); Swap(pts[sz-5], pts[sz-4]);
pts.append(s01); Swap(pts[sz-2], pts[sz-1]);
pts.append(generatePoint(snapped,s1,p1,p1Index,s2,p2,p2Index));
pts.append(s23);
}
else
{
pts.append(s23);
pts.append(s01);
pts.append(generatePoint(snapped,s0,p0,p0Index,s3,p3,p3Index));
pts.append(generatePoint(snapped,s1,p1,p1Index,s2,p2,p2Index));
pts.append(s01);
pts.append(s23);
} }
} }
break; break;
case 0x09:
case 0x06: case 0x06:
case 0x09:
{ {
Type s01 = generatePoint(snapped,s0,p0,p0Index,s1,p1,p1Index); Type p0p1 =
Type s23 = generatePoint(snapped,s2,p2,p2Index,s3,p3,p3Index); generatePoint(snapped,s0,p0,p0Index,s1,p1,p1Index);
Type p2p3 =
generatePoint(snapped,s2,p2,p2Index,s3,p3,p3Index);
if (isoVal3 >= isoVal1) pts.append(p0p1);
pts.append
(
generatePoint(snapped,s1,p1,p1Index,s3,p3,p3Index)
);
pts.append(p2p3);
pts.append(p0p1);
pts.append(p2p3);
pts.append
(
generatePoint(snapped,s0,p0,p0Index,s2,p2,p2Index)
);
if (triIndex == 0x09)
{ {
pts.append(s01); // Flip normals
pts.append(generatePoint(snapped,s1,p1,p1Index,s3,p3,p3Index)); label sz = pts.size();
pts.append(s23); Swap(pts[sz-5], pts[sz-4]);
pts.append(s01); Swap(pts[sz-2], pts[sz-1]);
pts.append(generatePoint(snapped,s0,p0,p0Index,s2,p2,p2Index));
pts.append(s23);
}
else
{
pts.append(generatePoint(snapped,s1,p1,p1Index,s3,p3,p3Index));
pts.append(s01);
pts.append(s23);
pts.append(generatePoint(snapped,s0,p0,p0Index,s2,p2,p2Index));
pts.append(s01);
pts.append(s23);
} }
} }
break; break;
case 0x07:
case 0x08: case 0x08:
case 0x07:
{ {
// 3 is common point pts.append
if (isoVal3 >= isoVal0) (
generatePoint(snapped,s3,p3,p3Index,s0,p0,p0Index)
);
pts.append
(
generatePoint(snapped,s3,p3,p3Index,s2,p2,p2Index)
);
pts.append
(
generatePoint(snapped,s3,p3,p3Index,s1,p1,p1Index)
);
if (triIndex == 0x07)
{ {
pts.append(generatePoint(snapped,s3,p3,p3Index,s0,p0,p0Index)); // Flip normals
pts.append(generatePoint(snapped,s3,p3,p3Index,s2,p2,p2Index)); label sz = pts.size();
pts.append(generatePoint(snapped,s3,p3,p3Index,s1,p1,p1Index)); Swap(pts[sz-2], pts[sz-1]);
}
else
{
pts.append(generatePoint(snapped,s3,p3,p3Index,s2,p2,p2Index));
pts.append(generatePoint(snapped,s3,p3,p3Index,s0,p0,p0Index));
pts.append(generatePoint(snapped,s3,p3,p3Index,s1,p1,p1Index));
} }
} }
break; break;
@ -341,22 +374,18 @@ void Foam::isoSurfaceCell::generateTriPoints
( (
snappedPoints, snappedPoints,
pVals_[f0[1]],
pVals[f0[1]], pVals[f0[1]],
pCoords[f0[1]], pCoords[f0[1]],
snappedPoint[f0[1]], snappedPoint[f0[1]],
pVals_[f0[0]],
pVals[f0[0]], pVals[f0[0]],
pCoords[f0[0]], pCoords[f0[0]],
snappedPoint[f0[0]], snappedPoint[f0[0]],
pVals_[f0[2]],
pVals[f0[2]], pVals[f0[2]],
pCoords[f0[2]], pCoords[f0[2]],
snappedPoint[f0[2]], snappedPoint[f0[2]],
pVals_[oppositeI],
pVals[oppositeI], pVals[oppositeI],
pCoords[oppositeI], pCoords[oppositeI],
snappedPoint[oppositeI], snappedPoint[oppositeI],
@ -370,22 +399,18 @@ void Foam::isoSurfaceCell::generateTriPoints
( (
snappedPoints, snappedPoints,
pVals_[f0[0]],
pVals[f0[0]], pVals[f0[0]],
pCoords[f0[0]], pCoords[f0[0]],
snappedPoint[f0[0]], snappedPoint[f0[0]],
pVals_[f0[1]],
pVals[f0[1]], pVals[f0[1]],
pCoords[f0[1]], pCoords[f0[1]],
snappedPoint[f0[1]], snappedPoint[f0[1]],
pVals_[f0[2]],
pVals[f0[2]], pVals[f0[2]],
pCoords[f0[2]], pCoords[f0[2]],
snappedPoint[f0[2]], snappedPoint[f0[2]],
pVals_[oppositeI],
pVals[oppositeI], pVals[oppositeI],
pCoords[oppositeI], pCoords[oppositeI],
snappedPoint[oppositeI], snappedPoint[oppositeI],
@ -411,7 +436,6 @@ void Foam::isoSurfaceCell::generateTriPoints
} }
label fp = f.fcIndex(fp0); label fp = f.fcIndex(fp0);
for (label i = 2; i < f.size(); i++) for (label i = 2; i < f.size(); i++)
{ {
label nextFp = f.fcIndex(fp); label nextFp = f.fcIndex(fp);
@ -425,22 +449,18 @@ void Foam::isoSurfaceCell::generateTriPoints
( (
snappedPoints, snappedPoints,
pVals_[tri[1]],
pVals[tri[1]], pVals[tri[1]],
pCoords[tri[1]], pCoords[tri[1]],
snappedPoint[tri[1]], snappedPoint[tri[1]],
pVals_[tri[0]],
pVals[tri[0]], pVals[tri[0]],
pCoords[tri[0]], pCoords[tri[0]],
snappedPoint[tri[0]], snappedPoint[tri[0]],
pVals_[tri[2]],
pVals[tri[2]], pVals[tri[2]],
pCoords[tri[2]], pCoords[tri[2]],
snappedPoint[tri[2]], snappedPoint[tri[2]],
cVals_[cellI],
cVals[cellI], cVals[cellI],
cCoords[cellI], cCoords[cellI],
snappedCc[cellI], snappedCc[cellI],
@ -454,22 +474,18 @@ void Foam::isoSurfaceCell::generateTriPoints
( (
snappedPoints, snappedPoints,
pVals_[tri[0]],
pVals[tri[0]], pVals[tri[0]],
pCoords[tri[0]], pCoords[tri[0]],
snappedPoint[tri[0]], snappedPoint[tri[0]],
pVals_[tri[1]],
pVals[tri[1]], pVals[tri[1]],
pCoords[tri[1]], pCoords[tri[1]],
snappedPoint[tri[1]], snappedPoint[tri[1]],
pVals_[tri[2]],
pVals[tri[2]], pVals[tri[2]],
pCoords[tri[2]], pCoords[tri[2]],
snappedPoint[tri[2]], snappedPoint[tri[2]],
cVals_[cellI],
cVals[cellI], cVals[cellI],
cCoords[cellI], cCoords[cellI],
snappedCc[cellI], snappedCc[cellI],
@ -495,7 +511,7 @@ void Foam::isoSurfaceCell::generateTriPoints
if (countNotFoundTets > 0) if (countNotFoundTets > 0)
{ {
WarningIn("Foam::isoSurfaceCell::generateTriPoints") WarningIn("Foam::isoSurfaceCell::generateTriPoints(..)")
<< "Could not find " << countNotFoundTets << "Could not find " << countNotFoundTets
<< " tet base points, which may lead to inverted triangles." << " tet base points, which may lead to inverted triangles."
<< endl; << endl;
@ -510,13 +526,11 @@ template<class Type>
Foam::tmp<Foam::Field<Type> > Foam::tmp<Foam::Field<Type> >
Foam::isoSurfaceCell::interpolate Foam::isoSurfaceCell::interpolate
( (
const scalarField& cVals,
const scalarField& pVals,
const Field<Type>& cCoords, const Field<Type>& cCoords,
const Field<Type>& pCoords const Field<Type>& pCoords
) const ) const
{ {
DynamicList<Type> triPoints(nCutCells_); DynamicList<Type> triPoints(3*nCutCells_);
DynamicList<label> triMeshCells(nCutCells_); DynamicList<label> triMeshCells(nCutCells_);
// Dummy snap data // Dummy snap data
@ -524,59 +538,6 @@ Foam::isoSurfaceCell::interpolate
labelList snappedCc(mesh_.nCells(), -1); labelList snappedCc(mesh_.nCells(), -1);
labelList snappedPoint(mesh_.nPoints(), -1); labelList snappedPoint(mesh_.nPoints(), -1);
generateTriPoints
(
cVals,
pVals,
cCoords,
pCoords,
snappedPoints,
snappedCc,
snappedPoint,
triPoints,
triMeshCells
);
// One value per point
tmp<Field<Type> > tvalues(new Field<Type>(points().size()));
Field<Type>& values = tvalues();
forAll(triPoints, i)
{
label mergedPointI = triPointMergeMap_[i];
if (mergedPointI >= 0)
{
values[mergedPointI] = triPoints[i];
}
}
return tvalues;
}
template<class Type>
Foam::tmp<Foam::Field<Type> >
Foam::isoSurfaceCell::interpolate
(
const Field<Type>& cCoords,
const Field<Type>& pCoords
) const
{
DynamicList<Type> triPoints(nCutCells_);
DynamicList<label> triMeshCells(nCutCells_);
// Dummy snap data
DynamicList<Type> snappedPoints;
labelList snappedCc(mesh_.nCells(), -1);
labelList snappedPoint(mesh_.nPoints(), -1);
generateTriPoints generateTriPoints
( (
cVals_, cVals_,
@ -593,22 +554,15 @@ Foam::isoSurfaceCell::interpolate
triMeshCells triMeshCells
); );
return isoSurface::interpolate
// One value per point (
tmp<Field<Type> > tvalues(new Field<Type>(points().size())); points().size(),
Field<Type>& values = tvalues(); triPointMergeMap_,
interpolatedPoints_,
forAll(triPoints, i) interpolatedOldPoints_,
{ interpolationWeights_,
label mergedPointI = triPointMergeMap_[i]; triPoints
);
if (mergedPointI >= 0)
{
values[mergedPointI] = triPoints[i];
}
}
return tvalues;
} }

View File

@ -2,7 +2,7 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2015 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -120,7 +120,7 @@ Foam::isoSurface::adaptPatchFields
{ {
fvPatchField<Type>& pfld = const_cast<fvPatchField<Type>&> fvPatchField<Type>& pfld = const_cast<fvPatchField<Type>&>
( (
fld.boundaryField()[patchI] sliceFld.boundaryField()[patchI]
); );
const scalarField& w = mesh.weights().boundaryField()[patchI]; const scalarField& w = mesh.weights().boundaryField()[patchI];
@ -189,6 +189,8 @@ Type Foam::isoSurface::generatePoint
} }
// Note: cannot use simpler isoSurfaceCell::generateTriPoints since
// the need here to sometimes pass in remote 'snappedPoints'
template<class Type> template<class Type>
void Foam::isoSurface::generateTriPoints void Foam::isoSurface::generateTriPoints
( (
@ -240,8 +242,8 @@ void Foam::isoSurface::generateTriPoints
case 0x0F: case 0x0F:
break; break;
case 0x0E:
case 0x01: case 0x01:
case 0x0E:
points.append points.append
( (
generatePoint(s0,p0,hasSnap0,snapP0,s1,p1,hasSnap1,snapP1) generatePoint(s0,p0,hasSnap0,snapP0,s1,p1,hasSnap1,snapP1)
@ -254,10 +256,16 @@ void Foam::isoSurface::generateTriPoints
( (
generatePoint(s0,p0,hasSnap0,snapP0,s3,p3,hasSnap3,snapP3) generatePoint(s0,p0,hasSnap0,snapP0,s3,p3,hasSnap3,snapP3)
); );
if (triIndex == 0x0E)
{
// Flip normals
label sz = points.size();
Swap(points[sz-2], points[sz-1]);
}
break; break;
case 0x0D:
case 0x02: case 0x02:
case 0x0D:
points.append points.append
( (
generatePoint(s1,p1,hasSnap1,snapP1,s0,p0,hasSnap0,snapP0) generatePoint(s1,p1,hasSnap1,snapP1,s0,p0,hasSnap0,snapP0)
@ -270,97 +278,133 @@ void Foam::isoSurface::generateTriPoints
( (
generatePoint(s1,p1,hasSnap1,snapP1,s2,p2,hasSnap2,snapP2) generatePoint(s1,p1,hasSnap1,snapP1,s2,p2,hasSnap2,snapP2)
); );
if (triIndex == 0x0D)
{
// Flip normals
label sz = points.size();
Swap(points[sz-2], points[sz-1]);
}
break; break;
case 0x0C:
case 0x03: case 0x03:
{ case 0x0C:
Type tp1 = {
generatePoint(s0,p0,hasSnap0,snapP0,s2,p2,hasSnap2,snapP2); Type p0p2 =
Type tp2 = generatePoint(s0,p0,hasSnap0,snapP0,s2,p2,hasSnap2,snapP2);
generatePoint(s1,p1,hasSnap1,snapP1,s3,p3,hasSnap3,snapP3); Type p1p3 =
generatePoint(s1,p1,hasSnap1,snapP1,s3,p3,hasSnap3,snapP3);
points.append points.append
( (
generatePoint(s0,p0,hasSnap0,snapP0,s3,p3,hasSnap3,snapP3) generatePoint(s0,p0,hasSnap0,snapP0,s3,p3,hasSnap3,snapP3)
); );
points.append(tp1); points.append(p1p3);
points.append(tp2); points.append(p0p2);
points.append(tp2);
points.append points.append(p1p3);
( points.append
generatePoint(s1,p1,hasSnap1,snapP1,s2,p2,hasSnap2,snapP2) (
); generatePoint(s1,p1,hasSnap1,snapP1,s2,p2,hasSnap2,snapP2)
points.append(tp1); );
} points.append(p0p2);
}
if (triIndex == 0x0C)
{
// Flip normals
label sz = points.size();
Swap(points[sz-5], points[sz-4]);
Swap(points[sz-2], points[sz-1]);
}
break; break;
case 0x0B:
case 0x04: case 0x04:
{ case 0x0B:
points.append {
( points.append
generatePoint(s2,p2,hasSnap2,snapP2,s0,p0,hasSnap0,snapP0) (
); generatePoint(s2,p2,hasSnap2,snapP2,s0,p0,hasSnap0,snapP0)
points.append );
( points.append
generatePoint(s2,p2,hasSnap2,snapP2,s1,p1,hasSnap1,snapP1) (
); generatePoint(s2,p2,hasSnap2,snapP2,s1,p1,hasSnap1,snapP1)
points.append );
( points.append
generatePoint(s2,p2,hasSnap2,snapP2,s3,p3,hasSnap3,snapP3) (
); generatePoint(s2,p2,hasSnap2,snapP2,s3,p3,hasSnap3,snapP3)
} );
}
if (triIndex == 0x0B)
{
// Flip normals
label sz = points.size();
Swap(points[sz-2], points[sz-1]);
}
break; break;
case 0x0A:
case 0x05: case 0x05:
{ case 0x0A:
Type tp0 = {
generatePoint(s0,p0,hasSnap0,snapP0,s1,p1,hasSnap1,snapP1); Type p0p1 =
Type tp1 = generatePoint(s0,p0,hasSnap0,snapP0,s1,p1,hasSnap1,snapP1);
generatePoint(s2,p2,hasSnap2,snapP2,s3,p3,hasSnap3,snapP3); Type p2p3 =
generatePoint(s2,p2,hasSnap2,snapP2,s3,p3,hasSnap3,snapP3);
points.append(tp0); points.append(p0p1);
points.append(tp1); points.append(p2p3);
points.append points.append
( (
generatePoint(s0,p0,hasSnap0,snapP0,s3,p3,hasSnap3,snapP3) generatePoint(s0,p0,hasSnap0,snapP0,s3,p3,hasSnap3,snapP3)
); );
points.append(tp0);
points.append points.append(p0p1);
( points.append
generatePoint(s1,p1,hasSnap1,snapP1,s2,p2,hasSnap2,snapP2) (
); generatePoint(s1,p1,hasSnap1,snapP1,s2,p2,hasSnap2,snapP2)
points.append(tp1); );
} points.append(p2p3);
}
if (triIndex == 0x0A)
{
// Flip normals
label sz = points.size();
Swap(points[sz-5], points[sz-4]);
Swap(points[sz-2], points[sz-1]);
}
break; break;
case 0x09:
case 0x06: case 0x06:
{ case 0x09:
Type tp0 = {
generatePoint(s0,p0,hasSnap0,snapP0,s1,p1,hasSnap1,snapP1); Type p0p1 =
Type tp1 = generatePoint(s0,p0,hasSnap0,snapP0,s1,p1,hasSnap1,snapP1);
generatePoint(s2,p2,hasSnap2,snapP2,s3,p3,hasSnap3,snapP3); Type p2p3 =
generatePoint(s2,p2,hasSnap2,snapP2,s3,p3,hasSnap3,snapP3);
points.append(tp0); points.append(p0p1);
points.append points.append
( (
generatePoint(s1,p1,hasSnap1,snapP1,s3,p3,hasSnap3,snapP3) generatePoint(s1,p1,hasSnap1,snapP1,s3,p3,hasSnap3,snapP3)
); );
points.append(tp1); points.append(p2p3);
points.append(tp0);
points.append points.append(p0p1);
( points.append(p2p3);
generatePoint(s0,p0,hasSnap0,snapP0,s2,p2,hasSnap2,snapP2) points.append
); (
points.append(tp1); generatePoint(s0,p0,hasSnap0,snapP0,s2,p2,hasSnap2,snapP2)
} );
}
if (triIndex == 0x09)
{
// Flip normals
label sz = points.size();
Swap(points[sz-5], points[sz-4]);
Swap(points[sz-2], points[sz-1]);
}
break; break;
case 0x07:
case 0x08: case 0x08:
case 0x07:
points.append points.append
( (
generatePoint(s3,p3,hasSnap3,snapP3,s0,p0,hasSnap0,snapP0) generatePoint(s3,p3,hasSnap3,snapP3,s0,p0,hasSnap0,snapP0)
@ -373,6 +417,12 @@ void Foam::isoSurface::generateTriPoints
( (
generatePoint(s3,p3,hasSnap3,snapP3,s1,p1,hasSnap1,snapP1) generatePoint(s3,p3,hasSnap3,snapP3,s1,p1,hasSnap1,snapP1)
); );
if (triIndex == 0x07)
{
// Flip normals
label sz = points.size();
Swap(points[sz-2], points[sz-1]);
}
break; break;
} }
} }
@ -689,6 +739,69 @@ void Foam::isoSurface::generateTriPoints
//} //}
template<class Type>
Foam::tmp<Foam::Field<Type> >
Foam::isoSurface::interpolate
(
const label nPoints,
const labelList& triPointMergeMap,
const labelList& interpolatedPoints,
const List<FixedList<label, 3> >& interpolatedOldPoints,
const List<FixedList<scalar, 3> >& interpolationWeights,
const DynamicList<Type>& unmergedValues
)
{
// One value per point
tmp<Field<Type> > tvalues(new Field<Type>(nPoints, pTraits<Type>::zero));
Field<Type>& values = tvalues();
// Pass1: unweighted average of merged point values
{
labelList nValues(values.size(), 0);
forAll(unmergedValues, i)
{
label mergedPointI = triPointMergeMap[i];
if (mergedPointI >= 0)
{
values[mergedPointI] += unmergedValues[i];
nValues[mergedPointI]++;
}
}
forAll(values, i)
{
if (nValues[i] > 0)
{
values[i] /= scalar(nValues[i]);
}
}
}
// Pass2: weighted average for remaining values (from clipped triangles)
forAll(interpolatedPoints, i)
{
label pointI = interpolatedPoints[i];
const FixedList<label, 3>& oldPoints = interpolatedOldPoints[i];
const FixedList<scalar, 3>& w = interpolationWeights[i];
// Note: zeroing should not be necessary if interpolation only done
// for newly introduced points (i.e. not in triPointMergeMap)
values[pointI] = pTraits<Type>::zero;
forAll(oldPoints, j)
{
values[pointI] = w[j]*unmergedValues[oldPoints[j]];
}
}
return tvalues;
}
template<class Type> template<class Type>
Foam::tmp<Foam::Field<Type> > Foam::tmp<Foam::Field<Type> >
Foam::isoSurface::interpolate Foam::isoSurface::interpolate
@ -707,7 +820,7 @@ Foam::isoSurface::interpolate
> > c2(adaptPatchFields(cCoords)); > > c2(adaptPatchFields(cCoords));
DynamicList<Type> triPoints(nCutCells_); DynamicList<Type> triPoints(3*nCutCells_);
DynamicList<label> triMeshCells(nCutCells_); DynamicList<label> triMeshCells(nCutCells_);
// Dummy snap data // Dummy snap data
@ -731,52 +844,15 @@ Foam::isoSurface::interpolate
triMeshCells triMeshCells
); );
return interpolate
// One value per point
tmp<Field<Type> > tvalues
( (
new Field<Type>(points().size(), pTraits<Type>::zero) points().size(),
triPointMergeMap_,
interpolatedPoints_,
interpolatedOldPoints_,
interpolationWeights_,
triPoints
); );
Field<Type>& values = tvalues();
labelList nValues(values.size(), 0);
forAll(triPoints, i)
{
label mergedPointI = triPointMergeMap_[i];
if (mergedPointI >= 0)
{
values[mergedPointI] += triPoints[i];
nValues[mergedPointI]++;
}
}
if (debug)
{
Pout<< "nValues:" << values.size() << endl;
label nMult = 0;
forAll(nValues, i)
{
if (nValues[i] == 0)
{
FatalErrorIn("isoSurface::interpolate(..)")
<< "point:" << i << " nValues:" << nValues[i]
<< abort(FatalError);
}
else if (nValues[i] > 1)
{
nMult++;
}
}
Pout<< "Of which mult:" << nMult << endl;
}
forAll(values, i)
{
values[i] /= scalar(nValues[i]);
}
return tvalues;
} }

View File

@ -122,18 +122,52 @@ void Foam::sampledIsoSurface::getIsoFields() const
// Get pointField // Get pointField
// ~~~~~~~~~~~~~~ // ~~~~~~~~~~~~~~
// In case of multiple iso values we don't want to calculate multiple e.g.
// "volPointInterpolate(p)" so register it and re-use it. This is the
// same as the 'cache' functionality from volPointInterpolate but
// unfortunately that one does not guarantee that the field pointer
// remain: e.g. some other
// functionObject might delete the cached version.
// (volPointInterpolation::interpolate with cache=false deletes any
// registered one or if mesh.changing())
if (!subMeshPtr_.valid()) if (!subMeshPtr_.valid())
{ {
word pointFldName = "volPointInterpolate(" + isoField_ + ')'; const word pointFldName =
"volPointInterpolate_"
+ type()
+ "("
+ isoField_
+ ')';
if (fvm.foundObject<pointScalarField>(pointFldName)) if (fvm.foundObject<pointScalarField>(pointFldName))
{ {
if (debug) if (debug)
{ {
Info<< "sampledIsoSurface::getIsoFields() : lookup pointField " Info<< "sampledIsoSurface::getIsoFields() :"
<< pointFldName << endl; << " lookup pointField " << pointFldName << endl;
} }
pointFieldPtr_ = &fvm.lookupObject<pointScalarField>(pointFldName); const pointScalarField& pfld = fvm.lookupObject<pointScalarField>
(
pointFldName
);
if (!pfld.upToDate(*volFieldPtr_))
{
if (debug)
{
Info<< "sampledIsoSurface::getIsoFields() :"
<< " updating pointField " << pointFldName << endl;
}
// Update the interpolated value
volPointInterpolation::New(fvm).interpolate
(
*volFieldPtr_,
const_cast<pointScalarField&>(pfld)
);
}
pointFieldPtr_ = &pfld;
} }
else else
{ {
@ -141,33 +175,23 @@ void Foam::sampledIsoSurface::getIsoFields() const
if (debug) if (debug)
{ {
Info<< "sampledIsoSurface::getIsoFields() : " Info<< "sampledIsoSurface::getIsoFields() :"
<< "checking pointField " << pointFldName << " creating and storing pointField "
<< " for same time " << fvm.time().timeName() << pointFldName << " for time "
<< endl; << fvm.time().timeName() << endl;
} }
if tmp<pointScalarField> tpfld
( (
storedPointFieldPtr_.empty() volPointInterpolation::New(fvm).interpolate
|| (fvm.time().timeName() != storedPointFieldPtr_().instance())
)
{
if (debug)
{
Info<< "sampledIsoSurface::getIsoFields() :"
<< " interpolating volField " << volFieldPtr_->name()
<< " to get pointField " << pointFldName << endl;
}
storedPointFieldPtr_.reset
( (
volPointInterpolation::New(fvm) *volFieldPtr_,
.interpolate(*volFieldPtr_).ptr() pointFldName,
); false
storedPointFieldPtr_->checkOut(); )
pointFieldPtr_ = storedPointFieldPtr_.operator->(); );
} pointFieldPtr_ = tpfld.ptr();
const_cast<pointScalarField*>(pointFieldPtr_)->store();
} }
@ -233,8 +257,10 @@ void Foam::sampledIsoSurface::getIsoFields() const
// Pointfield on submesh // Pointfield on submesh
word pointFldName = const word pointFldName =
"volPointInterpolate(" "volPointInterpolate_"
+ type()
+ "("
+ volSubFieldPtr_->name() + volSubFieldPtr_->name()
+ ')'; + ')';
@ -245,11 +271,28 @@ void Foam::sampledIsoSurface::getIsoFields() const
Info<< "sampledIsoSurface::getIsoFields() :" Info<< "sampledIsoSurface::getIsoFields() :"
<< " submesh lookup pointField " << pointFldName << endl; << " submesh lookup pointField " << pointFldName << endl;
} }
storedPointSubFieldPtr_.clear(); const pointScalarField& pfld = subFvm.lookupObject<pointScalarField>
pointSubFieldPtr_ = &subFvm.lookupObject<pointScalarField>
( (
pointFldName pointFldName
); );
if (!pfld.upToDate(*volSubFieldPtr_))
{
if (debug)
{
Info<< "sampledIsoSurface::getIsoFields() :"
<< " updating submesh pointField "
<< pointFldName << endl;
}
// Update the interpolated value
volPointInterpolation::New(subFvm).interpolate
(
*volSubFieldPtr_,
const_cast<pointScalarField&>(pfld)
);
}
pointFieldPtr_ = &pfld;
} }
else else
{ {
@ -260,15 +303,15 @@ void Foam::sampledIsoSurface::getIsoFields() const
<< volSubFieldPtr_->name() << volSubFieldPtr_->name()
<< " to get submesh pointField " << pointFldName << endl; << " to get submesh pointField " << pointFldName << endl;
} }
storedPointSubFieldPtr_.reset tmp<pointScalarField> tpfld
( (
volPointInterpolation::New volPointInterpolation::New
( (
subFvm subFvm
).interpolate(*volSubFieldPtr_).ptr() ).interpolate(*volSubFieldPtr_)
); );
storedPointSubFieldPtr_->checkOut(); pointSubFieldPtr_ = tpfld.ptr();
pointSubFieldPtr_ = storedPointSubFieldPtr_.operator->(); const_cast<pointScalarField*>(pointSubFieldPtr_)->store();
} }
@ -349,28 +392,34 @@ bool Foam::sampledIsoSurface::updateGeometry() const
if (subMeshPtr_.valid()) if (subMeshPtr_.valid())
{ {
const volScalarField& vfld = *volSubFieldPtr_;
surfPtr_.reset surfPtr_.reset
( (
new isoSurface new isoSurface
( (
*volSubFieldPtr_, vfld,
*pointSubFieldPtr_, *pointSubFieldPtr_,
isoVal_, isoVal_,
regularise_, regularise_,
bounds_,
mergeTol_ mergeTol_
) )
); );
} }
else else
{ {
const volScalarField& vfld = *volFieldPtr_;
surfPtr_.reset surfPtr_.reset
( (
new isoSurface new isoSurface
( (
*volFieldPtr_, vfld,
*pointFieldPtr_, *pointFieldPtr_,
isoVal_, isoVal_,
regularise_, regularise_,
bounds_,
mergeTol_ mergeTol_
) )
); );
@ -412,6 +461,7 @@ Foam::sampledIsoSurface::sampledIsoSurface
sampledSurface(name, mesh, dict), sampledSurface(name, mesh, dict),
isoField_(dict.lookup("isoField")), isoField_(dict.lookup("isoField")),
isoVal_(readScalar(dict.lookup("isoValue"))), isoVal_(readScalar(dict.lookup("isoValue"))),
bounds_(dict.lookupOrDefault("bounds", boundBox::greatBox)),
mergeTol_(dict.lookupOrDefault("mergeTol", 1e-6)), mergeTol_(dict.lookupOrDefault("mergeTol", 1e-6)),
regularise_(dict.lookupOrDefault("regularise", true)), regularise_(dict.lookupOrDefault("regularise", true)),
average_(dict.lookupOrDefault("average", false)), average_(dict.lookupOrDefault("average", false)),
@ -422,7 +472,6 @@ Foam::sampledIsoSurface::sampledIsoSurface
prevTimeIndex_(-1), prevTimeIndex_(-1),
storedVolFieldPtr_(NULL), storedVolFieldPtr_(NULL),
volFieldPtr_(NULL), volFieldPtr_(NULL),
storedPointFieldPtr_(NULL),
pointFieldPtr_(NULL) pointFieldPtr_(NULL)
{ {
if (!sampledSurface::interpolate()) if (!sampledSurface::interpolate())

View File

@ -63,6 +63,9 @@ class sampledIsoSurface
//- Iso value //- Iso value
const scalar isoVal_; const scalar isoVal_;
//- Optional bounding box to trim triangles against
const boundBox bounds_;
//- Merge tolerance //- Merge tolerance
const scalar mergeTol_; const scalar mergeTol_;
@ -94,7 +97,6 @@ class sampledIsoSurface
mutable const volScalarField* volFieldPtr_; mutable const volScalarField* volFieldPtr_;
//- Cached pointfield //- Cached pointfield
mutable autoPtr<pointScalarField> storedPointFieldPtr_;
mutable const pointScalarField* pointFieldPtr_; mutable const pointScalarField* pointFieldPtr_;
// And on subsetted mesh // And on subsetted mesh
@ -107,7 +109,6 @@ class sampledIsoSurface
mutable const volScalarField* volSubFieldPtr_; mutable const volScalarField* volSubFieldPtr_;
//- Cached pointfield //- Cached pointfield
mutable autoPtr<pointScalarField> storedPointSubFieldPtr_;
mutable const pointScalarField* pointSubFieldPtr_; mutable const pointScalarField* pointSubFieldPtr_;

View File

@ -2,7 +2,7 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2011 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2015 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -148,7 +148,8 @@ bool Foam::sampledIsoSurfaceCell::updateGeometry() const
cellAvg, cellAvg,
pointFld().internalField(), pointFld().internalField(),
isoVal_, isoVal_,
regularise_ regularise_,
bounds_
); );
const_cast<sampledIsoSurfaceCell&> const_cast<sampledIsoSurfaceCell&>
@ -166,7 +167,8 @@ bool Foam::sampledIsoSurfaceCell::updateGeometry() const
cellFld.internalField(), cellFld.internalField(),
pointFld().internalField(), pointFld().internalField(),
isoVal_, isoVal_,
regularise_ regularise_,
bounds_
); );
const_cast<sampledIsoSurfaceCell&> const_cast<sampledIsoSurfaceCell&>
@ -185,6 +187,7 @@ bool Foam::sampledIsoSurfaceCell::updateGeometry() const
<< " average : " << average_ << nl << " average : " << average_ << nl
<< " isoField : " << isoField_ << nl << " isoField : " << isoField_ << nl
<< " isoValue : " << isoVal_ << nl << " isoValue : " << isoVal_ << nl
<< " bounds : " << bounds_ << nl
<< " points : " << points().size() << nl << " points : " << points().size() << nl
<< " tris : " << triSurface::size() << nl << " tris : " << triSurface::size() << nl
<< " cut cells : " << meshCells_.size() << endl; << " cut cells : " << meshCells_.size() << endl;
@ -206,6 +209,7 @@ Foam::sampledIsoSurfaceCell::sampledIsoSurfaceCell
sampledSurface(name, mesh, dict), sampledSurface(name, mesh, dict),
isoField_(dict.lookup("isoField")), isoField_(dict.lookup("isoField")),
isoVal_(readScalar(dict.lookup("isoValue"))), isoVal_(readScalar(dict.lookup("isoValue"))),
bounds_(dict.lookupOrDefault("bounds", boundBox::greatBox)),
regularise_(dict.lookupOrDefault("regularise", true)), regularise_(dict.lookupOrDefault("regularise", true)),
average_(dict.lookupOrDefault("average", true)), average_(dict.lookupOrDefault("average", true)),
zoneKey_(keyType::null), zoneKey_(keyType::null),

View File

@ -62,6 +62,9 @@ class sampledIsoSurfaceCell
//- Iso value //- Iso value
const scalar isoVal_; const scalar isoVal_;
//- Optional bounding box to trim triangles against
const boundBox bounds_;
//- Whether to coarse //- Whether to coarse
const Switch regularise_; const Switch regularise_;

View File

@ -2,7 +2,7 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2014 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -230,6 +230,7 @@ void Foam::sampledCuttingPlane::createGeometry()
pointDistance_, pointDistance_,
0.0, 0.0,
regularise_, regularise_,
bounds_,
mergeTol_ mergeTol_
) )
//new isoSurfaceCell //new isoSurfaceCell
@ -262,6 +263,7 @@ Foam::sampledCuttingPlane::sampledCuttingPlane
: :
sampledSurface(name, mesh, dict), sampledSurface(name, mesh, dict),
plane_(dict), plane_(dict),
bounds_(dict.lookupOrDefault("bounds", boundBox::greatBox)),
mergeTol_(dict.lookupOrDefault("mergeTol", 1e-6)), mergeTol_(dict.lookupOrDefault("mergeTol", 1e-6)),
regularise_(dict.lookupOrDefault("regularise", true)), regularise_(dict.lookupOrDefault("regularise", true)),
average_(dict.lookupOrDefault("average", false)), average_(dict.lookupOrDefault("average", false)),

View File

@ -60,6 +60,9 @@ class sampledCuttingPlane
//- Plane //- Plane
const plane plane_; const plane plane_;
//- Optional bounding box to trim triangles against
const boundBox bounds_;
//- Merge tolerance //- Merge tolerance
const scalar mergeTol_; const scalar mergeTol_;

View File

@ -2,7 +2,7 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2011-2014 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2015 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -84,11 +84,7 @@ const Foam::labelList& Foam::sampledPatch::patchIDs() const
{ {
if (patchIDs_.empty()) if (patchIDs_.empty())
{ {
patchIDs_ = mesh().boundaryMesh().patchSet patchIDs_ = mesh().boundaryMesh().patchSet(patchNames_).sortedToc();
(
patchNames_,
false
).sortedToc();
} }
return patchIDs_; return patchIDs_;
} }

View File

@ -2,8 +2,8 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2011-2015 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2014 OpenFOAM Foundation
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -162,19 +162,7 @@ void Foam::sampledSurfaces::write()
const label nFields = classifyFields(); const label nFields = classifyFields();
if (Pstream::master()) // write geometry first if required,
{
if (debug)
{
Pout<< "Creating directory "
<< outputPath_/obr_.time().timeName() << nl << endl;
}
mkDir(outputPath_/obr_.time().timeName());
}
// Write geometry first if required,
// or when no fields would otherwise be written // or when no fields would otherwise be written
if (nFields == 0 || formatter_->separateGeometry()) if (nFields == 0 || formatter_->separateGeometry())
{ {

View File

@ -644,8 +644,25 @@ bool Foam::sampledTriSurfaceMesh::update()
return false; return false;
} }
// Calculate surface and mesh overlap bounding box
treeBoundBox bb
(
surface_.triSurface::points(),
surface_.triSurface::meshPoints()
);
bb.min() = max(bb.min(), mesh().bounds().min());
bb.max() = min(bb.max(), mesh().bounds().max());
// Extend a bit
const vector span(bb.span());
bb.min() -= 0.5*span;
bb.max() += 0.5*span;
bb.inflate(1e-6);
// Mesh search engine, no triangulation of faces. // Mesh search engine, no triangulation of faces.
meshSearch meshSearcher(mesh(), polyMesh::FACE_PLANES); meshSearch meshSearcher(mesh(), bb, polyMesh::FACE_PLANES);
return update(meshSearcher); return update(meshSearcher);
} }

View File

@ -1,56 +0,0 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: dev |
| \\ / A nd | Web: www.OpenFOAM.org |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class volScalarField;
location "0";
object T;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
dimensions [0 0 0 1 0 0 0];
internalField uniform 293;
boundaryField
{
frontAndBack
{
type zeroGradient;
}
topAndBottom
{
type zeroGradient;
}
hot
{
type externalCoupledTemperature;
commsDir "${FOAM_CASE}/comms";
fileName "data";
initByExternal yes;
log true;
value uniform 307.75; // 34.6 degC
}
cold
{
type externalCoupledTemperature;
commsDir "${FOAM_CASE}/comms";
fileName "data";
initByExternal yes;
log true;
value uniform 288.15; // 15 degC
}
}
// ************************************************************************* //

View File

@ -1,51 +0,0 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: dev |
| \\ / A nd | Web: www.OpenFOAM.org |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class volScalarField;
location "0";
object alphat;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
dimensions [1 -1 -1 0 0 0 0];
internalField uniform 0;
boundaryField
{
frontAndBack
{
type compressible::alphatWallFunction;
Prt 0.85;
value uniform 0;
}
topAndBottom
{
type compressible::alphatWallFunction;
Prt 0.85;
value uniform 0;
}
hot
{
type compressible::alphatWallFunction;
Prt 0.85;
value uniform 0;
}
cold
{
type compressible::alphatWallFunction;
Prt 0.85;
value uniform 0;
}
}
// ************************************************************************* //

View File

@ -1,47 +0,0 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: dev |
| \\ / A nd | Web: www.OpenFOAM.org |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class volScalarField;
location "0";
object epsilon;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
dimensions [0 2 -3 0 0 0 0];
internalField uniform 4e-06;
boundaryField
{
frontAndBack
{
type epsilonWallFunction;
value uniform 4e-06;
}
topAndBottom
{
type epsilonWallFunction;
value uniform 4e-06;
}
hot
{
type epsilonWallFunction;
value uniform 4e-06;
}
cold
{
type epsilonWallFunction;
value uniform 4e-06;
}
}
// ************************************************************************* //

View File

@ -1,47 +0,0 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: dev |
| \\ / A nd | Web: www.OpenFOAM.org |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class volScalarField;
location "0";
object omega;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
dimensions [0 0 -1 0 0 0 0];
internalField uniform 0.12;
boundaryField
{
frontAndBack
{
type omegaWallFunction;
value uniform 0.12;
}
topAndBottom
{
type omegaWallFunction;
value uniform 0.12;
}
hot
{
type omegaWallFunction;
value uniform 0.12;
}
cold
{
type omegaWallFunction;
value uniform 0.12;
}
}
// ************************************************************************* //

View File

@ -1,14 +0,0 @@
#!/bin/sh
cd ${0%/*} || exit 1 # Run from this directory
# Source tutorial run functions
. $WM_PROJECT_DIR/bin/tools/CleanFunctions
cleanCase
rm -rf comms
killall externalSolver > /dev/null 2>&1
# ----------------------------------------------------------------- end-of-file

View File

@ -1,14 +0,0 @@
#!/bin/sh
cd ${0%/*} || exit 1 # Run from this directory
# Source tutorial run functions
. $WM_PROJECT_DIR/bin/tools/RunFunctions
./Allrun.pre
runApplication $(getApplication) &
./externalSolver
# ----------------------------------------------------------------- end-of-file

View File

@ -1,16 +0,0 @@
#!/bin/sh
cd ${0%/*} || exit 1 # Run from this directory
# Source tutorial run functions
. $WM_PROJECT_DIR/bin/tools/RunFunctions
./Allrun.pre
runApplication decomposePar
runParallel $(getApplication) 4 &
./externalSolver
# ----------------------------------------------------------------- end-of-file

View File

@ -1,11 +0,0 @@
#!/bin/sh
cd ${0%/*} || exit 1 # Run from this directory
# Source tutorial run functions
. $WM_PROJECT_DIR/bin/tools/RunFunctions
runApplication blockMesh
runApplication createExternalCoupledPatchGeometry T
# ----------------------------------------------------------------- end-of-file

View File

@ -1,5 +0,0 @@
Example of an explicit coupling between OpenFOAM and an external application
using the externalCoupled boundary conditions.
The case is based on the buoyantCavity tutorial case, whereby on each iteration
the 'hot' and 'cold' patch temperatures are incremented by 1K.

View File

@ -0,0 +1,30 @@
/*--------------------------------*- 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 volScalarField;
object T;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
dimensions [0 0 0 1 0 0 0];
internalField uniform 300;
boundaryField
{
".*"
{
type calculated;
value uniform 300;
}
}
// ************************************************************************* //

View File

@ -10,41 +10,21 @@ FoamFile
version 2.0; version 2.0;
format ascii; format ascii;
class volVectorField; class volVectorField;
location "0";
object U; object U;
} }
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
dimensions [0 1 -1 0 0 0 0]; dimensions [0 1 -1 0 0 0 0];
internalField uniform (0 0 0); internalField uniform (0.01 0 0);
boundaryField boundaryField
{ {
frontAndBack ".*"
{ {
type fixedValue; type calculated;
value uniform (0 0 0); value uniform (0.01 0 0);
}
topAndBottom
{
type fixedValue;
value uniform (0 0 0);
}
hot
{
type fixedValue;
value uniform (0 0 0);
}
cold
{
type fixedValue;
value uniform (0 0 0);
} }
} }
// ************************************************************************* // // ************************************************************************* //

View File

@ -0,0 +1,31 @@
/*--------------------------------*- 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 volScalarField;
object epsilon;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
dimensions [0 2 -3 0 0 0 0];
internalField uniform 0.01;
boundaryField
{
".*"
{
type calculated;
value uniform 0.01;
}
}
// ************************************************************************* //

View File

@ -0,0 +1,31 @@
/*--------------------------------*- 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 volScalarField;
object k;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
dimensions [0 2 -2 0 0 0 0];
internalField uniform 0.1;
boundaryField
{
".*"
{
type calculated;
value uniform 0.1;
}
}
// ************************************************************************* //

View File

@ -10,7 +10,6 @@ FoamFile
version 2.0; version 2.0;
format ascii; format ascii;
class volScalarField; class volScalarField;
location "0";
object p; object p;
} }
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -21,30 +20,11 @@ internalField uniform 1e5;
boundaryField boundaryField
{ {
frontAndBack ".*"
{ {
type calculated; type calculated;
value $internalField; value uniform 1e5;
}
topAndBottom
{
type calculated;
value $internalField;
}
hot
{
type calculated;
value $internalField;
}
cold
{
type calculated;
value $internalField;
} }
} }
// ************************************************************************* // // ************************************************************************* //

View File

@ -10,7 +10,6 @@ FoamFile
version 2.0; version 2.0;
format ascii; format ascii;
class volScalarField; class volScalarField;
location "0";
object p_rgh; object p_rgh;
} }
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -21,30 +20,11 @@ internalField uniform 1e5;
boundaryField boundaryField
{ {
frontAndBack ".*"
{ {
type fixedFluxPressure; type calculated;
value uniform 1e5;
}
topAndBottom
{
type fixedFluxPressure;
value uniform 1e5;
}
hot
{
type fixedFluxPressure;
value uniform 1e5;
}
cold
{
type fixedFluxPressure;
value uniform 1e5; value uniform 1e5;
} }
} }
// ************************************************************************* // // ************************************************************************* //

View File

@ -0,0 +1,23 @@
#!/bin/sh
cd ${0%/*} || exit 1 # Run from this directory
# Source tutorial clean functions
. $WM_PROJECT_DIR/bin/tools/CleanFunctions
cleanCase
rm -rf comms
rm -rf VTK
rm -rf constant/cellToRegion constant/polyMesh/sets
rm -rf 0/bottomWater
rm -rf 0/topAir
rm -rf 0/heater
rm -rf 0/leftSolid
rm -rf 0/rightSolid
rm -f 0/cellToRegion
rm -rf constant/bottomWater/polyMesh
rm -rf constant/topAir/polyMesh
rm -rf constant/heater/polyMesh
rm -rf constant/leftSolid/polyMesh
rm -rf constant/rightSolid/polyMesh
# ----------------------------------------------------------------- end-of-file

View File

@ -0,0 +1,28 @@
#!/bin/sh
cd ${0%/*} || exit 1 # Run from this directory
# Source tutorial run functions
. $WM_PROJECT_DIR/bin/tools/RunFunctions
./Allrun.pre
#-- Run on single processor
#runApplication `getApplication` &
# Simulated external solver
#runApplication ./externalSolver
# Decompose
runApplication decomposePar -allRegions
# Run OpenFOAM
runParallel `getApplication` 4 &
# Simulated external solver
runApplication ./externalSolver
# Reconstruct
runApplication reconstructPar -allRegions
# ----------------------------------------------------------------- end-of-file

View File

@ -0,0 +1,33 @@
#!/bin/sh
cd ${0%/*} || exit 1 # Run from this directory
# Source tutorial run functions
. $WM_PROJECT_DIR/bin/tools/RunFunctions
runApplication blockMesh
runApplication topoSet
runApplication splitMeshRegions -cellZones -overwrite
# remove fluid fields from solid regions (important for post-processing)
for i in heater leftSolid rightSolid
do
rm -f 0*/$i/{nut,alphat,epsilon,k,U,p_rgh}
done
for i in bottomWater topAir heater leftSolid rightSolid
do
changeDictionary -region $i > log.changeDictionary.$i 2>&1
done
# Create coupling geometry
runApplication createExternalCoupledPatchGeometry \
-regions '(topAir heater)' coupleGroup
echo
echo "creating files for paraview post-processing"
echo
paraFoam -touchAll
# ----------------------------------------------------------------- end-of-file

View File

@ -0,0 +1,3 @@
Modification of the heatTransfer chtMultiRegionFoam tutorial that demonstrates
the externalCoupled functionObject in combination with the ./externalSolver
script to simulate coupling to an external code.

View File

@ -10,7 +10,6 @@ FoamFile
version 2.0; version 2.0;
format ascii; format ascii;
class uniformDimensionedVectorField; class uniformDimensionedVectorField;
location "constant";
object g; object g;
} }
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -18,5 +17,4 @@ FoamFile
dimensions [0 1 -2 0 0 0 0]; dimensions [0 1 -2 0 0 0 0];
value (0 -9.81 0); value (0 -9.81 0);
// ************************************************************************* // // ************************************************************************* //

View File

@ -0,0 +1,22 @@
/*--------------------------------*- 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 radiationProperties;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
radiation off;
radiationModel none;
// ************************************************************************* //

View File

@ -9,39 +9,43 @@ FoamFile
{ {
version 2.0; version 2.0;
format ascii; format ascii;
class volScalarField; class dictionary;
location "0"; object thermophysicalProperties;
object k;
} }
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
dimensions [0 2 -2 0 0 0 0]; thermoType
internalField uniform 3.75e-04;
boundaryField
{ {
frontAndBack type heRhoThermo;
mixture pureMixture;
transport const;
thermo hConst;
equationOfState rhoConst;
specie specie;
energy sensibleEnthalpy;
}
mixture
{
specie
{ {
type kqRWallFunction; nMoles 1;
value uniform 3.75e-04; molWeight 18;
} }
topAndBottom equationOfState
{ {
type kqRWallFunction; rho 1000;
value uniform 3.75e-04;
} }
hot thermodynamics
{ {
type kqRWallFunction; Cp 4181;
value uniform 3.75e-04; Hf 0;
} }
cold transport
{ {
type kqRWallFunction; mu 959e-6;
value uniform 3.75e-04; Pr 6.62;
} }
} }
// ************************************************************************* // // ************************************************************************* //

View File

@ -0,0 +1,19 @@
/*--------------------------------*- 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 turbulenceProperties;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
simulationType laminar;
// ************************************************************************* //

View File

@ -0,0 +1,23 @@
/*--------------------------------*- 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;
location "constant";
object radiationProperties;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
radiation off;
radiationModel none;
// ************************************************************************* //

View File

@ -9,39 +9,45 @@ FoamFile
{ {
version 2.0; version 2.0;
format ascii; format ascii;
class volScalarField; class dictionary;
location "0"; object thermophysicalProperties;
object nut;
} }
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
dimensions [0 2 -1 0 0 0 0]; thermoType
internalField uniform 0;
boundaryField
{ {
frontAndBack type heSolidThermo;
mixture pureMixture;
transport constIso;
thermo hConst;
equationOfState rhoConst;
specie specie;
energy sensibleEnthalpy;
}
mixture
{
specie
{ {
type nutUWallFunction; nMoles 1;
value uniform 0; molWeight 50;
} }
topAndBottom
transport
{ {
type nutUWallFunction; kappa 80;
value uniform 0;
} }
hot
thermodynamics
{ {
type nutUWallFunction; Hf 0;
value uniform 0; Cp 450;
} }
cold
equationOfState
{ {
type nutUWallFunction; rho 8000;
value uniform 0;
} }
} }
// ************************************************************************* // // ************************************************************************* //

View File

@ -14,66 +14,77 @@ FoamFile
} }
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
convertToMeters 0.001; convertToMeters 1;
vertices vertices
( (
( 0 0 -260) (-0.1 -0.04 -0.05)
(76 0 -260) ( 0.1 -0.04 -0.05)
(76 2180 -260) ( 0.1 0.04 -0.05)
( 0 2180 -260) (-0.1 0.04 -0.05)
( 0 0 260) (-0.1 -0.04 0.05)
(76 0 260) ( 0.1 -0.04 0.05)
(76 2180 260) ( 0.1 0.04 0.05)
( 0 2180 260) (-0.1 0.04 0.05)
);
blocks
(
hex (0 1 2 3 4 5 6 7) (30 10 10) simpleGrading (1 1 1)
); );
edges edges
( (
); );
blocks
(
hex (0 1 2 3 4 5 6 7) (35 150 15) simpleGrading (1 1 1)
);
boundary boundary
( (
frontAndBack maxY
{ {
type wall; type wall;
faces faces
( (
(0 1 5 4) (3 7 6 2)
(2 3 7 6)
); );
} }
minX
topAndBottom {
type patch;
faces
(
(0 4 7 3)
);
}
maxX
{
type patch;
faces
(
(2 6 5 1)
);
}
minY
{
type wall;
faces
(
(1 5 4 0)
);
}
minZ
{
type wall;
faces
(
(0 3 2 1)
);
}
maxZ
{ {
type wall; type wall;
faces faces
( (
(4 5 6 7) (4 5 6 7)
(3 2 1 0)
);
}
hot
{
type wall;
faces
(
(6 5 1 2)
);
}
cold
{
type wall;
faces
(
(4 7 3 0)
); );
} }
); );
@ -81,3 +92,5 @@ boundary
mergePatchPairs mergePatchPairs
( (
); );
// ************************************************************************* //

View File

@ -1,7 +1,7 @@
/*--------------------------------*- C++ -*----------------------------------*\ /*--------------------------------*- C++ -*----------------------------------*\
| ========= | | | ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: dev | | \\ / O peration | Version: dev-OpenCFD.feature-externalCoupled |
| \\ / A nd | Web: www.OpenFOAM.org | | \\ / A nd | Web: www.OpenFOAM.org |
| \\/ M anipulation | | | \\/ M anipulation | |
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
@ -15,35 +15,47 @@ FoamFile
} }
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
4 6
( (
frontAndBack maxY
{ {
type wall; type wall;
inGroups 1(wall); inGroups 1(wall);
nFaces 1050; nFaces 300;
startFace 228225; startFace 8300;
} }
topAndBottom minX
{ {
type wall; type patch;
inGroups 1(wall); nFaces 100;
nFaces 10500; startFace 8600;
startFace 229275;
} }
hot maxX
{ {
type wall; type patch;
inGroups 1(wall); nFaces 100;
nFaces 2250; startFace 8700;
startFace 239775;
} }
cold minY
{ {
type wall; type wall;
inGroups 1(wall); inGroups 1(wall);
nFaces 2250; nFaces 300;
startFace 242025; startFace 8800;
}
minZ
{
type wall;
inGroups 1(wall);
nFaces 300;
startFace 9100;
}
maxZ
{
type wall;
inGroups 1(wall);
nFaces 300;
startFace 9400;
} }
) )

View File

@ -0,0 +1,24 @@
/*--------------------------------*- 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;
location "constant";
object regionProperties;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
regions
(
fluid (bottomWater topAir)
solid (heater leftSolid rightSolid)
);
// ************************************************************************* //

View File

@ -0,0 +1 @@
../bottomWater/radiationProperties

View File

@ -10,7 +10,7 @@ FoamFile
version 2.0; version 2.0;
format ascii; format ascii;
class dictionary; class dictionary;
location "constant"; location "constant/bottomWater";
object thermophysicalProperties; object thermophysicalProperties;
} }
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -31,17 +31,17 @@ mixture
specie specie
{ {
nMoles 1; nMoles 1;
molWeight 28.96; molWeight 28.9;
} }
thermodynamics thermodynamics
{ {
Cp 1004.4; Cp 1000;
Hf 0; Hf 0;
} }
transport transport
{ {
mu 1.831e-05; mu 1.8e-05;
Pr 0.705; Pr 0.7;
} }
} }

View File

@ -0,0 +1 @@
../bottomWater/turbulenceProperties

View File

@ -1,20 +1,29 @@
#!/bin/sh #!/bin/sh
# #
# Dummy external solver to communicate with OpenFOAM via externalCoupled # Dummy external solver to communicate with OpenFOAM via externalCoupled
# boundary conditions # functionObject
# #
# Functionality is hard-coded for this particular test case # Functionality is hard-coded for this particular test case
# - patch temperatures increased by 1K on each step # - patch temperatures increased by 1K on each step
# #
cd ${0%/*} || exit 1 # run from this directory cd ${0%/*} || exit 1 # Run from this directory
# Check for unassigned variables
set -u
echo "Executing dummy external solver" echo "Executing dummy external solver"
commsDir="comms" commsDir="comms"
regionGroupName="heater_topAir"
patchGroupName="coupleGroup"
fieldName="T"
lockFile="${commsDir}/OpenFOAM.lock" lockFile="${commsDir}/OpenFOAM.lock"
dataFile="${commsDir}/data" dataFile="${commsDir}/${regionGroupName}/${patchGroupName}/${fieldName}"
waitSec=1 waitSec=1
timeOut=10 timeOut=10
nSteps=200 # maximum number of time steps. Note: should be more than
# number of iterations on the OpenFOAM side
refGrad=0 refGrad=0
valueFraction=1 valueFraction=1
@ -27,16 +36,21 @@ init()
{ {
log "initialisation: creating ${dataFile}.in" log "initialisation: creating ${dataFile}.in"
# Hard-coded for 2 patches of size 2250 # Hard-coded for patch of size 8 (heater/minY)
n=2250 n1=8
refCold=283 refValue1=500
refHot=303
touch "${dataFile}.in" touch "${dataFile}.in"
for i in $(seq 1 $n); do log "initialisation: adding $n1 data elements with refValue $refValue1"
echo "$refHot $refGrad $valueFraction" >> "${dataFile}.in" for i in $(seq 1 $n1); do
echo "$refValue1 $refGrad $valueFraction" >> "${dataFile}.in"
done done
for i in $(seq 1 $n); do
echo "$refCold $refGrad $valueFraction" >> "${dataFile}.in" # Hard-coded for patch of size 40 (topAir/minX)
n2=40
refValue2=300
log "initialisation: adding $n2 data elements with refValue $refValue2"
for i in $(seq 1 $n2); do
echo "$refValue2 $refGrad $valueFraction" >> "${dataFile}.in"
done done
# create lock file to pass control to OF # create lock file to pass control to OF
@ -44,6 +58,10 @@ init()
} }
# create the comms directory
mkdir -p ${commsDir}/${regionGroupName}/${patchGroupName}
# tutorial case employs the 'initByExternalOption', so we need to provide # tutorial case employs the 'initByExternalOption', so we need to provide
# the initial values # the initial values
init init
@ -51,7 +69,7 @@ init
totalWait=0 totalWait=0
step=0 step=0
while [ 1 ]; do while [ $step -lt $nSteps ]; do
if [ -f $lockFile ]; then if [ -f $lockFile ]; then
log "found lock file ${lockFile} - waiting" log "found lock file ${lockFile} - waiting"
totalWait=$(expr $totalWait + $waitSec) totalWait=$(expr $totalWait + $waitSec)
@ -70,9 +88,10 @@ while [ 1 ]; do
log "sleeping for $waitSec secs to simulate external process" log "sleeping for $waitSec secs to simulate external process"
sleep $waitSec sleep $waitSec
log "creating ${dataFile}.in" log "updating ${dataFile}.in from ${dataFile}.out"
awk '{if( $1 != "#" ){print $2+1 " 0 1"}}' ${dataFile}.out > ${dataFile}.in awk '{if( $1 != "#" ){print $1+1 " 0 1"}}' \
${dataFile}.out | tee ${dataFile}.in
log "creating lock file ${lockFile}" log "creating lock file ${lockFile}"
touch ${lockFile} touch ${lockFile}

View File

@ -0,0 +1,3 @@
fvSolution is used for outer correctors specification.
fvSchemes is only so that pre-processing activities can proceed

View File

@ -0,0 +1,173 @@
/*--------------------------------*- 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
{
U
{
internalField uniform (0.001 0 0);
boundaryField
{
minX
{
type fixedValue;
value uniform (0.001 0 0);
}
maxX
{
type inletOutlet;
inletValue uniform (0 0 0);
}
".*"
{
type fixedValue;
value uniform (0 0 0);
}
}
}
T
{
internalField uniform 300;
boundaryField
{
minX
{
type fixedValue;
value uniform 300;
}
maxX
{
type inletOutlet;
inletValue uniform 300;
}
".*"
{
type zeroGradient;
value uniform 300;
}
"bottomWater_to_.*"
{
type compressible::turbulentTemperatureCoupledBaffleMixed;
Tnbr T;
kappa fluidThermo;
kappaName none;
value uniform 300;
}
}
}
epsilon
{
internalField uniform 0.01;
boundaryField
{
minX
{
type fixedValue;
value uniform 0.01;
}
maxX
{
type inletOutlet;
inletValue uniform 0.01;
}
".*"
{
type epsilonWallFunction;
value uniform 0.01;
}
}
}
k
{
internalField uniform 0.1;
boundaryField
{
minX
{
type inletOutlet;
inletValue uniform 0.1;
}
maxX
{
type zeroGradient;
value uniform 0.1;
}
".*"
{
type kqRWallFunction;
value uniform 0.1;
}
}
}
p_rgh
{
internalField uniform 0;
boundaryField
{
minX
{
type zeroGradient;
value uniform 0;
}
maxX
{
type fixedValue;
value uniform 0;
}
".*"
{
type fixedFluxPressure;
value uniform 0;
}
}
}
p
{
internalField uniform 0;
boundaryField
{
".*"
{
type calculated;
value uniform 0;
}
}
}
}
// ************************************************************************* //

View File

@ -0,0 +1,72 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: dev |
| \\ / A nd | Web: www.OpenFOAM.org |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class dictionary;
note "mesh decomposition control dictionary";
location "system";
object decomposeParDict;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
numberOfSubdomains 4;
//- Keep owner and neighbour on same processor for faces in zones:
// preserveFaceZones (heater solid1 solid3);
method scotch;
// method hierarchical;
// method simple;
// method manual;
simpleCoeffs
{
n (2 2 1);
delta 0.001;
}
hierarchicalCoeffs
{
n (2 2 1);
delta 0.001;
order xyz;
}
scotchCoeffs
{
//processorWeights
//(
// 1
// 1
// 1
// 1
//);
//writeGraph true;
//strategy "b";
}
manualCoeffs
{
dataFile "decompositionData";
}
//// Is the case distributed
//distributed yes;
//// Per slave (so nProcs-1 entries) the directory above the case.
//roots
//(
// "/tmp"
// "/tmp"
//);
// ************************************************************************* //

View File

@ -16,7 +16,7 @@ FoamFile
ddtSchemes ddtSchemes
{ {
default steadyState; default Euler;
} }
gradSchemes gradSchemes
@ -28,18 +28,19 @@ divSchemes
{ {
default none; default none;
div(phi,U) bounded Gauss limitedLinear 0.2; div(phi,U) Gauss upwind;
div(phi,K) bounded Gauss limitedLinear 0.2; div(phi,K) Gauss linear;
div(phi,h) bounded Gauss limitedLinear 0.2; div(phi,h) Gauss upwind;
div(phi,k) bounded Gauss limitedLinear 0.2; div(phi,k) Gauss upwind;
div(phi,epsilon) bounded Gauss limitedLinear 0.2; div(phi,epsilon) Gauss upwind;
div(phi,omega) bounded Gauss limitedLinear 0.2; div(phi,R) Gauss upwind;
div(R) Gauss linear;
div(((rho*nuEff)*dev2(T(grad(U))))) Gauss linear; div(((rho*nuEff)*dev2(T(grad(U))))) Gauss linear;
} }
laplacianSchemes laplacianSchemes
{ {
default Gauss linear orthogonal; default Gauss linear corrected;
} }
interpolationSchemes interpolationSchemes
@ -49,13 +50,13 @@ interpolationSchemes
snGradSchemes snGradSchemes
{ {
default orthogonal; default corrected;
} }
wallDist fluxRequired
{ {
method meshWave; default no;
p_rgh;
} }
// ************************************************************************* // // ************************************************************************* //

View File

@ -10,68 +10,78 @@ FoamFile
version 2.0; version 2.0;
format ascii; format ascii;
class dictionary; class dictionary;
location "system";
object fvSolution; object fvSolution;
} }
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
solvers solvers
{ {
rho
{
solver PCG;
preconditioner DIC;
tolerance 1e-7;
relTol 0.1;
}
rhoFinal
{
$rho;
tolerance 1e-7;
relTol 0;
}
p_rgh p_rgh
{ {
solver GAMG; solver GAMG;
tolerance 1e-7; tolerance 1e-7;
relTol 0.01; relTol 0.01;
smoother DICGaussSeidel; smoother GaussSeidel;
cacheAgglomeration true; cacheAgglomeration true;
nCellsInCoarsestLevel 10; nCellsInCoarsestLevel 10;
agglomerator faceAreaPair; agglomerator faceAreaPair;
mergeLevels 1; mergeLevels 1;
} }
"(U|h|k|epsilon|omega)" p_rghFinal
{ {
solver PBiCG; $p_rgh;
preconditioner DILU; tolerance 1e-7;
tolerance 1e-8; relTol 0;
relTol 0.1; }
"(U|h|k|epsilon|R)"
{
solver PBiCG;
preconditioner DILU;
tolerance 1e-7;
relTol 0.1;
}
"(U|h|k|epsilon|R)Final"
{
$U;
tolerance 1e-7;
relTol 0;
} }
} }
SIMPLE PIMPLE
{ {
momentumPredictor yes; momentumPredictor on;
nCorrectors 2;
nNonOrthogonalCorrectors 0; nNonOrthogonalCorrectors 0;
pRefCell 0;
pRefValue 0;
residualControl
{
p_rgh 1e-2;
U 1e-3;
h 1e-3;
// possibly check turbulence fields
"(k|epsilon|omega)" 1e-3;
}
} }
relaxationFactors relaxationFactors
{ {
fields
{
rho 1.0;
p_rgh 0.7;
}
equations equations
{ {
U 0.3; "h.*" 1;
h 0.3; "U.*" 1;
"(k|epsilon|omega)" 0.7;
} }
} }
// ************************************************************************* // // ************************************************************************* //

View File

@ -0,0 +1,96 @@
/*--------------------------------*- 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;
location "system";
object controlDict;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// Library defines new boundary conditions
libs ("libOpenFOAM.so" "libjobControl.so");
application chtMultiRegionFoam;
startFrom startTime;
startTime 0;
stopAt endTime;
endTime 1;
deltaT 0.001;
writeControl adjustableRunTime;
writeInterval 0.1;
purgeWrite 0;
writeFormat ascii;
writePrecision 8;
writeCompression off;
timeFormat general;
timePrecision 6;
runTimeModifiable yes;
maxCo 0.6;
// Maximum diffusion number
maxDi 10.0;
adjustTimeStep yes;
functions
{
externalCoupled
{
// Where to load it from (if not already in solver)
functionObjectLibs ("libjobControl.so");
type externalCoupled;
// Directory to use for communication
commsDir "${FOAM_CASE}/comms";
// Does external process start first
initByExternal true;
// Additional output
log true;
regions
{
// Region name (wildcards allowed)
"(topAir|heater)"
{
// In topAir adjust the minX patch (fixedValue)
// Patch or patchGroup
coupleGroup
{
// Fields to output in commsDir
writeFields (T);
// Fields to read from commsDir
readFields (T);
}
}
}
}
}
// ************************************************************************* //

View File

@ -0,0 +1,60 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: dev |
| \\ / A nd | Web: www.OpenFOAM.org |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class dictionary;
note "mesh decomposition control dictionary";
location "system";
object decomposeParDict;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
numberOfSubdomains 4;
//- Keep owner and neighbour on same processor for faces in zones:
// preserveFaceZones (heater solid1 solid3);
method scotch;
// method hierarchical;
// method simple;
// method manual;
simpleCoeffs
{
n (2 2 1);
delta 0.001;
}
hierarchicalCoeffs
{
n (2 2 1);
delta 0.001;
order xyz;
}
manualCoeffs
{
dataFile "decompositionData";
}
//// Is the case distributed
//distributed yes;
//// Per slave (so nProcs-1 entries) the directory above the case.
//roots
//(
// "/tmp"
// "/tmp"
//);
// ************************************************************************* //

View File

@ -10,19 +10,36 @@ FoamFile
version 2.0; version 2.0;
format ascii; format ascii;
class dictionary; class dictionary;
location "system"; object fvSchemes;
object decomposeParDict;
} }
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
numberOfSubdomains 4; ddtSchemes
{
method simple; }
simpleCoeffs gradSchemes
{
}
divSchemes
{
}
laplacianSchemes
{
}
interpolationSchemes
{
}
snGradSchemes
{
}
fluxRequired
{ {
n (2 2 1);
delta 0.001;
} }

View File

@ -10,20 +10,13 @@ FoamFile
version 2.0; version 2.0;
format ascii; format ascii;
class dictionary; class dictionary;
object RASProperties; object fvSolution;
} }
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
simulationType RAS; PIMPLE
RAS
{ {
RASModel kOmegaSST; nOuterCorrectors 1;
turbulence on;
printCoeffs on;
} }
// ************************************************************************* // // ************************************************************************* //

View File

@ -0,0 +1,77 @@
/*--------------------------------*- 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
{
minY
{
type patch;
inGroups (coupleGroup);
}
minZ
{
type patch;
}
maxZ
{
type patch;
}
}
T
{
internalField uniform 300;
boundaryField
{
".*"
{
type zeroGradient;
value uniform 300;
}
"heater_to_.*"
{
type compressible::turbulentTemperatureCoupledBaffleMixed;
Tnbr T;
kappa solidThermo;
kappaName none;
value uniform 300;
}
heater_to_leftSolid
{
type compressible::turbulentTemperatureCoupledBaffleMixed;
Tnbr T;
kappa solidThermo;
kappaName none;
thicknessLayers (1e-3);
kappaLayers (5e-4);
value uniform 300;
}
minY
{
type fixedValue;
value uniform 500;
}
}
}
}
// ************************************************************************* //

View File

@ -10,39 +10,35 @@ FoamFile
version 2.0; version 2.0;
format ascii; format ascii;
class dictionary; class dictionary;
object controlDict; location "system";
object decomposeParDict;
} }
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
application buoyantSimpleFoam; numberOfSubdomains 4;
startFrom startTime; method scotch;
startTime 0; simpleCoeffs
{
n (2 2 1);
delta 0.001;
}
stopAt endTime; hierarchicalCoeffs
{
n (2 2 1);
delta 0.001;
order xyz;
}
endTime 100; scotchCoeffs
{
deltaT 1; }
writeControl timeStep;
writeInterval 10;
purgeWrite 0;
writeFormat ascii;
writePrecision 6;
writeCompression off;
timeFormat general;
timePrecision 6;
runTimeModifiable true;
manualCoeffs
{
dataFile "decompositionData";
}
// ************************************************************************* // // ************************************************************************* //

View File

@ -0,0 +1,53 @@
/*--------------------------------*- 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 fvSchemes;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
ddtSchemes
{
default Euler;
}
gradSchemes
{
default Gauss linear;
}
divSchemes
{
default none;
}
laplacianSchemes
{
default none;
laplacian(alpha,h) Gauss linear corrected;
}
interpolationSchemes
{
default linear;
}
snGradSchemes
{
default corrected;
}
fluxRequired
{
default no;
}
// ************************************************************************* //

View File

@ -0,0 +1,40 @@
/*--------------------------------*- 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 fvSolution;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
solvers
{
h
{
solver PCG;
preconditioner DIC;
tolerance 1e-06;
relTol 0.1;
}
hFinal
{
$h;
tolerance 1e-06;
relTol 0;
}
}
PIMPLE
{
nNonOrthogonalCorrectors 0;
}
// ************************************************************************* //

View File

@ -0,0 +1,65 @@
/*--------------------------------*- 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
{
minZ
{
type patch;
}
maxZ
{
type patch;
}
}
T
{
internalField uniform 300;
boundaryField
{
".*"
{
type zeroGradient;
value uniform 300;
}
"leftSolid_to_.*"
{
type compressible::turbulentTemperatureCoupledBaffleMixed;
Tnbr T;
kappa solidThermo;
kappaName none;
value uniform 300;
}
leftSolid_to_heater
{
type compressible::turbulentTemperatureCoupledBaffleMixed;
Tnbr T;
kappa solidThermo;
kappaName none;
thicknessLayers (1e-3);
kappaLayers (5e-4);
value uniform 300;
}
}
}
}
// ************************************************************************* //

View File

@ -0,0 +1,44 @@
/*--------------------------------*- 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;
location "system";
object decomposeParDict;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
numberOfSubdomains 4;
method scotch;
simpleCoeffs
{
n (2 2 1);
delta 0.001;
}
hierarchicalCoeffs
{
n (2 2 1);
delta 0.001;
order xyz;
}
scotchCoeffs
{
}
manualCoeffs
{
dataFile "decompositionData";
}
// ************************************************************************* //

View File

@ -0,0 +1,54 @@
/*--------------------------------*- 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
{
minZ
{
type patch;
}
maxZ
{
type patch;
}
}
T
{
internalField uniform 300;
boundaryField
{
".*"
{
type zeroGradient;
value uniform 300;
}
"rightSolid_to_.*"
{
type compressible::turbulentTemperatureCoupledBaffleMixed;
Tnbr T;
kappa solidThermo;
kappaName none;
value uniform 300;
}
}
}
}
// ************************************************************************* //

View File

@ -0,0 +1,44 @@
/*--------------------------------*- 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;
location "system";
object decomposeParDict;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
numberOfSubdomains 4;
method scotch;
simpleCoeffs
{
n (2 2 1);
delta 0.001;
}
hierarchicalCoeffs
{
n (2 2 1);
delta 0.001;
order xyz;
}
scotchCoeffs
{
}
manualCoeffs
{
dataFile "decompositionData";
}
// ************************************************************************* //

View File

@ -0,0 +1,179 @@
/*--------------------------------*- 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
{
minX
{
inGroups (coupleGroup);
}
}
U
{
internalField uniform (0.1 0 0);
boundaryField
{
".*"
{
type fixedValue;
value uniform (0 0 0);
}
minX
{
type fixedValue;
value uniform ( 0.1 0 0 );
}
maxX
{
type inletOutlet;
inletValue uniform ( 0 0 0 );
value uniform ( 0.1 0 0 );
}
}
}
T
{
internalField uniform 300;
boundaryField
{
".*"
{
type zeroGradient;
}
minX
{
type fixedValue;
value uniform 300;
}
maxX
{
type inletOutlet;
inletValue uniform 300;
value uniform 300;
}
"topAir_to_.*"
{
type compressible::turbulentTemperatureCoupledBaffleMixed;
Tnbr T;
kappa fluidThermo;
kappaName none;
value uniform 300;
}
}
}
epsilon
{
internalField uniform 0.01;
boundaryField
{
".*"
{
type epsilonWallFunction;
value uniform 0.01;
}
minX
{
type fixedValue;
value uniform 0.01;
}
maxX
{
type inletOutlet;
inletValue uniform 0.01;
value uniform 0.01;
}
}
}
k
{
internalField uniform 0.1;
boundaryField
{
".*"
{
type kqRWallFunction;
value uniform 0.1;
}
minX
{
type fixedValue;
value uniform 0.1;
}
maxX
{
type inletOutlet;
inletValue uniform 0.1;
value uniform 0.1;
}
}
}
p_rgh
{
internalField uniform 1e5;
boundaryField
{
".*"
{
type fixedFluxPressure;
value uniform 1e5;
}
maxX
{
type fixedValue;
value uniform 1e5;
}
}
}
p
{
internalField uniform 1e5;
boundaryField
{
".*"
{
type calculated;
value uniform 1e5;
}
maxX
{
type calculated;
value uniform 1e5;
}
}
}
}
// ************************************************************************* //

View File

@ -0,0 +1,72 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: dev |
| \\ / A nd | Web: www.OpenFOAM.org |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class dictionary;
note "mesh decomposition control dictionary";
location "system";
object decomposeParDict;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
numberOfSubdomains 4;
//- Keep owner and neighbour on same processor for faces in zones:
// preserveFaceZones (heater solid1 solid3);
method scotch;
// method hierarchical;
// method simple;
// method manual;
simpleCoeffs
{
n (2 2 1);
delta 0.001;
}
hierarchicalCoeffs
{
n (2 2 1);
delta 0.001;
order xyz;
}
scotchCoeffs
{
//processorWeights
//(
// 1
// 1
// 1
// 1
//);
//writeGraph true;
//strategy "b";
}
manualCoeffs
{
dataFile "decompositionData";
}
//// Is the case distributed
//distributed yes;
//// Per slave (so nProcs-1 entries) the directory above the case.
//roots
//(
// "/tmp"
// "/tmp"
//);
// ************************************************************************* //

View File

@ -0,0 +1 @@
../bottomWater/fvSchemes

View File

@ -0,0 +1 @@
../bottomWater/fvSolution

View File

@ -0,0 +1,178 @@
/*--------------------------------*- 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 topoSetDict;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
actions
(
// Heater
{
name heaterCellSet;
type cellSet;
action new;
source boxToCell;
sourceInfo
{
box (-0.01001 0 -100 )(0.01001 0.00999 100);
}
}
{
name heaterCellSet;
type cellSet;
action add;
source boxToCell;
sourceInfo
{
box (-0.01001 -100 -0.01001)(0.01001 0.00999 0.01001);
}
}
{
name heater;
type cellZoneSet;
action new;
source setToCellZone;
sourceInfo
{
set heaterCellSet;
}
}
// leftSolid
{
name leftSolidCellSet;
type cellSet;
action new;
source boxToCell;
sourceInfo
{
box (-100 0 -100 )(-0.01001 0.00999 100);
}
}
{
name leftSolid;
type cellZoneSet;
action new;
source setToCellZone;
sourceInfo
{
set leftSolidCellSet;
}
}
// rightSolid
{
name rightSolidCellSet;
type cellSet;
action new;
source boxToCell;
sourceInfo
{
box (0.01001 0 -100 )(100 0.00999 100);
}
}
{
name rightSolid;
type cellZoneSet;
action new;
source setToCellZone;
sourceInfo
{
set rightSolidCellSet;
}
}
// topAir
{
name topAirCellSet;
type cellSet;
action new;
source boxToCell;
sourceInfo
{
box (-100 0.00999 -100 )(100 100 100);
}
}
{
name topAir;
type cellZoneSet;
action new;
source setToCellZone;
sourceInfo
{
set topAirCellSet;
}
}
// bottomWater is all the other cells
{
name bottomWaterCellSet;
type cellSet;
action new;
source cellToCell;
sourceInfo
{
set heaterCellSet;
}
}
{
name bottomWaterCellSet;
type cellSet;
action add;
source cellToCell;
sourceInfo
{
set leftSolidCellSet;
}
}
{
name bottomWaterCellSet;
type cellSet;
action add;
source cellToCell;
sourceInfo
{
set rightSolidCellSet;
}
}
{
name bottomWaterCellSet;
type cellSet;
action add;
source cellToCell;
sourceInfo
{
set topAirCellSet;
}
}
{
name bottomWaterCellSet;
type cellSet;
action invert;
}
{
name bottomWater;
type cellZoneSet;
action new;
source setToCellZone;
sourceInfo
{
set bottomWaterCellSet;
}
}
);
// ************************************************************************* //