Merge branch 'master' into feature/cvMesh

Conflicts:
	src/OpenFOAM/algorithms/indexedOctree/indexedOctree.C
	src/OpenFOAM/algorithms/indexedOctree/indexedOctree.H
	src/dynamicMesh/polyMeshFilter/polyMeshFilter.C
	src/meshTools/indexedOctree/treeDataPrimitivePatch.C
	src/meshTools/indexedOctree/treeDataTriSurface.C
	src/meshTools/triSurface/triSurfaceSearch/triSurfaceSearch.C
This commit is contained in:
laurence
2013-05-08 12:20:52 +01:00
459 changed files with 195180 additions and 4530 deletions

10
README.txt Normal file
View File

@ -0,0 +1,10 @@
2013-01
- to UPstream added allocation of communicators
- added communicators to lduMesh,lduInterface and (indirectly)
to lduInterfaceField
- gamg agglomeration allocates new communicator for every level
- in all linear solvers/smoothers/preconditioners make they use
communicator
- added lots of warnings if using unexpected communicator (UPstream::warnComm)
- did LUScalarMatrix for 'directSolveCoarsest'

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License

View File

@ -5,5 +5,6 @@ set -x
wmake
wmake rhoPimplecFoam
wmake rhoLTSPimpleFoam
wmake rhoPimpleDyMFoam
# ----------------------------------------------------------------- end-of-file

View File

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

View File

@ -0,0 +1,27 @@
EXE_INC = \
-I.. \
-I$(LIB_SRC)/thermophysicalModels/basic/lnInclude \
-I$(LIB_SRC)/turbulenceModels/compressible/turbulenceModel \
-I$(LIB_SRC)/finiteVolume/cfdTools \
-I$(LIB_SRC)/finiteVolume/lnInclude \
-I$(LIB_SRC)/meshTools/lnInclude \
-I$(LIB_SRC)/sampling/lnInclude \
-I$(LIB_SRC)/fvOptions/lnInclude \
-I$(LIB_SRC)/dynamicFvMesh/lnInclude \
-I$(LIB_SRC)/dynamicMesh/lnInclude \
-I$(LIB_SRC)/meshTools/lnInclude \
EXE_LIBS = \
-lfluidThermophysicalModels \
-lspecie \
-lcompressibleTurbulenceModel \
-lcompressibleRASModels \
-lcompressibleLESModels \
-lfiniteVolume \
-lmeshTools \
-lsampling \
-lfvOptions \
-ldynamicFvMesh \
-ltopoChangerFvMesh \
-ldynamicMesh \
-lmeshTools

View File

@ -0,0 +1,59 @@
{
if (mesh.changing())
{
forAll(U.boundaryField(), patchi)
{
if (U.boundaryField()[patchi].fixesValue())
{
U.boundaryField()[patchi].initEvaluate();
}
}
forAll(U.boundaryField(), patchi)
{
if (U.boundaryField()[patchi].fixesValue())
{
U.boundaryField()[patchi].evaluate();
phi.boundaryField()[patchi] =
rho.boundaryField()[patchi]
*(
U.boundaryField()[patchi]
& mesh.Sf().boundaryField()[patchi]
);
}
}
}
volScalarField pcorr
(
IOobject
(
"pcorr",
runTime.timeName(),
mesh,
IOobject::NO_READ,
IOobject::NO_WRITE
),
mesh,
dimensionedScalar("pcorr", p.dimensions(), 0.0),
pcorrTypes
);
dimensionedScalar Dp("Dp", dimTime, 1.0);
while (pimple.correctNonOrthogonal())
{
fvScalarMatrix pcorrEqn
(
fvm::laplacian(Dp, pcorr) == fvc::div(phi) - divrhoU
);
pcorrEqn.solve();
if (pimple.finalNonOrthogonalIter())
{
phi -= pcorrEqn.flux();
}
}
}

View File

@ -0,0 +1,13 @@
wordList pcorrTypes
(
p.boundaryField().size(),
zeroGradientFvPatchScalarField::typeName
);
for (label i=0; i<p.boundaryField().size(); i++)
{
if (p.boundaryField()[i].fixesValue())
{
pcorrTypes[i] = fixedValueFvPatchScalarField::typeName;
}
}

View File

@ -0,0 +1,114 @@
rho = thermo.rho();
rho = max(rho, rhoMin);
rho = min(rho, rhoMax);
rho.relax();
volScalarField rAU(1.0/UEqn().A());
volVectorField HbyA("HbyA", U);
HbyA = rAU*UEqn().H();
if (pimple.nCorrPISO() <= 1)
{
UEqn.clear();
}
if (pimple.transonic())
{
surfaceScalarField phid
(
"phid",
fvc::interpolate(psi)
*(
(fvc::interpolate(HbyA) & mesh.Sf())
+ fvc::ddtPhiCorr(rAU, rho, U, phiAbs)
)
);
fvOptions.relativeFlux(fvc::interpolate(psi), phid);
volScalarField Dp("Dp", rho*rAU);
while (pimple.correctNonOrthogonal())
{
fvScalarMatrix pEqn
(
fvm::ddt(psi, p)
+ fvm::div(phid, p)
- fvm::laplacian(Dp, p)
==
fvOptions(psi, p, rho.name())
);
fvOptions.constrain(pEqn);
pEqn.solve(mesh.solver(p.select(pimple.finalInnerIter())));
if (pimple.finalNonOrthogonalIter())
{
phi == pEqn.flux();
}
}
}
else
{
surfaceScalarField phiHbyA
(
"phiHbyA",
fvc::interpolate(rho)
*(
(fvc::interpolate(HbyA) & mesh.Sf())
- fvc::meshPhi(rho, U)
+ fvc::ddtPhiCorr(rAU, rho, U, phiAbs)
)
);
fvOptions.relativeFlux(fvc::interpolate(rho), phiHbyA);
volScalarField Dp("Dp", rho*rAU);
while (pimple.correctNonOrthogonal())
{
// Pressure corrector
fvScalarMatrix pEqn
(
fvm::ddt(psi, p)
+ fvc::div(phiHbyA)
- fvm::laplacian(Dp, p)
==
fvOptions(psi, p, rho.name())
);
fvOptions.constrain(pEqn);
pEqn.solve(mesh.solver(p.select(pimple.finalInnerIter())));
if (pimple.finalNonOrthogonalIter())
{
phi = phiHbyA + pEqn.flux();
}
}
}
#include "rhoEqn.H"
#include "compressibleContinuityErrs.H"
// Explicitly relax pressure for momentum corrector
p.relax();
// Recalculate density from the relaxed pressure
rho = thermo.rho();
rho = max(rho, rhoMin);
rho = min(rho, rhoMax);
rho.relax();
Info<< "rho max/min : " << max(rho).value()
<< " " << min(rho).value() << endl;
U = HbyA - rAU*fvc::grad(p);
U.correctBoundaryConditions();
fvOptions.correct(U);
K = 0.5*magSqr(U);
if (thermo.dpdt())
{
dpdt = fvc::ddt(p);
}

View File

@ -0,0 +1,7 @@
#include "readTimeControls.H"
bool correctPhi =
pimple.dict().lookupOrDefault<Switch>("correctPhi", true);
bool checkMeshCourantNo =
pimple.dict().lookupOrDefault<Switch>("checkMeshCourantNo", false);

View File

@ -0,0 +1,146 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Application
rhoPimpleFoam
Description
Transient solver for laminar or turbulent flow of compressible fluids
for HVAC and similar applications.
Uses the flexible PIMPLE (PISO-SIMPLE) solution for time-resolved and
pseudo-transient simulations.
\*---------------------------------------------------------------------------*/
#include "fvCFD.H"
#include "dynamicFvMesh.H"
#include "psiThermo.H"
#include "turbulenceModel.H"
#include "bound.H"
#include "pimpleControl.H"
#include "fvIOoptionList.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
int main(int argc, char *argv[])
{
#include "setRootCase.H"
#include "createTime.H"
#include "createDynamicFvMesh.H"
#include "initContinuityErrs.H"
pimpleControl pimple(mesh);
#include "readControls.H"
#include "createFields.H"
#include "createFvOptions.H"
#include "createPcorrTypes.H"
#include "CourantNo.H"
#include "setInitialDeltaT.H"
// Create old-time absolute flux for ddtPhiCorr
surfaceScalarField phiAbs("phiAbs", phi);
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
Info<< "\nStarting time loop\n" << endl;
while (runTime.run())
{
#include "readControls.H"
#include "compressibleCourantNo.H"
// Make the fluxes absolute before mesh-motion
fvc::makeAbsolute(phi, rho, U);
// Update absolute flux for ddtPhiCorr
phiAbs = phi;
#include "setDeltaT.H"
runTime++;
Info<< "Time = " << runTime.timeName() << nl << endl;
{
// Store divrhoU from the previous time-step/mesh for the correctPhi
volScalarField divrhoU(fvc::div(phi));
// Do any mesh changes
mesh.update();
if (mesh.changing() && correctPhi)
{
#include "correctPhi.H"
}
}
// Make the fluxes relative to the mesh-motion
fvc::makeRelative(phi, rho, U);
if (mesh.changing() && checkMeshCourantNo)
{
#include "meshCourantNo.H"
}
if (pimple.nCorrPIMPLE() <= 1)
{
#include "rhoEqn.H"
Info<< "rhoEqn max/min : " << max(rho).value()
<< " " << min(rho).value() << endl;
}
// --- Pressure-velocity PIMPLE corrector loop
while (pimple.loop())
{
#include "UEqn.H"
#include "EEqn.H"
// --- Pressure corrector loop
while (pimple.correct())
{
#include "pEqn.H"
}
if (pimple.turbCorr())
{
turbulence->correct();
}
}
runTime.write();
Info<< "ExecutionTime = " << runTime.elapsedCpuTime() << " s"
<< " ClockTime = " << runTime.elapsedClockTime() << " s"
<< nl << endl;
}
Info<< "End\n" << endl;
return 0;
}
// ************************************************************************* //

View File

@ -1,25 +1,24 @@
EXE_INC = \
-I.. \
-I$(LIB_SRC)/dynamicFvMesh/lnInclude \
-I$(LIB_SRC)/dynamicMesh/lnInclude \
-I$(LIB_SRC)/meshTools/lnInclude \
-I$(LIB_SRC)/turbulenceModels/incompressible/turbulenceModel \
-I$(LIB_SRC)/transportModels \
-I$(LIB_SRC)/transportModels/incompressible/singlePhaseTransportModel \
-I$(LIB_SRC)/finiteVolume/lnInclude \
-I$(LIB_SRC)/fvOptions/lnInclude \
-I$(LIB_SRC)/sampling/lnInclude
-I$(LIB_SRC)/sampling/lnInclude \
-I$(LIB_SRC)/dynamicFvMesh/lnInclude \
-I$(LIB_SRC)/dynamicMesh/lnInclude \
-I$(LIB_SRC)/meshTools/lnInclude \
EXE_LIBS = \
-ldynamicFvMesh \
-ltopoChangerFvMesh \
-ldynamicMesh \
-lmeshTools \
-lincompressibleTransportModels \
-lincompressibleTurbulenceModel \
-lincompressibleRASModels \
-lincompressibleLESModels \
-lfiniteVolume \
-lfvOptions \
-lsampling
-lsampling \
-ldynamicFvMesh \
-ltopoChangerFvMesh \
-ldynamicMesh \
-lmeshTools

View File

@ -1,23 +0,0 @@
// Solve the Momentum equation
tmp<fvVectorMatrix> UEqn
(
fvm::ddt(U)
+ fvm::div(phi, U)
+ turbulence->divDevReff(U)
==
fvOptions(U)
);
UEqn().relax();
fvOptions.constrain(UEqn());
rAU = 1.0/UEqn().A();
if (pimple.momentumPredictor())
{
solve(UEqn() == -fvc::grad(p));
fvOptions.correct(U);
}

View File

@ -22,20 +22,6 @@
}
}
wordList pcorrTypes
(
p.boundaryField().size(),
zeroGradientFvPatchScalarField::typeName
);
forAll(p.boundaryField(), patchI)
{
if (p.boundaryField()[patchI].fixesValue())
{
pcorrTypes[patchI] = fixedValueFvPatchScalarField::typeName;
}
}
volScalarField pcorr
(
IOobject
@ -51,11 +37,13 @@
pcorrTypes
);
dimensionedScalar Dp("Dp", dimTime, 1.0);
while (pimple.correctNonOrthogonal())
{
fvScalarMatrix pcorrEqn
(
fvm::laplacian(rAU, pcorr) == fvc::div(phi)
fvm::laplacian(Dp, pcorr) == fvc::div(phi)
);
pcorrEqn.setReference(pRefCell, pRefValue);
@ -68,6 +56,4 @@
}
}
phi.oldTime() = phi;
#include "continuityErrs.H"

View File

@ -40,19 +40,3 @@
(
incompressible::turbulenceModel::New(U, phi, laminarTransport)
);
Info<< "Reading field rAU if present\n" << endl;
volScalarField rAU
(
IOobject
(
"rAU",
runTime.timeName(),
mesh,
IOobject::READ_IF_PRESENT,
IOobject::AUTO_WRITE
),
mesh,
runTime.deltaT(),
zeroGradientFvPatchScalarField::typeName
);

View File

@ -0,0 +1,13 @@
wordList pcorrTypes
(
p.boundaryField().size(),
zeroGradientFvPatchScalarField::typeName
);
for (label i=0; i<p.boundaryField().size(); i++)
{
if (p.boundaryField()[i].fixesValue())
{
pcorrTypes[i] = fixedValueFvPatchScalarField::typeName;
}
}

View File

