mirror of
https://develop.openfoam.com/Development/openfoam.git
synced 2025-11-28 03:28:01 +00:00
Merge branch 'master' of /home/dm4/OpenFOAM/OpenFOAM-dev
This commit is contained in:
@ -1,3 +0,0 @@
|
|||||||
buoyantBaffleSimpleFoam.C
|
|
||||||
|
|
||||||
EXE = $(FOAM_APPBIN)/buoyantBaffleSimpleFoam
|
|
||||||
@ -1,22 +0,0 @@
|
|||||||
EXE_INC = \
|
|
||||||
-I$(LIB_SRC)/thermophysicalModels/basic/lnInclude \
|
|
||||||
-I$(LIB_SRC)/thermophysicalModels/basicSolidThermo/lnInclude \
|
|
||||||
-I$(LIB_SRC)/thermophysicalModels/specie/lnInclude \
|
|
||||||
-I$(LIB_SRC)/meshTools/lnInclude \
|
|
||||||
-I$(LIB_SRC)/turbulenceModels \
|
|
||||||
-I$(LIB_SRC)/turbulenceModels/compressible/RAS/lnInclude \
|
|
||||||
-I$(LIB_SRC)/finiteVolume/cfdTools \
|
|
||||||
-I$(LIB_SRC)/finiteVolume/lnInclude \
|
|
||||||
-I$(LIB_SRC)/regionModels/regionModel/lnInclude \
|
|
||||||
-I$(LIB_SRC)/regionModels/thermoBaffleModels/lnInclude
|
|
||||||
|
|
||||||
EXE_LIBS = \
|
|
||||||
-lmeshTools \
|
|
||||||
-lbasicThermophysicalModels \
|
|
||||||
-lspecie \
|
|
||||||
-lcompressibleTurbulenceModel \
|
|
||||||
-lcompressibleRASModels \
|
|
||||||
-lfiniteVolume \
|
|
||||||
-lmeshTools \
|
|
||||||
-lthermoBaffleModels \
|
|
||||||
-lregionModels
|
|
||||||
@ -1,25 +0,0 @@
|
|||||||
// Solve the Momentum equation
|
|
||||||
|
|
||||||
tmp<fvVectorMatrix> UEqn
|
|
||||||
(
|
|
||||||
fvm::div(phi, U)
|
|
||||||
+ turbulence->divDevRhoReff(U)
|
|
||||||
);
|
|
||||||
|
|
||||||
UEqn().relax();
|
|
||||||
|
|
||||||
if (simple.momentumPredictor())
|
|
||||||
{
|
|
||||||
solve
|
|
||||||
(
|
|
||||||
UEqn()
|
|
||||||
==
|
|
||||||
fvc::reconstruct
|
|
||||||
(
|
|
||||||
(
|
|
||||||
- ghf*fvc::snGrad(rho)
|
|
||||||
- fvc::snGrad(p_rgh)
|
|
||||||
)*mesh.magSf()
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@ -1,83 +0,0 @@
|
|||||||
/*---------------------------------------------------------------------------*\
|
|
||||||
========= |
|
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
|
||||||
\\ / O peration |
|
|
||||||
\\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
|
|
||||||
\\/ M anipulation |
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
License
|
|
||||||
This file is part of OpenFOAM.
|
|
||||||
|
|
||||||
OpenFOAM is free software: you can redistribute it and/or modify it
|
|
||||||
under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
|
||||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
||||||
for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
Application
|
|
||||||
buoyantBaffleSimpleFoam
|
|
||||||
|
|
||||||
Description
|
|
||||||
Steady-state solver for buoyant, turbulent flow of compressible fluids
|
|
||||||
using thermal baffles
|
|
||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
#include "fvCFD.H"
|
|
||||||
#include "basicPsiThermo.H"
|
|
||||||
#include "RASModel.H"
|
|
||||||
#include "fixedGradientFvPatchFields.H"
|
|
||||||
#include "simpleControl.H"
|
|
||||||
#include "thermoBaffleModel.H"
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
|
||||||
{
|
|
||||||
#include "setRootCase.H"
|
|
||||||
#include "createTime.H"
|
|
||||||
#include "createMesh.H"
|
|
||||||
#include "readGravitationalAcceleration.H"
|
|
||||||
#include "createFields.H"
|
|
||||||
#include "initContinuityErrs.H"
|
|
||||||
|
|
||||||
simpleControl simple(mesh);
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
Info<< "\nStarting time loop\n" << endl;
|
|
||||||
|
|
||||||
while (simple.loop())
|
|
||||||
{
|
|
||||||
Info<< "Time = " << runTime.timeName() << nl << endl;
|
|
||||||
|
|
||||||
// Pressure-velocity SIMPLE corrector
|
|
||||||
{
|
|
||||||
#include "UEqn.H"
|
|
||||||
#include "hEqn.H"
|
|
||||||
#include "pEqn.H"
|
|
||||||
}
|
|
||||||
|
|
||||||
turbulence->correct();
|
|
||||||
|
|
||||||
runTime.write();
|
|
||||||
|
|
||||||
Info<< "ExecutionTime = " << runTime.elapsedCpuTime() << " s"
|
|
||||||
<< " ClockTime = " << runTime.elapsedClockTime() << " s"
|
|
||||||
<< nl << endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
Info<< "End\n" << endl;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
|
||||||
@ -1,94 +0,0 @@
|
|||||||
Info<< "Reading thermophysical properties\n" << endl;
|
|
||||||
|
|
||||||
autoPtr<basicPsiThermo> pThermo
|
|
||||||
(
|
|
||||||
basicPsiThermo::New(mesh)
|
|
||||||
);
|
|
||||||
basicPsiThermo& thermo = pThermo();
|
|
||||||
|
|
||||||
volScalarField rho
|
|
||||||
(
|
|
||||||
IOobject
|
|
||||||
(
|
|
||||||
"rho",
|
|
||||||
runTime.timeName(),
|
|
||||||
mesh,
|
|
||||||
IOobject::NO_READ,
|
|
||||||
IOobject::NO_WRITE
|
|
||||||
),
|
|
||||||
thermo.rho()
|
|
||||||
);
|
|
||||||
|
|
||||||
volScalarField& p = thermo.p();
|
|
||||||
volScalarField& h = thermo.h();
|
|
||||||
const volScalarField& psi = thermo.psi();
|
|
||||||
|
|
||||||
Info<< "Reading field U\n" << endl;
|
|
||||||
volVectorField U
|
|
||||||
(
|
|
||||||
IOobject
|
|
||||||
(
|
|
||||||
"U",
|
|
||||||
runTime.timeName(),
|
|
||||||
mesh,
|
|
||||||
IOobject::MUST_READ,
|
|
||||||
IOobject::AUTO_WRITE
|
|
||||||
),
|
|
||||||
mesh
|
|
||||||
);
|
|
||||||
|
|
||||||
#include "compressibleCreatePhi.H"
|
|
||||||
|
|
||||||
Info<< "Creating turbulence model\n" << endl;
|
|
||||||
autoPtr<compressible::RASModel> turbulence
|
|
||||||
(
|
|
||||||
compressible::RASModel::New
|
|
||||||
(
|
|
||||||
rho,
|
|
||||||
U,
|
|
||||||
phi,
|
|
||||||
thermo
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
Info<< "Calculating field g.h\n" << endl;
|
|
||||||
volScalarField gh("gh", g & mesh.C());
|
|
||||||
surfaceScalarField ghf("ghf", g & mesh.Cf());
|
|
||||||
|
|
||||||
Info<< "Reading field p_rgh\n" << endl;
|
|
||||||
volScalarField p_rgh
|
|
||||||
(
|
|
||||||
IOobject
|
|
||||||
(
|
|
||||||
"p_rgh",
|
|
||||||
runTime.timeName(),
|
|
||||||
mesh,
|
|
||||||
IOobject::MUST_READ,
|
|
||||||
IOobject::AUTO_WRITE
|
|
||||||
),
|
|
||||||
mesh
|
|
||||||
);
|
|
||||||
|
|
||||||
// Force p_rgh to be consistent with p
|
|
||||||
p_rgh = p - rho*gh;
|
|
||||||
|
|
||||||
|
|
||||||
label pRefCell = 0;
|
|
||||||
scalar pRefValue = 0.0;
|
|
||||||
setRefCell
|
|
||||||
(
|
|
||||||
p,
|
|
||||||
p_rgh,
|
|
||||||
mesh.solutionDict().subDict("SIMPLE"),
|
|
||||||
pRefCell,
|
|
||||||
pRefValue
|
|
||||||
);
|
|
||||||
|
|
||||||
autoPtr<regionModels::thermoBaffleModels::thermoBaffleModel> baffles
|
|
||||||
(
|
|
||||||
regionModels::thermoBaffleModels::thermoBaffleModel::New(mesh)
|
|
||||||
);
|
|
||||||
|
|
||||||
dimensionedScalar initialMass = fvc::domainIntegrate(rho);
|
|
||||||
dimensionedScalar totalVolume = sum(mesh.V());
|
|
||||||
@ -1,17 +0,0 @@
|
|||||||
{
|
|
||||||
fvScalarMatrix hEqn
|
|
||||||
(
|
|
||||||
fvm::div(phi, h)
|
|
||||||
- fvm::Sp(fvc::div(phi), h)
|
|
||||||
- fvm::laplacian(turbulence->alphaEff(), h)
|
|
||||||
==
|
|
||||||
fvc::div(phi/fvc::interpolate(rho)*fvc::interpolate(p))
|
|
||||||
- p*fvc::div(phi/fvc::interpolate(rho))
|
|
||||||
);
|
|
||||||
|
|
||||||
hEqn.relax();
|
|
||||||
hEqn.solve();
|
|
||||||
|
|
||||||
baffles->evolve();
|
|
||||||
thermo.correct();
|
|
||||||
}
|
|
||||||
@ -1,59 +0,0 @@
|
|||||||
{
|
|
||||||
rho = thermo.rho();
|
|
||||||
rho.relax();
|
|
||||||
|
|
||||||
volScalarField rAU(1.0/UEqn().A());
|
|
||||||
surfaceScalarField rhorAUf("(rho*(1|A(U)))", fvc::interpolate(rho*rAU));
|
|
||||||
|
|
||||||
U = rAU*UEqn().H();
|
|
||||||
UEqn.clear();
|
|
||||||
|
|
||||||
phi = fvc::interpolate(rho)*(fvc::interpolate(U) & mesh.Sf());
|
|
||||||
bool closedVolume = adjustPhi(phi, U, p_rgh);
|
|
||||||
|
|
||||||
surfaceScalarField buoyancyPhi(rhorAUf*ghf*fvc::snGrad(rho)*mesh.magSf());
|
|
||||||
phi -= buoyancyPhi;
|
|
||||||
|
|
||||||
while (simple.correctNonOrthogonal())
|
|
||||||
{
|
|
||||||
fvScalarMatrix p_rghEqn
|
|
||||||
(
|
|
||||||
fvm::laplacian(rhorAUf, p_rgh) == fvc::div(phi)
|
|
||||||
);
|
|
||||||
|
|
||||||
p_rghEqn.setReference(pRefCell, getRefCellValue(p_rgh, pRefCell));
|
|
||||||
p_rghEqn.solve();
|
|
||||||
|
|
||||||
if (simple.finalNonOrthogonalIter())
|
|
||||||
{
|
|
||||||
// Calculate the conservative fluxes
|
|
||||||
phi -= p_rghEqn.flux();
|
|
||||||
|
|
||||||
// Explicitly relax pressure for momentum corrector
|
|
||||||
p_rgh.relax();
|
|
||||||
|
|
||||||
// Correct the momentum source with the pressure gradient flux
|
|
||||||
// calculated from the relaxed pressure
|
|
||||||
U -= rAU*fvc::reconstruct((buoyancyPhi + p_rghEqn.flux())/rhorAUf);
|
|
||||||
U.correctBoundaryConditions();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#include "continuityErrs.H"
|
|
||||||
|
|
||||||
p = p_rgh + rho*gh;
|
|
||||||
|
|
||||||
// For closed-volume cases adjust the pressure level
|
|
||||||
// to obey overall mass continuity
|
|
||||||
if (closedVolume)
|
|
||||||
{
|
|
||||||
p += (initialMass - fvc::domainIntegrate(psi*p))
|
|
||||||
/fvc::domainIntegrate(psi);
|
|
||||||
p_rgh = p - rho*gh;
|
|
||||||
}
|
|
||||||
|
|
||||||
rho = thermo.rho();
|
|
||||||
rho.relax();
|
|
||||||
Info<< "rho max/min : " << max(rho).value() << " " << min(rho).value()
|
|
||||||
<< endl;
|
|
||||||
}
|
|
||||||
@ -27,8 +27,6 @@ License
|
|||||||
#include "Time.H"
|
#include "Time.H"
|
||||||
#include "fvMesh.H"
|
#include "fvMesh.H"
|
||||||
#include "IStringStream.H"
|
#include "IStringStream.H"
|
||||||
#include "octree.H"
|
|
||||||
#include "octreeDataCell.H"
|
|
||||||
#include "indexedOctree.H"
|
#include "indexedOctree.H"
|
||||||
#include "treeDataCell.H"
|
#include "treeDataCell.H"
|
||||||
#include "OFstream.H"
|
#include "OFstream.H"
|
||||||
@ -46,10 +44,14 @@ int main(int argc, char *argv[])
|
|||||||
# include "createTime.H"
|
# include "createTime.H"
|
||||||
# include "createMesh.H"
|
# include "createMesh.H"
|
||||||
|
|
||||||
label nReps = 100000;
|
//label nReps = 100000;
|
||||||
|
label nReps = 10000;
|
||||||
|
|
||||||
const point sample = args.argRead<point>(1);
|
const point sample = args.argRead<point>(1);
|
||||||
|
|
||||||
|
//const polyMesh::cellRepresentation decompMode = polyMesh::FACEPLANES;
|
||||||
|
const polyMesh::cellRepresentation decompMode = polyMesh::FACEDIAGTETS;
|
||||||
|
|
||||||
treeBoundBox meshBb(mesh.bounds());
|
treeBoundBox meshBb(mesh.bounds());
|
||||||
|
|
||||||
// Calculate typical cell related size to shift bb by.
|
// Calculate typical cell related size to shift bb by.
|
||||||
@ -69,65 +71,52 @@ int main(int argc, char *argv[])
|
|||||||
Info<< "Initialised mesh in "
|
Info<< "Initialised mesh in "
|
||||||
<< runTime.cpuTimeIncrement() << " s" << endl;
|
<< runTime.cpuTimeIncrement() << " s" << endl;
|
||||||
|
|
||||||
// Wrap indices and mesh information into helper object
|
|
||||||
octreeDataCell shapes(mesh);
|
|
||||||
|
|
||||||
octree<octreeDataCell> oc
|
|
||||||
(
|
|
||||||
shiftedBb, // overall bounding box
|
|
||||||
shapes, // all information needed to do checks on cells
|
|
||||||
1, // min. levels
|
|
||||||
10.0, // max. size of leaves
|
|
||||||
10.0 // maximum ratio of cubes v.s. cells
|
|
||||||
);
|
|
||||||
|
|
||||||
for (label i = 0; i < nReps - 1 ; i++)
|
|
||||||
{
|
{
|
||||||
oc.find(sample);
|
indexedOctree<treeDataCell> ioc
|
||||||
|
(
|
||||||
|
treeDataCell(true, mesh, decompMode), //FACEDIAGTETS),
|
||||||
|
shiftedBb,
|
||||||
|
10, // maxLevel
|
||||||
|
100, // leafsize
|
||||||
|
10.0 // duplicity
|
||||||
|
);
|
||||||
|
|
||||||
|
for (label i = 0; i < nReps - 1 ; i++)
|
||||||
|
{
|
||||||
|
if ((i % 100) == 0)
|
||||||
|
{
|
||||||
|
Info<< "indexed octree for " << i << endl;
|
||||||
|
}
|
||||||
|
ioc.findInside(sample);
|
||||||
|
}
|
||||||
|
|
||||||
|
Info<< "Point:" << sample << " is in shape "
|
||||||
|
<< ioc.findInside(sample)
|
||||||
|
<< ", where the possible cells were:" << nl
|
||||||
|
<< ioc.findIndices(sample)
|
||||||
|
<< endl;
|
||||||
|
|
||||||
|
Info<< "Found in indexedOctree " << nReps << " times in "
|
||||||
|
<< runTime.cpuTimeIncrement() << " s" << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
Info<< "Point:" << sample << " is in shape "
|
|
||||||
<< oc.find(sample) << endl;
|
|
||||||
|
|
||||||
oc.printStats(Info);
|
|
||||||
|
|
||||||
Info<< "Found in octree " << nReps << " times in "
|
|
||||||
<< runTime.cpuTimeIncrement() << " s" << endl;
|
|
||||||
|
|
||||||
indexedOctree<treeDataCell> ioc
|
|
||||||
(
|
|
||||||
treeDataCell(true, mesh),
|
|
||||||
shiftedBb,
|
|
||||||
8, // maxLevel
|
|
||||||
10, // leafsize
|
|
||||||
3.0 // duplicity
|
|
||||||
);
|
|
||||||
|
|
||||||
for (label i = 0; i < nReps - 1 ; i++)
|
|
||||||
{
|
{
|
||||||
ioc.findInside(sample);
|
for (label i = 0; i < nReps - 1 ; i++)
|
||||||
|
{
|
||||||
|
if ((i % 100) == 0)
|
||||||
|
{
|
||||||
|
Info<< "linear search for " << i << endl;
|
||||||
|
}
|
||||||
|
mesh.findCell(sample, decompMode);
|
||||||
|
}
|
||||||
|
|
||||||
|
Info<< "Point:" << sample << " is in cell "
|
||||||
|
<< mesh.findCell(sample, decompMode) << endl;
|
||||||
|
|
||||||
|
Info<< "Found in mesh.findCell " << nReps << " times in "
|
||||||
|
<< runTime.cpuTimeIncrement() << " s" << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
Info<< "Point:" << sample << " is in shape "
|
|
||||||
<< ioc.findInside(sample)
|
|
||||||
<< ", where the possible cells were:" << nl
|
|
||||||
<< ioc.findIndices(sample)
|
|
||||||
<< endl;
|
|
||||||
|
|
||||||
Info<< "Found in indexedOctree " << nReps << " times in "
|
|
||||||
<< runTime.cpuTimeIncrement() << " s" << endl;
|
|
||||||
|
|
||||||
for (label i = 0; i < nReps - 1 ; i++)
|
|
||||||
{
|
|
||||||
mesh.findCell(sample);
|
|
||||||
}
|
|
||||||
|
|
||||||
Info<< "Point:" << sample << " is in cell "
|
|
||||||
<< mesh.findCell(sample) << endl;
|
|
||||||
|
|
||||||
Info<< "Found in mesh.findCell " << nReps << " times in "
|
|
||||||
<< runTime.cpuTimeIncrement() << " s" << endl;
|
|
||||||
|
|
||||||
Info<< "End\n" << endl;
|
Info<< "End\n" << endl;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
@ -381,7 +381,7 @@ int main(int argc, char *argv[])
|
|||||||
(void)edgeCalc.minLen(Info);
|
(void)edgeCalc.minLen(Info);
|
||||||
|
|
||||||
// Search engine on mesh. Face decomposition since faces might be warped.
|
// Search engine on mesh. Face decomposition since faces might be warped.
|
||||||
meshSearch queryMesh(mesh, polyMesh::FACEDIAGTETS);
|
meshSearch queryMesh(mesh);
|
||||||
|
|
||||||
// Check all 'outside' points
|
// Check all 'outside' points
|
||||||
forAll(outsidePts, outsideI)
|
forAll(outsidePts, outsideI)
|
||||||
|
|||||||
@ -770,7 +770,15 @@ void deleteEmptyPatches(fvMesh& mesh)
|
|||||||
{
|
{
|
||||||
const polyBoundaryMesh& patches = mesh.boundaryMesh();
|
const polyBoundaryMesh& patches = mesh.boundaryMesh();
|
||||||
|
|
||||||
labelList oldToNew(patches.size());
|
wordList masterNames;
|
||||||
|
if (Pstream::master())
|
||||||
|
{
|
||||||
|
masterNames = patches.names();
|
||||||
|
}
|
||||||
|
Pstream::scatter(masterNames);
|
||||||
|
|
||||||
|
|
||||||
|
labelList oldToNew(patches.size(), -1);
|
||||||
label usedI = 0;
|
label usedI = 0;
|
||||||
label notUsedI = patches.size();
|
label notUsedI = patches.size();
|
||||||
|
|
||||||
@ -787,31 +795,55 @@ void deleteEmptyPatches(fvMesh& mesh)
|
|||||||
|
|
||||||
|
|
||||||
// Add all the non-empty, non-processor patches
|
// Add all the non-empty, non-processor patches
|
||||||
forAll(patches, patchI)
|
forAll(masterNames, masterI)
|
||||||
{
|
{
|
||||||
if (isA<processorPolyPatch>(patches[patchI]))
|
label patchI = patches.findPatchID(masterNames[masterI]);
|
||||||
|
|
||||||
|
if (patchI != -1)
|
||||||
{
|
{
|
||||||
// Processor patches are unique per processor so look at local
|
if (isA<processorPolyPatch>(patches[patchI]))
|
||||||
// size only
|
|
||||||
if (patches[patchI].size() == 0)
|
|
||||||
{
|
{
|
||||||
Pout<< "Deleting processor patch " << patchI
|
// Similar named processor patch? Not 'possible'.
|
||||||
<< " name:" << patches[patchI].name()
|
if (patches[patchI].size() == 0)
|
||||||
<< endl;
|
{
|
||||||
oldToNew[patchI] = --notUsedI;
|
Pout<< "Deleting processor patch " << patchI
|
||||||
|
<< " name:" << patches[patchI].name()
|
||||||
|
<< endl;
|
||||||
|
oldToNew[patchI] = --notUsedI;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
oldToNew[patchI] = usedI++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
oldToNew[patchI] = usedI++;
|
// Common patch.
|
||||||
|
if (returnReduce(patches[patchI].size(), sumOp<label>()) == 0)
|
||||||
|
{
|
||||||
|
Pout<< "Deleting patch " << patchI
|
||||||
|
<< " name:" << patches[patchI].name()
|
||||||
|
<< endl;
|
||||||
|
oldToNew[patchI] = --notUsedI;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
oldToNew[patchI] = usedI++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
}
|
||||||
|
|
||||||
|
// Add remaining patches at the end
|
||||||
|
forAll(patches, patchI)
|
||||||
|
{
|
||||||
|
if (oldToNew[patchI] == -1)
|
||||||
{
|
{
|
||||||
// All non-processor patches are present everywhere to reduce
|
// Unique to this processor. Note: could check that these are
|
||||||
// size
|
// only processor patches.
|
||||||
if (returnReduce(patches[patchI].size(), sumOp<label>()) == 0)
|
if (patches[patchI].size() == 0)
|
||||||
{
|
{
|
||||||
Pout<< "Deleting patch " << patchI
|
Pout<< "Deleting processor patch " << patchI
|
||||||
<< " name:" << patches[patchI].name()
|
<< " name:" << patches[patchI].name()
|
||||||
<< endl;
|
<< endl;
|
||||||
oldToNew[patchI] = --notUsedI;
|
oldToNew[patchI] = --notUsedI;
|
||||||
@ -2579,6 +2611,8 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
mesh.setInstance(meshInstance);
|
mesh.setInstance(meshInstance);
|
||||||
|
|
||||||
|
// Remove any unused patches
|
||||||
|
deleteEmptyPatches(mesh);
|
||||||
|
|
||||||
Pout<< "Writing mesh " << mesh.name()
|
Pout<< "Writing mesh " << mesh.name()
|
||||||
<< " to " << mesh.facesInstance() << nl
|
<< " to " << mesh.facesInstance() << nl
|
||||||
|
|||||||
@ -2194,7 +2194,7 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
label regionI = -1;
|
label regionI = -1;
|
||||||
|
|
||||||
label cellI = mesh.findCell(insidePoint, polyMesh::FACEDIAGTETS);
|
label cellI = mesh.findCell(insidePoint);
|
||||||
|
|
||||||
Info<< nl << "Found point " << insidePoint << " in cell " << cellI
|
Info<< nl << "Found point " << insidePoint << " in cell " << cellI
|
||||||
<< endl;
|
<< endl;
|
||||||
|
|||||||
@ -528,11 +528,7 @@ int main(int argc, char *argv[])
|
|||||||
<< "Cell number should be between 0 and "
|
<< "Cell number should be between 0 and "
|
||||||
<< mesh.nCells()-1 << nl
|
<< mesh.nCells()-1 << nl
|
||||||
<< "On this mesh the particle should be in cell "
|
<< "On this mesh the particle should be in cell "
|
||||||
<< mesh.findCell
|
<< mesh.findCell(iter().position())
|
||||||
(
|
|
||||||
iter().position(),
|
|
||||||
polyMesh::FACEDIAGTETS
|
|
||||||
)
|
|
||||||
<< exit(FatalError);
|
<< exit(FatalError);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -24,13 +24,13 @@ numberOfSubdomains 2;
|
|||||||
// (makes sense only for cyclic patches)
|
// (makes sense only for cyclic patches)
|
||||||
//preservePatches (cyclic_half0 cyclic_half1);
|
//preservePatches (cyclic_half0 cyclic_half1);
|
||||||
|
|
||||||
//- Keep all of faceZone on a single processor. This puts all cells
|
//- Keep all of faceSet on a single processor. This puts all cells
|
||||||
// connected with a point, edge or face on the same processor.
|
// connected with a point, edge or face on the same processor.
|
||||||
// (just having face connected cells might not guarantee a balanced
|
// (just having face connected cells might not guarantee a balanced
|
||||||
// decomposition)
|
// decomposition)
|
||||||
// The processor can be -1 (the decompositionMethod chooses the processor
|
// The processor can be -1 (the decompositionMethod chooses the processor
|
||||||
// for a good load balance) or explicitly provided (upsets balance).
|
// for a good load balance) or explicitly provided (upsets balance).
|
||||||
//singleProcessorFaceZones ((f0 -1));
|
//singleProcessorFaceSets ((f0 -1));
|
||||||
|
|
||||||
|
|
||||||
//- Use the volScalarField named here as a weight for each cell in the
|
//- Use the volScalarField named here as a weight for each cell in the
|
||||||
|
|||||||
@ -29,6 +29,7 @@ License
|
|||||||
#include "cellSet.H"
|
#include "cellSet.H"
|
||||||
#include "regionSplit.H"
|
#include "regionSplit.H"
|
||||||
#include "Tuple2.H"
|
#include "Tuple2.H"
|
||||||
|
#include "faceSet.H"
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
@ -110,11 +111,9 @@ void Foam::domainDecomposition::distributeCells()
|
|||||||
Map<label> specifiedProcessorFaces;
|
Map<label> specifiedProcessorFaces;
|
||||||
List<Tuple2<word, label> > zNameAndProcs;
|
List<Tuple2<word, label> > zNameAndProcs;
|
||||||
|
|
||||||
if (decompositionDict_.found("singleProcessorFaceZones"))
|
if (decompositionDict_.found("singleProcessorFaceSets"))
|
||||||
{
|
{
|
||||||
decompositionDict_.lookup("singleProcessorFaceZones") >> zNameAndProcs;
|
decompositionDict_.lookup("singleProcessorFaceSets") >> zNameAndProcs;
|
||||||
|
|
||||||
const faceZoneMesh& fZones = faceZones();
|
|
||||||
|
|
||||||
label nCells = 0;
|
label nCells = 0;
|
||||||
|
|
||||||
@ -122,23 +121,12 @@ void Foam::domainDecomposition::distributeCells()
|
|||||||
|
|
||||||
forAll(zNameAndProcs, i)
|
forAll(zNameAndProcs, i)
|
||||||
{
|
{
|
||||||
Info<< "Keeping all cells connected to faceZone "
|
Info<< "Keeping all cells connected to faceSet "
|
||||||
<< zNameAndProcs[i].first()
|
<< zNameAndProcs[i].first()
|
||||||
<< " on processor " << zNameAndProcs[i].second() << endl;
|
<< " on processor " << zNameAndProcs[i].second() << endl;
|
||||||
|
|
||||||
label zoneI = fZones.findZoneID(zNameAndProcs[i].first());
|
// Read faceSet
|
||||||
|
faceSet fz(*this, zNameAndProcs[i].first());
|
||||||
if (zoneI == -1)
|
|
||||||
{
|
|
||||||
FatalErrorIn("domainDecomposition::distributeCells()")
|
|
||||||
<< "Unknown singleProcessorFaceZone "
|
|
||||||
<< zNameAndProcs[i].first()
|
|
||||||
<< endl << "Valid faceZones are " << fZones.names()
|
|
||||||
<< exit(FatalError);
|
|
||||||
}
|
|
||||||
|
|
||||||
const faceZone& fz = fZones[zoneI];
|
|
||||||
|
|
||||||
nCells += fz.size();
|
nCells += fz.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -150,14 +138,13 @@ void Foam::domainDecomposition::distributeCells()
|
|||||||
// Fill
|
// Fill
|
||||||
forAll(zNameAndProcs, i)
|
forAll(zNameAndProcs, i)
|
||||||
{
|
{
|
||||||
label zoneI = fZones.findZoneID(zNameAndProcs[i].first());
|
faceSet fz(*this, zNameAndProcs[i].first());
|
||||||
const faceZone& fz = fZones[zoneI];
|
|
||||||
|
|
||||||
label procI = zNameAndProcs[i].second();
|
label procI = zNameAndProcs[i].second();
|
||||||
|
|
||||||
forAll(fz, fzI)
|
forAllConstIter(faceSet, fz, iter)
|
||||||
{
|
{
|
||||||
label faceI = fz[fzI];
|
label faceI = iter.key();
|
||||||
|
|
||||||
specifiedProcessorFaces.insert(faceI, procI);
|
specifiedProcessorFaces.insert(faceI, procI);
|
||||||
}
|
}
|
||||||
@ -333,7 +320,7 @@ void Foam::domainDecomposition::distributeCells()
|
|||||||
// For specifiedProcessorFaces rework the cellToProc to enforce
|
// For specifiedProcessorFaces rework the cellToProc to enforce
|
||||||
// all on one processor since we can't guarantee that the input
|
// all on one processor since we can't guarantee that the input
|
||||||
// to regionSplit was a single region.
|
// to regionSplit was a single region.
|
||||||
// E.g. faceZone 'a' with the cells split into two regions
|
// E.g. faceSet 'a' with the cells split into two regions
|
||||||
// by a notch formed by two walls
|
// by a notch formed by two walls
|
||||||
//
|
//
|
||||||
// \ /
|
// \ /
|
||||||
@ -345,12 +332,9 @@ void Foam::domainDecomposition::distributeCells()
|
|||||||
// unbalanced.
|
// unbalanced.
|
||||||
if (specifiedProcessorFaces.size())
|
if (specifiedProcessorFaces.size())
|
||||||
{
|
{
|
||||||
const faceZoneMesh& fZones = faceZones();
|
|
||||||
|
|
||||||
forAll(zNameAndProcs, i)
|
forAll(zNameAndProcs, i)
|
||||||
{
|
{
|
||||||
label zoneI = fZones.findZoneID(zNameAndProcs[i].first());
|
faceSet fz(*this, zNameAndProcs[i].first());
|
||||||
const faceZone& fz = fZones[zoneI];
|
|
||||||
|
|
||||||
if (fz.size())
|
if (fz.size())
|
||||||
{
|
{
|
||||||
@ -362,9 +346,9 @@ void Foam::domainDecomposition::distributeCells()
|
|||||||
procI = cellToProc_[faceOwner()[fz[0]]];
|
procI = cellToProc_[faceOwner()[fz[0]]];
|
||||||
}
|
}
|
||||||
|
|
||||||
forAll(fz, fzI)
|
forAllConstIter(faceSet, fz, iter)
|
||||||
{
|
{
|
||||||
label faceI = fz[fzI];
|
label faceI = iter.key();
|
||||||
|
|
||||||
cellToProc_[faceOwner()[faceI]] = procI;
|
cellToProc_[faceOwner()[faceI]] = procI;
|
||||||
if (isInternalFace(faceI))
|
if (isInternalFace(faceI))
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
|
|
||||||
foamToTetDualMesh.C
|
foamToTetDualMesh.C
|
||||||
|
|
||||||
EXE = $(FOAM_USER_APPBIN)/foamToTetDualMesh
|
EXE = $(FOAM_APPBIN)/foamToTetDualMesh
|
||||||
|
|||||||
@ -656,11 +656,6 @@ DebugSwitches
|
|||||||
nutWallFunction 0;
|
nutWallFunction 0;
|
||||||
obj 0;
|
obj 0;
|
||||||
objectRegistry 0;
|
objectRegistry 0;
|
||||||
octree 0;
|
|
||||||
octreeDataEdges 0;
|
|
||||||
octreeDataFace 0;
|
|
||||||
octreeDataFaceList 0;
|
|
||||||
octreeDataTriSurface 0;
|
|
||||||
off 0;
|
off 0;
|
||||||
omegaWallFunction 0;
|
omegaWallFunction 0;
|
||||||
oneEqEddy 0;
|
oneEqEddy 0;
|
||||||
|
|||||||
@ -183,7 +183,7 @@ Foam::tmp<Foam::labelField> Foam::pairGAMGAgglomeration::agglomerate
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reverese the map ordering to improve the next level of agglomeration
|
// Reverse the map ordering to improve the next level of agglomeration
|
||||||
// (doesn't always help and is sometimes detrimental)
|
// (doesn't always help and is sometimes detrimental)
|
||||||
nCoarseCells--;
|
nCoarseCells--;
|
||||||
|
|
||||||
|
|||||||
@ -558,14 +558,14 @@ public:
|
|||||||
(
|
(
|
||||||
const point&,
|
const point&,
|
||||||
label cellI,
|
label cellI,
|
||||||
const cellRepresentation
|
const cellRepresentation = FACEDIAGTETS
|
||||||
) const;
|
) const;
|
||||||
|
|
||||||
//- Find cell enclosing this location (-1 if not in mesh)
|
//- Find cell enclosing this location (-1 if not in mesh)
|
||||||
label findCell
|
label findCell
|
||||||
(
|
(
|
||||||
const point&,
|
const point&,
|
||||||
const cellRepresentation
|
const cellRepresentation = FACEDIAGTETS
|
||||||
) const;
|
) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -36,7 +36,7 @@ void Foam::ignitionSite::findIgnitionCells(const fvMesh& mesh)
|
|||||||
const volVectorField& centres = mesh.C();
|
const volVectorField& centres = mesh.C();
|
||||||
const scalarField& vols = mesh.V();
|
const scalarField& vols = mesh.V();
|
||||||
|
|
||||||
label ignCell = mesh.findCell(location_, polyMesh::FACEDIAGTETS);
|
label ignCell = mesh.findCell(location_);
|
||||||
if (ignCell == -1)
|
if (ignCell == -1)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
|
|||||||
@ -104,11 +104,7 @@ void Foam::basicSource::setCellSet()
|
|||||||
|
|
||||||
forAll(points_, i)
|
forAll(points_, i)
|
||||||
{
|
{
|
||||||
label cellI = mesh_.findCell
|
label cellI = mesh_.findCell(points_[i]);
|
||||||
(
|
|
||||||
points_[i],
|
|
||||||
polyMesh::FACEDIAGTETS
|
|
||||||
);
|
|
||||||
if (cellI >= 0)
|
if (cellI >= 0)
|
||||||
{
|
{
|
||||||
selectedCells.insert(cellI);
|
selectedCells.insert(cellI);
|
||||||
|
|||||||
@ -76,10 +76,16 @@ void Foam::setRefCell
|
|||||||
else if (dict.found(refPointName))
|
else if (dict.found(refPointName))
|
||||||
{
|
{
|
||||||
point refPointi(dict.lookup(refPointName));
|
point refPointi(dict.lookup(refPointName));
|
||||||
|
|
||||||
|
// Note: find reference cell using facePlanes to avoid constructing
|
||||||
|
// face decomposition structure. Most likely the reference
|
||||||
|
// cell is an undistorted one so this should not be a
|
||||||
|
// problem.
|
||||||
|
|
||||||
refCelli = field.mesh().findCell
|
refCelli = field.mesh().findCell
|
||||||
(
|
(
|
||||||
refPointi,
|
refPointi,
|
||||||
polyMesh::FACEDIAGTETS
|
polyMesh::FACEPLANES
|
||||||
);
|
);
|
||||||
label hasRef = (refCelli >= 0 ? 1 : 0);
|
label hasRef = (refCelli >= 0 ? 1 : 0);
|
||||||
label sumHasRef = returnReduce<label>(hasRef, sumOp<label>());
|
label sumHasRef = returnReduce<label>(hasRef, sumOp<label>());
|
||||||
|
|||||||
@ -143,7 +143,7 @@ Foam::cyclicAMIFvPatchField<Type>::patchNeighbourField() const
|
|||||||
{
|
{
|
||||||
const Field<Type>& iField = this->internalField();
|
const Field<Type>& iField = this->internalField();
|
||||||
const labelUList& nbrFaceCells =
|
const labelUList& nbrFaceCells =
|
||||||
cyclicAMIPatch_.cyclicAMIPatch().nbrPatch().faceCells();
|
cyclicAMIPatch_.cyclicAMIPatch().neighbPatch().faceCells();
|
||||||
|
|
||||||
Field<Type> pnf(iField, nbrFaceCells);
|
Field<Type> pnf(iField, nbrFaceCells);
|
||||||
|
|
||||||
@ -187,7 +187,7 @@ void Foam::cyclicAMIFvPatchField<Type>::updateInterfaceMatrix
|
|||||||
) const
|
) const
|
||||||
{
|
{
|
||||||
const labelUList& nbrFaceCells =
|
const labelUList& nbrFaceCells =
|
||||||
cyclicAMIPatch_.cyclicAMIPatch().nbrPatch().faceCells();
|
cyclicAMIPatch_.cyclicAMIPatch().neighbPatch().faceCells();
|
||||||
|
|
||||||
scalarField pnf(psiInternal, nbrFaceCells);
|
scalarField pnf(psiInternal, nbrFaceCells);
|
||||||
|
|
||||||
|
|||||||
@ -587,7 +587,41 @@ void Foam::fvMatrix<Type>::relax(const scalar alpha)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (debug)
|
||||||
|
{
|
||||||
|
// Calculate amount of non-dominance.
|
||||||
|
label nNon = 0;
|
||||||
|
scalar maxNon = 0.0;
|
||||||
|
scalar sumNon = 0.0;
|
||||||
|
forAll(D, celli)
|
||||||
|
{
|
||||||
|
scalar d = (sumOff[celli] - D[celli])/D[celli];
|
||||||
|
|
||||||
|
if (d > 0)
|
||||||
|
{
|
||||||
|
nNon++;
|
||||||
|
maxNon = max(maxNon, d);
|
||||||
|
sumNon += d;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
reduce(nNon, sumOp<label>());
|
||||||
|
reduce(maxNon, maxOp<scalar>());
|
||||||
|
reduce(sumNon, sumOp<scalar>());
|
||||||
|
sumNon /= returnReduce(D.size(), sumOp<label>());
|
||||||
|
|
||||||
|
InfoIn("fvMatrix<Type>::relax(const scalar alpha)")
|
||||||
|
<< "Matrix dominance test for " << psi_.name() << nl
|
||||||
|
<< " number of non-dominant cells : " << nNon << nl
|
||||||
|
<< " maximum relative non-dominance : " << maxNon << nl
|
||||||
|
<< " average relative non-dominance : " << sumNon << nl
|
||||||
|
<< endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Ensure the matrix is diagonally dominant...
|
// Ensure the matrix is diagonally dominant...
|
||||||
|
// (assumes that the central coefficient is positive)
|
||||||
max(D, D, sumOff);
|
max(D, D, sumOff);
|
||||||
|
|
||||||
// ... then relax
|
// ... then relax
|
||||||
|
|||||||
@ -364,6 +364,7 @@ public:
|
|||||||
// alpha = 1 : diagonally equal
|
// alpha = 1 : diagonally equal
|
||||||
// alpha < 1 : diagonally dominant
|
// alpha < 1 : diagonally dominant
|
||||||
// alpha = 0 : do nothing
|
// alpha = 0 : do nothing
|
||||||
|
// Note: Requires positive diagonal.
|
||||||
void relax(const scalar alpha);
|
void relax(const scalar alpha);
|
||||||
|
|
||||||
//- Relax matrix (for steady-state solution).
|
//- Relax matrix (for steady-state solution).
|
||||||
|
|||||||
@ -97,7 +97,7 @@ public:
|
|||||||
//- Return neighbour
|
//- Return neighbour
|
||||||
virtual label neighbPatchID() const
|
virtual label neighbPatchID() const
|
||||||
{
|
{
|
||||||
return cyclicAMIPolyPatch_.nbrPatchID();
|
return cyclicAMIPolyPatch_.neighbPatchID();
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual bool owner() const
|
virtual bool owner() const
|
||||||
@ -110,10 +110,16 @@ public:
|
|||||||
{
|
{
|
||||||
return refCast<const cyclicAMIFvPatch>
|
return refCast<const cyclicAMIFvPatch>
|
||||||
(
|
(
|
||||||
this->boundaryMesh()[cyclicAMIPolyPatch_.nbrPatchID()]
|
this->boundaryMesh()[cyclicAMIPolyPatch_.neighbPatchID()]
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//- Return a reference to the AMI interpolator
|
||||||
|
virtual const AMIPatchToPatchInterpolation& AMI() const
|
||||||
|
{
|
||||||
|
return cyclicAMIPolyPatch_.AMI();
|
||||||
|
}
|
||||||
|
|
||||||
//- Are the cyclic planes parallel
|
//- Are the cyclic planes parallel
|
||||||
virtual bool parallel() const
|
virtual bool parallel() const
|
||||||
{
|
{
|
||||||
@ -136,7 +142,7 @@ public:
|
|||||||
{
|
{
|
||||||
return refCast<const cyclicAMIFvPatch>
|
return refCast<const cyclicAMIFvPatch>
|
||||||
(
|
(
|
||||||
this->boundaryMesh()[cyclicAMIPolyPatch_.nbrPatchID()]
|
this->boundaryMesh()[cyclicAMIPolyPatch_.neighbPatchID()]
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -205,15 +205,7 @@ bool Foam::InjectionModel<CloudType>::findCellAtPosition
|
|||||||
{
|
{
|
||||||
position += SMALL*(cellCentres[cellI] - position);
|
position += SMALL*(cellCentres[cellI] - position);
|
||||||
|
|
||||||
if
|
if (this->owner().mesh().pointInCell(position, cellI))
|
||||||
(
|
|
||||||
this->owner().mesh().pointInCell
|
|
||||||
(
|
|
||||||
position,
|
|
||||||
cellI,
|
|
||||||
polyMesh::FACEDIAGTETS
|
|
||||||
)
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
procI = Pstream::myProcNo();
|
procI = Pstream::myProcNo();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -86,7 +86,7 @@ Foam::labelList Foam::refinementParameters::findCells(const polyMesh& mesh)
|
|||||||
{
|
{
|
||||||
const point& keepPoint = keepPoints_[i];
|
const point& keepPoint = keepPoints_[i];
|
||||||
|
|
||||||
label localCellI = mesh.findCell(keepPoint, polyMesh::FACEDIAGTETS);
|
label localCellI = mesh.findCell(keepPoint);
|
||||||
|
|
||||||
label globalCellI = -1;
|
label globalCellI = -1;
|
||||||
|
|
||||||
|
|||||||
@ -1825,7 +1825,7 @@ Foam::autoPtr<Foam::mapPolyMesh> Foam::meshRefinement::splitMeshRegions
|
|||||||
|
|
||||||
label regionI = -1;
|
label regionI = -1;
|
||||||
|
|
||||||
label cellI = mesh_.findCell(keepPoint, polyMesh::FACEDIAGTETS);
|
label cellI = mesh_.findCell(keepPoint);
|
||||||
|
|
||||||
if (cellI != -1)
|
if (cellI != -1)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -1248,7 +1248,7 @@ void Foam::meshRefinement::findCellZoneInsideWalk
|
|||||||
// Find the region containing the insidePoint
|
// Find the region containing the insidePoint
|
||||||
label keepRegionI = -1;
|
label keepRegionI = -1;
|
||||||
|
|
||||||
label cellI = mesh_.findCell(insidePoint, polyMesh::FACEDIAGTETS);
|
label cellI = mesh_.findCell(insidePoint);
|
||||||
|
|
||||||
if (cellI != -1)
|
if (cellI != -1)
|
||||||
{
|
{
|
||||||
@ -1418,7 +1418,7 @@ void Foam::meshRefinement::findCellZoneTopo
|
|||||||
// Find the region containing the keepPoint
|
// Find the region containing the keepPoint
|
||||||
label keepRegionI = -1;
|
label keepRegionI = -1;
|
||||||
|
|
||||||
label cellI = mesh_.findCell(keepPoint, polyMesh::FACEDIAGTETS);
|
label cellI = mesh_.findCell(keepPoint);
|
||||||
|
|
||||||
if (cellI != -1)
|
if (cellI != -1)
|
||||||
{
|
{
|
||||||
@ -1959,7 +1959,7 @@ Foam::autoPtr<Foam::mapPolyMesh> Foam::meshRefinement::splitMesh
|
|||||||
// Find the region containing the keepPoint
|
// Find the region containing the keepPoint
|
||||||
label keepRegionI = -1;
|
label keepRegionI = -1;
|
||||||
|
|
||||||
label cellI = mesh_.findCell(keepPoint, polyMesh::FACEDIAGTETS);
|
label cellI = mesh_.findCell(keepPoint);
|
||||||
|
|
||||||
if (cellI != -1)
|
if (cellI != -1)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -120,7 +120,7 @@ void Foam::AMIInterpolation<SourcePatch, TargetPatch>::checkPatches
|
|||||||
|
|
||||||
|
|
||||||
template<class SourcePatch, class TargetPatch>
|
template<class SourcePatch, class TargetPatch>
|
||||||
bool Foam::AMIInterpolation<SourcePatch, TargetPatch>::distributed
|
Foam::label Foam::AMIInterpolation<SourcePatch, TargetPatch>::calcDistribution
|
||||||
(
|
(
|
||||||
const primitivePatch& srcPatch,
|
const primitivePatch& srcPatch,
|
||||||
const primitivePatch& tgtPatch
|
const primitivePatch& tgtPatch
|
||||||
@ -140,13 +140,21 @@ bool Foam::AMIInterpolation<SourcePatch, TargetPatch>::distributed
|
|||||||
|
|
||||||
Pstream::gatherList(facesPresentOnProc);
|
Pstream::gatherList(facesPresentOnProc);
|
||||||
Pstream::scatterList(facesPresentOnProc);
|
Pstream::scatterList(facesPresentOnProc);
|
||||||
if (sum(facesPresentOnProc) > 1)
|
|
||||||
|
label nHaveFaces = sum(facesPresentOnProc);
|
||||||
|
|
||||||
|
if (nHaveFaces > 1)
|
||||||
{
|
{
|
||||||
return true;
|
return -1;
|
||||||
|
}
|
||||||
|
else if (nHaveFaces == 1)
|
||||||
|
{
|
||||||
|
return findIndex(facesPresentOnProc, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
// Either not parallel or no faces on any processor
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1005,7 +1013,7 @@ void Foam::AMIInterpolation<SourcePatch, TargetPatch>::calcAddressing
|
|||||||
template<class SourcePatch, class TargetPatch>
|
template<class SourcePatch, class TargetPatch>
|
||||||
void Foam::AMIInterpolation<SourcePatch, TargetPatch>::normaliseWeights
|
void Foam::AMIInterpolation<SourcePatch, TargetPatch>::normaliseWeights
|
||||||
(
|
(
|
||||||
const primitivePatch& patch,
|
const scalarField& patchAreas,
|
||||||
const word& patchName,
|
const word& patchName,
|
||||||
const labelListList& addr,
|
const labelListList& addr,
|
||||||
scalarListList& wght,
|
scalarListList& wght,
|
||||||
@ -1023,7 +1031,7 @@ void Foam::AMIInterpolation<SourcePatch, TargetPatch>::normaliseWeights
|
|||||||
scalar s = sum(wght[faceI]);
|
scalar s = sum(wght[faceI]);
|
||||||
wghtSum[faceI] = s;
|
wghtSum[faceI] = s;
|
||||||
|
|
||||||
scalar t = s/patch[faceI].mag(patch.points());
|
scalar t = s/patchAreas[faceI];
|
||||||
if (t < minBound)
|
if (t < minBound)
|
||||||
{
|
{
|
||||||
minBound = t;
|
minBound = t;
|
||||||
@ -1049,6 +1057,266 @@ void Foam::AMIInterpolation<SourcePatch, TargetPatch>::normaliseWeights
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class SourcePatch, class TargetPatch>
|
||||||
|
void Foam::AMIInterpolation<SourcePatch, TargetPatch>::agglomerate
|
||||||
|
(
|
||||||
|
const autoPtr<mapDistribute>& targetMapPtr,
|
||||||
|
const scalarField& fineSrcMagSf,
|
||||||
|
const labelListList& fineSrcAddress,
|
||||||
|
const scalarListList& fineSrcWeights,
|
||||||
|
|
||||||
|
const labelList& sourceRestrictAddressing,
|
||||||
|
const labelList& targetRestrictAddressing,
|
||||||
|
|
||||||
|
scalarField& srcMagSf,
|
||||||
|
labelListList& srcAddress,
|
||||||
|
scalarListList& srcWeights,
|
||||||
|
autoPtr<mapDistribute>& tgtMap
|
||||||
|
)
|
||||||
|
{
|
||||||
|
label sourceCoarseSize =
|
||||||
|
(
|
||||||
|
sourceRestrictAddressing.size()
|
||||||
|
? max(sourceRestrictAddressing)+1
|
||||||
|
: 0
|
||||||
|
);
|
||||||
|
|
||||||
|
label targetCoarseSize =
|
||||||
|
(
|
||||||
|
targetRestrictAddressing.size()
|
||||||
|
? max(targetRestrictAddressing)+1
|
||||||
|
: 0
|
||||||
|
);
|
||||||
|
|
||||||
|
// Agglomerate face areas
|
||||||
|
{
|
||||||
|
srcMagSf.setSize(sourceRestrictAddressing.size(), 0.0);
|
||||||
|
forAll(sourceRestrictAddressing, faceI)
|
||||||
|
{
|
||||||
|
label coarseFaceI = sourceRestrictAddressing[faceI];
|
||||||
|
srcMagSf[coarseFaceI] += fineSrcMagSf[faceI];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Agglomerate weights and indices
|
||||||
|
if (targetMapPtr.valid())
|
||||||
|
{
|
||||||
|
const mapDistribute& map = targetMapPtr();
|
||||||
|
|
||||||
|
// Get all restriction addressing.
|
||||||
|
labelList allRestrict(targetRestrictAddressing);
|
||||||
|
map.distribute(allRestrict);
|
||||||
|
|
||||||
|
// So now we have agglomeration of the target side in
|
||||||
|
// allRestrict:
|
||||||
|
// 0..size-1 : local agglomeration (= targetRestrictAddressing)
|
||||||
|
// size.. : agglomeration data from other processors
|
||||||
|
|
||||||
|
labelListList tgtSubMap(Pstream::nProcs());
|
||||||
|
|
||||||
|
// Local subMap is just identity
|
||||||
|
{
|
||||||
|
tgtSubMap[Pstream::myProcNo()] = identity(targetCoarseSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
forAll(map.subMap(), procI)
|
||||||
|
{
|
||||||
|
if (procI != Pstream::myProcNo())
|
||||||
|
{
|
||||||
|
// Combine entries that point to the same coarse element. All
|
||||||
|
// the elements refer to local data so index into
|
||||||
|
// targetRestrictAddressing or allRestrict (since the same
|
||||||
|
// for local data).
|
||||||
|
const labelList& elems = map.subMap()[procI];
|
||||||
|
labelList& newSubMap = tgtSubMap[procI];
|
||||||
|
newSubMap.setSize(elems.size());
|
||||||
|
|
||||||
|
labelList oldToNew(targetCoarseSize, -1);
|
||||||
|
label newI = 0;
|
||||||
|
|
||||||
|
forAll(elems, i)
|
||||||
|
{
|
||||||
|
label fineElem = elems[i];
|
||||||
|
label coarseElem = allRestrict[fineElem];
|
||||||
|
if (oldToNew[coarseElem] == -1)
|
||||||
|
{
|
||||||
|
oldToNew[coarseElem] = newI;
|
||||||
|
newSubMap[newI] = coarseElem;
|
||||||
|
newI++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
newSubMap.setSize(newI);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reconstruct constructMap by combining entries. Note that order
|
||||||
|
// of handing out indices should be the same as loop above to compact
|
||||||
|
// the sending map
|
||||||
|
|
||||||
|
labelListList tgtConstructMap(Pstream::nProcs());
|
||||||
|
labelList tgtCompactMap;
|
||||||
|
|
||||||
|
// Local constructMap is just identity
|
||||||
|
{
|
||||||
|
tgtConstructMap[Pstream::myProcNo()] =
|
||||||
|
identity(targetCoarseSize);
|
||||||
|
|
||||||
|
tgtCompactMap = targetRestrictAddressing;
|
||||||
|
}
|
||||||
|
tgtCompactMap.setSize(map.constructSize());
|
||||||
|
label compactI = targetCoarseSize;
|
||||||
|
|
||||||
|
// Compact data from other processors
|
||||||
|
forAll(map.constructMap(), procI)
|
||||||
|
{
|
||||||
|
if (procI != Pstream::myProcNo())
|
||||||
|
{
|
||||||
|
// Combine entries that point to the same coarse element. All
|
||||||
|
// elements now are remote data so we cannot use any local
|
||||||
|
// data here - use allRestrict instead.
|
||||||
|
const labelList& elems = map.constructMap()[procI];
|
||||||
|
|
||||||
|
labelList& newConstructMap = tgtConstructMap[procI];
|
||||||
|
newConstructMap.setSize(elems.size());
|
||||||
|
|
||||||
|
if (elems.size())
|
||||||
|
{
|
||||||
|
// Get the maximum target coarse size for this set of
|
||||||
|
// received data.
|
||||||
|
label remoteTargetCoarseSize = labelMin;
|
||||||
|
forAll(elems, i)
|
||||||
|
{
|
||||||
|
remoteTargetCoarseSize = max
|
||||||
|
(
|
||||||
|
remoteTargetCoarseSize,
|
||||||
|
allRestrict[elems[i]]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
remoteTargetCoarseSize += 1;
|
||||||
|
|
||||||
|
// Combine locally data coming from procI
|
||||||
|
labelList oldToNew(remoteTargetCoarseSize, -1);
|
||||||
|
label newI = 0;
|
||||||
|
|
||||||
|
forAll(elems, i)
|
||||||
|
{
|
||||||
|
label fineElem = elems[i];
|
||||||
|
// fineElem now points to section from procI
|
||||||
|
label coarseElem = allRestrict[fineElem];
|
||||||
|
if (oldToNew[coarseElem] == -1)
|
||||||
|
{
|
||||||
|
oldToNew[coarseElem] = newI;
|
||||||
|
tgtCompactMap[fineElem] = compactI;
|
||||||
|
newConstructMap[newI] = compactI++;
|
||||||
|
newI++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Get compact index
|
||||||
|
label compactI = oldToNew[coarseElem];
|
||||||
|
tgtCompactMap[fineElem] = newConstructMap[compactI];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
newConstructMap.setSize(newI);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
srcAddress.setSize(sourceCoarseSize);
|
||||||
|
srcWeights.setSize(sourceCoarseSize);
|
||||||
|
|
||||||
|
forAll(fineSrcAddress, faceI)
|
||||||
|
{
|
||||||
|
// All the elements contributing to faceI. Are slots in
|
||||||
|
// mapDistribute'd data.
|
||||||
|
const labelList& elems = fineSrcAddress[faceI];
|
||||||
|
const scalarList& weights = fineSrcWeights[faceI];
|
||||||
|
const scalar fineArea = fineSrcMagSf[faceI];
|
||||||
|
|
||||||
|
label coarseFaceI = sourceRestrictAddressing[faceI];
|
||||||
|
|
||||||
|
labelList& newElems = srcAddress[coarseFaceI];
|
||||||
|
scalarList& newWeights = srcWeights[coarseFaceI];
|
||||||
|
|
||||||
|
forAll(elems, i)
|
||||||
|
{
|
||||||
|
label elemI = elems[i];
|
||||||
|
label coarseElemI = tgtCompactMap[elemI];
|
||||||
|
|
||||||
|
label index = findIndex(newElems, coarseElemI);
|
||||||
|
if (index == -1)
|
||||||
|
{
|
||||||
|
newElems.append(coarseElemI);
|
||||||
|
newWeights.append(fineArea*weights[i]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
newWeights[index] += fineArea*weights[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tgtMap.reset
|
||||||
|
(
|
||||||
|
new mapDistribute
|
||||||
|
(
|
||||||
|
compactI,
|
||||||
|
tgtSubMap.xfer(),
|
||||||
|
tgtConstructMap.xfer()
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
srcAddress.setSize(sourceCoarseSize);
|
||||||
|
srcWeights.setSize(sourceCoarseSize);
|
||||||
|
|
||||||
|
forAll(fineSrcAddress, faceI)
|
||||||
|
{
|
||||||
|
// All the elements contributing to faceI. Are slots in
|
||||||
|
// mapDistribute'd data.
|
||||||
|
const labelList& elems = fineSrcAddress[faceI];
|
||||||
|
const scalarList& weights = fineSrcWeights[faceI];
|
||||||
|
const scalar fineArea = fineSrcMagSf[faceI];
|
||||||
|
|
||||||
|
label coarseFaceI = sourceRestrictAddressing[faceI];
|
||||||
|
|
||||||
|
labelList& newElems = srcAddress[coarseFaceI];
|
||||||
|
scalarList& newWeights = srcWeights[coarseFaceI];
|
||||||
|
|
||||||
|
forAll(elems, i)
|
||||||
|
{
|
||||||
|
label elemI = elems[i];
|
||||||
|
label coarseElemI = targetRestrictAddressing[elemI];
|
||||||
|
|
||||||
|
label index = findIndex(newElems, coarseElemI);
|
||||||
|
if (index == -1)
|
||||||
|
{
|
||||||
|
newElems.append(coarseElemI);
|
||||||
|
newWeights.append(fineArea*weights[i]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
newWeights[index] += fineArea*weights[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// weights normalisation
|
||||||
|
normaliseWeights
|
||||||
|
(
|
||||||
|
srcMagSf,
|
||||||
|
"source",
|
||||||
|
srcAddress,
|
||||||
|
srcWeights,
|
||||||
|
true
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
template<class SourcePatch, class TargetPatch>
|
template<class SourcePatch, class TargetPatch>
|
||||||
@ -1059,6 +1327,7 @@ Foam::AMIInterpolation<SourcePatch, TargetPatch>::AMIInterpolation
|
|||||||
const faceAreaIntersect::triangulationMode& triMode
|
const faceAreaIntersect::triangulationMode& triMode
|
||||||
)
|
)
|
||||||
:
|
:
|
||||||
|
singlePatchProc_(-999),
|
||||||
srcAddress_(),
|
srcAddress_(),
|
||||||
srcWeights_(),
|
srcWeights_(),
|
||||||
tgtAddress_(),
|
tgtAddress_(),
|
||||||
@ -1088,6 +1357,7 @@ Foam::AMIInterpolation<SourcePatch, TargetPatch>::AMIInterpolation
|
|||||||
const faceAreaIntersect::triangulationMode& triMode
|
const faceAreaIntersect::triangulationMode& triMode
|
||||||
)
|
)
|
||||||
:
|
:
|
||||||
|
singlePatchProc_(-999),
|
||||||
srcAddress_(),
|
srcAddress_(),
|
||||||
srcWeights_(),
|
srcWeights_(),
|
||||||
tgtAddress_(),
|
tgtAddress_(),
|
||||||
@ -1165,6 +1435,127 @@ Foam::AMIInterpolation<SourcePatch, TargetPatch>::AMIInterpolation
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class SourcePatch, class TargetPatch>
|
||||||
|
Foam::AMIInterpolation<SourcePatch, TargetPatch>::AMIInterpolation
|
||||||
|
(
|
||||||
|
const AMIInterpolation<SourcePatch, TargetPatch>& fineAMI,
|
||||||
|
const labelList& sourceRestrictAddressing,
|
||||||
|
const labelList& targetRestrictAddressing
|
||||||
|
)
|
||||||
|
:
|
||||||
|
singlePatchProc_(fineAMI.singlePatchProc_),
|
||||||
|
srcAddress_(),
|
||||||
|
srcWeights_(),
|
||||||
|
tgtAddress_(),
|
||||||
|
tgtWeights_(),
|
||||||
|
startSeedI_(0),
|
||||||
|
triMode_(fineAMI.triMode_),
|
||||||
|
srcMapPtr_(NULL),
|
||||||
|
tgtMapPtr_(NULL)
|
||||||
|
{
|
||||||
|
label sourceCoarseSize =
|
||||||
|
(
|
||||||
|
sourceRestrictAddressing.size()
|
||||||
|
? max(sourceRestrictAddressing)+1
|
||||||
|
: 0
|
||||||
|
);
|
||||||
|
|
||||||
|
label neighbourCoarseSize =
|
||||||
|
(
|
||||||
|
targetRestrictAddressing.size()
|
||||||
|
? max(targetRestrictAddressing)+1
|
||||||
|
: 0
|
||||||
|
);
|
||||||
|
|
||||||
|
if (debug & 2)
|
||||||
|
{
|
||||||
|
Pout<< "AMI: Creating addressing and weights as agglomeration of AMI :"
|
||||||
|
<< " source:" << fineAMI.srcAddress().size()
|
||||||
|
<< " target:" << fineAMI.tgtAddress().size()
|
||||||
|
<< " coarse source size:" << sourceCoarseSize
|
||||||
|
<< " neighbour source size:" << neighbourCoarseSize
|
||||||
|
<< endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
if
|
||||||
|
(
|
||||||
|
fineAMI.srcAddress().size() != sourceRestrictAddressing.size()
|
||||||
|
|| fineAMI.tgtAddress().size() != targetRestrictAddressing.size()
|
||||||
|
)
|
||||||
|
{
|
||||||
|
FatalErrorIn
|
||||||
|
(
|
||||||
|
"AMIInterpolation<SourcePatch, TargetPatch>::AMIInterpolation\n"
|
||||||
|
"(\n"
|
||||||
|
" const AMIInterpolation<SourcePatch, TargetPatch>&,\n"
|
||||||
|
" const label,\n"
|
||||||
|
" const labelList&\n"
|
||||||
|
")"
|
||||||
|
) << "Size mismatch." << nl
|
||||||
|
<< "Source patch size:" << fineAMI.srcAddress().size() << nl
|
||||||
|
<< "Source agglomeration size:"
|
||||||
|
<< sourceRestrictAddressing.size() << nl
|
||||||
|
<< "Target patch size:" << fineAMI.tgtAddress().size() << nl
|
||||||
|
<< "Target agglomeration size:"
|
||||||
|
<< targetRestrictAddressing.size()
|
||||||
|
<< exit(FatalError);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Agglomerate addresses and weights
|
||||||
|
|
||||||
|
agglomerate
|
||||||
|
(
|
||||||
|
fineAMI.tgtMapPtr_,
|
||||||
|
fineAMI.srcMagSf(),
|
||||||
|
fineAMI.srcAddress(),
|
||||||
|
fineAMI.srcWeights(),
|
||||||
|
|
||||||
|
sourceRestrictAddressing,
|
||||||
|
targetRestrictAddressing,
|
||||||
|
|
||||||
|
srcMagSf_,
|
||||||
|
srcAddress_,
|
||||||
|
srcWeights_,
|
||||||
|
tgtMapPtr_
|
||||||
|
);
|
||||||
|
|
||||||
|
//if (tgtMapPtr_.valid())
|
||||||
|
//{
|
||||||
|
// Pout<< "tgtMap:" << endl;
|
||||||
|
// string oldPrefix = Pout.prefix();
|
||||||
|
// Pout.prefix() = oldPrefix + " ";
|
||||||
|
// tgtMapPtr_().printLayout(Pout);
|
||||||
|
// Pout.prefix() = oldPrefix;
|
||||||
|
//}
|
||||||
|
|
||||||
|
agglomerate
|
||||||
|
(
|
||||||
|
fineAMI.srcMapPtr_,
|
||||||
|
fineAMI.tgtMagSf(),
|
||||||
|
fineAMI.tgtAddress(),
|
||||||
|
fineAMI.tgtWeights(),
|
||||||
|
|
||||||
|
targetRestrictAddressing,
|
||||||
|
sourceRestrictAddressing,
|
||||||
|
|
||||||
|
tgtMagSf_,
|
||||||
|
tgtAddress_,
|
||||||
|
tgtWeights_,
|
||||||
|
srcMapPtr_
|
||||||
|
);
|
||||||
|
|
||||||
|
//if (srcMapPtr_.valid())
|
||||||
|
//{
|
||||||
|
// Pout<< "srcMap:" << endl;
|
||||||
|
// string oldPrefix = Pout.prefix();
|
||||||
|
// Pout.prefix() = oldPrefix + " ";
|
||||||
|
// srcMapPtr_().printLayout(Pout);
|
||||||
|
// Pout.prefix() = oldPrefix;
|
||||||
|
//}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
template<class SourcePatch, class TargetPatch>
|
template<class SourcePatch, class TargetPatch>
|
||||||
@ -1181,9 +1572,23 @@ void Foam::AMIInterpolation<SourcePatch, TargetPatch>::update
|
|||||||
const primitivePatch& tgtPatch
|
const primitivePatch& tgtPatch
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
static label patchI = 0;
|
// Calculate face areas
|
||||||
|
srcMagSf_.setSize(srcPatch.size());
|
||||||
|
forAll(srcMagSf_, faceI)
|
||||||
|
{
|
||||||
|
srcMagSf_[faceI] = srcPatch[faceI].mag(srcPatch.points());
|
||||||
|
}
|
||||||
|
tgtMagSf_.setSize(tgtPatch.size());
|
||||||
|
forAll(tgtMagSf_, faceI)
|
||||||
|
{
|
||||||
|
tgtMagSf_[faceI] = tgtPatch[faceI].mag(tgtPatch.points());
|
||||||
|
}
|
||||||
|
|
||||||
if (Pstream::parRun() && distributed(srcPatch, tgtPatch))
|
|
||||||
|
// Calculate if patches present on multiple processors
|
||||||
|
singlePatchProc_ = calcDistribution(srcPatch, tgtPatch);
|
||||||
|
|
||||||
|
if (singlePatchProc_ == -1)
|
||||||
{
|
{
|
||||||
// convert local addressing to global addressing
|
// convert local addressing to global addressing
|
||||||
globalIndex globalSrcFaces(srcPatch.size());
|
globalIndex globalSrcFaces(srcPatch.size());
|
||||||
@ -1288,8 +1693,8 @@ void Foam::AMIInterpolation<SourcePatch, TargetPatch>::update
|
|||||||
);
|
);
|
||||||
|
|
||||||
// weights normalisation
|
// weights normalisation
|
||||||
normaliseWeights(srcPatch, "source", srcAddress_, srcWeights_, true);
|
normaliseWeights(srcMagSf_, "source", srcAddress_, srcWeights_, true);
|
||||||
normaliseWeights(tgtPatch, "target", tgtAddress_, tgtWeights_, true);
|
normaliseWeights(tgtMagSf_, "target", tgtAddress_, tgtWeights_, true);
|
||||||
|
|
||||||
// cache maps and reset addresses
|
// cache maps and reset addresses
|
||||||
List<Map<label> > cMap;
|
List<Map<label> > cMap;
|
||||||
@ -1308,11 +1713,9 @@ void Foam::AMIInterpolation<SourcePatch, TargetPatch>::update
|
|||||||
|
|
||||||
calcAddressing(srcPatch, tgtPatch);
|
calcAddressing(srcPatch, tgtPatch);
|
||||||
|
|
||||||
normaliseWeights(srcPatch, "source", srcAddress_, srcWeights_, true);
|
normaliseWeights(srcMagSf_, "source", srcAddress_, srcWeights_, true);
|
||||||
normaliseWeights(tgtPatch, "target", tgtAddress_, tgtWeights_, true);
|
normaliseWeights(tgtMagSf_, "target", tgtAddress_, tgtWeights_, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
patchI++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1348,7 +1751,7 @@ Foam::AMIInterpolation<SourcePatch, TargetPatch>::interpolateToSource
|
|||||||
|
|
||||||
Field<Type>& result = tresult();
|
Field<Type>& result = tresult();
|
||||||
|
|
||||||
if (Pstream::parRun())
|
if (singlePatchProc_ == -1)
|
||||||
{
|
{
|
||||||
const mapDistribute& map = tgtMapPtr_();
|
const mapDistribute& map = tgtMapPtr_();
|
||||||
|
|
||||||
@ -1430,7 +1833,7 @@ Foam::AMIInterpolation<SourcePatch, TargetPatch>::interpolateToTarget
|
|||||||
|
|
||||||
Field<Type>& result = tresult();
|
Field<Type>& result = tresult();
|
||||||
|
|
||||||
if (Pstream::parRun())
|
if (singlePatchProc_ == -1)
|
||||||
{
|
{
|
||||||
const mapDistribute& map = srcMapPtr_();
|
const mapDistribute& map = srcMapPtr_();
|
||||||
|
|
||||||
|
|||||||
@ -106,8 +106,16 @@ class AMIInterpolation
|
|||||||
|
|
||||||
// Private data
|
// Private data
|
||||||
|
|
||||||
|
|
||||||
|
//- Index of processor that holds all of both sides. -1 in all other
|
||||||
|
// cases
|
||||||
|
label singlePatchProc_;
|
||||||
|
|
||||||
// Source patch
|
// Source patch
|
||||||
|
|
||||||
|
//- Source face areas
|
||||||
|
scalarField srcMagSf_;
|
||||||
|
|
||||||
//- Addresses of target faces per source face
|
//- Addresses of target faces per source face
|
||||||
labelListList srcAddress_;
|
labelListList srcAddress_;
|
||||||
|
|
||||||
@ -117,6 +125,9 @@ class AMIInterpolation
|
|||||||
|
|
||||||
// Target patch
|
// Target patch
|
||||||
|
|
||||||
|
//- Target face areas
|
||||||
|
scalarField tgtMagSf_;
|
||||||
|
|
||||||
//- Addresses of source faces per target face
|
//- Addresses of source faces per target face
|
||||||
labelListList tgtAddress_;
|
labelListList tgtAddress_;
|
||||||
|
|
||||||
@ -168,8 +179,8 @@ class AMIInterpolation
|
|||||||
|
|
||||||
// Parallel functionality
|
// Parallel functionality
|
||||||
|
|
||||||
//- Return true if faces are spread over multiple domains
|
//- Calculate if patches are on multiple processors
|
||||||
bool distributed
|
label calcDistribution
|
||||||
(
|
(
|
||||||
const primitivePatch& srcPatch,
|
const primitivePatch& srcPatch,
|
||||||
const primitivePatch& tgtPatch
|
const primitivePatch& tgtPatch
|
||||||
@ -276,15 +287,32 @@ class AMIInterpolation
|
|||||||
// NOTE: if area weights are incorrect by 'a significant amount'
|
// NOTE: if area weights are incorrect by 'a significant amount'
|
||||||
// normalisation may stabilise the solution, but will introduce
|
// normalisation may stabilise the solution, but will introduce
|
||||||
// numerical error!
|
// numerical error!
|
||||||
void normaliseWeights
|
static void normaliseWeights
|
||||||
(
|
(
|
||||||
const primitivePatch& patch,
|
const scalarField& patchAreas,
|
||||||
const word& patchName,
|
const word& patchName,
|
||||||
const labelListList& addr,
|
const labelListList& addr,
|
||||||
scalarListList& wght,
|
scalarListList& wght,
|
||||||
const bool output
|
const bool output
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Constructor helper
|
||||||
|
|
||||||
|
static void agglomerate
|
||||||
|
(
|
||||||
|
const autoPtr<mapDistribute>& targetMap,
|
||||||
|
const scalarField& fineSrcMagSf,
|
||||||
|
const labelListList& fineSrcAddress,
|
||||||
|
const scalarListList& fineSrcWeights,
|
||||||
|
|
||||||
|
const labelList& sourceRestrictAddressing,
|
||||||
|
const labelList& targetRestrictAddressing,
|
||||||
|
|
||||||
|
scalarField& srcMagSf,
|
||||||
|
labelListList& srcAddress,
|
||||||
|
scalarListList& srcWeights,
|
||||||
|
autoPtr<mapDistribute>& tgtMap
|
||||||
|
);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
@ -307,6 +335,15 @@ public:
|
|||||||
const faceAreaIntersect::triangulationMode& triMode
|
const faceAreaIntersect::triangulationMode& triMode
|
||||||
);
|
);
|
||||||
|
|
||||||
|
//- Construct from agglomeration of AMIInterpolation. Agglomeration
|
||||||
|
// passed in as new coarse size and addressing from fine from coarse.
|
||||||
|
AMIInterpolation
|
||||||
|
(
|
||||||
|
const AMIInterpolation<SourcePatch, TargetPatch>& fineAMI,
|
||||||
|
const labelList& sourceRestrictAddressing,
|
||||||
|
const labelList& neighbourRestrictAddressing
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
//- Destructor
|
//- Destructor
|
||||||
~AMIInterpolation();
|
~AMIInterpolation();
|
||||||
@ -316,22 +353,43 @@ public:
|
|||||||
|
|
||||||
// Access
|
// Access
|
||||||
|
|
||||||
|
//- -1 or the processor holding all faces (both sides) of the AMI
|
||||||
|
label singlePatchProc() const;
|
||||||
|
|
||||||
// Source patch
|
// Source patch
|
||||||
|
|
||||||
|
//- Return const access to source patch face areas
|
||||||
|
inline const scalarField& srcMagSf() const;
|
||||||
|
|
||||||
//- Return const access to source patch addressing
|
//- Return const access to source patch addressing
|
||||||
inline const labelListList& srcAddress();
|
inline const labelListList& srcAddress() const;
|
||||||
|
|
||||||
//- Return const access to source patch weights
|
//- Return const access to source patch weights
|
||||||
inline const scalarListList& srcWeights();
|
inline const scalarListList& srcWeights() const;
|
||||||
|
|
||||||
|
//- Source map pointer - valid only if singlePatchProc=-1.
|
||||||
|
// This gets
|
||||||
|
// source data into a form to be consumed by
|
||||||
|
// tgtAddress, tgtWeights
|
||||||
|
inline const mapDistribute& srcMap() const;
|
||||||
|
|
||||||
|
|
||||||
// Target patch
|
// Target patch
|
||||||
|
|
||||||
|
//- Return const access to target patch face areas
|
||||||
|
inline const scalarField& tgtMagSf() const;
|
||||||
|
|
||||||
//- Return const access to target patch addressing
|
//- Return const access to target patch addressing
|
||||||
inline const labelListList& tgtAddress();
|
inline const labelListList& tgtAddress() const;
|
||||||
|
|
||||||
//- Return const access to target patch weights
|
//- Return const access to target patch weights
|
||||||
inline const scalarListList& tgtWeights();
|
inline const scalarListList& tgtWeights() const;
|
||||||
|
|
||||||
|
//- Target map pointer - valid only if singlePatchProc=-1.
|
||||||
|
// This gets
|
||||||
|
// target data into a form to be consumed by
|
||||||
|
// srcAddress, srcWeights
|
||||||
|
inline const mapDistribute& tgtMap() const;
|
||||||
|
|
||||||
|
|
||||||
// Manipulation
|
// Manipulation
|
||||||
|
|||||||
@ -23,9 +23,25 @@ License
|
|||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
template<class SourcePatch, class TargetPatch>
|
||||||
|
inline Foam::label
|
||||||
|
Foam::AMIInterpolation<SourcePatch, TargetPatch>::singlePatchProc() const
|
||||||
|
{
|
||||||
|
return singlePatchProc_;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class SourcePatch, class TargetPatch>
|
||||||
|
inline const Foam::scalarField&
|
||||||
|
Foam::AMIInterpolation<SourcePatch, TargetPatch>::srcMagSf() const
|
||||||
|
{
|
||||||
|
return srcMagSf_;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
template<class SourcePatch, class TargetPatch>
|
template<class SourcePatch, class TargetPatch>
|
||||||
inline const Foam::labelListList&
|
inline const Foam::labelListList&
|
||||||
Foam::AMIInterpolation<SourcePatch, TargetPatch>::srcAddress()
|
Foam::AMIInterpolation<SourcePatch, TargetPatch>::srcAddress() const
|
||||||
{
|
{
|
||||||
return srcAddress_;
|
return srcAddress_;
|
||||||
}
|
}
|
||||||
@ -33,15 +49,31 @@ Foam::AMIInterpolation<SourcePatch, TargetPatch>::srcAddress()
|
|||||||
|
|
||||||
template<class SourcePatch, class TargetPatch>
|
template<class SourcePatch, class TargetPatch>
|
||||||
inline const Foam::scalarListList&
|
inline const Foam::scalarListList&
|
||||||
Foam::AMIInterpolation<SourcePatch, TargetPatch>::srcWeights()
|
Foam::AMIInterpolation<SourcePatch, TargetPatch>::srcWeights() const
|
||||||
{
|
{
|
||||||
return srcWeights_;
|
return srcWeights_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class SourcePatch, class TargetPatch>
|
||||||
|
inline const Foam::mapDistribute&
|
||||||
|
Foam::AMIInterpolation<SourcePatch, TargetPatch>::srcMap() const
|
||||||
|
{
|
||||||
|
return srcMapPtr_();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class SourcePatch, class TargetPatch>
|
||||||
|
inline const Foam::scalarField&
|
||||||
|
Foam::AMIInterpolation<SourcePatch, TargetPatch>::tgtMagSf() const
|
||||||
|
{
|
||||||
|
return tgtMagSf_;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
template<class SourcePatch, class TargetPatch>
|
template<class SourcePatch, class TargetPatch>
|
||||||
inline const Foam::labelListList&
|
inline const Foam::labelListList&
|
||||||
Foam::AMIInterpolation<SourcePatch, TargetPatch>::tgtAddress()
|
Foam::AMIInterpolation<SourcePatch, TargetPatch>::tgtAddress() const
|
||||||
{
|
{
|
||||||
return tgtAddress_;
|
return tgtAddress_;
|
||||||
}
|
}
|
||||||
@ -49,10 +81,18 @@ Foam::AMIInterpolation<SourcePatch, TargetPatch>::tgtAddress()
|
|||||||
|
|
||||||
template<class SourcePatch, class TargetPatch>
|
template<class SourcePatch, class TargetPatch>
|
||||||
inline const Foam::scalarListList&
|
inline const Foam::scalarListList&
|
||||||
Foam::AMIInterpolation<SourcePatch, TargetPatch>::tgtWeights()
|
Foam::AMIInterpolation<SourcePatch, TargetPatch>::tgtWeights() const
|
||||||
{
|
{
|
||||||
return tgtWeights_;
|
return tgtWeights_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class SourcePatch, class TargetPatch>
|
||||||
|
inline const Foam::mapDistribute&
|
||||||
|
Foam::AMIInterpolation<SourcePatch, TargetPatch>::tgtMap() const
|
||||||
|
{
|
||||||
|
return tgtMapPtr_();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
// ************************************************************************* //
|
||||||
|
|||||||
@ -0,0 +1,107 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
License
|
||||||
|
This file is part of OpenFOAM.
|
||||||
|
|
||||||
|
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#include "cyclicAMIGAMGInterfaceField.H"
|
||||||
|
#include "addToRunTimeSelectionTable.H"
|
||||||
|
#include "lduMatrix.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
defineTypeNameAndDebug(cyclicAMIGAMGInterfaceField, 0);
|
||||||
|
addToRunTimeSelectionTable
|
||||||
|
(
|
||||||
|
GAMGInterfaceField,
|
||||||
|
cyclicAMIGAMGInterfaceField,
|
||||||
|
lduInterface
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Foam::cyclicAMIGAMGInterfaceField::cyclicAMIGAMGInterfaceField
|
||||||
|
(
|
||||||
|
const GAMGInterface& GAMGCp,
|
||||||
|
const lduInterfaceField& fineInterface
|
||||||
|
)
|
||||||
|
:
|
||||||
|
GAMGInterfaceField(GAMGCp, fineInterface),
|
||||||
|
cyclicAMIInterface_(refCast<const cyclicAMIGAMGInterface>(GAMGCp)),
|
||||||
|
doTransform_(false),
|
||||||
|
rank_(0)
|
||||||
|
{
|
||||||
|
const cyclicAMILduInterfaceField& p =
|
||||||
|
refCast<const cyclicAMILduInterfaceField>(fineInterface);
|
||||||
|
|
||||||
|
doTransform_ = p.doTransform();
|
||||||
|
rank_ = p.rank();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * Desstructor * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Foam::cyclicAMIGAMGInterfaceField::~cyclicAMIGAMGInterfaceField()
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
void Foam::cyclicAMIGAMGInterfaceField::updateInterfaceMatrix
|
||||||
|
(
|
||||||
|
const scalarField& psiInternal,
|
||||||
|
scalarField& result,
|
||||||
|
const lduMatrix&,
|
||||||
|
const scalarField& coeffs,
|
||||||
|
const direction cmpt,
|
||||||
|
const Pstream::commsTypes
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
// Get neighbouring field
|
||||||
|
scalarField pnf
|
||||||
|
(
|
||||||
|
cyclicAMIInterface_.neighbPatch().interfaceInternalField(psiInternal)
|
||||||
|
);
|
||||||
|
|
||||||
|
if (cyclicAMIInterface_.owner())
|
||||||
|
{
|
||||||
|
pnf = cyclicAMIInterface_.AMI().interpolateToSource(pnf);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pnf = cyclicAMIInterface_.neighbPatch().AMI().interpolateToTarget(pnf);
|
||||||
|
}
|
||||||
|
|
||||||
|
const labelUList& faceCells = cyclicAMIInterface_.faceCells();
|
||||||
|
|
||||||
|
forAll(faceCells, elemI)
|
||||||
|
{
|
||||||
|
result[faceCells[elemI]] -= coeffs[elemI]*pnf[elemI];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -0,0 +1,158 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
License
|
||||||
|
This file is part of OpenFOAM.
|
||||||
|
|
||||||
|
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
Class
|
||||||
|
Foam::cyclicAMIGAMGInterfaceField
|
||||||
|
|
||||||
|
Description
|
||||||
|
GAMG agglomerated cyclic interface field.
|
||||||
|
|
||||||
|
SourceFiles
|
||||||
|
cyclicAMIGAMGInterfaceField.C
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef cyclicAMIGAMGInterfaceField_H
|
||||||
|
#define cyclicAMIGAMGInterfaceField_H
|
||||||
|
|
||||||
|
#include "GAMGInterfaceField.H"
|
||||||
|
#include "cyclicAMIGAMGInterface.H"
|
||||||
|
#include "cyclicAMILduInterfaceField.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
Class cyclicAMIGAMGInterfaceField Declaration
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
class cyclicAMIGAMGInterfaceField
|
||||||
|
:
|
||||||
|
public GAMGInterfaceField,
|
||||||
|
virtual public cyclicAMILduInterfaceField
|
||||||
|
{
|
||||||
|
// Private data
|
||||||
|
|
||||||
|
//- Local reference cast into the cyclic interface
|
||||||
|
const cyclicAMIGAMGInterface& cyclicAMIInterface_;
|
||||||
|
|
||||||
|
//- Is the transform required
|
||||||
|
bool doTransform_;
|
||||||
|
|
||||||
|
//- Rank of component for transformation
|
||||||
|
int rank_;
|
||||||
|
|
||||||
|
|
||||||
|
// Private Member Functions
|
||||||
|
|
||||||
|
//- Disallow default bitwise copy construct
|
||||||
|
cyclicAMIGAMGInterfaceField(const cyclicAMIGAMGInterfaceField&);
|
||||||
|
|
||||||
|
//- Disallow default bitwise assignment
|
||||||
|
void operator=(const cyclicAMIGAMGInterfaceField&);
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
//- Runtime type information
|
||||||
|
TypeName("cyclicAMI");
|
||||||
|
|
||||||
|
|
||||||
|
// Constructors
|
||||||
|
|
||||||
|
//- Construct from GAMG interface and fine level interface field
|
||||||
|
cyclicAMIGAMGInterfaceField
|
||||||
|
(
|
||||||
|
const GAMGInterface& GAMGCp,
|
||||||
|
const lduInterfaceField& fineInterfaceField
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
//- Destructor
|
||||||
|
virtual ~cyclicAMIGAMGInterfaceField();
|
||||||
|
|
||||||
|
|
||||||
|
// Member Functions
|
||||||
|
|
||||||
|
// Access
|
||||||
|
|
||||||
|
//- Return size
|
||||||
|
label size() const
|
||||||
|
{
|
||||||
|
return cyclicAMIInterface_.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Interface matrix update
|
||||||
|
|
||||||
|
//- Update result field based on interface functionality
|
||||||
|
virtual void updateInterfaceMatrix
|
||||||
|
(
|
||||||
|
const scalarField& psiInternal,
|
||||||
|
scalarField& result,
|
||||||
|
const lduMatrix&,
|
||||||
|
const scalarField& coeffs,
|
||||||
|
const direction cmpt,
|
||||||
|
const Pstream::commsTypes commsType
|
||||||
|
) const;
|
||||||
|
|
||||||
|
|
||||||
|
//- Cyclic interface functions
|
||||||
|
|
||||||
|
//- Does the interface field perform the transfromation
|
||||||
|
virtual bool doTransform() const
|
||||||
|
{
|
||||||
|
return doTransform_;
|
||||||
|
}
|
||||||
|
|
||||||
|
//- Return face transformation tensor
|
||||||
|
virtual const tensorField& forwardT() const
|
||||||
|
{
|
||||||
|
return cyclicAMIInterface_.forwardT();
|
||||||
|
}
|
||||||
|
|
||||||
|
//- Return neighbour-cell transformation tensor
|
||||||
|
virtual const tensorField& reverseT() const
|
||||||
|
{
|
||||||
|
return cyclicAMIInterface_.reverseT();
|
||||||
|
}
|
||||||
|
|
||||||
|
//- Return rank of component for transform
|
||||||
|
virtual int rank() const
|
||||||
|
{
|
||||||
|
return rank_;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
} // End namespace Foam
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -0,0 +1,198 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
License
|
||||||
|
This file is part of OpenFOAM.
|
||||||
|
|
||||||
|
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#include "AMIInterpolation.H"
|
||||||
|
#include "cyclicAMIGAMGInterface.H"
|
||||||
|
#include "addToRunTimeSelectionTable.H"
|
||||||
|
#include "Map.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
defineTypeNameAndDebug(cyclicAMIGAMGInterface, 0);
|
||||||
|
addToRunTimeSelectionTable
|
||||||
|
(
|
||||||
|
GAMGInterface,
|
||||||
|
cyclicAMIGAMGInterface,
|
||||||
|
lduInterface
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Foam::cyclicAMIGAMGInterface::cyclicAMIGAMGInterface
|
||||||
|
(
|
||||||
|
const label index,
|
||||||
|
const lduInterfacePtrsList& coarseInterfaces,
|
||||||
|
const lduInterface& fineInterface,
|
||||||
|
const labelField& localRestrictAddressing,
|
||||||
|
const labelField& neighbourRestrictAddressing
|
||||||
|
)
|
||||||
|
:
|
||||||
|
GAMGInterface
|
||||||
|
(
|
||||||
|
index,
|
||||||
|
coarseInterfaces,
|
||||||
|
fineInterface,
|
||||||
|
localRestrictAddressing,
|
||||||
|
neighbourRestrictAddressing
|
||||||
|
),
|
||||||
|
fineCyclicAMIInterface_
|
||||||
|
(
|
||||||
|
refCast<const cyclicAMILduInterface>(fineInterface)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
// Construct face agglomeration from cell agglomeration
|
||||||
|
{
|
||||||
|
// From coarse face to cell
|
||||||
|
DynamicList<label> dynFaceCells(localRestrictAddressing.size());
|
||||||
|
|
||||||
|
// From face to coarse face
|
||||||
|
DynamicList<label> dynFaceRestrictAddressing
|
||||||
|
(
|
||||||
|
localRestrictAddressing.size()
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<label> masterToCoarseFace(localRestrictAddressing.size());
|
||||||
|
|
||||||
|
forAll(localRestrictAddressing, ffi)
|
||||||
|
{
|
||||||
|
label curMaster = localRestrictAddressing[ffi];
|
||||||
|
|
||||||
|
Map<label>::const_iterator fnd = masterToCoarseFace.find
|
||||||
|
(
|
||||||
|
curMaster
|
||||||
|
);
|
||||||
|
|
||||||
|
if (fnd == masterToCoarseFace.end())
|
||||||
|
{
|
||||||
|
// New coarse face
|
||||||
|
label coarseI = dynFaceCells.size();
|
||||||
|
dynFaceRestrictAddressing.append(coarseI);
|
||||||
|
dynFaceCells.append(curMaster);
|
||||||
|
masterToCoarseFace.insert(curMaster, coarseI);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Already have coarse face
|
||||||
|
dynFaceRestrictAddressing.append(fnd());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
faceCells_.transfer(dynFaceCells);
|
||||||
|
faceRestrictAddressing_.transfer(dynFaceRestrictAddressing);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// On the owner side construct the AMI
|
||||||
|
|
||||||
|
if (fineCyclicAMIInterface_.owner())
|
||||||
|
{
|
||||||
|
// Construct the neighbour side agglomeration (as the neighbour would
|
||||||
|
// do it so it the exact loop above using neighbourRestrictAddressing
|
||||||
|
// instead of localRestrictAddressing)
|
||||||
|
|
||||||
|
labelList nbrFaceRestrictAddressing;
|
||||||
|
{
|
||||||
|
// From face to coarse face
|
||||||
|
DynamicList<label> dynNbrFaceRestrictAddressing
|
||||||
|
(
|
||||||
|
neighbourRestrictAddressing.size()
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<label> masterToCoarseFace(neighbourRestrictAddressing.size());
|
||||||
|
|
||||||
|
forAll(neighbourRestrictAddressing, ffi)
|
||||||
|
{
|
||||||
|
label curMaster = neighbourRestrictAddressing[ffi];
|
||||||
|
|
||||||
|
Map<label>::const_iterator fnd = masterToCoarseFace.find
|
||||||
|
(
|
||||||
|
curMaster
|
||||||
|
);
|
||||||
|
|
||||||
|
if (fnd == masterToCoarseFace.end())
|
||||||
|
{
|
||||||
|
// New coarse face
|
||||||
|
label coarseI = masterToCoarseFace.size();
|
||||||
|
dynNbrFaceRestrictAddressing.append(coarseI);
|
||||||
|
masterToCoarseFace.insert(curMaster, coarseI);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Already have coarse face
|
||||||
|
dynNbrFaceRestrictAddressing.append(fnd());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
nbrFaceRestrictAddressing.transfer(dynNbrFaceRestrictAddressing);
|
||||||
|
}
|
||||||
|
|
||||||
|
amiPtr_.reset
|
||||||
|
(
|
||||||
|
new AMIPatchToPatchInterpolation
|
||||||
|
(
|
||||||
|
fineCyclicAMIInterface_.AMI(),
|
||||||
|
faceRestrictAddressing_,
|
||||||
|
nbrFaceRestrictAddressing
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * Desstructor * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Foam::cyclicAMIGAMGInterface::~cyclicAMIGAMGInterface()
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Foam::tmp<Foam::labelField> Foam::cyclicAMIGAMGInterface::internalFieldTransfer
|
||||||
|
(
|
||||||
|
const Pstream::commsTypes,
|
||||||
|
const labelUList& iF
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
const cyclicAMIGAMGInterface& nbr =
|
||||||
|
dynamic_cast<const cyclicAMIGAMGInterface&>(neighbPatch());
|
||||||
|
const labelUList& nbrFaceCells = nbr.faceCells();
|
||||||
|
|
||||||
|
tmp<labelField> tpnf(new labelField(nbrFaceCells.size()));
|
||||||
|
labelField& pnf = tpnf();
|
||||||
|
|
||||||
|
forAll(pnf, facei)
|
||||||
|
{
|
||||||
|
pnf[facei] = iF[nbrFaceCells[facei]];
|
||||||
|
}
|
||||||
|
|
||||||
|
return tpnf;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -0,0 +1,158 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
License
|
||||||
|
This file is part of OpenFOAM.
|
||||||
|
|
||||||
|
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
Class
|
||||||
|
Foam::cyclicAMIGAMGInterface
|
||||||
|
|
||||||
|
Description
|
||||||
|
GAMG agglomerated cyclic AMI interface.
|
||||||
|
|
||||||
|
SourceFiles
|
||||||
|
cyclicAMIGAMGInterface.C
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef cyclicAMIGAMGInterface_H
|
||||||
|
#define cyclicAMIGAMGInterface_H
|
||||||
|
|
||||||
|
#include "GAMGInterface.H"
|
||||||
|
#include "cyclicAMILduInterface.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
Class cyclicAMIGAMGInterface Declaration
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
class cyclicAMIGAMGInterface
|
||||||
|
:
|
||||||
|
public GAMGInterface,
|
||||||
|
virtual public cyclicAMILduInterface
|
||||||
|
{
|
||||||
|
// Private data
|
||||||
|
|
||||||
|
//- Reference for the cyclicLduInterface from which this is
|
||||||
|
// agglomerated
|
||||||
|
const cyclicAMILduInterface& fineCyclicAMIInterface_;
|
||||||
|
|
||||||
|
//- AMI interface
|
||||||
|
autoPtr<AMIPatchToPatchInterpolation> amiPtr_;
|
||||||
|
|
||||||
|
|
||||||
|
// Private Member Functions
|
||||||
|
|
||||||
|
//- Disallow default bitwise copy construct
|
||||||
|
cyclicAMIGAMGInterface(const cyclicAMIGAMGInterface&);
|
||||||
|
|
||||||
|
//- Disallow default bitwise assignment
|
||||||
|
void operator=(const cyclicAMIGAMGInterface&);
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
//- Runtime type information
|
||||||
|
TypeName("cyclicAMI");
|
||||||
|
|
||||||
|
|
||||||
|
// Constructors
|
||||||
|
|
||||||
|
//- Construct from fine level interface,
|
||||||
|
// local and neighbour restrict addressing
|
||||||
|
cyclicAMIGAMGInterface
|
||||||
|
(
|
||||||
|
const label index,
|
||||||
|
const lduInterfacePtrsList& coarseInterfaces,
|
||||||
|
const lduInterface& fineInterface,
|
||||||
|
const labelField& restrictAddressing,
|
||||||
|
const labelField& neighbourRestrictAddressing
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
//- Destructor
|
||||||
|
virtual ~cyclicAMIGAMGInterface();
|
||||||
|
|
||||||
|
|
||||||
|
// Member Functions
|
||||||
|
|
||||||
|
// Interface transfer functions
|
||||||
|
|
||||||
|
//- Transfer and return internal field adjacent to the interface
|
||||||
|
virtual tmp<labelField> internalFieldTransfer
|
||||||
|
(
|
||||||
|
const Pstream::commsTypes commsType,
|
||||||
|
const labelUList& iF
|
||||||
|
) const;
|
||||||
|
|
||||||
|
|
||||||
|
//- Cyclic interface functions
|
||||||
|
|
||||||
|
//- Return neigbour processor number
|
||||||
|
virtual label neighbPatchID() const
|
||||||
|
{
|
||||||
|
return fineCyclicAMIInterface_.neighbPatchID();
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual bool owner() const
|
||||||
|
{
|
||||||
|
return fineCyclicAMIInterface_.owner();
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual const cyclicAMIGAMGInterface& neighbPatch() const
|
||||||
|
{
|
||||||
|
return dynamic_cast<const cyclicAMIGAMGInterface&>
|
||||||
|
(
|
||||||
|
coarseInterfaces_[neighbPatchID()]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual const AMIPatchToPatchInterpolation& AMI() const
|
||||||
|
{
|
||||||
|
return amiPtr_();
|
||||||
|
}
|
||||||
|
|
||||||
|
//- Return face transformation tensor
|
||||||
|
virtual const tensorField& forwardT() const
|
||||||
|
{
|
||||||
|
return fineCyclicAMIInterface_.forwardT();
|
||||||
|
}
|
||||||
|
|
||||||
|
//- Return neighbour-cell transformation tensor
|
||||||
|
virtual const tensorField& reverseT() const
|
||||||
|
{
|
||||||
|
return fineCyclicAMIInterface_.reverseT();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
} // End namespace Foam
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -36,6 +36,7 @@ SourceFiles
|
|||||||
#define cyclicAMILduInterface_H
|
#define cyclicAMILduInterface_H
|
||||||
|
|
||||||
#include "primitiveFieldsFwd.H"
|
#include "primitiveFieldsFwd.H"
|
||||||
|
#include "AMIPatchToPatchInterpolation.H"
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
@ -78,6 +79,8 @@ public:
|
|||||||
//- Return processor number
|
//- Return processor number
|
||||||
virtual const cyclicAMILduInterface& neighbPatch() const = 0;
|
virtual const cyclicAMILduInterface& neighbPatch() const = 0;
|
||||||
|
|
||||||
|
virtual const AMIPatchToPatchInterpolation& AMI() const = 0;
|
||||||
|
|
||||||
//- Return face transformation tensor
|
//- Return face transformation tensor
|
||||||
virtual const tensorField& forwardT() const = 0;
|
virtual const tensorField& forwardT() const = 0;
|
||||||
|
|
||||||
|
|||||||
@ -86,7 +86,7 @@ void Foam::cyclicAMIPolyPatch::calcTransforms()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Half1
|
// Half1
|
||||||
const cyclicAMIPolyPatch& half1 = nbrPatch();
|
const cyclicAMIPolyPatch& half1 = neighbPatch();
|
||||||
vectorField half1Areas(half1.size());
|
vectorField half1Areas(half1.size());
|
||||||
forAll(half1, facei)
|
forAll(half1, facei)
|
||||||
{
|
{
|
||||||
@ -114,14 +114,14 @@ void Foam::cyclicAMIPolyPatch::calcTransforms
|
|||||||
const vectorField& half1Areas
|
const vectorField& half1Areas
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
if (transform_ != nbrPatch().transform_)
|
if (transform_ != neighbPatch().transform_)
|
||||||
{
|
{
|
||||||
FatalErrorIn("cyclicAMIPolyPatch::calcTransforms()")
|
FatalErrorIn("cyclicAMIPolyPatch::calcTransforms()")
|
||||||
<< "Patch " << name()
|
<< "Patch " << name()
|
||||||
<< " has transform type " << transformTypeNames[transform_]
|
<< " has transform type " << transformTypeNames[transform_]
|
||||||
<< ", neighbour patch " << nbrPatchName_
|
<< ", neighbour patch " << nbrPatchName_
|
||||||
<< " has transform type "
|
<< " has transform type "
|
||||||
<< nbrPatch().transformTypeNames[nbrPatch().transform_]
|
<< neighbPatch().transformTypeNames[neighbPatch().transform_]
|
||||||
<< exit(FatalError);
|
<< exit(FatalError);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -221,19 +221,19 @@ void Foam::cyclicAMIPolyPatch::calcTransforms
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Foam::cyclicAMIPolyPatch::resetAMI()
|
void Foam::cyclicAMIPolyPatch::resetAMI() const
|
||||||
{
|
{
|
||||||
if (owner())
|
if (owner())
|
||||||
{
|
{
|
||||||
AMIPtr_.clear();
|
AMIPtr_.clear();
|
||||||
|
|
||||||
const polyPatch& nbr = nbrPatch();
|
const polyPatch& nbr = neighbPatch();
|
||||||
pointField nbrPoints = nbrPatch().localPoints();
|
pointField nbrPoints = neighbPatch().localPoints();
|
||||||
|
|
||||||
if (debug)
|
if (debug)
|
||||||
{
|
{
|
||||||
OFstream os(name() + "_neighbourPatch-org.obj");
|
OFstream os(name() + "_neighbourPatch-org.obj");
|
||||||
meshTools::writeOBJ(os, nbrPatch().localFaces(), nbrPoints);
|
meshTools::writeOBJ(os, neighbPatch().localFaces(), nbrPoints);
|
||||||
}
|
}
|
||||||
|
|
||||||
// transform neighbour patch to local system
|
// transform neighbour patch to local system
|
||||||
@ -288,9 +288,9 @@ void Foam::cyclicAMIPolyPatch::calcGeometry(PstreamBuffers& pBufs)
|
|||||||
faceCentres(),
|
faceCentres(),
|
||||||
faceAreas(),
|
faceAreas(),
|
||||||
faceCellCentres(),
|
faceCellCentres(),
|
||||||
nbrPatch().faceCentres(),
|
neighbPatch().faceCentres(),
|
||||||
nbrPatch().faceAreas(),
|
neighbPatch().faceAreas(),
|
||||||
nbrPatch().faceCellCentres()
|
neighbPatch().faceCellCentres()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -535,7 +535,7 @@ Foam::cyclicAMIPolyPatch::~cyclicAMIPolyPatch()
|
|||||||
|
|
||||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||||
|
|
||||||
Foam::label Foam::cyclicAMIPolyPatch::nbrPatchID() const
|
Foam::label Foam::cyclicAMIPolyPatch::neighbPatchID() const
|
||||||
{
|
{
|
||||||
if (nbrPatchID_ == -1)
|
if (nbrPatchID_ == -1)
|
||||||
{
|
{
|
||||||
@ -543,7 +543,7 @@ Foam::label Foam::cyclicAMIPolyPatch::nbrPatchID() const
|
|||||||
|
|
||||||
if (nbrPatchID_ == -1)
|
if (nbrPatchID_ == -1)
|
||||||
{
|
{
|
||||||
FatalErrorIn("cyclicPolyAMIPatch::nbrPatchID() const")
|
FatalErrorIn("cyclicPolyAMIPatch::neighbPatchID() const")
|
||||||
<< "Illegal neighbourPatch name " << nbrPatchName_
|
<< "Illegal neighbourPatch name " << nbrPatchName_
|
||||||
<< nl << "Valid patch names are "
|
<< nl << "Valid patch names are "
|
||||||
<< this->boundaryMesh().names()
|
<< this->boundaryMesh().names()
|
||||||
@ -557,13 +557,13 @@ Foam::label Foam::cyclicAMIPolyPatch::nbrPatchID() const
|
|||||||
this->boundaryMesh()[nbrPatchID_]
|
this->boundaryMesh()[nbrPatchID_]
|
||||||
);
|
);
|
||||||
|
|
||||||
if (nbrPatch.nbrPatchName() != name())
|
if (nbrPatch.neighbPatchName() != name())
|
||||||
{
|
{
|
||||||
WarningIn("cyclicAMIPolyPatch::nbrPatchID() const")
|
WarningIn("cyclicAMIPolyPatch::neighbPatchID() const")
|
||||||
<< "Patch " << name()
|
<< "Patch " << name()
|
||||||
<< " specifies neighbour patch " << nbrPatchName()
|
<< " specifies neighbour patch " << neighbPatchName()
|
||||||
<< nl << " but that in return specifies "
|
<< nl << " but that in return specifies "
|
||||||
<< nbrPatch.nbrPatchName() << endl;
|
<< nbrPatch.neighbPatchName() << endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -573,12 +573,12 @@ Foam::label Foam::cyclicAMIPolyPatch::nbrPatchID() const
|
|||||||
|
|
||||||
bool Foam::cyclicAMIPolyPatch::owner() const
|
bool Foam::cyclicAMIPolyPatch::owner() const
|
||||||
{
|
{
|
||||||
return index() < nbrPatchID();
|
return index() < neighbPatchID();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const Foam::autoPtr<Foam::searchableSurface>&
|
const Foam::autoPtr<Foam::searchableSurface>&
|
||||||
Foam::cyclicAMIPolyPatch::surfPtr()
|
Foam::cyclicAMIPolyPatch::surfPtr() const
|
||||||
{
|
{
|
||||||
const word surfType(surfDict_.lookupOrDefault<word>("type", "none"));
|
const word surfType(surfDict_.lookupOrDefault<word>("type", "none"));
|
||||||
|
|
||||||
@ -609,7 +609,7 @@ Foam::cyclicAMIPolyPatch::surfPtr()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const Foam::AMIPatchToPatchInterpolation& Foam::cyclicAMIPolyPatch::AMI()
|
const Foam::AMIPatchToPatchInterpolation& Foam::cyclicAMIPolyPatch::AMI() const
|
||||||
{
|
{
|
||||||
if (!owner())
|
if (!owner())
|
||||||
{
|
{
|
||||||
@ -626,6 +626,16 @@ const Foam::AMIPatchToPatchInterpolation& Foam::cyclicAMIPolyPatch::AMI()
|
|||||||
resetAMI();
|
resetAMI();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (debug)
|
||||||
|
{
|
||||||
|
Pout<< "cyclicAMIPolyPatch : " << name()
|
||||||
|
<< " constructed AMI with " << endl
|
||||||
|
<< " " << ":srcAddress:" << AMIPtr_().srcAddress().size() << endl
|
||||||
|
<< " " << " tgAddress :" << AMIPtr_().tgtAddress().size() << endl
|
||||||
|
<< endl;
|
||||||
|
}
|
||||||
|
|
||||||
return AMIPtr_();
|
return AMIPtr_();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -86,10 +86,10 @@ private:
|
|||||||
|
|
||||||
|
|
||||||
//- AMI interpolation class
|
//- AMI interpolation class
|
||||||
autoPtr<AMIPatchToPatchInterpolation> AMIPtr_;
|
mutable autoPtr<AMIPatchToPatchInterpolation> AMIPtr_;
|
||||||
|
|
||||||
//- Projection surface
|
//- Projection surface
|
||||||
autoPtr<searchableSurface> surfPtr_;
|
mutable autoPtr<searchableSurface> surfPtr_;
|
||||||
|
|
||||||
//- Dictionary used during projection surface construction
|
//- Dictionary used during projection surface construction
|
||||||
const dictionary surfDict_;
|
const dictionary surfDict_;
|
||||||
@ -110,7 +110,7 @@ private:
|
|||||||
);
|
);
|
||||||
|
|
||||||
//- Reset the AMI interpolator
|
//- Reset the AMI interpolator
|
||||||
void resetAMI();
|
void resetAMI() const;
|
||||||
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
@ -255,22 +255,22 @@ public:
|
|||||||
// Access
|
// Access
|
||||||
|
|
||||||
//- Neighbour patch name
|
//- Neighbour patch name
|
||||||
inline const word& nbrPatchName() const;
|
inline const word& neighbPatchName() const;
|
||||||
|
|
||||||
//- Neighbour patch ID
|
//- Neighbour patch ID
|
||||||
virtual label nbrPatchID() const;
|
virtual label neighbPatchID() const;
|
||||||
|
|
||||||
//- Does this side own the patch?
|
//- Does this side own the patch?
|
||||||
virtual bool owner() const;
|
virtual bool owner() const;
|
||||||
|
|
||||||
//- Return a reference to the neihgjbour patch
|
//- Return a reference to the neighbour patch
|
||||||
inline const cyclicAMIPolyPatch& nbrPatch() const;
|
inline const cyclicAMIPolyPatch& neighbPatch() const;
|
||||||
|
|
||||||
//- Return a reference to the projection surface
|
//- Return a reference to the projection surface
|
||||||
const autoPtr<searchableSurface>& surfPtr();
|
const autoPtr<searchableSurface>& surfPtr() const;
|
||||||
|
|
||||||
//- Return a reference to the AMI interpolator
|
//- Return a reference to the AMI interpolator
|
||||||
const AMIPatchToPatchInterpolation& AMI();
|
const AMIPatchToPatchInterpolation& AMI() const;
|
||||||
|
|
||||||
|
|
||||||
// Transformations
|
// Transformations
|
||||||
|
|||||||
@ -25,16 +25,16 @@ License
|
|||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
inline const Foam::word& Foam::cyclicAMIPolyPatch::nbrPatchName() const
|
inline const Foam::word& Foam::cyclicAMIPolyPatch::neighbPatchName() const
|
||||||
{
|
{
|
||||||
return nbrPatchName_;
|
return nbrPatchName_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
inline const Foam::cyclicAMIPolyPatch&
|
inline const Foam::cyclicAMIPolyPatch&
|
||||||
Foam::cyclicAMIPolyPatch::nbrPatch() const
|
Foam::cyclicAMIPolyPatch::neighbPatch() const
|
||||||
{
|
{
|
||||||
const polyPatch& pp = this->boundaryMesh()[nbrPatchID()];
|
const polyPatch& pp = this->boundaryMesh()[neighbPatchID()];
|
||||||
return refCast<const cyclicAMIPolyPatch>(pp);
|
return refCast<const cyclicAMIPolyPatch>(pp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -23,8 +23,6 @@ License
|
|||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
//#include "cyclicAMIPolyPatch.H"
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
template<class Type>
|
template<class Type>
|
||||||
@ -39,7 +37,7 @@ Foam::tmp<Foam::Field<Type> > Foam::cyclicAMIPolyPatch::interpolate
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return nbrPatch().AMIPtr_->interpolateToTarget(fld);
|
return neighbPatch().AMIPtr_->interpolateToTarget(fld);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -56,7 +54,7 @@ Foam::tmp<Foam::Field<Type> > Foam::cyclicAMIPolyPatch::interpolate
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return nbrPatch().AMIPtr_->interpolateToTarget(tFld);
|
return neighbPatch().AMIPtr_->interpolateToTarget(tFld);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -40,15 +40,6 @@ $(patchWave)/patchEdgeFaceInfo.C
|
|||||||
|
|
||||||
regionSplit/regionSplit.C
|
regionSplit/regionSplit.C
|
||||||
|
|
||||||
octree/octreeName.C
|
|
||||||
octree/octreeDataPoint.C
|
|
||||||
octree/octreeDataPointTreeLeaf.C
|
|
||||||
octree/octreeDataEdges.C
|
|
||||||
octree/octreeDataCell.C
|
|
||||||
octree/octreeDataFace.C
|
|
||||||
octree/treeNodeName.C
|
|
||||||
octree/treeLeafName.C
|
|
||||||
|
|
||||||
indexedOctree/treeDataEdge.C
|
indexedOctree/treeDataEdge.C
|
||||||
indexedOctree/treeDataFace.C
|
indexedOctree/treeDataFace.C
|
||||||
indexedOctree/treeDataPoint.C
|
indexedOctree/treeDataPoint.C
|
||||||
@ -153,8 +144,6 @@ $(intersectedSurface)/intersectedSurface.C
|
|||||||
$(intersectedSurface)/edgeSurface.C
|
$(intersectedSurface)/edgeSurface.C
|
||||||
|
|
||||||
triSurface/triSurfaceSearch/triSurfaceSearch.C
|
triSurface/triSurfaceSearch/triSurfaceSearch.C
|
||||||
triSurface/octreeData/octreeDataTriSurface.C
|
|
||||||
triSurface/octreeData/octreeDataTriSurfaceTreeLeaf.C
|
|
||||||
triSurface/triangleFuncs/triangleFuncs.C
|
triSurface/triangleFuncs/triangleFuncs.C
|
||||||
triSurface/surfaceFeatures/surfaceFeatures.C
|
triSurface/surfaceFeatures/surfaceFeatures.C
|
||||||
triSurface/triSurfaceTools/triSurfaceTools.C
|
triSurface/triSurfaceTools/triSurfaceTools.C
|
||||||
@ -165,6 +154,8 @@ twoDPointCorrector/twoDPointCorrector.C
|
|||||||
AMI=AMIInterpolation
|
AMI=AMIInterpolation
|
||||||
$(AMI)/AMIInterpolation/AMIInterpolationName.C
|
$(AMI)/AMIInterpolation/AMIInterpolationName.C
|
||||||
$(AMI)/faceAreaIntersect/faceAreaIntersect.C
|
$(AMI)/faceAreaIntersect/faceAreaIntersect.C
|
||||||
|
$(AMI)/GAMG/interfaces/cyclicAMIGAMGInterface/cyclicAMIGAMGInterface.C
|
||||||
|
$(AMI)/GAMG/interfaceFields/cyclicAMIGAMGInterfaceField/cyclicAMIGAMGInterfaceField.C
|
||||||
|
|
||||||
AMICycPatches=$(AMI)/patches/cyclic
|
AMICycPatches=$(AMI)/patches/cyclic
|
||||||
$(AMICycPatches)/cyclicAMILduInterfaceField/cyclicAMILduInterface.C
|
$(AMICycPatches)/cyclicAMILduInterfaceField/cyclicAMILduInterface.C
|
||||||
|
|||||||
@ -174,7 +174,7 @@ void Foam::mappedPatchBase::findSamples
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Octree based search engine
|
// Octree based search engine
|
||||||
meshSearch meshSearchEngine(mesh, polyMesh::FACEDIAGTETS);
|
meshSearch meshSearchEngine(mesh);
|
||||||
|
|
||||||
forAll(samples, sampleI)
|
forAll(samples, sampleI)
|
||||||
{
|
{
|
||||||
@ -291,7 +291,7 @@ void Foam::mappedPatchBase::findSamples
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Octree based search engine
|
// Octree based search engine
|
||||||
meshSearch meshSearchEngine(mesh, polyMesh::FACEDIAGTETS);
|
meshSearch meshSearchEngine(mesh);
|
||||||
|
|
||||||
forAll(samples, sampleI)
|
forAll(samples, sampleI)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -1,925 +0,0 @@
|
|||||||
/*---------------------------------------------------------------------------*\
|
|
||||||
========= |
|
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
|
||||||
\\ / O peration |
|
|
||||||
\\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
|
|
||||||
\\/ M anipulation |
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
License
|
|
||||||
This file is part of OpenFOAM.
|
|
||||||
|
|
||||||
OpenFOAM is free software: you can redistribute it and/or modify it
|
|
||||||
under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
|
||||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
||||||
for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
#include "octree.H"
|
|
||||||
#include "treeLeaf.H"
|
|
||||||
#include "treeNode.H"
|
|
||||||
#include "long.H"
|
|
||||||
#include "cpuTime.H"
|
|
||||||
#include "linePointRef.H"
|
|
||||||
#include "pointIndexHit.H"
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
template <class Type>
|
|
||||||
Foam::string Foam::octree<Type>::volType(const label type)
|
|
||||||
{
|
|
||||||
if (type == UNKNOWN)
|
|
||||||
{
|
|
||||||
return "unknown";
|
|
||||||
}
|
|
||||||
else if (type == MIXED)
|
|
||||||
{
|
|
||||||
return "mixed";
|
|
||||||
}
|
|
||||||
else if (type == INSIDE)
|
|
||||||
{
|
|
||||||
return "inside";
|
|
||||||
}
|
|
||||||
else if (type == OUTSIDE)
|
|
||||||
{
|
|
||||||
return "outside";
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
FatalErrorIn("volType(const label)") << "type:" << type
|
|
||||||
<< " unknown." << abort(FatalError);
|
|
||||||
|
|
||||||
return "dummy";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Determine inside/outside status of vector compared to geometry-based normal
|
|
||||||
template <class Type>
|
|
||||||
Foam::label Foam::octree<Type>::getVolType
|
|
||||||
(
|
|
||||||
const vector& geomNormal,
|
|
||||||
const vector& vec
|
|
||||||
)
|
|
||||||
{
|
|
||||||
scalar sign = geomNormal & vec;
|
|
||||||
|
|
||||||
if (sign >= 0)
|
|
||||||
{
|
|
||||||
return octree<Type>::OUTSIDE;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return octree<Type>::INSIDE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
template <class Type>
|
|
||||||
Foam::octree<Type>::octree
|
|
||||||
(
|
|
||||||
const treeBoundBox& octreeBb,
|
|
||||||
const Type& shapes,
|
|
||||||
const label minNLevels,
|
|
||||||
const scalar maxLeafRatio,
|
|
||||||
const scalar maxShapeRatio
|
|
||||||
)
|
|
||||||
:
|
|
||||||
topNode_(new treeNode<Type>(octreeBb)),
|
|
||||||
shapes_(shapes),
|
|
||||||
octreeBb_(octreeBb),
|
|
||||||
maxLeafRatio_(maxLeafRatio),
|
|
||||||
maxShapeRatio_(maxShapeRatio),
|
|
||||||
minNLevels_(minNLevels),
|
|
||||||
deepestLevel_(0),
|
|
||||||
nEntries_(0),
|
|
||||||
nNodes_(0),
|
|
||||||
nLeaves_(0),
|
|
||||||
endIter_(*this, -1),
|
|
||||||
endConstIter_(*this, -1)
|
|
||||||
{
|
|
||||||
cpuTime timer;
|
|
||||||
|
|
||||||
setNodes(nNodes() + 1);
|
|
||||||
|
|
||||||
const label nShapes = shapes_.size();
|
|
||||||
|
|
||||||
labelList indices(nShapes);
|
|
||||||
for (label i = 0; i < nShapes; i++)
|
|
||||||
{
|
|
||||||
indices[i] = i;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create initial level (0) of subLeaves
|
|
||||||
if (debug & 1)
|
|
||||||
{
|
|
||||||
Pout<< "octree : --- Start of Level " << deepestLevel_
|
|
||||||
<< " ----" << endl;
|
|
||||||
}
|
|
||||||
topNode_->distribute(0, *this, shapes_, indices);
|
|
||||||
|
|
||||||
if (debug & 1)
|
|
||||||
{
|
|
||||||
printStats(Pout);
|
|
||||||
Pout<< "octree : --- End of Level " << deepestLevel_
|
|
||||||
<< " ----" << endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Breadth first creation of tree
|
|
||||||
// Stop if: - level above minlevel and
|
|
||||||
// - less than so many cells per endpoint
|
|
||||||
// (so bottom level is fine enough)
|
|
||||||
// - every shape mentioned in only so many
|
|
||||||
// leaves. (if shape bb quite big it will end up
|
|
||||||
// in lots of leaves).
|
|
||||||
// - no change in number of leaves
|
|
||||||
// (happens if leafs fine enough)
|
|
||||||
// This guarantees that tree
|
|
||||||
// - is fine enough (if minLevel > 0)
|
|
||||||
// - has some guaranteed maximum size (maxShapeRatio)
|
|
||||||
|
|
||||||
label oldNLeaves = -1; // make test below pass first time.
|
|
||||||
label oldNNodes = -1;
|
|
||||||
deepestLevel_ = 1;
|
|
||||||
while
|
|
||||||
(
|
|
||||||
(deepestLevel_ <= minNLevels_)
|
|
||||||
|| (
|
|
||||||
(nEntries() > maxLeafRatio * nLeaves()) // shapes per leaf
|
|
||||||
&& (nEntries() < maxShapeRatio * nShapes) // entries per shape
|
|
||||||
)
|
|
||||||
)
|
|
||||||
{
|
|
||||||
if (deepestLevel_ >= maxNLevels)
|
|
||||||
{
|
|
||||||
if (debug & 1)
|
|
||||||
{
|
|
||||||
Pout<< "octree : exiting since maxNLevels "
|
|
||||||
<< maxNLevels << " reached" << endl;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((oldNLeaves == nLeaves()) && (oldNNodes == nNodes()))
|
|
||||||
{
|
|
||||||
if (debug & 1)
|
|
||||||
{
|
|
||||||
Pout<< "octree : exiting since nLeaves and nNodes do not change"
|
|
||||||
<< endl;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (debug & 1)
|
|
||||||
{
|
|
||||||
Pout<< "octree : --- Start of Level " << deepestLevel_
|
|
||||||
<< " ----" << endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
oldNLeaves = nLeaves();
|
|
||||||
oldNNodes = nNodes();
|
|
||||||
|
|
||||||
topNode_->redistribute
|
|
||||||
(
|
|
||||||
1,
|
|
||||||
*this,
|
|
||||||
shapes_,
|
|
||||||
deepestLevel_
|
|
||||||
);
|
|
||||||
|
|
||||||
if (debug & 1)
|
|
||||||
{
|
|
||||||
printStats(Pout);
|
|
||||||
|
|
||||||
Pout<< "octree : --- End of Level " << deepestLevel_
|
|
||||||
<< " ----" << endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
deepestLevel_++;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if (debug & 1)
|
|
||||||
{
|
|
||||||
Pout<< "octree : Constructed octree in = "
|
|
||||||
<< timer.cpuTimeIncrement()
|
|
||||||
<< " s\n" << endl << endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set volume type of non-treeleaf nodes.
|
|
||||||
topNode_->setSubNodeType(0, *this, shapes_);
|
|
||||||
|
|
||||||
if (debug & 1)
|
|
||||||
{
|
|
||||||
Pout<< "octree : Added node information to octree in = "
|
|
||||||
<< timer.cpuTimeIncrement()
|
|
||||||
<< " s\n" << endl << endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
template <class Type>
|
|
||||||
Foam::octree<Type>::~octree()
|
|
||||||
{
|
|
||||||
delete topNode_;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
template <class Type>
|
|
||||||
Foam::label Foam::octree<Type>::getSampleType(const point& sample) const
|
|
||||||
{
|
|
||||||
return topNode_->getSampleType(0, *this, shapes_, sample);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template <class Type>
|
|
||||||
Foam::label Foam::octree<Type>::find(const point& sample) const
|
|
||||||
{
|
|
||||||
return topNode_->find(shapes_, sample);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template <class Type>
|
|
||||||
bool Foam::octree<Type>::findTightest
|
|
||||||
(
|
|
||||||
const point& sample,
|
|
||||||
treeBoundBox& tightest
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
return topNode_->findTightest
|
|
||||||
(
|
|
||||||
shapes_,
|
|
||||||
sample,
|
|
||||||
tightest
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template <class Type>
|
|
||||||
Foam::label Foam::octree<Type>::findNearest
|
|
||||||
(
|
|
||||||
const point& sample,
|
|
||||||
treeBoundBox& tightest,
|
|
||||||
scalar& tightestDist
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
label tightestI = -1;
|
|
||||||
|
|
||||||
if (debug & 4)
|
|
||||||
{
|
|
||||||
Pout<< "octree::findNearest : searching for nearest for "
|
|
||||||
<< "sample:" << sample
|
|
||||||
<< " tightest:" << tightest << endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
topNode_->findNearest
|
|
||||||
(
|
|
||||||
shapes_,
|
|
||||||
sample,
|
|
||||||
tightest,
|
|
||||||
tightestI,
|
|
||||||
tightestDist
|
|
||||||
);
|
|
||||||
|
|
||||||
if (debug & 4)
|
|
||||||
{
|
|
||||||
Pout<< "octree::findNearest : found nearest for "
|
|
||||||
<< "sample:" << sample << " with "
|
|
||||||
<< " tightestI:" << tightestI
|
|
||||||
<< " tightest:" << tightest
|
|
||||||
<< " tightestDist:" << tightestDist
|
|
||||||
<< endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
return tightestI;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template <class Type>
|
|
||||||
Foam::label Foam::octree<Type>::findNearest
|
|
||||||
(
|
|
||||||
const linePointRef& ln,
|
|
||||||
treeBoundBox& tightest,
|
|
||||||
point& linePoint,
|
|
||||||
point& shapePoint
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
// Start off from miss with points at large distance apart.
|
|
||||||
label tightestI = -1;
|
|
||||||
linePoint = point(-GREAT, -GREAT, -GREAT);
|
|
||||||
shapePoint = point(GREAT, GREAT, GREAT);
|
|
||||||
|
|
||||||
topNode_->findNearest
|
|
||||||
(
|
|
||||||
shapes_,
|
|
||||||
ln,
|
|
||||||
tightest,
|
|
||||||
tightestI,
|
|
||||||
linePoint,
|
|
||||||
shapePoint
|
|
||||||
);
|
|
||||||
|
|
||||||
return tightestI;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template <class Type>
|
|
||||||
Foam::labelList Foam::octree<Type>::findBox(const boundBox& bb) const
|
|
||||||
{
|
|
||||||
// Storage for labels of shapes inside bb. Size estimate.
|
|
||||||
labelHashSet elements(100);
|
|
||||||
|
|
||||||
topNode_->findBox(shapes_, bb, elements);
|
|
||||||
|
|
||||||
return elements.toc();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template <class Type>
|
|
||||||
Foam::pointIndexHit Foam::octree<Type>::findLine
|
|
||||||
(
|
|
||||||
const point& treeStart,
|
|
||||||
const point& treeEnd
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
// Initialize to a miss
|
|
||||||
pointIndexHit hitInfo(false, treeStart, -1);
|
|
||||||
|
|
||||||
const vector dir(treeEnd - treeStart);
|
|
||||||
|
|
||||||
// Current line segment to search
|
|
||||||
point start(treeStart);
|
|
||||||
point end(treeEnd);
|
|
||||||
|
|
||||||
while (true)
|
|
||||||
{
|
|
||||||
// Find nearest treeLeaf intersected by line
|
|
||||||
point leafIntPoint;
|
|
||||||
|
|
||||||
const treeLeaf<Type>* leafPtr = findLeafLine
|
|
||||||
(
|
|
||||||
start,
|
|
||||||
end,
|
|
||||||
leafIntPoint
|
|
||||||
);
|
|
||||||
|
|
||||||
if (!leafPtr)
|
|
||||||
{
|
|
||||||
// Reached end of string of treeLeaves to be searched. Return
|
|
||||||
// whatever we have found so far.
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Inside treeLeaf find nearest intersection
|
|
||||||
scalar minS = GREAT;
|
|
||||||
|
|
||||||
const labelList& indices = leafPtr->indices();
|
|
||||||
|
|
||||||
forAll(indices, elemI)
|
|
||||||
{
|
|
||||||
label index = indices[elemI];
|
|
||||||
|
|
||||||
point pt;
|
|
||||||
bool hit = shapes().intersects(index, start, end, pt);
|
|
||||||
|
|
||||||
if (hit)
|
|
||||||
{
|
|
||||||
// Check whether intersection nearer p
|
|
||||||
scalar s = (pt - treeStart) & dir;
|
|
||||||
|
|
||||||
if (s < minS)
|
|
||||||
{
|
|
||||||
minS = s;
|
|
||||||
|
|
||||||
// Update hit info
|
|
||||||
hitInfo.setHit();
|
|
||||||
hitInfo.setPoint(pt);
|
|
||||||
hitInfo.setIndex(index);
|
|
||||||
|
|
||||||
// Update segment to search
|
|
||||||
end = pt;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (hitInfo.hit())
|
|
||||||
{
|
|
||||||
// Found intersected shape.
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Start from end of current leaf
|
|
||||||
start = leafIntPoint;
|
|
||||||
}
|
|
||||||
|
|
||||||
return hitInfo;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template <class Type>
|
|
||||||
Foam::pointIndexHit Foam::octree<Type>::findLineAny
|
|
||||||
(
|
|
||||||
const point& start,
|
|
||||||
const point& end
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
// Initialize to a miss
|
|
||||||
pointIndexHit hitInfo(false, start, -1);
|
|
||||||
|
|
||||||
// Start of segment in current treeNode.
|
|
||||||
point p(start);
|
|
||||||
while (true)
|
|
||||||
{
|
|
||||||
// Find treeLeaf intersected by line
|
|
||||||
point leafIntPoint;
|
|
||||||
|
|
||||||
const treeLeaf<Type>* leafPtr = findLeafLine(p, end, leafIntPoint);
|
|
||||||
|
|
||||||
if (!leafPtr)
|
|
||||||
{
|
|
||||||
// Reached end of string of treeLeaves to be searched. Return
|
|
||||||
// whatever we have found so far.
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Inside treeLeaf find any intersection
|
|
||||||
|
|
||||||
// Vector from endPoint to entry point of leaf.
|
|
||||||
const vector edgeVec(end - p);
|
|
||||||
|
|
||||||
const labelList& indices = leafPtr->indices();
|
|
||||||
|
|
||||||
forAll(indices, elemI)
|
|
||||||
{
|
|
||||||
label index = indices[elemI];
|
|
||||||
|
|
||||||
point pt;
|
|
||||||
bool hit = shapes().intersects
|
|
||||||
(
|
|
||||||
index,
|
|
||||||
p,
|
|
||||||
end,
|
|
||||||
pt
|
|
||||||
);
|
|
||||||
|
|
||||||
if (hit)
|
|
||||||
{
|
|
||||||
hitInfo.setHit();
|
|
||||||
hitInfo.setPoint(pt);
|
|
||||||
hitInfo.setIndex(index);
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (hitInfo.hit())
|
|
||||||
{
|
|
||||||
// Found intersected shape.
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Start from end of current leaf
|
|
||||||
p = leafIntPoint;
|
|
||||||
}
|
|
||||||
|
|
||||||
return hitInfo;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template <class Type>
|
|
||||||
const Foam::treeLeaf<Type>* Foam::octree<Type>::findLeafLine
|
|
||||||
(
|
|
||||||
const point& start,
|
|
||||||
const point& end,
|
|
||||||
point& leafIntPoint
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
// returns first found cube along line
|
|
||||||
|
|
||||||
if (debug & 2)
|
|
||||||
{
|
|
||||||
Pout<< "octree::findLeafLine : searching for shapes on line "
|
|
||||||
<< "start:" << start
|
|
||||||
<< " end:" << end << endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If start is outside project onto top cube
|
|
||||||
if (octreeBb_.contains(start))
|
|
||||||
{
|
|
||||||
leafIntPoint = start;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (!octreeBb_.intersects(start, end, leafIntPoint))
|
|
||||||
{
|
|
||||||
if (debug & 2)
|
|
||||||
{
|
|
||||||
Pout<< "octree::findLeafLine : start outside domain but does"
|
|
||||||
<< " not intersect : start:"
|
|
||||||
<< start << endl;
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (debug & 2)
|
|
||||||
{
|
|
||||||
Pout<< "octree::findLeafLine : start propagated to inside"
|
|
||||||
" domain : "
|
|
||||||
<< leafIntPoint << endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Normal action: find next intersection along line
|
|
||||||
const treeLeaf<Type>* leafPtr = topNode_->findLeafLine
|
|
||||||
(
|
|
||||||
0,
|
|
||||||
shapes_,
|
|
||||||
leafIntPoint,
|
|
||||||
end
|
|
||||||
);
|
|
||||||
|
|
||||||
if (debug & 2)
|
|
||||||
{
|
|
||||||
Pout<< "returning from octree::findLeafLine with "
|
|
||||||
<< "leafIntersection:" << leafIntPoint
|
|
||||||
<< " leafPtr:" << long(leafPtr) << endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
return leafPtr;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template <class Type>
|
|
||||||
void Foam::octree<Type>::writeOBJ
|
|
||||||
(
|
|
||||||
Ostream& os,
|
|
||||||
label& vertNo
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
scalar minx = octreeBb_.min().x();
|
|
||||||
scalar miny = octreeBb_.min().y();
|
|
||||||
scalar minz = octreeBb_.min().z();
|
|
||||||
|
|
||||||
scalar maxx = octreeBb_.max().x();
|
|
||||||
scalar maxy = octreeBb_.max().y();
|
|
||||||
scalar maxz = octreeBb_.max().z();
|
|
||||||
|
|
||||||
os << "v " << minx << " " << miny << " " << minz << endl;
|
|
||||||
os << "v " << maxx << " " << miny << " " << minz << endl;
|
|
||||||
os << "v " << maxx << " " << maxy << " " << minz << endl;
|
|
||||||
os << "v " << minx << " " << maxy << " " << minz << endl;
|
|
||||||
|
|
||||||
os << "v " << minx << " " << miny << " " << maxz << endl;
|
|
||||||
os << "v " << maxx << " " << miny << " " << maxz << endl;
|
|
||||||
os << "v " << maxx << " " << maxy << " " << maxz << endl;
|
|
||||||
os << "v " << minx << " " << maxy << " " << maxz << endl;
|
|
||||||
|
|
||||||
// Bottom face
|
|
||||||
os << "l " << vertNo + 1 << " " << vertNo + 2 << endl;
|
|
||||||
os << "l " << vertNo + 2 << " " << vertNo + 3 << endl;
|
|
||||||
os << "l " << vertNo + 3 << " " << vertNo + 4 << endl;
|
|
||||||
os << "l " << vertNo + 4 << " " << vertNo + 1 << endl;
|
|
||||||
|
|
||||||
// Top face
|
|
||||||
os << "l " << vertNo + 5 << " " << vertNo + 6 << endl;
|
|
||||||
os << "l " << vertNo + 6 << " " << vertNo + 7 << endl;
|
|
||||||
os << "l " << vertNo + 7 << " " << vertNo + 8 << endl;
|
|
||||||
os << "l " << vertNo + 8 << " " << vertNo + 5 << endl;
|
|
||||||
|
|
||||||
// Edges from bottom to top face
|
|
||||||
os << "l " << vertNo + 1 << " " << vertNo + 5 << endl;
|
|
||||||
os << "l " << vertNo + 2 << " " << vertNo + 6 << endl;
|
|
||||||
os << "l " << vertNo + 3 << " " << vertNo + 7 << endl;
|
|
||||||
os << "l " << vertNo + 4 << " " << vertNo + 8 << endl;
|
|
||||||
|
|
||||||
vertNo += 8;
|
|
||||||
|
|
||||||
topNode_->writeOBJ(os, 1, vertNo);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template <class Type>
|
|
||||||
void Foam::octree<Type>::printStats(Ostream& os) const
|
|
||||||
{
|
|
||||||
os << "Statistics after iteration " << deepestLevel() << ':' << endl
|
|
||||||
<< " nShapes :" << shapes().size() << endl
|
|
||||||
<< " nNodes :" << nNodes() << endl
|
|
||||||
<< " nLeaves :" << nLeaves() << endl
|
|
||||||
<< " nEntries :" << nEntries() << endl;
|
|
||||||
|
|
||||||
if (nLeaves() && shapes().size())
|
|
||||||
{
|
|
||||||
os
|
|
||||||
<< " Cells per leaf :"
|
|
||||||
<< scalar(nEntries())/nLeaves()
|
|
||||||
<< nl
|
|
||||||
<< " Every cell in :"
|
|
||||||
<< scalar(nEntries())/shapes().size() << " cubes"
|
|
||||||
<< endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * STL iterator * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
// Construct from a octree. Set index at end.
|
|
||||||
template <class Type>
|
|
||||||
Foam::octree<Type>::iterator::iterator(octree<Type>& oc)
|
|
||||||
:
|
|
||||||
octree_(oc),
|
|
||||||
curLeaf_(oc.nLeaves())
|
|
||||||
{
|
|
||||||
leaves_.setSize(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Construct from octree. Set index.
|
|
||||||
template <class Type>
|
|
||||||
Foam::octree<Type>::iterator::iterator(octree<Type>& oc, label index)
|
|
||||||
:
|
|
||||||
octree_(oc),
|
|
||||||
curLeaf_(index)
|
|
||||||
{
|
|
||||||
if (index >= 0)
|
|
||||||
{
|
|
||||||
leaves_.setSize(oc.nLeaves());
|
|
||||||
|
|
||||||
label leafIndex = 0;
|
|
||||||
octree_.topNode()->findLeaves(leaves_, leafIndex);
|
|
||||||
|
|
||||||
if (leafIndex != oc.nLeaves())
|
|
||||||
{
|
|
||||||
FatalErrorIn
|
|
||||||
(
|
|
||||||
"octree::iterator::iterator"
|
|
||||||
"(octree&, label)"
|
|
||||||
)
|
|
||||||
<< "Traversal of tree returns : " << leafIndex << endl
|
|
||||||
<< "Statistics of octree say : " << oc.nLeaves() << endl
|
|
||||||
<< abort(FatalError);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template <class Type>
|
|
||||||
void Foam::octree<Type>::iterator::operator=(const iterator& iter)
|
|
||||||
{
|
|
||||||
if ((curLeaf_ < 0) && (iter.curLeaf_ >= 0))
|
|
||||||
{
|
|
||||||
FatalErrorIn
|
|
||||||
(
|
|
||||||
"octree::iterator::operator="
|
|
||||||
"(const iterator&)"
|
|
||||||
)
|
|
||||||
<< "lhs : " << curLeaf_ << endl
|
|
||||||
<< "rhs : " << iter.curLeaf_ << endl
|
|
||||||
<< abort(FatalError);
|
|
||||||
}
|
|
||||||
curLeaf_ = iter.curLeaf_;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template <class Type>
|
|
||||||
bool Foam::octree<Type>::iterator::operator==(const iterator& iter) const
|
|
||||||
{
|
|
||||||
label index1 =
|
|
||||||
(curLeaf_ >= 0 ? curLeaf_ : octree_.nLeaves());
|
|
||||||
label index2 =
|
|
||||||
(iter.curLeaf_ >= 0 ? iter.curLeaf_ : iter.octree_.nLeaves());
|
|
||||||
|
|
||||||
return index1 == index2;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template <class Type>
|
|
||||||
bool Foam::octree<Type>::iterator::operator!=(const iterator& iter) const
|
|
||||||
{
|
|
||||||
return !(iterator::operator==(iter));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template <class Type>
|
|
||||||
Foam::treeLeaf<Type>& Foam::octree<Type>::iterator::operator*()
|
|
||||||
{
|
|
||||||
return *leaves_[curLeaf_];
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template <class Type>
|
|
||||||
typename Foam::octree<Type>::iterator&
|
|
||||||
Foam::octree<Type>::iterator::operator++()
|
|
||||||
{
|
|
||||||
curLeaf_++;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template <class Type>
|
|
||||||
typename Foam::octree<Type>::iterator
|
|
||||||
Foam::octree<Type>::iterator::operator++(int)
|
|
||||||
{
|
|
||||||
iterator tmp = *this;
|
|
||||||
++*this;
|
|
||||||
return tmp;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template <class Type>
|
|
||||||
typename Foam::octree<Type>::iterator
|
|
||||||
Foam::octree<Type>::begin()
|
|
||||||
{
|
|
||||||
return iterator(*this, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template <class Type>
|
|
||||||
const typename Foam::octree<Type>::iterator&
|
|
||||||
Foam::octree<Type>::end()
|
|
||||||
{
|
|
||||||
return octree<Type>::endIter_;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * STL const_iterator * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
// Construct for a given octree
|
|
||||||
template <class Type>
|
|
||||||
Foam::octree<Type>::const_iterator::const_iterator(const octree<Type>& oc)
|
|
||||||
:
|
|
||||||
octree_(oc),
|
|
||||||
curLeaf_(oc.nLeaves())
|
|
||||||
{
|
|
||||||
leaves_.setSize(oc.nLeaves());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Construct for a given octree
|
|
||||||
template <class Type>
|
|
||||||
Foam::octree<Type>::const_iterator::const_iterator
|
|
||||||
(
|
|
||||||
const octree<Type>& oc,
|
|
||||||
label index
|
|
||||||
)
|
|
||||||
:
|
|
||||||
octree_(oc),
|
|
||||||
curLeaf_(index)
|
|
||||||
{
|
|
||||||
if (index >= 0)
|
|
||||||
{
|
|
||||||
leaves_.setSize(oc.nLeaves());
|
|
||||||
|
|
||||||
label leafIndex = 0;
|
|
||||||
octree_.topNode()->findLeaves(leaves_, leafIndex);
|
|
||||||
|
|
||||||
if (leafIndex != oc.nLeaves())
|
|
||||||
{
|
|
||||||
FatalErrorIn
|
|
||||||
(
|
|
||||||
"octree::const_iterator::const_iterator"
|
|
||||||
"(octree&, label)"
|
|
||||||
)
|
|
||||||
<< "Traversal of tree returns : " << leafIndex << endl
|
|
||||||
<< "Statistics of octree say : " << oc.nLeaves() << endl
|
|
||||||
<< abort(FatalError);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template <class Type>
|
|
||||||
void Foam::octree<Type>::const_iterator::operator=(const const_iterator& iter)
|
|
||||||
{
|
|
||||||
if ((curLeaf_ < 0) && (iter.curLeaf_ >= 0))
|
|
||||||
{
|
|
||||||
FatalErrorIn
|
|
||||||
(
|
|
||||||
"octree::const_iterator::operator="
|
|
||||||
"(const const_iterator&)"
|
|
||||||
)
|
|
||||||
<< "lhs : " << curLeaf_ << endl
|
|
||||||
<< "rhs : " << iter.curLeaf_ << endl
|
|
||||||
<< abort(FatalError);
|
|
||||||
}
|
|
||||||
curLeaf_ = iter.curLeaf_;
|
|
||||||
curLeaf_ = iter.curLeaf_;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template <class Type>
|
|
||||||
bool Foam::octree<Type>::const_iterator::operator==
|
|
||||||
(
|
|
||||||
const const_iterator& iter
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
label index1 =
|
|
||||||
(curLeaf_ >= 0 ? curLeaf_ : octree_.nLeaves());
|
|
||||||
label index2 =
|
|
||||||
(iter.curLeaf_ >= 0 ? iter.curLeaf_ : iter.octree_.nLeaves());
|
|
||||||
|
|
||||||
return index1 == index2;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template <class Type>
|
|
||||||
bool Foam::octree<Type>::const_iterator::operator!=
|
|
||||||
(
|
|
||||||
const const_iterator& iter
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
return !(const_iterator::operator==(iter));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template <class Type>
|
|
||||||
const Foam::treeLeaf<Type>& Foam::octree<Type>::const_iterator::operator*()
|
|
||||||
{
|
|
||||||
return *leaves_[curLeaf_];
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template <class Type>
|
|
||||||
typename Foam::octree<Type>::const_iterator&
|
|
||||||
Foam::octree<Type>::const_iterator::operator++()
|
|
||||||
{
|
|
||||||
curLeaf_++;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template <class Type>
|
|
||||||
typename Foam::octree<Type>::const_iterator
|
|
||||||
Foam::octree<Type>::const_iterator::operator++(int)
|
|
||||||
{
|
|
||||||
const_iterator tmp = *this;
|
|
||||||
++*this;
|
|
||||||
return tmp;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template <class Type>
|
|
||||||
typename Foam::octree<Type>::const_iterator
|
|
||||||
Foam::octree<Type>::begin() const
|
|
||||||
{
|
|
||||||
return const_iterator(*this, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template <class Type>
|
|
||||||
typename Foam::octree<Type>::const_iterator
|
|
||||||
Foam::octree<Type>::cbegin() const
|
|
||||||
{
|
|
||||||
return const_iterator(*this, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template <class Type>
|
|
||||||
const typename Foam::octree<Type>::const_iterator&
|
|
||||||
Foam::octree<Type>::end() const
|
|
||||||
{
|
|
||||||
return octree<Type>::endConstIter_;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template <class Type>
|
|
||||||
const typename Foam::octree<Type>::const_iterator&
|
|
||||||
Foam::octree<Type>::cend() const
|
|
||||||
{
|
|
||||||
return octree<Type>::endConstIter_;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * Friend Operators * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
template <class Type>
|
|
||||||
Foam::Ostream& Foam::operator<<(Ostream& os, const octree<Type>& oc)
|
|
||||||
{
|
|
||||||
return os << token::BEGIN_LIST
|
|
||||||
//<< token::SPACE << oc.shapes_
|
|
||||||
<< token::SPACE << oc.octreeBb_
|
|
||||||
<< token::SPACE << oc.maxLeafRatio_
|
|
||||||
<< token::SPACE << oc.maxShapeRatio_
|
|
||||||
<< token::SPACE << oc.minNLevels_
|
|
||||||
<< token::SPACE << oc.deepestLevel_
|
|
||||||
<< token::SPACE << oc.nEntries_
|
|
||||||
<< token::SPACE << oc.nNodes_
|
|
||||||
<< token::SPACE << oc.nLeaves_
|
|
||||||
<< token::SPACE << *oc.topNode_
|
|
||||||
<< token::SPACE << token::END_LIST;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
|
||||||
@ -1,498 +0,0 @@
|
|||||||
/*---------------------------------------------------------------------------*\
|
|
||||||
========= |
|
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
|
||||||
\\ / O peration |
|
|
||||||
\\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
|
|
||||||
\\/ M anipulation |
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
License
|
|
||||||
This file is part of OpenFOAM.
|
|
||||||
|
|
||||||
OpenFOAM is free software: you can redistribute it and/or modify it
|
|
||||||
under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
|
||||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
||||||
for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
Class
|
|
||||||
Foam::octree
|
|
||||||
|
|
||||||
Description
|
|
||||||
Octree, templated on type of shapes it refers to.
|
|
||||||
|
|
||||||
Uses the octreeData class, which is a list of 1D, 2D or 3D shapes.
|
|
||||||
Various implementations of octreeData which know about cell&meshes,
|
|
||||||
patches&meshes and points.
|
|
||||||
|
|
||||||
The octree can be used to
|
|
||||||
- find the "nearest" shape to a point
|
|
||||||
- find the shape which contains a point (only sensible for 3D shapes)
|
|
||||||
- find intersections of line with shapes
|
|
||||||
|
|
||||||
The tree consists of
|
|
||||||
- treeNode : holds sub-treeNodes or treeLeaves
|
|
||||||
- treeLeaf : is the one that actually holds data
|
|
||||||
|
|
||||||
The data is stored purely as a list of indices into octreeData.
|
|
||||||
|
|
||||||
The construction on the depth of the tree is:
|
|
||||||
- one can specify a minimum depth
|
|
||||||
(though the tree will never be refined if all leaves contain <=1
|
|
||||||
shapes)
|
|
||||||
- after the minimum depth two statistics are used to decide further
|
|
||||||
refinement:
|
|
||||||
- average number of entries per leaf (leafRatio). Since inside a
|
|
||||||
leaf most algorithms are n or n^2 this value has to be small.
|
|
||||||
- average number of leaves a shape is in. Because of bounding boxes,
|
|
||||||
a single shape can be in multiple leaves. If the bbs are large
|
|
||||||
compared to the leaf size this multiplicity can become extremely
|
|
||||||
large and will become larger with more levels.
|
|
||||||
|
|
||||||
Note: the octree gets constructed with an overall bounding box. If your
|
|
||||||
mesh is regular it is a good idea to make this overall bb a bit wider than
|
|
||||||
the bb of the shapes itself. Otherwise lots of shapes end up exactly on the
|
|
||||||
edge of a bb and hence go into more than one subcube.
|
|
||||||
|
|
||||||
E.g. octree of face centres of lid driven cavity.
|
|
||||||
|
|
||||||
-# bb exact -> total 1457 leaves (every point in 7.1 leaves)
|
|
||||||
-# bb.max incremented by 1% -> total 80 leaves
|
|
||||||
(every point in exactly 1 leaf)
|
|
||||||
|
|
||||||
\par Ideas for parallel implementation:
|
|
||||||
|
|
||||||
The data inserted into the octree (the
|
|
||||||
'octreeData') has to be local to the processor. The data to be looked
|
|
||||||
for (usually a sample point) can be global to the domain.
|
|
||||||
The algorithm:
|
|
||||||
- search for all my points
|
|
||||||
- collect results which have to do with a processor patch
|
|
||||||
- global sum all these. If 0 exit.
|
|
||||||
- exchange data on all processor patches
|
|
||||||
- start again
|
|
||||||
|
|
||||||
So data transfers one processor per iteration. One could think of having
|
|
||||||
an extra search mechanism one level above which does an initial search
|
|
||||||
knowing the average shape of a processor distribution (square/cube for
|
|
||||||
most decomposition methods) and can assign sample points to the (almost)
|
|
||||||
correct processor at once.
|
|
||||||
|
|
||||||
SourceFiles
|
|
||||||
octree.C
|
|
||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
#ifndef octree_H
|
|
||||||
#define octree_H
|
|
||||||
|
|
||||||
#include "treeBoundBoxList.H"
|
|
||||||
#include "treeLeaf.H"
|
|
||||||
#include "pointIndexHit.H"
|
|
||||||
#include "linePointRef.H"
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
namespace Foam
|
|
||||||
{
|
|
||||||
|
|
||||||
// Forward declaration of classes
|
|
||||||
template<class Type> class treeNode;
|
|
||||||
|
|
||||||
// Forward declaration of friend functions and operators
|
|
||||||
|
|
||||||
template<class Type>
|
|
||||||
Ostream& operator<<(Ostream&, const octree<Type>&);
|
|
||||||
|
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*\
|
|
||||||
Class octreeName Declaration
|
|
||||||
\*---------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
TemplateName(octree);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*\
|
|
||||||
Class octree Declaration
|
|
||||||
\*---------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
template <class Type>
|
|
||||||
class octree
|
|
||||||
:
|
|
||||||
public octreeName
|
|
||||||
{
|
|
||||||
// Private data
|
|
||||||
|
|
||||||
//- Top treeNode. Modified by lower levels.
|
|
||||||
treeNode<Type>* topNode_;
|
|
||||||
|
|
||||||
//- all shapes
|
|
||||||
const Type shapes_;
|
|
||||||
|
|
||||||
//- Overall bb of octree
|
|
||||||
const treeBoundBox octreeBb_;
|
|
||||||
|
|
||||||
//- Refinement crit: size of leaves. Average number of entries per
|
|
||||||
// leaf. Should be fine enough for efficient searching at lowest level.
|
|
||||||
const scalar maxLeafRatio_;
|
|
||||||
|
|
||||||
//- Refinement crit: multiplicity of entries (so in how many leaves
|
|
||||||
// each shape is mentioned)
|
|
||||||
const scalar maxShapeRatio_;
|
|
||||||
|
|
||||||
//- Refinement crit: min no. of levels
|
|
||||||
const label minNLevels_;
|
|
||||||
|
|
||||||
//- Actual depth
|
|
||||||
label deepestLevel_;
|
|
||||||
|
|
||||||
//- Total number of (references to) shapes in octree
|
|
||||||
// (shapes can be stored in more than one treeLeaf)
|
|
||||||
label nEntries_;
|
|
||||||
|
|
||||||
//- Total number of treeNodes
|
|
||||||
label nNodes_;
|
|
||||||
|
|
||||||
//- Total number of treeLeaves
|
|
||||||
label nLeaves_;
|
|
||||||
|
|
||||||
|
|
||||||
// Static data members
|
|
||||||
//- Refinement crit: max number of level
|
|
||||||
static const label maxNLevels = 20;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Private Member Functions
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
// Data types
|
|
||||||
|
|
||||||
//- volume types
|
|
||||||
enum volumeType
|
|
||||||
{
|
|
||||||
UNKNOWN,
|
|
||||||
MIXED,
|
|
||||||
INSIDE,
|
|
||||||
OUTSIDE
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
// Static data members
|
|
||||||
|
|
||||||
//- for debugging:return printable representation of volumeType
|
|
||||||
static string volType(const label);
|
|
||||||
|
|
||||||
//- Code the vector with respect to the geometry. geomNormal guaranteed
|
|
||||||
// to point outside.
|
|
||||||
static label getVolType
|
|
||||||
(
|
|
||||||
const vector& geomNormal,
|
|
||||||
const vector& vec
|
|
||||||
);
|
|
||||||
|
|
||||||
// Constructors
|
|
||||||
|
|
||||||
//- Construct from components
|
|
||||||
octree
|
|
||||||
(
|
|
||||||
const treeBoundBox& octreeBb,
|
|
||||||
const Type& shapes,
|
|
||||||
const label minNLevels, // minimum number of levels
|
|
||||||
const scalar maxLeafRatio, // max avg. size of leaves
|
|
||||||
const scalar maxShapeRatio // max avg. duplicity.
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
//- Destructor
|
|
||||||
~octree();
|
|
||||||
|
|
||||||
|
|
||||||
// Member Functions
|
|
||||||
|
|
||||||
// Access
|
|
||||||
|
|
||||||
const Type& shapes() const
|
|
||||||
{
|
|
||||||
return shapes_;
|
|
||||||
}
|
|
||||||
|
|
||||||
const treeBoundBox& octreeBb() const
|
|
||||||
{
|
|
||||||
return octreeBb_;
|
|
||||||
}
|
|
||||||
|
|
||||||
scalar maxShapeRatio() const
|
|
||||||
{
|
|
||||||
return maxShapeRatio_;
|
|
||||||
}
|
|
||||||
|
|
||||||
scalar maxLeafRatio() const
|
|
||||||
{
|
|
||||||
return maxLeafRatio_;
|
|
||||||
}
|
|
||||||
|
|
||||||
label minNLevels() const
|
|
||||||
{
|
|
||||||
return minNLevels_;
|
|
||||||
}
|
|
||||||
|
|
||||||
// After construction: octree statistics
|
|
||||||
|
|
||||||
treeNode<Type>* topNode() const
|
|
||||||
{
|
|
||||||
return topNode_;
|
|
||||||
}
|
|
||||||
|
|
||||||
label deepestLevel() const
|
|
||||||
{
|
|
||||||
return deepestLevel_;
|
|
||||||
}
|
|
||||||
|
|
||||||
label nEntries() const
|
|
||||||
{
|
|
||||||
return nEntries_;
|
|
||||||
}
|
|
||||||
|
|
||||||
label nNodes() const
|
|
||||||
{
|
|
||||||
return nNodes_;
|
|
||||||
}
|
|
||||||
|
|
||||||
label nLeaves() const
|
|
||||||
{
|
|
||||||
return nLeaves_;
|
|
||||||
}
|
|
||||||
|
|
||||||
void setEntries(const label n)
|
|
||||||
{
|
|
||||||
nEntries_ = n;
|
|
||||||
}
|
|
||||||
|
|
||||||
void setNodes(const label n)
|
|
||||||
{
|
|
||||||
nNodes_ = n;
|
|
||||||
}
|
|
||||||
|
|
||||||
void setLeaves(const label n)
|
|
||||||
{
|
|
||||||
nLeaves_ = n;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Queries
|
|
||||||
|
|
||||||
//- Returns type of sample with respect to nearest shape.
|
|
||||||
// Meaning of type is determined by shapes.getSampleType().
|
|
||||||
// Normally based on outwards pointing normal. For e.g.
|
|
||||||
// octreeDataFace returns one of
|
|
||||||
// inside : on other side of normal on nearest face
|
|
||||||
// outside : on same side as normal on nearest face
|
|
||||||
// unknown : not above nearest face; surface probably not
|
|
||||||
// closed.
|
|
||||||
// mixed : should never happen
|
|
||||||
label getSampleType(const point& sample) const;
|
|
||||||
|
|
||||||
//- Find shape containing point in tree
|
|
||||||
// Returns -1 if not in found. Uses Type::contains.
|
|
||||||
label find(const point& sample) const;
|
|
||||||
|
|
||||||
//- Calculate tightest fitting bounding box. Uses
|
|
||||||
// Type::findTightest.
|
|
||||||
bool findTightest
|
|
||||||
(
|
|
||||||
const point& sample,
|
|
||||||
treeBoundBox& tightest
|
|
||||||
) const;
|
|
||||||
|
|
||||||
//- Find nearest shape. Returns index of shape or -1 if not found.
|
|
||||||
// tightestDist is both input and output. Uses Type::calcNearest.
|
|
||||||
label findNearest
|
|
||||||
(
|
|
||||||
const point& sample,
|
|
||||||
treeBoundBox& tightest,
|
|
||||||
scalar& tightestDist
|
|
||||||
) const;
|
|
||||||
|
|
||||||
//- Find nearest to line. Returns -1 or index of shape and
|
|
||||||
// sets:
|
|
||||||
// - tightest (is both input and output).
|
|
||||||
// - linePoint : point on line (-GREAT,-GREAT,-GREAT if not found)
|
|
||||||
// - shapePoint : point on shape (GREAT, GREAT, GREAT if not found)
|
|
||||||
// Uses Type::calcNearest.
|
|
||||||
label findNearest
|
|
||||||
(
|
|
||||||
const linePointRef& ln,
|
|
||||||
treeBoundBox& tightest,
|
|
||||||
point& linePoint,
|
|
||||||
point& shapePoint
|
|
||||||
) const;
|
|
||||||
|
|
||||||
//- Find (in no particular order) indices of all shapes inside or
|
|
||||||
// overlapping bounding box (i.e. all shapes not outside box)
|
|
||||||
labelList findBox(const boundBox& bb) const;
|
|
||||||
|
|
||||||
//- Find intersected shape along line. pointIndexHit contains index
|
|
||||||
// of nearest shape intersected and the intersection point. Uses
|
|
||||||
// findLeafLine.
|
|
||||||
pointIndexHit findLine(const point& start, const point& end) const;
|
|
||||||
|
|
||||||
//- Like above but just tests whether line hits anything. So
|
|
||||||
// returns first intersection found, not nessecarily nearest.
|
|
||||||
pointIndexHit findLineAny(const point& start, const point& end)
|
|
||||||
const;
|
|
||||||
|
|
||||||
//- Find leaf along line. Set leafIntPoint to leave point of
|
|
||||||
// treeLeaf.
|
|
||||||
const treeLeaf<Type>* findLeafLine
|
|
||||||
(
|
|
||||||
const point& start,
|
|
||||||
const point& end,
|
|
||||||
point& leafIntPoint
|
|
||||||
) const;
|
|
||||||
|
|
||||||
|
|
||||||
// Write
|
|
||||||
|
|
||||||
//- Dump graphical representation in .obj format
|
|
||||||
void writeOBJ(Ostream& os, label& vertNo) const;
|
|
||||||
|
|
||||||
//- Print some stats on octree
|
|
||||||
void printStats(Ostream& os) const;
|
|
||||||
|
|
||||||
|
|
||||||
// STL iterator
|
|
||||||
|
|
||||||
class iterator;
|
|
||||||
friend class iterator;
|
|
||||||
|
|
||||||
//- An STL iterator for octree
|
|
||||||
class iterator
|
|
||||||
{
|
|
||||||
// Private data
|
|
||||||
|
|
||||||
//- Reference to the octree this is an iterator for
|
|
||||||
octree& octree_;
|
|
||||||
|
|
||||||
//- List of pointers to treeLeaves
|
|
||||||
List<treeLeaf<Type>*> leaves_;
|
|
||||||
|
|
||||||
//- Current treeLeaf index
|
|
||||||
label curLeaf_;
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
//- Construct for a given octree
|
|
||||||
iterator(octree&);
|
|
||||||
|
|
||||||
//- Contruct for a given octree, at a certain position
|
|
||||||
iterator(octree& oc, const label index);
|
|
||||||
|
|
||||||
|
|
||||||
// Member operators
|
|
||||||
|
|
||||||
void operator=(const iterator&);
|
|
||||||
|
|
||||||
bool operator==(const iterator&) const;
|
|
||||||
bool operator!=(const iterator&) const;
|
|
||||||
|
|
||||||
treeLeaf<Type>& operator*();
|
|
||||||
|
|
||||||
iterator& operator++();
|
|
||||||
iterator operator++(int);
|
|
||||||
};
|
|
||||||
|
|
||||||
//- iterator set to the begining of the octree
|
|
||||||
iterator begin();
|
|
||||||
|
|
||||||
//- iterator set to beyond the end of the octree
|
|
||||||
const iterator& end();
|
|
||||||
|
|
||||||
|
|
||||||
// STL const_iterator
|
|
||||||
|
|
||||||
class const_iterator;
|
|
||||||
friend class const_iterator;
|
|
||||||
|
|
||||||
//- An STL const_iterator for octree
|
|
||||||
class const_iterator
|
|
||||||
{
|
|
||||||
// Private data
|
|
||||||
|
|
||||||
//- Reference to the list this is an iterator for
|
|
||||||
const octree& octree_;
|
|
||||||
|
|
||||||
//- List of treeLeafs
|
|
||||||
List<const treeLeaf<Type>*> leaves_;
|
|
||||||
|
|
||||||
//- Current treeLeaf index
|
|
||||||
label curLeaf_;
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
//- Construct for a given octree
|
|
||||||
const_iterator(const octree&);
|
|
||||||
|
|
||||||
//- Construct for a given octree and index
|
|
||||||
const_iterator(const octree&, label);
|
|
||||||
|
|
||||||
// Member operators
|
|
||||||
|
|
||||||
void operator=(const const_iterator&);
|
|
||||||
|
|
||||||
bool operator==(const const_iterator&) const;
|
|
||||||
bool operator!=(const const_iterator&) const;
|
|
||||||
|
|
||||||
const treeLeaf<Type>& operator*();
|
|
||||||
|
|
||||||
const_iterator& operator++();
|
|
||||||
const_iterator operator++(int);
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
//- const_iterator set to the begining of the octree
|
|
||||||
inline const_iterator begin() const;
|
|
||||||
inline const_iterator cbegin() const;
|
|
||||||
|
|
||||||
//- const_iterator set to beyond the end of the octree
|
|
||||||
inline const const_iterator& end() const;
|
|
||||||
inline const const_iterator& cend() const;
|
|
||||||
|
|
||||||
|
|
||||||
// IOstream Operators
|
|
||||||
|
|
||||||
friend Ostream& operator<< <Type>(Ostream&, const octree<Type>&);
|
|
||||||
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
//- iterator returned by end()
|
|
||||||
iterator endIter_;
|
|
||||||
|
|
||||||
//- const_iterator returned by end()
|
|
||||||
const_iterator endConstIter_;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
} // End namespace Foam
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
#ifdef NoRepository
|
|
||||||
# include "octree.C"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
|
||||||
@ -1,242 +0,0 @@
|
|||||||
/*---------------------------------------------------------------------------*\
|
|
||||||
========= |
|
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
|
||||||
\\ / O peration |
|
|
||||||
\\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
|
|
||||||
\\/ M anipulation |
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
License
|
|
||||||
This file is part of OpenFOAM.
|
|
||||||
|
|
||||||
OpenFOAM is free software: you can redistribute it and/or modify it
|
|
||||||
under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
|
||||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
||||||
for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
#include "octreeDataCell.H"
|
|
||||||
#include "polyMesh.H"
|
|
||||||
#include "primitiveMesh.H"
|
|
||||||
#include "treeNode.H"
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
// Construct from components
|
|
||||||
Foam::octreeDataCell::octreeDataCell
|
|
||||||
(
|
|
||||||
const polyMesh& mesh,
|
|
||||||
const labelList& cellLabels,
|
|
||||||
const treeBoundBoxList& bbs
|
|
||||||
)
|
|
||||||
:
|
|
||||||
mesh_(mesh),
|
|
||||||
cellLabels_(cellLabels),
|
|
||||||
bbs_(bbs)
|
|
||||||
{}
|
|
||||||
|
|
||||||
|
|
||||||
// Construct from mesh (assumes all cells)
|
|
||||||
Foam::octreeDataCell::octreeDataCell
|
|
||||||
(
|
|
||||||
const polyMesh& mesh
|
|
||||||
)
|
|
||||||
:
|
|
||||||
mesh_(mesh),
|
|
||||||
cellLabels_(mesh_.nCells()),
|
|
||||||
bbs_
|
|
||||||
(
|
|
||||||
mesh_.nCells(),
|
|
||||||
treeBoundBox::invertedBox
|
|
||||||
)
|
|
||||||
{
|
|
||||||
// Set one-one indexing
|
|
||||||
for (label i=0; i < mesh_.nCells(); i++)
|
|
||||||
{
|
|
||||||
cellLabels_[i] = i;
|
|
||||||
}
|
|
||||||
|
|
||||||
const pointField& points = mesh_.points();
|
|
||||||
const faceList& faces = mesh_.faces();
|
|
||||||
const cellList& cells = mesh_.cells();
|
|
||||||
|
|
||||||
forAll(cells, celli)
|
|
||||||
{
|
|
||||||
const labelList& facesi = cells[celli];
|
|
||||||
|
|
||||||
forAll(facesi, facei)
|
|
||||||
{
|
|
||||||
const labelList& pointsi = faces[facesi[facei]];
|
|
||||||
|
|
||||||
forAll(pointsi, pointi)
|
|
||||||
{
|
|
||||||
const point& p = points[pointsi[pointi]];
|
|
||||||
|
|
||||||
bbs_[celli].min() = min(bbs_[celli].min(), p);
|
|
||||||
bbs_[celli].max() = max(bbs_[celli].max(), p);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
Foam::label Foam::octreeDataCell::getSampleType
|
|
||||||
(
|
|
||||||
octree<octreeDataCell>&,
|
|
||||||
const point&
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
return octree<octreeDataCell>::UNKNOWN;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool Foam::octreeDataCell::overlaps
|
|
||||||
(
|
|
||||||
const label index,
|
|
||||||
const treeBoundBox& cubeBb
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
return cubeBb.overlaps(bbs_[index]);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool Foam::octreeDataCell::contains
|
|
||||||
(
|
|
||||||
const label index,
|
|
||||||
const point& sample
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
return mesh_.pointInCell
|
|
||||||
(
|
|
||||||
sample,
|
|
||||||
cellLabels_[index],
|
|
||||||
polyMesh::FACEDIAGTETS
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool Foam::octreeDataCell::intersects
|
|
||||||
(
|
|
||||||
const label,
|
|
||||||
const point&,
|
|
||||||
const point&,
|
|
||||||
point&
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
//Hack: don't know what to do here.
|
|
||||||
|
|
||||||
notImplemented
|
|
||||||
(
|
|
||||||
"octreeDataCell::intersects(const label, const point&,"
|
|
||||||
"const point&, point&)"
|
|
||||||
);
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool Foam::octreeDataCell::findTightest
|
|
||||||
(
|
|
||||||
const label index,
|
|
||||||
const point& sample,
|
|
||||||
treeBoundBox& tightest
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
|
|
||||||
// get nearest and furthest away vertex
|
|
||||||
point myNear, myFar;
|
|
||||||
bbs_[index].calcExtremities(sample, myNear, myFar);
|
|
||||||
|
|
||||||
const point dist = myFar - sample;
|
|
||||||
scalar myFarDist = mag(dist);
|
|
||||||
|
|
||||||
point tightestNear, tightestFar;
|
|
||||||
tightest.calcExtremities(sample, tightestNear, tightestFar);
|
|
||||||
|
|
||||||
scalar tightestFarDist = mag(tightestFar - sample);
|
|
||||||
|
|
||||||
if (tightestFarDist < myFarDist)
|
|
||||||
{
|
|
||||||
// Keep current tightest.
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Construct bb around sample and myFar
|
|
||||||
const point dist2(fabs(dist.x()), fabs(dist.y()), fabs(dist.z()));
|
|
||||||
|
|
||||||
tightest.min() = sample - dist2;
|
|
||||||
tightest.max() = sample + dist2;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Determine numerical value of sign of sample compared to shape at index
|
|
||||||
Foam::scalar Foam::octreeDataCell::calcSign
|
|
||||||
(
|
|
||||||
const label,
|
|
||||||
const point&,
|
|
||||||
vector& n
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
n = vector::zero;
|
|
||||||
|
|
||||||
return GREAT;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Calculate nearest point on/in shapei
|
|
||||||
Foam::scalar Foam::octreeDataCell::calcNearest
|
|
||||||
(
|
|
||||||
const label index,
|
|
||||||
const point& sample,
|
|
||||||
point& nearest
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
nearest = mesh_.cellCentres()[cellLabels_[index]];
|
|
||||||
|
|
||||||
return mag(nearest - sample);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Calculate nearest point on/in shapei
|
|
||||||
Foam::scalar Foam::octreeDataCell::calcNearest
|
|
||||||
(
|
|
||||||
const label index,
|
|
||||||
const linePointRef& ln,
|
|
||||||
point& linePt,
|
|
||||||
point& shapePt
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
notImplemented
|
|
||||||
(
|
|
||||||
"octreeDataCell::calcNearest(const label, const linePointRef&"
|
|
||||||
", point& linePt, point&)"
|
|
||||||
);
|
|
||||||
return GREAT;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Foam::octreeDataCell::write
|
|
||||||
(
|
|
||||||
Ostream& os,
|
|
||||||
const label index
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
os << cellLabels_[index] << " " << bbs_[index];
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
|
||||||
@ -1,196 +0,0 @@
|
|||||||
/*---------------------------------------------------------------------------*\
|
|
||||||
========= |
|
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
|
||||||
\\ / O peration |
|
|
||||||
\\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
|
|
||||||
\\/ M anipulation |
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
License
|
|
||||||
This file is part of OpenFOAM.
|
|
||||||
|
|
||||||
OpenFOAM is free software: you can redistribute it and/or modify it
|
|
||||||
under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
|
||||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
||||||
for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
Class
|
|
||||||
Foam::octreeDataCell
|
|
||||||
|
|
||||||
Description
|
|
||||||
Encapsulation of data needed to search in/for cells.
|
|
||||||
|
|
||||||
Used to find the cell containing a point (e.g. cell-cell mapping).
|
|
||||||
|
|
||||||
SourceFiles
|
|
||||||
octreeDataCell.C
|
|
||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
#ifndef octreeDataCell_H
|
|
||||||
#define octreeDataCell_H
|
|
||||||
|
|
||||||
#include "treeBoundBoxList.H"
|
|
||||||
#include "labelList.H"
|
|
||||||
#include "linePointRef.H"
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
namespace Foam
|
|
||||||
{
|
|
||||||
|
|
||||||
// Forward declaration of classes
|
|
||||||
class polyMesh;
|
|
||||||
template<class Type> class octree;
|
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*\
|
|
||||||
Class octreeDataCell Declaration
|
|
||||||
\*---------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
class octreeDataCell
|
|
||||||
{
|
|
||||||
// Private data
|
|
||||||
|
|
||||||
const polyMesh& mesh_;
|
|
||||||
|
|
||||||
labelList cellLabels_;
|
|
||||||
|
|
||||||
treeBoundBoxList bbs_;
|
|
||||||
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
// Constructors
|
|
||||||
|
|
||||||
//- Construct from components.
|
|
||||||
octreeDataCell
|
|
||||||
(
|
|
||||||
const polyMesh&,
|
|
||||||
const labelList& cellLabels,
|
|
||||||
const treeBoundBoxList& bbs
|
|
||||||
);
|
|
||||||
|
|
||||||
//- Construct from mesh. Uses all cells in mesh.
|
|
||||||
octreeDataCell(const polyMesh&);
|
|
||||||
|
|
||||||
|
|
||||||
// Member Functions
|
|
||||||
|
|
||||||
// Access
|
|
||||||
|
|
||||||
const labelList& cellLabels() const
|
|
||||||
{
|
|
||||||
return cellLabels_;
|
|
||||||
}
|
|
||||||
|
|
||||||
const polyMesh& mesh() const
|
|
||||||
{
|
|
||||||
return mesh_;
|
|
||||||
}
|
|
||||||
|
|
||||||
const treeBoundBoxList& allBb() const
|
|
||||||
{
|
|
||||||
return bbs_;
|
|
||||||
}
|
|
||||||
|
|
||||||
label size() const
|
|
||||||
{
|
|
||||||
return bbs_.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Search
|
|
||||||
|
|
||||||
//- Get type of sample
|
|
||||||
label getSampleType(octree<octreeDataCell>&, const point&) const;
|
|
||||||
|
|
||||||
//- Does (bb of) shape at index overlap bb
|
|
||||||
bool overlaps
|
|
||||||
(
|
|
||||||
const label index,
|
|
||||||
const treeBoundBox& sampleBb
|
|
||||||
) const;
|
|
||||||
|
|
||||||
//- Does shape at index contain sample
|
|
||||||
bool contains
|
|
||||||
(
|
|
||||||
const label index,
|
|
||||||
const point& sample
|
|
||||||
) const;
|
|
||||||
|
|
||||||
//- Segment (from start to end) intersection with shape
|
|
||||||
// at index. If intersects returns true and sets intersectionPoint
|
|
||||||
// BUG: not yet done.
|
|
||||||
bool intersects
|
|
||||||
(
|
|
||||||
const label index,
|
|
||||||
const point& start,
|
|
||||||
const point& end,
|
|
||||||
point& intersectionPoint
|
|
||||||
) const;
|
|
||||||
|
|
||||||
//- Sets newTightest to bounding box (and returns true) if
|
|
||||||
// nearer to sample than tightest bounding box. Otherwise
|
|
||||||
// returns false
|
|
||||||
bool findTightest
|
|
||||||
(
|
|
||||||
const label index,
|
|
||||||
const point& sample,
|
|
||||||
treeBoundBox& tightest
|
|
||||||
) const;
|
|
||||||
|
|
||||||
//- Given index get unit normal and calculate (numerical) sign
|
|
||||||
// of sample.
|
|
||||||
// Used to determine accuracy of calcNearest or inside/outside.
|
|
||||||
// Note: always returns GREAT since no inside/outside.
|
|
||||||
scalar calcSign
|
|
||||||
(
|
|
||||||
const label index,
|
|
||||||
const point& sample,
|
|
||||||
vector& n
|
|
||||||
) const;
|
|
||||||
|
|
||||||
//- Calculates nearest (to sample) point in shape.
|
|
||||||
// Returns point and mag(nearest - sample)
|
|
||||||
scalar calcNearest
|
|
||||||
(
|
|
||||||
const Foam::label index,
|
|
||||||
const Foam::point& sample,
|
|
||||||
point& nearest
|
|
||||||
) const;
|
|
||||||
|
|
||||||
//- Calculates nearest (to line segment) point in shape.
|
|
||||||
// Returns distance and both point.
|
|
||||||
scalar calcNearest
|
|
||||||
(
|
|
||||||
const label index,
|
|
||||||
const linePointRef& ln,
|
|
||||||
point& linePt, // nearest point on line
|
|
||||||
point& shapePt // nearest point on shape
|
|
||||||
) const;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Write
|
|
||||||
|
|
||||||
// Write shape at index
|
|
||||||
void write(Ostream& os, const label index) const;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
} // End namespace Foam
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
|
||||||
@ -1,240 +0,0 @@
|
|||||||
/*---------------------------------------------------------------------------*\
|
|
||||||
========= |
|
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
|
||||||
\\ / O peration |
|
|
||||||
\\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
|
|
||||||
\\/ M anipulation |
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
License
|
|
||||||
This file is part of OpenFOAM.
|
|
||||||
|
|
||||||
OpenFOAM is free software: you can redistribute it and/or modify it
|
|
||||||
under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
|
||||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
||||||
for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
#include "octreeDataEdges.H"
|
|
||||||
|
|
||||||
#include "line.H"
|
|
||||||
#include "labelList.H"
|
|
||||||
#include "octree.H"
|
|
||||||
#include "linePointRef.H"
|
|
||||||
#include "pointHit.H"
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
defineTypeNameAndDebug(Foam::octreeDataEdges, 0);
|
|
||||||
|
|
||||||
Foam::scalar Foam::octreeDataEdges::tol(1E-6);
|
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
// Construct from selected edges. Bounding box calculated.
|
|
||||||
Foam::octreeDataEdges::octreeDataEdges
|
|
||||||
(
|
|
||||||
const edgeList& edges,
|
|
||||||
const pointField& points,
|
|
||||||
const labelList& edgeLabels
|
|
||||||
)
|
|
||||||
:
|
|
||||||
edges_(edges),
|
|
||||||
points_(points),
|
|
||||||
edgeLabels_(edgeLabels),
|
|
||||||
allBb_(edgeLabels_.size())
|
|
||||||
{
|
|
||||||
// Generate tight fitting bounding box
|
|
||||||
forAll(edgeLabels_, i)
|
|
||||||
{
|
|
||||||
label edgeI = edgeLabels_[i];
|
|
||||||
|
|
||||||
const edge& e = edges_[edgeI];
|
|
||||||
|
|
||||||
const point& a = points_[e.start()];
|
|
||||||
const point& b = points_[e.end()];
|
|
||||||
|
|
||||||
allBb_[i].min() = min(a, b);
|
|
||||||
allBb_[i].max() = max(a, b);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Construct as copy
|
|
||||||
Foam::octreeDataEdges::octreeDataEdges(const octreeDataEdges& shapes)
|
|
||||||
:
|
|
||||||
edges_(shapes.edges()),
|
|
||||||
points_(shapes.points()),
|
|
||||||
edgeLabels_(shapes.edgeLabels()),
|
|
||||||
allBb_(shapes.allBb())
|
|
||||||
{}
|
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
Foam::octreeDataEdges::~octreeDataEdges()
|
|
||||||
{}
|
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
Foam::label Foam::octreeDataEdges::getSampleType
|
|
||||||
(
|
|
||||||
const octree<octreeDataEdges>&,
|
|
||||||
const point&
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
return octree<octreeDataEdges>::UNKNOWN;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool Foam::octreeDataEdges::overlaps
|
|
||||||
(
|
|
||||||
const label index,
|
|
||||||
const treeBoundBox& sampleBb
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
return sampleBb.overlaps(allBb_[index]);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool Foam::octreeDataEdges::contains
|
|
||||||
(
|
|
||||||
const label,
|
|
||||||
const point&
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
notImplemented
|
|
||||||
(
|
|
||||||
"octreeDataEdges::contains(const label, const point&)"
|
|
||||||
);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool Foam::octreeDataEdges::intersects
|
|
||||||
(
|
|
||||||
const label,
|
|
||||||
const point&,
|
|
||||||
const point&,
|
|
||||||
point&
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
notImplemented
|
|
||||||
(
|
|
||||||
"octreeDataEdges::intersects(const label, const point&"
|
|
||||||
", const point&, point&)"
|
|
||||||
);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool Foam::octreeDataEdges::findTightest
|
|
||||||
(
|
|
||||||
const label index,
|
|
||||||
const point& sample,
|
|
||||||
treeBoundBox& tightest
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
// Get nearest and furthest away vertex
|
|
||||||
point myNear, myFar;
|
|
||||||
allBb_[index].calcExtremities(sample, myNear, myFar);
|
|
||||||
|
|
||||||
const point dist = myFar - sample;
|
|
||||||
scalar myFarDist = mag(dist);
|
|
||||||
|
|
||||||
point tightestNear, tightestFar;
|
|
||||||
tightest.calcExtremities(sample, tightestNear, tightestFar);
|
|
||||||
|
|
||||||
scalar tightestFarDist = mag(tightestFar - sample);
|
|
||||||
|
|
||||||
if (tightestFarDist < myFarDist)
|
|
||||||
{
|
|
||||||
// Keep current tightest.
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Construct bb around sample and myFar
|
|
||||||
const point dist2(fabs(dist.x()), fabs(dist.y()), fabs(dist.z()));
|
|
||||||
|
|
||||||
tightest.min() = sample - dist2;
|
|
||||||
tightest.max() = sample + dist2;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Determine numerical value of sign of sample compared to shape at index
|
|
||||||
Foam::scalar Foam::octreeDataEdges::calcSign
|
|
||||||
(
|
|
||||||
const label,
|
|
||||||
const point&,
|
|
||||||
point& n
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
n = vector::zero;
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Calculate nearest point on/in shapei
|
|
||||||
Foam::scalar Foam::octreeDataEdges::calcNearest
|
|
||||||
(
|
|
||||||
const label index,
|
|
||||||
const point& sample,
|
|
||||||
point& nearest
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
const edge& e = edges_[edgeLabels_[index]];
|
|
||||||
|
|
||||||
pointHit nearHit = e.line(points_).nearestDist(sample);
|
|
||||||
|
|
||||||
nearest = nearHit.rawPoint();
|
|
||||||
|
|
||||||
return nearHit.distance();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Calculate nearest point on/in shapei
|
|
||||||
Foam::scalar Foam::octreeDataEdges::calcNearest
|
|
||||||
(
|
|
||||||
const label index,
|
|
||||||
const linePointRef& sampleLine,
|
|
||||||
point& sampleLinePt,
|
|
||||||
point& shapePt
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
const edge& e = edges_[edgeLabels_[index]];
|
|
||||||
|
|
||||||
linePointRef edgeLine(e.line(points_));
|
|
||||||
|
|
||||||
return edgeLine.nearestDist(sampleLine, shapePt, sampleLinePt);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Foam::octreeDataEdges::write
|
|
||||||
(
|
|
||||||
Ostream& os,
|
|
||||||
const label index
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
os << edgeLabels_[index] << " " << allBb_[index];
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
|
||||||
@ -1,221 +0,0 @@
|
|||||||
/*---------------------------------------------------------------------------*\
|
|
||||||
========= |
|
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
|
||||||
\\ / O peration |
|
|
||||||
\\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
|
|
||||||
\\/ M anipulation |
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
License
|
|
||||||
This file is part of OpenFOAM.
|
|
||||||
|
|
||||||
OpenFOAM is free software: you can redistribute it and/or modify it
|
|
||||||
under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
|
||||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
||||||
for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
Class
|
|
||||||
Foam::octreeDataEdges
|
|
||||||
|
|
||||||
Description
|
|
||||||
Holds data for octree to work on an edges subset.
|
|
||||||
|
|
||||||
SourceFiles
|
|
||||||
octreeDataEdges.C
|
|
||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
#ifndef octreeDataEdges_H
|
|
||||||
#define octreeDataEdges_H
|
|
||||||
|
|
||||||
#include "line.H"
|
|
||||||
#include "linePointRef.H"
|
|
||||||
#include "treeBoundBoxList.H"
|
|
||||||
#include "labelList.H"
|
|
||||||
#include "className.H"
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
namespace Foam
|
|
||||||
{
|
|
||||||
|
|
||||||
// Forward declaration of classes
|
|
||||||
template<class Type> class octree;
|
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*\
|
|
||||||
Class octreeDataEdges Declaration
|
|
||||||
\*---------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
class octreeDataEdges
|
|
||||||
{
|
|
||||||
// Static data
|
|
||||||
|
|
||||||
//- tolerance on linear dimensions
|
|
||||||
static scalar tol;
|
|
||||||
|
|
||||||
|
|
||||||
// Private data
|
|
||||||
|
|
||||||
//- Reference to edgeList
|
|
||||||
const edgeList& edges_;
|
|
||||||
|
|
||||||
//- Reference to points
|
|
||||||
const pointField& points_;
|
|
||||||
|
|
||||||
//- labels of edges
|
|
||||||
labelList edgeLabels_;
|
|
||||||
|
|
||||||
//- bbs for all above edges
|
|
||||||
treeBoundBoxList allBb_;
|
|
||||||
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
// Declare name of the class and its debug switch
|
|
||||||
ClassName("octreeDataEdges");
|
|
||||||
|
|
||||||
// Constructors
|
|
||||||
|
|
||||||
//- Construct from selected edges. !Holds references to edges and points
|
|
||||||
octreeDataEdges
|
|
||||||
(
|
|
||||||
const edgeList& edges,
|
|
||||||
const pointField& points,
|
|
||||||
const labelList& edgeLabels
|
|
||||||
);
|
|
||||||
|
|
||||||
//- Construct as copy
|
|
||||||
octreeDataEdges(const octreeDataEdges&);
|
|
||||||
|
|
||||||
|
|
||||||
//- Destructor
|
|
||||||
~octreeDataEdges();
|
|
||||||
|
|
||||||
|
|
||||||
// Member Functions
|
|
||||||
|
|
||||||
// Access
|
|
||||||
|
|
||||||
const edgeList& edges() const
|
|
||||||
{
|
|
||||||
return edges_;
|
|
||||||
}
|
|
||||||
|
|
||||||
const pointField& points() const
|
|
||||||
{
|
|
||||||
return points_;
|
|
||||||
}
|
|
||||||
|
|
||||||
const labelList& edgeLabels() const
|
|
||||||
{
|
|
||||||
return edgeLabels_;
|
|
||||||
}
|
|
||||||
|
|
||||||
const treeBoundBoxList& allBb() const
|
|
||||||
{
|
|
||||||
return allBb_;
|
|
||||||
}
|
|
||||||
|
|
||||||
label size() const
|
|
||||||
{
|
|
||||||
return allBb_.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Search
|
|
||||||
|
|
||||||
//- Get type of sample
|
|
||||||
label getSampleType
|
|
||||||
(
|
|
||||||
const octree<octreeDataEdges>&,
|
|
||||||
const point&
|
|
||||||
) const;
|
|
||||||
|
|
||||||
//- Does (bb of) shape at index overlap bb
|
|
||||||
bool overlaps
|
|
||||||
(
|
|
||||||
const label index,
|
|
||||||
const treeBoundBox& sampleBb
|
|
||||||
) const;
|
|
||||||
|
|
||||||
//- Does shape at index contain sample
|
|
||||||
bool contains
|
|
||||||
(
|
|
||||||
const label index,
|
|
||||||
const point& sample
|
|
||||||
) const;
|
|
||||||
|
|
||||||
//- Segment (from start to end) intersection with shape at index.
|
|
||||||
// If intersects returns true and sets intersectionPoint
|
|
||||||
bool intersects
|
|
||||||
(
|
|
||||||
const label index,
|
|
||||||
const point& start,
|
|
||||||
const point& end,
|
|
||||||
point& intersectionPoint
|
|
||||||
) const;
|
|
||||||
|
|
||||||
//- Sets newTightest to bounding box (and returns true) if
|
|
||||||
// nearer to sample than tightest bounding box. Otherwise
|
|
||||||
// returns false.
|
|
||||||
bool findTightest
|
|
||||||
(
|
|
||||||
const label index,
|
|
||||||
const point& sample,
|
|
||||||
treeBoundBox& tightest
|
|
||||||
) const;
|
|
||||||
|
|
||||||
//- Given index get unit normal and calculate (numerical) sign
|
|
||||||
// of sample.
|
|
||||||
// Used to determine accuracy of calcNearest or inside/outside.
|
|
||||||
scalar calcSign
|
|
||||||
(
|
|
||||||
const label index,
|
|
||||||
const point& sample,
|
|
||||||
vector& n
|
|
||||||
) const;
|
|
||||||
|
|
||||||
//- Calculates nearest (to sample) point in shape.
|
|
||||||
// Returns point and mag(nearest - sample).
|
|
||||||
scalar calcNearest
|
|
||||||
(
|
|
||||||
const label index,
|
|
||||||
const point& sample,
|
|
||||||
point& nearest
|
|
||||||
) const;
|
|
||||||
|
|
||||||
//- Calculates nearest (to line segment) point in shape.
|
|
||||||
// Returns distance and both point.
|
|
||||||
scalar calcNearest
|
|
||||||
(
|
|
||||||
const label index,
|
|
||||||
const linePointRef& ln,
|
|
||||||
point& linePt, // nearest point on line
|
|
||||||
point& shapePt // nearest point on shape
|
|
||||||
) const;
|
|
||||||
|
|
||||||
|
|
||||||
// Write
|
|
||||||
|
|
||||||
//- Write shape at index
|
|
||||||
void write(Ostream& os, const label index) const;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
} // End namespace Foam
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
|
||||||
@ -1,717 +0,0 @@
|
|||||||
/*---------------------------------------------------------------------------*\
|
|
||||||
========= |
|
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
|
||||||
\\ / O peration |
|
|
||||||
\\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
|
|
||||||
\\/ M anipulation |
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
License
|
|
||||||
This file is part of OpenFOAM.
|
|
||||||
|
|
||||||
OpenFOAM is free software: you can redistribute it and/or modify it
|
|
||||||
under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
|
||||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
||||||
for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
#include "octreeDataFace.H"
|
|
||||||
#include "labelList.H"
|
|
||||||
#include "polyMesh.H"
|
|
||||||
#include "octree.H"
|
|
||||||
#include "polyPatch.H"
|
|
||||||
#include "triangleFuncs.H"
|
|
||||||
#include "linePointRef.H"
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
defineTypeNameAndDebug(Foam::octreeDataFace, 0);
|
|
||||||
|
|
||||||
Foam::scalar Foam::octreeDataFace::tol(1E-6);
|
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
|
||||||
|
|
||||||
void Foam::octreeDataFace::calcBb()
|
|
||||||
{
|
|
||||||
allBb_.setSize(meshFaces_.size());
|
|
||||||
allBb_ = treeBoundBox::invertedBox;
|
|
||||||
|
|
||||||
forAll(meshFaces_, i)
|
|
||||||
{
|
|
||||||
// Update bb of face
|
|
||||||
treeBoundBox& myBb = allBb_[i];
|
|
||||||
|
|
||||||
const face& f = mesh_.faces()[meshFaces_[i]];
|
|
||||||
|
|
||||||
forAll(f, faceVertexI)
|
|
||||||
{
|
|
||||||
const point& coord = mesh_.points()[f[faceVertexI]];
|
|
||||||
|
|
||||||
myBb.min() = min(myBb.min(), coord);
|
|
||||||
myBb.max() = max(myBb.max(), coord);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
// Construct from selected mesh faces
|
|
||||||
Foam::octreeDataFace::octreeDataFace
|
|
||||||
(
|
|
||||||
const primitiveMesh& mesh,
|
|
||||||
const labelList& meshFaces,
|
|
||||||
const treeBoundBoxList& allBb
|
|
||||||
)
|
|
||||||
:
|
|
||||||
mesh_(mesh),
|
|
||||||
meshFaces_(meshFaces),
|
|
||||||
allBb_(allBb)
|
|
||||||
{}
|
|
||||||
|
|
||||||
|
|
||||||
// Construct from selected mesh faces. Bounding box calculated.
|
|
||||||
Foam::octreeDataFace::octreeDataFace
|
|
||||||
(
|
|
||||||
const primitiveMesh& mesh,
|
|
||||||
const labelList& meshFaces
|
|
||||||
)
|
|
||||||
:
|
|
||||||
mesh_(mesh),
|
|
||||||
meshFaces_(meshFaces),
|
|
||||||
allBb_(meshFaces_.size())
|
|
||||||
{
|
|
||||||
// Generate tight fitting bounding box
|
|
||||||
calcBb();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Construct from selected mesh faces
|
|
||||||
Foam::octreeDataFace::octreeDataFace
|
|
||||||
(
|
|
||||||
const primitiveMesh& mesh,
|
|
||||||
const UList<const labelList*>& meshFaceListPtrs,
|
|
||||||
const UList<const treeBoundBoxList*>& bbListPtrs
|
|
||||||
)
|
|
||||||
:
|
|
||||||
mesh_(mesh),
|
|
||||||
meshFaces_(0),
|
|
||||||
allBb_(0)
|
|
||||||
{
|
|
||||||
label faceI = 0;
|
|
||||||
|
|
||||||
forAll(meshFaceListPtrs, listI)
|
|
||||||
{
|
|
||||||
faceI += meshFaceListPtrs[listI]->size();
|
|
||||||
}
|
|
||||||
|
|
||||||
meshFaces_.setSize(faceI);
|
|
||||||
allBb_.setSize(faceI);
|
|
||||||
|
|
||||||
faceI = 0;
|
|
||||||
|
|
||||||
forAll(meshFaceListPtrs, listI)
|
|
||||||
{
|
|
||||||
const labelList& meshFaces = *meshFaceListPtrs[listI];
|
|
||||||
const treeBoundBoxList& allBb = *bbListPtrs[listI];
|
|
||||||
|
|
||||||
forAll(meshFaces, meshFaceI)
|
|
||||||
{
|
|
||||||
meshFaces_[faceI] = meshFaces[meshFaceI];
|
|
||||||
allBb_[faceI] = allBb[meshFaceI];
|
|
||||||
faceI++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Construct from selected mesh faces. Bounding box calculated.
|
|
||||||
Foam::octreeDataFace::octreeDataFace
|
|
||||||
(
|
|
||||||
const primitiveMesh& mesh,
|
|
||||||
const UList<const labelList*>& meshFaceListPtrs
|
|
||||||
)
|
|
||||||
:
|
|
||||||
mesh_(mesh),
|
|
||||||
meshFaces_(0)
|
|
||||||
{
|
|
||||||
label faceI = 0;
|
|
||||||
|
|
||||||
forAll(meshFaceListPtrs, listI)
|
|
||||||
{
|
|
||||||
faceI += meshFaceListPtrs[listI]->size();
|
|
||||||
}
|
|
||||||
|
|
||||||
meshFaces_.setSize(faceI);
|
|
||||||
|
|
||||||
faceI = 0;
|
|
||||||
|
|
||||||
forAll(meshFaceListPtrs, listI)
|
|
||||||
{
|
|
||||||
const labelList& meshFaces = *meshFaceListPtrs[listI];
|
|
||||||
|
|
||||||
forAll(meshFaces, meshFaceI)
|
|
||||||
{
|
|
||||||
meshFaces_[faceI++] = meshFaces[meshFaceI];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Generate tight fitting bounding box
|
|
||||||
calcBb();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Construct from all faces in polyPatch. Bounding box calculated.
|
|
||||||
Foam::octreeDataFace::octreeDataFace(const polyPatch& patch)
|
|
||||||
:
|
|
||||||
mesh_(patch.boundaryMesh().mesh()),
|
|
||||||
meshFaces_(patch.size())
|
|
||||||
{
|
|
||||||
forAll(patch, patchFaceI)
|
|
||||||
{
|
|
||||||
meshFaces_[patchFaceI] = patch.start() + patchFaceI;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Generate tight fitting bounding box
|
|
||||||
calcBb();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Construct from primitiveMesh. Inserts all boundary faces.
|
|
||||||
Foam::octreeDataFace::octreeDataFace(const primitiveMesh& mesh)
|
|
||||||
:
|
|
||||||
mesh_(mesh),
|
|
||||||
meshFaces_(0),
|
|
||||||
allBb_(0)
|
|
||||||
{
|
|
||||||
// Size storage
|
|
||||||
meshFaces_.setSize(mesh_.nFaces() - mesh_.nInternalFaces());
|
|
||||||
|
|
||||||
// Set info for all boundary faces.
|
|
||||||
label boundaryFaceI = 0;
|
|
||||||
|
|
||||||
for (label faceI = mesh_.nInternalFaces(); faceI < mesh_.nFaces(); faceI++)
|
|
||||||
{
|
|
||||||
meshFaces_[boundaryFaceI++] = faceI;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Generate tight fitting bounding box
|
|
||||||
calcBb();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Construct as copy
|
|
||||||
Foam::octreeDataFace::octreeDataFace(const octreeDataFace& shapes)
|
|
||||||
:
|
|
||||||
mesh_(shapes.mesh()),
|
|
||||||
meshFaces_(shapes.meshFaces()),
|
|
||||||
allBb_(shapes.allBb())
|
|
||||||
{}
|
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
Foam::octreeDataFace::~octreeDataFace()
|
|
||||||
{}
|
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
Foam::label Foam::octreeDataFace::getSampleType
|
|
||||||
(
|
|
||||||
const octree<octreeDataFace>& oc,
|
|
||||||
const point& sample
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
// Need to determine whether sample is 'inside' or 'outside'
|
|
||||||
// Done by finding nearest face. This gives back a face which is
|
|
||||||
// guaranteed to contain nearest point. This point can be
|
|
||||||
// - in interior of face: compare to face normal
|
|
||||||
// - on edge of face: compare to edge normal
|
|
||||||
// - on point of face: compare to point normal
|
|
||||||
// Unfortunately the octree does not give us back the intersection point
|
|
||||||
// or where on the face it has hit so we have to recreate all that
|
|
||||||
// information.
|
|
||||||
|
|
||||||
treeBoundBox tightest(treeBoundBox::greatBox);
|
|
||||||
scalar tightestDist(treeBoundBox::great);
|
|
||||||
// Find nearest face to sample
|
|
||||||
label index = oc.findNearest(sample, tightest, tightestDist);
|
|
||||||
|
|
||||||
if (index == -1)
|
|
||||||
{
|
|
||||||
FatalErrorIn
|
|
||||||
(
|
|
||||||
"octreeDataFace::getSampleType"
|
|
||||||
"(octree<octreeDataFace>&, const point&)"
|
|
||||||
) << "Could not find " << sample << " in octree."
|
|
||||||
<< abort(FatalError);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Get actual intersection point on face
|
|
||||||
label faceI = meshFaces_[index];
|
|
||||||
|
|
||||||
if (debug & 2)
|
|
||||||
{
|
|
||||||
Pout<< "getSampleType : sample:" << sample
|
|
||||||
<< " nearest face:" << faceI;
|
|
||||||
}
|
|
||||||
|
|
||||||
const face& f = mesh_.faces()[faceI];
|
|
||||||
|
|
||||||
const pointField& points = mesh_.points();
|
|
||||||
|
|
||||||
pointHit curHit = f.nearestPoint(sample, points);
|
|
||||||
|
|
||||||
//
|
|
||||||
// 1] Check whether sample is above face
|
|
||||||
//
|
|
||||||
|
|
||||||
if (curHit.hit())
|
|
||||||
{
|
|
||||||
// Simple case. Compare to face normal.
|
|
||||||
|
|
||||||
if (debug & 2)
|
|
||||||
{
|
|
||||||
Pout<< " -> face hit:" << curHit.hitPoint()
|
|
||||||
<< " comparing to face normal " << mesh_.faceAreas()[faceI]
|
|
||||||
<< endl;
|
|
||||||
}
|
|
||||||
return octree<octreeDataFace>::getVolType
|
|
||||||
(
|
|
||||||
mesh_.faceAreas()[faceI],
|
|
||||||
sample - curHit.hitPoint()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (debug & 2)
|
|
||||||
{
|
|
||||||
Pout<< " -> face miss:" << curHit.missPoint();
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// 2] Check whether intersection is on one of the face vertices or
|
|
||||||
// face centre
|
|
||||||
//
|
|
||||||
|
|
||||||
scalar typDim = sqrt(mag(mesh_.faceAreas()[faceI])) + VSMALL;
|
|
||||||
|
|
||||||
forAll(f, fp)
|
|
||||||
{
|
|
||||||
if ((mag(points[f[fp]] - curHit.missPoint())/typDim) < tol)
|
|
||||||
{
|
|
||||||
// Face intersection point equals face vertex fp
|
|
||||||
|
|
||||||
// Calculate point normal (wrong: uses face normals instead of
|
|
||||||
// triangle normals)
|
|
||||||
const labelList& myFaces = mesh_.pointFaces()[f[fp]];
|
|
||||||
|
|
||||||
vector pointNormal(vector::zero);
|
|
||||||
|
|
||||||
forAll(myFaces, myFaceI)
|
|
||||||
{
|
|
||||||
if (myFaces[myFaceI] >= mesh_.nInternalFaces())
|
|
||||||
{
|
|
||||||
vector n = mesh_.faceAreas()[myFaces[myFaceI]];
|
|
||||||
n /= mag(n) + VSMALL;
|
|
||||||
|
|
||||||
pointNormal += n;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (debug & 2)
|
|
||||||
{
|
|
||||||
Pout<< " -> face point hit :" << points[f[fp]]
|
|
||||||
<< " point normal:" << pointNormal
|
|
||||||
<< " distance:"
|
|
||||||
<< mag(points[f[fp]] - curHit.missPoint())/typDim
|
|
||||||
<< endl;
|
|
||||||
}
|
|
||||||
return octree<octreeDataFace>::getVolType
|
|
||||||
(
|
|
||||||
pointNormal,
|
|
||||||
sample - curHit.missPoint()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ((mag(mesh_.faceCentres()[faceI] - curHit.missPoint())/typDim) < tol)
|
|
||||||
{
|
|
||||||
// Face intersection point equals face centre. Normal at face centre
|
|
||||||
// is already average of face normals
|
|
||||||
|
|
||||||
if (debug & 2)
|
|
||||||
{
|
|
||||||
Pout<< " -> centre hit:" << mesh_.faceCentres()[faceI]
|
|
||||||
<< " distance:"
|
|
||||||
<< mag(mesh_.faceCentres()[faceI] - curHit.missPoint())/typDim
|
|
||||||
<< endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
return octree<octreeDataFace>::getVolType
|
|
||||||
(
|
|
||||||
mesh_.faceAreas()[faceI],
|
|
||||||
sample - curHit.missPoint()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//
|
|
||||||
// 3] Get the 'real' edge the face intersection is on
|
|
||||||
//
|
|
||||||
|
|
||||||
const labelList& myEdges = mesh_.faceEdges()[faceI];
|
|
||||||
|
|
||||||
forAll(myEdges, myEdgeI)
|
|
||||||
{
|
|
||||||
const edge& e = mesh_.edges()[myEdges[myEdgeI]];
|
|
||||||
|
|
||||||
pointHit edgeHit = line<point, const point&>
|
|
||||||
(
|
|
||||||
points[e.start()],
|
|
||||||
points[e.end()]
|
|
||||||
).nearestDist(sample);
|
|
||||||
|
|
||||||
|
|
||||||
if ((mag(edgeHit.rawPoint() - curHit.missPoint())/typDim) < tol)
|
|
||||||
{
|
|
||||||
// Face intersection point lies on edge e
|
|
||||||
|
|
||||||
// Calculate edge normal (wrong: uses face normals instead of
|
|
||||||
// triangle normals)
|
|
||||||
const labelList& myFaces = mesh_.edgeFaces()[myEdges[myEdgeI]];
|
|
||||||
|
|
||||||
vector edgeNormal(vector::zero);
|
|
||||||
|
|
||||||
forAll(myFaces, myFaceI)
|
|
||||||
{
|
|
||||||
if (myFaces[myFaceI] >= mesh_.nInternalFaces())
|
|
||||||
{
|
|
||||||
vector n = mesh_.faceAreas()[myFaces[myFaceI]];
|
|
||||||
n /= mag(n) + VSMALL;
|
|
||||||
|
|
||||||
edgeNormal += n;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (debug & 2)
|
|
||||||
{
|
|
||||||
Pout<< " -> real edge hit point:" << edgeHit.rawPoint()
|
|
||||||
<< " comparing to edge normal:" << edgeNormal
|
|
||||||
<< endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Found face intersection point on this edge. Compare to edge
|
|
||||||
// normal
|
|
||||||
return octree<octreeDataFace>::getVolType
|
|
||||||
(
|
|
||||||
edgeNormal,
|
|
||||||
sample - curHit.missPoint()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//
|
|
||||||
// 4] Get the internal edge the face intersection is on
|
|
||||||
//
|
|
||||||
|
|
||||||
forAll(f, fp)
|
|
||||||
{
|
|
||||||
pointHit edgeHit =
|
|
||||||
line<point, const point&>
|
|
||||||
(
|
|
||||||
points[f[fp]],
|
|
||||||
mesh_.faceCentres()[faceI]
|
|
||||||
).nearestDist(sample);
|
|
||||||
|
|
||||||
if ((mag(edgeHit.rawPoint() - curHit.missPoint())/typDim) < tol)
|
|
||||||
{
|
|
||||||
// Face intersection point lies on edge between two face triangles
|
|
||||||
|
|
||||||
// Calculate edge normal as average of the two triangle normals
|
|
||||||
const label fpPrev = f.rcIndex(fp);
|
|
||||||
const label fpNext = f.fcIndex(fp);
|
|
||||||
|
|
||||||
vector e = points[f[fp]] - mesh_.faceCentres()[faceI];
|
|
||||||
vector ePrev = points[f[fpPrev]] - mesh_.faceCentres()[faceI];
|
|
||||||
vector eNext = points[f[fpNext]] - mesh_.faceCentres()[faceI];
|
|
||||||
|
|
||||||
vector nLeft = ePrev ^ e;
|
|
||||||
nLeft /= mag(nLeft) + VSMALL;
|
|
||||||
|
|
||||||
vector nRight = e ^ eNext;
|
|
||||||
nRight /= mag(nRight) + VSMALL;
|
|
||||||
|
|
||||||
if (debug & 2)
|
|
||||||
{
|
|
||||||
Pout<< " -> internal edge hit point:" << edgeHit.rawPoint()
|
|
||||||
<< " comparing to edge normal "
|
|
||||||
<< 0.5*(nLeft + nRight)
|
|
||||||
<< endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Found face intersection point on this edge. Compare to edge
|
|
||||||
// normal
|
|
||||||
return octree<octreeDataFace>::getVolType
|
|
||||||
(
|
|
||||||
0.5*(nLeft + nRight),
|
|
||||||
sample - curHit.missPoint()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (debug & 2)
|
|
||||||
{
|
|
||||||
Pout<< "Did not find sample " << sample
|
|
||||||
<< " anywhere related to nearest face " << faceI << endl
|
|
||||||
<< "Face:";
|
|
||||||
|
|
||||||
forAll(f, fp)
|
|
||||||
{
|
|
||||||
Pout<< " vertex:" << f[fp] << " coord:" << points[f[fp]]
|
|
||||||
<< endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Can't determine status of sample with respect to nearest face.
|
|
||||||
// Either
|
|
||||||
// - tolerances are wrong. (if e.g. face has zero area)
|
|
||||||
// - or (more likely) surface is not closed.
|
|
||||||
|
|
||||||
return octree<octreeDataFace>::UNKNOWN;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool Foam::octreeDataFace::overlaps
|
|
||||||
(
|
|
||||||
const label index,
|
|
||||||
const treeBoundBox& sampleBb
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
//return sampleBb.overlaps(allBb_[index]);
|
|
||||||
|
|
||||||
//- Exact test of face intersecting bb
|
|
||||||
|
|
||||||
// 1. Quick rejection: bb does not intersect face bb at all
|
|
||||||
if (!sampleBb.overlaps(allBb_[index]))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 2. Check if one or more face points inside
|
|
||||||
label faceI = meshFaces_[index];
|
|
||||||
|
|
||||||
const face& f = mesh_.faces()[faceI];
|
|
||||||
|
|
||||||
const pointField& points = mesh_.points();
|
|
||||||
if (sampleBb.containsAny(points, f))
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 3. Difficult case: all points are outside but connecting edges might
|
|
||||||
// go through cube. Use triangle-bounding box intersection.
|
|
||||||
const point& fc = mesh_.faceCentres()[faceI];
|
|
||||||
|
|
||||||
forAll(f, fp)
|
|
||||||
{
|
|
||||||
const label fp1 = f.fcIndex(fp);
|
|
||||||
|
|
||||||
bool triIntersects = triangleFuncs::intersectBb
|
|
||||||
(
|
|
||||||
points[f[fp]],
|
|
||||||
points[f[fp1]],
|
|
||||||
fc,
|
|
||||||
sampleBb
|
|
||||||
);
|
|
||||||
|
|
||||||
if (triIntersects)
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool Foam::octreeDataFace::contains(const label, const point&) const
|
|
||||||
{
|
|
||||||
notImplemented
|
|
||||||
(
|
|
||||||
"octreeDataFace::contains(const label, const point&)"
|
|
||||||
);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool Foam::octreeDataFace::intersects
|
|
||||||
(
|
|
||||||
const label index,
|
|
||||||
const point& start,
|
|
||||||
const point& end,
|
|
||||||
point& intersectionPoint
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
label faceI = meshFaces_[index];
|
|
||||||
|
|
||||||
const face& f = mesh_.faces()[faceI];
|
|
||||||
|
|
||||||
const vector dir(end - start);
|
|
||||||
|
|
||||||
// Disable picking up intersections behind us.
|
|
||||||
scalar oldTol = intersection::setPlanarTol(0.0);
|
|
||||||
|
|
||||||
pointHit inter = f.ray
|
|
||||||
(
|
|
||||||
start,
|
|
||||||
dir,
|
|
||||||
mesh_.points(),
|
|
||||||
intersection::HALF_RAY,
|
|
||||||
intersection::VECTOR
|
|
||||||
);
|
|
||||||
|
|
||||||
intersection::setPlanarTol(oldTol);
|
|
||||||
|
|
||||||
if (inter.hit() && inter.distance() <= mag(dir))
|
|
||||||
{
|
|
||||||
intersectionPoint = inter.hitPoint();
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool Foam::octreeDataFace::findTightest
|
|
||||||
(
|
|
||||||
const label index,
|
|
||||||
const point& sample,
|
|
||||||
treeBoundBox& tightest
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
// Get furthest away vertex
|
|
||||||
point myNear, myFar;
|
|
||||||
allBb_[index].calcExtremities(sample, myNear, myFar);
|
|
||||||
|
|
||||||
const point dist = myFar - sample;
|
|
||||||
scalar myFarDist = mag(dist);
|
|
||||||
|
|
||||||
point tightestNear, tightestFar;
|
|
||||||
tightest.calcExtremities(sample, tightestNear, tightestFar);
|
|
||||||
|
|
||||||
scalar tightestFarDist = mag(tightestFar - sample);
|
|
||||||
|
|
||||||
if (tightestFarDist < myFarDist)
|
|
||||||
{
|
|
||||||
// Keep current tightest.
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Construct bb around sample and myFar
|
|
||||||
const point dist2(fabs(dist.x()), fabs(dist.y()), fabs(dist.z()));
|
|
||||||
|
|
||||||
tightest.min() = sample - dist2;
|
|
||||||
tightest.max() = sample + dist2;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Determine numerical value of sign of sample compared to shape at index
|
|
||||||
Foam::scalar Foam::octreeDataFace::calcSign
|
|
||||||
(
|
|
||||||
const label index,
|
|
||||||
const point& sample,
|
|
||||||
point& n
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
label faceI = meshFaces_[index];
|
|
||||||
|
|
||||||
n = mesh_.faceAreas()[faceI];
|
|
||||||
|
|
||||||
n /= mag(n) + VSMALL;
|
|
||||||
|
|
||||||
vector vec = sample - mesh_.faceCentres()[faceI];
|
|
||||||
|
|
||||||
vec /= mag(vec) + VSMALL;
|
|
||||||
|
|
||||||
return n & vec;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Calculate nearest point on/in shapei
|
|
||||||
Foam::scalar Foam::octreeDataFace::calcNearest
|
|
||||||
(
|
|
||||||
const label index,
|
|
||||||
const point& sample,
|
|
||||||
point& nearest
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
label faceI = meshFaces_[index];
|
|
||||||
|
|
||||||
const face& f = mesh_.faces()[faceI];
|
|
||||||
|
|
||||||
pointHit nearHit = f.nearestPoint(sample, mesh_.points());
|
|
||||||
|
|
||||||
nearest = nearHit.rawPoint();
|
|
||||||
|
|
||||||
if (debug & 1)
|
|
||||||
{
|
|
||||||
const point& ctr = mesh_.faceCentres()[faceI];
|
|
||||||
|
|
||||||
scalar sign = mesh_.faceAreas()[faceI] & (sample - nearest);
|
|
||||||
|
|
||||||
Pout<< "octreeDataFace::calcNearest : "
|
|
||||||
<< "sample:" << sample
|
|
||||||
<< " index:" << index
|
|
||||||
<< " faceI:" << faceI
|
|
||||||
<< " ctr:" << ctr
|
|
||||||
<< " sign:" << sign
|
|
||||||
<< " nearest point:" << nearest
|
|
||||||
<< " distance to face:" << nearHit.distance()
|
|
||||||
<< endl;
|
|
||||||
}
|
|
||||||
return nearHit.distance();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Calculate nearest point on/in shapei
|
|
||||||
Foam::scalar Foam::octreeDataFace::calcNearest
|
|
||||||
(
|
|
||||||
const label index,
|
|
||||||
const linePointRef& ln,
|
|
||||||
point& linePt,
|
|
||||||
point& shapePt
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
notImplemented
|
|
||||||
(
|
|
||||||
"octreeDataFace::calcNearest(const label, const linePointRef&"
|
|
||||||
", point&, point&)"
|
|
||||||
);
|
|
||||||
return GREAT;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Foam::octreeDataFace::write(Ostream& os, const label index) const
|
|
||||||
{
|
|
||||||
os << meshFaces_[index] << " " << allBb_[index];
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
|
||||||
@ -1,248 +0,0 @@
|
|||||||
/*---------------------------------------------------------------------------*\
|
|
||||||
========= |
|
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
|
||||||
\\ / O peration |
|
|
||||||
\\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
|
|
||||||
\\/ M anipulation |
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
License
|
|
||||||
This file is part of OpenFOAM.
|
|
||||||
|
|
||||||
OpenFOAM is free software: you can redistribute it and/or modify it
|
|
||||||
under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
|
||||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
||||||
for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
Class
|
|
||||||
Foam::octreeDataFace
|
|
||||||
|
|
||||||
Description
|
|
||||||
Holds data for octree to work on mesh faces.
|
|
||||||
|
|
||||||
For example, calculate (in calcNearest) the correct intersection point
|
|
||||||
with a face.
|
|
||||||
|
|
||||||
SourceFiles
|
|
||||||
octreeDataFace.C
|
|
||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
#ifndef octreeDataFace_H
|
|
||||||
#define octreeDataFace_H
|
|
||||||
|
|
||||||
#include "treeBoundBoxList.H"
|
|
||||||
#include "faceList.H"
|
|
||||||
#include "point.H"
|
|
||||||
#include "className.H"
|
|
||||||
#include "linePointRef.H"
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
namespace Foam
|
|
||||||
{
|
|
||||||
|
|
||||||
// Forward declaration of classes
|
|
||||||
class primitiveMesh;
|
|
||||||
template<class Type> class octree;
|
|
||||||
class polyPatch;
|
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*\
|
|
||||||
Class octreeDataFace Declaration
|
|
||||||
\*---------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
class octreeDataFace
|
|
||||||
{
|
|
||||||
// Static data
|
|
||||||
|
|
||||||
//- tolerance on linear dimensions
|
|
||||||
static scalar tol;
|
|
||||||
|
|
||||||
|
|
||||||
// Private data
|
|
||||||
|
|
||||||
//- the mesh
|
|
||||||
const primitiveMesh& mesh_;
|
|
||||||
|
|
||||||
//- labels (in mesh indexing) of faces
|
|
||||||
labelList meshFaces_;
|
|
||||||
|
|
||||||
//- bbs for all above faces
|
|
||||||
treeBoundBoxList allBb_;
|
|
||||||
|
|
||||||
|
|
||||||
// Private Member Functions
|
|
||||||
|
|
||||||
//- Set allBb to tight fitting bounding box
|
|
||||||
void calcBb();
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
// Declare name of the class and its debug switch
|
|
||||||
ClassName("octreeDataFace");
|
|
||||||
|
|
||||||
// Constructors
|
|
||||||
|
|
||||||
//- Construct from selected mesh faces.
|
|
||||||
octreeDataFace
|
|
||||||
(
|
|
||||||
const primitiveMesh&,
|
|
||||||
const labelList& meshFaces,
|
|
||||||
const treeBoundBoxList&
|
|
||||||
);
|
|
||||||
|
|
||||||
//- Construct from selected mesh faces. Tight fitting bounding boxes
|
|
||||||
// generated internally.
|
|
||||||
octreeDataFace
|
|
||||||
(
|
|
||||||
const primitiveMesh&,
|
|
||||||
const labelList& meshFaces
|
|
||||||
);
|
|
||||||
|
|
||||||
//- Construct from selected mesh faces.
|
|
||||||
octreeDataFace
|
|
||||||
(
|
|
||||||
const primitiveMesh&,
|
|
||||||
const UList<const labelList*>&,
|
|
||||||
const UList<const treeBoundBoxList*>&
|
|
||||||
);
|
|
||||||
|
|
||||||
//- Construct from selected mesh faces.
|
|
||||||
// Tight-fitting bounding boxes generated internally.
|
|
||||||
octreeDataFace(const primitiveMesh&, const UList<const labelList*>&);
|
|
||||||
|
|
||||||
//- Construct from all faces in patch.
|
|
||||||
// Tight-fitting bounding boxes generated internally.
|
|
||||||
octreeDataFace(const polyPatch&);
|
|
||||||
|
|
||||||
//- Construct from all boundary faces.
|
|
||||||
// Tight-fitting bounding boxes generated internally.
|
|
||||||
octreeDataFace(const primitiveMesh&);
|
|
||||||
|
|
||||||
//- Construct as copy
|
|
||||||
octreeDataFace(const octreeDataFace&);
|
|
||||||
|
|
||||||
|
|
||||||
//- Destructor
|
|
||||||
~octreeDataFace();
|
|
||||||
|
|
||||||
|
|
||||||
// Member Functions
|
|
||||||
|
|
||||||
// Access
|
|
||||||
|
|
||||||
const primitiveMesh& mesh() const
|
|
||||||
{
|
|
||||||
return mesh_;
|
|
||||||
}
|
|
||||||
|
|
||||||
const labelList& meshFaces() const
|
|
||||||
{
|
|
||||||
return meshFaces_;
|
|
||||||
}
|
|
||||||
|
|
||||||
const treeBoundBoxList& allBb() const
|
|
||||||
{
|
|
||||||
return allBb_;
|
|
||||||
}
|
|
||||||
|
|
||||||
label size() const
|
|
||||||
{
|
|
||||||
return allBb_.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Search
|
|
||||||
|
|
||||||
//- Get type of sample
|
|
||||||
label getSampleType
|
|
||||||
(
|
|
||||||
const octree<octreeDataFace>&,
|
|
||||||
const point&
|
|
||||||
) const;
|
|
||||||
|
|
||||||
//- Does (bb of) shape at index overlap bb
|
|
||||||
bool overlaps
|
|
||||||
(
|
|
||||||
const label index,
|
|
||||||
const treeBoundBox& sampleBb
|
|
||||||
) const;
|
|
||||||
|
|
||||||
//- Does shape at index contain sample
|
|
||||||
bool contains(const label index, const point& sample) const;
|
|
||||||
|
|
||||||
//- Segment (from start to end) intersection with shape
|
|
||||||
// at index. If intersects returns true and sets intersectionPoint
|
|
||||||
bool intersects
|
|
||||||
(
|
|
||||||
const label index,
|
|
||||||
const point& start,
|
|
||||||
const point& end,
|
|
||||||
point& intersectionPoint
|
|
||||||
) const;
|
|
||||||
|
|
||||||
//- Sets newTightest to bounding box (and returns true) if
|
|
||||||
// nearer to sample than tightest bounding box. Otherwise
|
|
||||||
// returns false.
|
|
||||||
bool findTightest
|
|
||||||
(
|
|
||||||
const label index,
|
|
||||||
const point& sample,
|
|
||||||
treeBoundBox& tightest
|
|
||||||
) const;
|
|
||||||
|
|
||||||
//- Given index get unit normal and calculate (numerical) sign
|
|
||||||
// of sample.
|
|
||||||
// Used to determine accuracy of calcNearest or inside/outside.
|
|
||||||
scalar calcSign
|
|
||||||
(
|
|
||||||
const label index,
|
|
||||||
const point& sample,
|
|
||||||
vector& n
|
|
||||||
) const;
|
|
||||||
|
|
||||||
//- Calculates nearest (to sample) point in shape.
|
|
||||||
// Returns point and mag(nearest - sample). Returns GREAT if
|
|
||||||
// sample does not project onto (triangle decomposition) of face.
|
|
||||||
scalar calcNearest
|
|
||||||
(
|
|
||||||
const label index,
|
|
||||||
const point& sample,
|
|
||||||
point& nearest
|
|
||||||
) const;
|
|
||||||
|
|
||||||
//- Calculates nearest (to line segment) point in shape.
|
|
||||||
// Returns distance and both point.
|
|
||||||
scalar calcNearest
|
|
||||||
(
|
|
||||||
const label index,
|
|
||||||
const linePointRef& ln,
|
|
||||||
point& linePt, // nearest point on line
|
|
||||||
point& shapePt // nearest point on shape
|
|
||||||
) const;
|
|
||||||
|
|
||||||
|
|
||||||
// Write
|
|
||||||
|
|
||||||
//- Write shape at index
|
|
||||||
void write(Ostream& os, const label index) const;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
} // End namespace Foam
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
|
||||||
@ -1,191 +0,0 @@
|
|||||||
/*---------------------------------------------------------------------------*\
|
|
||||||
========= |
|
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
|
||||||
\\ / O peration |
|
|
||||||
\\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
|
|
||||||
\\/ M anipulation |
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
License
|
|
||||||
This file is part of OpenFOAM.
|
|
||||||
|
|
||||||
OpenFOAM is free software: you can redistribute it and/or modify it
|
|
||||||
under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
|
||||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
||||||
for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
#include "octreeDataPoint.H"
|
|
||||||
|
|
||||||
#include "labelList.H"
|
|
||||||
#include "treeBoundBox.H"
|
|
||||||
#include "octree.H"
|
|
||||||
#include "linePointRef.H"
|
|
||||||
#include "pointHit.H"
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
// Construct from components
|
|
||||||
Foam::octreeDataPoint::octreeDataPoint(const pointField& points)
|
|
||||||
:
|
|
||||||
points_(points)
|
|
||||||
{}
|
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
//- Get type of volume
|
|
||||||
Foam::label Foam::octreeDataPoint::getSampleType
|
|
||||||
(
|
|
||||||
const octree<octreeDataPoint>&,
|
|
||||||
const point&
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
return octree<octreeDataPoint>::UNKNOWN;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool Foam::octreeDataPoint::overlaps
|
|
||||||
(
|
|
||||||
const label index,
|
|
||||||
const treeBoundBox& sampleBb
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
return sampleBb.contains(points_[index]);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool Foam::octreeDataPoint::contains
|
|
||||||
(
|
|
||||||
const label,
|
|
||||||
const point&
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
notImplemented
|
|
||||||
(
|
|
||||||
"octreeDataPoint::contains(const label, const point&)"
|
|
||||||
);
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool Foam::octreeDataPoint::intersects
|
|
||||||
(
|
|
||||||
const label,
|
|
||||||
const point&,
|
|
||||||
const point&,
|
|
||||||
point&
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
notImplemented
|
|
||||||
(
|
|
||||||
"octreeDataPoint::intersects(const label, const point&,"
|
|
||||||
"const point&, point&)"
|
|
||||||
);
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool Foam::octreeDataPoint::findTightest
|
|
||||||
(
|
|
||||||
const label,
|
|
||||||
const point&,
|
|
||||||
treeBoundBox&
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
notImplemented
|
|
||||||
(
|
|
||||||
"octreeDataPoint::findTightest(const label, const point&,"
|
|
||||||
"treeBoundBox&)"
|
|
||||||
);
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Foam::scalar Foam::octreeDataPoint::calcSign
|
|
||||||
(
|
|
||||||
const label,
|
|
||||||
const point&,
|
|
||||||
vector& n
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
n = vector::zero;
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Calculate nearest point on/in shapei
|
|
||||||
inline Foam::scalar Foam::octreeDataPoint::calcNearest
|
|
||||||
(
|
|
||||||
const label index,
|
|
||||||
const point& sample,
|
|
||||||
point& nearest
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
nearest = points_[index];
|
|
||||||
return magSqr(points_[index] - sample);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Foam::octreeDataPoint::write
|
|
||||||
(
|
|
||||||
Ostream& os,
|
|
||||||
const label index
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
if ((index < 0) || (index > points().size()))
|
|
||||||
{
|
|
||||||
FatalErrorIn("octreeDataPoint::write(Ostream&, const label)")
|
|
||||||
<< "Index " << index << " outside 0.." << points().size()
|
|
||||||
<< abort(FatalError);
|
|
||||||
}
|
|
||||||
os << ' ' << points()[index];
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Calculate nearest point on/in shapei
|
|
||||||
Foam::scalar Foam::octreeDataPoint::calcNearest
|
|
||||||
(
|
|
||||||
const label index,
|
|
||||||
const linePointRef& ln,
|
|
||||||
point& linePt,
|
|
||||||
point& shapePt
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
// Nearest point on shape
|
|
||||||
shapePt = points_[index];
|
|
||||||
|
|
||||||
// Nearest point on line
|
|
||||||
pointHit pHit = ln.nearestDist(shapePt);
|
|
||||||
|
|
||||||
linePt = pHit.rawPoint();
|
|
||||||
|
|
||||||
return pHit.distance();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * Friend Operators * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
Foam::Ostream& Foam::operator<<
|
|
||||||
(
|
|
||||||
Foam::Ostream& os,
|
|
||||||
const Foam::octreeDataPoint& ocPts
|
|
||||||
)
|
|
||||||
{
|
|
||||||
return os << ocPts.points();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
|
||||||
@ -1,184 +0,0 @@
|
|||||||
/*---------------------------------------------------------------------------*\
|
|
||||||
========= |
|
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
|
||||||
\\ / O peration |
|
|
||||||
\\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
|
|
||||||
\\/ M anipulation |
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
License
|
|
||||||
This file is part of OpenFOAM.
|
|
||||||
|
|
||||||
OpenFOAM is free software: you can redistribute it and/or modify it
|
|
||||||
under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
|
||||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
||||||
for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
Class
|
|
||||||
Foam::octreeDataPoint
|
|
||||||
|
|
||||||
Description
|
|
||||||
Encapsulation of data needed for octree searches.
|
|
||||||
|
|
||||||
Used for searching for nearest point. No bounding boxes around points.
|
|
||||||
Only overlaps and calcNearest are implemented, rest makes little sense.
|
|
||||||
Holds (reference to) pointField.
|
|
||||||
|
|
||||||
SourceFiles
|
|
||||||
octreeDataPoint.C
|
|
||||||
octreeDataPointTreaLeaf.H (template specialization of treeleaf)
|
|
||||||
octreeDataPointTreeLeaf.C (template specialization of treeleaf)
|
|
||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
#ifndef octreeDataPoint_H
|
|
||||||
#define octreeDataPoint_H
|
|
||||||
|
|
||||||
#include "point.H"
|
|
||||||
#include "pointField.H"
|
|
||||||
#include "treeBoundBox.H"
|
|
||||||
#include "linePointRef.H"
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
namespace Foam
|
|
||||||
{
|
|
||||||
|
|
||||||
template<class Type> class octree;
|
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*\
|
|
||||||
Class octreeDataPoint Declaration
|
|
||||||
\*---------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
class octreeDataPoint
|
|
||||||
{
|
|
||||||
// Private data
|
|
||||||
|
|
||||||
const pointField& points_;
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
// Constructors
|
|
||||||
|
|
||||||
//- Construct from components. Holds reference to points!
|
|
||||||
explicit octreeDataPoint(const pointField&);
|
|
||||||
|
|
||||||
|
|
||||||
// Member Functions
|
|
||||||
|
|
||||||
// Access
|
|
||||||
|
|
||||||
const pointField& points() const
|
|
||||||
{
|
|
||||||
return points_;
|
|
||||||
}
|
|
||||||
|
|
||||||
label size() const
|
|
||||||
{
|
|
||||||
return points_.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Search
|
|
||||||
|
|
||||||
//- Get type of sample
|
|
||||||
label getSampleType
|
|
||||||
(
|
|
||||||
const octree<octreeDataPoint>&,
|
|
||||||
const point&
|
|
||||||
) const;
|
|
||||||
|
|
||||||
//- Does (bb of) shape at index overlap bb
|
|
||||||
bool overlaps
|
|
||||||
(
|
|
||||||
const label index,
|
|
||||||
const treeBoundBox& sampleBb
|
|
||||||
) const;
|
|
||||||
|
|
||||||
//- Does shape at index contain sample
|
|
||||||
bool contains
|
|
||||||
(
|
|
||||||
const label index,
|
|
||||||
const point& sample
|
|
||||||
) const;
|
|
||||||
|
|
||||||
//- Segment (from start to end) intersection with shape
|
|
||||||
// at index. If intersects returns true and sets intersectionPoint
|
|
||||||
bool intersects
|
|
||||||
(
|
|
||||||
const label index,
|
|
||||||
const point& start,
|
|
||||||
const point& end,
|
|
||||||
point& intersectionPoint
|
|
||||||
) const;
|
|
||||||
|
|
||||||
//- Sets newTightest to bounding box (and returns true) if
|
|
||||||
// nearer to sample than tightest bounding box. Otherwise
|
|
||||||
// returns false.
|
|
||||||
bool findTightest
|
|
||||||
(
|
|
||||||
const label index,
|
|
||||||
const point& sample,
|
|
||||||
treeBoundBox& tightest
|
|
||||||
) const;
|
|
||||||
|
|
||||||
//- Given index get unit normal and calculate (numerical) sign
|
|
||||||
// of sample.
|
|
||||||
// Used to determine accuracy of calcNearest or inside/outside.
|
|
||||||
// Note: always returns GREAT since no inside/outside.
|
|
||||||
scalar calcSign
|
|
||||||
(
|
|
||||||
const label index,
|
|
||||||
const point& sample,
|
|
||||||
vector& n
|
|
||||||
) const;
|
|
||||||
|
|
||||||
|
|
||||||
//- Calculates nearest (to sample) point on/in shape.
|
|
||||||
// Returns point and mag(nearest - sample)
|
|
||||||
scalar calcNearest
|
|
||||||
(
|
|
||||||
const label index,
|
|
||||||
const point& sample,
|
|
||||||
point& nearest
|
|
||||||
) const;
|
|
||||||
|
|
||||||
//- Calculates nearest (to line segment) point in shape.
|
|
||||||
// Returns distance and both point.
|
|
||||||
scalar calcNearest
|
|
||||||
(
|
|
||||||
const label index,
|
|
||||||
const linePointRef& ln,
|
|
||||||
point& linePt, // nearest point on line
|
|
||||||
point& shapePt // nearest point on shape
|
|
||||||
) const;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Write
|
|
||||||
|
|
||||||
//- Write shape at index
|
|
||||||
void write(Ostream& os, const label index) const;
|
|
||||||
|
|
||||||
|
|
||||||
// IOstream Operators
|
|
||||||
|
|
||||||
friend Ostream& operator<<(Ostream&, const octreeDataPoint&);
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
} // End namespace Foam
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
|
||||||
@ -1,105 +0,0 @@
|
|||||||
/*---------------------------------------------------------------------------*\
|
|
||||||
========= |
|
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
|
||||||
\\ / O peration |
|
|
||||||
\\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
|
|
||||||
\\/ M anipulation |
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
License
|
|
||||||
This file is part of OpenFOAM.
|
|
||||||
|
|
||||||
OpenFOAM is free software: you can redistribute it and/or modify it
|
|
||||||
under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
|
||||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
||||||
for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
//#include "octreeDataPointTreeLeaf.H"
|
|
||||||
#include "octreeDataPoint.H"
|
|
||||||
#include "treeLeaf.H"
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * Template Specialisations * * * * * * * * * * * //
|
|
||||||
|
|
||||||
template<>
|
|
||||||
Foam::label Foam::treeLeaf<Foam::octreeDataPoint>::find
|
|
||||||
(
|
|
||||||
const octreeDataPoint& shapes,
|
|
||||||
const point& sample
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
notImplemented
|
|
||||||
(
|
|
||||||
"Foam::treeLeaf<Foam::octreeDataPoint>::find("
|
|
||||||
"const octreeDataPoint& shapes,"
|
|
||||||
"const point& sample"
|
|
||||||
);
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template<>
|
|
||||||
bool Foam::treeLeaf<Foam::octreeDataPoint>::findNearest
|
|
||||||
(
|
|
||||||
const octreeDataPoint& shapes,
|
|
||||||
const point& sample,
|
|
||||||
treeBoundBox& tightest,
|
|
||||||
label& tightestI,
|
|
||||||
scalar& tightestDist
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
// Some aliases
|
|
||||||
const pointField& points = shapes.points();
|
|
||||||
point& tMin = tightest.min();
|
|
||||||
point& tMax = tightest.max();
|
|
||||||
|
|
||||||
scalar minDist2 = sqr(tightestDist);
|
|
||||||
|
|
||||||
label minIndex = -1;
|
|
||||||
forAll(indices_, i)
|
|
||||||
{
|
|
||||||
label pointi = indices_[i];
|
|
||||||
scalar dist = magSqr(points[pointi] - sample);
|
|
||||||
|
|
||||||
if (dist < minDist2)
|
|
||||||
{
|
|
||||||
minDist2 = dist;
|
|
||||||
minIndex = pointi;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (minIndex != -1)
|
|
||||||
{
|
|
||||||
tightestDist = sqrt(minDist2);
|
|
||||||
|
|
||||||
// New nearer. Update 'tightest' bounding box
|
|
||||||
tMin.x() = sample.x() - tightestDist;
|
|
||||||
tMin.y() = sample.y() - tightestDist;
|
|
||||||
tMin.z() = sample.z() - tightestDist;
|
|
||||||
|
|
||||||
tMax.x() = sample.x() + tightestDist;
|
|
||||||
tMax.y() = sample.y() + tightestDist;
|
|
||||||
tMax.z() = sample.z() + tightestDist;
|
|
||||||
|
|
||||||
tightestI = minIndex;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// New no nearer so nothing changed
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
|
||||||
@ -1,75 +0,0 @@
|
|||||||
/*---------------------------------------------------------------------------*\
|
|
||||||
========= |
|
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
|
||||||
\\ / O peration |
|
|
||||||
\\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
|
|
||||||
\\/ M anipulation |
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
License
|
|
||||||
This file is part of OpenFOAM.
|
|
||||||
|
|
||||||
OpenFOAM is free software: you can redistribute it and/or modify it
|
|
||||||
under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
|
||||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
||||||
for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
Class
|
|
||||||
Foam::octreeDataPointTreeLeaf
|
|
||||||
|
|
||||||
Description
|
|
||||||
Template specialisation for octreeDataPoint
|
|
||||||
|
|
||||||
SourceFiles
|
|
||||||
octreeDataPointTreeLeaf.C
|
|
||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
#ifndef octreeDataPointTreeLeaf_H
|
|
||||||
#define octreeDataPointTreeLeaf_H
|
|
||||||
|
|
||||||
#include "treeLeaf.H"
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
namespace Foam
|
|
||||||
{
|
|
||||||
|
|
||||||
// Forward declaration of classes
|
|
||||||
class octreeDataPoint;
|
|
||||||
|
|
||||||
template<>
|
|
||||||
label treeLeaf<octreeDataPoint>::find
|
|
||||||
(
|
|
||||||
const octreeDataPoint& shapes,
|
|
||||||
const point& sample
|
|
||||||
) const;
|
|
||||||
|
|
||||||
|
|
||||||
template<>
|
|
||||||
bool treeLeaf<octreeDataPoint>::findNearest
|
|
||||||
(
|
|
||||||
const octreeDataPoint& shapes,
|
|
||||||
const point& sample,
|
|
||||||
treeBoundBox& tightest,
|
|
||||||
label& tightestI,
|
|
||||||
scalar& tightestDist
|
|
||||||
) const;
|
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
} // End namespace Foam
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
|
||||||
@ -1,180 +0,0 @@
|
|||||||
/*---------------------------------------------------------------------------*\
|
|
||||||
========= |
|
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
|
||||||
\\ / O peration |
|
|
||||||
\\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
|
|
||||||
\\/ M anipulation |
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
License
|
|
||||||
This file is part of OpenFOAM.
|
|
||||||
|
|
||||||
OpenFOAM is free software: you can redistribute it and/or modify it
|
|
||||||
under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
|
||||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
||||||
for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
#include "octreeLine.H"
|
|
||||||
#include "octree.H"
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
|
||||||
|
|
||||||
// Calculate sorted list of intersections
|
|
||||||
template <class Type>
|
|
||||||
void Foam::octreeLine<Type>::calcSortedIntersections()
|
|
||||||
{
|
|
||||||
// Determine intersections and sort acc. to distance to start
|
|
||||||
|
|
||||||
const labelList& indices = currentLeaf_->indices();
|
|
||||||
|
|
||||||
sortedIntersections_.setSize(indices.size());
|
|
||||||
|
|
||||||
const vector direction = endPoint_ - realStartPoint_;
|
|
||||||
|
|
||||||
label nHits = 0;
|
|
||||||
|
|
||||||
forAll(indices, elemI)
|
|
||||||
{
|
|
||||||
point pt;
|
|
||||||
bool hit = tree_.shapes().intersects
|
|
||||||
(
|
|
||||||
indices[elemI],
|
|
||||||
realStartPoint_,
|
|
||||||
direction,
|
|
||||||
pt
|
|
||||||
);
|
|
||||||
|
|
||||||
if (hit && (indices[elemI] != lastElem_))
|
|
||||||
{
|
|
||||||
sortedIntersections_[nHits++] = pointHitSort
|
|
||||||
(
|
|
||||||
pointHit
|
|
||||||
(
|
|
||||||
true,
|
|
||||||
pt,
|
|
||||||
Foam::magSqr(pt - leafExitPoint_),
|
|
||||||
false
|
|
||||||
),
|
|
||||||
indices[elemI]
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
sortedIntersections_.setSize(nHits);
|
|
||||||
|
|
||||||
Foam::sort(sortedIntersections_);
|
|
||||||
|
|
||||||
//// After sorting
|
|
||||||
//forAll(sortedIntersections_, i)
|
|
||||||
//{
|
|
||||||
// Pout<< "calcSortedIntersections: After sorting:"
|
|
||||||
// << i << " distance:"
|
|
||||||
// << sortedIntersections_[i].inter().distance()
|
|
||||||
// << " index:" << sortedIntersections_[i].index()
|
|
||||||
// << endl;
|
|
||||||
//}
|
|
||||||
|
|
||||||
lastElem_ = -1;
|
|
||||||
|
|
||||||
if (nHits > 0)
|
|
||||||
{
|
|
||||||
lastElem_ = sortedIntersections_[nHits - 1].index();
|
|
||||||
|
|
||||||
//Pout<< "Storing lastElem_:" << lastElem_ << endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Reset index into sortedIntersections_
|
|
||||||
sortedI_ = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Searches for leaf with intersected elements. Return true if found; false
|
|
||||||
// otherwise. Sets currentLeaf_ and sortedIntersections_.
|
|
||||||
template <class Type>
|
|
||||||
bool Foam::octreeLine<Type>::getNextLeaf()
|
|
||||||
{
|
|
||||||
do
|
|
||||||
{
|
|
||||||
// No current leaf. Find first one.
|
|
||||||
// Note: search starts from top every time
|
|
||||||
|
|
||||||
point start(leafExitPoint_);
|
|
||||||
currentLeaf_ = tree_.findLeafLine(start, endPoint_, leafExitPoint_);
|
|
||||||
|
|
||||||
if (!currentLeaf_)
|
|
||||||
{
|
|
||||||
// No leaf found. Give up.
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get intersections and sort.
|
|
||||||
calcSortedIntersections();
|
|
||||||
}
|
|
||||||
while (sortedIntersections_.empty());
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
template <class Type>
|
|
||||||
Foam::octreeLine<Type>::octreeLine
|
|
||||||
(
|
|
||||||
const octree<Type>& tree,
|
|
||||||
const point& startPoint,
|
|
||||||
const point& endPoint
|
|
||||||
)
|
|
||||||
:
|
|
||||||
tree_(tree),
|
|
||||||
startPoint_(startPoint),
|
|
||||||
endPoint_(endPoint),
|
|
||||||
realStartPoint_(startPoint),
|
|
||||||
leafExitPoint_(startPoint_),
|
|
||||||
currentLeaf_(NULL),
|
|
||||||
sortedIntersections_(0),
|
|
||||||
lastElem_(-1),
|
|
||||||
sortedI_(-1)
|
|
||||||
{}
|
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
template <class Type>
|
|
||||||
Foam::octreeLine<Type>::~octreeLine()
|
|
||||||
{}
|
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
template <class Type>
|
|
||||||
bool Foam::octreeLine<Type>::getIntersection()
|
|
||||||
{
|
|
||||||
// Go to next element in sortedIntersections
|
|
||||||
|
|
||||||
sortedI_++;
|
|
||||||
|
|
||||||
if (sortedI_ >= sortedIntersections_.size())
|
|
||||||
{
|
|
||||||
// Past all sortedIntersections in current leaf. Go to next one.
|
|
||||||
if (!getNextLeaf())
|
|
||||||
{
|
|
||||||
// No valid leaf found
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
sortedI_ = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
|
||||||
@ -1,193 +0,0 @@
|
|||||||
/*---------------------------------------------------------------------------*\
|
|
||||||
========= |
|
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
|
||||||
\\ / O peration |
|
|
||||||
\\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
|
|
||||||
\\/ M anipulation |
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
License
|
|
||||||
This file is part of OpenFOAM.
|
|
||||||
|
|
||||||
OpenFOAM is free software: you can redistribute it and/or modify it
|
|
||||||
under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
|
||||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
||||||
for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
Class
|
|
||||||
Foam::octreeLine
|
|
||||||
|
|
||||||
Description
|
|
||||||
Iterates over intersections of line with octree leaf elements.
|
|
||||||
|
|
||||||
Used as in
|
|
||||||
\code
|
|
||||||
octree<octreeDataFace> oc( .. );
|
|
||||||
|
|
||||||
octreeLine<octreeDataFace> lineSearch(oc, pStart, pEnd);
|
|
||||||
|
|
||||||
while (lineSearch.getIntersection())
|
|
||||||
{
|
|
||||||
const point& pt = lineSearch.hitInfo().hitPoint();
|
|
||||||
..
|
|
||||||
}
|
|
||||||
\endcode
|
|
||||||
|
|
||||||
SourceFiles
|
|
||||||
octreeLine.C
|
|
||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
#ifndef octreeLine_H
|
|
||||||
#define octreeLine_H
|
|
||||||
|
|
||||||
#include "boolList.H"
|
|
||||||
#include "point.H"
|
|
||||||
#include "pointHitSort.H"
|
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
namespace Foam
|
|
||||||
{
|
|
||||||
|
|
||||||
// Forward declaration of classes
|
|
||||||
template<class Type> class octree;
|
|
||||||
template<class Type> class treeLeaf;
|
|
||||||
|
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*\
|
|
||||||
Class octreeLine Declaration
|
|
||||||
\*---------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
template <class Type>
|
|
||||||
class octreeLine
|
|
||||||
{
|
|
||||||
// Private data
|
|
||||||
|
|
||||||
//- Octree reference
|
|
||||||
const octree<Type>& tree_;
|
|
||||||
|
|
||||||
//- Start of segment
|
|
||||||
const point startPoint_;
|
|
||||||
|
|
||||||
//- End of segment
|
|
||||||
const point endPoint_;
|
|
||||||
|
|
||||||
//- Start moved into bb
|
|
||||||
point realStartPoint_;
|
|
||||||
|
|
||||||
//- Exit point of intersection with current treeLeaf
|
|
||||||
point leafExitPoint_;
|
|
||||||
|
|
||||||
//- Current treeLeaf to be searched in.
|
|
||||||
const treeLeaf<Type>* currentLeaf_;
|
|
||||||
|
|
||||||
//- Sorted list of intersections
|
|
||||||
List<pointHitSort> sortedIntersections_;
|
|
||||||
|
|
||||||
//- index of last hit in previous treeLeaf. Used so if shape double
|
|
||||||
// it does not get counted twice. Note is not ok for concave shapes
|
|
||||||
label lastElem_;
|
|
||||||
|
|
||||||
//- Current hit: index in sortedIntersections_
|
|
||||||
label sortedI_;
|
|
||||||
|
|
||||||
// Private Member Functions
|
|
||||||
|
|
||||||
//- Calculate sorted list of intersections
|
|
||||||
void calcSortedIntersections();
|
|
||||||
|
|
||||||
//- Searches for leaf with intersected elements.
|
|
||||||
// Return true if found; false otherwise.
|
|
||||||
// Sets currentLeaf_ and sortedIntersections_
|
|
||||||
bool getNextLeaf();
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
// Constructors
|
|
||||||
|
|
||||||
//- Construct from components
|
|
||||||
octreeLine
|
|
||||||
(
|
|
||||||
const octree<Type>& tree,
|
|
||||||
const point& startPoint,
|
|
||||||
const point& endPoint
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
//- Destructor
|
|
||||||
~octreeLine();
|
|
||||||
|
|
||||||
|
|
||||||
// Member Functions
|
|
||||||
|
|
||||||
const octree<Type>& tree() const
|
|
||||||
{
|
|
||||||
return tree_;
|
|
||||||
}
|
|
||||||
|
|
||||||
const point& leafExitPoint() const
|
|
||||||
{
|
|
||||||
return leafExitPoint_;
|
|
||||||
}
|
|
||||||
|
|
||||||
const point& endPoint() const
|
|
||||||
{
|
|
||||||
return endPoint_;
|
|
||||||
}
|
|
||||||
|
|
||||||
const point& startPoint() const
|
|
||||||
{
|
|
||||||
return startPoint_;
|
|
||||||
}
|
|
||||||
|
|
||||||
const treeLeaf<Type>* currentLeaf() const
|
|
||||||
{
|
|
||||||
return currentLeaf_;
|
|
||||||
}
|
|
||||||
|
|
||||||
const List<pointHitSort>& sortedIntersections() const
|
|
||||||
{
|
|
||||||
return sortedIntersections_;
|
|
||||||
}
|
|
||||||
|
|
||||||
label hitIndex() const
|
|
||||||
{
|
|
||||||
return sortedIntersections_[sortedI_].index();
|
|
||||||
}
|
|
||||||
|
|
||||||
const pointHit& hitInfo() const
|
|
||||||
{
|
|
||||||
return sortedIntersections_[sortedI_].inter();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//- go to next intersection. Return false if no intersections.
|
|
||||||
bool getIntersection();
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
} // End namespace Foam
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
#ifdef NoRepository
|
|
||||||
# include "octreeLine.C"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
|
||||||
@ -1,32 +0,0 @@
|
|||||||
/*---------------------------------------------------------------------------*\
|
|
||||||
========= |
|
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
|
||||||
\\ / O peration |
|
|
||||||
\\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
|
|
||||||
\\/ M anipulation |
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
License
|
|
||||||
This file is part of OpenFOAM.
|
|
||||||
|
|
||||||
OpenFOAM is free software: you can redistribute it and/or modify it
|
|
||||||
under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
|
||||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
||||||
for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
#include "octree.H"
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
defineTypeNameAndDebug(Foam::octreeName, 0);
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
|
||||||
@ -1,95 +0,0 @@
|
|||||||
/*---------------------------------------------------------------------------*\
|
|
||||||
========= |
|
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
|
||||||
\\ / O peration |
|
|
||||||
\\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
|
|
||||||
\\/ M anipulation |
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
License
|
|
||||||
This file is part of OpenFOAM.
|
|
||||||
|
|
||||||
OpenFOAM is free software: you can redistribute it and/or modify it
|
|
||||||
under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
|
||||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
||||||
for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
Class
|
|
||||||
Foam::treeElem
|
|
||||||
|
|
||||||
Description
|
|
||||||
Common functionality of treeNode and treeLeaf.
|
|
||||||
|
|
||||||
SourceFiles
|
|
||||||
treeElem.C
|
|
||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
#ifndef treeElem_H
|
|
||||||
#define treeElem_H
|
|
||||||
|
|
||||||
#include "treeBoundBox.H"
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
namespace Foam
|
|
||||||
{
|
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*\
|
|
||||||
Class treeElem Declaration
|
|
||||||
\*---------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
template <class Type>
|
|
||||||
class treeElem
|
|
||||||
{
|
|
||||||
// Private data
|
|
||||||
|
|
||||||
//- Bounding box of this node
|
|
||||||
treeBoundBox bb_;
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
// Constructors
|
|
||||||
|
|
||||||
//- Construct from bounding box
|
|
||||||
treeElem(const treeBoundBox& bb)
|
|
||||||
:
|
|
||||||
bb_(bb)
|
|
||||||
{}
|
|
||||||
|
|
||||||
|
|
||||||
// Member Functions
|
|
||||||
|
|
||||||
// Access
|
|
||||||
|
|
||||||
//- Bounding box of this node
|
|
||||||
const treeBoundBox& bb() const
|
|
||||||
{
|
|
||||||
return bb_;
|
|
||||||
}
|
|
||||||
|
|
||||||
//- Bounding box of this node
|
|
||||||
treeBoundBox& bb()
|
|
||||||
{
|
|
||||||
return bb_;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
} // End namespace Foam
|
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
|
||||||
@ -1,466 +0,0 @@
|
|||||||
/*---------------------------------------------------------------------------*\
|
|
||||||
========= |
|
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
|
||||||
\\ / O peration |
|
|
||||||
\\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
|
|
||||||
\\/ M anipulation |
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
License
|
|
||||||
This file is part of OpenFOAM.
|
|
||||||
|
|
||||||
OpenFOAM is free software: you can redistribute it and/or modify it
|
|
||||||
under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
|
||||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
||||||
for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
#include "treeLeaf.H"
|
|
||||||
#include "treeNode.H"
|
|
||||||
#include "treeBoundBox.H"
|
|
||||||
#include "octree.H"
|
|
||||||
#include "HashSet.H"
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
|
||||||
|
|
||||||
template <class Type>
|
|
||||||
void Foam::treeLeaf<Type>::space(Ostream& os, const label n)
|
|
||||||
{
|
|
||||||
for (label i=0; i<n; i++)
|
|
||||||
{
|
|
||||||
os << ' ';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
// Construct with given size
|
|
||||||
template <class Type>
|
|
||||||
Foam::treeLeaf<Type>::treeLeaf(const treeBoundBox& bb, const label size)
|
|
||||||
:
|
|
||||||
treeElem<Type>(bb), size_(0), indices_(size)
|
|
||||||
{}
|
|
||||||
|
|
||||||
|
|
||||||
// Construct from list
|
|
||||||
template <class Type>
|
|
||||||
Foam::treeLeaf<Type>::treeLeaf(const treeBoundBox& bb, const labelList& indices)
|
|
||||||
:
|
|
||||||
treeElem<Type>(bb), size_(indices.size()), indices_(indices)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Construct from Istream
|
|
||||||
template <class Type>
|
|
||||||
Foam::treeLeaf<Type>::treeLeaf(Istream& is)
|
|
||||||
{
|
|
||||||
is >> *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
template <class Type>
|
|
||||||
Foam::treeLeaf<Type>::~treeLeaf()
|
|
||||||
{}
|
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
// Take cells at this level and distribute them to lower levels
|
|
||||||
template <class Type>
|
|
||||||
Foam::treeLeaf<Type>* Foam::treeLeaf<Type>::redistribute
|
|
||||||
(
|
|
||||||
const label level,
|
|
||||||
octree<Type>& top,
|
|
||||||
const Type& shapes
|
|
||||||
)
|
|
||||||
{
|
|
||||||
if (debug & 1)
|
|
||||||
{
|
|
||||||
space(Pout, level);
|
|
||||||
Pout<< "treeLeaf::redistribute with bb:" << this->bb() << endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (size_ <= top.maxLeafRatio())
|
|
||||||
{
|
|
||||||
// leaf small enough
|
|
||||||
if (debug & 1)
|
|
||||||
{
|
|
||||||
space(Pout, level);
|
|
||||||
Pout<< "end of treeLeaf::redistribute : small enough" << endl;
|
|
||||||
}
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// create treeNode for this level
|
|
||||||
treeNode<Type>* treeNodePtr = new treeNode<Type>(this->bb());
|
|
||||||
|
|
||||||
top.setNodes(top.nNodes() + 1);
|
|
||||||
|
|
||||||
treeNodePtr->distribute
|
|
||||||
(
|
|
||||||
level,
|
|
||||||
top,
|
|
||||||
shapes,
|
|
||||||
indices_
|
|
||||||
);
|
|
||||||
|
|
||||||
if (debug & 1)
|
|
||||||
{
|
|
||||||
space(Pout, level);
|
|
||||||
Pout<< "end of treeLeaf::redistribute : done creating node"
|
|
||||||
<< this->bb() << endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
// return pointer to let level above know.
|
|
||||||
return reinterpret_cast<treeLeaf<Type>*>(treeNodePtr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Set type of subnodes. Since contains elements return mixed type always.
|
|
||||||
template <class Type>
|
|
||||||
Foam::label Foam::treeLeaf<Type>::setSubNodeType
|
|
||||||
(
|
|
||||||
const label level,
|
|
||||||
octree<Type>& top,
|
|
||||||
const Type& shapes
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
if (size() == 0)
|
|
||||||
{
|
|
||||||
FatalErrorIn
|
|
||||||
(
|
|
||||||
"treeLeaf<Type>::setSubNodeType(const label, octree<Type>&, "
|
|
||||||
"const Type&)"
|
|
||||||
) << "empty leaf. bb:" << this->bb()
|
|
||||||
<< abort(FatalError);
|
|
||||||
}
|
|
||||||
return octree<Type>::MIXED;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template <class Type>
|
|
||||||
Foam::label Foam::treeLeaf<Type>::getSampleType
|
|
||||||
(
|
|
||||||
const label level,
|
|
||||||
const octree<Type>& top,
|
|
||||||
const Type& shapes,
|
|
||||||
const point& sample
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
return shapes.getSampleType(top, sample);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template <class Type>
|
|
||||||
Foam::label Foam::treeLeaf<Type>::find
|
|
||||||
(
|
|
||||||
const Type& shapes,
|
|
||||||
const point& sample
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
forAll(indices_, i)
|
|
||||||
{
|
|
||||||
if (shapes.contains(indices_[i], sample))
|
|
||||||
{
|
|
||||||
return indices_[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template <class Type>
|
|
||||||
bool Foam::treeLeaf<Type>::findTightest
|
|
||||||
(
|
|
||||||
const Type& shapes,
|
|
||||||
const point& sample,
|
|
||||||
treeBoundBox& tightest
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
bool changed = false;
|
|
||||||
|
|
||||||
forAll(indices_, i)
|
|
||||||
{
|
|
||||||
changed |= shapes.findTightest
|
|
||||||
(
|
|
||||||
indices_[i],
|
|
||||||
sample,
|
|
||||||
tightest
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return changed;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template <class Type>
|
|
||||||
bool Foam::treeLeaf<Type>::findNearest
|
|
||||||
(
|
|
||||||
const Type& shapes,
|
|
||||||
const point& sample,
|
|
||||||
treeBoundBox& tightest,
|
|
||||||
label& tightestI,
|
|
||||||
scalar& tightestDist
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
bool changed = false;
|
|
||||||
|
|
||||||
forAll(indices_, i)
|
|
||||||
{
|
|
||||||
if (shapes.overlaps(indices_[i], tightest))
|
|
||||||
{
|
|
||||||
if (debug & 8)
|
|
||||||
{
|
|
||||||
//space(Pout, level);
|
|
||||||
Pout<< "treeLeaf<Type>::findNearest : sample:" << sample
|
|
||||||
<< " shape:" << indices_[i] << " overlaps:" << tightest
|
|
||||||
<< endl;
|
|
||||||
}
|
|
||||||
point nearest;
|
|
||||||
scalar thisDist = shapes.calcNearest(indices_[i], sample, nearest);
|
|
||||||
|
|
||||||
if (thisDist < tightestDist)
|
|
||||||
{
|
|
||||||
// Construct new tightest Bb
|
|
||||||
point dist(thisDist, thisDist, thisDist);
|
|
||||||
|
|
||||||
tightest.min() = sample - dist;
|
|
||||||
tightest.max() = sample + dist;
|
|
||||||
|
|
||||||
// Update other return values
|
|
||||||
tightestI = indices_[i];
|
|
||||||
|
|
||||||
tightestDist = thisDist;
|
|
||||||
|
|
||||||
changed = true;
|
|
||||||
|
|
||||||
if (debug & 8)
|
|
||||||
{
|
|
||||||
//space(Pout, level);
|
|
||||||
Pout<< "treeLeaf<Type>::findNearest : Found nearer : shape:"
|
|
||||||
<< tightestI << " distance:" << tightestDist
|
|
||||||
<< " to sample:" << sample << endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (changed)
|
|
||||||
{
|
|
||||||
if (debug & 8)
|
|
||||||
{
|
|
||||||
//space(Pout, level);
|
|
||||||
Pout<< "treeLeaf<Type>::findNearest : sample:" << sample
|
|
||||||
<< " new nearer:" << tightestDist
|
|
||||||
<< endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return changed;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template <class Type>
|
|
||||||
bool Foam::treeLeaf<Type>::findNearest
|
|
||||||
(
|
|
||||||
const Type& shapes,
|
|
||||||
const linePointRef& ln,
|
|
||||||
treeBoundBox& tightest,
|
|
||||||
label& tightestI,
|
|
||||||
point& linePoint, // nearest point on line
|
|
||||||
point& shapePoint // nearest point on shape
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
// Initial smallest distance
|
|
||||||
scalar tightestDist = mag(linePoint - shapePoint);
|
|
||||||
|
|
||||||
bool changed = false;
|
|
||||||
|
|
||||||
forAll(indices_, i)
|
|
||||||
{
|
|
||||||
if (shapes.overlaps(indices_[i], tightest))
|
|
||||||
{
|
|
||||||
// Calculate nearest point on line and on shape.
|
|
||||||
point linePt, shapePt;
|
|
||||||
scalar thisDist = shapes.calcNearest
|
|
||||||
(
|
|
||||||
indices_[i],
|
|
||||||
ln,
|
|
||||||
linePt,
|
|
||||||
shapePt
|
|
||||||
);
|
|
||||||
|
|
||||||
if (thisDist < tightestDist)
|
|
||||||
{
|
|
||||||
// Found nearer. Use.
|
|
||||||
tightestDist = thisDist;
|
|
||||||
tightestI = indices_[i];
|
|
||||||
linePoint = linePt;
|
|
||||||
shapePoint = shapePt;
|
|
||||||
// Construct new tightest Bb. Nearest point can never be further
|
|
||||||
// away than bounding box of line + margin equal to the distance
|
|
||||||
vector span(thisDist, thisDist, thisDist);
|
|
||||||
|
|
||||||
tightest.min() = min(ln.start(), ln.end()) - span;
|
|
||||||
tightest.max() = max(ln.start(), ln.end()) + span;
|
|
||||||
|
|
||||||
changed = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return changed;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template <class Type>
|
|
||||||
bool Foam::treeLeaf<Type>::findBox
|
|
||||||
(
|
|
||||||
const Type& shapes,
|
|
||||||
const boundBox& box,
|
|
||||||
labelHashSet& elements
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
bool changed = false;
|
|
||||||
|
|
||||||
forAll(indices_, i)
|
|
||||||
{
|
|
||||||
if (shapes.overlaps(indices_[i], box))
|
|
||||||
{
|
|
||||||
elements.insert(indices_[i]);
|
|
||||||
|
|
||||||
changed = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return changed;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template <class Type>
|
|
||||||
void Foam::treeLeaf<Type>::printLeaf
|
|
||||||
(
|
|
||||||
Ostream& os,
|
|
||||||
const label level
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
space(os, level);
|
|
||||||
|
|
||||||
os << "leaf:" << this->bb()
|
|
||||||
<< " number of entries:" << indices().size() << endl;
|
|
||||||
|
|
||||||
space(os, level);
|
|
||||||
|
|
||||||
os << indices() << endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Dump cube coordinates in OBJ format
|
|
||||||
template <class Type>
|
|
||||||
void Foam::treeLeaf<Type>::writeOBJ
|
|
||||||
(
|
|
||||||
Ostream& os,
|
|
||||||
const label level,
|
|
||||||
label& vertNo
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
point min = this->bb().min();
|
|
||||||
point max = this->bb().max();
|
|
||||||
|
|
||||||
os << "v " << min.x() << " " << min.y() << " " << min.z() << endl;
|
|
||||||
os << "v " << max.x() << " " << min.y() << " " << min.z() << endl;
|
|
||||||
os << "v " << max.x() << " " << max.y() << " " << min.z() << endl;
|
|
||||||
os << "v " << min.x() << " " << max.y() << " " << min.z() << endl;
|
|
||||||
|
|
||||||
os << "v " << min.x() << " " << min.y() << " " << max.z() << endl;
|
|
||||||
os << "v " << max.x() << " " << min.y() << " " << max.z() << endl;
|
|
||||||
os << "v " << max.x() << " " << max.y() << " " << max.z() << endl;
|
|
||||||
os << "v " << min.x() << " " << max.y() << " " << max.z() << endl;
|
|
||||||
|
|
||||||
os << "l " << vertNo << " " << vertNo+1 << endl;
|
|
||||||
os << "l " << vertNo+1 << " " << vertNo+2 << endl;
|
|
||||||
os << "l " << vertNo+2 << " " << vertNo+3 << endl;
|
|
||||||
os << "l " << vertNo+3 << " " << vertNo << endl;
|
|
||||||
|
|
||||||
os << "l " << vertNo+4 << " " << vertNo+5 << endl;
|
|
||||||
os << "l " << vertNo+5 << " " << vertNo+6 << endl;
|
|
||||||
os << "l " << vertNo+6 << " " << vertNo+7 << endl;
|
|
||||||
os << "l " << vertNo+7 << " " << vertNo << endl;
|
|
||||||
|
|
||||||
os << "l " << vertNo << " " << vertNo+4 << endl;
|
|
||||||
os << "l " << vertNo+1 << " " << vertNo+5 << endl;
|
|
||||||
os << "l " << vertNo+2 << " " << vertNo+6 << endl;
|
|
||||||
os << "l " << vertNo+3 << " " << vertNo+7 << endl;
|
|
||||||
|
|
||||||
vertNo += 8;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template <class Type>
|
|
||||||
Foam::label Foam::treeLeaf<Type>::countLeaf
|
|
||||||
(
|
|
||||||
Ostream& os,
|
|
||||||
const label level
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
label nItems = size();
|
|
||||||
|
|
||||||
space(os, level);
|
|
||||||
|
|
||||||
os << "leaf:" << this->bb() << " has size:" << nItems << endl;
|
|
||||||
|
|
||||||
return nItems;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * Friend Operators * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
template <class Type>
|
|
||||||
Foam::Istream& Foam::operator>> (Istream& is, treeLeaf<Type>& leaf)
|
|
||||||
{
|
|
||||||
is >> leaf.bb() >> leaf.indices_;
|
|
||||||
|
|
||||||
// Was written trimmed
|
|
||||||
leaf.size_ = leaf.indices_.size();
|
|
||||||
return is;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template <class Type>
|
|
||||||
Foam::Ostream& Foam::operator<< (Ostream& os, const treeLeaf<Type>& leaf)
|
|
||||||
{
|
|
||||||
os << leaf.bb();
|
|
||||||
|
|
||||||
if (leaf.indices().size() == leaf.size())
|
|
||||||
{
|
|
||||||
os << leaf.indices();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Storage not trimmed
|
|
||||||
os << token::SPACE << leaf.size() << token::SPACE << token::BEGIN_LIST;
|
|
||||||
forAll(leaf, i)
|
|
||||||
{
|
|
||||||
os << token::SPACE << leaf.indices()[i];
|
|
||||||
}
|
|
||||||
os << token::END_LIST;
|
|
||||||
}
|
|
||||||
return os;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
|
||||||
@ -1,283 +0,0 @@
|
|||||||
/*---------------------------------------------------------------------------*\
|
|
||||||
========= |
|
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
|
||||||
\\ / O peration |
|
|
||||||
\\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
|
|
||||||
\\/ M anipulation |
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
License
|
|
||||||
This file is part of OpenFOAM.
|
|
||||||
|
|
||||||
OpenFOAM is free software: you can redistribute it and/or modify it
|
|
||||||
under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
|
||||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
||||||
for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
Class
|
|
||||||
Foam::treeLeaf
|
|
||||||
|
|
||||||
Description
|
|
||||||
An octree treeLeaf.
|
|
||||||
|
|
||||||
SourceFiles
|
|
||||||
treeLeaf.C
|
|
||||||
octreeDataPointTreaLeaf.H (specialization for points)
|
|
||||||
octreeDataPointTreeLeaf.C
|
|
||||||
octreeDataTriSurfaceTreeLeaf.H (specialization for triSurface)
|
|
||||||
octreeDataTriSurfaceTreeLeaf.C
|
|
||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
#ifndef treeLeaf_H
|
|
||||||
#define treeLeaf_H
|
|
||||||
|
|
||||||
#include "labelList.H"
|
|
||||||
#include "treeElem.H"
|
|
||||||
#include "boolList.H"
|
|
||||||
#include "linePointRef.H"
|
|
||||||
#include "HashSet.H"
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
namespace Foam
|
|
||||||
{
|
|
||||||
|
|
||||||
class treeBoundBox;
|
|
||||||
class Ostream;
|
|
||||||
|
|
||||||
template<class Type> class octree;
|
|
||||||
template<class Type> class treeLeaf;
|
|
||||||
|
|
||||||
// Forward declaration of friend functions and operators
|
|
||||||
|
|
||||||
template<class Type> Istream& operator>>(Istream&, treeLeaf<Type>&);
|
|
||||||
template<class Type> Ostream& operator<<(Ostream&, const treeLeaf<Type>&);
|
|
||||||
|
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*\
|
|
||||||
Class treeLeafName Declaration
|
|
||||||
\*---------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
TemplateName(treeLeaf);
|
|
||||||
|
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*\
|
|
||||||
Class treeLeaf Declaration
|
|
||||||
\*---------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
template <class Type>
|
|
||||||
class treeLeaf
|
|
||||||
:
|
|
||||||
public treeElem<Type>,
|
|
||||||
public treeLeafName
|
|
||||||
{
|
|
||||||
// Private data
|
|
||||||
|
|
||||||
// Keeps real size (at construction time indices_ might be untrimmed)
|
|
||||||
label size_;
|
|
||||||
|
|
||||||
// Indices of 'things' whose bb overlaps leaf bb.
|
|
||||||
labelList indices_;
|
|
||||||
|
|
||||||
|
|
||||||
// Private Member Functions
|
|
||||||
|
|
||||||
static void space(Ostream&, const label);
|
|
||||||
|
|
||||||
//- Disallow default bitwise copy construct
|
|
||||||
treeLeaf(const treeLeaf&);
|
|
||||||
|
|
||||||
//- Disallow default bitwise assignment
|
|
||||||
void operator=(const treeLeaf&);
|
|
||||||
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
// Constructors
|
|
||||||
|
|
||||||
//- Construct with size
|
|
||||||
treeLeaf(const treeBoundBox& bb, const label size);
|
|
||||||
|
|
||||||
//- Construct from list
|
|
||||||
treeLeaf(const treeBoundBox& bb, const labelList& indices);
|
|
||||||
|
|
||||||
//- Construct from Istream
|
|
||||||
treeLeaf(Istream&);
|
|
||||||
|
|
||||||
|
|
||||||
//- Destructor
|
|
||||||
~treeLeaf();
|
|
||||||
|
|
||||||
|
|
||||||
// Member Functions
|
|
||||||
|
|
||||||
// Access
|
|
||||||
|
|
||||||
label size() const
|
|
||||||
{
|
|
||||||
return size_;
|
|
||||||
}
|
|
||||||
|
|
||||||
const labelList& indices() const
|
|
||||||
{
|
|
||||||
return indices_;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Edit
|
|
||||||
|
|
||||||
void insert(const label index)
|
|
||||||
{
|
|
||||||
if (size_ >= indices_.size())
|
|
||||||
{
|
|
||||||
FatalErrorIn
|
|
||||||
(
|
|
||||||
"treeLeaf<Type>::insert(index)"
|
|
||||||
)
|
|
||||||
<< "overflow"
|
|
||||||
<< " size_ :" << size_
|
|
||||||
<< " size():" << indices_.size()
|
|
||||||
<< abort(FatalError);
|
|
||||||
}
|
|
||||||
indices_[size_++] = index;
|
|
||||||
}
|
|
||||||
|
|
||||||
void trim()
|
|
||||||
{
|
|
||||||
if (size_ == 0)
|
|
||||||
{
|
|
||||||
FatalErrorIn
|
|
||||||
(
|
|
||||||
"treeLeaf<Type>::trim()"
|
|
||||||
)
|
|
||||||
<< "Trying to trim empty leaf: " << endl
|
|
||||||
<< " size_ :" << size_
|
|
||||||
<< " size():" << indices_.size()
|
|
||||||
<< abort(FatalError);
|
|
||||||
}
|
|
||||||
indices_.setSize(size_);
|
|
||||||
}
|
|
||||||
|
|
||||||
//- Take indices at refineLevel and distribute them to lower levels
|
|
||||||
treeLeaf<Type>* redistribute
|
|
||||||
(
|
|
||||||
const label,
|
|
||||||
octree<Type>&,
|
|
||||||
const Type&
|
|
||||||
);
|
|
||||||
|
|
||||||
label setSubNodeType
|
|
||||||
(
|
|
||||||
const label level,
|
|
||||||
octree<Type>& top,
|
|
||||||
const Type& shapes
|
|
||||||
) const;
|
|
||||||
|
|
||||||
// Search
|
|
||||||
|
|
||||||
//- Get type of sample
|
|
||||||
label getSampleType
|
|
||||||
(
|
|
||||||
const label level,
|
|
||||||
const octree<Type>& top,
|
|
||||||
const Type& shapes,
|
|
||||||
const point& sample
|
|
||||||
) const;
|
|
||||||
|
|
||||||
//- Find index of shape containing sample
|
|
||||||
label find
|
|
||||||
(
|
|
||||||
const Type& shapes,
|
|
||||||
const point& sample
|
|
||||||
) const;
|
|
||||||
|
|
||||||
//- Find tightest fitting bounding box in leaf
|
|
||||||
bool findTightest
|
|
||||||
(
|
|
||||||
const Type& shapes,
|
|
||||||
const point& sample,
|
|
||||||
treeBoundBox& tightest
|
|
||||||
) const;
|
|
||||||
|
|
||||||
//- Find nearest point.
|
|
||||||
bool findNearest
|
|
||||||
(
|
|
||||||
const Type& shapes,
|
|
||||||
const point& sample,
|
|
||||||
treeBoundBox& tightest,
|
|
||||||
label& tightestI,
|
|
||||||
scalar& tightestDist
|
|
||||||
) const;
|
|
||||||
|
|
||||||
//- Find nearest shape to line
|
|
||||||
// Returns true if found nearer shape and updates nearest and
|
|
||||||
// tightest
|
|
||||||
bool findNearest
|
|
||||||
(
|
|
||||||
const Type& shapes,
|
|
||||||
const linePointRef& ln,
|
|
||||||
treeBoundBox& tightest,
|
|
||||||
label& tightestI, // index of nearest shape
|
|
||||||
point& linePoint, // nearest point on line
|
|
||||||
point& shapePoint // nearest point on shape
|
|
||||||
) const;
|
|
||||||
|
|
||||||
//- Find shapes not outside box. Return true if anything found.
|
|
||||||
bool findBox
|
|
||||||
(
|
|
||||||
const Type& shapes,
|
|
||||||
const boundBox& bb,
|
|
||||||
labelHashSet& elements
|
|
||||||
) const;
|
|
||||||
|
|
||||||
// Write
|
|
||||||
|
|
||||||
//- Debug: print a leaf
|
|
||||||
void printLeaf(Ostream&, const label) const;
|
|
||||||
|
|
||||||
//- Debug: Write bb in OBJ format
|
|
||||||
void writeOBJ
|
|
||||||
(
|
|
||||||
Ostream& os,
|
|
||||||
const label level,
|
|
||||||
label& vertNo
|
|
||||||
) const;
|
|
||||||
|
|
||||||
//- debug:
|
|
||||||
label countLeaf(Ostream&, const label) const;
|
|
||||||
|
|
||||||
|
|
||||||
// IOstream Operators
|
|
||||||
|
|
||||||
friend Istream& operator>> <Type>(Istream&, treeLeaf<Type>&);
|
|
||||||
friend Ostream& operator<< <Type>(Ostream&, const treeLeaf<Type>&);
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
} // End namespace Foam
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
#ifdef NoRepository
|
|
||||||
# include "treeLeaf.C"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
#include "octreeDataPointTreeLeaf.H"
|
|
||||||
#include "octreeDataTriSurfaceTreeLeaf.H"
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
|
||||||
@ -1,32 +0,0 @@
|
|||||||
/*---------------------------------------------------------------------------*\
|
|
||||||
========= |
|
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
|
||||||
\\ / O peration |
|
|
||||||
\\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
|
|
||||||
\\/ M anipulation |
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
License
|
|
||||||
This file is part of OpenFOAM.
|
|
||||||
|
|
||||||
OpenFOAM is free software: you can redistribute it and/or modify it
|
|
||||||
under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
|
||||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
||||||
for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
#include "treeLeaf.H"
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
defineTypeNameAndDebug(Foam::treeLeafName, 0);
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
|
||||||
File diff suppressed because it is too large
Load Diff
@ -1,345 +0,0 @@
|
|||||||
/*---------------------------------------------------------------------------*\
|
|
||||||
========= |
|
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
|
||||||
\\ / O peration |
|
|
||||||
\\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
|
|
||||||
\\/ M anipulation |
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
License
|
|
||||||
This file is part of OpenFOAM.
|
|
||||||
|
|
||||||
OpenFOAM is free software: you can redistribute it and/or modify it
|
|
||||||
under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
|
||||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
||||||
for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
Class
|
|
||||||
Foam::treeNode
|
|
||||||
|
|
||||||
Description
|
|
||||||
Class to implement octree.
|
|
||||||
|
|
||||||
Holds the pointers to sub-octants. These are either other treeNodes or
|
|
||||||
treeLeafs. The treeLeafs hold the actual data as a list of indices into
|
|
||||||
octreeData.
|
|
||||||
|
|
||||||
Note
|
|
||||||
To prevent calculation errors all bounding boxes used in octrees are
|
|
||||||
calculated only once.
|
|
||||||
|
|
||||||
The pointers to either treeNode/treeLeaf are implemented 'by hand'
|
|
||||||
(explicitly marking type) instead of using a proper virtual mechanism
|
|
||||||
to save some space in the treeLeaves.
|
|
||||||
|
|
||||||
SourceFiles
|
|
||||||
treeNode.C
|
|
||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
#ifndef treeNode_H
|
|
||||||
#define treeNode_H
|
|
||||||
|
|
||||||
#include "treeBoundBoxList.H"
|
|
||||||
#include "treeElem.H"
|
|
||||||
#include "linePointRef.H"
|
|
||||||
#include "HashSet.H"
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
namespace Foam
|
|
||||||
{
|
|
||||||
|
|
||||||
// class intersection;
|
|
||||||
|
|
||||||
template<class Type> class octree;
|
|
||||||
template<class Type> class treeLeaf;
|
|
||||||
template<class Type> class treeNode;
|
|
||||||
|
|
||||||
// Forward declaration of friend functions and operators
|
|
||||||
|
|
||||||
template<class Type> Istream& operator>>(Istream&, treeNode<Type>&);
|
|
||||||
template<class Type> Ostream& operator<<(Ostream&, const treeNode<Type>&);
|
|
||||||
|
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*\
|
|
||||||
Class treeNodeName Declaration
|
|
||||||
\*---------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
TemplateName(treeNode);
|
|
||||||
|
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*\
|
|
||||||
Class treeNode Declaration
|
|
||||||
\*---------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
template <class Type>
|
|
||||||
class treeNode
|
|
||||||
:
|
|
||||||
public treeElem<Type>,
|
|
||||||
public treeNodeName
|
|
||||||
{
|
|
||||||
// Private data
|
|
||||||
|
|
||||||
//- Position of the midpoint
|
|
||||||
const point mid_;
|
|
||||||
|
|
||||||
//- Type stored in subNodes_
|
|
||||||
unsigned char subNodeTypes_;
|
|
||||||
|
|
||||||
//- Pointers to sub treeNode or treeLeaf
|
|
||||||
treeElem<Type>* subNodes_[8];
|
|
||||||
|
|
||||||
//- Constant valid for whole subNode/leaf
|
|
||||||
label volType_;
|
|
||||||
|
|
||||||
// Static data members
|
|
||||||
|
|
||||||
//- leaf offset for octant index
|
|
||||||
static const label leafOffset;
|
|
||||||
|
|
||||||
|
|
||||||
// Private Member Functions
|
|
||||||
|
|
||||||
//- mark pointer to subnode as being a treeNode*
|
|
||||||
void setAsNode(const label octant);
|
|
||||||
|
|
||||||
//- mark pointer to subnode as being a treeLeaf*
|
|
||||||
void setAsLeaf(const label octant);
|
|
||||||
|
|
||||||
//- Set pointer to sub node
|
|
||||||
void setNodePtr(const label octant, treeElem<Type>* treeNodePtr);
|
|
||||||
|
|
||||||
//- Set pointer to sub leaf
|
|
||||||
void setLeafPtr(const label octant, treeElem<Type>* treeLeafPtr);
|
|
||||||
|
|
||||||
//- Set type of octant
|
|
||||||
void setVolType(const label octant, const label type);
|
|
||||||
|
|
||||||
//- Get type of octant
|
|
||||||
inline label getVolType(const label octant) const;
|
|
||||||
|
|
||||||
//- Find first leaf on line start-end. Updates start.
|
|
||||||
const treeLeaf<Type>* findLeafLineOctant
|
|
||||||
(
|
|
||||||
const int level,
|
|
||||||
const Type& shapes,
|
|
||||||
const label octant,
|
|
||||||
const vector& direction,
|
|
||||||
point& start,
|
|
||||||
const point& end
|
|
||||||
) const;
|
|
||||||
|
|
||||||
|
|
||||||
//- Print spaces
|
|
||||||
static void space(Ostream&, const label);
|
|
||||||
|
|
||||||
//- Disallow default bitwise copy construct
|
|
||||||
treeNode(const treeNode&);
|
|
||||||
|
|
||||||
//- Disallow default bitwise assignment
|
|
||||||
void operator=(const treeNode&);
|
|
||||||
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
// Constructors
|
|
||||||
|
|
||||||
//- Construct from components
|
|
||||||
treeNode(const treeBoundBox&);
|
|
||||||
|
|
||||||
//- Construct from Istream
|
|
||||||
treeNode(Istream&);
|
|
||||||
|
|
||||||
|
|
||||||
//- Destructor
|
|
||||||
~treeNode();
|
|
||||||
|
|
||||||
|
|
||||||
// Member Functions
|
|
||||||
|
|
||||||
// Access
|
|
||||||
|
|
||||||
//- The midpoint position
|
|
||||||
inline const point& midpoint() const;
|
|
||||||
|
|
||||||
//- array of 8 subNodes/leaves
|
|
||||||
inline treeElem<Type>* const* subNodes() const;
|
|
||||||
|
|
||||||
//- octant contains pointer to treeNode(1) or treeLeaf(0)
|
|
||||||
inline label isNode(const label octant) const;
|
|
||||||
|
|
||||||
//- Get pointer to sub node
|
|
||||||
inline treeNode<Type>* getNodePtr(const label octant) const;
|
|
||||||
|
|
||||||
//- Get pointer to sub leaf
|
|
||||||
inline treeLeaf<Type>* getLeafPtr(const label octant) const;
|
|
||||||
|
|
||||||
// Edit
|
|
||||||
|
|
||||||
//- Take list of shapes and distribute over the 8 octants
|
|
||||||
void distribute
|
|
||||||
(
|
|
||||||
const label,
|
|
||||||
octree<Type>&,
|
|
||||||
const Type& shapes,
|
|
||||||
const labelList&
|
|
||||||
);
|
|
||||||
|
|
||||||
//- Distribute at certain level only
|
|
||||||
void redistribute
|
|
||||||
(
|
|
||||||
const label,
|
|
||||||
octree<Type>&,
|
|
||||||
const Type& shapes,
|
|
||||||
const label
|
|
||||||
);
|
|
||||||
|
|
||||||
//- Set type of subnodes
|
|
||||||
label setSubNodeType
|
|
||||||
(
|
|
||||||
const label level,
|
|
||||||
octree<Type>& top,
|
|
||||||
const Type& shapes
|
|
||||||
);
|
|
||||||
|
|
||||||
// Search
|
|
||||||
|
|
||||||
//- Find type of node sample is in. Used for inside/outside
|
|
||||||
// determination
|
|
||||||
label getSampleType
|
|
||||||
(
|
|
||||||
const label level,
|
|
||||||
const octree<Type>& top,
|
|
||||||
const Type& shapes,
|
|
||||||
const point& sample
|
|
||||||
) const;
|
|
||||||
|
|
||||||
//- Find index of shape containing sample.
|
|
||||||
label find
|
|
||||||
(
|
|
||||||
const Type& shapes,
|
|
||||||
const point& sample
|
|
||||||
) const;
|
|
||||||
|
|
||||||
//- Find tightest bounding box around sample which is guaranteed
|
|
||||||
// to hold at least one cell.
|
|
||||||
// Current best bb in tightest,
|
|
||||||
// returns true if newTightest has changed, 0 otherwise.
|
|
||||||
bool findTightest
|
|
||||||
(
|
|
||||||
const Type& shapes,
|
|
||||||
const point& sample,
|
|
||||||
treeBoundBox& tightest
|
|
||||||
) const;
|
|
||||||
|
|
||||||
//- Find nearest shape to sample
|
|
||||||
// Returns true if found nearer shape and updates
|
|
||||||
// tightest, tightestI, tightestDist
|
|
||||||
bool findNearest
|
|
||||||
(
|
|
||||||
const Type& shapes,
|
|
||||||
const point& sample,
|
|
||||||
treeBoundBox& tightest,
|
|
||||||
label& tightestI,
|
|
||||||
scalar& tightestDist
|
|
||||||
) const;
|
|
||||||
|
|
||||||
//- Find nearest shape to line
|
|
||||||
// Returns true if found nearer shape and updates nearest and
|
|
||||||
// tightest
|
|
||||||
bool findNearest
|
|
||||||
(
|
|
||||||
const Type& shapes,
|
|
||||||
const linePointRef& ln,
|
|
||||||
treeBoundBox& tightest,
|
|
||||||
label& tightestI, // index of nearest shape
|
|
||||||
point& linePoint, // nearest point on line
|
|
||||||
point& shapePoint // nearest point on shape
|
|
||||||
) const;
|
|
||||||
|
|
||||||
//- Find shapes not outside box. Return true if anything found.
|
|
||||||
bool findBox
|
|
||||||
(
|
|
||||||
const Type& shapes,
|
|
||||||
const boundBox& bb,
|
|
||||||
labelHashSet& elements
|
|
||||||
) const;
|
|
||||||
|
|
||||||
//- Find treeLeaves intersecting line segment [start..end]
|
|
||||||
// Updates: start
|
|
||||||
const treeLeaf<Type>* findLeafLine
|
|
||||||
(
|
|
||||||
const label level,
|
|
||||||
const Type& shapes,
|
|
||||||
point& start,
|
|
||||||
const point& end
|
|
||||||
) const;
|
|
||||||
|
|
||||||
|
|
||||||
//- Collect all treeLeafs in leafArray. leafIndex points to first
|
|
||||||
// empty slot in leafArray and gets updated.
|
|
||||||
void findLeaves
|
|
||||||
(
|
|
||||||
List<treeLeaf<Type>*>& leafArray,
|
|
||||||
label& leafIndex
|
|
||||||
) const;
|
|
||||||
|
|
||||||
//- Same but for const.
|
|
||||||
void findLeaves
|
|
||||||
(
|
|
||||||
List<const treeLeaf<Type>*>& leafArray,
|
|
||||||
label& leafIndex
|
|
||||||
) const;
|
|
||||||
|
|
||||||
|
|
||||||
// Write
|
|
||||||
|
|
||||||
//- Print contents of node.
|
|
||||||
void printNode
|
|
||||||
(
|
|
||||||
Ostream& os,
|
|
||||||
const label level
|
|
||||||
) const;
|
|
||||||
|
|
||||||
//- Write subleafs in OBJ format.
|
|
||||||
void writeOBJ
|
|
||||||
(
|
|
||||||
Ostream& os,
|
|
||||||
const label level,
|
|
||||||
label& vertNo
|
|
||||||
) const;
|
|
||||||
|
|
||||||
|
|
||||||
// IOstream Operators
|
|
||||||
|
|
||||||
friend Istream& operator>> <Type> (Istream&, treeNode<Type>&);
|
|
||||||
friend Ostream& operator<< <Type> (Ostream&, const treeNode<Type>&);
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
} // End namespace Foam
|
|
||||||
|
|
||||||
|
|
||||||
#include "treeNodeI.H"
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
#ifdef NoRepository
|
|
||||||
# include "treeNode.C"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
|
||||||
@ -1,100 +0,0 @@
|
|||||||
/*---------------------------------------------------------------------------*\
|
|
||||||
========= |
|
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
|
||||||
\\ / O peration |
|
|
||||||
\\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
|
|
||||||
\\/ M anipulation |
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
License
|
|
||||||
This file is part of OpenFOAM.
|
|
||||||
|
|
||||||
OpenFOAM is free software: you can redistribute it and/or modify it
|
|
||||||
under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
|
||||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
||||||
for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
Description
|
|
||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
// Get type of octant
|
|
||||||
template <class Type>
|
|
||||||
inline Foam::label Foam::treeNode<Type>::getVolType(const label octant) const
|
|
||||||
{
|
|
||||||
return (volType_ >> 2*octant) & 0x3;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template <class Type>
|
|
||||||
inline const Foam::point& Foam::treeNode<Type>::midpoint() const
|
|
||||||
{
|
|
||||||
return mid_;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template <class Type>
|
|
||||||
inline Foam::treeElem<Type>* const* Foam::treeNode<Type>::subNodes() const
|
|
||||||
{
|
|
||||||
return subNodes_;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// octant contains pointer to treeNode(1) or treeLeaf(0)
|
|
||||||
template <class Type>
|
|
||||||
inline Foam::label Foam::treeNode<Type>::isNode(const label octant) const
|
|
||||||
{
|
|
||||||
return subNodeTypes_ & (0x1 << octant);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Get pointer to sub node
|
|
||||||
template <class Type>
|
|
||||||
inline Foam::treeNode<Type>* Foam::treeNode<Type>::getNodePtr
|
|
||||||
(
|
|
||||||
const label octant
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
# ifdef FULLDEBUG
|
|
||||||
if (!isNode(octant))
|
|
||||||
{
|
|
||||||
FatalErrorIn("treeNode::getNodePtr(const label)")
|
|
||||||
<< "not a treeNode"
|
|
||||||
<< abort(FatalError);
|
|
||||||
}
|
|
||||||
# endif
|
|
||||||
|
|
||||||
return static_cast<treeNode<Type>*>(subNodes_[octant]);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Get pointer to sub leaf
|
|
||||||
template <class Type>
|
|
||||||
inline Foam::treeLeaf<Type>* Foam::treeNode<Type>::getLeafPtr
|
|
||||||
(
|
|
||||||
const label octant
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
# ifdef FULLDEBUG
|
|
||||||
if (isNode(octant))
|
|
||||||
{
|
|
||||||
FatalErrorIn("treeNode::getLeafPtr(const label)")
|
|
||||||
<< "not a treeLeaf"
|
|
||||||
<< abort(FatalError);
|
|
||||||
}
|
|
||||||
# endif
|
|
||||||
|
|
||||||
return static_cast<treeLeaf<Type>*>(subNodes_[octant]);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
|
||||||
@ -1,32 +0,0 @@
|
|||||||
/*---------------------------------------------------------------------------*\
|
|
||||||
========= |
|
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
|
||||||
\\ / O peration |
|
|
||||||
\\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
|
|
||||||
\\/ M anipulation |
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
License
|
|
||||||
This file is part of OpenFOAM.
|
|
||||||
|
|
||||||
OpenFOAM is free software: you can redistribute it and/or modify it
|
|
||||||
under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
|
||||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
||||||
for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
#include "treeNode.H"
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
defineTypeNameAndDebug(Foam::treeNodeName, 0);
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
|
||||||
@ -60,7 +60,7 @@ Foam::topoSetSource::addToUsageTable Foam::regionToCell::usage_
|
|||||||
|
|
||||||
void Foam::regionToCell::combine(topoSet& set, const bool add) const
|
void Foam::regionToCell::combine(topoSet& set, const bool add) const
|
||||||
{
|
{
|
||||||
label cellI = mesh_.findCell(insidePoint_, polyMesh::FACEDIAGTETS);
|
label cellI = mesh_.findCell(insidePoint_);
|
||||||
|
|
||||||
// Load the subset of cells
|
// Load the subset of cells
|
||||||
boolList blockedFace(mesh_.nFaces(), false);
|
boolList blockedFace(mesh_.nFaces(), false);
|
||||||
|
|||||||
@ -166,7 +166,7 @@ void Foam::surfaceToCell::combine(topoSet& set, const bool add) const
|
|||||||
|
|
||||||
// Construct search engine on mesh
|
// Construct search engine on mesh
|
||||||
|
|
||||||
meshSearch queryMesh(mesh_, polyMesh::FACEDIAGTETS);
|
meshSearch queryMesh(mesh_);
|
||||||
|
|
||||||
|
|
||||||
// Check all 'outside' points
|
// Check all 'outside' points
|
||||||
|
|||||||
@ -235,7 +235,7 @@ void Foam::surfaceSets::getSurfaceSets
|
|||||||
)
|
)
|
||||||
{
|
{
|
||||||
// Construct search engine on mesh
|
// Construct search engine on mesh
|
||||||
meshSearch queryMesh(mesh, polyMesh::FACEDIAGTETS);
|
meshSearch queryMesh(mesh);
|
||||||
|
|
||||||
// Cut faces with surface and classify cells
|
// Cut faces with surface and classify cells
|
||||||
cellClassification cellType
|
cellClassification cellType
|
||||||
|
|||||||
@ -1,555 +0,0 @@
|
|||||||
/*---------------------------------------------------------------------------*\
|
|
||||||
========= |
|
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
|
||||||
\\ / O peration |
|
|
||||||
\\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
|
|
||||||
\\/ M anipulation |
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
License
|
|
||||||
This file is part of OpenFOAM.
|
|
||||||
|
|
||||||
OpenFOAM is free software: you can redistribute it and/or modify it
|
|
||||||
under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
|
||||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
||||||
for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
#include "octreeDataTriSurface.H"
|
|
||||||
|
|
||||||
#include "labelList.H"
|
|
||||||
#include "treeBoundBox.H"
|
|
||||||
#include "faceList.H"
|
|
||||||
#include "triPointRef.H"
|
|
||||||
#include "octree.H"
|
|
||||||
#include "triSurfaceTools.H"
|
|
||||||
#include "triangleFuncs.H"
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
defineTypeNameAndDebug(Foam::octreeDataTriSurface, 0);
|
|
||||||
|
|
||||||
Foam::scalar Foam::octreeDataTriSurface::tol(1E-6);
|
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
|
||||||
|
|
||||||
// Fast distance to triangle calculation. From
|
|
||||||
// "Distance Between Point and Triangle in 3D"
|
|
||||||
// David Eberly, Magic Software Inc. Aug. 2003.
|
|
||||||
// Works on function Q giving distance to point and tries to minimize this.
|
|
||||||
void Foam::octreeDataTriSurface::nearestCoords
|
|
||||||
(
|
|
||||||
const point& base,
|
|
||||||
const point& E0,
|
|
||||||
const point& E1,
|
|
||||||
const scalar a,
|
|
||||||
const scalar b,
|
|
||||||
const scalar c,
|
|
||||||
const point& P,
|
|
||||||
scalar& s,
|
|
||||||
scalar& t
|
|
||||||
)
|
|
||||||
{
|
|
||||||
// distance vector
|
|
||||||
const vector D(base - P);
|
|
||||||
|
|
||||||
// Precalculate distance factors.
|
|
||||||
const scalar d = E0 & D;
|
|
||||||
const scalar e = E1 & D;
|
|
||||||
|
|
||||||
// Do classification
|
|
||||||
const scalar det = a*c - b*b;
|
|
||||||
|
|
||||||
s = b*e - c*d;
|
|
||||||
t = b*d - a*e;
|
|
||||||
|
|
||||||
if (s+t < det)
|
|
||||||
{
|
|
||||||
if (s < 0)
|
|
||||||
{
|
|
||||||
if (t < 0)
|
|
||||||
{
|
|
||||||
//region 4
|
|
||||||
if (e > 0)
|
|
||||||
{
|
|
||||||
//min on edge t = 0
|
|
||||||
t = 0;
|
|
||||||
s = (d >= 0 ? 0 : (-d >= a ? 1 : -d/a));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
//min on edge s=0
|
|
||||||
s = 0;
|
|
||||||
t = (e >= 0 ? 0 : (-e >= c ? 1 : -e/c));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
//region 3. Min on edge s = 0
|
|
||||||
s = 0;
|
|
||||||
t = (e >= 0 ? 0 : (-e >= c ? 1 : -e/c));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (t < 0)
|
|
||||||
{
|
|
||||||
//region 5
|
|
||||||
t = 0;
|
|
||||||
s = (d >= 0 ? 0 : (-d >= a ? 1 : -d/a));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
//region 0
|
|
||||||
const scalar invDet = 1/det;
|
|
||||||
s *= invDet;
|
|
||||||
t *= invDet;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (s < 0)
|
|
||||||
{
|
|
||||||
//region 2
|
|
||||||
const scalar tmp0 = b + d;
|
|
||||||
const scalar tmp1 = c + e;
|
|
||||||
if (tmp1 > tmp0)
|
|
||||||
{
|
|
||||||
//min on edge s+t=1
|
|
||||||
const scalar numer = tmp1 - tmp0;
|
|
||||||
const scalar denom = a-2*b+c;
|
|
||||||
s = (numer >= denom ? 1 : numer/denom);
|
|
||||||
t = 1 - s;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
//min on edge s=0
|
|
||||||
s = 0;
|
|
||||||
t = (tmp1 <= 0 ? 1 : (e >= 0 ? 0 : - e/c));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (t < 0)
|
|
||||||
{
|
|
||||||
//region 6
|
|
||||||
const scalar tmp0 = b + d;
|
|
||||||
const scalar tmp1 = c + e;
|
|
||||||
if (tmp1 > tmp0)
|
|
||||||
{
|
|
||||||
//min on edge s+t=1
|
|
||||||
const scalar numer = tmp1 - tmp0;
|
|
||||||
const scalar denom = a-2*b+c;
|
|
||||||
s = (numer >= denom ? 1 : numer/denom);
|
|
||||||
t = 1 - s;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
//min on edge t=0
|
|
||||||
t = 0;
|
|
||||||
s = (tmp1 <= 0 ? 1 : (d >= 0 ? 0 : - d/a));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
//region 1
|
|
||||||
const scalar numer = c+e-(b+d);
|
|
||||||
if (numer <= 0)
|
|
||||||
{
|
|
||||||
s = 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
const scalar denom = a-2*b+c;
|
|
||||||
s = (numer >= denom ? 1 : numer/denom);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
t = 1 - s;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Calculate distance.
|
|
||||||
// Note: abs should not be needed but truncation error causes problems
|
|
||||||
// with points very close to one of the triangle vertices.
|
|
||||||
// (seen up to -9e-15). Alternatively add some small value.
|
|
||||||
|
|
||||||
// const scalar f = D & D;
|
|
||||||
// return a*s*s + 2*b*s*t + c*t*t + 2*d*s + 2*e*t + f + SMALL;
|
|
||||||
// return Foam::mag(a*s*s + 2*b*s*t + c*t*t + 2*d*s + 2*e*t + f);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Foam::point Foam::octreeDataTriSurface::nearestPoint
|
|
||||||
(
|
|
||||||
const label index,
|
|
||||||
const point& p
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
scalar s;
|
|
||||||
scalar t;
|
|
||||||
|
|
||||||
nearestCoords
|
|
||||||
(
|
|
||||||
base_[index],
|
|
||||||
E0_[index],
|
|
||||||
E1_[index],
|
|
||||||
a_[index],
|
|
||||||
b_[index],
|
|
||||||
c_[index],
|
|
||||||
p,
|
|
||||||
s,
|
|
||||||
t
|
|
||||||
);
|
|
||||||
|
|
||||||
return base_[index] + s*E0_[index] + t*E1_[index];
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Helper function to calculate tight fitting bounding boxes.
|
|
||||||
Foam::treeBoundBoxList Foam::octreeDataTriSurface::calcBb
|
|
||||||
(
|
|
||||||
const triSurface& surf
|
|
||||||
)
|
|
||||||
{
|
|
||||||
treeBoundBoxList allBb(surf.size(), treeBoundBox::invertedBox);
|
|
||||||
|
|
||||||
const labelListList& pointFcs = surf.pointFaces();
|
|
||||||
const pointField& localPts = surf.localPoints();
|
|
||||||
|
|
||||||
forAll(pointFcs, pointI)
|
|
||||||
{
|
|
||||||
const labelList& myFaces = pointFcs[pointI];
|
|
||||||
const point& vertCoord = localPts[pointI];
|
|
||||||
|
|
||||||
forAll(myFaces, myFaceI)
|
|
||||||
{
|
|
||||||
// Update bb
|
|
||||||
label faceI = myFaces[myFaceI];
|
|
||||||
|
|
||||||
treeBoundBox& bb = allBb[faceI];
|
|
||||||
|
|
||||||
bb.min() = min(bb.min(), vertCoord);
|
|
||||||
bb.max() = max(bb.max(), vertCoord);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return allBb;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
// Construct from components
|
|
||||||
Foam::octreeDataTriSurface::octreeDataTriSurface(const triSurface& surface)
|
|
||||||
:
|
|
||||||
surface_(surface),
|
|
||||||
allBb_(calcBb(surface_)),
|
|
||||||
base_(surface_.size()),
|
|
||||||
E0_(surface_.size()),
|
|
||||||
E1_(surface_.size()),
|
|
||||||
a_(surface_.size()),
|
|
||||||
b_(surface_.size()),
|
|
||||||
c_(surface_.size())
|
|
||||||
{
|
|
||||||
// Precalculate factors for distance calculation
|
|
||||||
const pointField& points = surface_.points();
|
|
||||||
|
|
||||||
forAll(surface_, faceI)
|
|
||||||
{
|
|
||||||
const labelledTri& f = surface_[faceI];
|
|
||||||
|
|
||||||
// Calculate base and spanning vectors of triangles
|
|
||||||
base_[faceI] = points[f[1]];
|
|
||||||
E0_[faceI] = points[f[0]] - points[f[1]];
|
|
||||||
E1_[faceI] = points[f[2]] - points[f[1]];
|
|
||||||
|
|
||||||
a_[faceI] = E0_[faceI] & E0_[faceI];
|
|
||||||
b_[faceI] = E0_[faceI] & E1_[faceI];
|
|
||||||
c_[faceI] = E1_[faceI] & E1_[faceI];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Construct from components
|
|
||||||
Foam::octreeDataTriSurface::octreeDataTriSurface
|
|
||||||
(
|
|
||||||
const triSurface& surface,
|
|
||||||
const treeBoundBoxList& allBb
|
|
||||||
)
|
|
||||||
:
|
|
||||||
surface_(surface),
|
|
||||||
allBb_(allBb),
|
|
||||||
base_(surface_.size()),
|
|
||||||
E0_(surface_.size()),
|
|
||||||
E1_(surface_.size()),
|
|
||||||
a_(surface_.size()),
|
|
||||||
b_(surface_.size()),
|
|
||||||
c_(surface_.size())
|
|
||||||
{
|
|
||||||
const pointField& points = surface_.points();
|
|
||||||
|
|
||||||
forAll(surface_, faceI)
|
|
||||||
{
|
|
||||||
const labelledTri& f = surface_[faceI];
|
|
||||||
|
|
||||||
// Calculate base and spanning vectors of triangles
|
|
||||||
base_[faceI] = points[f[1]];
|
|
||||||
E0_[faceI] = points[f[0]] - points[f[1]];
|
|
||||||
E1_[faceI] = points[f[2]] - points[f[1]];
|
|
||||||
|
|
||||||
a_[faceI] = E0_[faceI] & E0_[faceI];
|
|
||||||
b_[faceI] = E0_[faceI] & E1_[faceI];
|
|
||||||
c_[faceI] = E1_[faceI] & E1_[faceI];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
Foam::label Foam::octreeDataTriSurface::getSampleType
|
|
||||||
(
|
|
||||||
const octree<octreeDataTriSurface>& oc,
|
|
||||||
const point& sample
|
|
||||||
) const
|
|
||||||
|
|
||||||
{
|
|
||||||
treeBoundBox tightest(treeBoundBox::greatBox);
|
|
||||||
scalar tightestDist(treeBoundBox::great);
|
|
||||||
|
|
||||||
// Find nearest face to sample
|
|
||||||
label faceI = oc.findNearest(sample, tightest, tightestDist);
|
|
||||||
|
|
||||||
if (debug & 2)
|
|
||||||
{
|
|
||||||
Pout<< "getSampleType : sample:" << sample
|
|
||||||
<< " nearest face:" << faceI;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (faceI == -1)
|
|
||||||
{
|
|
||||||
FatalErrorIn
|
|
||||||
(
|
|
||||||
"octreeDataTriSurface::getSampleType"
|
|
||||||
"(octree<octreeDataTriSurface>&, const point&)"
|
|
||||||
) << "Could not find " << sample << " in octree."
|
|
||||||
<< abort(FatalError);
|
|
||||||
}
|
|
||||||
|
|
||||||
pointHit curHit = surface_[faceI].nearestPoint(sample, surface_.points());
|
|
||||||
|
|
||||||
// Get normal according to position on face. On point -> pointNormal,
|
|
||||||
// on edge-> edge normal, face normal on interior.
|
|
||||||
vector n
|
|
||||||
(
|
|
||||||
triSurfaceTools::surfaceNormal
|
|
||||||
(
|
|
||||||
surface_,
|
|
||||||
faceI,
|
|
||||||
curHit.rawPoint()
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
return
|
|
||||||
octree<octreeDataTriSurface>::getVolType(n, sample - curHit.rawPoint());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Check if any point on triangle is inside cubeBb.
|
|
||||||
bool Foam::octreeDataTriSurface::overlaps
|
|
||||||
(
|
|
||||||
const label index,
|
|
||||||
const treeBoundBox& cubeBb
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
//return cubeBb.overlaps(allBb_[index]);
|
|
||||||
|
|
||||||
//- Exact test of triangle intersecting bb
|
|
||||||
|
|
||||||
// Quick rejection.
|
|
||||||
if (!cubeBb.overlaps(allBb_[index]))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Triangle points
|
|
||||||
const pointField& points = surface_.points();
|
|
||||||
const labelledTri& f = surface_[index];
|
|
||||||
|
|
||||||
// Check if one or more triangle point inside
|
|
||||||
if (cubeBb.containsAny(points, f))
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
const point& p0 = points[f[0]];
|
|
||||||
const point& p1 = points[f[1]];
|
|
||||||
const point& p2 = points[f[2]];
|
|
||||||
// Now we have the difficult case: all points are outside but connecting
|
|
||||||
// edges might go through cube. Use fast intersection of bounding box.
|
|
||||||
|
|
||||||
return triangleFuncs::intersectBb(p0, p1, p2, cubeBb);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool Foam::octreeDataTriSurface::contains
|
|
||||||
(
|
|
||||||
const label,
|
|
||||||
const point&
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
notImplemented
|
|
||||||
(
|
|
||||||
"octreeDataTriSurface::contains(const label, const point&)"
|
|
||||||
);
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool Foam::octreeDataTriSurface::intersects
|
|
||||||
(
|
|
||||||
const label index,
|
|
||||||
const point& start,
|
|
||||||
const point& end,
|
|
||||||
point& intersectionPoint
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
if (mag(surface_.faceNormals()[index]) < VSMALL)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
const vector dir(end - start);
|
|
||||||
|
|
||||||
// Disable picking up intersections behind us.
|
|
||||||
scalar oldTol = intersection::setPlanarTol(0.0);
|
|
||||||
|
|
||||||
pointHit inter = surface_[index].ray
|
|
||||||
(
|
|
||||||
start,
|
|
||||||
dir,
|
|
||||||
surface_.points(),
|
|
||||||
intersection::HALF_RAY
|
|
||||||
);
|
|
||||||
|
|
||||||
intersection::setPlanarTol(oldTol);
|
|
||||||
|
|
||||||
if (inter.hit() && inter.distance() <= mag(dir))
|
|
||||||
{
|
|
||||||
// Note: no extra test on whether intersection is in front of us
|
|
||||||
// since using half_ray AND zero tolerance. (note that tolerance
|
|
||||||
// is used to look behind us)
|
|
||||||
intersectionPoint = inter.hitPoint();
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool Foam::octreeDataTriSurface::findTightest
|
|
||||||
(
|
|
||||||
const label index,
|
|
||||||
const point& sample,
|
|
||||||
treeBoundBox& tightest
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
|
|
||||||
// get nearest and furthest away vertex
|
|
||||||
point myNear, myFar;
|
|
||||||
allBb_[index].calcExtremities(sample, myNear, myFar);
|
|
||||||
|
|
||||||
const point dist = myFar - sample;
|
|
||||||
scalar myFarDist = mag(dist);
|
|
||||||
|
|
||||||
point tightestNear, tightestFar;
|
|
||||||
tightest.calcExtremities(sample, tightestNear, tightestFar);
|
|
||||||
|
|
||||||
scalar tightestFarDist = mag(tightestFar - sample);
|
|
||||||
|
|
||||||
if (tightestFarDist < myFarDist)
|
|
||||||
{
|
|
||||||
// Keep current tightest.
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Construct bb around sample and myFar
|
|
||||||
const point dist2(fabs(dist.x()), fabs(dist.y()), fabs(dist.z()));
|
|
||||||
|
|
||||||
tightest.min() = sample - dist2;
|
|
||||||
tightest.max() = sample + dist2;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Determine numerical value of sign of sample compared to shape at index
|
|
||||||
Foam::scalar Foam::octreeDataTriSurface::calcSign
|
|
||||||
(
|
|
||||||
const label index,
|
|
||||||
const point& sample,
|
|
||||||
vector& n
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
n = surface_.faceNormals()[index];
|
|
||||||
|
|
||||||
// take vector from sample to any point on face (we use vertex 0)
|
|
||||||
vector vec = sample - surface_.points()[surface_[index][0]];
|
|
||||||
|
|
||||||
vec /= mag(vec) + VSMALL;
|
|
||||||
|
|
||||||
return n & vec;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Calculate nearest point to sample on/in shapei. !Does not set nearest
|
|
||||||
Foam::scalar Foam::octreeDataTriSurface::calcNearest
|
|
||||||
(
|
|
||||||
const label index,
|
|
||||||
const point& sample,
|
|
||||||
point&
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
return mag(nearestPoint(index, sample) - sample);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Calculate nearest point on/in shapei
|
|
||||||
Foam::scalar Foam::octreeDataTriSurface::calcNearest
|
|
||||||
(
|
|
||||||
const label index,
|
|
||||||
const linePointRef& ln,
|
|
||||||
point& linePt,
|
|
||||||
point& shapePt
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
notImplemented
|
|
||||||
(
|
|
||||||
"octreeDataTriSurface::calcNearest"
|
|
||||||
"(const label, const linePointRef&, point& linePt, point&)"
|
|
||||||
);
|
|
||||||
return GREAT;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Foam::octreeDataTriSurface::write
|
|
||||||
(
|
|
||||||
Ostream& os,
|
|
||||||
const label index
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
os << surface_[index] << token::SPACE << allBb_[index];
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
|
||||||
@ -1,235 +0,0 @@
|
|||||||
/*---------------------------------------------------------------------------*\
|
|
||||||
========= |
|
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
|
||||||
\\ / O peration |
|
|
||||||
\\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
|
|
||||||
\\/ M anipulation |
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
License
|
|
||||||
This file is part of OpenFOAM.
|
|
||||||
|
|
||||||
OpenFOAM is free software: you can redistribute it and/or modify it
|
|
||||||
under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
|
||||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
||||||
for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
Class
|
|
||||||
Foam::octreeDataTriSurface
|
|
||||||
|
|
||||||
Description
|
|
||||||
Encapsulates data for octree searches on triSurface.
|
|
||||||
|
|
||||||
SourceFiles
|
|
||||||
octreeDataTriSurface.C
|
|
||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
#ifndef octreeDataTriSurface_H
|
|
||||||
#define octreeDataTriSurface_H
|
|
||||||
|
|
||||||
#include "treeBoundBoxList.H"
|
|
||||||
#include "labelList.H"
|
|
||||||
#include "point.H"
|
|
||||||
#include "triSurface.H"
|
|
||||||
#include "linePointRef.H"
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
namespace Foam
|
|
||||||
{
|
|
||||||
|
|
||||||
// Forward declaration of classes
|
|
||||||
template<class Type> class octree;
|
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*\
|
|
||||||
Class octreeDataTriSurface Declaration
|
|
||||||
\*---------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
class octreeDataTriSurface
|
|
||||||
{
|
|
||||||
// Static data
|
|
||||||
|
|
||||||
//- tolerance on linear dimensions
|
|
||||||
static scalar tol;
|
|
||||||
|
|
||||||
// Private data
|
|
||||||
|
|
||||||
const triSurface& surface_;
|
|
||||||
|
|
||||||
const treeBoundBoxList allBb_;
|
|
||||||
|
|
||||||
// Extra data to speed up distance searches.
|
|
||||||
// Triangles expressed as base + spanning vectors
|
|
||||||
pointField base_;
|
|
||||||
pointField E0_;
|
|
||||||
pointField E1_;
|
|
||||||
scalarList a_;
|
|
||||||
scalarList b_;
|
|
||||||
scalarList c_;
|
|
||||||
|
|
||||||
|
|
||||||
// Private Static Functions
|
|
||||||
|
|
||||||
//- fast triangle nearest point calculation. Returns point in E0, E1
|
|
||||||
// coordinate system: base + s*E0 + t*E1
|
|
||||||
static void nearestCoords
|
|
||||||
(
|
|
||||||
const point& base,
|
|
||||||
const point& E0,
|
|
||||||
const point& E1,
|
|
||||||
const scalar a,
|
|
||||||
const scalar b,
|
|
||||||
const scalar c,
|
|
||||||
const point& P,
|
|
||||||
scalar& s,
|
|
||||||
scalar& t
|
|
||||||
);
|
|
||||||
|
|
||||||
//- Calculate bounding boxes for triangles
|
|
||||||
static treeBoundBoxList calcBb(const triSurface&);
|
|
||||||
|
|
||||||
// Private Member Functions
|
|
||||||
|
|
||||||
//- nearest point in xyz coord system
|
|
||||||
point nearestPoint(const label index, const point& P) const;
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
// Declare name of the class and its debug switch
|
|
||||||
ClassName("octreeDataTriSurface");
|
|
||||||
|
|
||||||
|
|
||||||
// Constructors
|
|
||||||
|
|
||||||
//- Construct from triSurface. Holds reference. Bounding box
|
|
||||||
// calculated from triangle points.
|
|
||||||
octreeDataTriSurface(const triSurface&);
|
|
||||||
|
|
||||||
//- Construct from triSurface and bounding box.
|
|
||||||
// Holds references.
|
|
||||||
octreeDataTriSurface(const triSurface&, const treeBoundBoxList&);
|
|
||||||
|
|
||||||
|
|
||||||
// Member Functions
|
|
||||||
|
|
||||||
// Access
|
|
||||||
|
|
||||||
const triSurface& surface() const
|
|
||||||
{
|
|
||||||
return surface_;
|
|
||||||
}
|
|
||||||
|
|
||||||
const treeBoundBoxList& allBb() const
|
|
||||||
{
|
|
||||||
return allBb_;
|
|
||||||
}
|
|
||||||
|
|
||||||
label size() const
|
|
||||||
{
|
|
||||||
return allBb_.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Search
|
|
||||||
|
|
||||||
//- Get type of sample
|
|
||||||
label getSampleType
|
|
||||||
(
|
|
||||||
const octree<octreeDataTriSurface>&,
|
|
||||||
const point&
|
|
||||||
) const;
|
|
||||||
|
|
||||||
//- Does (bb of) shape at index overlap bb
|
|
||||||
bool overlaps
|
|
||||||
(
|
|
||||||
const label index,
|
|
||||||
const treeBoundBox& sampleBb
|
|
||||||
) const;
|
|
||||||
|
|
||||||
//- Does shape at index contain sample
|
|
||||||
bool contains
|
|
||||||
(
|
|
||||||
const label index,
|
|
||||||
const point& sample
|
|
||||||
) const;
|
|
||||||
|
|
||||||
//- Segment (from start to end) intersection with shape
|
|
||||||
// at index. If intersects returns true and sets intersectionPoint
|
|
||||||
bool intersects
|
|
||||||
(
|
|
||||||
const label index,
|
|
||||||
const point& start,
|
|
||||||
const point& end,
|
|
||||||
point& intersectionPoint
|
|
||||||
) const;
|
|
||||||
|
|
||||||
//- Sets newTightest to bounding box (and returns true) if
|
|
||||||
// nearer to sample than tightest bounding box. Otherwise
|
|
||||||
// returns false.
|
|
||||||
bool findTightest
|
|
||||||
(
|
|
||||||
const label index,
|
|
||||||
const point& sample,
|
|
||||||
treeBoundBox& tightest
|
|
||||||
) const;
|
|
||||||
|
|
||||||
//- Given index get unit normal and calculate (numerical) sign
|
|
||||||
// of sample.
|
|
||||||
// Used to determine accuracy of calcNearest or inside/outside.
|
|
||||||
scalar calcSign
|
|
||||||
(
|
|
||||||
const label index,
|
|
||||||
const point& sample,
|
|
||||||
vector& n
|
|
||||||
) const;
|
|
||||||
|
|
||||||
//- Calculates nearest (to sample) point in shape.
|
|
||||||
// Returns point and mag(nearest - sample)
|
|
||||||
scalar calcNearest
|
|
||||||
(
|
|
||||||
const label index,
|
|
||||||
const point& sample,
|
|
||||||
point& nearest
|
|
||||||
) const;
|
|
||||||
|
|
||||||
//- Calculates nearest (to line segment) point in shape.
|
|
||||||
// Returns distance and both point.
|
|
||||||
scalar calcNearest
|
|
||||||
(
|
|
||||||
const label index,
|
|
||||||
const linePointRef& ln,
|
|
||||||
point& linePt, // nearest point on line
|
|
||||||
point& shapePt // nearest point on shape
|
|
||||||
) const;
|
|
||||||
|
|
||||||
|
|
||||||
// Write
|
|
||||||
|
|
||||||
// Write shape at index
|
|
||||||
void write(Ostream& os, const label index) const;
|
|
||||||
|
|
||||||
|
|
||||||
// IOstream Operators
|
|
||||||
|
|
||||||
friend Istream& operator>>(Istream&, octreeDataTriSurface&);
|
|
||||||
friend Ostream& operator<<(Ostream&, const octreeDataTriSurface&);
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
} // End namespace Foam
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
|
||||||
@ -1,81 +0,0 @@
|
|||||||
/*---------------------------------------------------------------------------*\
|
|
||||||
========= |
|
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
|
||||||
\\ / O peration |
|
|
||||||
\\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
|
|
||||||
\\/ M anipulation |
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
License
|
|
||||||
This file is part of OpenFOAM.
|
|
||||||
|
|
||||||
OpenFOAM is free software: you can redistribute it and/or modify it
|
|
||||||
under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
|
||||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
||||||
for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
#include "octreeDataTriSurfaceTreeLeaf.H"
|
|
||||||
#include "octreeDataTriSurface.H"
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * Template Specialisations * * * * * * * * * * * //
|
|
||||||
|
|
||||||
template<>
|
|
||||||
bool Foam::treeLeaf<Foam::octreeDataTriSurface>::findNearest
|
|
||||||
(
|
|
||||||
const octreeDataTriSurface& shapes,
|
|
||||||
const point& sample,
|
|
||||||
treeBoundBox& tightest,
|
|
||||||
label& tightestI,
|
|
||||||
scalar& tightestDist
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
// Some aliases
|
|
||||||
const treeBoundBoxList& allBb = shapes.allBb();
|
|
||||||
point& min = tightest.min();
|
|
||||||
point& max = tightest.max();
|
|
||||||
|
|
||||||
point nearest;
|
|
||||||
|
|
||||||
bool changed = false;
|
|
||||||
forAll(indices_, i)
|
|
||||||
{
|
|
||||||
label faceI = indices_[i];
|
|
||||||
|
|
||||||
// Quick rejection test.
|
|
||||||
if (tightest.overlaps(allBb[faceI]))
|
|
||||||
{
|
|
||||||
// Full calculation
|
|
||||||
scalar dist = shapes.calcNearest(faceI, sample, nearest);
|
|
||||||
|
|
||||||
if (dist < tightestDist)
|
|
||||||
{
|
|
||||||
// Update bb (centered around sample, span is dist)
|
|
||||||
min.x() = sample.x() - dist;
|
|
||||||
min.y() = sample.y() - dist;
|
|
||||||
min.z() = sample.z() - dist;
|
|
||||||
|
|
||||||
max.x() = sample.x() + dist;
|
|
||||||
max.y() = sample.y() + dist;
|
|
||||||
max.z() = sample.z() + dist;
|
|
||||||
|
|
||||||
tightestI = faceI;
|
|
||||||
tightestDist = dist;
|
|
||||||
|
|
||||||
changed = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return changed;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
|
||||||
@ -1,67 +0,0 @@
|
|||||||
/*---------------------------------------------------------------------------*\
|
|
||||||
========= |
|
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
|
||||||
\\ / O peration |
|
|
||||||
\\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
|
|
||||||
\\/ M anipulation |
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
License
|
|
||||||
This file is part of OpenFOAM.
|
|
||||||
|
|
||||||
OpenFOAM is free software: you can redistribute it and/or modify it
|
|
||||||
under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
|
||||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
||||||
for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
Class
|
|
||||||
Foam::octreeDataTriSurfaceTreeLeaf
|
|
||||||
|
|
||||||
Description
|
|
||||||
Template specialisation for octreeDataTriSurfaceTreeLeaf
|
|
||||||
|
|
||||||
SourceFiles
|
|
||||||
octreeDataTriSurfaceTreeLeafTreeLeaf.C
|
|
||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
#ifndef octreeDataTriSurfaceTreeLeaf_H
|
|
||||||
#define octreeDataTriSurfaceTreeLeaf_H
|
|
||||||
|
|
||||||
#include "treeLeaf.H"
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
namespace Foam
|
|
||||||
{
|
|
||||||
|
|
||||||
// Forward declaration of classes
|
|
||||||
class octreeDataTriSurface;
|
|
||||||
|
|
||||||
template<>
|
|
||||||
bool treeLeaf<octreeDataTriSurface>::findNearest
|
|
||||||
(
|
|
||||||
const octreeDataTriSurface& shapes,
|
|
||||||
const point& sample,
|
|
||||||
treeBoundBox& tightest,
|
|
||||||
label& tightestI,
|
|
||||||
scalar& tightestDist
|
|
||||||
) const;
|
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
} // End namespace Foam
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
|
||||||
@ -363,7 +363,7 @@ void Foam::streamLine::read(const dictionary& dict)
|
|||||||
|
|
||||||
const fvMesh& mesh = dynamic_cast<const fvMesh&>(obr_);
|
const fvMesh& mesh = dynamic_cast<const fvMesh&>(obr_);
|
||||||
|
|
||||||
meshSearchPtr_.reset(new meshSearch(mesh, polyMesh::FACEDIAGTETS));
|
meshSearchPtr_.reset(new meshSearch(mesh));
|
||||||
|
|
||||||
const dictionary& coeffsDict = dict.subDict(seedSet_ + "Coeffs");
|
const dictionary& coeffsDict = dict.subDict(seedSet_ + "Coeffs");
|
||||||
sampledSetPtr_ = sampledSet::New
|
sampledSetPtr_ = sampledSet::New
|
||||||
|
|||||||
@ -267,7 +267,7 @@ void Foam::meshToMesh::cellAddresses
|
|||||||
cellAddressing_[toI] = -1;
|
cellAddressing_[toI] = -1;
|
||||||
|
|
||||||
// Check point is actually in the nearest cell
|
// Check point is actually in the nearest cell
|
||||||
if (fromMesh.pointInCell(p, curCell, polyMesh::FACEDIAGTETS))
|
if (fromMesh.pointInCell(p, curCell))
|
||||||
{
|
{
|
||||||
cellAddressing_[toI] = curCell;
|
cellAddressing_[toI] = curCell;
|
||||||
}
|
}
|
||||||
@ -292,15 +292,7 @@ void Foam::meshToMesh::cellAddresses
|
|||||||
{
|
{
|
||||||
// search through all the neighbours.
|
// search through all the neighbours.
|
||||||
// If point is in neighbour reset current cell
|
// If point is in neighbour reset current cell
|
||||||
if
|
if (fromMesh.pointInCell(p, neighbours[nI]))
|
||||||
(
|
|
||||||
fromMesh.pointInCell
|
|
||||||
(
|
|
||||||
p,
|
|
||||||
neighbours[nI],
|
|
||||||
polyMesh::FACEDIAGTETS
|
|
||||||
)
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
cellAddressing_[toI] = neighbours[nI];
|
cellAddressing_[toI] = neighbours[nI];
|
||||||
found = true;
|
found = true;
|
||||||
@ -324,15 +316,7 @@ void Foam::meshToMesh::cellAddresses
|
|||||||
{
|
{
|
||||||
// search through all the neighbours.
|
// search through all the neighbours.
|
||||||
// If point is in neighbour reset current cell
|
// If point is in neighbour reset current cell
|
||||||
if
|
if (fromMesh.pointInCell(p, nn[nI]))
|
||||||
(
|
|
||||||
fromMesh.pointInCell
|
|
||||||
(
|
|
||||||
p,
|
|
||||||
nn[nI],
|
|
||||||
polyMesh::FACEDIAGTETS
|
|
||||||
)
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
cellAddressing_[toI] = nn[nI];
|
cellAddressing_[toI] = nn[nI];
|
||||||
found = true;
|
found = true;
|
||||||
|
|||||||
@ -45,7 +45,7 @@ void Foam::probes::findElements(const fvMesh& mesh)
|
|||||||
{
|
{
|
||||||
const vector& location = operator[](probeI);
|
const vector& location = operator[](probeI);
|
||||||
|
|
||||||
elementList_[probeI] = mesh.findCell(location, polyMesh::FACEDIAGTETS);
|
elementList_[probeI] = mesh.findCell(location);
|
||||||
|
|
||||||
if (debug && elementList_[probeI] != -1)
|
if (debug && elementList_[probeI] != -1)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -138,7 +138,7 @@ Foam::sampledSets::sampledSets
|
|||||||
mesh_(refCast<const fvMesh>(obr)),
|
mesh_(refCast<const fvMesh>(obr)),
|
||||||
loadFromFiles_(loadFromFiles),
|
loadFromFiles_(loadFromFiles),
|
||||||
outputPath_(fileName::null),
|
outputPath_(fileName::null),
|
||||||
searchEngine_(mesh_, polyMesh::FACEDIAGTETS),
|
searchEngine_(mesh_),
|
||||||
interpolationScheme_(word::null),
|
interpolationScheme_(word::null),
|
||||||
writeFormat_(word::null)
|
writeFormat_(word::null)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -53,11 +53,7 @@ void Foam::triSurfaceMeshPointSet::calcSamples
|
|||||||
{
|
{
|
||||||
forAll(sampleCoords_, sampleI)
|
forAll(sampleCoords_, sampleI)
|
||||||
{
|
{
|
||||||
label cellI = searchEngine().findCell
|
label cellI = searchEngine().findCell(sampleCoords_[sampleI]);
|
||||||
(
|
|
||||||
sampleCoords_[sampleI],
|
|
||||||
polyMesh::FACEDIAGTETS
|
|
||||||
);
|
|
||||||
|
|
||||||
if (cellI != -1)
|
if (cellI != -1)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -491,9 +491,6 @@ void Foam::MeshedSurface<Face>::clear()
|
|||||||
template<class Face>
|
template<class Face>
|
||||||
void Foam::MeshedSurface<Face>::movePoints(const pointField& newPoints)
|
void Foam::MeshedSurface<Face>::movePoints(const pointField& newPoints)
|
||||||
{
|
{
|
||||||
// Remove all geometry dependent data
|
|
||||||
ParentType::clearTopology();
|
|
||||||
|
|
||||||
// Adapt for new point position
|
// Adapt for new point position
|
||||||
ParentType::movePoints(newPoints);
|
ParentType::movePoints(newPoints);
|
||||||
|
|
||||||
@ -508,13 +505,12 @@ void Foam::MeshedSurface<Face>::scalePoints(const scalar scaleFactor)
|
|||||||
// avoid bad scaling
|
// avoid bad scaling
|
||||||
if (scaleFactor > 0 && scaleFactor != 1.0)
|
if (scaleFactor > 0 && scaleFactor != 1.0)
|
||||||
{
|
{
|
||||||
// Remove all geometry dependent data
|
pointField newPoints(scaleFactor*this->points());
|
||||||
ParentType::clearTopology();
|
|
||||||
|
|
||||||
// Adapt for new point position
|
// Adapt for new point position
|
||||||
ParentType::movePoints(pointField());
|
ParentType::movePoints(newPoints);
|
||||||
|
|
||||||
storedPoints() *= scaleFactor;
|
storedPoints() = newPoints;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,27 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
. $WM_PROJECT_DIR/bin/tools/RunFunctions
|
|
||||||
|
|
||||||
# Get application name
|
|
||||||
application=`getApplication`
|
|
||||||
|
|
||||||
cp -r 0.org 0
|
|
||||||
runApplication blockMesh
|
|
||||||
|
|
||||||
runApplication setSet -batch baffle.setSet
|
|
||||||
|
|
||||||
unset FOAM_SETNAN
|
|
||||||
unset FOAM_SIGFPE
|
|
||||||
|
|
||||||
# Add the patches for the baffles
|
|
||||||
runApplication changeDictionary -literalRE
|
|
||||||
rm log.changeDictionary
|
|
||||||
|
|
||||||
# Create first baffle
|
|
||||||
createBaffles baffleFaces '(baffle1Wall_0 baffle1Wall_1)' -overwrite > log.createBaffles 2>&1
|
|
||||||
# Create second baffle
|
|
||||||
createBaffles baffleFaces2 '(baffle2Wall_0 baffle2Wall_1)' -overwrite > log.createBaffles 2>&1
|
|
||||||
|
|
||||||
# Reset proper values at the baffles
|
|
||||||
runApplication changeDictionary
|
|
||||||
|
|
||||||
runApplication $application
|
|
||||||
@ -1,6 +0,0 @@
|
|||||||
# Create face set
|
|
||||||
faceSet baffleFaces new boxToFace (0.29 0 0) (0.31 0.18 2)
|
|
||||||
faceZoneSet baffleFaces new setToFaceZone baffleFaces
|
|
||||||
|
|
||||||
faceSet baffleFaces2 new boxToFace (0.59 0.0 0.0)(0.61 0.18 2.0)
|
|
||||||
faceZoneSet baffleFaces2 new setToFaceZone baffleFaces2
|
|
||||||
@ -44,6 +44,10 @@ boundaryField
|
|||||||
{
|
{
|
||||||
type empty;
|
type empty;
|
||||||
}
|
}
|
||||||
|
"baffle1Wall.*"
|
||||||
|
{
|
||||||
|
type calculated;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -46,6 +46,10 @@ boundaryField
|
|||||||
{
|
{
|
||||||
type empty;
|
type empty;
|
||||||
}
|
}
|
||||||
|
"baffle1Wall.*"
|
||||||
|
{
|
||||||
|
type calculated;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -45,6 +45,10 @@ boundaryField
|
|||||||
{
|
{
|
||||||
type empty;
|
type empty;
|
||||||
}
|
}
|
||||||
|
"baffle1Wall.*"
|
||||||
|
{
|
||||||
|
type calculated;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -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 Q;
|
||||||
|
}
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
dimensions [1 -1 -3 0 0 0 0];
|
||||||
|
|
||||||
|
internalField uniform 17000;
|
||||||
|
|
||||||
|
boundaryField
|
||||||
|
{
|
||||||
|
".*"
|
||||||
|
{
|
||||||
|
type zeroGradient;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -0,0 +1,27 @@
|
|||||||
|
/*--------------------------------*- 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 300;
|
||||||
|
|
||||||
|
boundaryField
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -44,6 +44,10 @@ boundaryField
|
|||||||
{
|
{
|
||||||
type empty;
|
type empty;
|
||||||
}
|
}
|
||||||
|
"baffle1Wall.*"
|
||||||
|
{
|
||||||
|
type calculated;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -44,6 +44,10 @@ boundaryField
|
|||||||
{
|
{
|
||||||
type empty;
|
type empty;
|
||||||
}
|
}
|
||||||
|
"baffle1Wall.*"
|
||||||
|
{
|
||||||
|
type calculated;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -45,6 +45,10 @@ boundaryField
|
|||||||
{
|
{
|
||||||
type empty;
|
type empty;
|
||||||
}
|
}
|
||||||
|
"baffle1Wall.*"
|
||||||
|
{
|
||||||
|
type calculated;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -24,27 +24,31 @@ boundaryField
|
|||||||
floor
|
floor
|
||||||
{
|
{
|
||||||
type calculated;
|
type calculated;
|
||||||
value uniform 101325;
|
value $internalField;
|
||||||
}
|
}
|
||||||
ceiling
|
ceiling
|
||||||
{
|
{
|
||||||
type calculated;
|
type calculated;
|
||||||
value uniform 101325;
|
value $internalField;
|
||||||
}
|
}
|
||||||
inlet
|
inlet
|
||||||
{
|
{
|
||||||
type calculated;
|
type calculated;
|
||||||
value uniform 101325;
|
value $internalField;
|
||||||
}
|
}
|
||||||
outlet
|
outlet
|
||||||
{
|
{
|
||||||
type calculated;
|
type calculated;
|
||||||
value uniform 101325;
|
value $internalField;
|
||||||
}
|
}
|
||||||
fixedWalls
|
fixedWalls
|
||||||
{
|
{
|
||||||
type empty;
|
type empty;
|
||||||
}
|
}
|
||||||
|
"baffle1Wall.*"
|
||||||
|
{
|
||||||
|
type calculated;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -17,38 +17,38 @@ FoamFile
|
|||||||
|
|
||||||
dimensions [ 1 -1 -2 0 0 0 0 ];
|
dimensions [ 1 -1 -2 0 0 0 0 ];
|
||||||
|
|
||||||
internalField uniform 0;
|
internalField uniform 101325;
|
||||||
|
|
||||||
boundaryField
|
boundaryField
|
||||||
{
|
{
|
||||||
floor
|
floor
|
||||||
{
|
{
|
||||||
type buoyantPressure;
|
type buoyantPressure;
|
||||||
gradient uniform 0;
|
value $internalField;
|
||||||
value uniform 0;
|
|
||||||
}
|
}
|
||||||
ceiling
|
ceiling
|
||||||
{
|
{
|
||||||
type buoyantPressure;
|
type buoyantPressure;
|
||||||
gradient uniform 0;
|
value $internalField;
|
||||||
value uniform 0;
|
|
||||||
}
|
}
|
||||||
inlet
|
inlet
|
||||||
{
|
{
|
||||||
type buoyantPressure;
|
type buoyantPressure;
|
||||||
gradient uniform 0;
|
value $internalField;
|
||||||
value uniform 0;
|
|
||||||
}
|
}
|
||||||
outlet
|
outlet
|
||||||
{
|
{
|
||||||
type buoyantPressure;
|
type buoyantPressure;
|
||||||
gradient uniform 0;
|
value $internalField;
|
||||||
value uniform 0;
|
|
||||||
}
|
}
|
||||||
fixedWalls
|
fixedWalls
|
||||||
{
|
{
|
||||||
type empty;
|
type empty;
|
||||||
}
|
}
|
||||||
|
"baffle1Wall.*"
|
||||||
|
{
|
||||||
|
type calculated;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -5,6 +5,7 @@ cd ${0%/*} || exit 1 # run from this directory
|
|||||||
. $WM_PROJECT_DIR/bin/tools/CleanFunctions
|
. $WM_PROJECT_DIR/bin/tools/CleanFunctions
|
||||||
|
|
||||||
cleanCase
|
cleanCase
|
||||||
|
rm -rf constant/baffleRegion/polyMesh
|
||||||
rm -rf sets 0
|
rm -rf sets 0
|
||||||
|
|
||||||
# ----------------------------------------------------------------- end-of-file
|
# ----------------------------------------------------------------- end-of-file
|
||||||
32
tutorials/heatTransfer/buoyantSimpleFoam/circuitBoardCooling/Allrun
Executable file
32
tutorials/heatTransfer/buoyantSimpleFoam/circuitBoardCooling/Allrun
Executable file
@ -0,0 +1,32 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
. $WM_PROJECT_DIR/bin/tools/RunFunctions
|
||||||
|
|
||||||
|
# Get application name
|
||||||
|
application=`getApplication`
|
||||||
|
|
||||||
|
cp -r 0.org 0
|
||||||
|
runApplication blockMesh
|
||||||
|
|
||||||
|
runApplication topoSet
|
||||||
|
|
||||||
|
unset FOAM_SETNAN
|
||||||
|
unset FOAM_SIGFPE
|
||||||
|
|
||||||
|
# Create first baffle
|
||||||
|
createBaffles baffleFaces '(baffle1Wall_0 baffle1Wall_1)' -overwrite > log.createBaffles 2>&1
|
||||||
|
|
||||||
|
# Create region
|
||||||
|
runApplication extrudeToRegionMesh -overwrite
|
||||||
|
|
||||||
|
# Set the BC's for the baffle
|
||||||
|
runApplication changeDictionary -dict system/changeDictionaryDict.baffle
|
||||||
|
rm log.changeDictionary
|
||||||
|
|
||||||
|
# Set Bc's for the region baffle
|
||||||
|
runApplication changeDictionary -dict system/changeDictionaryDict.baffleRegion -literalRE
|
||||||
|
rm log.changeDictionary
|
||||||
|
|
||||||
|
# Reset proper values at the region
|
||||||
|
runApplication changeDictionary -region baffleRegion -literalRE
|
||||||
|
|
||||||
|
runApplication $application
|
||||||
@ -30,7 +30,7 @@ vertices
|
|||||||
|
|
||||||
blocks
|
blocks
|
||||||
(
|
(
|
||||||
hex (0 1 2 3 4 5 6 7) (40 20 1) simpleGrading (1 1 1)
|
hex (0 1 2 3 4 5 6 7) (50 40 1) simpleGrading (1 1 1)
|
||||||
);
|
);
|
||||||
|
|
||||||
edges
|
edges
|
||||||
@ -87,7 +87,7 @@ boundary
|
|||||||
|
|
||||||
baffle1Wall_0
|
baffle1Wall_0
|
||||||
{
|
{
|
||||||
type mappedWall;
|
type directMappedWall;
|
||||||
sampleMode nearestPatchFace;
|
sampleMode nearestPatchFace;
|
||||||
sampleRegion region0;
|
sampleRegion region0;
|
||||||
samplePatch baffle1Wall_1;
|
samplePatch baffle1Wall_1;
|
||||||
@ -98,7 +98,7 @@ boundary
|
|||||||
|
|
||||||
baffle1Wall_1
|
baffle1Wall_1
|
||||||
{
|
{
|
||||||
type mappedWall;
|
type directMappedWall;
|
||||||
sampleMode nearestPatchFace;
|
sampleMode nearestPatchFace;
|
||||||
sampleRegion region0;
|
sampleRegion region0;
|
||||||
samplePatch baffle1Wall_0;
|
samplePatch baffle1Wall_0;
|
||||||
@ -106,28 +106,6 @@ boundary
|
|||||||
offset (0 0 0);
|
offset (0 0 0);
|
||||||
faces ();
|
faces ();
|
||||||
}
|
}
|
||||||
|
|
||||||
baffle2Wall_0
|
|
||||||
{
|
|
||||||
type mappedWall;
|
|
||||||
sampleMode nearestPatchFace;
|
|
||||||
sampleRegion region0;
|
|
||||||
samplePatch baffle2Wall_1;
|
|
||||||
offsetMode uniform;
|
|
||||||
offset (0 0 0);
|
|
||||||
faces ();
|
|
||||||
}
|
|
||||||
|
|
||||||
baffle2Wall_1
|
|
||||||
{
|
|
||||||
type mappedWall;
|
|
||||||
sampleMode nearestPatchFace;
|
|
||||||
sampleRegion region0;
|
|
||||||
samplePatch baffle2Wall_0;
|
|
||||||
offsetMode uniform;
|
|
||||||
offset (0 0 0);
|
|
||||||
faces ();
|
|
||||||
}
|
|
||||||
);
|
);
|
||||||
|
|
||||||
mergePatchPairs
|
mergePatchPairs
|
||||||
@ -15,81 +15,61 @@ FoamFile
|
|||||||
}
|
}
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
9
|
7
|
||||||
(
|
(
|
||||||
floor
|
floor
|
||||||
{
|
{
|
||||||
type wall;
|
type wall;
|
||||||
nFaces 40;
|
nFaces 50;
|
||||||
startFace 1526;
|
startFace 3896;
|
||||||
}
|
}
|
||||||
ceiling
|
ceiling
|
||||||
{
|
{
|
||||||
type wall;
|
type wall;
|
||||||
nFaces 40;
|
nFaces 50;
|
||||||
startFace 1566;
|
startFace 3946;
|
||||||
}
|
}
|
||||||
inlet
|
inlet
|
||||||
{
|
{
|
||||||
type patch;
|
type patch;
|
||||||
nFaces 20;
|
nFaces 40;
|
||||||
startFace 1606;
|
startFace 3996;
|
||||||
}
|
}
|
||||||
outlet
|
outlet
|
||||||
{
|
{
|
||||||
type patch;
|
type patch;
|
||||||
nFaces 20;
|
nFaces 40;
|
||||||
startFace 1626;
|
startFace 4036;
|
||||||
}
|
}
|
||||||
fixedWalls
|
fixedWalls
|
||||||
{
|
{
|
||||||
type empty;
|
type empty;
|
||||||
nFaces 1600;
|
nFaces 4000;
|
||||||
startFace 1646;
|
startFace 4076;
|
||||||
}
|
}
|
||||||
baffle1Wall_0
|
baffle1Wall_0
|
||||||
{
|
{
|
||||||
type mappedWall;
|
type directMappedWall;
|
||||||
nFaces 7;
|
nFaces 14;
|
||||||
startFace 3246;
|
startFace 8076;
|
||||||
sampleMode nearestPatchFace;
|
sampleMode nearestPatchFace;
|
||||||
sampleRegion region0;
|
sampleRegion region0;
|
||||||
samplePatch baffle1Wall_1;
|
samplePatch baffle1Wall_1;
|
||||||
offsetMode uniform;
|
offsetMode uniform;
|
||||||
offset (0 0 0);
|
offset ( 0 0 0 );
|
||||||
|
faces ( );
|
||||||
}
|
}
|
||||||
baffle1Wall_1
|
baffle1Wall_1
|
||||||
{
|
{
|
||||||
type mappedWall;
|
type directMappedWall;
|
||||||
nFaces 7;
|
nFaces 14;
|
||||||
startFace 3253;
|
startFace 8090;
|
||||||
sampleMode nearestPatchFace;
|
sampleMode nearestPatchFace;
|
||||||
sampleRegion region0;
|
sampleRegion region0;
|
||||||
samplePatch baffle1Wall_0;
|
samplePatch baffle1Wall_0;
|
||||||
offsetMode uniform;
|
offsetMode uniform;
|
||||||
offset (0 0 0);
|
offset ( 0 0 0 );
|
||||||
}
|
faces ( );
|
||||||
baffle2Wall_0
|
|
||||||
{
|
|
||||||
type mappedWall;
|
|
||||||
nFaces 7;
|
|
||||||
startFace 3260;
|
|
||||||
sampleMode nearestPatchFace;
|
|
||||||
sampleRegion region0;
|
|
||||||
samplePatch baffle2Wall_1;
|
|
||||||
offsetMode uniform;
|
|
||||||
offset (0 0 0);
|
|
||||||
}
|
|
||||||
baffle2Wall_1
|
|
||||||
{
|
|
||||||
type mappedWall;
|
|
||||||
nFaces 7;
|
|
||||||
startFace 3267;
|
|
||||||
sampleMode nearestPatchFace;
|
|
||||||
sampleRegion region0;
|
|
||||||
samplePatch baffle2Wall_0;
|
|
||||||
offsetMode uniform;
|
|
||||||
offset (0 0 0);
|
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -0,0 +1,57 @@
|
|||||||
|
/*--------------------------------*- 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
|
||||||
|
{
|
||||||
|
T
|
||||||
|
{
|
||||||
|
boundaryField
|
||||||
|
{
|
||||||
|
"region0_to.*"
|
||||||
|
{
|
||||||
|
type compressible::temperatureThermoBaffle;
|
||||||
|
neighbourFieldName T;
|
||||||
|
K solidThermo;
|
||||||
|
KName none;
|
||||||
|
|
||||||
|
value uniform 300;
|
||||||
|
}
|
||||||
|
baffleFaces2_side
|
||||||
|
{
|
||||||
|
type zeroGradient;
|
||||||
|
}
|
||||||
|
floor
|
||||||
|
{
|
||||||
|
type fixedValue;
|
||||||
|
value uniform 300;
|
||||||
|
}
|
||||||
|
fixedWalls
|
||||||
|
{
|
||||||
|
type empty;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
boundary
|
||||||
|
{
|
||||||
|
floor
|
||||||
|
{
|
||||||
|
type patch;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user