@ -10,13 +10,9 @@ surfaceScalarField phiHbyA
(
"phiHbyA",
(fvc::interpolate(HbyA) & mesh.Sf())
+ fvc::ddtPhiCorr(rAU, U, phiAbs)
);
if (ddtPhiCorr)
{
phiHbyA += fvc::ddtPhiCorr(rAU, U, phi);
}
if (p.needReference())
{
fvc::makeRelative(phiHbyA, U);

View File

@ -33,9 +33,9 @@ Description
\*---------------------------------------------------------------------------*/
#include "fvCFD.H"
#include "dynamicFvMesh.H"
#include "singlePhaseTransportModel.H"
#include "turbulenceModel.H"
#include "dynamicFvMesh.H"
#include "pimpleControl.H"
#include "fvIOoptionList.H"
@ -44,15 +44,21 @@ Description
int main(int argc, char *argv[])
{
#include "setRootCase.H"
#include "createTime.H"
#include "createDynamicFvMesh.H"
#include "initContinuityErrs.H"
pimpleControl pimple(mesh);
#include "createFields.H"
#include "createFvOptions.H"
#include "readTimeControls.H"
#include "createPcorrTypes.H"
#include "CourantNo.H"
#include "setInitialDeltaT.H"
pimpleControl pimple(mesh);
// Create old-time absolute flux for ddtPhiCorr
surfaceScalarField phiAbs("phiAbs", phi);
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -66,6 +72,9 @@ int main(int argc, char *argv[])
// Make the fluxes absolute
fvc::makeAbsolute(phi, U);
// Update absolute flux for ddtPhiCorr
phiAbs = phi;
#include "setDeltaT.H"
runTime++;

View File

@ -1,12 +1,7 @@
#include "readTimeControls.H"
const dictionary& pimpleDict = pimple.dict();
const bool correctPhi =
pimpleDict.lookupOrDefault("correctPhi", false);
pimple.dict().lookupOrDefault("correctPhi", false);
const bool checkMeshCourantNo =
pimpleDict.lookupOrDefault("checkMeshCourantNo", false);
const bool ddtPhiCorr =
pimpleDict.lookupOrDefault("ddtPhiCorr", true);
pimple.dict().lookupOrDefault("checkMeshCourantNo", false);

View File

@ -37,7 +37,7 @@ Description
#include "fvCFD.H"
#include "turbulenceModel.H"
#include "fluidThermoCloud.H"
#include "basicThermoCloud.H"
#include "coalCloud.H"
#include "psiCombustionModel.H"
#include "fvIOoptionList.H"

View File

@ -9,7 +9,7 @@ coalCloud coalParcels
);
Info<< "\nConstructing limestone cloud" << endl;
fluidThermoCloud limestoneParcels
basicThermoCloud limestoneParcels
(
"limestoneCloud1",
rho,

View File

@ -1,7 +1,5 @@
{
label nAlphaCorr(readLabel(pimple.dict().lookup("nAlphaCorr")));
label nAlphaSubCycles(readLabel(pimple.dict().lookup("nAlphaSubCycles")));
#include "alphaControls.H"
surfaceScalarField phic(mag(phi/mesh.magSf()));
phic = min(interface.cAlpha()*phic, max(phic));

View File

@ -137,9 +137,6 @@ int main(int argc, char *argv[])
while (pimple.correct())
{
#include "pEqn.H"
// Make the fluxes relative to the mesh motion
fvc::makeRelative(phi, U);
}
}

View File

@ -38,7 +38,7 @@
pcorrTypes
);
dimensionedScalar rAUf("(1|A(U))", dimTime/rho.dimensions(), 1.0);
dimensionedScalar Dp("Dp", dimTime/rho.dimensions(), 1.0);
adjustPhi(phi, U, pcorr);
@ -46,7 +46,7 @@
{
fvScalarMatrix pcorrEqn
(
fvm::laplacian(rAUf, pcorr) == fvc::div(phi) - divU
fvm::laplacian(Dp, pcorr) == fvc::div(phi) - divU
);
pcorrEqn.solve();

View File

@ -1,17 +1,5 @@
#include "readTimeControls.H"
label nAlphaCorr(readLabel(pimple.dict().lookup("nAlphaCorr")));
label nAlphaSubCycles(readLabel(pimple.dict().lookup("nAlphaSubCycles")));
if (nAlphaSubCycles > 1 && pimple.nCorrPIMPLE() != 1)
{
FatalErrorIn(args.executable())
<< "Sub-cycling alpha is only allowed for PISO, "
"i.e. when the number of outer-correctors = 1"
<< exit(FatalError);
}
bool correctPhi =
pimple.dict().lookupOrDefault<Switch>("correctPhi", true);

View File

@ -56,7 +56,7 @@ int main(int argc, char *argv[])
pimpleControl pimple(mesh);
#include "readControls.H"
#include "readTimeControls.H"
#include "initContinuityErrs.H"
#include "createFields.H"
#include "CourantNo.H"
@ -68,7 +68,7 @@ int main(int argc, char *argv[])
while (runTime.run())
{
#include "readControls.H"
#include "readTimeControls.H"
#include "CourantNo.H"
#include "setDeltaT.H"

View File

@ -85,8 +85,8 @@
if (pimple.finalNonOrthogonalIter())
{
//p = max(p_rgh + (alpha1*rho1 + alpha2*rho2)*gh, pMin);
//p_rgh = p - (alpha1*rho1 + alpha2*rho2)*gh;
p = max(p_rgh + (alpha1*rho1 + alpha2*rho2)*gh, pMin);
p_rgh = p - (alpha1*rho1 + alpha2*rho2)*gh;
dgdt =
(
@ -102,7 +102,7 @@
}
}
p = max(p_rgh + (alpha1*rho1 + alpha2*rho2)*gh, pMin);
// p = max(p_rgh + (alpha1*rho1 + alpha2*rho2)*gh, pMin);
// Update densities from change in p_rgh
rho1 += psi1*(p_rgh - p_rgh_0);

View File

@ -1,13 +0,0 @@
#include "readTimeControls.H"
label nAlphaCorr(readLabel(pimple.dict().lookup("nAlphaCorr")));
label nAlphaSubCycles(readLabel(pimple.dict().lookup("nAlphaSubCycles")));
if (nAlphaSubCycles > 1 && pimple.nCorrPIMPLE() != 1)
{
FatalErrorIn(args.executable())
<< "Sub-cycling alpha is only allowed for PISO operation, "
"i.e. when the number of outer-correctors = 1"
<< exit(FatalError);
}

View File

@ -28,8 +28,8 @@
+ (
he1.name() == thermo1.phasePropertyName("e")
? fvc::div(alphaPhi1, p)
: -dalpha1pdt
? fvc::ddt(alpha1)*p + fvc::div(alphaPhi1, p)
: -alpha1*dpdt
)/rho1
- fvm::laplacian(k1, he1)
@ -50,8 +50,8 @@
+ (
he2.name() == thermo2.phasePropertyName("e")
? fvc::div(alphaPhi2, p)
: -dalpha2pdt
? fvc::ddt(alpha2)*p + fvc::div(alphaPhi2, p)
: -alpha2*dpdt
)/rho2
- fvm::laplacian(k2, he2)

View File

@ -275,8 +275,8 @@
);
Info<< "Creating field dalpha1pdt\n" << endl;
volScalarField dalpha1pdt
Info<< "Creating field dpdt\n" << endl;
volScalarField dpdt
(
IOobject
(
@ -285,21 +285,9 @@
mesh
),
mesh,
dimensionedScalar("dalpha1pdt", p.dimensions()/dimTime, 0)
dimensionedScalar("dpdt", p.dimensions()/dimTime, 0)
);
Info<< "Creating field dalpha2pdt\n" << endl;
volScalarField dalpha2pdt
(
IOobject
(
"dpdt",
runTime.timeName(),
mesh
),
mesh,
dimensionedScalar("dalpha2pdt", p.dimensions()/dimTime, 0)
);
Info<< "Creating field kinetic energy K\n" << endl;
volScalarField K1("K" + phase1Name, 0.5*magSqr(U1));

View File

@ -208,13 +208,8 @@
K1 = 0.5*magSqr(U1);
K2 = 0.5*magSqr(U2);
if (thermo1.dpdt())
if (thermo1.dpdt() || thermo2.dpdt())
{
dalpha1pdt = fvc::ddt(alpha1, p);
}
if (thermo2.dpdt())
{
dalpha2pdt = fvc::ddt(alpha2, p);
dpdt = fvc::ddt(p);
}
}

View File

@ -1,4 +1,2 @@
#include "readTimeControls.H"
int nAlphaCorr(readInt(pimple.dict().lookup("nAlphaCorr")));
int nAlphaSubCycles(readInt(pimple.dict().lookup("nAlphaSubCycles")));
#include "alphaControls.H"

View File

@ -1,5 +1,4 @@
label nAlphaCorr(readLabel(pimple.dict().lookup("nAlphaCorr")));
label nAlphaSubCycles(readLabel(pimple.dict().lookup("nAlphaSubCycles")));
#include "alphaControls.H"
if (nAlphaSubCycles > 1)
{

View File

@ -130,10 +130,7 @@
<< ", " << gMax(1/rDeltaT.internalField()) << endl;
}
label nAlphaSubCycles
(
readLabel(pimpleDict.lookup("nAlphaSubCycles"))
);
#include "alphaControls.H"
rSubDeltaT = rDeltaT*nAlphaSubCycles;
}

View File

@ -1,5 +1,4 @@
label nAlphaCorr(readLabel(pimple.dict().lookup("nAlphaCorr")));
label nAlphaSubCycles(readLabel(pimple.dict().lookup("nAlphaSubCycles")));
#include "alphaControls.H"
if (nAlphaSubCycles > 1)
{

View File

@ -50,11 +50,11 @@
{
phi -= pcorrEqn.flux();
phiAbs = phi;
phiAbs.oldTime() = phi;
fvc::makeRelative(phi, U);
phi.oldTime() = phi;
}
}
}
phi.oldTime() = phi;
#include "continuityErrs.H"

View File

@ -51,10 +51,11 @@ int main(int argc, char *argv[])
#include "createDynamicFvMesh.H"
#include "initContinuityErrs.H"
#include "createFields.H"
#include "readTimeControls.H"
pimpleControl pimple(mesh);
#include "readTimeControls.H"
surfaceScalarField phiAbs("phiAbs", phi);
fvc::makeAbsolute(phiAbs, U);

View File

@ -63,7 +63,6 @@ int main(int argc, char *argv[])
#include "CourantNo.H"
#include "setInitialDeltaT.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
Info<< "\nStarting time loop\n" << endl;

View File

@ -1,6 +1,4 @@
const dictionary& pimpleDict = pimple.dict();
label nAlphaCorr(readLabel(pimpleDict.lookup("nAlphaCorr")));
label nAlphaSubCycles(readLabel(pimpleDict.lookup("nAlphaSubCycles")));
#include "alphaControls.H"
if (nAlphaSubCycles > 1)
{

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
@ -174,8 +174,10 @@ Foam::threePhaseInterfaceProperties::threePhaseInterfaceProperties
(
readScalar
(
mixture.U().mesh().solutionDict().subDict("PIMPLE").
lookup("cAlpha")
mixture.U().mesh().solverDict
(
mixture_.alpha1().name()
).lookup("cAlpha")
)
),
sigma12_(mixture.lookup("sigma12")),

View File

@ -5,7 +5,10 @@ EXE_INC = \
-I$(LIB_SRC)/transportModels/interfaceProperties/lnInclude \
-I$(LIB_SRC)/turbulenceModels/incompressible/turbulenceModel \
-IphaseChangeTwoPhaseMixtures/phaseChangeTwoPhaseMixture \
-I$(LIB_SRC)/finiteVolume/lnInclude
-I$(LIB_SRC)/finiteVolume/lnInclude \
-I$(LIB_SRC)/meshTools/lnInclude \
-I$(LIB_SRC)/fvOptions/lnInclude\
-I$(LIB_SRC)/sampling/lnInclude
EXE_LIBS = \
-ltwoPhaseMixture \
@ -15,4 +18,7 @@ EXE_LIBS = \
-lincompressibleTurbulenceModel \
-lincompressibleRASModels \
-lincompressibleLESModels \
-lfiniteVolume
-lfiniteVolume \
-lmeshTools \
-lfvOptions \
-lsampling

View File

@ -4,9 +4,41 @@
surfaceScalarField phir("phir", phic*interface.nHatf());
for (int gCorr=0; gCorr<nAlphaCorr; gCorr++)
Pair<tmp<volScalarField> > vDotAlphal =
twoPhaseProperties->vDotAlphal();
const volScalarField& vDotcAlphal = vDotAlphal[0]();
const volScalarField& vDotvAlphal = vDotAlphal[1]();
const volScalarField vDotvmcAlphal(vDotvAlphal - vDotcAlphal);
tmp<surfaceScalarField> tphiAlpha;
if (MULESCorr)
{
surfaceScalarField phiAlpha
fvScalarMatrix alpha1Eqn
(
fvm::ddt(alpha1)
+ fvm::div(phi, alpha1, "UD") - fvm::Sp(divU, alpha1)
==
fvm::Sp(vDotvmcAlphal, alpha1)
+ vDotcAlphal
);
alpha1Eqn.solve();
Info<< "Phase-1 volume fraction = "
<< alpha1.weightedAverage(mesh.Vsc()).value()
<< " Min(alpha1) = " << min(alpha1).value()
<< " Max(alpha1) = " << max(alpha1).value()
<< endl;
tphiAlpha = alpha1Eqn.flux();
}
volScalarField alpha10("alpha10", alpha1);
for (int aCorr=0; aCorr<nAlphaCorr; aCorr++)
{
tmp<surfaceScalarField> tphiAlphaCorr
(
fvc::flux
(
@ -16,71 +48,58 @@
)
+ fvc::flux
(
-fvc::flux(-phir, scalar(1) - alpha1, alpharScheme),
-fvc::flux(-phir, alpha2, alpharScheme),
alpha1,
alpharScheme
)
);
Pair<tmp<volScalarField> > vDotAlphal =
twoPhaseProperties->vDotAlphal();
const volScalarField& vDotcAlphal = vDotAlphal[0]();
const volScalarField& vDotvAlphal = vDotAlphal[1]();
if (MULESCorr)
{
tphiAlphaCorr() -= tphiAlpha();
volScalarField Sp
(
IOobject
volScalarField alpha100("alpha100", alpha10);
alpha10 = alpha1;
MULES::correct
(
"Sp",
runTime.timeName(),
mesh
),
vDotvAlphal - vDotcAlphal
);
geometricOneField(),
alpha1,
tphiAlphaCorr(),
vDotvmcAlphal,
(
divU*(alpha10 - alpha100)
- vDotvmcAlphal*alpha10
)(),
1,
0
);
volScalarField Su
(
IOobject
tphiAlpha() += tphiAlphaCorr();
}
else
{
MULES::explicitSolve
(
"Su",
runTime.timeName(),
mesh
),
// Divergence term is handled explicitly to be
// consistent with the explicit transport solution
divU*alpha1
+ vDotcAlphal
);
geometricOneField(),
alpha1,
phi,
tphiAlphaCorr(),
vDotvmcAlphal,
(divU*alpha1 + vDotcAlphal)(),
1,
0
);
//MULES::explicitSolve
//(
// geometricOneField(),
// alpha1,
// phi,
// phiAlpha,
// Sp,
// Su,
// 1,
// 0
//);
tphiAlpha = tphiAlphaCorr;
}
MULES::implicitSolve
(
geometricOneField(),
alpha1,
phi,
phiAlpha,
Sp,
Su,
1,
0
);
rhoPhi +=
(runTime.deltaT()/totalDeltaT)
*(phiAlpha*(rho1 - rho2) + phi*rho2);
alpha2 = 1.0 - alpha1;
}
rhoPhi = tphiAlpha()*(rho1 - rho2) + phi*rho2;
Info<< "Liquid phase volume fraction = "
<< alpha1.weightedAverage(mesh.V()).value()
<< " Min(alpha1) = " << min(alpha1).value()

View File

@ -11,21 +11,18 @@ surfaceScalarField rhoPhi
);
{
const dictionary& pimpleDict = pimple.dict();
label nAlphaCorr(readLabel(pimpleDict.lookup("nAlphaCorr")));
label nAlphaSubCycles(readLabel(pimpleDict.lookup("nAlphaSubCycles")));
#include "alphaControls.H"
surfaceScalarField phic(mag(phi/mesh.magSf()));
phic = min(interface.cAlpha()*phic, max(phic));
volScalarField divU(fvc::div(phi));
dimensionedScalar totalDeltaT = runTime.deltaT();
if (nAlphaSubCycles > 1)
{
dimensionedScalar totalDeltaT = runTime.deltaT();
surfaceScalarField rhoPhiSum("rhoPhiSum", rhoPhi);
for
(
subCycle<volScalarField> alphaSubCycle(alpha1, nAlphaSubCycles);
@ -33,12 +30,15 @@ surfaceScalarField rhoPhi
)
{
#include "alphaEqn.H"
rhoPhiSum += (runTime.deltaT()/totalDeltaT)*rhoPhi;
}
rhoPhi = rhoPhiSum;
}
else
{
#include "alphaEqn.H"
}
rho == alpha1*rho1 + (scalar(1) - alpha1)*rho2;
rho == alpha1*rho1 + alpha2*rho2;
}

View File

@ -12,20 +12,6 @@
mesh
);
Info<< "Reading field alpha1\n" << endl;
volScalarField alpha1
(
IOobject
(
"alpha1",
runTime.timeName(),
mesh,
IOobject::MUST_READ,
IOobject::AUTO_WRITE
),
mesh
);
Info<< "Reading field U\n" << endl;
volVectorField U
(
@ -42,14 +28,19 @@
#include "createPhi.H"
Info<< "Creating phaseChangeTwoPhaseMixture\n" << endl;
autoPtr<phaseChangeTwoPhaseMixture> twoPhaseProperties =
phaseChangeTwoPhaseMixture::New(U, phi);
volScalarField& alpha1(twoPhaseProperties->alpha1());
volScalarField& alpha2(twoPhaseProperties->alpha2());
const dimensionedScalar& rho1 = twoPhaseProperties->rho1();
const dimensionedScalar& rho2 = twoPhaseProperties->rho2();
const dimensionedScalar& pSat = twoPhaseProperties->pSat();
// Need to store rho for ddt(rho, U)
volScalarField rho
(
@ -60,11 +51,12 @@
mesh,
IOobject::READ_IF_PRESENT
),
alpha1*rho1 + (scalar(1) - alpha1)*rho2,
alpha1*rho1 + alpha2*rho2,
alpha1.boundaryField().types()
);
rho.oldTime();
// Construct interface from alpha1 distribution
interfaceProperties interface(alpha1, U, twoPhaseProperties());
@ -113,3 +105,5 @@
);
p_rgh = p - rho*gh;
}
fv::IOoptionList fvOptions(mesh);

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
@ -47,6 +47,7 @@ Description
#include "phaseChangeTwoPhaseMixture.H"
#include "turbulenceModel.H"
#include "pimpleControl.H"
#include "fvIOoptionList.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -80,14 +81,10 @@ int main(int argc, char *argv[])
Info<< "Time = " << runTime.timeName() << nl << endl;
twoPhaseProperties->correct();
#include "alphaEqnSubCycle.H"
if (pimple.nCorrPIMPLE() == 1)
{
interface.correct();
}
turbulence->correct();
interface.correct();
// --- Pressure-velocity PIMPLE corrector loop
while (pimple.loop())
@ -99,9 +96,12 @@ int main(int argc, char *argv[])
{
#include "pEqn.H"
}
}
twoPhaseProperties->correct();
if (pimple.turbCorr())
{
turbulence->correct();
}
}
runTime.write();

View File

@ -46,6 +46,7 @@
U = HbyA + rAU*fvc::reconstruct((phig + p_rghEqn.flux())/rAUf);
U.correctBoundaryConditions();
fvOptions.correct(U);
}
}

View File

@ -29,7 +29,10 @@ License
#include "Time.H"
#include "subCycle.H"
#include "MULES.H"
#include "surfaceInterpolate.H"
#include "fvcGrad.H"
#include "fvcSnGrad.H"
#include "fvcDiv.H"
#include "fvcFlux.H"
#include "fvcAverage.H"
@ -809,9 +812,8 @@ void Foam::multiphaseSystem::solve()
const Time& runTime = mesh_.time();
const dictionary& pimpleDict = mesh_.solutionDict().subDict("PIMPLE");
label nAlphaSubCycles(readLabel(pimpleDict.lookup("nAlphaSubCycles")));
const dictionary& alphaControls = mesh_.solverDict(phases_.first().name());
label nAlphaSubCycles(readLabel(alphaControls.lookup("nAlphaSubCycles")));
if (nAlphaSubCycles > 1)
{

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
@ -28,7 +28,10 @@ License
#include "Time.H"
#include "subCycle.H"
#include "MULES.H"
#include "surfaceInterpolate.H"
#include "fvcGrad.H"
#include "fvcSnGrad.H"
#include "fvcDiv.H"
#include "fvcFlux.H"
// * * * * * * * * * * * * * * * Static Member Data * * * * * * * * * * * * //
@ -246,15 +249,12 @@ void Foam::multiphaseMixture::solve()
const Time& runTime = mesh_.time();
const dictionary& pimpleDict = mesh_.solutionDict().subDict("PIMPLE");
label nAlphaSubCycles(readLabel(pimpleDict.lookup("nAlphaSubCycles")));
scalar cAlpha(readScalar(pimpleDict.lookup("cAlpha")));
volScalarField& alpha = phases_.first();
const dictionary& alphaControls = mesh_.solverDict(alpha.name());
label nAlphaSubCycles(readLabel(alphaControls.lookup("nAlphaSubCycles")));
scalar cAlpha(readScalar(alphaControls.lookup("cAlpha")));
if (nAlphaSubCycles > 1)
{
surfaceScalarField rhoPhiSum(0.0*rhoPhi_);

View File

@ -1,5 +1,4 @@
label nAlphaCorr(readLabel(pimple.dict().lookup("nAlphaCorr")));
label nAlphaSubCycles(readLabel(pimple.dict().lookup("nAlphaSubCycles")));
#include "alphaControls.H"
if (nAlphaSubCycles > 1)
{

View File

@ -1,5 +1,4 @@
#include "readTimeControls.H"
#include "alphaControls.H"
int nAlphaCorr(readInt(pimple.dict().lookup("nAlphaCorr")));
int nAlphaSubCycles(readInt(pimple.dict().lookup("nAlphaSubCycles")));
Switch correctAlpha(pimple.dict().lookup("correctAlpha"));

View File

@ -0,0 +1,3 @@
laplacianFoam.C
EXE = $(FOAM_USER_APPBIN)/laplacianFoam-communicators

View File

@ -0,0 +1,3 @@
EXE_INC = -I$(LIB_SRC)/finiteVolume/lnInclude
EXE_LIBS = -lfiniteVolume

View File

@ -0,0 +1,37 @@
Info<< "Reading field T\n" << endl;
volScalarField T
(
IOobject
(
"T",
runTime.timeName(),
mesh,
IOobject::MUST_READ,
IOobject::AUTO_WRITE
),
mesh
);
Info<< "Reading transportProperties\n" << endl;
IOdictionary transportProperties
(
IOobject
(
"transportProperties",
runTime.constant(),
mesh,
IOobject::MUST_READ_IF_MODIFIED,
IOobject::NO_WRITE
)
);
Info<< "Reading diffusivity DT\n" << endl;
dimensionedScalar DT
(
transportProperties.lookup("DT")
);

View File

@ -0,0 +1,817 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2013 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Application
laplacianFoam
Description
Solves a simple Laplace equation, e.g. for thermal diffusion in a solid.
\*---------------------------------------------------------------------------*/
#include "fvCFD.H"
#include "simpleControl.H"
#include "globalIndex.H"
#include "lduPrimitiveMesh.H"
#include "processorGAMGInterface.H"
#include "GAMGInterfaceField.H"
#include "processorLduInterfaceField.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
void checkUpperTriangular
(
const label size,
const labelUList& l,
const labelUList& u
)
{
forAll(l, faceI)
{
if (u[faceI] < l[faceI])
{
FatalErrorIn
(
"checkUpperTriangular"
"(const label, const labelUList&, const labelUList&)"
) << "Reversed face. Problem at face " << faceI
<< " l:" << l[faceI] << " u:" << u[faceI] << abort(FatalError);
}
if (l[faceI] < 0 || u[faceI] < 0 || u[faceI] >= size)
{
FatalErrorIn
(
"checkUpperTriangular"
"(const label, const labelUList&, const labelUList&)"
) << "Illegal cell label. Problem at face " << faceI
<< " l:" << l[faceI] << " u:" << u[faceI] << abort(FatalError);
}
}
for (label faceI=1; faceI < l.size(); faceI++)
{
if (l[faceI-1] > l[faceI])
{
FatalErrorIn
(
"checkUpperTriangular"
"(const label, const labelUList&, const labelUList&)"
) << "Lower not in incremental cell order."
<< " Problem at face " << faceI
<< " l:" << l[faceI] << " u:" << u[faceI]
<< " previous l:" << l[faceI-1] << abort(FatalError);
}
else if (l[faceI-1] == l[faceI])
{
// Same cell.
if (u[faceI-1] > u[faceI])
{
FatalErrorIn
(
"checkUpperTriangular"
"(const label, const labelUList&, const labelUList&)"
) << "Upper not in incremental cell order."
<< " Problem at face " << faceI
<< " l:" << l[faceI] << " u:" << u[faceI]
<< " previous u:" << u[faceI-1] << abort(FatalError);
}
}
}
}
void print(const string& msg, const lduMesh& mesh)
{
const lduAddressing& addressing = mesh.lduAddr();
const lduInterfacePtrsList interfaces = mesh.interfaces();
Pout<< "Mesh:" << msg.c_str() << nl
<< " cells:" << addressing.size() << nl
<< " faces:" << addressing.lowerAddr().size() << nl
<< " patches:" << interfaces.size() << nl;
const labelUList& l = addressing.lowerAddr();
const labelUList& startAddr = addressing.losortStartAddr();
const labelUList& addr = addressing.losortAddr();
forAll(addressing, cellI)
{
Pout<< " cell:" << cellI << nl;
label start = startAddr[cellI];
label end = startAddr[cellI+1];
for (label index = start; index < end; index++)
{
Pout<< " nbr:" << l[addr[index]] << nl;
}
}
Pout<< " Patches:" << nl;
forAll(interfaces, i)
{
if (interfaces.set(i))
{
if (isA<processorLduInterface>(interfaces[i]))
{
const processorLduInterface& pldui =
refCast<const processorLduInterface>(interfaces[i]);
Pout<< " " << i
<< " me:" << pldui.myProcNo()
<< " nbr:" << pldui.neighbProcNo()
<< " comm:" << pldui.comm()
<< " tag:" << pldui.tag()
<< nl;
}
{
Pout<< " " << i << " addressing:" << nl;
const labelUList& faceCells = interfaces[i].faceCells();
forAll(faceCells, i)
{
Pout<< "\t\t" << i << '\t' << faceCells[i] << nl;
}
}
}
}
}
template<class ProcPatch>
lduSchedule nonBlockingSchedule
(
const lduInterfacePtrsList& interfaces
)
{
lduSchedule schedule(2*interfaces.size());
label slotI = 0;
forAll(interfaces, i)
{
if (interfaces.set(i) && !isA<ProcPatch>(interfaces[i]))
{
schedule[slotI].patch = i;
schedule[slotI].init = true;
slotI++;
schedule[slotI].patch = i;
schedule[slotI].init = false;
slotI++;
}
}
forAll(interfaces, i)
{
if (interfaces.set(i) && isA<ProcPatch>(interfaces[i]))
{
schedule[slotI].patch = i;
schedule[slotI].init = true;
slotI++;
}
}
forAll(interfaces, i)
{
if (interfaces.set(i) && isA<ProcPatch>(interfaces[i]))
{
schedule[slotI].patch = i;
schedule[slotI].init = false;
slotI++;
}
}
return schedule;
}
void sendReceive
(
const label comm,
const label tag,
const globalIndex& offsets,
const scalarField& field,
scalarField& allField
)
{
label nProcs = Pstream::nProcs(comm);
if (Pstream::master(comm))
{
allField.setSize(offsets.size());
// Assign master slot
SubList<scalar>
(
allField,
offsets.localSize(0),
offsets.offset(0)
).assign(field);
// Assign slave slots
for (label procI = 1; procI < nProcs; procI++)
{
SubList<scalar> procSlot
(
allField,
offsets.localSize(procI),
offsets.offset(procI)
);
Pout<< "Receiving allField from " << procI
<< " at offset:" << offsets.offset(procI)
<< " size:" << offsets.size()
<< endl;
IPstream::read
(
Pstream::nonBlocking,
procI,
reinterpret_cast<char*>(procSlot.begin()),
procSlot.byteSize(),
tag,
comm
);
}
}
else
{
OPstream::write
(
Pstream::nonBlocking,
0, // master
reinterpret_cast<const char*>(field.begin()),
field.byteSize(),
tag,
comm
);
}
}
void sendReceive
(
const label comm,
const label tag,
const globalIndex& offsets,
const FieldField<Field, scalar>& field,
FieldField<Field, scalar>& allField
)
{
PstreamBuffers pBufs(Pstream::nonBlocking, Pstream::msgType(), comm);
if (!Pstream::master(comm))
{
UOPstream toMaster(Pstream::masterNo(), pBufs);
Pout<< "To 0 sending " << field.size()
<< " fields." << endl;
forAll(field, intI)
{
toMaster << field[intI];
}
}
pBufs.finishedSends();
if (Pstream::master(comm))
{
allField.setSize(offsets.size());
forAll(allField, i)
{
allField.set(i, new scalarField(0));
}
// Insert master values
forAll(field, intI)
{
allField[intI] = field[intI];
}
// Receive and insert slave values
label nProcs = Pstream::nProcs(comm);
for (label procI = 1; procI < nProcs; procI++)
{
UIPstream fromSlave(procI, pBufs);
label nSlaveInts = offsets.localSize(procI);
Pout<< "From " << procI << " receiving "
<< nSlaveInts << " fields." << endl;
for (label intI = 0; intI < nSlaveInts; intI++)
{
label slotI = offsets.toGlobal(procI, intI);
Pout<< " int:" << intI << " goes into slot " << slotI
<< endl;
fromSlave >> allField[slotI];
}
}
}
}
void collect
(
const label comm,
const globalIndex& cellOffsets,
const globalIndex& faceOffsets,
const scalarField& diagonal,
const scalarField& upper,
const scalarField& lower,
scalarField& allDiagonal,
scalarField& allUpper,
scalarField& allLower
)
{
label nOutstanding = Pstream::nRequests();
int allDiagonalTag = Pstream::allocateTag("allDiagonal:" __FILE__);
int allUpperTag = Pstream::allocateTag("allUpper:" __FILE__);
int allLowerTag = Pstream::allocateTag("allLower:" __FILE__);
sendReceive
(
comm,
allDiagonalTag,
cellOffsets,
diagonal,
allDiagonal
);
sendReceive
(
comm,
allUpperTag,
faceOffsets,
upper,
allUpper
);
sendReceive
(
comm,
allLowerTag,
faceOffsets,
lower,
allLower
);
Pstream::waitRequests(nOutstanding);
Pstream::freeTag("allDiagonal:" __FILE__, allDiagonalTag);
Pstream::freeTag("allUpper:" __FILE__, allUpperTag);
Pstream::freeTag("allLower:" __FILE__, allLowerTag);
}
void setCommunicator(fvMesh& mesh, const label newComm)
{
const polyBoundaryMesh& pbm = mesh.boundaryMesh();
// The current state is consistent with the mesh so check where the new
// communicator is and adjust accordingly.
forAll(pbm, patchI)
{
if (isA<processorPolyPatch>(pbm[patchI]))
{
processorPolyPatch& ppp = const_cast<processorPolyPatch&>
(
refCast
<
const processorPolyPatch
>(pbm[patchI])
);
label thisRank = UPstream::procNo
(
newComm,
ppp.comm(),
ppp.myProcNo()
);
label nbrRank = UPstream::procNo
(
newComm,
ppp.comm(),
ppp.neighbProcNo()
);
//ppp.comm() = newComm;
ppp.myProcNo() = thisRank;
ppp.neighbProcNo() = nbrRank;
}
}
mesh.polyMesh::comm() = newComm;
}
namespace Foam
{
typedef UPtrList<const GAMGInterfaceField> GAMGInterfaceFieldPtrsList;
}
// Gather matrices from processors procIDs[1..] on procIDs[0]
void gatherMatrices
(
const labelList& procIDs,
const PtrList<lduMesh>& procMeshes,
const lduMatrix& mat,
const FieldField<Field, scalar>& interfaceBouCoeffs,
const FieldField<Field, scalar>& interfaceIntCoeffs,
const lduInterfaceFieldPtrsList& interfaces,
PtrList<lduMatrix>& otherMats,
PtrList<FieldField<Field, scalar> >& otherBouCoeffs,
PtrList<FieldField<Field, scalar> >& otherIntCoeffs,
PtrList<GAMGInterfaceFieldPtrsList>& otherInterfaces
)
{
const label meshComm = mat.mesh().comm();
//lduInterfacePtrsList interfaces(mesh.interfaces());
if (Pstream::myProcNo(meshComm) == procIDs[0])
{
// Master.
otherMats.setSize(procIDs.size()-1);
otherBouCoeffs.setSize(procIDs.size()-1);
otherIntCoeffs.setSize(procIDs.size()-1);
otherInterfaces.setSize(procIDs.size()-1);
for (label i = 1; i < procIDs.size(); i++)
{
const lduMesh& procMesh = procMeshes[i];
const lduInterfacePtrsList procInterfaces = procMesh.interfaces();
IPstream fromSlave
(
Pstream::scheduled,
procIDs[i],
0, // bufSize
Pstream::msgType(),
meshComm
);
otherMats.set(i-1, new lduMatrix(procMesh, fromSlave));
// Receive number of/valid interfaces
boolList validTransforms(fromSlave);
List<int> validRanks(fromSlave);
// Size coefficients
otherBouCoeffs.set
(
i-1,
new FieldField<Field, scalar>(validTransforms.size())
);
otherIntCoeffs.set
(
i-1,
new FieldField<Field, scalar>(validTransforms.size())
);
otherInterfaces.set
(
i-1,
new GAMGInterfaceFieldPtrsList(validTransforms.size())
);
forAll(validTransforms, intI)
{
if (validTransforms[intI])
{
const processorGAMGInterface& interface =
refCast<const processorGAMGInterface>
(
procInterfaces[intI]
);
otherBouCoeffs[i-1].set(intI, new scalarField(fromSlave));
otherIntCoeffs[i-1].set(intI, new scalarField(fromSlave));
otherInterfaces[i-1].set
(
intI,
GAMGInterfaceField::New
(
interface, //procInterfaces[intI],
validTransforms[intI],
validRanks[intI]
).ptr()
);
}
}
}
}
else
{
// Send to master
OPstream toMaster
(
Pstream::scheduled,
procIDs[0],
0,
Pstream::msgType(),
meshComm
);
// Count valid interfaces
boolList validTransforms(interfaceBouCoeffs.size(), false);
List<int> validRanks(interfaceBouCoeffs.size(), -1);
forAll(interfaces, intI)
{
if (interfaces.set(intI))
{
const processorLduInterfaceField& interface =
refCast<const processorLduInterfaceField>
(
interfaces[intI]
);
validTransforms[intI] = interface.doTransform();
validRanks[intI] = interface.rank();
}
}
toMaster << mat << validTransforms << validRanks;
forAll(validTransforms, intI)
{
if (validTransforms[intI])
{
toMaster
<< interfaceBouCoeffs[intI]
<< interfaceIntCoeffs[intI];
}
}
}
}
int main(int argc, char *argv[])
{
#include "setRootCase.H"
#include "createTime.H"
#include "createMesh.H"
#include "createFields.H"
simpleControl simple(mesh);
//const polyBoundaryMesh& pbm = mesh.boundaryMesh();
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
Info<< "\nCalculating temperature distribution\n" << endl;
// Get a subset of processors
labelList subProcs(3);
subProcs[0] = 0;
subProcs[1] = 1;
subProcs[2] = 2;
const UPstream::communicator newComm
(
UPstream::worldComm,
subProcs,
true
);
Pout<< "procIDs world :" << UPstream::procID(UPstream::worldComm) << endl;
Pout<< "procIDs newComm:" << UPstream::procID(newComm) << endl;
//// On ALL processors: get the interfaces:
//lduInterfacePtrsList interfaces(mesh.interfaces());
//PtrList<lduMesh> procMeshes;
//
//if (Pstream::myProcNo(newComm) != -1)
//{
// print("InitialMesh", mesh);
//
// labelList procIDs(3);
// procIDs[0] = 0;
// procIDs[1] = 1;
// procIDs[2] = 2;
//
////XXXXXX
// // Collect meshes from procs 0,1 (in newComm) on 1.
// lduPrimitiveMesh::gather(mesh, procIDs, procMeshes);
//
// if (Pstream::myProcNo(newComm) == procIDs[0])
// {
// // Print a bit
// forAll(procMeshes, i)
// {
// const lduMesh& pMesh = procMeshes[i];
// print("procMesh" + Foam::name(i), pMesh);
//
// const lduAddressing& addr = pMesh.lduAddr();
// checkUpperTriangular
// (
// addr.size(),
// addr.lowerAddr(),
// addr.upperAddr()
// );
// }
//
//
// // Combine
// labelList cellOffsets;
// labelListList faceMap;
// labelListList boundaryMap;
// labelListListList boundaryFaceMap;
// //autoPtr<lduPrimitiveMesh> allMeshPtr = combineMeshes
// //(
// // newComm,
// // procIDs,
// // procMeshes,
// //
// // cellOffsets, // per mesh the starting cell
// // faceMap, // per mesh the starting face
// // boundaryMap, // per mesh,per interface the starting face
// // boundaryFaceMap
// //);
// //const lduPrimitiveMesh& allMesh = allMeshPtr();
// const lduPrimitiveMesh allMesh
// (
// newComm,
// procIDs,
// procMeshes,
//
// cellOffsets,
// faceMap,
// boundaryMap,
// boundaryFaceMap
// );
//
//
// print("ALLMESH", allMesh);
//
// forAll(procMeshes, procMeshI)
// {
// const lduMesh& pMesh = procMeshes[procMeshI];
// //const lduAddressing& pAddressing = pMesh.lduAddr();
//
// Pout<< "procMesh" << procMeshI << endl
// << " cells start at:" << cellOffsets[procMeshI] << endl
// << " faces to to:" << faceMap[procMeshI] << endl;
//
// lduInterfacePtrsList interfaces = pMesh.interfaces();
// forAll(interfaces, intI)
// {
// Pout<< " patch:" << intI
// << " becomes patch:" << boundaryMap[procMeshI][intI]
// << endl;
//
// Pout<< " patch:" << intI
// << " faces become faces:"
// << boundaryFaceMap[procMeshI][intI]
// << endl;
// }
// }
// }
//
//
// // Construct test data
// // ~~~~~~~~~~~~~~~~~~~
//
// GAMGInterfaceFieldPtrsList interfaces(interfaces.size());
// FieldField<Field, scalar> interfaceBouCoeffs(interfaces.size());
// FieldField<Field, scalar> interfaceIntCoeffs(interfaces.size());
//
// forAll(interfaces, intI)
// {
// if (interfaces.set(intI))
// {
// label size = interfaces[intI].size();
//
// interfaces.set
// (
// intI,
// GAMGInterfaceField::New
// (
// mesh.interfaces()[intI],
// interfaces[intI]
// )
// );
// interfaceBouCoeffs.set(intI, new scalarField(size, 111));
// interfaceIntCoeffs.set(intI, new scalarField(size, 222));
// }
// }
//
//
// PtrList<lduMatrix> otherMats;
// PtrList<FieldField<Field, scalar> > otherBouCoeffs;
// PtrList<FieldField<Field, scalar> > otherIntCoeffs;
// PtrList<GAMGInterfaceFieldPtrsList> otherInterfaces;
// gatherMatrices
// (
// procIDs,
// procMeshes,
//
// mat,
// interfaceBouCoeffs,
// interfaceIntCoeffs,
// interfaces,
//
// otherMats,
// otherBouCoeffs,
// otherIntCoeffs,
// otherInterfaces
// );
////XXXXXX
//}
{
Pout<< "World:" << UPstream::worldComm
<< " procID:" << 2
<< " subComm:" << newComm
<< " rank1:" << UPstream::procNo(newComm, UPstream::worldComm, 1)
<< " rank2:" << UPstream::procNo(newComm, UPstream::worldComm, 2)
<< endl;
}
while (simple.loop())
{
Info<< "Time = " << runTime.timeName() << nl << endl;
while (simple.correctNonOrthogonal())
{
fvScalarMatrix Teqn
(
//fvm::ddt(T) - fvm::laplacian(DT, T)
fvm::laplacian(DT, T)
);
{
label oldWarn = UPstream::warnComm;
UPstream::warnComm = newComm;
label oldComm = mesh.comm();
setCommunicator(mesh, newComm);
Pout<< "** oldcomm:" << oldComm
<< " newComm:" << mesh.comm() << endl;
if (Pstream::myProcNo(mesh.comm()) != -1)
{
solve(Teqn);
}
setCommunicator(mesh, oldComm);
Pout<< "** reset mesh to:" << mesh.comm() << endl;
UPstream::warnComm = oldWarn;
}
}
#include "write.H"
Info<< "ExecutionTime = " << runTime.elapsedCpuTime() << " s"
<< " ClockTime = " << runTime.elapsedClockTime() << " s"
<< nl << endl;
}
Pout<< "End\n" << endl;
return 0;
}
// ************************************************************************* //

View File

@ -0,0 +1,46 @@
if (runTime.outputTime())
{
volVectorField gradT(fvc::grad(T));
volScalarField gradTx
(
IOobject
(
"gradTx",
runTime.timeName(),
mesh,
IOobject::NO_READ,
IOobject::AUTO_WRITE
),
gradT.component(vector::X)
);
volScalarField gradTy
(
IOobject
(
"gradTy",
runTime.timeName(),
mesh,
IOobject::NO_READ,
IOobject::AUTO_WRITE
),
gradT.component(vector::Y)
);
volScalarField gradTz
(
IOobject
(
"gradTz",
runTime.timeName(),
mesh,
IOobject::NO_READ,
IOobject::AUTO_WRITE
),
gradT.component(vector::Z)
);
runTime.write();
}

View File

@ -0,0 +1,3 @@
Test-parallel-communicators.C
EXE = $(FOAM_USER_APPBIN)/Test-parallel-communicators

View File

@ -0,0 +1,203 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2013 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Application
Test-parallel-communicators
Description
Checks communication using user-defined communicators
\*---------------------------------------------------------------------------*/
#include "argList.H"
#include "Time.H"
#include "IPstream.H"
#include "OPstream.H"
#include "vector.H"
#include "IOstreams.H"
#include "PstreamReduceOps.H"
using namespace Foam;
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
scalar sumReduce
(
const label comm,
const scalar localValue
)
{
scalar sum;
if (Pstream::parRun())
{
if (UPstream::master(comm))
{
// Add master value and all slaves
sum = localValue;
for
(
int slave=Pstream::firstSlave();
slave<=Pstream::lastSlave(comm);
slave++
)
{
scalar slaveValue;
UIPstream::read
(
Pstream::blocking,
slave,
reinterpret_cast<char*>(&slaveValue),
sizeof(scalar),
UPstream::msgType(), // tag
comm // communicator
);
sum += slaveValue;
}
// Send back to slaves
for
(
int slave=UPstream::firstSlave();
slave<=UPstream::lastSlave(comm);
slave++
)
{
UOPstream::write
(
UPstream::blocking,
slave,
reinterpret_cast<const char*>(&sum),
sizeof(scalar),
UPstream::msgType(), // tag
comm // communicator
);
}
}
else
{
{
UOPstream::write
(
UPstream::blocking,
UPstream::masterNo(),
reinterpret_cast<const char*>(&localValue),
sizeof(scalar),
UPstream::msgType(), // tag
comm // communicator
);
}
{
UIPstream::read
(
UPstream::blocking,
UPstream::masterNo(),
reinterpret_cast<char*>(&sum),
sizeof(scalar),
UPstream::msgType(), // tag
comm // communicator
);
}
}
}
return sum;
}
int main(int argc, char *argv[])
{
# include "setRootCase.H"
# include "createTime.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// Allocate a communicator
label n = Pstream::nProcs(UPstream::worldComm);
DynamicList<label> bottom;
DynamicList<label> top;
for (label i = 0; i < n/2; i++)
{
bottom.append(i);
}
for (label i = n/2; i < n; i++)
{
top.append(i);
}
//Pout<< "bottom:" << bottom << endl;
Pout<< "top :" << top << endl;
scalar localValue = 111*UPstream::myProcNo(UPstream::worldComm);
Pout<< "localValue :" << localValue << endl;
label comm = Pstream::allocateCommunicator
(
UPstream::worldComm,
top
);
Pout<< "allocated comm :" << comm << endl;
Pout<< "comm myproc :" << Pstream::myProcNo(comm)
<< endl;
if (Pstream::myProcNo(comm) != -1)
{
//scalar sum = sumReduce(comm, localValue);
//scalar sum = localValue;
//reduce
//(
// UPstream::treeCommunication(comm),
// sum,
// sumOp<scalar>(),
// Pstream::msgType(),
// comm
//);
scalar sum = returnReduce
(
localValue,
sumOp<scalar>(),
Pstream::msgType(),
comm
);
Pout<< "sum :" << sum << endl;
}
Pstream::freeCommunicator(comm);
Pout<< "End\n" << endl;
return 0;
}
// ************************************************************************* //

View File

@ -493,6 +493,7 @@ int main(int argc, char *argv[])
mesh.nFaces(), // start
patchI, // index
mesh.boundaryMesh(),// polyBoundaryMesh
Pstream::worldComm, // communicator
Pstream::myProcNo(),// myProcNo
nbrProcI // neighbProcNo
)

View File

@ -222,6 +222,11 @@ castellatedMeshControls
// are only on the boundary of corresponding cellZones or also allow
// free-standing zone faces. Not used if there are no faceZones.
allowFreeStandingZoneFaces true;
// Optional: whether all baffles get eroded away. WIP. Used for
// surface simplification.
//allowFreeStandingBaffles false;
}
// Settings for the snapping.

View File

@ -148,7 +148,7 @@ bool Foam::checkWedges
{
Info<< " ***Wedge patch " << pp.name() << " not planar."
<< " Point " << pt << " is not in patch plane by "
<< d << " meter."
<< d << " metre."
<< endl;
}
return true;
@ -854,7 +854,7 @@ Foam::label Foam::checkGeometry(const polyMesh& mesh, const bool allGeometry)
if (allGeometry)
{
faceSet faces(mesh, "lowVolRatioFaces", mesh.nFaces()/100);
if (mesh.checkVolRatio(true, 0.05, &faces))
if (mesh.checkVolRatio(true, 0.01, &faces))
{
noFailedChecks++;

View File

@ -62,7 +62,7 @@ int main(int argc, char *argv[])
boundBox bb(points);
Info<< "bounding box: min = " << bb.min()
<< " max = " << bb.max() << " meters."
<< " max = " << bb.max() << " metres."
<< endl;

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
@ -54,7 +54,7 @@ Foam::label Foam::mergePolyMesh::patchIndex(const polyPatch& p)
{
if (patchNames_[patchI] == pName)
{
if (patchTypes_[patchI] == pType)
if (word(patchDicts_[patchI]["type"]) == pType)
{
// Found name and types match
return patchI;
@ -68,7 +68,11 @@ Foam::label Foam::mergePolyMesh::patchIndex(const polyPatch& p)
}
// Patch not found. Append to the list
patchTypes_.append(pType);
{
OStringStream os;
p.write(os);
patchDicts_.append(dictionary(IStringStream(os.str())()));
}
if (nameFound)
{
@ -121,20 +125,22 @@ Foam::mergePolyMesh::mergePolyMesh(const IOobject& io)
:
polyMesh(io),
meshMod_(*this),
patchTypes_(2*boundaryMesh().size()),
patchNames_(2*boundaryMesh().size()),
patchDicts_(2*boundaryMesh().size()),
pointZoneNames_(),
faceZoneNames_(),
cellZoneNames_()
{
// Insert the original patches into the list
wordList curPatchTypes = boundaryMesh().types();
wordList curPatchNames = boundaryMesh().names();
forAll(curPatchTypes, patchI)
forAll(boundaryMesh(), patchI)
{
patchTypes_.append(curPatchTypes[patchI]);
patchNames_.append(curPatchNames[patchI]);
patchNames_.append(boundaryMesh()[patchI].name());
OStringStream os;
boundaryMesh()[patchI].write(os);
patchDicts_.append(dictionary(IStringStream(os.str())()));
}
// Insert point, face and cell zones into the list
@ -379,7 +385,7 @@ void Foam::mergePolyMesh::addMesh(const polyMesh& m)
void Foam::mergePolyMesh::merge()
{
Info<< "patch names: " << patchNames_ << nl
<< "patch types: " << patchTypes_ << nl
<< "patch dicts: " << patchDicts_ << nl
<< "point zone names: " << pointZoneNames_ << nl
<< "face zone names: " << faceZoneNames_ << nl
<< "cell zone names: " << cellZoneNames_ << endl;
@ -409,14 +415,16 @@ void Foam::mergePolyMesh::merge()
for (; patchI < patchNames_.size(); patchI++)
{
// Add a patch
dictionary dict(patchDicts_[patchI]);
dict.set("nFaces", 0);
dict.set("startFace", endOfLastPatch);
newPatches[patchI] =
(
polyPatch::New
(
patchTypes_[patchI],
patchNames_[patchI],
0,
endOfLastPatch,
dict,
patchI,
oldPatches
).ptr()

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
@ -58,12 +58,12 @@ class mergePolyMesh
//- Topological change to accumulated all mesh changes
polyTopoChange meshMod_;
//- Patch types
DynamicList<word> patchTypes_;
//- Patch names
DynamicList<word> patchNames_;
//- Patch dictionaries
DynamicList<dictionary> patchDicts_;
//- Point zone names
DynamicList<word> pointZoneNames_;

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
@ -448,6 +448,7 @@ bool Foam::domainDecomposition::writeDecomposition()
curStart,
nPatches,
procMesh.boundaryMesh(),
Pstream::worldComm,
procI,
curNeighbourProcessors[procPatchI]
);
@ -475,6 +476,7 @@ bool Foam::domainDecomposition::writeDecomposition()
curStart,
nPatches,
procMesh.boundaryMesh(),
Pstream::worldComm,
procI,
curNeighbourProcessors[procPatchI],
referPatch,

View File

@ -1043,7 +1043,6 @@ int main(int argc, char *argv[])
surfaceMeshWriter writer
(
vMesh,
binary,
pp,
fz.name(),

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
@ -30,14 +30,12 @@ License
Foam::surfaceMeshWriter::surfaceMeshWriter
(
const vtkMesh& vMesh,
const bool binary,
const indirectPrimitivePatch& pp,
const word& name,
const fileName& fName
)
:
vMesh_(vMesh),
binary_(binary),
pp_(pp),
fName_(fName),
@ -78,8 +76,4 @@ Foam::surfaceMeshWriter::surfaceMeshWriter
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
// ************************************************************************* //

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
@ -53,13 +53,11 @@ namespace Foam
class volPointInterpolation;
/*---------------------------------------------------------------------------*\
Class surfaceMeshWriter Declaration
Class surfaceMeshWriter Declaration
\*---------------------------------------------------------------------------*/
class surfaceMeshWriter
{
const vtkMesh& vMesh_;
const bool binary_;
const indirectPrimitivePatch& pp_;
@ -68,9 +66,6 @@ class surfaceMeshWriter
std::ofstream os_;
// label nPoints_;
//
// label nFaces_;
public:
@ -79,7 +74,6 @@ public:
//- Construct from components
surfaceMeshWriter
(
const vtkMesh&,
const bool binary,
const indirectPrimitivePatch& pp,
const word& name,
@ -94,19 +88,6 @@ public:
return os_;
}
// label nPoints() const
// {
// return nPoints_;
// }
//
// label nFaces() const
// {
// return nFaces_;
// }
//
// //- Write cellIDs
// void writePatchIDs();
//- Extract face data
template<class Type>
tmp<Field<Type> > getFaceField

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License

View File

@ -179,12 +179,13 @@ void Foam::vtkPV398Foam::convertMeshPatches
const word patchName = getPartName(partId);
labelHashSet patchIds(patches.patchSet(List<wordRe>(1, patchName)));
labelHashSet
patchIds(patches.patchSet(List<wordRe>(1, wordRe(patchName))));
if (debug)
{
Info<< "Creating VTK mesh for patches [" << patchIds <<"] "
<< patchName << endl;
<< patchName << endl;
}
vtkPolyData* vtkmesh = NULL;

View File

@ -97,6 +97,33 @@ int main(int argc, char *argv[])
cci.write();
}
volScalarField V
(
IOobject
(
"V",
runTime.timeName(),
mesh,
IOobject::NO_READ,
IOobject::AUTO_WRITE,
false
),
mesh,
dimensionedScalar("V", mesh.V().dimensions(), 0.0),
calculatedFvPatchField<scalar>::typeName
);
V.dimensionedInternalField() = mesh.V();
forAll(V.boundaryField(), patchI)
{
V.boundaryField()[patchI] =
V.boundaryField()[patchI].patch().magSf();
}
Info<< "Writing cellVolumes and patch faceAreas to " << V.name()
<< " in " << runTime.timeName() << endl;
V.write();
}
Info<< "\nEnd\n" << endl;

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
@ -40,6 +40,7 @@ Description
#include "pairPatchAgglomeration.H"
#include "labelListIOList.H"
#include "syncTools.H"
#include "globalIndex.H"
using namespace Foam;
@ -53,7 +54,7 @@ int main(int argc, char *argv[])
#include "createTime.H"
#include "createNamedMesh.H"
const word dictName("faceAgglomerateDict");
const word dictName("viewFactorsDict");
#include "setConstantMeshDictionaryIO.H"
@ -79,16 +80,16 @@ int main(int argc, char *argv[])
boundary.size()
);
forAll(boundary, patchId)
label nCoarseFaces = 0;
forAllConstIter(dictionary, agglomDict, iter)
{
const polyPatch& pp = boundary[patchId];
label patchI = pp.index();
finalAgglom[patchI].setSize(pp.size(), 0);
if (!pp.coupled())
labelList patchIds = boundary.findIndices(iter().keyword());
forAll(patchIds, i)
{
if (agglomDict.found(pp.name()))
label patchI = patchIds[i];
const polyPatch& pp = boundary[patchI];
if (!pp.coupled())
{
Info << "\nAgglomerating patch : " << pp.name() << endl;
pairPatchAgglomeration agglomObject
@ -99,12 +100,11 @@ int main(int argc, char *argv[])
agglomObject.agglomerate();
finalAgglom[patchI] =
agglomObject.restrictTopBottomAddressing();
}
else
{
FatalErrorIn(args.executable())
<< "Patch " << pp.name() << " not found in dictionary: "
<< agglomDict.name() << exit(FatalError);
if (finalAgglom[patchI].size())
{
nCoarseFaces += max(finalAgglom[patchI] + 1);
}
}
}
}
@ -144,6 +144,7 @@ int main(int argc, char *argv[])
if (writeAgglom)
{
globalIndex index(nCoarseFaces);
volScalarField facesAgglomeration
(
IOobject
@ -158,14 +159,26 @@ int main(int argc, char *argv[])
dimensionedScalar("facesAgglomeration", dimless, 0)
);
label coarsePatchIndex = 0;
forAll(boundary, patchId)
{
fvPatchScalarField& bFacesAgglomeration =
facesAgglomeration.boundaryField()[patchId];
forAll(bFacesAgglomeration, j)
const polyPatch& pp = boundary[patchId];
if (pp.size() > 0)
{
bFacesAgglomeration[j] = finalAgglom[patchId][j];
fvPatchScalarField& bFacesAgglomeration =
facesAgglomeration.boundaryField()[patchId];
forAll(bFacesAgglomeration, j)
{
bFacesAgglomeration[j] =
index.toGlobal
(
Pstream::myProcNo(),
finalAgglom[patchId][j] + coarsePatchIndex
);
}
coarsePatchIndex += max(finalAgglom[patchId]) + 1;
}
}

View File

@ -17,6 +17,12 @@ FoamFile
// Write agglomeration as a volScalarField with calculated boundary values
writeFacesAgglomeration true;
//Debug option
debug 0;
//Dump connectivity rays
dumpRays false;
// Per patch (wildcard possible) the coarsening level
bottomAir_to_heater
{

View File

@ -0,0 +1,4 @@
mapLagrangian.C
mapFields.C
EXE = $(FOAM_APPBIN)/mapFieldsNew

View File

@ -0,0 +1,13 @@
EXE_INC = \
-DFULLDEBUG -g -O0 \
-I$(LIB_SRC)/meshTools/lnInclude \
-I$(LIB_SRC)/lagrangian/basic/lnInclude \
-I$(LIB_SRC)/finiteVolume/lnInclude \
-I$(LIB_SRC)/sampling/lnInclude
EXE_LIBS = \
-lsampling \
-lmeshTools \
-llagrangian \
-lfiniteVolume \
-lgenericPatchFields

View File

@ -0,0 +1,184 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
InNamespace
Foam
Description
Gets the indices of (source)particles that have been appended to the
target cloud and maps the lagrangian fields accordingly.
\*---------------------------------------------------------------------------*/
#ifndef MapLagrangianFields_H
#define MapLagrangianFields_H
#include "cloud.H"
#include "GeometricField.H"
#include "meshToMeshNew.H"
#include "IOobjectList.H"
#include "CompactIOField.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
//- Gets the indices of (source)particles that have been appended to the
// target cloud and maps the lagrangian fields accordingly.
template<class Type>
void MapLagrangianFields
(
const string& cloudName,
const IOobjectList& objects,
const polyMesh& meshTarget,
const labelList& addParticles
)
{
{
IOobjectList fields = objects.lookupClass(IOField<Type>::typeName);
forAllIter(IOobjectList, fields, fieldIter)
{
const word& fieldName = fieldIter()->name();
Info<< " mapping lagrangian field " << fieldName << endl;
// Read field (does not need mesh)
IOField<Type> fieldSource(*fieldIter());
// Map
IOField<Type> fieldTarget
(
IOobject
(
fieldName,
meshTarget.time().timeName(),
cloud::prefix/cloudName,
meshTarget,
IOobject::NO_READ,
IOobject::NO_WRITE,
false
),
addParticles.size()
);
forAll(addParticles, i)
{
fieldTarget[i] = fieldSource[addParticles[i]];
}
// Write field
fieldTarget.write();
}
}
{
IOobjectList fieldFields =
objects.lookupClass(IOField<Field<Type> >::typeName);
forAllIter(IOobjectList, fieldFields, fieldIter)
{
const word& fieldName = fieldIter()->name();
Info<< " mapping lagrangian fieldField " << fieldName << endl;
// Read field (does not need mesh)
IOField<Field<Type> > fieldSource(*fieldIter());
// Map - use CompactIOField to automatically write in
// compact form for binary format.
CompactIOField<Field<Type>, Type> fieldTarget
(
IOobject
(
fieldName,
meshTarget.time().timeName(),
cloud::prefix/cloudName,
meshTarget,
IOobject::NO_READ,
IOobject::NO_WRITE,
false
),
addParticles.size()
);
forAll(addParticles, i)
{
fieldTarget[i] = fieldSource[addParticles[i]];
}
// Write field
fieldTarget.write();
}
}
{
IOobjectList fieldFields =
objects.lookupClass(CompactIOField<Field<Type>, Type>::typeName);
forAllIter(IOobjectList, fieldFields, fieldIter)
{
Info<< " mapping lagrangian fieldField "
<< fieldIter()->name() << endl;
// Read field (does not need mesh)
CompactIOField<Field<Type>, Type> fieldSource(*fieldIter());
// Map
CompactIOField<Field<Type>, Type> fieldTarget
(
IOobject
(
fieldIter()->name(),
meshTarget.time().timeName(),
cloud::prefix/cloudName,
meshTarget,
IOobject::NO_READ,
IOobject::NO_WRITE,
false
),
addParticles.size()
);
forAll(addParticles, i)
{
fieldTarget[i] = fieldSource[addParticles[i]];
}
// Write field
fieldTarget.write();
}
}
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,131 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#ifndef MapMeshes_H
#define MapMeshes_H
#include "MapVolFields.H"
#include "mapLagrangian.H"
#include "UnMapped.H"
#include "pointMesh.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
template<template<class> class CombineOp>
void MapMesh
(
const meshToMeshNew& interp,
const HashSet<word>& selectedFields,
const bool noLagrangian
)
{
{
const polyMesh& meshSource = interp.srcRegion();
// Search for list of objects for this time
IOobjectList objects(meshSource, meshSource.time().timeName());
// Map volFields
// ~~~~~~~~~~~~~
MapVolFields<scalar>
(
objects,
selectedFields,
interp,
CombineOp<scalar>()
);
MapVolFields<vector>
(
objects,
selectedFields,
interp,
CombineOp<vector>()
);
MapVolFields<sphericalTensor>
(
objects,
selectedFields,
interp,
CombineOp<sphericalTensor>()
);
MapVolFields<symmTensor>
(
objects,
selectedFields,
interp,
CombineOp<symmTensor>()
);
MapVolFields<tensor>
(
objects,
selectedFields,
interp,
CombineOp<tensor>()
);
}
{
const polyMesh& meshTarget = interp.tgtRegion();
// Search for list of target objects for this time
IOobjectList objects(meshTarget, meshTarget.time().timeName());
// Mark surfaceFields as unmapped
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
UnMapped<surfaceScalarField>(objects);
UnMapped<surfaceVectorField>(objects);
UnMapped<surfaceSphericalTensorField>(objects);
UnMapped<surfaceSymmTensorField>(objects);
UnMapped<surfaceTensorField>(objects);
// Mark pointFields as unmapped
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
UnMapped<pointScalarField>(objects);
UnMapped<pointVectorField>(objects);
UnMapped<pointSphericalTensorField>(objects);
UnMapped<pointSymmTensorField>(objects);
UnMapped<pointTensorField>(objects);
}
if (!noLagrangian)
{
mapLagrangian(interp);
}
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,104 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#ifndef MapConsistentVolFields_H
#define MapConsistentVolFields_H
#include "GeometricField.H"
#include "meshToMeshNew.H"
#include "IOobjectList.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
template<class Type, class CombineOp>
void MapVolFields
(
const IOobjectList& objects,
const HashSet<word>& selectedFields,
const meshToMeshNew& interp,
const CombineOp& cop
)
{
typedef GeometricField<Type, fvPatchField, volMesh> fieldType;
const fvMesh& meshSource = static_cast<const fvMesh&>(interp.srcRegion());
const fvMesh& meshTarget = static_cast<const fvMesh&>(interp.tgtRegion());
IOobjectList fields = objects.lookupClass(fieldType::typeName);
forAllIter(IOobjectList, fields, fieldIter)
{
const word& fieldName = fieldIter()->name();
if (selectedFields.empty() || selectedFields.found(fieldName))
{
Info<< " interpolating " << fieldName << endl;
const fieldType fieldSource(*fieldIter(), meshSource);
IOobject targetIO
(
fieldName,
meshTarget.time().timeName(),
meshTarget,
IOobject::MUST_READ
);
if (targetIO.headerOk())
{
fieldType fieldTarget(targetIO, meshTarget);
interp.mapSrcToTgt(fieldSource, cop, fieldTarget);
fieldTarget.write();
}
else
{
targetIO.readOpt() = IOobject::NO_READ;
tmp<fieldType>
tfieldTarget(interp.mapSrcToTgt(fieldSource, cop));
fieldType fieldTarget(targetIO, tfieldTarget);
fieldTarget.write();
}
}
}
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,57 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#ifndef UnMapped_H
#define UnMapped_H
#include "IOobjectList.H"
#include "OSspecific.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
template<class Type>
void UnMapped(const IOobjectList& objects)
{
IOobjectList fields = objects.lookupClass(Type::typeName);
forAllConstIter(IOobjectList, fields, fieldIter)
{
mvBak(fieldIter()->objectPath(), "unmapped");
}
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,11 @@
Info<< "\nCreate databases as time" << endl;
HashTable<string> srcOptions(args.options());
srcOptions.erase("case");
srcOptions.insert("case", fileName(rootDirSource/caseDirSource));
argList argsSrc(args, srcOptions, false, false, false);
Time runTimeSource(Time::controlDictName, argsSrc);
Time runTimeTarget(Time::controlDictName, args);

View File

@ -0,0 +1,343 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Application
mapFields
Description
Maps volume fields from one mesh to another, reading and
interpolating all fields present in the time directory of both cases.
\*---------------------------------------------------------------------------*/
#include "fvCFD.H"
#include "meshToMeshNew.H"
#include "processorPolyPatch.H"
#include "MapMeshes.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
void mapConsistentMesh
(
const fvMesh& meshSource,
const fvMesh& meshTarget,
const meshToMeshNew::interpolationMethod& mapMethod,
const bool subtract,
const HashSet<word>& selectedFields,
const bool noLagrangian
)
{
Info<< nl << "Consistently creating and mapping fields for time "
<< meshSource.time().timeName() << nl << endl;
meshToMeshNew interp(meshSource, meshTarget, mapMethod);
if (subtract)
{
MapMesh<minusEqOp>
(
interp,
selectedFields,
noLagrangian
);
}
else
{
MapMesh<plusEqOp>
(
interp,
selectedFields,
noLagrangian
);
}
}
void mapSubMesh
(
const fvMesh& meshSource,
const fvMesh& meshTarget,
const HashTable<word>& patchMap,
const wordList& cuttingPatches,
const meshToMeshNew::interpolationMethod& mapMethod,
const bool subtract,
const HashSet<word>& selectedFields,
const bool noLagrangian
)
{
Info<< nl << "Creating and mapping fields for time "
<< meshSource.time().timeName() << nl << endl;
meshToMeshNew interp
(
meshSource,
meshTarget,
mapMethod,
patchMap,
cuttingPatches
);
if (subtract)
{
MapMesh<minusEqOp>
(
interp,
selectedFields,
noLagrangian
);
}
else
{
MapMesh<plusEqOp>
(
interp,
selectedFields,
noLagrangian
);
}
}
wordList addProcessorPatches
(
const fvMesh& meshTarget,
const wordList& cuttingPatches
)
{
// Add the processor patches to the cutting list
HashSet<word> cuttingPatchTable;
forAll(cuttingPatches, i)
{
cuttingPatchTable.insert(cuttingPatches[i]);
}
const polyBoundaryMesh& pbm = meshTarget.boundaryMesh();
forAll(pbm, patchI)
{
if (isA<processorPolyPatch>(pbm[patchI]))
{
const word& patchName = pbm[patchI].name();
cuttingPatchTable.insert(patchName);
}
}
return cuttingPatchTable.toc();
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
int main(int argc, char *argv[])
{
argList::addNote
(
"map volume fields from one mesh to another"
);
argList::validArgs.append("sourceCase");
argList::addOption
(
"sourceTime",
"scalar|'latestTime'",
"specify the source time"
);
argList::addOption
(
"sourceRegion",
"word",
"specify the source region"
);
argList::addOption
(
"targetRegion",
"word",
"specify the target region"
);
argList::addBoolOption
(
"consistent",
"source and target geometry and boundary conditions identical"
);
argList::addOption
(
"mapMethod",
"word",
"specify the mapping method"
);
argList::addBoolOption
(
"subtract",
"subtract mapped source from target"
);
argList::addOption
(
"fields",
"list",
"specify a list of fields to be mapped. Eg, '(U T p)' - "
"regular expressions not currently supported"
);
argList::addBoolOption
(
"noLagrangian",
"skip mapping lagrangian positions and fields"
);
argList args(argc, argv);
fileName rootDirTarget(args.rootPath());
fileName caseDirTarget(args.globalCaseName());
const fileName casePath = args[1];
const fileName rootDirSource = casePath.path();
const fileName caseDirSource = casePath.name();
Info<< "Source: " << rootDirSource << " " << caseDirSource << endl;
word sourceRegion = fvMesh::defaultRegion;
if (args.optionFound("sourceRegion"))
{
sourceRegion = args["sourceRegion"];
Info<< "Source region: " << sourceRegion << endl;
}
Info<< "Target: " << rootDirTarget << " " << caseDirTarget << endl;
word targetRegion = fvMesh::defaultRegion;
if (args.optionFound("targetRegion"))
{
targetRegion = args["targetRegion"];
Info<< "Target region: " << targetRegion << endl;
}
const bool consistent = args.optionFound("consistent");
meshToMeshNew::interpolationMethod mapMethod =
meshToMeshNew::imCellVolumeWeight;
if (args.optionFound("mapMethod"))
{
mapMethod = meshToMeshNew::interpolationMethodNames_[args["mapMethod"]];
Info<< "Mapping method: "
<< meshToMeshNew::interpolationMethodNames_[mapMethod] << endl;
}
const bool subtract = args.optionFound("subtract");
if (subtract)
{
Info<< "Subtracting mapped source field from target" << endl;
}
HashSet<word> selectedFields;
if (args.optionFound("fields"))
{
args.optionLookup("fields")() >> selectedFields;
}
const bool noLagrangian = args.optionFound("noLagrangian");
#include "createTimes.H"
HashTable<word> patchMap;
wordList cuttingPatches;
if (!consistent)
{
IOdictionary mapFieldsDict
(
IOobject
(
"mapFieldsDict",
runTimeTarget.system(),
runTimeTarget,
IOobject::MUST_READ_IF_MODIFIED,
IOobject::NO_WRITE,
false
)
);
mapFieldsDict.lookup("patchMap") >> patchMap;
mapFieldsDict.lookup("cuttingPatches") >> cuttingPatches;
}
#include "setTimeIndex.H"
Info<< "\nCreate meshes\n" << endl;
fvMesh meshSource
(
IOobject
(
sourceRegion,
runTimeSource.timeName(),
runTimeSource
)
);
fvMesh meshTarget
(
IOobject
(
targetRegion,
runTimeTarget.timeName(),
runTimeTarget
)
);
Info<< "Source mesh size: " << meshSource.nCells() << tab
<< "Target mesh size: " << meshTarget.nCells() << nl << endl;
if (consistent)
{
mapConsistentMesh
(
meshSource,
meshTarget,
mapMethod,
subtract,
selectedFields,
noLagrangian
);
}
else
{
mapSubMesh
(
meshSource,
meshTarget,
patchMap,
addProcessorPatches(meshTarget, cuttingPatches),
mapMethod,
subtract,
selectedFields,
noLagrangian
);
}
Info<< "\nEnd\n" << endl;
return 0;
}
// ************************************************************************* //

View File

@ -0,0 +1,30 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: dev |
| \\ / A nd | Web: www.OpenFOAM.org |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class dictionary;
object mapFieldsDict;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// List of pairs of source/target patches for mapping
patchMap
(
lid movingWall
);
// List of target patches cutting the source domain (these need to be
// handled specially e.g. interpolated from internal values)
cuttingPatches
(
fixedWalls
);
// ************************************************************************* //

View File

@ -0,0 +1,303 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "MapLagrangianFields.H"
#include "passiveParticleCloud.H"
#include "meshSearch.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
static const scalar perturbFactor = 1e-6;
// Special version of findCell that generates a cell guaranteed to be
// compatible with tracking.
static label findCell(const Cloud<passiveParticle>& cloud, const point& pt)
{
label cellI = -1;
label tetFaceI = -1;
label tetPtI = -1;
const polyMesh& mesh = cloud.pMesh();
mesh.findCellFacePt(pt, cellI, tetFaceI, tetPtI);
if (cellI >= 0)
{
return cellI;
}
else
{
// See if particle on face by finding nearest face and shifting
// particle.
meshSearch meshSearcher
(
mesh,
polyMesh::FACEPLANES // no decomposition needed
);
label faceI = meshSearcher.findNearestBoundaryFace(pt);
if (faceI >= 0)
{
const point& cc = mesh.cellCentres()[mesh.faceOwner()[faceI]];
const point perturbPt = (1-perturbFactor)*pt+perturbFactor*cc;
mesh.findCellFacePt(perturbPt, cellI, tetFaceI, tetPtI);
return cellI;
}
}
return -1;
}
void mapLagrangian(const meshToMeshNew& interp)
{
// Determine which particles are in meshTarget
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
const polyMesh& meshSource = interp.srcRegion();
const polyMesh& meshTarget = interp.tgtRegion();
const labelListList& sourceToTarget = interp.srcToTgtCellAddr();
const pointField& targetCc = meshTarget.cellCentres();
fileNameList cloudDirs
(
readDir
(
meshSource.time().timePath()/cloud::prefix,
fileName::DIRECTORY
)
);
forAll(cloudDirs, cloudI)
{
// Search for list of lagrangian objects for this time
IOobjectList objects
(
meshSource,
meshSource.time().timeName(),
cloud::prefix/cloudDirs[cloudI]
);
IOobject* positionsPtr = objects.lookup(word("positions"));
if (positionsPtr)
{
Info<< nl << " processing cloud " << cloudDirs[cloudI] << endl;
// Read positions & cell
passiveParticleCloud sourceParcels
(
meshSource,
cloudDirs[cloudI],
false
);
Info<< " read " << sourceParcels.size()
<< " parcels from source mesh." << endl;
// Construct empty target cloud
passiveParticleCloud targetParcels
(
meshTarget,
cloudDirs[cloudI],
IDLList<passiveParticle>()
);
particle::TrackingData<passiveParticleCloud> td(targetParcels);
label sourceParticleI = 0;
// Indices of source particles that get added to targetParcels
DynamicList<label> addParticles(sourceParcels.size());
// Unmapped particles
labelHashSet unmappedSource(sourceParcels.size());
// Initial: track from fine-mesh cell centre to particle position
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// This requires there to be no boundary in the way.
forAllConstIter(Cloud<passiveParticle>, sourceParcels, iter)
{
bool foundCell = false;
// Assume that cell from read parcel is the correct one...
if (iter().cell() >= 0)
{
const labelList& targetCells =
sourceToTarget[iter().cell()];
// Particle probably in one of the targetcells. Try
// all by tracking from their cell centre to the parcel
// position.
forAll(targetCells, i)
{
// Track from its cellcentre to position to make sure.
autoPtr<passiveParticle> newPtr
(
new passiveParticle
(
meshTarget,
targetCc[targetCells[i]],
targetCells[i]
)
);
passiveParticle& newP = newPtr();
label faceI = newP.track(iter().position(), td);
if (faceI < 0 && newP.cell() >= 0)
{
// Hit position.
foundCell = true;
addParticles.append(sourceParticleI);
targetParcels.addParticle(newPtr.ptr());
break;
}
}
}
if (!foundCell)
{
// Store for closer analysis
unmappedSource.insert(sourceParticleI);
}
sourceParticleI++;
}
Info<< " after meshToMesh addressing found "
<< targetParcels.size()
<< " parcels in target mesh." << endl;
// Do closer inspection for unmapped particles
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
if (unmappedSource.size())
{
sourceParticleI = 0;
forAllIter(Cloud<passiveParticle>, sourceParcels, iter)
{
if (unmappedSource.found(sourceParticleI))
{
label targetCell =
findCell(targetParcels, iter().position());
if (targetCell >= 0)
{
unmappedSource.erase(sourceParticleI);
addParticles.append(sourceParticleI);
iter().cell() = targetCell;
targetParcels.addParticle
(
sourceParcels.remove(&iter())
);
}
}
sourceParticleI++;
}
}
addParticles.shrink();
Info<< " after additional mesh searching found "
<< targetParcels.size() << " parcels in target mesh." << endl;
if (addParticles.size())
{
IOPosition<passiveParticleCloud>(targetParcels).write();
// addParticles now contains the indices of the sourceMesh
// particles that were appended to the target mesh.
// Map lagrangian fields
// ~~~~~~~~~~~~~~~~~~~~~
MapLagrangianFields<label>
(
cloudDirs[cloudI],
objects,
meshTarget,
addParticles
);
MapLagrangianFields<scalar>
(
cloudDirs[cloudI],
objects,
meshTarget,
addParticles
);
MapLagrangianFields<vector>
(
cloudDirs[cloudI],
objects,
meshTarget,
addParticles
);
MapLagrangianFields<sphericalTensor>
(
cloudDirs[cloudI],
objects,
meshTarget,
addParticles
);
MapLagrangianFields<symmTensor>
(
cloudDirs[cloudI],
objects,
meshTarget,
addParticles
);
MapLagrangianFields<tensor>
(
cloudDirs[cloudI],
objects,
meshTarget,
addParticles
);
}
}
}
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// ************************************************************************* //

View File

@ -0,0 +1,56 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
InNamespace
Foam
Description
Maps lagrangian positions and fields
SourceFiles
mapLagrangian.C
\*---------------------------------------------------------------------------*/
#ifndef mapLagrangian_H
#define mapLagrangian_H
#include "meshToMeshNew.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
//- Maps lagrangian positions and fields
void mapLagrangian(const meshToMeshNew& interp);
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,33 @@
{
instantList sourceTimes = runTimeSource.times();
label sourceTimeIndex = runTimeSource.timeIndex();
if (args.optionFound("sourceTime"))
{
if (args["sourceTime"] == "latestTime")
{
sourceTimeIndex = sourceTimes.size() - 1;
}
else
{
sourceTimeIndex = Time::findClosestTimeIndex
(
sourceTimes,
args.optionRead<scalar>("sourceTime")
);
}
}
else
{
sourceTimeIndex = Time::findClosestTimeIndex
(
sourceTimes,
runTimeTarget.time().value()
);
}
runTimeSource.setTime(sourceTimes[sourceTimeIndex], sourceTimeIndex);
Info<< "\nSource time: " << runTimeSource.value()
<< "\nTarget time: " << runTimeTarget.value()
<< endl;
}

View File

@ -32,6 +32,19 @@ forAll(patches, patchI)
}
}
labelList triSurfaceToAgglom(5*nFineFaces);
const triSurface localSurface = triangulate
(
patches,
includePatches,
finalAgglom,
triSurfaceToAgglom,
globalNumbering,
coarsePatches
);
distributedTriSurfaceMesh surfacesMesh
(
IOobject
@ -43,12 +56,13 @@ distributedTriSurfaceMesh surfacesMesh
IOobject::NO_READ,
IOobject::NO_WRITE
),
triSurfaceTools::triangulate
(
patches,
includePatches
),
localSurface,
dict
);
triSurfaceToAgglom.resize(surfacesMesh.size());
//surfacesMesh.searchableSurface::write();
surfacesMesh.setField(triSurfaceToAgglom);

View File

@ -2,7 +2,7 @@
// Pre-size by assuming a certain percentage is visible.
// Maximum lenght for dynamicList
const label maxDynListLength = 10000;
const label maxDynListLength = 100000;
for (label procI = 0; procI < Pstream::nProcs(); procI++)
{
@ -14,12 +14,17 @@ for (label procI = 0; procI < Pstream::nProcs(); procI++)
DynamicList<label> startIndex(start.size());
DynamicList<label> endIndex(start.size());
DynamicList<label> startAgg(start.size());
DynamicList<label> endAgg(start.size());
const pointField& myFc = remoteCoarseCf[Pstream::myProcNo()];
const vectorField& myArea = remoteCoarseSf[Pstream::myProcNo()];
const labelField& myAgg = remoteCoarseAgg[Pstream::myProcNo()];
const pointField& remoteArea = remoteCoarseSf[procI];
const pointField& remoteFc = remoteCoarseCf[procI];
const labelField& remoteAgg = remoteCoarseAgg[procI];
label i = 0;
label j = 0;
@ -29,6 +34,7 @@ for (label procI = 0; procI < Pstream::nProcs(); procI++)
{
const point& fc = myFc[i];
const vector& fA = myArea[i];
const label& fAgg = myAgg[i];
for (; j < remoteFc.size(); j++)//
{
@ -36,26 +42,32 @@ for (label procI = 0; procI < Pstream::nProcs(); procI++)
{
const point& remFc = remoteFc[j];
const vector& remA = remoteArea[j];
const label& remAgg = remoteAgg[j];
const vector& d = remFc - fc;
if (((d & fA) < 0.) && ((d & remA) > 0))
{
start.append(fc + 0.0001*d);
start.append(fc + 0.001*d);
startIndex.append(i);
end.append(fc + 0.9999*d);
startAgg.append(globalNumbering.toGlobal(procI, fAgg));
end.append(fc + 0.999*d);
label globalI = globalNumbering.toGlobal(procI, j);
endIndex.append(globalI);
endAgg.append(globalNumbering.toGlobal(procI, remAgg));
if (startIndex.size() > maxDynListLength)
{
break;
FatalErrorIn
(
"shootRays"
) << "Dynamic list need from capacity."
<< "Actual size maxDynListLength : "
<< maxDynListLength
<< abort(FatalError);
}
}
}
}
if (startIndex.size() > maxDynListLength)
{
break;
}
if (j == remoteFc.size())
{
@ -63,23 +75,102 @@ for (label procI = 0; procI < Pstream::nProcs(); procI++)
}
}
List<pointIndexHit> hitInfo(startIndex.size());
surfacesMesh.findLine(start, end, hitInfo);
}while (returnReduce(i < myFc.size(), orOp<bool>()));
forAll (hitInfo, rayI)
List<pointIndexHit> hitInfo(startIndex.size());
surfacesMesh.findLine(start, end, hitInfo);
// Return hit global agglo index
labelList aggHitIndex;
surfacesMesh.getField(hitInfo, aggHitIndex);
DynamicList<label> dRayIs;
// Collect the rays which has not abstacle in bettween in rayStartFace
// and rayEndFace. If the ray hit itself get stored in dRayIs
forAll (hitInfo, rayI)
{
if (!hitInfo[rayI].hit())
{
if (!hitInfo[rayI].hit())
rayStartFace.append(startIndex[rayI]);
rayEndFace.append(endIndex[rayI]);
}
else if (aggHitIndex[rayI] == startAgg[rayI])
{
dRayIs.append(rayI);
}
}
start.clear();
// Continue rays which hit themself. If they hit the target
// agglomeration are added to rayStartFace and rayEndFace
bool firstLoop = true;
DynamicField<point> startHitItself;
DynamicField<point> endHitItself;
label iter = 0;
do
{
labelField rayIs;
rayIs.transfer(dRayIs);
dRayIs.clear();
forAll (rayIs, rayI)
{
const label rayID = rayIs[rayI];
label hitIndex = -1;
if (firstLoop)
{
rayStartFace.append(startIndex[rayI]);
rayEndFace.append(endIndex[rayI]);
hitIndex = rayIs[rayI];
}
else
{
hitIndex = rayI;
}
if (hitInfo[hitIndex].hit())
{
if (aggHitIndex[hitIndex] == startAgg[rayID])
{
const vector& endP = end[rayID];
const vector& startP = hitInfo[hitIndex].hitPoint();
const vector& d = endP - startP;
startHitItself.append(startP + 0.01*d);
endHitItself.append(startP + 1.01*d);
dRayIs.append(rayID);
}
else if (aggHitIndex[hitIndex] == endAgg[rayID])
{
rayStartFace.append(startIndex[rayID]);
rayEndFace.append(endIndex[rayID]);
}
}
}
start.clear();
startIndex.clear();
end.clear();
endIndex.clear();
hitInfo.clear();
hitInfo.resize(dRayIs.size());
}while (returnReduce(i < myFc.size(), orOp<bool>()));
surfacesMesh.findLine(startHitItself, endHitItself, hitInfo);
surfacesMesh.getField(hitInfo, aggHitIndex);
endHitItself.clear();
startHitItself.clear();
firstLoop = false;
iter ++;
}while (returnReduce(hitInfo.size(), orOp<bool>()) > 0 && iter < 10);
startIndex.clear();
end.clear();
endIndex.clear();
startAgg.clear();
endAgg.clear();
}

View File

@ -68,6 +68,101 @@ Description
using namespace Foam;
triSurface triangulate
(
const polyBoundaryMesh& bMesh,
const labelHashSet& includePatches,
const labelListIOList& finalAgglom,
labelList& triSurfaceToAgglom,
const globalIndex& globalNumbering,
const polyBoundaryMesh& coarsePatches
)
{
const polyMesh& mesh = bMesh.mesh();
// Storage for surfaceMesh. Size estimate.
DynamicList<labelledTri> triangles
(
mesh.nFaces() - mesh.nInternalFaces()
);
label newPatchI = 0;
label localTriFaceI = 0;
forAllConstIter(labelHashSet, includePatches, iter)
{
const label patchI = iter.key();
const polyPatch& patch = bMesh[patchI];
const pointField& points = patch.points();
label nTriTotal = 0;
forAll(patch, patchFaceI)
{
const face& f = patch[patchFaceI];
faceList triFaces(f.nTriangles(points));
label nTri = 0;
f.triangles(points, nTri, triFaces);
forAll(triFaces, triFaceI)
{
const face& f = triFaces[triFaceI];
triangles.append(labelledTri(f[0], f[1], f[2], newPatchI));
nTriTotal++;
triSurfaceToAgglom[localTriFaceI++] = globalNumbering.toGlobal
(
Pstream::myProcNo(),
finalAgglom[patchI][patchFaceI]
+ coarsePatches[patchI].start()
);
}
}
newPatchI++;
}
triSurfaceToAgglom.resize(localTriFaceI-1);
triangles.shrink();
// Create globally numbered tri surface
triSurface rawSurface(triangles, mesh.points());
// Create locally numbered tri surface
triSurface surface
(
rawSurface.localFaces(),
rawSurface.localPoints()
);
// Add patch names to surface
surface.patches().setSize(newPatchI);
newPatchI = 0;
forAllConstIter(labelHashSet, includePatches, iter)
{
const label patchI = iter.key();
const polyPatch& patch = bMesh[patchI];
surface.patches()[newPatchI].index() = patchI;
surface.patches()[newPatchI].name() = patch.name();
surface.patches()[newPatchI].geometricType() = patch.type();
newPatchI++;
}
return surface;
}
void writeRays
(
const fileName& fName,
@ -213,7 +308,7 @@ int main(int argc, char *argv[])
if (debug)
{
Info << "\nCreating single cell mesh..." << endl;
Pout << "\nCreating single cell mesh..." << endl;
}
singleCellFvMesh coarseMesh
@ -230,6 +325,11 @@ int main(int argc, char *argv[])
finalAgglom
);
if (debug)
{
Pout << "\nCreated single cell mesh..." << endl;
}
// Calculate total number of fine and coarse faces
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@ -283,6 +383,8 @@ int main(int argc, char *argv[])
DynamicList<point> localCoarseCf(nCoarseFaces);
DynamicList<point> localCoarseSf(nCoarseFaces);
DynamicList<label> localAgg(nCoarseFaces);
forAll (viewFactorsPatches, i)
{
const label patchID = viewFactorsPatches[i];
@ -296,11 +398,18 @@ int main(int argc, char *argv[])
const pointField& coarseCf = coarseMesh.Cf().boundaryField()[patchID];
const pointField& coarseSf = coarseMesh.Sf().boundaryField()[patchID];
labelHashSet includePatches;
includePatches.insert(patchID);
forAll(coarseCf, faceI)
{
point cf = coarseCf[faceI];
const label coarseFaceI = coarsePatchFace[faceI];
const labelList& fineFaces = coarseToFine[coarseFaceI];
const label agglomI =
agglom[fineFaces[0]] + coarsePatches[patchID].start();
// Construct single face
uindirectPrimitivePatch upp
(
@ -308,6 +417,7 @@ int main(int argc, char *argv[])
pp.points()
);
List<point> availablePoints
(
upp.faceCentres().size()
@ -342,6 +452,7 @@ int main(int argc, char *argv[])
point sf = coarseSf[faceI];
localCoarseCf.append(cf);
localCoarseSf.append(sf);
localAgg.append(agglomI);
}
}
@ -350,9 +461,12 @@ int main(int argc, char *argv[])
List<pointField> remoteCoarseCf(Pstream::nProcs());
List<pointField> remoteCoarseSf(Pstream::nProcs());
List<labelField> remoteCoarseAgg(Pstream::nProcs());
remoteCoarseCf[Pstream::myProcNo()] = localCoarseCf;
remoteCoarseSf[Pstream::myProcNo()] = localCoarseSf;
remoteCoarseAgg[Pstream::myProcNo()] = localAgg;
// Collect remote Cf and Sf on fine mesh
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@ -370,8 +484,12 @@ int main(int argc, char *argv[])
Pstream::scatterList(remoteCoarseCf);
Pstream::gatherList(remoteCoarseSf);
Pstream::scatterList(remoteCoarseSf);
Pstream::gatherList(remoteCoarseAgg);
Pstream::scatterList(remoteCoarseAgg);
globalIndex globalNumbering(nCoarseFaces);
// Set up searching engine for obstacles
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#include "searchingEngine.H"
@ -383,8 +501,6 @@ int main(int argc, char *argv[])
DynamicList<label> rayEndFace(rayStartFace.size());
globalIndex globalNumbering(nCoarseFaces);
// Return rayStartFace in local index andrayEndFace in global index
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

View File

@ -435,7 +435,7 @@ int main(int argc, char *argv[])
scalar smallDim = 1e-6 * bb.mag();
Info<< "Checking for points less than 1e-6 of bounding box ("
<< bb.span() << " meter) apart."
<< bb.span() << " metre) apart."
<< endl;
// Sort points

View File

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

View File

@ -0,0 +1,9 @@
EXE_INC = \
-I$(LIB_SRC)/meshTools/lnInclude \
-I$(LIB_SRC)/fileFormats/lnInclude \
-I$(LIB_SRC)/triSurface/lnInclude
EXE_LIBS = \
-lmeshTools \
-lfileFormats \
-ltriSurface

View File

@ -0,0 +1,525 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2013 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Application
surfaceHookUp
Description
Find close open edges and stitches the surface along them
Usage
- surfaceHookUp hookDistance [OPTION]
\*---------------------------------------------------------------------------*/
#include "argList.H"
#include "Time.H"
#include "triSurfaceMesh.H"
#include "indexedOctree.H"
#include "treeBoundBox.H"
#include "PackedBoolList.H"
#include "unitConversion.H"
#include "searchableSurfaces.H"
using namespace Foam;
// Split faceI along edgeI at position newPointI
void greenRefine
(
const triSurface& surf,
const label faceI,
const label edgeI,
const label newPointI,
DynamicList<labelledTri>& newFaces
)
{
const labelledTri& f = surf.localFaces()[faceI];
const edge& e = surf.edges()[edgeI];
// Find index of edge in face.
label fp0 = findIndex(f, e[0]);
label fp1 = f.fcIndex(fp0);
label fp2 = f.fcIndex(fp1);
if (f[fp1] == e[1])
{
// Edge oriented like face
newFaces.append
(
labelledTri
(
f[fp0],
newPointI,
f[fp2],
f.region()
)
);
newFaces.append
(
labelledTri
(
newPointI,
f[fp1],
f[fp2],
f.region()
)
);
}
else
{
newFaces.append
(
labelledTri
(
f[fp2],
newPointI,
f[fp1],
f.region()
)
);
newFaces.append
(
labelledTri
(
newPointI,
f[fp0],
f[fp1],
f.region()
)
);
}
}
//scalar checkEdgeAngle
//(
// const triSurface& surf,
// const label edgeIndex,
// const label pointIndex,
// const scalar& angle
//)
//{
// const edge& e = surf.edges()[edgeIndex];
// vector eVec = e.vec(surf.localPoints());
// eVec /= mag(eVec) + SMALL;
// const labelList& pEdges = surf.pointEdges()[pointIndex];
//
// forAll(pEdges, eI)
// {
// const edge& nearE = surf.edges()[pEdges[eI]];
// vector nearEVec = nearE.vec(surf.localPoints());
// nearEVec /= mag(nearEVec) + SMALL;
// const scalar dot = eVec & nearEVec;
// const scalar minCos = degToRad(angle);
// if (mag(dot) > minCos)
// {
// return false;
// }
// }
// return true;
//}
void createBoundaryEdgeTrees
(
const PtrList<triSurfaceMesh>& surfs,
PtrList<indexedOctree<treeDataEdge> >& bEdgeTrees,
labelListList& treeBoundaryEdges
)
{
forAll(surfs, surfI)
{
const triSurface& surf = surfs[surfI];
// Boundary edges
treeBoundaryEdges[surfI] =
labelList
(
identity(surf.nEdges() - surf.nInternalEdges())
+ surf.nInternalEdges()
);
Random rndGen(17301893);
// Slightly extended bb. Slightly off-centred just so on symmetric
// geometry there are less face/edge aligned items.
treeBoundBox bb
(
treeBoundBox(UList<point>(surf.localPoints())).extend(rndGen, 1e-4)
);
bb.min() -= point(ROOTVSMALL, ROOTVSMALL, ROOTVSMALL);
bb.max() += point(ROOTVSMALL, ROOTVSMALL, ROOTVSMALL);
bEdgeTrees.set
(
surfI,
new indexedOctree<treeDataEdge>
(
treeDataEdge
(
false, // cachebb
surf.edges(), // edges
surf.localPoints(), // points
treeBoundaryEdges[surfI] // selected edges
),
bb, // bb
8, // maxLevel
10, // leafsize
3.0 // duplicity
)
);
}
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
int main(int argc, char *argv[])
{
argList::addNote
(
"hook surfaces to other surfaces by moving and retriangulating their"
"boundary edges to match other surface boundary edges"
);
argList::noParallel();
argList::validArgs.append("hookTolerance");
# include "addDictOption.H"
# include "setRootCase.H"
# include "createTime.H"
const word dictName("surfaceHookUpDict");
# include "setSystemRunTimeDictionaryIO.H"
Info<< "Reading " << dictName << nl << endl;
const IOdictionary dict(dictIO);
const scalar dist(args.argRead<scalar>(1));
const scalar matchTolerance(SMALL);
Info<< "Hooking distance = " << dist << endl;
searchableSurfaces surfs
(
IOobject
(
"surfacesToHook",
runTime.constant(),
"triSurface",
runTime
),
dict
);
Info<< nl << "Reading surfaces: " << endl;
forAll(surfs, surfI)
{
Info<< incrIndent;
Info<< nl << indent << "Surface = " << surfs.names()[surfI] << endl;
const wordList& regions = surfs[surfI].regions();
forAll(regions, surfRegionI)
{
Info<< incrIndent;
Info<< indent << "Regions = " << regions[surfRegionI] << endl;
Info<< decrIndent;
}
Info<< decrIndent;
}
PtrList<indexedOctree<treeDataEdge> > bEdgeTrees(surfs.size());
labelListList treeBoundaryEdges(surfs.size());
List<DynamicList<labelledTri> > newFaces(surfs.size());
List<DynamicList<point> > newPoints(surfs.size());
List<PackedBoolList> visitedFace(surfs.size());
PtrList<triSurfaceMesh> newSurfaces(surfs.size());
forAll(surfs, surfI)
{
const triSurfaceMesh& surf =
refCast<const triSurfaceMesh>(surfs[surfI]);
newSurfaces.set
(
surfI,
new triSurfaceMesh
(
IOobject
(
"hookedSurface_" + surfs.names()[surfI],
runTime.constant(),
"triSurface",
runTime
),
surf
)
);
}
label nChanged = 0;
label nIters = 0;
do
{
Info<< nl << "Iteration = " << nIters++ << endl;
nChanged = 0;
createBoundaryEdgeTrees(newSurfaces, bEdgeTrees, treeBoundaryEdges);
forAll(newSurfaces, surfI)
{
const triSurface& newSurf = newSurfaces[surfI];
newFaces[surfI] = newSurf.localFaces();
newPoints[surfI] = newSurf.localPoints();
visitedFace[surfI] = PackedBoolList(newSurf.size(), false);
}
forAll(newSurfaces, surfI)
{
const triSurface& surf = newSurfaces[surfI];
List<pointIndexHit> bPointsTobEdges(surf.boundaryPoints().size());
labelList bPointsHitTree(surf.boundaryPoints().size(), -1);
const labelListList& pointEdges = surf.pointEdges();
forAll(bPointsTobEdges, bPointI)
{
pointIndexHit& nearestHit = bPointsTobEdges[bPointI];
const label pointI = surf.boundaryPoints()[bPointI];
const point& samplePt = surf.localPoints()[pointI];
const labelList& pEdges = pointEdges[pointI];
// Add edges connected to the edge to the shapeMask
DynamicList<label> shapeMask;
shapeMask.append(pEdges);
forAll(bEdgeTrees, treeI)
{
const indexedOctree<treeDataEdge>& bEdgeTree =
bEdgeTrees[treeI];
pointIndexHit currentHit =
bEdgeTree.findNearest
(
samplePt,
sqr(dist),
treeDataEdge::findNearestOpSubset
(
bEdgeTree,
shapeMask
)
);
if
(
currentHit.hit()
&&
(
!nearestHit.hit()
||
(
magSqr(currentHit.hitPoint() - samplePt)
< magSqr(nearestHit.hitPoint() - samplePt)
)
)
)
{
nearestHit = currentHit;
bPointsHitTree[bPointI] = treeI;
}
}
scalar dist2 = magSqr(nearestHit.rawPoint() - samplePt);
if (nearestHit.hit())
{
// bool rejectEdge =
// checkEdgeAngle
// (
// surf,
// nearestHit.index(),
// pointI,
// 30
// );
if (dist2 > Foam::sqr(dist))
{
nearestHit.setMiss();
}
}
}
forAll(bPointsTobEdges, bPointI)
{
const pointIndexHit& eHit = bPointsTobEdges[bPointI];
if (eHit.hit())
{
const label hitSurfI = bPointsHitTree[bPointI];
const triSurface& hitSurf = newSurfaces[hitSurfI];
const label eIndex =
treeBoundaryEdges[hitSurfI][eHit.index()];
const edge& e = hitSurf.edges()[eIndex];
const label pointI = surf.boundaryPoints()[bPointI];
const labelList& eFaces = hitSurf.edgeFaces()[eIndex];
if (eFaces.size() != 1)
{
WarningIn(args.executable())
<< "Edge is attached to " << eFaces.size()
<< " faces." << endl;
continue;
}
const label faceI = eFaces[0];
if (visitedFace[hitSurfI][faceI])
{
continue;
}
DynamicList<labelledTri> newFacesFromSplit(2);
const point& pt = surf.localPoints()[pointI];
if
(
(
magSqr(pt - hitSurf.localPoints()[e.start()])
< matchTolerance
)
|| (
magSqr(pt - hitSurf.localPoints()[e.end()])
< matchTolerance
)
)
{
continue;
}
nChanged++;
// Keep the points in the same place and move the edge
newPoints[hitSurfI].append(newPoints[surfI][pointI]);
// Move the points to the edges
//newPoints[pointI] = eHit.hitPoint();
//newPoints.append(eHit.hitPoint());
visitedFace[hitSurfI][faceI] = true;
// Split the other face.
greenRefine
(
hitSurf,
faceI,
eIndex,
newPoints[hitSurfI].size() - 1,
newFacesFromSplit
);
forAll(newFacesFromSplit, newFaceI)
{
if (newFaceI == 0)
{
newFaces[hitSurfI][faceI] = newFacesFromSplit[0];
}
else
{
newFaces[hitSurfI].append
(
newFacesFromSplit[newFaceI]
);
}
}
}
}
}
Info<< " Number of edges split = " << nChanged << endl;
forAll(newSurfaces, surfI)
{
newSurfaces.set
(
surfI,
new triSurfaceMesh
(
IOobject
(
"hookedSurface_" + surfs.names()[surfI],
runTime.constant(),
"triSurface",
runTime
),
triSurface
(
newFaces[surfI],
newSurfaces[surfI].patches(),
pointField(newPoints[surfI])
)
)
);
}
} while (nChanged > 0);
Info<< endl;
forAll(newSurfaces, surfI)
{
const triSurfaceMesh& newSurf = newSurfaces[surfI];
Info<< "Writing hooked surface " << newSurf.searchableSurface::name()
<< endl;
newSurf.searchableSurface::write();
}
Info<< "\nEnd\n" << endl;
return 0;
}
// ************************************************************************* //

View File

@ -0,0 +1,22 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: dev |
| \\ / A nd | Web: www.OpenFOAM.org |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class dictionary;
location "system";
object surfaceHookUpDict;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
surface1.stl {type triSurfaceMesh;}
surface2.stl {type triSurfaceMesh;}
// ************************************************************************* //

View File

@ -54,7 +54,7 @@ int main(int argc, char *argv[])
const fileName outFileName = args[3];
Info<< "Reading surface from " << surfFileName << " ..." << endl;
Info<< "Merging points within " << mergeTol << " meter." << endl;
Info<< "Merging points within " << mergeTol << " metre." << endl;
triSurface surf1(surfFileName);

View File

@ -224,6 +224,13 @@ case ThirdParty:
set mpfr_version=mpfr-3.1.0
set mpc_version=mpc-0.9
breaksw
case Gcc48:
case Gcc48++0x:
set gcc_version=gcc-4.8.0
set gmp_version=gmp-5.0.4
set mpfr_version=mpfr-3.1.0
set mpc_version=mpc-0.9
breaksw
case Gcc47:
case Gcc47++0x:
set gcc_version=gcc-4.7.2
@ -242,8 +249,7 @@ case ThirdParty:
# using clang - not gcc
setenv WM_CC 'clang'
setenv WM_CXX 'clang++'
set clang_version=llvm-3.1
#set clang_version=llvm-svn
set clang_version=llvm-3.2
breaksw
default:
echo

View File

@ -246,6 +246,12 @@ OpenFOAM | ThirdParty)
mpfr_version=mpfr-3.1.0
mpc_version=mpc-0.9
;;
Gcc48 | Gcc48++0x)
gcc_version=gcc-4.8.0
gmp_version=gmp-5.0.4
mpfr_version=mpfr-3.1.0
mpc_version=mpc-0.9
;;
Gcc47 | Gcc47++0x)
gcc_version=gcc-4.7.2
gmp_version=gmp-5.0.4
@ -262,8 +268,7 @@ OpenFOAM | ThirdParty)
# using clang - not gcc
export WM_CC='clang'
export WM_CXX='clang++'
clang_version=llvm-3.1
#clang_version=llvm-svn
clang_version=llvm-3.2
;;
*)
echo 1>&2

View File

@ -2,7 +2,7 @@
# ========= |
# \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
# \\ / O peration |
# \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
# \\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
# \\/ M anipulation |
#------------------------------------------------------------------------------
# License

View File

@ -312,12 +312,34 @@ $(GAMGAgglomeration)/GAMGAgglomerateLduAddressing.C
pairGAMGAgglomeration = $(GAMGAgglomerations)/pairGAMGAgglomeration
$(pairGAMGAgglomeration)/pairGAMGAgglomeration.C
$(pairGAMGAgglomeration)/pairGAMGAgglomerate.C
$(pairGAMGAgglomeration)/pairGAMGAgglomerationCombineLevels.C
algebraicPairGAMGAgglomeration = $(GAMGAgglomerations)/algebraicPairGAMGAgglomeration
$(algebraicPairGAMGAgglomeration)/algebraicPairGAMGAgglomeration.C
dummyAgglomeration = $(GAMGAgglomerations)/dummyAgglomeration
$(dummyAgglomeration)/dummyAgglomeration.C
GAMGProcAgglomerations = $(GAMG)/GAMGProcAgglomerations
GAMGProcAgglomeration = $(GAMGProcAgglomerations)/GAMGProcAgglomeration
$(GAMGProcAgglomeration)/GAMGProcAgglomeration.C
masterCoarsestGAMGProcAgglomeration = $(GAMGProcAgglomerations)/masterCoarsestGAMGProcAgglomeration
$(masterCoarsestGAMGProcAgglomeration)/masterCoarsestGAMGProcAgglomeration.C
manualGAMGProcAgglomeration = $(GAMGProcAgglomerations)/manualGAMGProcAgglomeration
$(manualGAMGProcAgglomeration)/manualGAMGProcAgglomeration.C
eagerGAMGProcAgglomeration = $(GAMGProcAgglomerations)/eagerGAMGProcAgglomeration
$(eagerGAMGProcAgglomeration)/eagerGAMGProcAgglomeration.C
noneGAMGProcAgglomeration = $(GAMGProcAgglomerations)/noneGAMGProcAgglomeration
$(noneGAMGProcAgglomeration)/noneGAMGProcAgglomeration.C
/*
cellFaceRatioGAMGProcAgglomeration = $(GAMGProcAgglomerations)/cellFaceRatioGAMGProcAgglomeration
$(cellFaceRatioGAMGProcAgglomeration)/cellFaceRatioGAMGProcAgglomeration.C
*/
meshes/lduMesh/lduMesh.C
meshes/lduMesh/lduPrimitiveMesh.C
LduMatrix = matrices/LduMatrix
$(LduMatrix)/LduMatrix/lduMatrices.C

View File

@ -58,6 +58,7 @@ template<class T> class SubList;
// Forward declaration of friend functions and operators
template<class T> class UList;
template<class T> Ostream& operator<<(Ostream&, const UList<T>&);
template<class T> Istream& operator>>(Istream&, UList<T>&);
typedef UList<label> labelUList;
@ -349,6 +350,14 @@ public:
Ostream&,
const UList<T>&
);
//- Read UList contents from Istream. Requires size to have been set
// before.
friend Istream& operator>> <T>
(
Istream&,
UList<T>&
);
};
template<class T>

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
@ -26,6 +26,7 @@ License
#include "UList.H"
#include "Ostream.H"
#include "token.H"
#include "SLList.H"
#include "contiguous.H"
// * * * * * * * * * * * * * * * Ostream Operator * * * * * * * * * * * * * //
@ -137,4 +138,155 @@ Foam::Ostream& Foam::operator<<(Foam::Ostream& os, const Foam::UList<T>& L)
}
template<class T>
Foam::Istream& Foam::operator>>(Istream& is, UList<T>& L)
{
is.fatalCheck("operator>>(Istream&, UList<T>&)");
token firstToken(is);
is.fatalCheck("operator>>(Istream&, UList<T>&) : reading first token");
if (firstToken.isCompound())
{
List<T> elems;
elems.transfer
(
dynamicCast<token::Compound<List<T> > >
(
firstToken.transferCompoundToken(is)
)
);
// Check list length
label s = elems.size();
if (s != L.size())
{
FatalIOErrorIn("operator>>(Istream&, UList<T>&)", is)
<< "incorrect length for UList. Read " << s
<< " expected " << L.size()
<< exit(FatalIOError);
}
for (register label i=0; i<s; i++)
{
L[i] = elems[i];
}
}
else if (firstToken.isLabel())
{
label s = firstToken.labelToken();
// Set list length to that read
if (s != L.size())
{
FatalIOErrorIn("operator>>(Istream&, UList<T>&)", is)
<< "incorrect length for UList. Read " << s
<< " expected " << L.size()
<< exit(FatalIOError);
}
// Read list contents depending on data format
if (is.format() == IOstream::ASCII || !contiguous<T>())
{
// Read beginning of contents
char delimiter = is.readBeginList("List");
if (s)
{
if (delimiter == token::BEGIN_LIST)
{
for (register label i=0; i<s; i++)
{
is >> L[i];
is.fatalCheck
(
"operator>>(Istream&, UList<T>&) : reading entry"
);
}
}
else
{
T element;
is >> element;
is.fatalCheck
(
"operator>>(Istream&, UList<T>&) : "
"reading the single entry"
);
for (register label i=0; i<s; i++)
{
L[i] = element;
}
}
}
// Read end of contents
is.readEndList("List");
}
else
{
if (s)
{
is.read(reinterpret_cast<char*>(L.data()), s*sizeof(T));
is.fatalCheck
(
"operator>>(Istream&, UList<T>&) : reading the binary block"
);
}
}
}
else if (firstToken.isPunctuation())
{
if (firstToken.pToken() != token::BEGIN_LIST)
{
FatalIOErrorIn("operator>>(Istream&, UList<T>&)", is)
<< "incorrect first token, expected '(', found "
<< firstToken.info()
<< exit(FatalIOError);
}
// Putback the opening bracket
is.putBack(firstToken);
// Now read as a singly-linked list
SLList<T> sll(is);
if (sll.size() != L.size())
{
FatalIOErrorIn("operator>>(Istream&, UList<T>&)", is)
<< "incorrect length for UList. Read " << sll.size()
<< " expected " << L.size()
<< exit(FatalIOError);
}
// Convert the singly-linked list to this list
label i = 0;
for
(
typename SLList<T>::const_iterator iter = sll.begin();
iter != sll.end();
++iter
)
{
L[i] = iter();
}
}
else
{
FatalIOErrorIn("operator>>(Istream&, UList<T>&)", is)
<< "incorrect first token, expected <int> or '(', found "
<< firstToken.info()
<< exit(FatalIOError);
}
return is;
}
// ************************************************************************* //

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