Parallel topological changes and internal combustion engine simulations
This commit is contained in:
parent
70cd53a2a1
commit
dc37b56def
98 changed files with 2575 additions and 2741 deletions
|
@ -36,7 +36,6 @@ Description
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
|
|
||||||
# include "setRootCase.H"
|
# include "setRootCase.H"
|
||||||
|
|
||||||
# include "createTime.H"
|
# include "createTime.H"
|
||||||
|
|
|
@ -4,10 +4,12 @@ EXE_INC = \
|
||||||
-I$(LIB_SRC)/dynamicMesh/dynamicMesh/lnInclude \
|
-I$(LIB_SRC)/dynamicMesh/dynamicMesh/lnInclude \
|
||||||
-I$(LIB_SRC)/dynamicMesh/dynamicFvMesh/lnInclude \
|
-I$(LIB_SRC)/dynamicMesh/dynamicFvMesh/lnInclude \
|
||||||
-I$(LIB_SRC)/thermophysicalModels/basic/lnInclude \
|
-I$(LIB_SRC)/thermophysicalModels/basic/lnInclude \
|
||||||
-I$(LIB_SRC)/turbulenceModels/compressible/turbulenceModel
|
-I$(LIB_SRC)/turbulenceModels/compressible/turbulenceModel \
|
||||||
|
-I$(LIB_SRC)/engine/lnInclude
|
||||||
|
|
||||||
EXE_LIBS = \
|
EXE_LIBS = \
|
||||||
-lengine \
|
-lengine \
|
||||||
|
-lfiniteVolume \
|
||||||
-ldynamicFvMesh \
|
-ldynamicFvMesh \
|
||||||
-ldynamicMesh \
|
-ldynamicMesh \
|
||||||
-ltopoChangerFvMesh \
|
-ltopoChangerFvMesh \
|
||||||
|
@ -17,6 +19,5 @@ EXE_LIBS = \
|
||||||
-lbasicThermophysicalModels \
|
-lbasicThermophysicalModels \
|
||||||
-lspecie \
|
-lspecie \
|
||||||
-lmeshTools \
|
-lmeshTools \
|
||||||
-lfiniteVolume \
|
|
||||||
$(WM_DECOMP_LIBS) \
|
$(WM_DECOMP_LIBS) \
|
||||||
-llduSolvers
|
-llduSolvers
|
||||||
|
|
|
@ -6,6 +6,13 @@
|
||||||
+ turbulence->divDevRhoReff(U)
|
+ turbulence->divDevRhoReff(U)
|
||||||
);
|
);
|
||||||
|
|
||||||
UEqn.relax();
|
if (oCorr == nOuterCorr - 1)
|
||||||
|
{
|
||||||
|
UEqn.relax(1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
UEqn.relax();
|
||||||
|
}
|
||||||
|
|
||||||
solve(UEqn == -fvc::grad(p));
|
solve(UEqn == -fvc::grad(p));
|
||||||
|
|
|
@ -8,6 +8,8 @@
|
||||||
);
|
);
|
||||||
basicPsiThermo& thermo = pThermo();
|
basicPsiThermo& thermo = pThermo();
|
||||||
|
|
||||||
|
// Make density field with zero gradient boundary conditions to handle
|
||||||
|
// attach-detach cases. HJ, 20/Mar/2011
|
||||||
volScalarField rho
|
volScalarField rho
|
||||||
(
|
(
|
||||||
IOobject
|
IOobject
|
||||||
|
@ -18,7 +20,8 @@
|
||||||
IOobject::NO_READ,
|
IOobject::NO_READ,
|
||||||
IOobject::AUTO_WRITE
|
IOobject::AUTO_WRITE
|
||||||
),
|
),
|
||||||
thermo.rho()
|
thermo.rho(),
|
||||||
|
zeroGradientFvPatchScalarField::typeName
|
||||||
);
|
);
|
||||||
rho.oldTime();
|
rho.oldTime();
|
||||||
|
|
||||||
|
@ -73,6 +76,7 @@
|
||||||
fvc::DDt(surfaceScalarField("phiU", phi/fvc::interpolate(rho)), p)
|
fvc::DDt(surfaceScalarField("phiU", phi/fvc::interpolate(rho)), p)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
volScalarField dpdt = fvc::ddt(p);
|
||||||
|
|
||||||
volScalarField rUA
|
volScalarField rUA
|
||||||
(
|
(
|
||||||
|
|
|
@ -1,17 +1,17 @@
|
||||||
Pav << runTime.theta() << " " << p.weightedAverage(mesh.V()).value() << endl;
|
Pav << runTime.theta() << " " << p.weightedAverage(mesh.V()).value() << endl;
|
||||||
Tav << runTime.theta() << " " << T.weightedAverage(mesh.V()).value() << endl;
|
Tav << runTime.theta() << " " << T.weightedAverage(mesh.V()).value() << endl;
|
||||||
|
|
||||||
Info << "Max T = " << max(T) << " K" << endl;
|
Info << "Max T = " << max(T).value() << " K" << endl;
|
||||||
Info << "Min T = " << min(T) << " K" << endl;
|
Info << "Min T = " << min(T).value() << " K" << endl;
|
||||||
Info << "Max p = " << max(p)/1.0e5 << " bar" << endl;
|
Info << "Max p = " << max(p).value()/1.0e5 << " bar" << endl;
|
||||||
|
|
||||||
massBal << runTime.theta() << " "
|
massBal << runTime.theta() << " "
|
||||||
<< fvc::domainIntegrate(rho).value() << endl;
|
<< fvc::domainIntegrate(rho).value() << endl;
|
||||||
volume << runTime.theta() << " " << sum(mesh.V()) << endl;
|
volume << runTime.theta() << " " << sum(mesh.V()) << endl;
|
||||||
|
|
||||||
debugT << nl << "Crank angle: " << runTime.theta() << endl;
|
debugT << nl << "Crank angle: " << runTime.theta() << endl;
|
||||||
debugT << "Max T = " << max(T) << " K" << endl;
|
debugT << "Max T = " << max(T).value() << " K" << endl;
|
||||||
debugT << "Min T = " << min(T) << " K" << endl;
|
debugT << "Min T = " << min(T).value() << " K" << endl;
|
||||||
|
|
||||||
kav << runTime.theta() << " "
|
kav << runTime.theta() << " "
|
||||||
<< (turbulence->k())().weightedAverage(mesh.V()).value() << endl;
|
<< (turbulence->k())().weightedAverage(mesh.V()).value() << endl;
|
||||||
|
|
|
@ -2,45 +2,71 @@
|
||||||
rho = thermo.rho();
|
rho = thermo.rho();
|
||||||
|
|
||||||
rUA = 1.0/UEqn.A();
|
rUA = 1.0/UEqn.A();
|
||||||
H = UEqn.H();
|
|
||||||
U = rUA*UEqn.H();
|
U = rUA*UEqn.H();
|
||||||
|
|
||||||
phi = fvc::interpolate(rho)
|
if (nOuterCorr != 1)
|
||||||
*((fvc::interpolate(U) & mesh.Sf()) - fvc::meshPhi(rho, U));
|
|
||||||
|
|
||||||
// Store pressure for under-relaxation
|
|
||||||
p.storePrevIter();
|
|
||||||
|
|
||||||
for (int nonOrth=0; nonOrth<=nNonOrthCorr; nonOrth++)
|
|
||||||
{
|
{
|
||||||
fvScalarMatrix pEqn
|
p.storePrevIter();
|
||||||
(
|
}
|
||||||
fvm::ddt(psi, p)
|
|
||||||
+ fvc::div(phi)
|
|
||||||
- fvm::laplacian(rho*rUA, p)
|
|
||||||
);
|
|
||||||
|
|
||||||
pEqn.solve();
|
if (transonic)
|
||||||
|
{
|
||||||
|
surfaceScalarField phid =
|
||||||
|
fvc::interpolate(thermo.psi())*
|
||||||
|
((fvc::interpolate(U) & mesh.Sf()) - fvc::meshPhi(rho, U));
|
||||||
|
|
||||||
if (nonOrth == nNonOrthCorr)
|
for (int nonOrth=0; nonOrth<=nNonOrthCorr; nonOrth++)
|
||||||
{
|
{
|
||||||
phi += pEqn.flux();
|
fvScalarMatrix pEqn
|
||||||
|
(
|
||||||
|
fvm::ddt(psi, p)
|
||||||
|
+ fvm::div(phid, p, "div(phid,p)")
|
||||||
|
- fvm::laplacian(rho*rUA, p)
|
||||||
|
);
|
||||||
|
|
||||||
|
pEqn.solve();
|
||||||
|
|
||||||
|
if (nonOrth == nNonOrthCorr)
|
||||||
|
{
|
||||||
|
phi == pEqn.flux();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
phi = fvc::interpolate(rho)*
|
||||||
|
((fvc::interpolate(U) & mesh.Sf()) - fvc::meshPhi(rho, U));
|
||||||
|
|
||||||
|
for (int nonOrth=0; nonOrth<=nNonOrthCorr; nonOrth++)
|
||||||
|
{
|
||||||
|
fvScalarMatrix pEqn
|
||||||
|
(
|
||||||
|
fvm::ddt(psi, p)
|
||||||
|
+ fvc::div(phi)
|
||||||
|
- fvm::laplacian(rho*rUA, p)
|
||||||
|
);
|
||||||
|
|
||||||
|
pEqn.solve();
|
||||||
|
|
||||||
|
if (nonOrth == nNonOrthCorr)
|
||||||
|
{
|
||||||
|
phi += pEqn.flux();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Explicitly relax pressure except for last corrector
|
||||||
|
if (oCorr != nOuterCorr - 1)
|
||||||
|
{
|
||||||
|
p.relax();
|
||||||
|
}
|
||||||
|
|
||||||
# include "rhoEqn.H"
|
# include "rhoEqn.H"
|
||||||
# include "compressibleContinuityErrs.H"
|
# include "compressibleContinuityErrs.H"
|
||||||
|
|
||||||
// Warning:
|
|
||||||
// rho does not carry working boundary conditions and needs to be updated
|
|
||||||
// strictly according to the thermodynamics package
|
|
||||||
// HJ, 22/Aug/2007
|
|
||||||
thermo.correct();
|
|
||||||
rho = thermo.rho();
|
|
||||||
|
|
||||||
DpDt = fvc::DDt(surfaceScalarField("phiU", phi/fvc::interpolate(rho)), p);
|
|
||||||
|
|
||||||
U -= rUA*fvc::grad(p);
|
U -= rUA*fvc::grad(p);
|
||||||
U.correctBoundaryConditions();
|
U.correctBoundaryConditions();
|
||||||
}
|
|
||||||
|
|
||||||
|
DpDt = fvc::DDt(surfaceScalarField("phiU", phi/fvc::interpolate(rho)), p);
|
||||||
|
dpdt = fvc::ddt(p);
|
||||||
|
}
|
||||||
|
|
|
@ -1,14 +0,0 @@
|
||||||
# include "readTimeControls.H"
|
|
||||||
# include "readPISOControls.H"
|
|
||||||
|
|
||||||
bool correctPhi = false;
|
|
||||||
if (piso.found("correctPhi"))
|
|
||||||
{
|
|
||||||
correctPhi = Switch(piso.lookup("correctPhi"));
|
|
||||||
}
|
|
||||||
|
|
||||||
bool checkMeshCourantNo = false;
|
|
||||||
if (piso.found("checkMeshCourantNo"))
|
|
||||||
{
|
|
||||||
checkMeshCourantNo = Switch(piso.lookup("checkMeshCourantNo"));
|
|
||||||
}
|
|
|
@ -49,8 +49,8 @@ int main(int argc, char *argv[])
|
||||||
# include "setRootCase.H"
|
# include "setRootCase.H"
|
||||||
|
|
||||||
# include "createEngineTime.H"
|
# include "createEngineTime.H"
|
||||||
# include "createDynamicFvMesh.H"
|
# include "createEngineDynamicMesh.H"
|
||||||
# include "readPISOControls.H"
|
# include "readPIMPLEControls.H"
|
||||||
# include "createFields.H"
|
# include "createFields.H"
|
||||||
# include "initContinuityErrs.H"
|
# include "initContinuityErrs.H"
|
||||||
# include "readEngineTimeControls.H"
|
# include "readEngineTimeControls.H"
|
||||||
|
@ -67,7 +67,9 @@ int main(int argc, char *argv[])
|
||||||
|
|
||||||
while (runTime.run())
|
while (runTime.run())
|
||||||
{
|
{
|
||||||
# include "readControls.H"
|
# include "readPIMPLEControls.H"
|
||||||
|
# include "checkTotalVolume.H"
|
||||||
|
# include "readEngineTimeControls.H"
|
||||||
# include "compressibleCourantNo.H"
|
# include "compressibleCourantNo.H"
|
||||||
# include "setDeltaT.H"
|
# include "setDeltaT.H"
|
||||||
|
|
||||||
|
@ -75,39 +77,48 @@ int main(int argc, char *argv[])
|
||||||
|
|
||||||
Info<< "Crank angle = " << runTime.theta() << " CA-deg" << endl;
|
Info<< "Crank angle = " << runTime.theta() << " CA-deg" << endl;
|
||||||
|
|
||||||
// make phi relative
|
// Make flux absolute
|
||||||
|
|
||||||
phi += meshFlux;
|
phi += meshFlux;
|
||||||
|
|
||||||
bool meshChanged = mesh.update();
|
bool meshChanged = mesh.update();
|
||||||
reduce(meshChanged, orOp<bool>());
|
|
||||||
|
# include "volContinuity.H"
|
||||||
|
|
||||||
|
mesh.setBoundaryVelocity(U);
|
||||||
|
|
||||||
if (meshChanged)
|
if (meshChanged)
|
||||||
{
|
{
|
||||||
thermo.correct();
|
thermo.correct();
|
||||||
|
rho = thermo.rho();
|
||||||
# include "checkTotalVolume.H"
|
rho.correctBoundaryConditions();
|
||||||
# include "compressibleCorrectPhi.H"
|
|
||||||
# include "CourantNo.H"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
meshFlux = fvc::interpolate(rho)*fvc::meshPhi(rho, U);
|
meshFlux = fvc::interpolate(rho)*fvc::meshPhi(rho, U);
|
||||||
|
|
||||||
// Make phi absolute
|
phi = fvc::interpolate(rho)
|
||||||
|
*((fvc::interpolate(U) & mesh.Sf()) - fvc::meshPhi(rho, U));
|
||||||
|
|
||||||
phi -= meshFlux;
|
DpDt = dpdt + fvc::div(phi/fvc::interpolate(rho), p)
|
||||||
|
- fvc::div(phi/fvc::interpolate(rho) + fvc::meshPhi(U))*p;
|
||||||
|
|
||||||
# include "rhoEqn.H"
|
|
||||||
|
|
||||||
// --- SIMPLE loop
|
|
||||||
for (int corr=1; corr<=nCorr; corr++)
|
|
||||||
{
|
{
|
||||||
|
# include "compressibleCourantNo.H"
|
||||||
|
}
|
||||||
|
|
||||||
|
// Pressure-velocity corrector
|
||||||
|
int oCorr = 0;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
# include "rhoEqn.H"
|
||||||
# include "UEqn.H"
|
# include "UEqn.H"
|
||||||
|
|
||||||
# include "hEqn.H"
|
// --- PISO loop
|
||||||
|
for (int corr = 1; corr <= nCorr; corr++)
|
||||||
# include "pEqn.H"
|
{
|
||||||
}
|
# include "pEqn.H"
|
||||||
|
# include "hEqn.H"
|
||||||
|
}
|
||||||
|
} while (++oCorr < nOuterCorr);
|
||||||
|
|
||||||
turbulence->correct();
|
turbulence->correct();
|
||||||
|
|
||||||
|
|
|
@ -103,12 +103,18 @@ int main(int argc, char *argv[])
|
||||||
mesh,
|
mesh,
|
||||||
IOobject::NO_READ
|
IOobject::NO_READ
|
||||||
),
|
),
|
||||||
mag(fvc::div(phi, U) + fvc::div(turbulence->R()) + fvc::grad(p))
|
mag
|
||||||
|
(
|
||||||
|
fvc::div(phi, U)
|
||||||
|
+ fvc::div(turbulence->R())
|
||||||
|
+ fvc::grad(p)
|
||||||
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
Info<< "uResidual max: " << max(uResidual.internalField())
|
Info<< "uResidual max: " << max(uResidual.internalField())
|
||||||
<< " mean: "
|
<< " mean: "
|
||||||
<< sum(uResidual.internalField()*mesh.V())/sum(mesh.V()).value()
|
<< sum(uResidual.internalField()*mesh.V())/
|
||||||
|
sum(mesh.V()).value()
|
||||||
<< endl;
|
<< endl;
|
||||||
|
|
||||||
uResidual.write();
|
uResidual.write();
|
||||||
|
@ -119,7 +125,6 @@ int main(int argc, char *argv[])
|
||||||
}
|
}
|
||||||
|
|
||||||
Info<< endl;
|
Info<< endl;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Info<< "End\n" << endl;
|
Info<< "End\n" << endl;
|
||||||
|
|
|
@ -4,6 +4,7 @@ EXE_INC = \
|
||||||
-I$(LIB_SRC)/meshTools/lnInclude \
|
-I$(LIB_SRC)/meshTools/lnInclude \
|
||||||
-I$(LIB_SRC)/triSurface/lnInclude \
|
-I$(LIB_SRC)/triSurface/lnInclude \
|
||||||
-I$(LIB_SRC)/dynamicMesh/dynamicMesh/lnInclude \
|
-I$(LIB_SRC)/dynamicMesh/dynamicMesh/lnInclude \
|
||||||
|
-I$(LIB_SRC)/dynamicMesh/dynamicFvMesh/lnInclude \
|
||||||
-I$(LIB_SRC)/edgeMesh/lnInclude \
|
-I$(LIB_SRC)/edgeMesh/lnInclude \
|
||||||
-I$(LIB_SRC)/finiteVolume/lnInclude
|
-I$(LIB_SRC)/finiteVolume/lnInclude
|
||||||
|
|
||||||
|
@ -12,4 +13,5 @@ EXE_LIBS = \
|
||||||
-ldecompositionMethods \
|
-ldecompositionMethods \
|
||||||
-lmeshTools \
|
-lmeshTools \
|
||||||
-ldynamicMesh \
|
-ldynamicMesh \
|
||||||
|
-ldynamicFvMesh \
|
||||||
-lautoMesh
|
-lautoMesh
|
||||||
|
|
|
@ -49,6 +49,7 @@ int main(int argc, char *argv[])
|
||||||
# include "createEngineTime.H"
|
# include "createEngineTime.H"
|
||||||
# include "createEngineDynamicMesh.H"
|
# include "createEngineDynamicMesh.H"
|
||||||
|
|
||||||
|
|
||||||
fileName path = runTime.caseName();
|
fileName path = runTime.caseName();
|
||||||
OFstream volFile(path+"/totVol.Cyl");
|
OFstream volFile(path+"/totVol.Cyl");
|
||||||
|
|
||||||
|
|
|
@ -54,7 +54,8 @@ int main(int argc, char *argv[])
|
||||||
fadScalarField b = tf - ten;
|
fadScalarField b = tf - ten;
|
||||||
fadScalarField c = ten - tf;
|
fadScalarField c = ten - tf;
|
||||||
fadScalarField d = sqr(tf - ten);
|
fadScalarField d = sqr(tf - ten);
|
||||||
fadScalarField e = (sqr(tf - bs + 10) + 22.3*sqr(cs - bs + 10));
|
fadScalarField e =
|
||||||
|
(sqr(tf - bs + fadScalar(10)) + 22.3*sqr(cs - bs + fadScalar(10)));
|
||||||
fadScalarField f = d/e;
|
fadScalarField f = d/e;
|
||||||
// fadScalarField g = Foam::atan(f); // HJ, not prepared
|
// fadScalarField g = Foam::atan(f); // HJ, not prepared
|
||||||
// fadScalarField h = Foam::log(f); // HJ, not prepared
|
// fadScalarField h = Foam::log(f); // HJ, not prepared
|
||||||
|
@ -62,7 +63,11 @@ int main(int argc, char *argv[])
|
||||||
|
|
||||||
Info << "new tf: " << tf << endl;
|
Info << "new tf: " << tf << endl;
|
||||||
|
|
||||||
Field<Vector<fadScalar> > tfVector(3, Vector<fadScalar>(1, 2, 3));
|
Field<Vector<fadScalar> > tfVector
|
||||||
|
(
|
||||||
|
3,
|
||||||
|
Vector<fadScalar>(fadScalar(1), fadScalar(2), fadScalar(3))
|
||||||
|
);
|
||||||
|
|
||||||
Info << "tfVector: " << tfVector << endl;
|
Info << "tfVector: " << tfVector << endl;
|
||||||
|
|
||||||
|
|
|
@ -144,9 +144,51 @@ int main(int argc, char *argv[])
|
||||||
|
|
||||||
// Mesh write will be controlled by hand
|
// Mesh write will be controlled by hand
|
||||||
meshPtr->write();
|
meshPtr->write();
|
||||||
|
procMeshes.writeAddressing();
|
||||||
meshPtr->setMotionWriteOpt(IOobject::NO_WRITE);
|
meshPtr->setMotionWriteOpt(IOobject::NO_WRITE);
|
||||||
meshPtr->setTopoWriteOpt(IOobject::NO_WRITE);
|
meshPtr->setTopoWriteOpt(IOobject::NO_WRITE);
|
||||||
|
|
||||||
|
// Write cell decomposition
|
||||||
|
if (writeCellDist)
|
||||||
|
{
|
||||||
|
// Write as volScalarField for post-processing
|
||||||
|
Info<< "Writing cellDist to time " << runTime.timeName()
|
||||||
|
<< endl;
|
||||||
|
volScalarField cellDist
|
||||||
|
(
|
||||||
|
IOobject
|
||||||
|
(
|
||||||
|
"cellDist",
|
||||||
|
runTime.timeName(),
|
||||||
|
meshPtr(),
|
||||||
|
IOobject::NO_READ,
|
||||||
|
IOobject::NO_WRITE
|
||||||
|
),
|
||||||
|
meshPtr(),
|
||||||
|
dimensionedScalar("cellDist", dimless, 0),
|
||||||
|
zeroGradientFvPatchScalarField::typeName
|
||||||
|
);
|
||||||
|
scalarField& cellDistIn = cellDist.internalField();
|
||||||
|
|
||||||
|
label cellI = 0;
|
||||||
|
|
||||||
|
forAll (procMeshes.meshes(), procI)
|
||||||
|
{
|
||||||
|
for
|
||||||
|
(
|
||||||
|
label i = 0;
|
||||||
|
i < procMeshes.meshes()[procI].nCells();
|
||||||
|
i++
|
||||||
|
)
|
||||||
|
{
|
||||||
|
cellDistIn[cellI] = procI;
|
||||||
|
cellI++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cellDist.write();
|
||||||
|
}
|
||||||
|
|
||||||
// Get region prefix for lagrangian
|
// Get region prefix for lagrangian
|
||||||
fileName regionPrefix = "";
|
fileName regionPrefix = "";
|
||||||
if (regionName != fvMesh::defaultRegion)
|
if (regionName != fvMesh::defaultRegion)
|
||||||
|
@ -222,6 +264,8 @@ int main(int argc, char *argv[])
|
||||||
if (writeCellDist)
|
if (writeCellDist)
|
||||||
{
|
{
|
||||||
// Write as volScalarField for post-processing
|
// Write as volScalarField for post-processing
|
||||||
|
Info<< "Writing cellDist to time " << runTime.timeName()
|
||||||
|
<< endl;
|
||||||
volScalarField cellDist
|
volScalarField cellDist
|
||||||
(
|
(
|
||||||
IOobject
|
IOobject
|
||||||
|
|
|
@ -77,13 +77,13 @@ void setFieldType
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
forAll(selectedCells, celli)
|
forAll (selectedCells, celli)
|
||||||
{
|
{
|
||||||
field[selectedCells[celli]] = value;
|
field[selectedCells[celli]] = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
forAll(field.boundaryField(), patchi)
|
forAll (field.boundaryField(), patchi)
|
||||||
{
|
{
|
||||||
// Forced patch assignment. HJ, 1/Aug/2010
|
// Forced patch assignment. HJ, 1/Aug/2010
|
||||||
field.boundaryField()[patchi] ==
|
field.boundaryField()[patchi] ==
|
||||||
|
@ -176,13 +176,10 @@ public:
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
timeSelector::addOptions();
|
|
||||||
|
|
||||||
# include "setRootCase.H"
|
# include "setRootCase.H"
|
||||||
# include "createTime.H"
|
# include "createTime.H"
|
||||||
|
|
||||||
// Get times list
|
Info<< "Time = " << runTime.timeName() << endl;
|
||||||
instantList timeDirs = timeSelector::select0(runTime, args);
|
|
||||||
|
|
||||||
# include "createMesh.H"
|
# include "createMesh.H"
|
||||||
|
|
||||||
|
@ -216,7 +213,7 @@ int main(int argc, char *argv[])
|
||||||
|
|
||||||
PtrList<entry> regions(setFieldsDict.lookup("regions"));
|
PtrList<entry> regions(setFieldsDict.lookup("regions"));
|
||||||
|
|
||||||
forAll(regions, regionI)
|
forAll (regions, regionI)
|
||||||
{
|
{
|
||||||
const entry& region = regions[regionI];
|
const entry& region = regions[regionI];
|
||||||
|
|
||||||
|
|
|
@ -40,6 +40,8 @@ DebugSwitches
|
||||||
mixingPlane 0;
|
mixingPlane 0;
|
||||||
MixingPlaneInterpolation 0;
|
MixingPlaneInterpolation 0;
|
||||||
|
|
||||||
|
tetFemVectorMatrix 0;
|
||||||
|
|
||||||
overlapGgi 0;
|
overlapGgi 0;
|
||||||
cyclicGgi 0;
|
cyclicGgi 0;
|
||||||
coupledLduMatrix 1;
|
coupledLduMatrix 1;
|
||||||
|
|
|
@ -466,9 +466,12 @@ initEvaluate
|
||||||
const Pstream::commsTypes commsType
|
const Pstream::commsTypes commsType
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
if (this->isPointField())
|
if (Pstream::parRun())
|
||||||
{
|
{
|
||||||
initAddFieldTempl(Pstream::blocking, this->internalField());
|
if (this->isPointField())
|
||||||
|
{
|
||||||
|
initAddFieldTempl(Pstream::blocking, this->internalField());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -491,27 +494,30 @@ evaluate
|
||||||
const Pstream::commsTypes commsType
|
const Pstream::commsTypes commsType
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
if (this->isPointField())
|
if (Pstream::parRun())
|
||||||
{
|
{
|
||||||
// Get the neighbour side values
|
if (this->isPointField())
|
||||||
tmp<Field<Type> > tpNeighbour = receivePointField<Type>(commsType);
|
|
||||||
Field<Type>& tpn = tpNeighbour();
|
|
||||||
|
|
||||||
if (doTransform())
|
|
||||||
{
|
{
|
||||||
const processorPolyPatch& ppp = procPatch_.procPolyPatch();
|
// Get the neighbour side values
|
||||||
const tensorField& forwardT = ppp.forwardT();
|
tmp<Field<Type> > tpNeighbour = receivePointField<Type>(commsType);
|
||||||
|
Field<Type>& tpn = tpNeighbour();
|
||||||
|
|
||||||
transform(tpn, forwardT[0], tpn);
|
if (doTransform())
|
||||||
|
{
|
||||||
|
const processorPolyPatch& ppp = procPatch_.procPolyPatch();
|
||||||
|
const tensorField& forwardT = ppp.forwardT();
|
||||||
|
|
||||||
|
transform(tpn, forwardT[0], tpn);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Average over two sides
|
||||||
|
tpn = 0.5*(patchInternalField(this->internalField()) + tpn);
|
||||||
|
|
||||||
|
// Get internal field to insert values into
|
||||||
|
Field<Type>& iF = const_cast<Field<Type>&>(this->internalField());
|
||||||
|
|
||||||
|
this->setInInternalField(iF, tpn);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Average over two sides
|
|
||||||
tpn = 0.5*(patchInternalField(this->internalField()) + tpn);
|
|
||||||
|
|
||||||
// Get internal field to insert values into
|
|
||||||
Field<Type>& iF = const_cast<Field<Type>&>(this->internalField());
|
|
||||||
|
|
||||||
this->setInInternalField(iF, tpn);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -697,7 +703,7 @@ initAddUpperLower
|
||||||
{
|
{
|
||||||
// Gather the data from the given field and send it. Note that the
|
// Gather the data from the given field and send it. Note that the
|
||||||
// size of the field is equal to the number of edges on the field
|
// size of the field is equal to the number of edges on the field
|
||||||
// and NOT the number of points.
|
// and NOT the number of points. HJ, 14/Nov/2001
|
||||||
|
|
||||||
// Get the addressing
|
// Get the addressing
|
||||||
const labelList& me = procPatch_.localEdgeIndices();
|
const labelList& me = procPatch_.localEdgeIndices();
|
||||||
|
|
|
@ -144,6 +144,7 @@ public:
|
||||||
const scalarField& y
|
const scalarField& y
|
||||||
);
|
);
|
||||||
|
|
||||||
|
//- Create and return a clone
|
||||||
autoPtr<curve> clone() const
|
autoPtr<curve> clone() const
|
||||||
{
|
{
|
||||||
return autoPtr<curve>(new curve(*this));
|
return autoPtr<curve>(new curve(*this));
|
||||||
|
|
|
@ -95,7 +95,8 @@ public:
|
||||||
// If object pointer already set issue a FatalError.
|
// If object pointer already set issue a FatalError.
|
||||||
inline void set(T*);
|
inline void set(T*);
|
||||||
|
|
||||||
//- If object pointer already set, delete object and set to given pointer
|
//- If object pointer already set, delete object and set to
|
||||||
|
// given pointer
|
||||||
inline void reset(T* = 0);
|
inline void reset(T* = 0);
|
||||||
|
|
||||||
//- If object pointer points to valid object:
|
//- If object pointer points to valid object:
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
EXE_INC = \
|
EXE_INC = \
|
||||||
-I$(LIB_SRC)/decompositionMethods/decompositionMethods/lnInclude \
|
-I$(LIB_SRC)/decompositionMethods/decompositionMethods/lnInclude \
|
||||||
-I$(LIB_SRC)/dynamicMesh/dynamicMesh/lnInclude \
|
-I$(LIB_SRC)/dynamicMesh/dynamicMesh/lnInclude \
|
||||||
|
-I$(LIB_SRC)/dynamicMesh/dynamicFvMesh/lnInclude \
|
||||||
-I$(LIB_SRC)/finiteVolume/lnInclude \
|
-I$(LIB_SRC)/finiteVolume/lnInclude \
|
||||||
-I$(LIB_SRC)/lagrangian/basic/lnInclude \
|
-I$(LIB_SRC)/lagrangian/basic/lnInclude \
|
||||||
-I$(LIB_SRC)/meshTools/lnInclude \
|
-I$(LIB_SRC)/meshTools/lnInclude \
|
||||||
|
@ -10,6 +11,7 @@ EXE_INC = \
|
||||||
LIB_LIBS = \
|
LIB_LIBS = \
|
||||||
-ldecompositionMethods \
|
-ldecompositionMethods \
|
||||||
-ldynamicMesh \
|
-ldynamicMesh \
|
||||||
|
-ldynamicFvMesh \
|
||||||
-lfiniteVolume \
|
-lfiniteVolume \
|
||||||
-llagrangian \
|
-llagrangian \
|
||||||
-lmeshTools \
|
-lmeshTools \
|
||||||
|
|
|
@ -2975,7 +2975,8 @@ void Foam::autoLayerDriver::addLayers
|
||||||
);
|
);
|
||||||
|
|
||||||
const_cast<Time&>(mesh.time())++;
|
const_cast<Time&>(mesh.time())++;
|
||||||
Info<< "Writing shrunk mesh to " << meshRefiner_.timeName() << endl;
|
Info<< "Writing shrunk mesh to " << meshRefiner_.timeName()
|
||||||
|
<< endl;
|
||||||
|
|
||||||
// See comment in autoSnapDriver why we should not remove meshPhi
|
// See comment in autoSnapDriver why we should not remove meshPhi
|
||||||
// using mesh.clearPout().
|
// using mesh.clearPout().
|
||||||
|
|
|
@ -1613,7 +1613,7 @@ Foam::label Foam::meshRefinement::addPatch
|
||||||
fvBoundaryMesh& fvPatches = const_cast<fvBoundaryMesh&>(mesh.boundary());
|
fvBoundaryMesh& fvPatches = const_cast<fvBoundaryMesh&>(mesh.boundary());
|
||||||
|
|
||||||
// Add polyPatch at the end
|
// Add polyPatch at the end
|
||||||
polyPatches.setSize(sz+1);
|
polyPatches.setSize(sz + 1);
|
||||||
polyPatches.set
|
polyPatches.set
|
||||||
(
|
(
|
||||||
sz,
|
sz,
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
decompositionMethod/decompositionMethod.C
|
decompositionMethod/decompositionMethod.C
|
||||||
|
manualDecomp/manualDecomp.C
|
||||||
geomDecomp/geomDecomp.C
|
geomDecomp/geomDecomp.C
|
||||||
simpleGeomDecomp/simpleGeomDecomp.C
|
simpleGeomDecomp/simpleGeomDecomp.C
|
||||||
hierarchGeomDecomp/hierarchGeomDecomp.C
|
hierarchGeomDecomp/hierarchGeomDecomp.C
|
||||||
manualDecomp/manualDecomp.C
|
patchConstrainedDecomp/patchConstrainedDecomp.C
|
||||||
|
|
||||||
LIB = $(FOAM_LIBBIN)/libdecompositionMethods
|
LIB = $(FOAM_LIBBIN)/libdecompositionMethods
|
||||||
|
|
|
@ -28,6 +28,9 @@ InClass
|
||||||
\*---------------------------------------------------------------------------*/
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
#include "decompositionMethod.H"
|
#include "decompositionMethod.H"
|
||||||
|
#include "cyclicPolyPatch.H"
|
||||||
|
#include "syncTools.H"
|
||||||
|
#include "globalIndex.H"
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
@ -38,7 +41,336 @@ namespace Foam
|
||||||
defineRunTimeSelectionTable(decompositionMethod, dictionaryMesh);
|
defineRunTimeSelectionTable(decompositionMethod, dictionaryMesh);
|
||||||
}
|
}
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
|
||||||
|
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
|
||||||
|
|
||||||
|
void Foam::decompositionMethod::calcCSR
|
||||||
|
(
|
||||||
|
const labelListList& cellCells,
|
||||||
|
List<int>& adjncy,
|
||||||
|
List<int>& xadj
|
||||||
|
)
|
||||||
|
{
|
||||||
|
// Count number of internal faces
|
||||||
|
label nConnections = 0;
|
||||||
|
|
||||||
|
forAll(cellCells, coarseI)
|
||||||
|
{
|
||||||
|
nConnections += cellCells[coarseI].size();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create the adjncy array as twice the size of the total number of
|
||||||
|
// internal faces
|
||||||
|
adjncy.setSize(nConnections);
|
||||||
|
|
||||||
|
xadj.setSize(cellCells.size() + 1);
|
||||||
|
|
||||||
|
|
||||||
|
// Fill in xadj
|
||||||
|
// ~~~~~~~~~~~~
|
||||||
|
label freeAdj = 0;
|
||||||
|
|
||||||
|
forAll(cellCells, coarseI)
|
||||||
|
{
|
||||||
|
xadj[coarseI] = freeAdj;
|
||||||
|
|
||||||
|
const labelList& cCells = cellCells[coarseI];
|
||||||
|
|
||||||
|
forAll(cCells, i)
|
||||||
|
{
|
||||||
|
adjncy[freeAdj++] = cCells[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
xadj[cellCells.size()] = freeAdj;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::decompositionMethod::calcCSR
|
||||||
|
(
|
||||||
|
const polyMesh& mesh,
|
||||||
|
List<int>& adjncy,
|
||||||
|
List<int>& xadj
|
||||||
|
)
|
||||||
|
{
|
||||||
|
// Make Metis CSR (Compressed Storage Format) storage
|
||||||
|
// adjncy : contains neighbours (= edges in graph)
|
||||||
|
// xadj(celli) : start of information in adjncy for celli
|
||||||
|
|
||||||
|
xadj.setSize(mesh.nCells() + 1);
|
||||||
|
|
||||||
|
// Initialise the number of internal faces of the cells to twice the
|
||||||
|
// number of internal faces
|
||||||
|
label nInternalFaces = 2*mesh.nInternalFaces();
|
||||||
|
|
||||||
|
// Check the boundary for coupled patches and add to the number of
|
||||||
|
// internal faces
|
||||||
|
const polyBoundaryMesh& pbm = mesh.boundaryMesh();
|
||||||
|
|
||||||
|
forAll(pbm, patchi)
|
||||||
|
{
|
||||||
|
if (isA<cyclicPolyPatch>(pbm[patchi]))
|
||||||
|
{
|
||||||
|
nInternalFaces += pbm[patchi].size();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create the adjncy array the size of the total number of internal and
|
||||||
|
// coupled faces
|
||||||
|
adjncy.setSize(nInternalFaces);
|
||||||
|
|
||||||
|
// Fill in xadj
|
||||||
|
// ~~~~~~~~~~~~
|
||||||
|
label freeAdj = 0;
|
||||||
|
|
||||||
|
for (label cellI = 0; cellI < mesh.nCells(); cellI++)
|
||||||
|
{
|
||||||
|
xadj[cellI] = freeAdj;
|
||||||
|
|
||||||
|
const labelList& cFaces = mesh.cells()[cellI];
|
||||||
|
|
||||||
|
forAll(cFaces, i)
|
||||||
|
{
|
||||||
|
label faceI = cFaces[i];
|
||||||
|
|
||||||
|
if
|
||||||
|
(
|
||||||
|
mesh.isInternalFace(faceI)
|
||||||
|
|| isA<cyclicPolyPatch>(pbm[pbm.whichPatch(faceI)])
|
||||||
|
)
|
||||||
|
{
|
||||||
|
freeAdj++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
xadj[mesh.nCells()] = freeAdj;
|
||||||
|
|
||||||
|
|
||||||
|
// Fill in adjncy
|
||||||
|
// ~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
labelList nFacesPerCell(mesh.nCells(), 0);
|
||||||
|
|
||||||
|
// Internal faces
|
||||||
|
for (label faceI = 0; faceI < mesh.nInternalFaces(); faceI++)
|
||||||
|
{
|
||||||
|
label own = mesh.faceOwner()[faceI];
|
||||||
|
label nei = mesh.faceNeighbour()[faceI];
|
||||||
|
|
||||||
|
adjncy[xadj[own] + nFacesPerCell[own]++] = nei;
|
||||||
|
adjncy[xadj[nei] + nFacesPerCell[nei]++] = own;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Coupled faces. Only cyclics done.
|
||||||
|
forAll(pbm, patchi)
|
||||||
|
{
|
||||||
|
if (isA<cyclicPolyPatch>(pbm[patchi]))
|
||||||
|
{
|
||||||
|
const unallocLabelList& faceCells = pbm[patchi].faceCells();
|
||||||
|
|
||||||
|
label sizeby2 = faceCells.size()/2;
|
||||||
|
|
||||||
|
for (label facei=0; facei<sizeby2; facei++)
|
||||||
|
{
|
||||||
|
label own = faceCells[facei];
|
||||||
|
label nei = faceCells[facei + sizeby2];
|
||||||
|
|
||||||
|
adjncy[xadj[own] + nFacesPerCell[own]++] = nei;
|
||||||
|
adjncy[xadj[nei] + nFacesPerCell[nei]++] = own;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::decompositionMethod::calcDistributedCSR
|
||||||
|
(
|
||||||
|
const polyMesh& mesh,
|
||||||
|
List<int>& adjncy,
|
||||||
|
List<int>& xadj
|
||||||
|
)
|
||||||
|
{
|
||||||
|
// Create global cell numbers
|
||||||
|
// ~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
globalIndex globalCells(mesh.nCells());
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// Make Metis Distributed CSR (Compressed Storage Format) storage
|
||||||
|
// adjncy : contains cellCells (= edges in graph)
|
||||||
|
// xadj(celli) : start of information in adjncy for celli
|
||||||
|
//
|
||||||
|
|
||||||
|
|
||||||
|
const labelList& faceOwner = mesh.faceOwner();
|
||||||
|
const labelList& faceNeighbour = mesh.faceNeighbour();
|
||||||
|
const polyBoundaryMesh& patches = mesh.boundaryMesh();
|
||||||
|
|
||||||
|
|
||||||
|
// Get renumbered owner on other side of coupled faces
|
||||||
|
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
List<int> globalNeighbour(mesh.nFaces()-mesh.nInternalFaces());
|
||||||
|
|
||||||
|
forAll(patches, patchI)
|
||||||
|
{
|
||||||
|
const polyPatch& pp = patches[patchI];
|
||||||
|
|
||||||
|
if (pp.coupled())
|
||||||
|
{
|
||||||
|
label faceI = pp.start();
|
||||||
|
label bFaceI = pp.start() - mesh.nInternalFaces();
|
||||||
|
|
||||||
|
forAll(pp, i)
|
||||||
|
{
|
||||||
|
globalNeighbour[bFaceI++] = globalCells.toGlobal
|
||||||
|
(
|
||||||
|
faceOwner[faceI++]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the cell on the other side of coupled patches
|
||||||
|
syncTools::swapBoundaryFaceList(mesh, globalNeighbour, false);
|
||||||
|
|
||||||
|
|
||||||
|
// Count number of faces (internal + coupled)
|
||||||
|
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
// Number of faces per cell
|
||||||
|
List<int> nFacesPerCell(mesh.nCells(), 0);
|
||||||
|
|
||||||
|
// Number of coupled faces
|
||||||
|
label nCoupledFaces = 0;
|
||||||
|
|
||||||
|
for (label faceI = 0; faceI < mesh.nInternalFaces(); faceI++)
|
||||||
|
{
|
||||||
|
nFacesPerCell[faceOwner[faceI]]++;
|
||||||
|
nFacesPerCell[faceNeighbour[faceI]]++;
|
||||||
|
}
|
||||||
|
// Handle coupled faces
|
||||||
|
forAll(patches, patchI)
|
||||||
|
{
|
||||||
|
const polyPatch& pp = patches[patchI];
|
||||||
|
|
||||||
|
if (pp.coupled())
|
||||||
|
{
|
||||||
|
label faceI = pp.start();
|
||||||
|
|
||||||
|
forAll(pp, i)
|
||||||
|
{
|
||||||
|
nCoupledFaces++;
|
||||||
|
nFacesPerCell[faceOwner[faceI++]]++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Fill in xadj
|
||||||
|
// ~~~~~~~~~~~~
|
||||||
|
|
||||||
|
xadj.setSize(mesh.nCells() + 1);
|
||||||
|
|
||||||
|
int freeAdj = 0;
|
||||||
|
|
||||||
|
for (label cellI = 0; cellI < mesh.nCells(); cellI++)
|
||||||
|
{
|
||||||
|
xadj[cellI] = freeAdj;
|
||||||
|
|
||||||
|
freeAdj += nFacesPerCell[cellI];
|
||||||
|
}
|
||||||
|
xadj[mesh.nCells()] = freeAdj;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Fill in adjncy
|
||||||
|
// ~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
adjncy.setSize(2*mesh.nInternalFaces() + nCoupledFaces);
|
||||||
|
|
||||||
|
nFacesPerCell = 0;
|
||||||
|
|
||||||
|
// For internal faces is just offsetted owner and neighbour
|
||||||
|
for (label faceI = 0; faceI < mesh.nInternalFaces(); faceI++)
|
||||||
|
{
|
||||||
|
label own = faceOwner[faceI];
|
||||||
|
label nei = faceNeighbour[faceI];
|
||||||
|
|
||||||
|
adjncy[xadj[own] + nFacesPerCell[own]++] = globalCells.toGlobal(nei);
|
||||||
|
adjncy[xadj[nei] + nFacesPerCell[nei]++] = globalCells.toGlobal(own);
|
||||||
|
}
|
||||||
|
// For boundary faces is offsetted coupled neighbour
|
||||||
|
forAll(patches, patchI)
|
||||||
|
{
|
||||||
|
const polyPatch& pp = patches[patchI];
|
||||||
|
|
||||||
|
if (pp.coupled())
|
||||||
|
{
|
||||||
|
label faceI = pp.start();
|
||||||
|
label bFaceI = pp.start()-mesh.nInternalFaces();
|
||||||
|
|
||||||
|
forAll(pp, i)
|
||||||
|
{
|
||||||
|
label own = faceOwner[faceI];
|
||||||
|
adjncy[xadj[own] + nFacesPerCell[own]++] =
|
||||||
|
globalNeighbour[bFaceI];
|
||||||
|
|
||||||
|
faceI++;
|
||||||
|
bFaceI++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::decompositionMethod::calcCellCells
|
||||||
|
(
|
||||||
|
const polyMesh& mesh,
|
||||||
|
const labelList& fineToCoarse,
|
||||||
|
const label nCoarse,
|
||||||
|
labelListList& cellCells
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (fineToCoarse.size() != mesh.nCells())
|
||||||
|
{
|
||||||
|
FatalErrorIn
|
||||||
|
(
|
||||||
|
"decompositionMethod::calcCellCells"
|
||||||
|
"(const labelList&, labelListList&) const"
|
||||||
|
) << "Only valid for mesh agglomeration." << exit(FatalError);
|
||||||
|
}
|
||||||
|
|
||||||
|
List<DynamicList<label> > dynCellCells(nCoarse);
|
||||||
|
|
||||||
|
forAll(mesh.faceNeighbour(), faceI)
|
||||||
|
{
|
||||||
|
label own = fineToCoarse[mesh.faceOwner()[faceI]];
|
||||||
|
label nei = fineToCoarse[mesh.faceNeighbour()[faceI]];
|
||||||
|
|
||||||
|
if (own != nei)
|
||||||
|
{
|
||||||
|
if (findIndex(dynCellCells[own], nei) == -1)
|
||||||
|
{
|
||||||
|
dynCellCells[own].append(nei);
|
||||||
|
}
|
||||||
|
if (findIndex(dynCellCells[nei], own) == -1)
|
||||||
|
{
|
||||||
|
dynCellCells[nei].append(own);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cellCells.setSize(dynCellCells.size());
|
||||||
|
forAll(dynCellCells, coarseI)
|
||||||
|
{
|
||||||
|
cellCells[coarseI].transfer(dynCellCells[coarseI]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
Foam::autoPtr<Foam::decompositionMethod> Foam::decompositionMethod::New
|
Foam::autoPtr<Foam::decompositionMethod> Foam::decompositionMethod::New
|
||||||
(
|
(
|
||||||
|
@ -102,17 +434,40 @@ Foam::autoPtr<Foam::decompositionMethod> Foam::decompositionMethod::New
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||||
|
|
||||||
Foam::labelList Foam::decompositionMethod::decompose
|
Foam::labelList Foam::decompositionMethod::decompose
|
||||||
(
|
(
|
||||||
const pointField& points
|
const pointField& points
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
scalarField weights(0);
|
scalarField weights(points.size(), 1);
|
||||||
|
|
||||||
return decompose(points, weights);
|
return decompose(points, weights);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::labelList Foam::decompositionMethod::decompose
|
||||||
|
(
|
||||||
|
const labelList& fineToCoarse,
|
||||||
|
const pointField& coarsePoints
|
||||||
|
)
|
||||||
|
{
|
||||||
|
// Decompose based on agglomerated points
|
||||||
|
labelList coarseDistribution(decompose(coarsePoints));
|
||||||
|
|
||||||
|
// Rework back into decomposition for original mesh_
|
||||||
|
labelList fineDistribution(fineToCoarse.size());
|
||||||
|
|
||||||
|
forAll(fineDistribution, i)
|
||||||
|
{
|
||||||
|
fineDistribution[i] = coarseDistribution[fineToCoarse[i]];
|
||||||
|
}
|
||||||
|
|
||||||
|
return fineDistribution;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
Foam::labelList Foam::decompositionMethod::decompose
|
Foam::labelList Foam::decompositionMethod::decompose
|
||||||
(
|
(
|
||||||
const labelList& fineToCoarse,
|
const labelList& fineToCoarse,
|
||||||
|
@ -135,82 +490,4 @@ Foam::labelList Foam::decompositionMethod::decompose
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Foam::labelList Foam::decompositionMethod::decompose
|
|
||||||
(
|
|
||||||
const labelList& fineToCoarse,
|
|
||||||
const pointField& coarsePoints
|
|
||||||
)
|
|
||||||
{
|
|
||||||
// Decompose based on agglomerated points
|
|
||||||
labelList coarseDistribution(decompose(coarsePoints));
|
|
||||||
|
|
||||||
// Rework back into decomposition for original mesh_
|
|
||||||
labelList fineDistribution(fineToCoarse.size());
|
|
||||||
|
|
||||||
forAll(fineDistribution, i)
|
|
||||||
{
|
|
||||||
fineDistribution[i] = coarseDistribution[fineToCoarse[i]];
|
|
||||||
}
|
|
||||||
|
|
||||||
return fineDistribution;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Foam::decompositionMethod::calcCellCells
|
|
||||||
(
|
|
||||||
const polyMesh& mesh,
|
|
||||||
const labelList& fineToCoarse,
|
|
||||||
const label nCoarse,
|
|
||||||
labelListList& cellCells
|
|
||||||
)
|
|
||||||
{
|
|
||||||
if (fineToCoarse.size() != mesh.nCells())
|
|
||||||
{
|
|
||||||
FatalErrorIn
|
|
||||||
(
|
|
||||||
"decompositionMethod::calcCellCells"
|
|
||||||
"(const labelList&, labelListList&) const"
|
|
||||||
) << "Only valid for mesh agglomeration." << exit(FatalError);
|
|
||||||
}
|
|
||||||
|
|
||||||
List<DynamicList<label> > dynCellCells(nCoarse);
|
|
||||||
|
|
||||||
forAll(mesh.faceNeighbour(), faceI)
|
|
||||||
{
|
|
||||||
label own = fineToCoarse[mesh.faceOwner()[faceI]];
|
|
||||||
label nei = fineToCoarse[mesh.faceNeighbour()[faceI]];
|
|
||||||
|
|
||||||
if (own != nei)
|
|
||||||
{
|
|
||||||
if (findIndex(dynCellCells[own], nei) == -1)
|
|
||||||
{
|
|
||||||
dynCellCells[own].append(nei);
|
|
||||||
}
|
|
||||||
if (findIndex(dynCellCells[nei], own) == -1)
|
|
||||||
{
|
|
||||||
dynCellCells[nei].append(own);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
cellCells.setSize(dynCellCells.size());
|
|
||||||
forAll(dynCellCells, coarseI)
|
|
||||||
{
|
|
||||||
cellCells[coarseI].transfer(dynCellCells[coarseI]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Foam::labelList Foam::decompositionMethod::decompose
|
|
||||||
(
|
|
||||||
const labelListList& globalCellCells,
|
|
||||||
const pointField& cc
|
|
||||||
)
|
|
||||||
{
|
|
||||||
scalarField cWeights(0);
|
|
||||||
|
|
||||||
return decompose(globalCellCells, cc, cWeights);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
// ************************************************************************* //
|
||||||
|
|
|
@ -48,30 +48,64 @@ namespace Foam
|
||||||
|
|
||||||
class decompositionMethod
|
class decompositionMethod
|
||||||
{
|
{
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
// Protected data
|
// Protected data
|
||||||
|
|
||||||
|
//- Decomposition dictionary
|
||||||
const dictionary& decompositionDict_;
|
const dictionary& decompositionDict_;
|
||||||
|
|
||||||
|
//- Number of processors in decomposition
|
||||||
label nProcessors_;
|
label nProcessors_;
|
||||||
|
|
||||||
|
|
||||||
//- Helper: determine (non-parallel) cellCells from mesh agglomeration.
|
//- Helper to convert connectivity supplied as cellCells into
|
||||||
|
// simple CSR (Metis, scotch) storage
|
||||||
|
static void calcCSR
|
||||||
|
(
|
||||||
|
const labelListList& globalCellCells,
|
||||||
|
List<int>& adjncy,
|
||||||
|
List<int>& xadj
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Helper: convert local connectivity from the mesh
|
||||||
|
// into CSR (Metis, scotch) storage
|
||||||
|
// Treats cyclics as coupled, but not processor patches
|
||||||
|
static void calcCSR
|
||||||
|
(
|
||||||
|
const polyMesh& mesh,
|
||||||
|
List<int>& adjncy,
|
||||||
|
List<int>& xadj
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Helper: convert mesh connectivity into distributed CSR
|
||||||
|
// Very dubious coding. HJ, 1/Mar/2011
|
||||||
|
static void calcDistributedCSR
|
||||||
|
(
|
||||||
|
const polyMesh&,
|
||||||
|
List<int>& adjncy,
|
||||||
|
List<int>& xadj
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Helper: determine (non-parallel) cellCells from mesh
|
||||||
|
// with agglomeration
|
||||||
static void calcCellCells
|
static void calcCellCells
|
||||||
(
|
(
|
||||||
const polyMesh& mesh,
|
const polyMesh& mesh,
|
||||||
const labelList& agglom,
|
const labelList& fineToCoarse,
|
||||||
const label nCoarse,
|
const label nCoarse,
|
||||||
labelListList& cellCells
|
labelListList& cellCells
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
// Private Member Functions
|
// Private Member Functions
|
||||||
|
|
||||||
//- Disallow default bitwise copy construct and assignment
|
//- Disallow default bitwise copy construct
|
||||||
decompositionMethod(const decompositionMethod&);
|
decompositionMethod(const decompositionMethod&);
|
||||||
|
|
||||||
|
//- Disallow default bitwise assignment
|
||||||
void operator=(const decompositionMethod&);
|
void operator=(const decompositionMethod&);
|
||||||
|
|
||||||
|
|
||||||
|
@ -109,7 +143,7 @@ public:
|
||||||
|
|
||||||
// Selectors
|
// Selectors
|
||||||
|
|
||||||
//- Return a reference to the selected decomposition method
|
//- Return a pointer to the selected decomposition method
|
||||||
static autoPtr<decompositionMethod> New
|
static autoPtr<decompositionMethod> New
|
||||||
(
|
(
|
||||||
const dictionary& decompositionDict
|
const dictionary& decompositionDict
|
||||||
|
@ -148,46 +182,37 @@ public:
|
||||||
// proc boundaries)
|
// proc boundaries)
|
||||||
virtual bool parallelAware() const = 0;
|
virtual bool parallelAware() const = 0;
|
||||||
|
|
||||||
//- Return for every coordinate the wanted processor number. Use the
|
//- Decompose cells
|
||||||
// mesh connectivity (if needed)
|
// If needed, use connectivity directly from the mesh
|
||||||
|
// Calls decompose (below) with uniform weights
|
||||||
|
virtual labelList decompose(const pointField&);
|
||||||
|
|
||||||
|
//- Decompose cells with weights
|
||||||
virtual labelList decompose
|
virtual labelList decompose
|
||||||
(
|
(
|
||||||
const pointField& points,
|
const pointField& points,
|
||||||
const scalarField& pointWeights
|
const scalarField& pointWeights
|
||||||
) = 0;
|
) = 0;
|
||||||
|
|
||||||
//- Like decompose but with uniform weights on the points
|
|
||||||
virtual labelList decompose(const pointField&);
|
|
||||||
|
|
||||||
|
//- Decompose cell clusters
|
||||||
//- Return for every coordinate the wanted processor number. Gets
|
// Calls decompose (below) with uniform weights
|
||||||
// passed agglomeration map (from fine to coarse cells) and coarse cell
|
|
||||||
// location. Can be overridden by decomposers that provide this
|
|
||||||
// functionality natively. Coarse cells are local to the processor
|
|
||||||
// (if in parallel). If you want to have coarse cells spanning
|
|
||||||
// processors use the globalCellCells instead.
|
|
||||||
virtual labelList decompose
|
virtual labelList decompose
|
||||||
(
|
(
|
||||||
const labelList& cellToRegion,
|
const labelList& fineToCoarse,
|
||||||
const pointField& regionPoints,
|
const pointField& coarsePoints
|
||||||
const scalarField& regionWeights
|
|
||||||
);
|
);
|
||||||
|
|
||||||
//- Like decompose but with uniform weights on the regions
|
//- Decompose cell clusters with weights on clusters
|
||||||
virtual labelList decompose
|
virtual labelList decompose
|
||||||
(
|
(
|
||||||
const labelList& cellToRegion,
|
const labelList& fineToCoarse,
|
||||||
const pointField& regionPoints
|
const pointField& coarsePoints,
|
||||||
|
const scalarField& coarseWeights
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
//- Return for every coordinate the wanted processor number. Explicitly
|
//- Decompose cells with weights with explicitly provided connectivity
|
||||||
// provided connectivity - does not use mesh_.
|
|
||||||
// The connectivity is equal to mesh.cellCells() except for
|
|
||||||
// - in parallel the cell numbers are global cell numbers (starting
|
|
||||||
// from 0 at processor0 and then incrementing all through the
|
|
||||||
// processors)
|
|
||||||
// - the connections are across coupled patches
|
|
||||||
virtual labelList decompose
|
virtual labelList decompose
|
||||||
(
|
(
|
||||||
const labelListList& globalCellCells,
|
const labelListList& globalCellCells,
|
||||||
|
@ -195,13 +220,6 @@ public:
|
||||||
const scalarField& cWeights
|
const scalarField& cWeights
|
||||||
) = 0;
|
) = 0;
|
||||||
|
|
||||||
//- Like decompose but with uniform weights on the cells
|
|
||||||
virtual labelList decompose
|
|
||||||
(
|
|
||||||
const labelListList& globalCellCells,
|
|
||||||
const pointField& cc
|
|
||||||
);
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -40,8 +40,7 @@ Foam::geomDecomp::geomDecomp
|
||||||
delta_(readScalar(geomDecomDict_.lookup("delta"))),
|
delta_(readScalar(geomDecomDict_.lookup("delta"))),
|
||||||
rotDelta_(I)
|
rotDelta_(I)
|
||||||
{
|
{
|
||||||
// check that the case makes sense :
|
// Check that the case makes sense
|
||||||
|
|
||||||
if (nProcessors_ != n_.x()*n_.y()*n_.z())
|
if (nProcessors_ != n_.x()*n_.y()*n_.z())
|
||||||
{
|
{
|
||||||
FatalErrorIn
|
FatalErrorIn
|
||||||
|
|
|
@ -37,7 +37,7 @@ SourceFiles
|
||||||
#define geomDecomp_H
|
#define geomDecomp_H
|
||||||
|
|
||||||
#include "decompositionMethod.H"
|
#include "decompositionMethod.H"
|
||||||
#include "Vector.H"
|
#include "labelVector.H"
|
||||||
|
|
||||||
namespace Foam
|
namespace Foam
|
||||||
{
|
{
|
||||||
|
@ -50,17 +50,32 @@ class geomDecomp
|
||||||
:
|
:
|
||||||
public decompositionMethod
|
public decompositionMethod
|
||||||
{
|
{
|
||||||
|
// Private Member Functions
|
||||||
|
|
||||||
|
//- Disallow default bitwise copy construct
|
||||||
|
geomDecomp(const geomDecomp&);
|
||||||
|
|
||||||
|
//- Disallow default bitwise assignment
|
||||||
|
void operator=(const geomDecomp&);
|
||||||
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
// Protected data
|
// Protected data
|
||||||
|
|
||||||
|
//- Geometric decomposition dictionary
|
||||||
const dictionary& geomDecomDict_;
|
const dictionary& geomDecomDict_;
|
||||||
|
|
||||||
Vector<label> n_;
|
//- Number of splits in the (x y z) direction
|
||||||
|
labelVector n_;
|
||||||
|
|
||||||
|
//- Small rotation to achieve smooth geometric decomposition
|
||||||
scalar delta_;
|
scalar delta_;
|
||||||
|
|
||||||
|
//- Small rotation tensor, calculated from delta
|
||||||
tensor rotDelta_;
|
tensor rotDelta_;
|
||||||
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
// Constructors
|
// Constructors
|
||||||
|
|
|
@ -50,6 +50,7 @@ namespace Foam
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
void Foam::hierarchGeomDecomp::setDecompOrder()
|
void Foam::hierarchGeomDecomp::setDecompOrder()
|
||||||
|
@ -157,7 +158,7 @@ void Foam::hierarchGeomDecomp::calculateSortedWeightedSizes
|
||||||
{
|
{
|
||||||
// Evaluate cumulative weights.
|
// Evaluate cumulative weights.
|
||||||
sortedWeightedSizes[0] = 0;
|
sortedWeightedSizes[0] = 0;
|
||||||
forAll(current, i)
|
forAll (current, i)
|
||||||
{
|
{
|
||||||
label pointI = current[indices[i]];
|
label pointI = current[indices[i]];
|
||||||
sortedWeightedSizes[i + 1] = sortedWeightedSizes[i] + weights[pointI];
|
sortedWeightedSizes[i + 1] = sortedWeightedSizes[i] + weights[pointI];
|
||||||
|
@ -328,7 +329,7 @@ void Foam::hierarchGeomDecomp::findBinary
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Sort points into bins according to one component. Recurses to next component.
|
// Sort points into bins according to one component. Recurses to next component
|
||||||
void Foam::hierarchGeomDecomp::sortComponent
|
void Foam::hierarchGeomDecomp::sortComponent
|
||||||
(
|
(
|
||||||
const label sizeTol,
|
const label sizeTol,
|
||||||
|
@ -351,7 +352,7 @@ void Foam::hierarchGeomDecomp::sortComponent
|
||||||
// Storage for sorted component compI
|
// Storage for sorted component compI
|
||||||
SortableList<scalar> sortedCoord(current.size());
|
SortableList<scalar> sortedCoord(current.size());
|
||||||
|
|
||||||
forAll(current, i)
|
forAll (current, i)
|
||||||
{
|
{
|
||||||
label pointI = current[i];
|
label pointI = current[i];
|
||||||
|
|
||||||
|
@ -458,7 +459,7 @@ void Foam::hierarchGeomDecomp::sortComponent
|
||||||
// Copy localSize elements starting from leftIndex.
|
// Copy localSize elements starting from leftIndex.
|
||||||
labelList slice(localSize);
|
labelList slice(localSize);
|
||||||
|
|
||||||
forAll(slice, i)
|
forAll (slice, i)
|
||||||
{
|
{
|
||||||
label pointI = current[sortedCoord.indices()[leftIndex+i]];
|
label pointI = current[sortedCoord.indices()[leftIndex+i]];
|
||||||
|
|
||||||
|
@ -502,7 +503,7 @@ void Foam::hierarchGeomDecomp::sortComponent
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Sort points into bins according to one component. Recurses to next component.
|
// Sort points into bins according to one component. Recurses to next component
|
||||||
void Foam::hierarchGeomDecomp::sortComponent
|
void Foam::hierarchGeomDecomp::sortComponent
|
||||||
(
|
(
|
||||||
const label sizeTol,
|
const label sizeTol,
|
||||||
|
@ -526,7 +527,7 @@ void Foam::hierarchGeomDecomp::sortComponent
|
||||||
// Storage for sorted component compI
|
// Storage for sorted component compI
|
||||||
SortableList<scalar> sortedCoord(current.size());
|
SortableList<scalar> sortedCoord(current.size());
|
||||||
|
|
||||||
forAll(current, i)
|
forAll (current, i)
|
||||||
{
|
{
|
||||||
label pointI = current[i];
|
label pointI = current[i];
|
||||||
|
|
||||||
|
@ -641,7 +642,7 @@ void Foam::hierarchGeomDecomp::sortComponent
|
||||||
// Copy localSize elements starting from leftIndex.
|
// Copy localSize elements starting from leftIndex.
|
||||||
labelList slice(localSize);
|
labelList slice(localSize);
|
||||||
|
|
||||||
forAll(slice, i)
|
forAll (slice, i)
|
||||||
{
|
{
|
||||||
label pointI = current[sortedCoord.indices()[leftIndex+i]];
|
label pointI = current[sortedCoord.indices()[leftIndex+i]];
|
||||||
|
|
||||||
|
@ -725,7 +726,8 @@ Foam::labelList Foam::hierarchGeomDecomp::decompose
|
||||||
|
|
||||||
// Start off with every point sorted onto itself.
|
// Start off with every point sorted onto itself.
|
||||||
labelList slice(points.size());
|
labelList slice(points.size());
|
||||||
forAll(slice, i)
|
|
||||||
|
forAll (slice, i)
|
||||||
{
|
{
|
||||||
slice[i] = i;
|
slice[i] = i;
|
||||||
}
|
}
|
||||||
|
@ -767,7 +769,8 @@ Foam::labelList Foam::hierarchGeomDecomp::decompose
|
||||||
|
|
||||||
// Start off with every point sorted onto itself.
|
// Start off with every point sorted onto itself.
|
||||||
labelList slice(points.size());
|
labelList slice(points.size());
|
||||||
forAll(slice, i)
|
|
||||||
|
forAll (slice, i)
|
||||||
{
|
{
|
||||||
slice[i] = i;
|
slice[i] = i;
|
||||||
}
|
}
|
||||||
|
|
|
@ -77,6 +77,13 @@ class hierarchGeomDecomp
|
||||||
|
|
||||||
// Private Member Functions
|
// Private Member Functions
|
||||||
|
|
||||||
|
//- Disallow default bitwise copy construct
|
||||||
|
hierarchGeomDecomp(const hierarchGeomDecomp&);
|
||||||
|
|
||||||
|
//- Disallow default bitwise assignment
|
||||||
|
void operator=(const hierarchGeomDecomp&);
|
||||||
|
|
||||||
|
|
||||||
//- Convert ordering string ("xyz") into list of components.
|
//- Convert ordering string ("xyz") into list of components.
|
||||||
void setDecompOrder();
|
void setDecompOrder();
|
||||||
|
|
||||||
|
@ -105,13 +112,13 @@ class hierarchGeomDecomp
|
||||||
// wantedSize. Binary search.
|
// wantedSize. Binary search.
|
||||||
static void findBinary
|
static void findBinary
|
||||||
(
|
(
|
||||||
const label sizeTol, // size difference considered acceptible
|
const label sizeTol, // Acceptable size difference
|
||||||
const List<scalar>&,
|
const List<scalar>&,
|
||||||
const label leftIndex, // index of previous value
|
const label leftIndex, // index of previous value
|
||||||
const scalar leftValue, // value at leftIndex
|
const scalar leftValue, // value at leftIndex
|
||||||
const scalar maxValue, // global max of values
|
const scalar maxValue, // global max of values
|
||||||
const scalar wantedSize, // wanted size
|
const scalar wantedSize, // wanted size
|
||||||
label& mid, // index where size of bin is wantedSize
|
label& mid, // index where bin size is wantedSize
|
||||||
scalar& midValue // value at mid
|
scalar& midValue // value at mid
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -120,14 +127,14 @@ class hierarchGeomDecomp
|
||||||
// wantedSize. Binary search.
|
// wantedSize. Binary search.
|
||||||
static void findBinary
|
static void findBinary
|
||||||
(
|
(
|
||||||
const label sizeTol, // size difference considered acceptible
|
const label sizeTol, // Acceptable size difference
|
||||||
const List<scalar>& sortedWeightedSizes,
|
const List<scalar>& sortedWeightedSizes,
|
||||||
const List<scalar>&,
|
const List<scalar>&,
|
||||||
const label leftIndex, // index of previous value
|
const label leftIndex, // index of previous value
|
||||||
const scalar leftValue, // value at leftIndex
|
const scalar leftValue, // value at leftIndex
|
||||||
const scalar maxValue, // global max of values
|
const scalar maxValue, // global max of values
|
||||||
const scalar wantedSize, // wanted size
|
const scalar wantedSize, // wanted size
|
||||||
label& mid, // index where size of bin is wantedSize
|
label& mid, // index where bin size is wantedSize
|
||||||
scalar& midValue // value at mid
|
scalar& midValue // value at mid
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -156,11 +163,6 @@ class hierarchGeomDecomp
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
//- Disallow default bitwise copy construct and assignment
|
|
||||||
void operator=(const hierarchGeomDecomp&);
|
|
||||||
hierarchGeomDecomp(const hierarchGeomDecomp&);
|
|
||||||
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
//- Runtime type information
|
//- Runtime type information
|
||||||
|
@ -194,25 +196,19 @@ public:
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
//- Return for every coordinate the wanted processor number. Use the
|
//- Decompose cells without weights. Code for weighted decomposition
|
||||||
// mesh connectivity (if needed)
|
// is a bit complex so it is kept separate for now
|
||||||
|
virtual labelList decompose(const pointField&);
|
||||||
|
|
||||||
|
//- Decompose cells with weights
|
||||||
virtual labelList decompose
|
virtual labelList decompose
|
||||||
(
|
(
|
||||||
const pointField&,
|
const pointField& points,
|
||||||
const scalarField& weights
|
const scalarField& weights
|
||||||
);
|
);
|
||||||
|
|
||||||
//- Without weights. Code for weighted decomposition is a bit complex
|
//- Decompose cells with weights with explicitly provided connectivity
|
||||||
// so kept separate for now.
|
// Does not use mesh for connectivity
|
||||||
virtual labelList decompose(const pointField&);
|
|
||||||
|
|
||||||
//- Return for every coordinate the wanted processor number. Explicitly
|
|
||||||
// provided connectivity - does not use mesh_.
|
|
||||||
// The connectivity is equal to mesh.cellCells() except for
|
|
||||||
// - in parallel the cell numbers are global cell numbers (starting
|
|
||||||
// from 0 at processor0 and then incrementing all through the
|
|
||||||
// processors)
|
|
||||||
// - the connections are across coupled patches
|
|
||||||
virtual labelList decompose
|
virtual labelList decompose
|
||||||
(
|
(
|
||||||
const labelListList& globalCellCells,
|
const labelListList& globalCellCells,
|
||||||
|
@ -223,6 +219,7 @@ public:
|
||||||
return decompose(cc, cWeights);
|
return decompose(cc, cWeights);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//- Decompose cells with weights with explicitly provided connectivity
|
||||||
virtual labelList decompose
|
virtual labelList decompose
|
||||||
(
|
(
|
||||||
const labelListList& globalCellCells,
|
const labelListList& globalCellCells,
|
||||||
|
|
|
@ -38,13 +38,6 @@ namespace Foam
|
||||||
{
|
{
|
||||||
defineTypeNameAndDebug(manualDecomp, 0);
|
defineTypeNameAndDebug(manualDecomp, 0);
|
||||||
|
|
||||||
addToRunTimeSelectionTable
|
|
||||||
(
|
|
||||||
decompositionMethod,
|
|
||||||
manualDecomp,
|
|
||||||
dictionary
|
|
||||||
);
|
|
||||||
|
|
||||||
addToRunTimeSelectionTable
|
addToRunTimeSelectionTable
|
||||||
(
|
(
|
||||||
decompositionMethod,
|
decompositionMethod,
|
||||||
|
@ -56,14 +49,6 @@ namespace Foam
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
Foam::manualDecomp::manualDecomp(const dictionary& decompositionDict)
|
|
||||||
:
|
|
||||||
decompositionMethod(decompositionDict)
|
|
||||||
{
|
|
||||||
notImplemented("manualDecomp(const dictionary&)");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Foam::manualDecomp::manualDecomp
|
Foam::manualDecomp::manualDecomp
|
||||||
(
|
(
|
||||||
const dictionary& decompositionDict,
|
const dictionary& decompositionDict,
|
||||||
|
@ -71,11 +56,14 @@ Foam::manualDecomp::manualDecomp
|
||||||
)
|
)
|
||||||
:
|
:
|
||||||
decompositionMethod(decompositionDict),
|
decompositionMethod(decompositionDict),
|
||||||
meshPtr_(&mesh),
|
mesh_(mesh),
|
||||||
decompDataFile_
|
decompDataFile_
|
||||||
(
|
(
|
||||||
decompositionDict.subDict(word(decompositionDict.lookup("method"))
|
decompositionDict.subDict
|
||||||
+ "Coeffs").lookup("dataFile")
|
(
|
||||||
|
word(decompositionDict.lookup("method"))
|
||||||
|
+ "Coeffs"
|
||||||
|
).lookup("dataFile")
|
||||||
)
|
)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
@ -88,22 +76,20 @@ Foam::labelList Foam::manualDecomp::decompose
|
||||||
const scalarField& pointWeights
|
const scalarField& pointWeights
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
const polyMesh& mesh = *meshPtr_;
|
|
||||||
|
|
||||||
labelIOList finalDecomp
|
labelIOList finalDecomp
|
||||||
(
|
(
|
||||||
IOobject
|
IOobject
|
||||||
(
|
(
|
||||||
decompDataFile_,
|
decompDataFile_,
|
||||||
mesh.facesInstance(),
|
mesh_.facesInstance(),
|
||||||
mesh,
|
mesh_,
|
||||||
IOobject::MUST_READ,
|
IOobject::MUST_READ,
|
||||||
IOobject::AUTO_WRITE,
|
IOobject::AUTO_WRITE,
|
||||||
false
|
false
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
// check if the final decomposition is OK
|
// Check if the final decomposition is OK
|
||||||
|
|
||||||
if (finalDecomp.size() != points.size())
|
if (finalDecomp.size() != points.size())
|
||||||
{
|
{
|
||||||
|
|
|
@ -42,7 +42,7 @@ namespace Foam
|
||||||
{
|
{
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*\
|
/*---------------------------------------------------------------------------*\
|
||||||
Class manualDecomp Declaration
|
Class manualDecomp Declaration
|
||||||
\*---------------------------------------------------------------------------*/
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
class manualDecomp
|
class manualDecomp
|
||||||
|
@ -51,17 +51,19 @@ class manualDecomp
|
||||||
{
|
{
|
||||||
// Private data
|
// Private data
|
||||||
|
|
||||||
const polyMesh* meshPtr_;
|
const polyMesh& mesh_;
|
||||||
|
|
||||||
fileName decompDataFile_;
|
fileName decompDataFile_;
|
||||||
|
|
||||||
|
|
||||||
// Private Member Functions
|
// Private Member Functions
|
||||||
|
|
||||||
//- Disallow default bitwise copy construct and assignment
|
//- Disallow default bitwise copy construct
|
||||||
void operator=(const manualDecomp&);
|
|
||||||
manualDecomp(const manualDecomp&);
|
manualDecomp(const manualDecomp&);
|
||||||
|
|
||||||
|
//- Disallow default bitwise assignment
|
||||||
|
void operator=(const manualDecomp&);
|
||||||
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
@ -97,21 +99,14 @@ public:
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
//- Return for every coordinate the wanted processor number. Use the
|
//- Decompose cells with weights
|
||||||
// mesh connectivity (if needed)
|
|
||||||
virtual labelList decompose
|
virtual labelList decompose
|
||||||
(
|
(
|
||||||
const pointField& points,
|
const pointField& points,
|
||||||
const scalarField& pointWeights
|
const scalarField& pointWeights
|
||||||
);
|
);
|
||||||
|
|
||||||
//- Return for every coordinate the wanted processor number. Explicitly
|
//- Decompose cells with weights with explicitly provided connectivity
|
||||||
// provided connectivity - does not use mesh_.
|
|
||||||
// The connectivity is equal to mesh.cellCells() except for
|
|
||||||
// - in parallel the cell numbers are global cell numbers (starting
|
|
||||||
// from 0 at processor0 and then incrementing all through the
|
|
||||||
// processors)
|
|
||||||
// - the connections are across coupled patches
|
|
||||||
virtual labelList decompose
|
virtual labelList decompose
|
||||||
(
|
(
|
||||||
const labelListList& globalCellCells,
|
const labelListList& globalCellCells,
|
||||||
|
|
|
@ -0,0 +1,120 @@
|
||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | Copyright held by original author
|
||||||
|
\\/ 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 2 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, write to the Free Software Foundation,
|
||||||
|
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
|
||||||
|
Description
|
||||||
|
Decomposition given a cell-to-processor association in a file
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#include "patchConstrainedDecomp.H"
|
||||||
|
#include "addToRunTimeSelectionTable.H"
|
||||||
|
#include "IFstream.H"
|
||||||
|
#include "labelIOList.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
defineTypeNameAndDebug(patchConstrainedDecomp, 0);
|
||||||
|
|
||||||
|
addToRunTimeSelectionTable
|
||||||
|
(
|
||||||
|
decompositionMethod,
|
||||||
|
patchConstrainedDecomp,
|
||||||
|
dictionaryMesh
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Foam::patchConstrainedDecomp::patchConstrainedDecomp
|
||||||
|
(
|
||||||
|
const dictionary& decompositionDict,
|
||||||
|
const polyMesh& mesh
|
||||||
|
)
|
||||||
|
:
|
||||||
|
decompositionMethod(decompositionDict),
|
||||||
|
mesh_(mesh),
|
||||||
|
dict_
|
||||||
|
(
|
||||||
|
decompositionDict.subDict
|
||||||
|
(
|
||||||
|
typeName + "Coeffs"
|
||||||
|
)
|
||||||
|
),
|
||||||
|
baseDecompPtr_
|
||||||
|
(
|
||||||
|
decompositionMethod::New(dict_, mesh)
|
||||||
|
),
|
||||||
|
patchConstraints_(dict_.lookup("patchConstraints"))
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Foam::labelList Foam::patchConstrainedDecomp::decompose
|
||||||
|
(
|
||||||
|
const pointField& points,
|
||||||
|
const scalarField& pointWeights
|
||||||
|
)
|
||||||
|
{
|
||||||
|
|
||||||
|
labelList finalDecomp = baseDecompPtr_->decompose(points, pointWeights);
|
||||||
|
|
||||||
|
// Impose the decomposition along patches
|
||||||
|
forAll (patchConstraints_, i)
|
||||||
|
{
|
||||||
|
const label patchID =
|
||||||
|
mesh_.boundaryMesh().findPatchID(patchConstraints_[i].first());
|
||||||
|
|
||||||
|
const label procID = patchConstraints_[i].second();
|
||||||
|
|
||||||
|
if (patchID < 0 || procID < 0 || procID > nProcessors_ - 1)
|
||||||
|
{
|
||||||
|
FatalErrorIn
|
||||||
|
(
|
||||||
|
"labelList patchConstrainedDecomp::decompose\n"
|
||||||
|
"(\n"
|
||||||
|
" const pointField& points,\n"
|
||||||
|
" const scalarField& pointWeights\n"
|
||||||
|
")"
|
||||||
|
) << "Incorrect patch constraint definition for "
|
||||||
|
<< patchConstraints_[i]
|
||||||
|
<< abort(FatalError);
|
||||||
|
}
|
||||||
|
|
||||||
|
const labelList fc = mesh_.boundaryMesh()[patchID].faceCells();
|
||||||
|
|
||||||
|
forAll (fc, fcI)
|
||||||
|
{
|
||||||
|
finalDecomp[fc[fcI]] = procID;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return finalDecomp;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
|
@ -22,114 +22,112 @@ License
|
||||||
along with OpenFOAM; if not, write to the Free Software Foundation,
|
along with OpenFOAM; if not, write to the Free Software Foundation,
|
||||||
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
|
||||||
Namespace
|
|
||||||
Foam::solidBodyMotionFunctions
|
|
||||||
|
|
||||||
Description
|
|
||||||
Namespace for solid-body motions
|
|
||||||
|
|
||||||
|
|
||||||
Class
|
Class
|
||||||
Foam::solidBodyMotionFunction
|
Foam::patchConstrainedDecomp
|
||||||
|
|
||||||
Description
|
Description
|
||||||
Base class for defining solid-body motions
|
Base decomposition type is modified by assigning patches to given
|
||||||
|
processors. This is controlled by the patch entry, giving patch names
|
||||||
|
and processor index for them.
|
||||||
|
|
||||||
SourceFiles
|
SourceFiles
|
||||||
solidBodyMotionFunction.C
|
patchConstrainedDecomp.C
|
||||||
newDynamicFvMesh.C
|
|
||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
#ifndef solidBodyMotionFunction_H
|
#ifndef patchConstrainedDecomp_H
|
||||||
#define solidBodyMotionFunction_H
|
#define patchConstrainedDecomp_H
|
||||||
|
|
||||||
#include "Time.H"
|
#include "decompositionMethod.H"
|
||||||
#include "dictionary.H"
|
#include "Tuple2.H"
|
||||||
#include "septernion.H"
|
|
||||||
#include "autoPtr.H"
|
|
||||||
#include "runTimeSelectionTables.H"
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
namespace Foam
|
namespace Foam
|
||||||
{
|
{
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*\
|
/*---------------------------------------------------------------------------*\
|
||||||
Class solidBodyMotionFunction Declaration
|
Class patchConstrainedDecomp Declaration
|
||||||
\*---------------------------------------------------------------------------*/
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
class solidBodyMotionFunction
|
class patchConstrainedDecomp
|
||||||
|
:
|
||||||
|
public decompositionMethod
|
||||||
{
|
{
|
||||||
protected:
|
// Private data types
|
||||||
|
|
||||||
// Protected data
|
typedef List<Tuple2<word, label> > procWordList;
|
||||||
|
|
||||||
dictionary SBMFCoeffs_;
|
|
||||||
const Time& time_;
|
|
||||||
|
|
||||||
|
|
||||||
private:
|
// Private data
|
||||||
|
|
||||||
|
//- Mesh
|
||||||
|
const polyMesh& mesh_;
|
||||||
|
|
||||||
|
//- Decomposition dictionary
|
||||||
|
dictionary dict_;
|
||||||
|
|
||||||
|
//- Base decomposition method
|
||||||
|
autoPtr<decompositionMethod> baseDecompPtr_;
|
||||||
|
|
||||||
|
//- Patch names to processor association
|
||||||
|
procWordList patchConstraints_;
|
||||||
|
|
||||||
|
|
||||||
// Private Member Functions
|
// Private Member Functions
|
||||||
|
|
||||||
//- Disallow default bitwise copy construct
|
//- Disallow default bitwise copy construct
|
||||||
solidBodyMotionFunction(const solidBodyMotionFunction&);
|
patchConstrainedDecomp(const patchConstrainedDecomp&);
|
||||||
|
|
||||||
//- Disallow default bitwise assignment
|
//- Disallow default bitwise copy construct and assignment
|
||||||
void operator=(const solidBodyMotionFunction&);
|
void operator=(const patchConstrainedDecomp&);
|
||||||
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
//- Runtime type information
|
//- Runtime type information
|
||||||
TypeName("solidBodyMotionFunction");
|
TypeName("patchConstrained");
|
||||||
|
|
||||||
|
|
||||||
// Declare run-time constructor selection table
|
|
||||||
|
|
||||||
declareRunTimeSelectionTable
|
|
||||||
(
|
|
||||||
autoPtr,
|
|
||||||
solidBodyMotionFunction,
|
|
||||||
dictionary,
|
|
||||||
(const dictionary& SBMFCoeffs, const Time& runTime),
|
|
||||||
(SBMFCoeffs, runTime)
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
// Constructors
|
// Constructors
|
||||||
|
|
||||||
//- Construct from the SBMFCoeffs dictionary and Time
|
//- Construct given the decomposition dictionary and mesh
|
||||||
solidBodyMotionFunction
|
patchConstrainedDecomp
|
||||||
(
|
(
|
||||||
const dictionary& SBMFCoeffs,
|
const dictionary& decompositionDict,
|
||||||
const Time& runTime
|
const polyMesh& mesh
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
// Selectors
|
|
||||||
|
|
||||||
//- Select constructed from the SBMFCoeffs dictionary and Time
|
|
||||||
static autoPtr<solidBodyMotionFunction> New
|
|
||||||
(
|
|
||||||
const dictionary& SBMFCoeffs,
|
|
||||||
const Time& runTime
|
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
// Destructor
|
// Destructor
|
||||||
|
|
||||||
virtual ~solidBodyMotionFunction();
|
virtual ~patchConstrainedDecomp()
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
// Member Functions
|
// Member Functions
|
||||||
|
|
||||||
//- Return the solid-body motion transformation septernion
|
//- Return parallel aware of base method
|
||||||
virtual septernion transformation() const = 0;
|
virtual bool parallelAware() const
|
||||||
|
{
|
||||||
|
return baseDecompPtr_->parallelAware();
|
||||||
|
}
|
||||||
|
|
||||||
//- Update properties from given dictionary
|
//- Decompose cells with weights
|
||||||
virtual bool read(const dictionary& SBMFCoeffs) = 0;
|
virtual labelList decompose
|
||||||
|
(
|
||||||
|
const pointField& points,
|
||||||
|
const scalarField& pointWeights
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Decompose cells with weights with explicitly provided connectivity
|
||||||
|
virtual labelList decompose
|
||||||
|
(
|
||||||
|
const labelListList& globalCellCells,
|
||||||
|
const pointField& cc,
|
||||||
|
const scalarField& cWeights
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return decompose(cc, cWeights);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -72,9 +72,9 @@ void Foam::simpleGeomDecomp::assignToProcessorGroup
|
||||||
|
|
||||||
// assign cells to the first few processor groups (those with
|
// assign cells to the first few processor groups (those with
|
||||||
// one extra cell each
|
// one extra cell each
|
||||||
for (j=0; j<fstProcessorGroup; j++)
|
for (j = 0; j < fstProcessorGroup; j++)
|
||||||
{
|
{
|
||||||
for (register label k=0; k<jumpb; k++)
|
for (register label k = 0; k < jumpb; k++)
|
||||||
{
|
{
|
||||||
processorGroup[ind++] = j;
|
processorGroup[ind++] = j;
|
||||||
}
|
}
|
||||||
|
@ -83,7 +83,7 @@ void Foam::simpleGeomDecomp::assignToProcessorGroup
|
||||||
// and now to the `normal' processor groups
|
// and now to the `normal' processor groups
|
||||||
for (; j<nProcGroup; j++)
|
for (; j<nProcGroup; j++)
|
||||||
{
|
{
|
||||||
for (register label k=0; k<jump; k++)
|
for (register label k = 0; k < jump; k++)
|
||||||
{
|
{
|
||||||
processorGroup[ind++] = j;
|
processorGroup[ind++] = j;
|
||||||
}
|
}
|
||||||
|
@ -316,4 +316,6 @@ Foam::labelList Foam::simpleGeomDecomp::decompose
|
||||||
|
|
||||||
return finalDecomp;
|
return finalDecomp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
// ************************************************************************* //
|
||||||
|
|
|
@ -41,7 +41,7 @@ namespace Foam
|
||||||
{
|
{
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*\
|
/*---------------------------------------------------------------------------*\
|
||||||
Class simpleGeomDecomp Declaration
|
Class simpleGeomDecomp Declaration
|
||||||
\*---------------------------------------------------------------------------*/
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
class simpleGeomDecomp
|
class simpleGeomDecomp
|
||||||
|
@ -61,10 +61,12 @@ class simpleGeomDecomp
|
||||||
const scalar summedWeights
|
const scalar summedWeights
|
||||||
);
|
);
|
||||||
|
|
||||||
//- Disallow default bitwise copy construct and assignment
|
//- Disallow default bitwise copy construct
|
||||||
void operator=(const simpleGeomDecomp&);
|
|
||||||
simpleGeomDecomp(const simpleGeomDecomp&);
|
simpleGeomDecomp(const simpleGeomDecomp&);
|
||||||
|
|
||||||
|
//- Disallow default bitwise assignment
|
||||||
|
void operator=(const simpleGeomDecomp&);
|
||||||
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
@ -75,7 +77,7 @@ public:
|
||||||
// Constructors
|
// Constructors
|
||||||
|
|
||||||
//- Construct given the decomposition dictionary
|
//- Construct given the decomposition dictionary
|
||||||
simpleGeomDecomp(const dictionary& decompositionDict);
|
explicit simpleGeomDecomp(const dictionary& decompositionDict);
|
||||||
|
|
||||||
//- Construct given the decomposition dictionary and mesh
|
//- Construct given the decomposition dictionary and mesh
|
||||||
simpleGeomDecomp
|
simpleGeomDecomp
|
||||||
|
|
|
@ -54,13 +54,11 @@ namespace Foam
|
||||||
|
|
||||||
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||||
|
|
||||||
// Call Metis with options from dictionary.
|
|
||||||
Foam::label Foam::metisDecomp::decompose
|
Foam::label Foam::metisDecomp::decompose
|
||||||
(
|
(
|
||||||
const List<int>& adjncy,
|
const List<int>& adjncy,
|
||||||
const List<int>& xadj,
|
const List<int>& xadj,
|
||||||
const scalarField& cWeights,
|
const scalarField& cWeights,
|
||||||
|
|
||||||
List<int>& finalDecomp
|
List<int>& finalDecomp
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
@ -133,7 +131,8 @@ Foam::label Foam::metisDecomp::decompose
|
||||||
if (method != "recursive" && method != "k-way")
|
if (method != "recursive" && method != "k-way")
|
||||||
{
|
{
|
||||||
FatalErrorIn("metisDecomp::decompose()")
|
FatalErrorIn("metisDecomp::decompose()")
|
||||||
<< "Method " << method << " in metisCoeffs in dictionary : "
|
<< "Method " << method
|
||||||
|
<< " in metisCoeffs in dictionary : "
|
||||||
<< decompositionDict_.name()
|
<< decompositionDict_.name()
|
||||||
<< " should be 'recursive' or 'k-way'"
|
<< " should be 'recursive' or 'k-way'"
|
||||||
<< exit(FatalError);
|
<< exit(FatalError);
|
||||||
|
@ -363,18 +362,18 @@ Foam::labelList Foam::metisDecomp::decompose
|
||||||
|
|
||||||
Foam::labelList Foam::metisDecomp::decompose
|
Foam::labelList Foam::metisDecomp::decompose
|
||||||
(
|
(
|
||||||
const labelList& agglom,
|
const labelList& fineToCoarse,
|
||||||
const pointField& agglomPoints,
|
const pointField& coarsePoints,
|
||||||
const scalarField& agglomWeights
|
const scalarField& coarseWeights
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
if (agglom.size() != mesh_.nCells())
|
if (fineToCoarse.size() != mesh_.nCells())
|
||||||
{
|
{
|
||||||
FatalErrorIn
|
FatalErrorIn
|
||||||
(
|
(
|
||||||
"metisDecomp::decompose"
|
"metisDecomp::decompose"
|
||||||
"(const labelList&, const pointField&, const scalarField&)"
|
"(const labelList&, const pointField&, const scalarField&)"
|
||||||
) << "Size of cell-to-coarse map " << agglom.size()
|
) << "Size of cell-to-coarse map " << fineToCoarse.size()
|
||||||
<< " differs from number of cells in mesh " << mesh_.nCells()
|
<< " differs from number of cells in mesh " << mesh_.nCells()
|
||||||
<< exit(FatalError);
|
<< exit(FatalError);
|
||||||
}
|
}
|
||||||
|
@ -390,8 +389,8 @@ Foam::labelList Foam::metisDecomp::decompose
|
||||||
calcCellCells
|
calcCellCells
|
||||||
(
|
(
|
||||||
mesh_,
|
mesh_,
|
||||||
agglom,
|
fineToCoarse,
|
||||||
agglomPoints.size(),
|
coarsePoints.size(),
|
||||||
cellCells
|
cellCells
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -400,15 +399,15 @@ Foam::labelList Foam::metisDecomp::decompose
|
||||||
|
|
||||||
// Decompose using default weights
|
// Decompose using default weights
|
||||||
List<int> finalDecomp;
|
List<int> finalDecomp;
|
||||||
decompose(adjncy, xadj, agglomWeights, finalDecomp);
|
decompose(adjncy, xadj, coarseWeights, finalDecomp);
|
||||||
|
|
||||||
|
|
||||||
// Rework back into decomposition for original mesh_
|
// Rework back into decomposition for original mesh_
|
||||||
labelList fineDistribution(agglom.size());
|
labelList fineDistribution(fineToCoarse.size());
|
||||||
|
|
||||||
forAll(fineDistribution, i)
|
forAll(fineDistribution, i)
|
||||||
{
|
{
|
||||||
fineDistribution[i] = finalDecomp[agglom[i]];
|
fineDistribution[i] = finalDecomp[fineToCoarse[i]];
|
||||||
}
|
}
|
||||||
|
|
||||||
return fineDistribution;
|
return fineDistribution;
|
||||||
|
@ -418,18 +417,18 @@ Foam::labelList Foam::metisDecomp::decompose
|
||||||
Foam::labelList Foam::metisDecomp::decompose
|
Foam::labelList Foam::metisDecomp::decompose
|
||||||
(
|
(
|
||||||
const labelListList& globalCellCells,
|
const labelListList& globalCellCells,
|
||||||
const pointField& cellCentres,
|
const pointField& cc,
|
||||||
const scalarField& cellWeights
|
const scalarField& cWeights
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
if (cellCentres.size() != globalCellCells.size())
|
if (cc.size() != globalCellCells.size())
|
||||||
{
|
{
|
||||||
FatalErrorIn
|
FatalErrorIn
|
||||||
(
|
(
|
||||||
"metisDecomp::decompose"
|
"metisDecomp::decompose"
|
||||||
"(const pointField&, const labelListList&, const scalarField&)"
|
"(const pointField&, const labelListList&, const scalarField&)"
|
||||||
) << "Inconsistent number of cells (" << globalCellCells.size()
|
) << "Inconsistent number of cells (" << globalCellCells.size()
|
||||||
<< ") and number of cell centres (" << cellCentres.size()
|
<< ") and number of cell centres (" << cc.size()
|
||||||
<< ")." << exit(FatalError);
|
<< ")." << exit(FatalError);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -442,17 +441,18 @@ Foam::labelList Foam::metisDecomp::decompose
|
||||||
List<int> xadj;
|
List<int> xadj;
|
||||||
scotchDecomp::calcCSR(globalCellCells, adjncy, xadj);
|
scotchDecomp::calcCSR(globalCellCells, adjncy, xadj);
|
||||||
|
|
||||||
|
|
||||||
// Decompose using default weights
|
// Decompose using default weights
|
||||||
List<int> finalDecomp;
|
List<int> finalDecomp;
|
||||||
decompose(adjncy, xadj, cellWeights, finalDecomp);
|
decompose(adjncy, xadj, cWeights, finalDecomp);
|
||||||
|
|
||||||
// Copy back to labelList
|
// Copy back to labelList
|
||||||
labelList decomp(finalDecomp.size());
|
labelList decomp(finalDecomp.size());
|
||||||
|
|
||||||
forAll(decomp, i)
|
forAll(decomp, i)
|
||||||
{
|
{
|
||||||
decomp[i] = finalDecomp[i];
|
decomp[i] = finalDecomp[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
return decomp;
|
return decomp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -56,6 +56,12 @@ class metisDecomp
|
||||||
|
|
||||||
// Private Member Functions
|
// Private Member Functions
|
||||||
|
|
||||||
|
//- Disallow default bitwise copy construct
|
||||||
|
metisDecomp(const metisDecomp&);
|
||||||
|
|
||||||
|
//- Disallow default bitwise assignment
|
||||||
|
void operator=(const metisDecomp&);
|
||||||
|
|
||||||
label decompose
|
label decompose
|
||||||
(
|
(
|
||||||
const List<int>& adjncy,
|
const List<int>& adjncy,
|
||||||
|
@ -64,10 +70,6 @@ class metisDecomp
|
||||||
List<int>& finalDecomp
|
List<int>& finalDecomp
|
||||||
);
|
);
|
||||||
|
|
||||||
//- Disallow default bitwise copy construct and assignment
|
|
||||||
void operator=(const metisDecomp&);
|
|
||||||
metisDecomp(const metisDecomp&);
|
|
||||||
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
@ -99,44 +101,28 @@ public:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
//- Return for every coordinate the wanted processor number. Use the
|
//- Decompose cells with weights
|
||||||
// mesh connectivity (if needed)
|
|
||||||
// Weights get normalised so the minimum value is 1 before truncation
|
|
||||||
// to an integer so the weights should be multiples of the minimum
|
|
||||||
// value. The overall sum of weights might otherwise overflow.
|
|
||||||
virtual labelList decompose
|
virtual labelList decompose
|
||||||
(
|
(
|
||||||
const pointField& points,
|
const pointField& points,
|
||||||
const scalarField& pointWeights
|
const scalarField& pointWeights
|
||||||
);
|
);
|
||||||
|
|
||||||
//- Return for every coordinate the wanted processor number. Gets
|
//- Decompose cell clusters with weights on clusters
|
||||||
// passed agglomeration map (from fine to coarse cells) and coarse cell
|
|
||||||
// location. Can be overridden by decomposers that provide this
|
|
||||||
// functionality natively.
|
|
||||||
// See note on weights above.
|
|
||||||
virtual labelList decompose
|
virtual labelList decompose
|
||||||
(
|
(
|
||||||
const labelList& agglom,
|
const labelList& fineToCoarse,
|
||||||
const pointField& regionPoints,
|
const pointField& coarsePoints,
|
||||||
const scalarField& regionWeights
|
const scalarField& coarseWeights
|
||||||
);
|
);
|
||||||
|
|
||||||
//- Return for every coordinate the wanted processor number. Explicitly
|
//- Decompose cells with weights with explicitly provided connectivity
|
||||||
// provided mesh connectivity.
|
|
||||||
// The connectivity is equal to mesh.cellCells() except for
|
|
||||||
// - in parallel the cell numbers are global cell numbers (starting
|
|
||||||
// from 0 at processor0 and then incrementing all through the
|
|
||||||
// processors)
|
|
||||||
// - the connections are across coupled patches
|
|
||||||
// See note on weights above.
|
|
||||||
virtual labelList decompose
|
virtual labelList decompose
|
||||||
(
|
(
|
||||||
const labelListList& globalCellCells,
|
const labelListList& globalCellCells,
|
||||||
const pointField& cc,
|
const pointField& cc,
|
||||||
const scalarField& cWeights
|
const scalarField& cWeights
|
||||||
);
|
);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -26,13 +26,11 @@ License
|
||||||
|
|
||||||
#include "parMetisDecomp.H"
|
#include "parMetisDecomp.H"
|
||||||
#include "metisDecomp.H"
|
#include "metisDecomp.H"
|
||||||
#include "scotchDecomp.H"
|
|
||||||
#include "syncTools.H"
|
|
||||||
#include "addToRunTimeSelectionTable.H"
|
#include "addToRunTimeSelectionTable.H"
|
||||||
#include "floatScalar.H"
|
#include "floatScalar.H"
|
||||||
#include "polyMesh.H"
|
|
||||||
#include "Time.H"
|
#include "Time.H"
|
||||||
#include "labelIOField.H"
|
#include "labelIOField.H"
|
||||||
|
#include "syncTools.H"
|
||||||
#include "globalIndex.H"
|
#include "globalIndex.H"
|
||||||
|
|
||||||
#include <mpi.h>
|
#include <mpi.h>
|
||||||
|
@ -68,7 +66,6 @@ Foam::label Foam::parMetisDecomp::decompose
|
||||||
Field<int>& cellWeights,
|
Field<int>& cellWeights,
|
||||||
Field<int>& faceWeights,
|
Field<int>& faceWeights,
|
||||||
const List<int>& options,
|
const List<int>& options,
|
||||||
|
|
||||||
List<int>& finalDecomp
|
List<int>& finalDecomp
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
@ -406,7 +403,7 @@ Foam::labelList Foam::parMetisDecomp::decompose
|
||||||
Field<int> adjncy;
|
Field<int> adjncy;
|
||||||
// Offsets into adjncy
|
// Offsets into adjncy
|
||||||
Field<int> xadj;
|
Field<int> xadj;
|
||||||
calcMetisDistributedCSR
|
calcDistributedCSR
|
||||||
(
|
(
|
||||||
mesh_,
|
mesh_,
|
||||||
adjncy,
|
adjncy,
|
||||||
|
@ -594,7 +591,6 @@ Foam::labelList Foam::parMetisDecomp::decompose
|
||||||
cellWeights,
|
cellWeights,
|
||||||
faceWeights,
|
faceWeights,
|
||||||
options,
|
options,
|
||||||
|
|
||||||
finalDecomp
|
finalDecomp
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -706,7 +702,11 @@ Foam::labelList Foam::parMetisDecomp::decompose
|
||||||
label globalNei = globalNeighbour[bFaceI++];
|
label globalNei = globalNeighbour[bFaceI++];
|
||||||
faceI++;
|
faceI++;
|
||||||
|
|
||||||
if (findIndex(dynRegionRegions[ownRegion], globalNei) == -1)
|
if
|
||||||
|
(
|
||||||
|
findIndex(dynRegionRegions[ownRegion], globalNei)
|
||||||
|
== -1
|
||||||
|
)
|
||||||
{
|
{
|
||||||
dynRegionRegions[ownRegion].append(globalNei);
|
dynRegionRegions[ownRegion].append(globalNei);
|
||||||
}
|
}
|
||||||
|
@ -738,6 +738,7 @@ Foam::labelList Foam::parMetisDecomp::decompose
|
||||||
{
|
{
|
||||||
cellDistribution[cellI] = regionDecomp[cellToRegion[cellI]];
|
cellDistribution[cellI] = regionDecomp[cellToRegion[cellI]];
|
||||||
}
|
}
|
||||||
|
|
||||||
return cellDistribution;
|
return cellDistribution;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -763,8 +764,12 @@ Foam::labelList Foam::parMetisDecomp::decompose
|
||||||
// For running sequential ...
|
// For running sequential ...
|
||||||
if (Pstream::nProcs() <= 1)
|
if (Pstream::nProcs() <= 1)
|
||||||
{
|
{
|
||||||
return metisDecomp(decompositionDict_, mesh_)
|
return metisDecomp(decompositionDict_, mesh_).decompose
|
||||||
.decompose(globalCellCells, cellCentres, cWeights);
|
(
|
||||||
|
globalCellCells,
|
||||||
|
cellCentres,
|
||||||
|
cWeights
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -772,9 +777,11 @@ Foam::labelList Foam::parMetisDecomp::decompose
|
||||||
|
|
||||||
// Connections
|
// Connections
|
||||||
Field<int> adjncy;
|
Field<int> adjncy;
|
||||||
|
|
||||||
// Offsets into adjncy
|
// Offsets into adjncy
|
||||||
Field<int> xadj;
|
Field<int> xadj;
|
||||||
scotchDecomp::calcCSR(globalCellCells, adjncy, xadj);
|
|
||||||
|
calcCSR(globalCellCells, adjncy, xadj);
|
||||||
|
|
||||||
// decomposition options. 0 = use defaults
|
// decomposition options. 0 = use defaults
|
||||||
List<int> options(3, 0);
|
List<int> options(3, 0);
|
||||||
|
@ -857,7 +864,6 @@ Foam::labelList Foam::parMetisDecomp::decompose
|
||||||
cellWeights,
|
cellWeights,
|
||||||
faceWeights,
|
faceWeights,
|
||||||
options,
|
options,
|
||||||
|
|
||||||
finalDecomp
|
finalDecomp
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -871,146 +877,4 @@ Foam::labelList Foam::parMetisDecomp::decompose
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Foam::parMetisDecomp::calcMetisDistributedCSR
|
|
||||||
(
|
|
||||||
const polyMesh& mesh,
|
|
||||||
List<int>& adjncy,
|
|
||||||
List<int>& xadj
|
|
||||||
)
|
|
||||||
{
|
|
||||||
// Create global cell numbers
|
|
||||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
globalIndex globalCells(mesh.nCells());
|
|
||||||
|
|
||||||
|
|
||||||
//
|
|
||||||
// Make Metis Distributed CSR (Compressed Storage Format) storage
|
|
||||||
// adjncy : contains cellCells (= edges in graph)
|
|
||||||
// xadj(celli) : start of information in adjncy for celli
|
|
||||||
//
|
|
||||||
|
|
||||||
|
|
||||||
const labelList& faceOwner = mesh.faceOwner();
|
|
||||||
const labelList& faceNeighbour = mesh.faceNeighbour();
|
|
||||||
const polyBoundaryMesh& patches = mesh.boundaryMesh();
|
|
||||||
|
|
||||||
|
|
||||||
// Get renumbered owner on other side of coupled faces
|
|
||||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
List<int> globalNeighbour(mesh.nFaces()-mesh.nInternalFaces());
|
|
||||||
|
|
||||||
forAll(patches, patchI)
|
|
||||||
{
|
|
||||||
const polyPatch& pp = patches[patchI];
|
|
||||||
|
|
||||||
if (pp.coupled())
|
|
||||||
{
|
|
||||||
label faceI = pp.start();
|
|
||||||
label bFaceI = pp.start() - mesh.nInternalFaces();
|
|
||||||
|
|
||||||
forAll(pp, i)
|
|
||||||
{
|
|
||||||
globalNeighbour[bFaceI++] = globalCells.toGlobal
|
|
||||||
(
|
|
||||||
faceOwner[faceI++]
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get the cell on the other side of coupled patches
|
|
||||||
syncTools::swapBoundaryFaceList(mesh, globalNeighbour, false);
|
|
||||||
|
|
||||||
|
|
||||||
// Count number of faces (internal + coupled)
|
|
||||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
// Number of faces per cell
|
|
||||||
List<int> nFacesPerCell(mesh.nCells(), 0);
|
|
||||||
|
|
||||||
// Number of coupled faces
|
|
||||||
label nCoupledFaces = 0;
|
|
||||||
|
|
||||||
for (label faceI = 0; faceI < mesh.nInternalFaces(); faceI++)
|
|
||||||
{
|
|
||||||
nFacesPerCell[faceOwner[faceI]]++;
|
|
||||||
nFacesPerCell[faceNeighbour[faceI]]++;
|
|
||||||
}
|
|
||||||
// Handle coupled faces
|
|
||||||
forAll(patches, patchI)
|
|
||||||
{
|
|
||||||
const polyPatch& pp = patches[patchI];
|
|
||||||
|
|
||||||
if (pp.coupled())
|
|
||||||
{
|
|
||||||
label faceI = pp.start();
|
|
||||||
|
|
||||||
forAll(pp, i)
|
|
||||||
{
|
|
||||||
nCoupledFaces++;
|
|
||||||
nFacesPerCell[faceOwner[faceI++]]++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Fill in xadj
|
|
||||||
// ~~~~~~~~~~~~
|
|
||||||
|
|
||||||
xadj.setSize(mesh.nCells()+1);
|
|
||||||
|
|
||||||
int freeAdj = 0;
|
|
||||||
|
|
||||||
for (label cellI = 0; cellI < mesh.nCells(); cellI++)
|
|
||||||
{
|
|
||||||
xadj[cellI] = freeAdj;
|
|
||||||
|
|
||||||
freeAdj += nFacesPerCell[cellI];
|
|
||||||
}
|
|
||||||
xadj[mesh.nCells()] = freeAdj;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Fill in adjncy
|
|
||||||
// ~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
adjncy.setSize(2*mesh.nInternalFaces() + nCoupledFaces);
|
|
||||||
|
|
||||||
nFacesPerCell = 0;
|
|
||||||
|
|
||||||
// For internal faces is just offsetted owner and neighbour
|
|
||||||
for (label faceI = 0; faceI < mesh.nInternalFaces(); faceI++)
|
|
||||||
{
|
|
||||||
label own = faceOwner[faceI];
|
|
||||||
label nei = faceNeighbour[faceI];
|
|
||||||
|
|
||||||
adjncy[xadj[own] + nFacesPerCell[own]++] = globalCells.toGlobal(nei);
|
|
||||||
adjncy[xadj[nei] + nFacesPerCell[nei]++] = globalCells.toGlobal(own);
|
|
||||||
}
|
|
||||||
// For boundary faces is offsetted coupled neighbour
|
|
||||||
forAll(patches, patchI)
|
|
||||||
{
|
|
||||||
const polyPatch& pp = patches[patchI];
|
|
||||||
|
|
||||||
if (pp.coupled())
|
|
||||||
{
|
|
||||||
label faceI = pp.start();
|
|
||||||
label bFaceI = pp.start()-mesh.nInternalFaces();
|
|
||||||
|
|
||||||
forAll(pp, i)
|
|
||||||
{
|
|
||||||
label own = faceOwner[faceI];
|
|
||||||
adjncy[xadj[own] + nFacesPerCell[own]++] =
|
|
||||||
globalNeighbour[bFaceI];
|
|
||||||
|
|
||||||
faceI++;
|
|
||||||
bFaceI++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
// ************************************************************************* //
|
||||||
|
|
|
@ -41,7 +41,7 @@ namespace Foam
|
||||||
{
|
{
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*\
|
/*---------------------------------------------------------------------------*\
|
||||||
Class parMetisDecomp Declaration
|
Class parMetisDecomp Declaration
|
||||||
\*---------------------------------------------------------------------------*/
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
class parMetisDecomp
|
class parMetisDecomp
|
||||||
|
@ -55,10 +55,18 @@ class parMetisDecomp
|
||||||
|
|
||||||
// Private Member Functions
|
// Private Member Functions
|
||||||
|
|
||||||
//- Insert list in front of list.
|
//- Disallow default bitwise copy construct
|
||||||
|
parMetisDecomp(const parMetisDecomp&);
|
||||||
|
|
||||||
|
//- Disallow default bitwise assignment
|
||||||
|
void operator=(const parMetisDecomp&);
|
||||||
|
|
||||||
|
|
||||||
|
//- Insert list in front of list
|
||||||
template<class Type>
|
template<class Type>
|
||||||
static void prepend(const UList<Type>&, List<Type>&);
|
static void prepend(const UList<Type>&, List<Type>&);
|
||||||
//- Insert list at end of list.
|
|
||||||
|
//- Insert list at end of list
|
||||||
template<class Type>
|
template<class Type>
|
||||||
static void append(const UList<Type>&, List<Type>&);
|
static void append(const UList<Type>&, List<Type>&);
|
||||||
|
|
||||||
|
@ -75,11 +83,6 @@ class parMetisDecomp
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
//- Disallow default bitwise copy construct and assignment
|
|
||||||
void operator=(const parMetisDecomp&);
|
|
||||||
parMetisDecomp(const parMetisDecomp&);
|
|
||||||
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
//- Runtime type information
|
//- Runtime type information
|
||||||
|
@ -110,22 +113,14 @@ public:
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
//- Return for every coordinate the wanted processor number. Use the
|
//- Decompose cells with weights
|
||||||
// mesh connectivity (if needed)
|
|
||||||
// Weights get normalised so the minimum value is 1 before truncation
|
|
||||||
// to an integer so the weights should be multiples of the minimum
|
|
||||||
// value. The overall sum of weights might otherwise overflow.
|
|
||||||
virtual labelList decompose
|
virtual labelList decompose
|
||||||
(
|
(
|
||||||
const pointField& points,
|
const pointField& points,
|
||||||
const scalarField& pointWeights
|
const scalarField& pointWeights
|
||||||
);
|
);
|
||||||
|
|
||||||
//- Return for every coordinate the wanted processor number. Gets
|
//- Decompose cell clusters with weights on clusters
|
||||||
// passed agglomeration map (from fine to coarse cells) and coarse cell
|
|
||||||
// location. Can be overridden by decomposers that provide this
|
|
||||||
// functionality natively.
|
|
||||||
// See note on weights above.
|
|
||||||
virtual labelList decompose
|
virtual labelList decompose
|
||||||
(
|
(
|
||||||
const labelList& cellToRegion,
|
const labelList& cellToRegion,
|
||||||
|
@ -133,28 +128,13 @@ public:
|
||||||
const scalarField& regionWeights
|
const scalarField& regionWeights
|
||||||
);
|
);
|
||||||
|
|
||||||
//- Return for every coordinate the wanted processor number. Explicitly
|
//- Decompose cells with weights with explicitly provided connectivity
|
||||||
// provided mesh connectivity.
|
|
||||||
// The connectivity is equal to mesh.cellCells() except for
|
|
||||||
// - in parallel the cell numbers are global cell numbers (starting
|
|
||||||
// from 0 at processor0 and then incrementing all through the
|
|
||||||
// processors)
|
|
||||||
// - the connections are across coupled patches
|
|
||||||
// See note on weights above.
|
|
||||||
virtual labelList decompose
|
virtual labelList decompose
|
||||||
(
|
(
|
||||||
const labelListList& globalCellCells,
|
const labelListList& globalCellCells,
|
||||||
const pointField& cc,
|
const pointField& cc,
|
||||||
const scalarField& cWeights
|
const scalarField& cWeights
|
||||||
);
|
);
|
||||||
|
|
||||||
//- Helper to convert mesh connectivity into distributed CSR
|
|
||||||
static void calcMetisDistributedCSR
|
|
||||||
(
|
|
||||||
const polyMesh&,
|
|
||||||
List<int>& adjncy,
|
|
||||||
List<int>& xadj
|
|
||||||
);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
scotchDecomp.C
|
scotchDecomp/scotchDecomp.C
|
||||||
|
engineScotchDecomp/engineScotchDecomp.C
|
||||||
|
|
||||||
LIB = $(FOAM_LIBBIN)/libscotchDecomp
|
LIB = $(FOAM_LIBBIN)/libscotchDecomp
|
||||||
|
|
|
@ -0,0 +1,459 @@
|
||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | Copyright held by original author
|
||||||
|
\\/ 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 2 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, write to the Free Software Foundation,
|
||||||
|
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#include "engineScotchDecomp.H"
|
||||||
|
#include "addToRunTimeSelectionTable.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
defineTypeNameAndDebug(engineScotchDecomp, 0);
|
||||||
|
|
||||||
|
addToRunTimeSelectionTable
|
||||||
|
(
|
||||||
|
scotchDecomp,
|
||||||
|
engineScotchDecomp,
|
||||||
|
dictionaryMesh
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Foam::engineScotchDecomp::engineScotchDecomp
|
||||||
|
(
|
||||||
|
const dictionary& decompositionDict,
|
||||||
|
const polyMesh& mesh
|
||||||
|
)
|
||||||
|
:
|
||||||
|
scotchDecomp(decompositionDict, mesh),
|
||||||
|
dict_(decompositionDict.subDict(typeName + "Coeffs")),
|
||||||
|
slidingPatchPairs_(dict_.lookup("slidingPatchPairs")),
|
||||||
|
expandSliding_(dict_.lookup("expandSliding"))
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Foam::labelList Foam::engineScotchDecomp::decompose
|
||||||
|
(
|
||||||
|
const pointField& points,
|
||||||
|
const scalarField& pointWeights
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (points.size() != mesh().nCells())
|
||||||
|
{
|
||||||
|
FatalErrorIn
|
||||||
|
(
|
||||||
|
"engineScotchDecomp::decompose\n"
|
||||||
|
"(\n"
|
||||||
|
" const pointField&,\n"
|
||||||
|
" const scalarField&\n"
|
||||||
|
")"
|
||||||
|
) << "Can use this decomposition method only for the whole mesh"
|
||||||
|
<< endl
|
||||||
|
<< "and supply one coordinate (cellCentre) for every cell." << endl
|
||||||
|
<< "The number of coordinates " << points.size() << endl
|
||||||
|
<< "The number of cells in the mesh " << mesh().nCells()
|
||||||
|
<< exit(FatalError);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create clustering to coarse level
|
||||||
|
|
||||||
|
labelList fineToCoarse(mesh().nCells(), -1);
|
||||||
|
|
||||||
|
// Mask all cells in the cylinder layering region with true
|
||||||
|
// Used in two-pass decomposition later
|
||||||
|
boolList cylinderMask(mesh().nCells(), false);
|
||||||
|
label nClusters = 0;
|
||||||
|
|
||||||
|
// Locate piston patch and cluster up colums, using opposite faces
|
||||||
|
label pistonPatchID = mesh().boundaryMesh().findPatchID("piston");
|
||||||
|
|
||||||
|
// Go through the sliding pairs and mark clustering
|
||||||
|
forAll (slidingPatchPairs_, pairI)
|
||||||
|
{
|
||||||
|
// Locate patch and cluster up colums, using opposite faces
|
||||||
|
label firstPatchID = mesh().boundaryMesh().findPatchID
|
||||||
|
(
|
||||||
|
slidingPatchPairs_[pairI].first()
|
||||||
|
);
|
||||||
|
|
||||||
|
label secondPatchID = mesh().boundaryMesh().findPatchID
|
||||||
|
(
|
||||||
|
slidingPatchPairs_[pairI].second()
|
||||||
|
);
|
||||||
|
|
||||||
|
if (firstPatchID == -1 || secondPatchID == -1)
|
||||||
|
{
|
||||||
|
FatalErrorIn
|
||||||
|
(
|
||||||
|
"labelList engineScotchDecomp::decompose\n"
|
||||||
|
"(\n"
|
||||||
|
" const pointField& points,\n"
|
||||||
|
" const scalarField& pointWeights\n"
|
||||||
|
")"
|
||||||
|
) << "Cannot find sliding patch pair "
|
||||||
|
<< slidingPatchPairs_[pairI]
|
||||||
|
<< abort(FatalError);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Put all cells next to the patch into a cluster
|
||||||
|
if (expandSliding_)
|
||||||
|
{
|
||||||
|
// Use point-cell addressing from patch points
|
||||||
|
const labelListList& pc = mesh().pointCells();
|
||||||
|
|
||||||
|
// First side
|
||||||
|
const labelList& mp1 =
|
||||||
|
mesh().boundaryMesh()[firstPatchID].meshPoints();
|
||||||
|
|
||||||
|
forAll (mp1, pointI)
|
||||||
|
{
|
||||||
|
const labelList& curCells = pc[mp1[pointI]];
|
||||||
|
|
||||||
|
forAll (curCells, cellI)
|
||||||
|
{
|
||||||
|
fineToCoarse[curCells[cellI]] = nClusters;
|
||||||
|
cylinderMask[curCells[cellI]] = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Second side
|
||||||
|
{
|
||||||
|
const labelList& mp2 =
|
||||||
|
mesh().boundaryMesh()[secondPatchID].meshPoints();
|
||||||
|
|
||||||
|
forAll (mp2, pointI)
|
||||||
|
{
|
||||||
|
const labelList& curCells = pc[mp2[pointI]];
|
||||||
|
|
||||||
|
forAll (curCells, cellI)
|
||||||
|
{
|
||||||
|
fineToCoarse[curCells[cellI]] = nClusters;
|
||||||
|
cylinderMask[curCells[cellI]] = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// First side
|
||||||
|
{
|
||||||
|
const labelList& fc1 =
|
||||||
|
mesh().boundaryMesh()[firstPatchID].faceCells();
|
||||||
|
|
||||||
|
forAll (fc1, fcI)
|
||||||
|
{
|
||||||
|
fineToCoarse[fc1[fcI]] = nClusters;
|
||||||
|
cylinderMask[fc1[fcI]] = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Second side
|
||||||
|
{
|
||||||
|
const labelList& fc2 =
|
||||||
|
mesh().boundaryMesh()[secondPatchID].faceCells();
|
||||||
|
|
||||||
|
forAll (fc2, fcI)
|
||||||
|
{
|
||||||
|
fineToCoarse[fc2[fcI]] = nClusters;
|
||||||
|
cylinderMask[fc2[fcI]] = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
nClusters++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pistonPatchID > -1)
|
||||||
|
{
|
||||||
|
// Found piston patch
|
||||||
|
const faceList& f = mesh().allFaces();
|
||||||
|
const cellList& c = mesh().cells();
|
||||||
|
const labelList& owner = mesh().faceOwner();
|
||||||
|
const labelList& neighbour = mesh().faceNeighbour();
|
||||||
|
|
||||||
|
const labelList& faceCells =
|
||||||
|
mesh().boundaryMesh()[pistonPatchID].faceCells();
|
||||||
|
|
||||||
|
forAll (faceCells, faceI)
|
||||||
|
{
|
||||||
|
// Get face index
|
||||||
|
label curFaceNo = faceI
|
||||||
|
+ mesh().boundaryMesh()[pistonPatchID].start();
|
||||||
|
|
||||||
|
// Get cell index
|
||||||
|
label curCellNo = faceCells[faceI];
|
||||||
|
|
||||||
|
// Mark cell to cluster
|
||||||
|
if (fineToCoarse[curCellNo] < 0)
|
||||||
|
{
|
||||||
|
// New cluster
|
||||||
|
fineToCoarse[curCellNo] = nClusters;
|
||||||
|
cylinderMask[curCellNo] = true;
|
||||||
|
|
||||||
|
for(;;)
|
||||||
|
{
|
||||||
|
// Attempt to find the next face and cell
|
||||||
|
curFaceNo = c[curCellNo].opposingFaceLabel(curFaceNo, f);
|
||||||
|
|
||||||
|
if (curFaceNo > -1)
|
||||||
|
{
|
||||||
|
// Face found, try for a cell
|
||||||
|
if (curFaceNo < mesh().nInternalFaces())
|
||||||
|
{
|
||||||
|
if (owner[curFaceNo] == curCellNo)
|
||||||
|
{
|
||||||
|
curCellNo = neighbour[curFaceNo];
|
||||||
|
}
|
||||||
|
else if (neighbour[curFaceNo] == curCellNo)
|
||||||
|
{
|
||||||
|
curCellNo = owner[curFaceNo];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Error in layering. Should never happen
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mark cell to cluster
|
||||||
|
fineToCoarse[curCellNo] = nClusters;
|
||||||
|
cylinderMask[curCellNo] = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Hit boundary face
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Cannot find opposing face: out of prismatic region
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Next cluster
|
||||||
|
nClusters++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Count cylinder cells from mask
|
||||||
|
label nCylinderCells = 0;
|
||||||
|
|
||||||
|
forAll (cylinderMask, cellI)
|
||||||
|
{
|
||||||
|
if (cylinderMask[cellI]) nCylinderCells++;
|
||||||
|
}
|
||||||
|
|
||||||
|
label nStaticCells = mesh().nCells() - nCylinderCells;
|
||||||
|
label nCylClusters = nClusters;
|
||||||
|
|
||||||
|
// Visit all unmarked cells and put them into single clusters
|
||||||
|
forAll (fineToCoarse, cellI)
|
||||||
|
{
|
||||||
|
if (fineToCoarse[cellI] == -1)
|
||||||
|
{
|
||||||
|
fineToCoarse[cellI] = nClusters;
|
||||||
|
nClusters++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
label nStaticClusters = nClusters - nCylClusters;
|
||||||
|
|
||||||
|
Info<< "Number of cells: " << mesh().nCells()
|
||||||
|
<< ", in cylinder + sliding: " << nCylinderCells
|
||||||
|
<< ", in static part: " << nStaticCells << nl
|
||||||
|
<< "Number of cylinder clusters " << nCylClusters
|
||||||
|
<< ", static clusters " << nStaticClusters
|
||||||
|
<< ", total clusters " << nClusters << endl;
|
||||||
|
|
||||||
|
// Mark-up complete. Create point centres and weights for all clusters
|
||||||
|
vectorField clusterCentres(nClusters, vector::zero);
|
||||||
|
|
||||||
|
// Stabilise cluster volumes in case a cluster ends up empty
|
||||||
|
// It is possible to have empty clusters without connectivity
|
||||||
|
scalarField clusterVols(nClusters, SMALL);
|
||||||
|
scalarField clusterWeights(nClusters, 0);
|
||||||
|
|
||||||
|
const vectorField& centres = mesh().cellCentres();
|
||||||
|
const scalarField& vols = mesh().cellVolumes();
|
||||||
|
|
||||||
|
forAll (fineToCoarse, cellI)
|
||||||
|
{
|
||||||
|
const label& curCoarse = fineToCoarse[cellI];
|
||||||
|
|
||||||
|
clusterCentres[curCoarse] += centres[cellI]*vols[cellI];
|
||||||
|
clusterVols[curCoarse] += vols[cellI];
|
||||||
|
clusterWeights[curCoarse] += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
clusterCentres /= clusterVols;
|
||||||
|
|
||||||
|
// Execute decomposition, first on cylinder layering zone, then on the rest
|
||||||
|
|
||||||
|
// Collect cell-cells in cylinder layering zone and the rest
|
||||||
|
|
||||||
|
// Create and cellCells hash lookup on two pieces
|
||||||
|
|
||||||
|
// Note: cell clusters come first and they will be done
|
||||||
|
// on a shortened list. Static clusters need to be renumbered by
|
||||||
|
// throwing away the first part of the list
|
||||||
|
|
||||||
|
List<labelHashSet> cylCellCellsHash(nCylClusters);
|
||||||
|
List<labelHashSet> staticCellCellsHash(nStaticClusters);
|
||||||
|
|
||||||
|
const labelListList cellCells = mesh().cellCells();
|
||||||
|
|
||||||
|
forAll (cellCells, cellI)
|
||||||
|
{
|
||||||
|
const labelList& curCC = cellCells[cellI];
|
||||||
|
|
||||||
|
label curCluster = fineToCoarse[cellI];
|
||||||
|
|
||||||
|
if (cylinderMask[cellI])
|
||||||
|
{
|
||||||
|
labelHashSet& curCylAddr = cylCellCellsHash[curCluster];
|
||||||
|
|
||||||
|
// Collect neighbour cluster addressing
|
||||||
|
forAll (curCC, neiI)
|
||||||
|
{
|
||||||
|
// Add neighbour if marked
|
||||||
|
if (cylinderMask[curCC[neiI]])
|
||||||
|
{
|
||||||
|
label nbrCluster = fineToCoarse[curCC[neiI]];
|
||||||
|
|
||||||
|
if (nbrCluster != curCluster)
|
||||||
|
{
|
||||||
|
if (!curCylAddr.found(nbrCluster))
|
||||||
|
{
|
||||||
|
curCylAddr.insert(nbrCluster);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Offset index
|
||||||
|
curCluster -= nCylClusters;
|
||||||
|
|
||||||
|
labelHashSet& curStaticAddr = staticCellCellsHash[curCluster];
|
||||||
|
|
||||||
|
forAll (curCC, neiI)
|
||||||
|
{
|
||||||
|
// Add neighbour if marked
|
||||||
|
if (!cylinderMask[curCC[neiI]])
|
||||||
|
{
|
||||||
|
label nbrCluster = fineToCoarse[curCC[neiI]]
|
||||||
|
- nCylClusters;
|
||||||
|
|
||||||
|
if (nbrCluster != curCluster)
|
||||||
|
{
|
||||||
|
if (!curStaticAddr.found(nbrCluster))
|
||||||
|
{
|
||||||
|
curStaticAddr.insert(nbrCluster);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Pack cellCells on the cylinder
|
||||||
|
labelListList cylCellCells(nCylClusters);
|
||||||
|
|
||||||
|
forAll (cylCellCellsHash, clusterI)
|
||||||
|
{
|
||||||
|
cylCellCells[clusterI] = cylCellCellsHash[clusterI].toc();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Decompose cylinder: size of list equals the number of clusters
|
||||||
|
// in the cylinder region
|
||||||
|
vectorField clusterCentresCyl = clusterCentres;
|
||||||
|
scalarField clusterWeightsCyl = clusterWeights;
|
||||||
|
|
||||||
|
clusterCentresCyl.setSize(nCylClusters);
|
||||||
|
clusterWeightsCyl.setSize(nCylClusters);
|
||||||
|
|
||||||
|
labelList cylDecomp = scotchDecomp::decompose
|
||||||
|
(
|
||||||
|
cylCellCells,
|
||||||
|
clusterCentresCyl,
|
||||||
|
clusterWeightsCyl
|
||||||
|
);
|
||||||
|
|
||||||
|
// Decompose static: size of list equals the number of clusters
|
||||||
|
|
||||||
|
labelListList staticCellCells(nStaticClusters);
|
||||||
|
|
||||||
|
forAll (staticCellCellsHash, clusterI)
|
||||||
|
{
|
||||||
|
staticCellCells[clusterI] = staticCellCellsHash[clusterI].toc();
|
||||||
|
}
|
||||||
|
|
||||||
|
vectorField clusterCentresStatic(nStaticClusters);
|
||||||
|
scalarField clusterWeightsStatic(nStaticClusters);
|
||||||
|
|
||||||
|
forAll (clusterCentresStatic, i)
|
||||||
|
{
|
||||||
|
clusterCentresStatic[i] = clusterCentres[nCylClusters + i];
|
||||||
|
clusterWeightsStatic[i] = clusterWeights[nCylClusters + i];
|
||||||
|
}
|
||||||
|
|
||||||
|
labelList staticDecomp = scotchDecomp::decompose
|
||||||
|
(
|
||||||
|
staticCellCells,
|
||||||
|
clusterCentresStatic,
|
||||||
|
clusterWeightsStatic
|
||||||
|
);
|
||||||
|
|
||||||
|
// Reconstruct final decomposition
|
||||||
|
|
||||||
|
labelList finalDecomp(mesh().nCells(), -1);
|
||||||
|
|
||||||
|
forAll (cylinderMask, cellI)
|
||||||
|
{
|
||||||
|
if (cylinderMask[cellI])
|
||||||
|
{
|
||||||
|
// Cylinder cell
|
||||||
|
finalDecomp[cellI] = cylDecomp[fineToCoarse[cellI]];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Static cell
|
||||||
|
finalDecomp[cellI] =
|
||||||
|
staticDecomp[fineToCoarse[cellI] - nCylClusters];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return finalDecomp;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
|
@ -0,0 +1,154 @@
|
||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | Copyright held by original author
|
||||||
|
\\/ 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 2 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, write to the Free Software Foundation,
|
||||||
|
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
|
||||||
|
Class
|
||||||
|
Foam::engineScotchDecomp
|
||||||
|
|
||||||
|
Description
|
||||||
|
Domain decomposition for internal combustion engine simulations with
|
||||||
|
topological changes.
|
||||||
|
|
||||||
|
The algorithm attempts to be as general as possible and operates in the
|
||||||
|
following steps:
|
||||||
|
- identify piston region and peform a decomposition biased towards the
|
||||||
|
piston axis. This aims to preserve load balancing when cell layers
|
||||||
|
are added
|
||||||
|
- identify static regions and decompose them separately
|
||||||
|
|
||||||
|
Author
|
||||||
|
Hrvoje Jasak, Wikki Ltd. All rights reserved.
|
||||||
|
|
||||||
|
SourceFiles
|
||||||
|
engineScotchDecomp.C
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef engineScotchDecomp_H
|
||||||
|
#define engineScotchDecomp_H
|
||||||
|
|
||||||
|
#include "scotchDecomp.H"
|
||||||
|
#include "Switch.H"
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
Class engineScotchDecomp Declaration
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
class engineScotchDecomp
|
||||||
|
:
|
||||||
|
public scotchDecomp
|
||||||
|
{
|
||||||
|
// Private data
|
||||||
|
|
||||||
|
//- Dictionary
|
||||||
|
dictionary dict_;
|
||||||
|
|
||||||
|
//- Sliding patch pairs
|
||||||
|
List<Pair<word> > slidingPatchPairs_;
|
||||||
|
|
||||||
|
//- Use expanded area around sliding patches
|
||||||
|
Switch expandSliding_;
|
||||||
|
|
||||||
|
|
||||||
|
// Private Member Functions
|
||||||
|
|
||||||
|
//- Disallow default bitwise copy construct
|
||||||
|
engineScotchDecomp(const engineScotchDecomp&);
|
||||||
|
|
||||||
|
//- Disallow default bitwise assignment
|
||||||
|
void operator=(const engineScotchDecomp&);
|
||||||
|
|
||||||
|
|
||||||
|
//- Check and print error message
|
||||||
|
static void check(const int, const char*);
|
||||||
|
|
||||||
|
label decompose
|
||||||
|
(
|
||||||
|
const List<int>& adjncy,
|
||||||
|
const List<int>& xadj,
|
||||||
|
const scalarField& cWeights,
|
||||||
|
List<int>& finalDecomp
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
//- Runtime type information
|
||||||
|
TypeName("engineScotch");
|
||||||
|
|
||||||
|
|
||||||
|
// Constructors
|
||||||
|
|
||||||
|
//- Construct given the decomposition dictionary and mesh
|
||||||
|
engineScotchDecomp
|
||||||
|
(
|
||||||
|
const dictionary& decompositionDict,
|
||||||
|
const polyMesh& mesh
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
// Destructor
|
||||||
|
|
||||||
|
virtual ~engineScotchDecomp()
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
// Member Functions
|
||||||
|
|
||||||
|
virtual bool parallelAware() const
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//- Decompose cells with weights
|
||||||
|
virtual labelList decompose
|
||||||
|
(
|
||||||
|
const pointField& points,
|
||||||
|
const scalarField& pointWeights
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Decompose cells with weights with explicitly provided connectivity
|
||||||
|
virtual labelList decompose
|
||||||
|
(
|
||||||
|
const labelListList& globalCellCells,
|
||||||
|
const pointField& cc,
|
||||||
|
const scalarField& cWeights
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return decompose(cc, cWeights);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
} // End namespace Foam
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
|
@ -109,7 +109,6 @@ License
|
||||||
#include "addToRunTimeSelectionTable.H"
|
#include "addToRunTimeSelectionTable.H"
|
||||||
#include "floatScalar.H"
|
#include "floatScalar.H"
|
||||||
#include "Time.H"
|
#include "Time.H"
|
||||||
#include "cyclicPolyPatch.H"
|
|
||||||
#include "OFstream.H"
|
#include "OFstream.H"
|
||||||
|
|
||||||
extern "C"
|
extern "C"
|
||||||
|
@ -465,17 +464,17 @@ Foam::labelList Foam::scotchDecomp::decompose
|
||||||
|
|
||||||
Foam::labelList Foam::scotchDecomp::decompose
|
Foam::labelList Foam::scotchDecomp::decompose
|
||||||
(
|
(
|
||||||
const labelList& agglom,
|
const labelList& fineToCoarse,
|
||||||
const pointField& agglomPoints,
|
const pointField& coarsePoints,
|
||||||
const scalarField& pointWeights
|
const scalarField& coarseWeights
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
if (agglom.size() != mesh_.nCells())
|
if (fineToCoarse.size() != mesh_.nCells())
|
||||||
{
|
{
|
||||||
FatalErrorIn
|
FatalErrorIn
|
||||||
(
|
(
|
||||||
"parMetisDecomp::decompose(const labelList&, const pointField&)"
|
"parMetisDecomp::decompose(const labelList&, const pointField&)"
|
||||||
) << "Size of cell-to-coarse map " << agglom.size()
|
) << "Size of cell-to-coarse map " << fineToCoarse.size()
|
||||||
<< " differs from number of cells in mesh " << mesh_.nCells()
|
<< " differs from number of cells in mesh " << mesh_.nCells()
|
||||||
<< exit(FatalError);
|
<< exit(FatalError);
|
||||||
}
|
}
|
||||||
|
@ -488,11 +487,12 @@ Foam::labelList Foam::scotchDecomp::decompose
|
||||||
{
|
{
|
||||||
// Get cellCells on coarse mesh.
|
// Get cellCells on coarse mesh.
|
||||||
labelListList cellCells;
|
labelListList cellCells;
|
||||||
|
|
||||||
calcCellCells
|
calcCellCells
|
||||||
(
|
(
|
||||||
mesh_,
|
mesh_,
|
||||||
agglom,
|
fineToCoarse,
|
||||||
agglomPoints.size(),
|
coarsePoints.size(),
|
||||||
cellCells
|
cellCells
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -501,14 +501,14 @@ Foam::labelList Foam::scotchDecomp::decompose
|
||||||
|
|
||||||
// Decompose using weights
|
// Decompose using weights
|
||||||
List<int> finalDecomp;
|
List<int> finalDecomp;
|
||||||
decompose(adjncy, xadj, pointWeights, finalDecomp);
|
decompose(adjncy, xadj, coarseWeights, finalDecomp);
|
||||||
|
|
||||||
// Rework back into decomposition for original mesh_
|
// Rework back into decomposition for original mesh_
|
||||||
labelList fineDistribution(agglom.size());
|
labelList fineDistribution(fineToCoarse.size());
|
||||||
|
|
||||||
forAll(fineDistribution, i)
|
forAll(fineDistribution, i)
|
||||||
{
|
{
|
||||||
fineDistribution[i] = finalDecomp[agglom[i]];
|
fineDistribution[i] = finalDecomp[fineToCoarse[i]];
|
||||||
}
|
}
|
||||||
|
|
||||||
return fineDistribution;
|
return fineDistribution;
|
||||||
|
@ -518,18 +518,18 @@ Foam::labelList Foam::scotchDecomp::decompose
|
||||||
Foam::labelList Foam::scotchDecomp::decompose
|
Foam::labelList Foam::scotchDecomp::decompose
|
||||||
(
|
(
|
||||||
const labelListList& globalCellCells,
|
const labelListList& globalCellCells,
|
||||||
const pointField& cellCentres,
|
const pointField& cc,
|
||||||
const scalarField& cWeights
|
const scalarField& cWeights
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
if (cellCentres.size() != globalCellCells.size())
|
if (cc.size() != globalCellCells.size())
|
||||||
{
|
{
|
||||||
FatalErrorIn
|
FatalErrorIn
|
||||||
(
|
(
|
||||||
"scotchDecomp::decompose"
|
"scotchDecomp::decompose"
|
||||||
"(const labelListList&, const pointField&, const scalarField&)"
|
"(const labelListList&, const pointField&, const scalarField&)"
|
||||||
) << "Inconsistent number of cells (" << globalCellCells.size()
|
) << "Inconsistent number of cells (" << globalCellCells.size()
|
||||||
<< ") and number of cell centres (" << cellCentres.size()
|
<< ") and number of cell centres (" << cc.size()
|
||||||
<< ")." << exit(FatalError);
|
<< ")." << exit(FatalError);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -548,152 +548,14 @@ Foam::labelList Foam::scotchDecomp::decompose
|
||||||
|
|
||||||
// Copy back to labelList
|
// Copy back to labelList
|
||||||
labelList decomp(finalDecomp.size());
|
labelList decomp(finalDecomp.size());
|
||||||
|
|
||||||
forAll(decomp, i)
|
forAll(decomp, i)
|
||||||
{
|
{
|
||||||
decomp[i] = finalDecomp[i];
|
decomp[i] = finalDecomp[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
return decomp;
|
return decomp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Foam::scotchDecomp::calcCSR
|
|
||||||
(
|
|
||||||
const polyMesh& mesh,
|
|
||||||
List<int>& adjncy,
|
|
||||||
List<int>& xadj
|
|
||||||
)
|
|
||||||
{
|
|
||||||
// Make Metis CSR (Compressed Storage Format) storage
|
|
||||||
// adjncy : contains neighbours (= edges in graph)
|
|
||||||
// xadj(celli) : start of information in adjncy for celli
|
|
||||||
|
|
||||||
xadj.setSize(mesh.nCells()+1);
|
|
||||||
|
|
||||||
// Initialise the number of internal faces of the cells to twice the
|
|
||||||
// number of internal faces
|
|
||||||
label nInternalFaces = 2*mesh.nInternalFaces();
|
|
||||||
|
|
||||||
// Check the boundary for coupled patches and add to the number of
|
|
||||||
// internal faces
|
|
||||||
const polyBoundaryMesh& pbm = mesh.boundaryMesh();
|
|
||||||
|
|
||||||
forAll(pbm, patchi)
|
|
||||||
{
|
|
||||||
if (isA<cyclicPolyPatch>(pbm[patchi]))
|
|
||||||
{
|
|
||||||
nInternalFaces += pbm[patchi].size();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create the adjncy array the size of the total number of internal and
|
|
||||||
// coupled faces
|
|
||||||
adjncy.setSize(nInternalFaces);
|
|
||||||
|
|
||||||
// Fill in xadj
|
|
||||||
// ~~~~~~~~~~~~
|
|
||||||
label freeAdj = 0;
|
|
||||||
|
|
||||||
for (label cellI = 0; cellI < mesh.nCells(); cellI++)
|
|
||||||
{
|
|
||||||
xadj[cellI] = freeAdj;
|
|
||||||
|
|
||||||
const labelList& cFaces = mesh.cells()[cellI];
|
|
||||||
|
|
||||||
forAll(cFaces, i)
|
|
||||||
{
|
|
||||||
label faceI = cFaces[i];
|
|
||||||
|
|
||||||
if
|
|
||||||
(
|
|
||||||
mesh.isInternalFace(faceI)
|
|
||||||
|| isA<cyclicPolyPatch>(pbm[pbm.whichPatch(faceI)])
|
|
||||||
)
|
|
||||||
{
|
|
||||||
freeAdj++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
xadj[mesh.nCells()] = freeAdj;
|
|
||||||
|
|
||||||
|
|
||||||
// Fill in adjncy
|
|
||||||
// ~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
labelList nFacesPerCell(mesh.nCells(), 0);
|
|
||||||
|
|
||||||
// Internal faces
|
|
||||||
for (label faceI = 0; faceI < mesh.nInternalFaces(); faceI++)
|
|
||||||
{
|
|
||||||
label own = mesh.faceOwner()[faceI];
|
|
||||||
label nei = mesh.faceNeighbour()[faceI];
|
|
||||||
|
|
||||||
adjncy[xadj[own] + nFacesPerCell[own]++] = nei;
|
|
||||||
adjncy[xadj[nei] + nFacesPerCell[nei]++] = own;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Coupled faces. Only cyclics done.
|
|
||||||
forAll(pbm, patchi)
|
|
||||||
{
|
|
||||||
if (isA<cyclicPolyPatch>(pbm[patchi]))
|
|
||||||
{
|
|
||||||
const unallocLabelList& faceCells = pbm[patchi].faceCells();
|
|
||||||
|
|
||||||
label sizeby2 = faceCells.size()/2;
|
|
||||||
|
|
||||||
for (label facei=0; facei<sizeby2; facei++)
|
|
||||||
{
|
|
||||||
label own = faceCells[facei];
|
|
||||||
label nei = faceCells[facei + sizeby2];
|
|
||||||
|
|
||||||
adjncy[xadj[own] + nFacesPerCell[own]++] = nei;
|
|
||||||
adjncy[xadj[nei] + nFacesPerCell[nei]++] = own;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// From cell-cell connections to Metis format (like CompactListList)
|
|
||||||
void Foam::scotchDecomp::calcCSR
|
|
||||||
(
|
|
||||||
const labelListList& cellCells,
|
|
||||||
List<int>& adjncy,
|
|
||||||
List<int>& xadj
|
|
||||||
)
|
|
||||||
{
|
|
||||||
// Count number of internal faces
|
|
||||||
label nConnections = 0;
|
|
||||||
|
|
||||||
forAll(cellCells, coarseI)
|
|
||||||
{
|
|
||||||
nConnections += cellCells[coarseI].size();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create the adjncy array as twice the size of the total number of
|
|
||||||
// internal faces
|
|
||||||
adjncy.setSize(nConnections);
|
|
||||||
|
|
||||||
xadj.setSize(cellCells.size()+1);
|
|
||||||
|
|
||||||
|
|
||||||
// Fill in xadj
|
|
||||||
// ~~~~~~~~~~~~
|
|
||||||
label freeAdj = 0;
|
|
||||||
|
|
||||||
forAll(cellCells, coarseI)
|
|
||||||
{
|
|
||||||
xadj[coarseI] = freeAdj;
|
|
||||||
|
|
||||||
const labelList& cCells = cellCells[coarseI];
|
|
||||||
|
|
||||||
forAll(cCells, i)
|
|
||||||
{
|
|
||||||
adjncy[freeAdj++] = cCells[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
xadj[cellCells.size()] = freeAdj;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
// ************************************************************************* //
|
|
@ -42,7 +42,7 @@ namespace Foam
|
||||||
{
|
{
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*\
|
/*---------------------------------------------------------------------------*\
|
||||||
Class scotchDecomp Declaration
|
Class scotchDecomp Declaration
|
||||||
\*---------------------------------------------------------------------------*/
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
class scotchDecomp
|
class scotchDecomp
|
||||||
|
@ -51,11 +51,19 @@ class scotchDecomp
|
||||||
{
|
{
|
||||||
// Private data
|
// Private data
|
||||||
|
|
||||||
|
//- Mesh reference
|
||||||
const polyMesh& mesh_;
|
const polyMesh& mesh_;
|
||||||
|
|
||||||
|
|
||||||
// Private Member Functions
|
// Private Member Functions
|
||||||
|
|
||||||
|
//- Disallow default bitwise copy construct
|
||||||
|
scotchDecomp(const scotchDecomp&);
|
||||||
|
|
||||||
|
//- Disallow default bitwise assignment
|
||||||
|
void operator=(const scotchDecomp&);
|
||||||
|
|
||||||
|
|
||||||
//- Check and print error message
|
//- Check and print error message
|
||||||
static void check(const int, const char*);
|
static void check(const int, const char*);
|
||||||
|
|
||||||
|
@ -67,10 +75,6 @@ class scotchDecomp
|
||||||
List<int>& finalDecomp
|
List<int>& finalDecomp
|
||||||
);
|
);
|
||||||
|
|
||||||
//- Disallow default bitwise copy construct and assignment
|
|
||||||
void operator=(const scotchDecomp&);
|
|
||||||
scotchDecomp(const scotchDecomp&);
|
|
||||||
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
@ -96,69 +100,40 @@ public:
|
||||||
|
|
||||||
// Member Functions
|
// Member Functions
|
||||||
|
|
||||||
|
//- Return mesh
|
||||||
|
const polyMesh& mesh() const
|
||||||
|
{
|
||||||
|
return mesh_;
|
||||||
|
}
|
||||||
|
|
||||||
virtual bool parallelAware() const
|
virtual bool parallelAware() const
|
||||||
{
|
{
|
||||||
// Metis does not know about proc boundaries
|
// Scotch does not know about proc boundaries
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
//- Return for every coordinate the wanted processor number. Use the
|
//- Decompose cells with weights
|
||||||
// mesh connectivity (if needed)
|
|
||||||
// Weights get normalised so the minimum value is 1 before truncation
|
|
||||||
// to an integer so the weights should be multiples of the minimum
|
|
||||||
// value. The overall sum of weights might otherwise overflow.
|
|
||||||
virtual labelList decompose
|
virtual labelList decompose
|
||||||
(
|
(
|
||||||
const pointField& points,
|
const pointField& points,
|
||||||
const scalarField& pointWeights
|
const scalarField& pointWeights
|
||||||
);
|
);
|
||||||
|
|
||||||
//- Return for every coordinate the wanted processor number. Gets
|
//- Decompose cell clusters with weights on clusters
|
||||||
// passed agglomeration map (from fine to coarse cells) and coarse cell
|
|
||||||
// location. Can be overridden by decomposers that provide this
|
|
||||||
// functionality natively.
|
|
||||||
// See note on weights above.
|
|
||||||
virtual labelList decompose
|
virtual labelList decompose
|
||||||
(
|
(
|
||||||
const labelList& agglom,
|
const labelList& fineToCoarse,
|
||||||
const pointField& regionPoints,
|
const pointField& coarsePoints,
|
||||||
const scalarField& regionWeights
|
const scalarField& coarseWeights
|
||||||
);
|
);
|
||||||
|
|
||||||
//- Return for every coordinate the wanted processor number. Explicitly
|
//- Decompose cells with weights with explicitly provided connectivity
|
||||||
// provided mesh connectivity.
|
|
||||||
// The connectivity is equal to mesh.cellCells() except for
|
|
||||||
// - in parallel the cell numbers are global cell numbers (starting
|
|
||||||
// from 0 at processor0 and then incrementing all through the
|
|
||||||
// processors)
|
|
||||||
// - the connections are across coupled patches
|
|
||||||
// See note on weights above.
|
|
||||||
virtual labelList decompose
|
virtual labelList decompose
|
||||||
(
|
(
|
||||||
const labelListList& globalCellCells,
|
const labelListList& globalCellCells,
|
||||||
const pointField& cc,
|
const pointField& cc,
|
||||||
const scalarField& cWeights
|
const scalarField& cWeights
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
//- Helper to convert local connectivity (supplied as owner,neighbour)
|
|
||||||
// into CSR (Metis,scotch) storage. Does cyclics but not processor
|
|
||||||
// patches
|
|
||||||
static void calcCSR
|
|
||||||
(
|
|
||||||
const polyMesh& mesh,
|
|
||||||
List<int>& adjncy,
|
|
||||||
List<int>& xadj
|
|
||||||
);
|
|
||||||
|
|
||||||
//- Helper to convert connectivity (supplied as cellcells) into
|
|
||||||
// CSR (Metis,scotch) storage
|
|
||||||
static void calcCSR
|
|
||||||
(
|
|
||||||
const labelListList& globalCellCells,
|
|
||||||
List<int>& adjncy,
|
|
||||||
List<int>& xadj
|
|
||||||
);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
dynamicFvMesh/dynamicFvMesh.C
|
dynamicFvMesh/dynamicFvMesh.C
|
||||||
dynamicFvMesh/newDynamicFvMesh.C
|
dynamicFvMesh/newDynamicFvMesh.C
|
||||||
|
|
||||||
staticFvMesh/staticFvMesh.C
|
staticFvMesh/staticFvMesh.C
|
||||||
|
solidBodyMotionFvMesh/solidBodyMotionFvMesh.C
|
||||||
dynamicBoxFvMesh/dynamicBoxFvMesh.C
|
dynamicBoxFvMesh/dynamicBoxFvMesh.C
|
||||||
movingBoxFvMesh/movingBoxFvMesh.C
|
movingBoxFvMesh/movingBoxFvMesh.C
|
||||||
dynamicBodyFvMesh/dynamicBodyFvMesh.C
|
dynamicBodyFvMesh/dynamicBodyFvMesh.C
|
||||||
|
@ -9,17 +11,12 @@ subsetMotionSolverFvMesh/subsetMotionSolverFvMesh.C
|
||||||
dynamicInkJetFvMesh/dynamicInkJetFvMesh.C
|
dynamicInkJetFvMesh/dynamicInkJetFvMesh.C
|
||||||
dynamicRefineFvMesh/dynamicRefineFvMesh.C
|
dynamicRefineFvMesh/dynamicRefineFvMesh.C
|
||||||
|
|
||||||
solidBodyMotionFvMesh/solidBodyMotionFvMesh.C
|
|
||||||
solidBodyMotionFunctions = solidBodyMotionFvMesh/solidBodyMotionFunctions
|
|
||||||
$(solidBodyMotionFunctions)/solidBodyMotionFunction/solidBodyMotionFunction.C
|
|
||||||
$(solidBodyMotionFunctions)/solidBodyMotionFunction/newSolidBodyMotionFunction.C
|
|
||||||
$(solidBodyMotionFunctions)/SDA/SDA.C
|
|
||||||
$(solidBodyMotionFunctions)/SKA/SKA.C
|
|
||||||
$(solidBodyMotionFunctions)/translation/translation.C
|
|
||||||
|
|
||||||
mixerGgiFvMesh/mixerGgiFvMesh.C
|
mixerGgiFvMesh/mixerGgiFvMesh.C
|
||||||
turboFvMesh/turboFvMesh.C
|
turboFvMesh/turboFvMesh.C
|
||||||
|
|
||||||
|
fvMeshAdder/fvMeshAdder.C
|
||||||
|
fvMeshDistribute/fvMeshDistribute.C
|
||||||
|
|
||||||
tetMetrics = dynamicTopoFvMesh/tetMetrics
|
tetMetrics = dynamicTopoFvMesh/tetMetrics
|
||||||
$(tetMetrics)/tetMetric.C
|
$(tetMetrics)/tetMetric.C
|
||||||
$(tetMetrics)/tetMetrics.C
|
$(tetMetrics)/tetMetrics.C
|
||||||
|
|
|
@ -3,6 +3,7 @@ EXE_INC = \
|
||||||
-I$(LIB_SRC)/meshTools/lnInclude \
|
-I$(LIB_SRC)/meshTools/lnInclude \
|
||||||
-I$(LIB_SRC)/dynamicMesh/dynamicMesh/lnInclude \
|
-I$(LIB_SRC)/dynamicMesh/dynamicMesh/lnInclude \
|
||||||
-I$(LIB_SRC)/finiteVolume/lnInclude \
|
-I$(LIB_SRC)/finiteVolume/lnInclude \
|
||||||
|
-I$(LIB_SRC)/dynamicMesh/meshMotion/solidBodyMotion/lnInclude \
|
||||||
-I$(LIB_SRC)/dynamicMesh/meshMotion/tetDecompositionMotionSolver/lnInclude \
|
-I$(LIB_SRC)/dynamicMesh/meshMotion/tetDecompositionMotionSolver/lnInclude \
|
||||||
-I$(LIB_SRC)/tetDecompositionFiniteElement/lnInclude \
|
-I$(LIB_SRC)/tetDecompositionFiniteElement/lnInclude \
|
||||||
$(WM_DECOMP_INC) \
|
$(WM_DECOMP_INC) \
|
||||||
|
@ -15,6 +16,7 @@ LIB_LIBS = \
|
||||||
-lmeshTools \
|
-lmeshTools \
|
||||||
-ldynamicMesh \
|
-ldynamicMesh \
|
||||||
-lfiniteVolume \
|
-lfiniteVolume \
|
||||||
|
-lsolidBodyMotion \
|
||||||
$(WM_DECOMP_LIBS) \
|
$(WM_DECOMP_LIBS) \
|
||||||
-lfvMotionSolver \
|
-lfvMotionSolver \
|
||||||
-lRBFMotionSolver \
|
-lRBFMotionSolver \
|
||||||
|
|
|
@ -65,10 +65,8 @@ class fvMeshAdder
|
||||||
:
|
:
|
||||||
public polyMeshAdder
|
public polyMeshAdder
|
||||||
{
|
{
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
|
||||||
// Private class
|
// Private class
|
||||||
|
|
||||||
class directFvPatchFieldMapper
|
class directFvPatchFieldMapper
|
|
@ -209,7 +209,7 @@ void Foam::fvMeshDistribute::printCoupleInfo
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Finds (non-empty) patch that exposed internal and proc faces can be put into.
|
// Finds (non-empty) patch that exposed internal and proc faces can be put into
|
||||||
Foam::label Foam::fvMeshDistribute::findNonEmptyPatch() const
|
Foam::label Foam::fvMeshDistribute::findNonEmptyPatch() const
|
||||||
{
|
{
|
||||||
const polyBoundaryMesh& patches = mesh_.boundaryMesh();
|
const polyBoundaryMesh& patches = mesh_.boundaryMesh();
|
||||||
|
@ -288,9 +288,11 @@ Foam::label Foam::fvMeshDistribute::addProcPatch
|
||||||
|
|
||||||
if (polyPatches.findPatchID(patchName) != -1)
|
if (polyPatches.findPatchID(patchName) != -1)
|
||||||
{
|
{
|
||||||
FatalErrorIn("fvMeshDistribute::addProcPatch(const word&, const label)")
|
FatalErrorIn
|
||||||
<< "Cannot create patch " << patchName << " since already exists."
|
(
|
||||||
<< nl
|
"fvMeshDistribute::addProcPatch(const word&, const label)"
|
||||||
|
) << "Cannot create patch " << patchName
|
||||||
|
<< " since it already exists." << nl
|
||||||
<< "Current patch names:" << polyPatches.names()
|
<< "Current patch names:" << polyPatches.names()
|
||||||
<< exit(FatalError);
|
<< exit(FatalError);
|
||||||
}
|
}
|
||||||
|
@ -635,7 +637,7 @@ void Foam::fvMeshDistribute::getNeighbourData
|
||||||
|
|
||||||
const polyBoundaryMesh& patches = mesh_.boundaryMesh();
|
const polyBoundaryMesh& patches = mesh_.boundaryMesh();
|
||||||
|
|
||||||
// Get neighbouring meshFace labels and new processor of coupled boundaries.
|
// Get neighbouring meshFace labels and new processor of coupled boundaries
|
||||||
labelList nbrFaces(nBnd, -1);
|
labelList nbrFaces(nBnd, -1);
|
||||||
labelList nbrNewProc(nBnd, -1);
|
labelList nbrNewProc(nBnd, -1);
|
||||||
|
|
||||||
|
@ -931,8 +933,8 @@ Foam::autoPtr<Foam::mapPolyMesh> Foam::fvMeshDistribute::doRemoveCells
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Delete and add processor patches. Changes mesh and returns per neighbour proc
|
// Delete and add processor patches. Changes mesh and returns per
|
||||||
// the processor patchID.
|
// neighbour processor the processor patchID.
|
||||||
void Foam::fvMeshDistribute::addProcPatches
|
void Foam::fvMeshDistribute::addProcPatches
|
||||||
(
|
(
|
||||||
const labelList& neighbourNewProc, // processor that neighbour is on
|
const labelList& neighbourNewProc, // processor that neighbour is on
|
||||||
|
@ -1371,7 +1373,7 @@ Foam::autoPtr<Foam::mapDistributePolyMesh> Foam::fvMeshDistribute::distribute
|
||||||
FatalErrorIn("fvMeshDistribute::distribute(const labelList&)")
|
FatalErrorIn("fvMeshDistribute::distribute(const labelList&)")
|
||||||
<< "This application requires all non-processor patches"
|
<< "This application requires all non-processor patches"
|
||||||
<< " to be present in the same order on all patches" << nl
|
<< " to be present in the same order on all patches" << nl
|
||||||
<< "followed by the processor patches (which of course are unique)."
|
<< "followed by the processor patches (which are unique)."
|
||||||
<< nl
|
<< nl
|
||||||
<< "Local patches:" << mesh_.boundaryMesh().names()
|
<< "Local patches:" << mesh_.boundaryMesh().names()
|
||||||
<< abort(FatalError);
|
<< abort(FatalError);
|
|
@ -195,7 +195,8 @@ void Foam::fvMeshDistribute::addPatchFields(const word& patchFieldType)
|
||||||
|
|
||||||
for
|
for
|
||||||
(
|
(
|
||||||
typename HashTable<const GeoField*>::const_iterator iter = flds.begin();
|
typename HashTable<const GeoField*>::const_iterator iter =
|
||||||
|
flds.begin();
|
||||||
iter != flds.end();
|
iter != flds.end();
|
||||||
++iter
|
++iter
|
||||||
)
|
)
|
||||||
|
@ -235,7 +236,8 @@ void Foam::fvMeshDistribute::deleteTrailingPatchFields()
|
||||||
|
|
||||||
for
|
for
|
||||||
(
|
(
|
||||||
typename HashTable<const GeoField*>::const_iterator iter = flds.begin();
|
typename HashTable<const GeoField*>::const_iterator iter =
|
||||||
|
flds.begin();
|
||||||
iter != flds.end();
|
iter != flds.end();
|
||||||
++iter
|
++iter
|
||||||
)
|
)
|
||||||
|
@ -347,7 +349,11 @@ void Foam::fvMeshDistribute::mapBoundaryFields
|
||||||
{
|
{
|
||||||
label oldLocalI = oldFaceI - oldPatchStarts[oldPatchI];
|
label oldLocalI = oldFaceI - oldPatchStarts[oldPatchI];
|
||||||
|
|
||||||
if (oldLocalI >= 0 && oldLocalI < oldBfld[oldPatchI].size())
|
if
|
||||||
|
(
|
||||||
|
oldLocalI >= 0
|
||||||
|
&& oldLocalI < oldBfld[oldPatchI].size()
|
||||||
|
)
|
||||||
{
|
{
|
||||||
patchFld[i] = oldBfld[oldPatchI][oldLocalI];
|
patchFld[i] = oldBfld[oldPatchI][oldLocalI];
|
||||||
}
|
}
|
||||||
|
@ -372,7 +378,8 @@ void Foam::fvMeshDistribute::initPatchFields
|
||||||
|
|
||||||
for
|
for
|
||||||
(
|
(
|
||||||
typename HashTable<const GeoField*>::const_iterator iter = flds.begin();
|
typename HashTable<const GeoField*>::const_iterator iter =
|
||||||
|
flds.begin();
|
||||||
iter != flds.end();
|
iter != flds.end();
|
||||||
++iter
|
++iter
|
||||||
)
|
)
|
||||||
|
@ -396,7 +403,7 @@ void Foam::fvMeshDistribute::initPatchFields
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Send fields. Note order supplied so we can receive in exactly the same order.
|
// Send fields. Note order supplied so we can receive in exactly the same order
|
||||||
// Note that field gets written as entry in dictionary so we
|
// Note that field gets written as entry in dictionary so we
|
||||||
// can construct from subdictionary.
|
// can construct from subdictionary.
|
||||||
// (since otherwise the reading as-a-dictionary mixes up entries from
|
// (since otherwise the reading as-a-dictionary mixes up entries from
|
||||||
|
@ -413,7 +420,7 @@ void Foam::fvMeshDistribute::initPatchFields
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// volVectorField {U {internalField ..; boundaryField ..;}}
|
// volVectorField {U {internalField ..; boundaryField ..;}}
|
||||||
//
|
|
||||||
template<class GeoField>
|
template<class GeoField>
|
||||||
void Foam::fvMeshDistribute::sendFields
|
void Foam::fvMeshDistribute::sendFields
|
||||||
(
|
(
|
||||||
|
@ -423,7 +430,8 @@ void Foam::fvMeshDistribute::sendFields
|
||||||
OSstream& toNbr
|
OSstream& toNbr
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
toNbr << GeoField::typeName << token::NL << token::BEGIN_BLOCK << token::NL;
|
toNbr<< GeoField::typeName << token::NL << token::BEGIN_BLOCK
|
||||||
|
<< token::NL;
|
||||||
forAll(fieldNames, i)
|
forAll(fieldNames, i)
|
||||||
{
|
{
|
||||||
if (debug)
|
if (debug)
|
|
@ -1,135 +0,0 @@
|
||||||
/*---------------------------------------------------------------------------*\
|
|
||||||
========= |
|
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
|
||||||
\\ / O peration |
|
|
||||||
\\ / A nd | Copyright held by original author
|
|
||||||
\\/ 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 2 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, write to the Free Software Foundation,
|
|
||||||
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
#include "SDA.H"
|
|
||||||
#include "addToRunTimeSelectionTable.H"
|
|
||||||
#include "mathematicalConstants.H"
|
|
||||||
|
|
||||||
using namespace Foam::mathematicalConstant;
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
namespace Foam
|
|
||||||
{
|
|
||||||
namespace solidBodyMotionFunctions
|
|
||||||
{
|
|
||||||
defineTypeNameAndDebug(SDA, 0);
|
|
||||||
addToRunTimeSelectionTable(solidBodyMotionFunction, SDA, dictionary);
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
Foam::solidBodyMotionFunctions::SDA::SDA
|
|
||||||
(
|
|
||||||
const dictionary& SBMFCoeffs,
|
|
||||||
const Time& runTime
|
|
||||||
)
|
|
||||||
:
|
|
||||||
solidBodyMotionFunction(SBMFCoeffs, runTime),
|
|
||||||
CofG_(SBMFCoeffs_.lookup("CofG"))
|
|
||||||
{
|
|
||||||
read(SBMFCoeffs);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * Destructors * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
Foam::solidBodyMotionFunctions::SDA::~SDA()
|
|
||||||
{}
|
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
Foam::septernion Foam::solidBodyMotionFunctions::SDA::transformation() const
|
|
||||||
{
|
|
||||||
scalar time = time_.value();
|
|
||||||
|
|
||||||
scalar Tpi = Tp_ + dTp_*(time/dTi_); // Current roll period [sec]
|
|
||||||
scalar wr = 2*pi/Tpi; // Current Freq [/sec]
|
|
||||||
|
|
||||||
// Current Phase for roll [rad]
|
|
||||||
scalar r = dTp_/dTi_;
|
|
||||||
scalar u = Tp_ + r*time;
|
|
||||||
scalar phr = 2*pi*((Tp_/u - 1) + log(mag(u)) - log(Tp_))/r;
|
|
||||||
|
|
||||||
// Current Phase for Sway [rad]
|
|
||||||
scalar phs = phr + pi;
|
|
||||||
|
|
||||||
// Current Phase for Heave [rad]
|
|
||||||
scalar phh = phr + pi/2;
|
|
||||||
|
|
||||||
scalar rollA = max(rollAmax_*exp(-sqr(Tpi - Tpn_)/(2*Q_)), rollAmin_);
|
|
||||||
|
|
||||||
vector T
|
|
||||||
(
|
|
||||||
0,
|
|
||||||
swayA_*(sin(wr*time + phs) - sin(phs)),
|
|
||||||
heaveA_*(sin(wr*time + phh) - sin(phh))
|
|
||||||
);
|
|
||||||
quaternion R(rollA*sin(wr*time + phr), 0, 0);
|
|
||||||
septernion TR(septernion(CofG_ + T)*R*septernion(-CofG_));
|
|
||||||
|
|
||||||
Info<< "solidBodyMotionFunctions::SDA::transformation(): "
|
|
||||||
<< "Time = " << time << " transformation: " << TR << endl;
|
|
||||||
|
|
||||||
return TR;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool Foam::solidBodyMotionFunctions::SDA::read(const dictionary& SBMFCoeffs)
|
|
||||||
{
|
|
||||||
solidBodyMotionFunction::read(SBMFCoeffs);
|
|
||||||
|
|
||||||
SBMFCoeffs_.lookup("CofG") >> CofG_;
|
|
||||||
SBMFCoeffs_.lookup("lamda") >> lamda_;
|
|
||||||
SBMFCoeffs_.lookup("rollAmax") >> rollAmax_;
|
|
||||||
SBMFCoeffs_.lookup("rollAmin") >> rollAmin_;
|
|
||||||
SBMFCoeffs_.lookup("heaveA") >> heaveA_;
|
|
||||||
SBMFCoeffs_.lookup("swayA") >> swayA_;
|
|
||||||
SBMFCoeffs_.lookup("Q") >> Q_;
|
|
||||||
SBMFCoeffs_.lookup("Tp") >> Tp_;
|
|
||||||
SBMFCoeffs_.lookup("Tpn") >> Tpn_;
|
|
||||||
SBMFCoeffs_.lookup("dTi") >> dTi_;
|
|
||||||
SBMFCoeffs_.lookup("dTp") >> dTp_;
|
|
||||||
|
|
||||||
// Rescale parameters according to the given scale parameter
|
|
||||||
if (lamda_ > 1 + SMALL)
|
|
||||||
{
|
|
||||||
heaveA_ /= lamda_;
|
|
||||||
swayA_ /= lamda_;
|
|
||||||
Tp_ /= sqrt(lamda_);
|
|
||||||
Tpn_ /= sqrt(lamda_);
|
|
||||||
dTi_ /= sqrt(lamda_);
|
|
||||||
dTp_ /= sqrt(lamda_);
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
|
|
@ -1,147 +0,0 @@
|
||||||
/*---------------------------------------------------------------------------*\
|
|
||||||
========= |
|
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
|
||||||
\\ / O peration |
|
|
||||||
\\ / A nd | Copyright held by original author
|
|
||||||
\\/ 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 2 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, write to the Free Software Foundation,
|
|
||||||
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
|
|
||||||
Class
|
|
||||||
Foam::solidBodyMotionFunctions::SDA
|
|
||||||
|
|
||||||
Description
|
|
||||||
Ship design analysis (SDA) 3DoF motion function.
|
|
||||||
|
|
||||||
Comprising sinusoidal roll (rotation about x), heave (z-translation)
|
|
||||||
and sway (y-translation) motions with changing amplitude and phase.
|
|
||||||
|
|
||||||
See Also
|
|
||||||
SKA (Sea Keeping Analysis) for 6DoF motion.
|
|
||||||
|
|
||||||
SourceFiles
|
|
||||||
SDA.C
|
|
||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
#ifndef SDA_H
|
|
||||||
#define SDA_H
|
|
||||||
|
|
||||||
#include "solidBodyMotionFunction.H"
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
namespace Foam
|
|
||||||
{
|
|
||||||
namespace solidBodyMotionFunctions
|
|
||||||
{
|
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*\
|
|
||||||
Class SDA Declaration
|
|
||||||
\*---------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
class SDA
|
|
||||||
:
|
|
||||||
public solidBodyMotionFunction
|
|
||||||
{
|
|
||||||
// Private data
|
|
||||||
|
|
||||||
//- Center of gravity
|
|
||||||
vector CofG_;
|
|
||||||
|
|
||||||
//- Model scale ratio
|
|
||||||
scalar lamda_;
|
|
||||||
|
|
||||||
//- Max roll amplitude [rad]
|
|
||||||
scalar rollAmax_;
|
|
||||||
|
|
||||||
//- Min roll amplitude [rad]
|
|
||||||
scalar rollAmin_;
|
|
||||||
|
|
||||||
//- Heave amplitude [m]
|
|
||||||
scalar heaveA_;
|
|
||||||
|
|
||||||
//- Sway amplitude [m]
|
|
||||||
scalar swayA_;
|
|
||||||
|
|
||||||
//- Damping Coefficient [-]
|
|
||||||
scalar Q_;
|
|
||||||
|
|
||||||
//- Time Period for liquid [sec]
|
|
||||||
scalar Tp_;
|
|
||||||
|
|
||||||
//- Natural Period of Ship [sec]
|
|
||||||
scalar Tpn_;
|
|
||||||
|
|
||||||
//- Reference time step [sec]
|
|
||||||
scalar dTi_;
|
|
||||||
|
|
||||||
//- Incr. in Tp/unit 'dTi'[-]
|
|
||||||
scalar dTp_;
|
|
||||||
|
|
||||||
|
|
||||||
// Private Member Functions
|
|
||||||
|
|
||||||
//- Disallow copy construct
|
|
||||||
SDA(const SDA&);
|
|
||||||
|
|
||||||
//- Disallow default bitwise assignment
|
|
||||||
void operator=(const SDA&);
|
|
||||||
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
//- Runtime type information
|
|
||||||
TypeName("SDA");
|
|
||||||
|
|
||||||
|
|
||||||
// Constructors
|
|
||||||
|
|
||||||
//- Construct from components
|
|
||||||
SDA
|
|
||||||
(
|
|
||||||
const dictionary& SBMFCoeffs,
|
|
||||||
const Time& runTime
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
// Destructor
|
|
||||||
|
|
||||||
virtual ~SDA();
|
|
||||||
|
|
||||||
|
|
||||||
// Member Functions
|
|
||||||
|
|
||||||
//- Return the solid-body motion transformation septernion
|
|
||||||
virtual septernion transformation() const;
|
|
||||||
|
|
||||||
//- Update properties from given dictionary
|
|
||||||
virtual bool read(const dictionary& SBMFCoeffs);
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
} // End namespace solidBodyMotionFunctions
|
|
||||||
} // End namespace Foam
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
|
|
@ -1,162 +0,0 @@
|
||||||
/*---------------------------------------------------------------------------*\
|
|
||||||
========= |
|
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
|
||||||
\\ / O peration |
|
|
||||||
\\ / A nd | Copyright held by original author
|
|
||||||
\\/ 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 2 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, write to the Free Software Foundation,
|
|
||||||
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
#include "SKA.H"
|
|
||||||
#include "addToRunTimeSelectionTable.H"
|
|
||||||
#include "Tuple2.H"
|
|
||||||
#include "IFstream.H"
|
|
||||||
#include "interpolateXY.H"
|
|
||||||
#include "mathematicalConstants.H"
|
|
||||||
|
|
||||||
using namespace Foam::mathematicalConstant;
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
namespace Foam
|
|
||||||
{
|
|
||||||
namespace solidBodyMotionFunctions
|
|
||||||
{
|
|
||||||
defineTypeNameAndDebug(SKA, 0);
|
|
||||||
addToRunTimeSelectionTable(solidBodyMotionFunction, SKA, dictionary);
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
Foam::solidBodyMotionFunctions::SKA::SKA
|
|
||||||
(
|
|
||||||
const dictionary& SBMFCoeffs,
|
|
||||||
const Time& runTime
|
|
||||||
)
|
|
||||||
:
|
|
||||||
solidBodyMotionFunction(SBMFCoeffs, runTime)
|
|
||||||
{
|
|
||||||
read(SBMFCoeffs);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * Destructors * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
Foam::solidBodyMotionFunctions::SKA::~SKA()
|
|
||||||
{}
|
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
Foam::septernion Foam::solidBodyMotionFunctions::SKA::transformation() const
|
|
||||||
{
|
|
||||||
scalar t = time_.value();
|
|
||||||
|
|
||||||
if (t < times_[0])
|
|
||||||
{
|
|
||||||
FatalErrorIn
|
|
||||||
(
|
|
||||||
"solidBodyMotionFunctions::SKA::transformation()"
|
|
||||||
) << "current time (" << t
|
|
||||||
<< ") is less than the minimum in the data table ("
|
|
||||||
<< times_[0] << ')'
|
|
||||||
<< exit(FatalError);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (t > times_[times_.size()-1])
|
|
||||||
{
|
|
||||||
FatalErrorIn
|
|
||||||
(
|
|
||||||
"solidBodyMotionFunctions::SKA::transformation()"
|
|
||||||
) << "current time (" << t
|
|
||||||
<< ") is greater than the maximum in the data table ("
|
|
||||||
<< times_[times_.size()-1] << ')'
|
|
||||||
<< exit(FatalError);
|
|
||||||
}
|
|
||||||
|
|
||||||
translationRotationVectors TRV = interpolateXY
|
|
||||||
(
|
|
||||||
t,
|
|
||||||
times_,
|
|
||||||
values_
|
|
||||||
);
|
|
||||||
|
|
||||||
// Convert the rotational motion from deg to rad
|
|
||||||
TRV[1] *= pi/180.0;
|
|
||||||
|
|
||||||
quaternion R(TRV[1].x(), TRV[1].y(), TRV[1].z());
|
|
||||||
septernion TR(septernion(CofG_ + TRV[0])*R*septernion(-CofG_));
|
|
||||||
|
|
||||||
Info<< "solidBodyMotionFunctions::SKA::transformation(): "
|
|
||||||
<< "Time = " << t << " transformation: " << TR << endl;
|
|
||||||
|
|
||||||
return TR;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool Foam::solidBodyMotionFunctions::SKA::read(const dictionary& SBMFCoeffs)
|
|
||||||
{
|
|
||||||
solidBodyMotionFunction::read(SBMFCoeffs);
|
|
||||||
|
|
||||||
// If the timeDataFileName has changed read the file
|
|
||||||
|
|
||||||
fileName newTimeDataFileName(SBMFCoeffs_.lookup("timeDataFileName"));
|
|
||||||
|
|
||||||
if (newTimeDataFileName != timeDataFileName_)
|
|
||||||
{
|
|
||||||
timeDataFileName_ = newTimeDataFileName;
|
|
||||||
|
|
||||||
IFstream dataStream(timeDataFileName_);
|
|
||||||
|
|
||||||
if (dataStream.good())
|
|
||||||
{
|
|
||||||
List<Tuple2<scalar, translationRotationVectors> > timeValues
|
|
||||||
(
|
|
||||||
dataStream
|
|
||||||
);
|
|
||||||
|
|
||||||
times_.setSize(timeValues.size());
|
|
||||||
values_.setSize(timeValues.size());
|
|
||||||
|
|
||||||
forAll(timeValues, i)
|
|
||||||
{
|
|
||||||
times_[i] = timeValues[i].first();
|
|
||||||
values_[i] = timeValues[i].second();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
FatalErrorIn
|
|
||||||
(
|
|
||||||
"solidBodyMotionFunctions::SKA::read(const dictionary&)"
|
|
||||||
) << "Cannot open time data file " << timeDataFileName_
|
|
||||||
<< exit(FatalError);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
SBMFCoeffs_.lookup("CofG") >> CofG_;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
|
|
@ -1,132 +0,0 @@
|
||||||
/*---------------------------------------------------------------------------*\
|
|
||||||
========= |
|
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
|
||||||
\\ / O peration |
|
|
||||||
\\ / A nd | Copyright held by original author
|
|
||||||
\\/ 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 2 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, write to the Free Software Foundation,
|
|
||||||
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
|
|
||||||
Class
|
|
||||||
Foam::solidBodyMotionFunctions::SKA
|
|
||||||
|
|
||||||
Description
|
|
||||||
Sea Keeping Analysis (SKA) 6DoF motion function.
|
|
||||||
|
|
||||||
Obtained by interpolating tabulated data for surge (x-translation),
|
|
||||||
sway (y-translation), heave (z-translation), roll (rotation about x),
|
|
||||||
pitch (rotation about y) and yaw (rotation about z).
|
|
||||||
|
|
||||||
See Also
|
|
||||||
SDA (Ship design analysis) for 3DoF motion.
|
|
||||||
|
|
||||||
SourceFiles
|
|
||||||
SKA.C
|
|
||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
#ifndef SKA_H
|
|
||||||
#define SKA_H
|
|
||||||
|
|
||||||
#include "solidBodyMotionFunction.H"
|
|
||||||
#include "primitiveFields.H"
|
|
||||||
#include "Vector2D.H"
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
namespace Foam
|
|
||||||
{
|
|
||||||
namespace solidBodyMotionFunctions
|
|
||||||
{
|
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*\
|
|
||||||
Class SKA Declaration
|
|
||||||
\*---------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
class SKA
|
|
||||||
:
|
|
||||||
public solidBodyMotionFunction
|
|
||||||
{
|
|
||||||
// Private data
|
|
||||||
|
|
||||||
//- Time data file name read from dictionary
|
|
||||||
fileName timeDataFileName_;
|
|
||||||
|
|
||||||
//- Center of gravity read from dictionary
|
|
||||||
vector CofG_;
|
|
||||||
|
|
||||||
//- Type used to read in the translation and rotation "vectors"
|
|
||||||
typedef Vector2D<vector> translationRotationVectors;
|
|
||||||
|
|
||||||
//- Field of times
|
|
||||||
scalarField times_;
|
|
||||||
|
|
||||||
//- Field of translation and rotation "vectors"
|
|
||||||
Field<translationRotationVectors> values_;
|
|
||||||
|
|
||||||
|
|
||||||
// Private Member Functions
|
|
||||||
|
|
||||||
//- Disallow copy construct
|
|
||||||
SKA(const SKA&);
|
|
||||||
|
|
||||||
//- Disallow default bitwise assignment
|
|
||||||
void operator=(const SKA&);
|
|
||||||
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
//- Runtime type information
|
|
||||||
TypeName("SKA");
|
|
||||||
|
|
||||||
|
|
||||||
// Constructors
|
|
||||||
|
|
||||||
//- Construct from components
|
|
||||||
SKA
|
|
||||||
(
|
|
||||||
const dictionary& SBMFCoeffs,
|
|
||||||
const Time& runTime
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
// Destructor
|
|
||||||
|
|
||||||
virtual ~SKA();
|
|
||||||
|
|
||||||
|
|
||||||
// Member Functions
|
|
||||||
|
|
||||||
//- Return the solid-body motion transformation septernion
|
|
||||||
virtual septernion transformation() const;
|
|
||||||
|
|
||||||
//- Update properties from given dictionary
|
|
||||||
virtual bool read(const dictionary& SBMFCoeffs);
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
} // End namespace solidBodyMotionFunctions
|
|
||||||
} // End namespace Foam
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
|
|
@ -1,66 +0,0 @@
|
||||||
/*---------------------------------------------------------------------------*\
|
|
||||||
========= |
|
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
|
||||||
\\ / O peration |
|
|
||||||
\\ / A nd | Copyright held by original author
|
|
||||||
\\/ 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 2 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, write to the Free Software Foundation,
|
|
||||||
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
#include "solidBodyMotionFunction.H"
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * Selectors * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
Foam::autoPtr<Foam::solidBodyMotionFunction> Foam::solidBodyMotionFunction::New
|
|
||||||
(
|
|
||||||
const dictionary& SBMFCoeffs,
|
|
||||||
const Time& runTime
|
|
||||||
)
|
|
||||||
{
|
|
||||||
word solidBodyMotionFunctionTypeName =
|
|
||||||
SBMFCoeffs.lookup("solidBodyMotionFunction");
|
|
||||||
|
|
||||||
Info<< "Selecting solid-body motion function "
|
|
||||||
<< solidBodyMotionFunctionTypeName << endl;
|
|
||||||
|
|
||||||
dictionaryConstructorTable::iterator cstrIter =
|
|
||||||
dictionaryConstructorTablePtr_->find(solidBodyMotionFunctionTypeName);
|
|
||||||
|
|
||||||
if (cstrIter == dictionaryConstructorTablePtr_->end())
|
|
||||||
{
|
|
||||||
FatalErrorIn
|
|
||||||
(
|
|
||||||
"solidBodyMotionFunction::New"
|
|
||||||
"("
|
|
||||||
" const dictionary& SBMFCoeffs,"
|
|
||||||
" const Time& runTime"
|
|
||||||
")"
|
|
||||||
) << "Unknown solidBodyMotionFunction type "
|
|
||||||
<< solidBodyMotionFunctionTypeName << endl << endl
|
|
||||||
<< "Valid solidBodyMotionFunctions are : " << endl
|
|
||||||
<< dictionaryConstructorTablePtr_->toc()
|
|
||||||
<< exit(FatalError);
|
|
||||||
}
|
|
||||||
|
|
||||||
return autoPtr<solidBodyMotionFunction>(cstrIter()(SBMFCoeffs, runTime));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
|
|
@ -1,70 +0,0 @@
|
||||||
/*---------------------------------------------------------------------------*\
|
|
||||||
========= |
|
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
|
||||||
\\ / O peration |
|
|
||||||
\\ / A nd | Copyright held by original author
|
|
||||||
\\/ 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 2 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, write to the Free Software Foundation,
|
|
||||||
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
#include "solidBodyMotionFunction.H"
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
defineTypeNameAndDebug(Foam::solidBodyMotionFunction, 0);
|
|
||||||
|
|
||||||
defineRunTimeSelectionTable(Foam::solidBodyMotionFunction, dictionary);
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
Foam::solidBodyMotionFunction::solidBodyMotionFunction
|
|
||||||
(
|
|
||||||
const dictionary& SBMFCoeffs,
|
|
||||||
const Time& runTime
|
|
||||||
)
|
|
||||||
:
|
|
||||||
SBMFCoeffs_
|
|
||||||
(
|
|
||||||
SBMFCoeffs.subDict
|
|
||||||
(
|
|
||||||
word(SBMFCoeffs.lookup("solidBodyMotionFunction")) + "Coeffs"
|
|
||||||
)
|
|
||||||
),
|
|
||||||
time_(runTime)
|
|
||||||
{}
|
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
Foam::solidBodyMotionFunction::~solidBodyMotionFunction()
|
|
||||||
{}
|
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
bool Foam::solidBodyMotionFunction::read(const dictionary& SBMFCoeffs)
|
|
||||||
{
|
|
||||||
SBMFCoeffs_ = SBMFCoeffs.subDict(type() + "Coeffs");
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
|
|
@ -1,98 +0,0 @@
|
||||||
/*---------------------------------------------------------------------------*\
|
|
||||||
========= |
|
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
|
||||||
\\ / O peration |
|
|
||||||
\\ / A nd | Copyright held by original author
|
|
||||||
\\/ 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 2 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, write to the Free Software Foundation,
|
|
||||||
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
#include "translation.H"
|
|
||||||
#include "addToRunTimeSelectionTable.H"
|
|
||||||
#include "mathematicalConstants.H"
|
|
||||||
|
|
||||||
using namespace Foam::mathematicalConstant;
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
namespace Foam
|
|
||||||
{
|
|
||||||
namespace solidBodyMotionFunctions
|
|
||||||
{
|
|
||||||
defineTypeNameAndDebug(translation, 0);
|
|
||||||
addToRunTimeSelectionTable
|
|
||||||
(
|
|
||||||
solidBodyMotionFunction,
|
|
||||||
translation,
|
|
||||||
dictionary
|
|
||||||
);
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
Foam::solidBodyMotionFunctions::translation::translation
|
|
||||||
(
|
|
||||||
const dictionary& SBMFCoeffs,
|
|
||||||
const Time& runTime
|
|
||||||
)
|
|
||||||
:
|
|
||||||
solidBodyMotionFunction(SBMFCoeffs, runTime),
|
|
||||||
velocity_(SBMFCoeffs_.lookup("velocity"))
|
|
||||||
{}
|
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * Destructors * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
Foam::solidBodyMotionFunctions::translation::~translation()
|
|
||||||
{}
|
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
Foam::septernion
|
|
||||||
Foam::solidBodyMotionFunctions::translation::transformation() const
|
|
||||||
{
|
|
||||||
scalar time = time_.value();
|
|
||||||
|
|
||||||
septernion TR(velocity_*time, quaternion::I);
|
|
||||||
|
|
||||||
Info<< "solidBodyMotionFunctions::translation::transformation(): "
|
|
||||||
<< "Time = " << time << " transformation: " << TR << endl;
|
|
||||||
|
|
||||||
return TR;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool Foam::solidBodyMotionFunctions::translation::read
|
|
||||||
(
|
|
||||||
const dictionary& SBMFCoeffs
|
|
||||||
)
|
|
||||||
{
|
|
||||||
solidBodyMotionFunction::read(SBMFCoeffs);
|
|
||||||
|
|
||||||
SBMFCoeffs_.lookup("velocity") >> velocity_;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
|
|
@ -1,111 +0,0 @@
|
||||||
/*---------------------------------------------------------------------------*\
|
|
||||||
========= |
|
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
|
||||||
\\ / O peration |
|
|
||||||
\\ / A nd | Copyright held by original author
|
|
||||||
\\/ 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 2 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, write to the Free Software Foundation,
|
|
||||||
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
|
|
||||||
Class
|
|
||||||
Foam::solidBodyMotionFunctions::translation
|
|
||||||
|
|
||||||
Description
|
|
||||||
translation motion function
|
|
||||||
|
|
||||||
SourceFiles
|
|
||||||
translation.C
|
|
||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
#ifndef translation_H
|
|
||||||
#define translation_H
|
|
||||||
|
|
||||||
#include "solidBodyMotionFunction.H"
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
namespace Foam
|
|
||||||
{
|
|
||||||
namespace solidBodyMotionFunctions
|
|
||||||
{
|
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*\
|
|
||||||
Class translation Declaration
|
|
||||||
\*---------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
class translation
|
|
||||||
:
|
|
||||||
public solidBodyMotionFunction
|
|
||||||
{
|
|
||||||
// Private data
|
|
||||||
|
|
||||||
//- Velocity
|
|
||||||
vector velocity_;
|
|
||||||
|
|
||||||
|
|
||||||
// Private Member Functions
|
|
||||||
|
|
||||||
//- Disallow copy construct
|
|
||||||
translation(const translation&);
|
|
||||||
|
|
||||||
//- Disallow default bitwise assignment
|
|
||||||
void operator=(const translation&);
|
|
||||||
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
//- Runtime type information
|
|
||||||
TypeName("translation");
|
|
||||||
|
|
||||||
|
|
||||||
// Constructors
|
|
||||||
|
|
||||||
//- Construct from components
|
|
||||||
translation
|
|
||||||
(
|
|
||||||
const dictionary& SBMFCoeffs,
|
|
||||||
const Time& runTime
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
// Destructor
|
|
||||||
|
|
||||||
virtual ~translation();
|
|
||||||
|
|
||||||
|
|
||||||
// Member Functions
|
|
||||||
|
|
||||||
//- Return the solid-body motion transformation septernion
|
|
||||||
virtual septernion transformation() const;
|
|
||||||
|
|
||||||
//- Update properties from given dictionary
|
|
||||||
virtual bool read(const dictionary& SBMFCoeffs);
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
} // End namespace solidBodyMotionFunctions
|
|
||||||
} // End namespace Foam
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
|
|
@ -53,20 +53,20 @@ Foam::solidBodyMotionFvMesh::solidBodyMotionFvMesh(const IOobject& io)
|
||||||
IOobject
|
IOobject
|
||||||
(
|
(
|
||||||
"dynamicMeshDict",
|
"dynamicMeshDict",
|
||||||
io.time().constant(),
|
time().constant(),
|
||||||
*this,
|
*this,
|
||||||
IOobject::MUST_READ,
|
IOobject::MUST_READ,
|
||||||
IOobject::NO_WRITE
|
IOobject::NO_WRITE
|
||||||
)
|
)
|
||||||
).subDict(typeName + "Coeffs")
|
).subDict(typeName + "Coeffs")
|
||||||
),
|
),
|
||||||
SBMFPtr_(solidBodyMotionFunction::New(dynamicMeshCoeffs_, io.time())),
|
SBMFPtr_(solidBodyMotionFunction::New(dynamicMeshCoeffs_, time())),
|
||||||
undisplacedPoints_
|
undisplacedPoints_
|
||||||
(
|
(
|
||||||
IOobject
|
IOobject
|
||||||
(
|
(
|
||||||
"points",
|
"points",
|
||||||
io.time().constant(),
|
time().constant(),
|
||||||
meshSubDir,
|
meshSubDir,
|
||||||
*this,
|
*this,
|
||||||
IOobject::MUST_READ,
|
IOobject::MUST_READ,
|
||||||
|
@ -88,8 +88,7 @@ bool Foam::solidBodyMotionFvMesh::update()
|
||||||
{
|
{
|
||||||
fvMesh::movePoints
|
fvMesh::movePoints
|
||||||
(
|
(
|
||||||
transform(SBMFPtr_().transformation(),
|
transform(SBMFPtr_().transformation(), undisplacedPoints_)
|
||||||
undisplacedPoints_)
|
|
||||||
);
|
);
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -60,10 +60,10 @@ class solidBodyMotionFvMesh
|
||||||
//- Dictionary of motion control parameters
|
//- Dictionary of motion control parameters
|
||||||
dictionary dynamicMeshCoeffs_;
|
dictionary dynamicMeshCoeffs_;
|
||||||
|
|
||||||
//- The motion control function
|
//- Motion control function
|
||||||
autoPtr<solidBodyMotionFunction> SBMFPtr_;
|
autoPtr<solidBodyMotionFunction> SBMFPtr_;
|
||||||
|
|
||||||
//- The reference points which are transformed
|
//- Reference points which are transformed
|
||||||
pointIOField undisplacedPoints_;
|
pointIOField undisplacedPoints_;
|
||||||
|
|
||||||
|
|
||||||
|
@ -85,7 +85,7 @@ public:
|
||||||
// Constructors
|
// Constructors
|
||||||
|
|
||||||
//- Construct from IOobject
|
//- Construct from IOobject
|
||||||
solidBodyMotionFvMesh(const IOobject& io);
|
explicit solidBodyMotionFvMesh(const IOobject& io);
|
||||||
|
|
||||||
|
|
||||||
// Destructor
|
// Destructor
|
||||||
|
|
|
@ -317,25 +317,10 @@ bool Foam::layerAdditionRemoval::changeTopology() const
|
||||||
// If the patch is empty on a processor in a parallel simulation,
|
// If the patch is empty on a processor in a parallel simulation,
|
||||||
// original values will be preserved. HJ, 7/Mar/2011
|
// original values will be preserved. HJ, 7/Mar/2011
|
||||||
|
|
||||||
Pout<< "HRVOJE 1: " << minDelta;
|
reduce(minDelta, minOp<scalar>());
|
||||||
// reduce(minDelta, minOp<scalar>());
|
reduce(maxDelta, maxOp<scalar>());
|
||||||
Foam::sleep(2);
|
reduce(avgDelta, sumOp<scalar>());
|
||||||
Pout<< " and " << minDelta << endl;;
|
reduce(nAvg, sumOp<scalar>());
|
||||||
|
|
||||||
Pout<< "2: " << maxDelta;
|
|
||||||
// reduce(maxDelta, maxOp<scalar>());
|
|
||||||
Foam::sleep(2);
|
|
||||||
Pout<< " and " << maxDelta << endl;;
|
|
||||||
|
|
||||||
Pout<< "3: " << avgDelta;
|
|
||||||
// reduce(avgDelta, sumOp<scalar>());
|
|
||||||
Foam::sleep(2);
|
|
||||||
Pout<< " and " << avgDelta << endl;;
|
|
||||||
|
|
||||||
Pout<< "4: " << nAvg;
|
|
||||||
// reduce(nAvg, sumOp<scalar>());
|
|
||||||
Foam::sleep(2);
|
|
||||||
Pout<< " and " << nAvg << endl;;
|
|
||||||
|
|
||||||
avgDelta /= nAvg;
|
avgDelta /= nAvg;
|
||||||
|
|
||||||
|
|
|
@ -1014,8 +1014,10 @@ Foam::autoPtr<Foam::mapPolyMesh> Foam::polyTopoChanger::changeMesh
|
||||||
) << "Face " << faceI << " in the new mesh is not "
|
) << "Face " << faceI << " in the new mesh is not "
|
||||||
<< "mapped correctly." << nl
|
<< "mapped correctly." << nl
|
||||||
<< "It uses a removed or a non-existing vertex or "
|
<< "It uses a removed or a non-existing vertex or "
|
||||||
<< "has been skipped ." << nl
|
<< "has been skipped." << nl
|
||||||
<< "Face before mapping: " << oldFace << nl
|
<< "Face before mapping: " << oldFace << " with points "
|
||||||
|
<< oldFace.points(newPointsZeroVol) << nl
|
||||||
|
<< mesh.allPoints().size() << nl
|
||||||
<< "Face after mapping: " << renumberedFace << nl
|
<< "Face after mapping: " << renumberedFace << nl
|
||||||
<< "Max new vertex index: "
|
<< "Max new vertex index: "
|
||||||
<< newPointsZeroVol.size() - 1 << "." << nl
|
<< newPointsZeroVol.size() - 1 << "." << nl
|
||||||
|
@ -1098,6 +1100,7 @@ Foam::autoPtr<Foam::mapPolyMesh> Foam::polyTopoChanger::changeMesh
|
||||||
|
|
||||||
if (rotate != 0)
|
if (rotate != 0)
|
||||||
{
|
{
|
||||||
|
Info<< "Rotating face" << endl;
|
||||||
newFaces[faceI] = rotateFace(newFaces[faceI], rotate);
|
newFaces[faceI] = rotateFace(newFaces[faceI], rotate);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@ topoChangerFvMesh/topoChangerFvMesh.C
|
||||||
linearValveFvMesh/linearValveFvMesh.C
|
linearValveFvMesh/linearValveFvMesh.C
|
||||||
attachDetachFvMesh/attachDetachFvMesh.C
|
attachDetachFvMesh/attachDetachFvMesh.C
|
||||||
linearValveLayersFvMesh/linearValveLayersFvMesh.C
|
linearValveLayersFvMesh/linearValveLayersFvMesh.C
|
||||||
movingConeTopoFvMesh/movingConeTopoFvMesh.C
|
movingBodyTopoFvMesh/movingBodyTopoFvMesh.C
|
||||||
mixerFvMesh/mixerFvMesh.C
|
mixerFvMesh/mixerFvMesh.C
|
||||||
multiMixerFvMesh/mixerRotor.C
|
multiMixerFvMesh/mixerRotor.C
|
||||||
multiMixerFvMesh/multiMixerFvMesh.C
|
multiMixerFvMesh/multiMixerFvMesh.C
|
||||||
|
|
|
@ -3,6 +3,7 @@ EXE_INC = \
|
||||||
-I$(LIB_SRC)/dynamicMesh/dynamicFvMesh/lnInclude \
|
-I$(LIB_SRC)/dynamicMesh/dynamicFvMesh/lnInclude \
|
||||||
-I$(LIB_SRC)/dynamicMesh/dynamicMesh/lnInclude \
|
-I$(LIB_SRC)/dynamicMesh/dynamicMesh/lnInclude \
|
||||||
-I$(LIB_SRC)/meshTools/lnInclude \
|
-I$(LIB_SRC)/meshTools/lnInclude \
|
||||||
|
-I$(LIB_SRC)/dynamicMesh/meshMotion/solidBodyMotion/lnInclude \
|
||||||
-I$(LIB_SRC)/dynamicMesh/meshMotion/tetDecompositionMotionSolver/lnInclude \
|
-I$(LIB_SRC)/dynamicMesh/meshMotion/tetDecompositionMotionSolver/lnInclude \
|
||||||
-I$(LIB_SRC)/tetDecompositionFiniteElement/lnInclude \
|
-I$(LIB_SRC)/tetDecompositionFiniteElement/lnInclude \
|
||||||
$(WM_DECOMP_INC)
|
$(WM_DECOMP_INC)
|
||||||
|
@ -12,4 +13,5 @@ LIB_LIBS = \
|
||||||
-ldynamicFvMesh \
|
-ldynamicFvMesh \
|
||||||
-ldynamicMesh \
|
-ldynamicMesh \
|
||||||
-lmeshTools \
|
-lmeshTools \
|
||||||
|
-lsolidBodyMotion \
|
||||||
$(WM_DECOMP_LIBS)
|
$(WM_DECOMP_LIBS)
|
||||||
|
|
|
@ -46,50 +46,40 @@ namespace Foam
|
||||||
void Foam::mixerFvMesh::addZonesAndModifiers()
|
void Foam::mixerFvMesh::addZonesAndModifiers()
|
||||||
{
|
{
|
||||||
// Add zones and modifiers for motion action
|
// Add zones and modifiers for motion action
|
||||||
|
Pout<< "pointZones().size(): " << pointZones().size()
|
||||||
|
<< " faceZones().size(): " << faceZones().size()
|
||||||
|
<< " cellZones().size(): " << cellZones().size()
|
||||||
|
<< " topoChanger_.size(): " << topoChanger_.size() << endl;
|
||||||
|
|
||||||
if
|
if (cellZones().size() > 0)
|
||||||
(
|
|
||||||
pointZones().size() > 0
|
|
||||||
|| faceZones().size() > 0
|
|
||||||
|| cellZones().size() > 0
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
Info<< "void mixerFvMesh::addZonesAndModifiers() : "
|
Info<< "void mixerFvMesh::addZonesAndModifiers() : "
|
||||||
<< "Zones and modifiers already present. Skipping."
|
<< "Zones and modifiers already present. Skipping."
|
||||||
<< endl;
|
<< endl;
|
||||||
|
|
||||||
if (topoChanger_.size() == 0)
|
// Check definition of the modifier
|
||||||
|
if
|
||||||
|
(
|
||||||
|
pointZones().size() > 0
|
||||||
|
|| faceZones().size() > 0
|
||||||
|
)
|
||||||
{
|
{
|
||||||
FatalErrorIn
|
if (topoChanger_.size() == 0)
|
||||||
(
|
{
|
||||||
"void mixerFvMesh::addZonesAndModifiers()"
|
FatalErrorIn
|
||||||
) << "Mesh modifiers not read properly"
|
(
|
||||||
<< abort(FatalError);
|
"void mixerFvMesh::addZonesAndModifiers()"
|
||||||
|
) << "Mesh modifiers not read properly. "
|
||||||
|
<< "pointZones = " << pointZones().size()
|
||||||
|
<< " faceZones = " << faceZones().size()
|
||||||
|
<< abort(FatalError);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Info<< "Time = " << time().timeName() << endl
|
// Find patches and check sizes
|
||||||
<< "Adding zones and modifiers to the mesh" << endl;
|
|
||||||
|
|
||||||
// Add zones
|
|
||||||
List<pointZone*> pz(1);
|
|
||||||
|
|
||||||
// Add an empty zone for cut points
|
|
||||||
|
|
||||||
pz[0] = new pointZone
|
|
||||||
(
|
|
||||||
"cutPointZone",
|
|
||||||
labelList(0),
|
|
||||||
0,
|
|
||||||
pointZones()
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
// Do face zones for slider
|
|
||||||
|
|
||||||
List<faceZone*> fz(3);
|
|
||||||
|
|
||||||
// Moving slider
|
// Moving slider
|
||||||
const word movingSliderName(dict_.subDict("slider").lookup("moving"));
|
const word movingSliderName(dict_.subDict("slider").lookup("moving"));
|
||||||
|
@ -114,51 +104,84 @@ void Foam::mixerFvMesh::addZonesAndModifiers()
|
||||||
}
|
}
|
||||||
|
|
||||||
const polyPatch& movingSlider = boundaryMesh()[movingSliderIndex];
|
const polyPatch& movingSlider = boundaryMesh()[movingSliderIndex];
|
||||||
|
|
||||||
labelList isf(movingSlider.size());
|
|
||||||
|
|
||||||
forAll (isf, i)
|
|
||||||
{
|
|
||||||
isf[i] = movingSlider.start() + i;
|
|
||||||
}
|
|
||||||
|
|
||||||
fz[0] = new faceZone
|
|
||||||
(
|
|
||||||
movingSliderName + "Zone",
|
|
||||||
isf,
|
|
||||||
boolList(movingSlider.size(), false),
|
|
||||||
0,
|
|
||||||
faceZones()
|
|
||||||
);
|
|
||||||
|
|
||||||
// Static slider
|
|
||||||
const polyPatch& staticSlider = boundaryMesh()[staticSliderIndex];
|
const polyPatch& staticSlider = boundaryMesh()[staticSliderIndex];
|
||||||
|
|
||||||
labelList osf(staticSlider.size());
|
List<pointZone*> pz;
|
||||||
|
List<faceZone*> fz;
|
||||||
|
|
||||||
forAll (osf, i)
|
bool addSlider = false;
|
||||||
|
|
||||||
|
if (movingSlider.size() > 0 && staticSlider.size() > 0)
|
||||||
{
|
{
|
||||||
osf[i] = staticSlider.start() + i;
|
addSlider = true;
|
||||||
|
|
||||||
|
pz.setSize(1);
|
||||||
|
fz.setSize(3);
|
||||||
|
|
||||||
|
Info<< "Time = " << time().timeName() << endl
|
||||||
|
<< "Adding zones and modifiers to the mesh" << endl;
|
||||||
|
|
||||||
|
// Add zones
|
||||||
|
|
||||||
|
// Add an empty zone for cut points
|
||||||
|
|
||||||
|
pz[0] = new pointZone
|
||||||
|
(
|
||||||
|
"cutPointZone",
|
||||||
|
labelList(0),
|
||||||
|
0,
|
||||||
|
pointZones()
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
// Do face zones for slider
|
||||||
|
|
||||||
|
// Moving slider
|
||||||
|
labelList isf(movingSlider.size());
|
||||||
|
|
||||||
|
forAll (isf, i)
|
||||||
|
{
|
||||||
|
isf[i] = movingSlider.start() + i;
|
||||||
|
}
|
||||||
|
|
||||||
|
fz[0] = new faceZone
|
||||||
|
(
|
||||||
|
movingSliderName + "Zone",
|
||||||
|
isf,
|
||||||
|
boolList(movingSlider.size(), false),
|
||||||
|
0,
|
||||||
|
faceZones()
|
||||||
|
);
|
||||||
|
|
||||||
|
// Static slider
|
||||||
|
labelList osf(staticSlider.size());
|
||||||
|
|
||||||
|
forAll (osf, i)
|
||||||
|
{
|
||||||
|
osf[i] = staticSlider.start() + i;
|
||||||
|
}
|
||||||
|
|
||||||
|
fz[1] = new faceZone
|
||||||
|
(
|
||||||
|
staticSliderName + "Zone",
|
||||||
|
osf,
|
||||||
|
boolList(staticSlider.size(), false),
|
||||||
|
1,
|
||||||
|
faceZones()
|
||||||
|
);
|
||||||
|
|
||||||
|
// Add empty zone for cut faces
|
||||||
|
fz[2] = new faceZone
|
||||||
|
(
|
||||||
|
"cutFaceZone",
|
||||||
|
labelList(0),
|
||||||
|
boolList(0, false),
|
||||||
|
2,
|
||||||
|
faceZones()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
fz[1] = new faceZone
|
// Add cell zone even if slider does not exist
|
||||||
(
|
|
||||||
staticSliderName + "Zone",
|
|
||||||
osf,
|
|
||||||
boolList(staticSlider.size(), false),
|
|
||||||
1,
|
|
||||||
faceZones()
|
|
||||||
);
|
|
||||||
|
|
||||||
// Add empty zone for cut faces
|
|
||||||
fz[2] = new faceZone
|
|
||||||
(
|
|
||||||
"cutFaceZone",
|
|
||||||
labelList(0),
|
|
||||||
boolList(0, false),
|
|
||||||
2,
|
|
||||||
faceZones()
|
|
||||||
);
|
|
||||||
|
|
||||||
List<cellZone*> cz(1);
|
List<cellZone*> cz(1);
|
||||||
|
|
||||||
|
@ -194,28 +217,32 @@ void Foam::mixerFvMesh::addZonesAndModifiers()
|
||||||
Info << "Adding point, face and cell zones" << endl;
|
Info << "Adding point, face and cell zones" << endl;
|
||||||
addZones(pz, fz, cz);
|
addZones(pz, fz, cz);
|
||||||
|
|
||||||
// Add a topology modifier
|
if (addSlider)
|
||||||
Info << "Adding topology modifiers" << endl;
|
{
|
||||||
topoChanger_.setSize(1);
|
// Add a topology modifier
|
||||||
topoChanger_.set
|
Info << "Adding topology modifiers" << endl;
|
||||||
(
|
topoChanger_.setSize(1);
|
||||||
0,
|
|
||||||
new slidingInterface
|
topoChanger_.set
|
||||||
(
|
(
|
||||||
"mixerSlider",
|
|
||||||
0,
|
0,
|
||||||
topoChanger_,
|
new slidingInterface
|
||||||
staticSliderName + "Zone",
|
(
|
||||||
movingSliderName + "Zone",
|
"mixerSlider",
|
||||||
"cutPointZone",
|
0,
|
||||||
"cutFaceZone",
|
topoChanger_,
|
||||||
staticSliderName,
|
staticSliderName + "Zone",
|
||||||
movingSliderName,
|
movingSliderName + "Zone",
|
||||||
slidingInterface::INTEGRAL, // Edge matching algorithm
|
"cutPointZone",
|
||||||
attachDetach_, // Attach-detach action
|
"cutFaceZone",
|
||||||
intersection::VISIBLE // Projection algorithm
|
staticSliderName,
|
||||||
)
|
movingSliderName,
|
||||||
);
|
slidingInterface::INTEGRAL, // Edge matching algorithm
|
||||||
|
attachDetach_, // Attach-detach action
|
||||||
|
intersection::VISIBLE // Projection algorithm
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
// Write mesh and modifiers
|
// Write mesh and modifiers
|
||||||
topoChanger_.writeOpt() = IOobject::AUTO_WRITE;
|
topoChanger_.writeOpt() = IOobject::AUTO_WRITE;
|
||||||
|
@ -226,7 +253,16 @@ void Foam::mixerFvMesh::addZonesAndModifiers()
|
||||||
|
|
||||||
bool Foam::mixerFvMesh::attached() const
|
bool Foam::mixerFvMesh::attached() const
|
||||||
{
|
{
|
||||||
return refCast<const slidingInterface>(topoChanger_[0]).attached();
|
bool result = false;
|
||||||
|
|
||||||
|
if (topoChanger_.size() > 0)
|
||||||
|
{
|
||||||
|
result = refCast<const slidingInterface>(topoChanger_[0]).attached();
|
||||||
|
}
|
||||||
|
|
||||||
|
reduce(result, orOp<bool>());
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -272,41 +308,43 @@ void Foam::mixerFvMesh::calcMovingMask() const
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const word movingSliderZoneName
|
if (topoChanger_.size() > 0)
|
||||||
(
|
|
||||||
word(dict_.subDict("slider").lookup("moving"))
|
|
||||||
+ "Zone"
|
|
||||||
);
|
|
||||||
|
|
||||||
const labelList& movingSliderAddr =
|
|
||||||
faceZones()[faceZones().findZoneID(movingSliderZoneName)];
|
|
||||||
|
|
||||||
forAll (movingSliderAddr, faceI)
|
|
||||||
{
|
{
|
||||||
const face& curFace = f[movingSliderAddr[faceI]];
|
// Topo changer present. Use zones for motion
|
||||||
|
const word movingSliderZoneName
|
||||||
|
(
|
||||||
|
word(dict_.subDict("slider").lookup("moving")) + "Zone"
|
||||||
|
);
|
||||||
|
|
||||||
forAll (curFace, pointI)
|
const labelList& movingSliderAddr =
|
||||||
|
faceZones()[faceZones().findZoneID(movingSliderZoneName)];
|
||||||
|
|
||||||
|
forAll (movingSliderAddr, faceI)
|
||||||
{
|
{
|
||||||
movingPointsMask[curFace[pointI]] = 1;
|
const face& curFace = f[movingSliderAddr[faceI]];
|
||||||
|
|
||||||
|
forAll (curFace, pointI)
|
||||||
|
{
|
||||||
|
movingPointsMask[curFace[pointI]] = 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
const word staticSliderZoneName
|
const word staticSliderZoneName
|
||||||
(
|
(
|
||||||
word(dict_.subDict("slider").lookup("static"))
|
word(dict_.subDict("slider").lookup("static")) + "Zone"
|
||||||
+ "Zone"
|
);
|
||||||
);
|
|
||||||
|
|
||||||
const labelList& staticSliderAddr =
|
const labelList& staticSliderAddr =
|
||||||
faceZones()[faceZones().findZoneID(staticSliderZoneName)];
|
faceZones()[faceZones().findZoneID(staticSliderZoneName)];
|
||||||
|
|
||||||
forAll (staticSliderAddr, faceI)
|
forAll (staticSliderAddr, faceI)
|
||||||
{
|
|
||||||
const face& curFace = f[staticSliderAddr[faceI]];
|
|
||||||
|
|
||||||
forAll (curFace, pointI)
|
|
||||||
{
|
{
|
||||||
movingPointsMask[curFace[pointI]] = 0;
|
const face& curFace = f[staticSliderAddr[faceI]];
|
||||||
|
|
||||||
|
forAll (curFace, pointI)
|
||||||
|
{
|
||||||
|
movingPointsMask[curFace[pointI]] = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -415,22 +453,43 @@ bool Foam::mixerFvMesh::update()
|
||||||
|
|
||||||
autoPtr<mapPolyMesh> topoChangeMap = topoChanger_.changeMesh();
|
autoPtr<mapPolyMesh> topoChangeMap = topoChanger_.changeMesh();
|
||||||
|
|
||||||
if (topoChangeMap->morphing())
|
bool localMorphing = topoChangeMap->morphing();
|
||||||
|
bool globalMorphing = localMorphing;
|
||||||
|
|
||||||
|
reduce(globalMorphing, orOp<bool>());
|
||||||
|
|
||||||
|
if (globalMorphing)
|
||||||
{
|
{
|
||||||
Info << "Attaching rotors" << endl;
|
Info << "Attaching rotors" << endl;
|
||||||
|
|
||||||
deleteDemandDrivenData(movingPointsMaskPtr_);
|
deleteDemandDrivenData(movingPointsMaskPtr_);
|
||||||
|
|
||||||
// Move the sliding interface points to correct position
|
// Move the sliding interface points to correct position
|
||||||
pointField mappedOldPointsNew(allPoints().size());
|
if (localMorphing)
|
||||||
mappedOldPointsNew.map(oldPointsNew, topoChangeMap->pointMap());
|
{
|
||||||
|
pointField mappedOldPointsNew(allPoints().size());
|
||||||
|
mappedOldPointsNew.map(oldPointsNew, topoChangeMap->pointMap());
|
||||||
|
|
||||||
movePoints(mappedOldPointsNew);
|
movePoints(mappedOldPointsNew);
|
||||||
resetMotion();
|
|
||||||
setV0();
|
resetMotion();
|
||||||
|
setV0();
|
||||||
|
|
||||||
|
// Move the sliding interface points to correct position
|
||||||
|
movePoints(topoChangeMap->preMotionPoints());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pointField newPoints = allPoints();
|
||||||
|
movePoints(oldPointsNew);
|
||||||
|
|
||||||
|
resetMotion();
|
||||||
|
setV0();
|
||||||
|
|
||||||
|
// Move the sliding interface points to correct position
|
||||||
|
movePoints(newPoints);
|
||||||
|
}
|
||||||
|
|
||||||
// Move the sliding interface points to correct position
|
|
||||||
movePoints(topoChangeMap->preMotionPoints());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return topoChangeMap->morphing();
|
return topoChangeMap->morphing();
|
||||||
|
|
|
@ -0,0 +1,306 @@
|
||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | Copyright held by original author
|
||||||
|
\\/ 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 2 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, write to the Free Software Foundation,
|
||||||
|
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#include "movingBodyTopoFvMesh.H"
|
||||||
|
#include "Time.H"
|
||||||
|
#include "mapPolyMesh.H"
|
||||||
|
#include "layerAdditionRemoval.H"
|
||||||
|
#include "volMesh.H"
|
||||||
|
#include "transformField.H"
|
||||||
|
#include "addToRunTimeSelectionTable.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
defineTypeNameAndDebug(movingBodyTopoFvMesh, 0);
|
||||||
|
|
||||||
|
addToRunTimeSelectionTable
|
||||||
|
(
|
||||||
|
topoChangerFvMesh,
|
||||||
|
movingBodyTopoFvMesh,
|
||||||
|
IOobject
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Foam::tmp<Foam::scalarField>
|
||||||
|
Foam::movingBodyTopoFvMesh::calcMotionMask() const
|
||||||
|
{
|
||||||
|
Info<< "Updating vertex markup" << endl;
|
||||||
|
|
||||||
|
tmp<scalarField> tvertexMarkup(new scalarField(allPoints().size(), 0));
|
||||||
|
scalarField& vertexMarkup = tvertexMarkup();
|
||||||
|
|
||||||
|
cellZoneID movingCellsID(movingCellsName_, cellZones());
|
||||||
|
|
||||||
|
// In order to do a correct update on a mask on processor boundaries,
|
||||||
|
// Detection of moving cells should use patchNeighbourField for
|
||||||
|
// processor (not coupled!) boundaries. This is done by expanding
|
||||||
|
// a moving cell set into a field and making sure that processor patch
|
||||||
|
// points move in sync. Not done at the moment, probably best to do
|
||||||
|
// using parallel update of pointFields. HJ, 19/Feb/2011
|
||||||
|
|
||||||
|
// If moving cells are found, perform mark-up
|
||||||
|
if (movingCellsID.active())
|
||||||
|
{
|
||||||
|
// Get cell-point addressing
|
||||||
|
const labelListList& cp = cellPoints();
|
||||||
|
|
||||||
|
// Get labels of all moving cells
|
||||||
|
const labelList& movingCells = cellZones()[movingCellsID.index()];
|
||||||
|
|
||||||
|
forAll (movingCells, cellI)
|
||||||
|
{
|
||||||
|
const labelList& curCp = cp[movingCells[cellI]];
|
||||||
|
|
||||||
|
forAll (curCp, pointI)
|
||||||
|
{
|
||||||
|
vertexMarkup[curCp[pointI]] = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
faceZoneID frontFacesID(frontFacesName_, faceZones());
|
||||||
|
|
||||||
|
if (frontFacesID.active())
|
||||||
|
{
|
||||||
|
const faceZone& frontFaces = faceZones()[frontFacesID.index()];
|
||||||
|
|
||||||
|
const labelList& mp = frontFaces().meshPoints();
|
||||||
|
|
||||||
|
forAll (mp, mpI)
|
||||||
|
{
|
||||||
|
vertexMarkup[mp[mpI]] = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
faceZoneID backFacesID(backFacesName_, faceZones());
|
||||||
|
|
||||||
|
if (backFacesID.active())
|
||||||
|
{
|
||||||
|
const faceZone& backFaces = faceZones()[backFacesID.index()];
|
||||||
|
|
||||||
|
const labelList& mp = backFaces().meshPoints();
|
||||||
|
|
||||||
|
forAll (mp, mpI)
|
||||||
|
{
|
||||||
|
vertexMarkup[mp[mpI]] = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return tvertexMarkup;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::movingBodyTopoFvMesh::addZonesAndModifiers()
|
||||||
|
{
|
||||||
|
// Add zones and modifiers for motion action
|
||||||
|
|
||||||
|
if (topoChanger_.size() > 0)
|
||||||
|
{
|
||||||
|
Info<< "void movingBodyTopoFvMesh::addZonesAndModifiers() : "
|
||||||
|
<< "Zones and modifiers already present. Skipping."
|
||||||
|
<< endl;
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add layer addition/removal interfaces
|
||||||
|
topoChanger_.setSize(2);
|
||||||
|
label nMods = 0;
|
||||||
|
|
||||||
|
|
||||||
|
faceZoneID frontFacesID(frontFacesName_, faceZones());
|
||||||
|
faceZoneID backFacesID(backFacesName_, faceZones());
|
||||||
|
|
||||||
|
if (frontFacesID.active())
|
||||||
|
{
|
||||||
|
const faceZone& frontFaces = faceZones()[frontFacesID.index()];
|
||||||
|
|
||||||
|
if (!frontFaces.empty())
|
||||||
|
{
|
||||||
|
topoChanger_.set
|
||||||
|
(
|
||||||
|
nMods,
|
||||||
|
new layerAdditionRemoval
|
||||||
|
(
|
||||||
|
frontFacesName_ + "Layer",
|
||||||
|
nMods,
|
||||||
|
topoChanger_,
|
||||||
|
frontFacesName_,
|
||||||
|
readScalar
|
||||||
|
(
|
||||||
|
dict_.subDict("front").lookup("minThickness")
|
||||||
|
),
|
||||||
|
readScalar
|
||||||
|
(
|
||||||
|
dict_.subDict("front").lookup("maxThickness")
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
nMods++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (backFacesID.active())
|
||||||
|
{
|
||||||
|
const faceZone& backFaces = faceZones()[backFacesID.index()];
|
||||||
|
|
||||||
|
if (!backFaces.empty())
|
||||||
|
{
|
||||||
|
topoChanger_.set
|
||||||
|
(
|
||||||
|
nMods,
|
||||||
|
new layerAdditionRemoval
|
||||||
|
(
|
||||||
|
backFacesName_ + "Layer",
|
||||||
|
nMods,
|
||||||
|
topoChanger_,
|
||||||
|
backFacesName_,
|
||||||
|
readScalar
|
||||||
|
(
|
||||||
|
dict_.subDict("back").lookup("minThickness")
|
||||||
|
),
|
||||||
|
readScalar
|
||||||
|
(
|
||||||
|
dict_.subDict("back").lookup("maxThickness")
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
nMods++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
topoChanger_.setSize(nMods);
|
||||||
|
|
||||||
|
reduce(nMods, sumOp<label>());
|
||||||
|
|
||||||
|
Info << "Adding " << nMods << " mesh modifiers" << endl;
|
||||||
|
|
||||||
|
// Write mesh and modifiers
|
||||||
|
topoChanger_.write();
|
||||||
|
|
||||||
|
// No need to write the mesh - only modifiers are added.
|
||||||
|
// HJ, 18/Feb/2011
|
||||||
|
// write();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
// Construct from components
|
||||||
|
Foam::movingBodyTopoFvMesh::movingBodyTopoFvMesh(const IOobject& io)
|
||||||
|
:
|
||||||
|
topoChangerFvMesh(io),
|
||||||
|
dict_
|
||||||
|
(
|
||||||
|
IOdictionary
|
||||||
|
(
|
||||||
|
IOobject
|
||||||
|
(
|
||||||
|
"dynamicMeshDict",
|
||||||
|
time().constant(),
|
||||||
|
*this,
|
||||||
|
IOobject::MUST_READ,
|
||||||
|
IOobject::NO_WRITE
|
||||||
|
)
|
||||||
|
).subDict(typeName + "Coeffs")
|
||||||
|
),
|
||||||
|
movingCellsName_(dict_.lookup("movingCells")),
|
||||||
|
frontFacesName_(dict_.lookup("frontFaces")),
|
||||||
|
backFacesName_(dict_.lookup("backFaces")),
|
||||||
|
SBMFPtr_(solidBodyMotionFunction::New(dict_, time())),
|
||||||
|
motionMask_()
|
||||||
|
{
|
||||||
|
addZonesAndModifiers();
|
||||||
|
motionMask_ = calcMotionMask();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Foam::movingBodyTopoFvMesh::~movingBodyTopoFvMesh()
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
bool Foam::movingBodyTopoFvMesh::update()
|
||||||
|
{
|
||||||
|
// Store points to recreate mesh motion
|
||||||
|
pointField oldPointsNew = allPoints();
|
||||||
|
pointField newPoints = allPoints();
|
||||||
|
|
||||||
|
autoPtr<mapPolyMesh> topoChangeMap = topoChanger_.changeMesh();
|
||||||
|
|
||||||
|
bool localMeshChanged = topoChangeMap->morphing();
|
||||||
|
bool globalMeshChanged = localMeshChanged;
|
||||||
|
reduce(globalMeshChanged, orOp<bool>());
|
||||||
|
|
||||||
|
if (globalMeshChanged)
|
||||||
|
{
|
||||||
|
Pout<< "Topology change. Calculating motion point mask" << endl;
|
||||||
|
motionMask_ = calcMotionMask();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (localMeshChanged)
|
||||||
|
{
|
||||||
|
// // Map old points onto the new mesh
|
||||||
|
// pointField mappedOldPointsNew(allPoints().size());
|
||||||
|
// mappedOldPointsNew.map(oldPointsNew, topoChangeMap->pointMap());
|
||||||
|
|
||||||
|
// movePoints(mappedOldPointsNew);
|
||||||
|
// resetMotion();
|
||||||
|
// setV0();
|
||||||
|
|
||||||
|
// Get new points from preMotion
|
||||||
|
newPoints = topoChangeMap().preMotionPoints();
|
||||||
|
}
|
||||||
|
// else
|
||||||
|
// {
|
||||||
|
// // No change, use old points
|
||||||
|
// movePoints(oldPointsNew);
|
||||||
|
// resetMotion();
|
||||||
|
// setV0();
|
||||||
|
// }
|
||||||
|
|
||||||
|
// Calculate new points using a velocity transformation
|
||||||
|
newPoints += motionMask_*
|
||||||
|
transform(SBMFPtr_().velocity(), newPoints)*time().deltaT().value();
|
||||||
|
|
||||||
|
Info << "Executing mesh motion" << endl;
|
||||||
|
movePoints(newPoints);
|
||||||
|
|
||||||
|
return localMeshChanged;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
|
@ -23,22 +23,30 @@ License
|
||||||
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
|
||||||
Class
|
Class
|
||||||
Foam::movingConeTopoFvMesh
|
Foam::movingBodyTopoFvMesh
|
||||||
|
|
||||||
Description
|
Description
|
||||||
Sample topoChangerFvMesh that moves an object in x direction
|
Sample topoChangerFvMesh that moves a cell zone in a given direction,
|
||||||
and introduces/removes layers.
|
introducing/removing layers around it.
|
||||||
|
|
||||||
|
Cells in the movingCells zone shall be moved given the prescribed velocity
|
||||||
|
and will be bounded in "front" and "back" by other cell zones.
|
||||||
|
Layer addition/removal interfaces are inserted at boundaries between the
|
||||||
|
moving zone and front and back, pointing outside of the moving cell zone
|
||||||
|
|
||||||
|
Author and rewrite
|
||||||
|
Hrvoje Jasak, Wikki Ltd.
|
||||||
|
|
||||||
SourceFiles
|
SourceFiles
|
||||||
movingConeTopoFvMesh.C
|
movingBodyTopoFvMesh.C
|
||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
#ifndef movingConeTopoFvMesh_H
|
#ifndef movingBodyTopoFvMesh_H
|
||||||
#define movingConeTopoFvMesh_H
|
#define movingBodyTopoFvMesh_H
|
||||||
|
|
||||||
#include "topoChangerFvMesh.H"
|
#include "topoChangerFvMesh.H"
|
||||||
#include "motionSolver.H"
|
#include "solidBodyMotionFunction.H"
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
@ -46,35 +54,29 @@ namespace Foam
|
||||||
{
|
{
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*\
|
/*---------------------------------------------------------------------------*\
|
||||||
Class movingConeTopoFvMesh Declaration
|
Class movingBodyTopoFvMesh Declaration
|
||||||
\*---------------------------------------------------------------------------*/
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
class movingConeTopoFvMesh
|
class movingBodyTopoFvMesh
|
||||||
:
|
:
|
||||||
public topoChangerFvMesh
|
public topoChangerFvMesh
|
||||||
{
|
{
|
||||||
// Private data
|
// Private data
|
||||||
|
|
||||||
//- Motion dictionary
|
//- Dynamic mesh dictionary
|
||||||
dictionary motionDict_;
|
dictionary dict_;
|
||||||
|
|
||||||
//- Motion velocity amplitude
|
//- Moving cell zone name
|
||||||
vector motionVelAmplitude_;
|
word movingCellsName_;
|
||||||
|
|
||||||
//- Motion velocity period
|
//- Front face zone name
|
||||||
scalar motionVelPeriod_;
|
word frontFacesName_;
|
||||||
|
|
||||||
//- Motion velocity period
|
//- Back face zone name
|
||||||
vector curMotionVel_;
|
word backFacesName_;
|
||||||
|
|
||||||
//- Left edge
|
//- Motion control function
|
||||||
scalar leftEdge_;
|
autoPtr<solidBodyMotionFunction> SBMFPtr_;
|
||||||
|
|
||||||
//- Current left obstacle position
|
|
||||||
scalar curLeft_;
|
|
||||||
|
|
||||||
//- Current right obstacle position
|
|
||||||
scalar curRight_;
|
|
||||||
|
|
||||||
//- Vertex motion mask
|
//- Vertex motion mask
|
||||||
scalarField motionMask_;
|
scalarField motionMask_;
|
||||||
|
@ -83,39 +85,34 @@ class movingConeTopoFvMesh
|
||||||
// Private Member Functions
|
// Private Member Functions
|
||||||
|
|
||||||
//- Disallow default bitwise copy construct
|
//- Disallow default bitwise copy construct
|
||||||
movingConeTopoFvMesh(const movingConeTopoFvMesh&);
|
movingBodyTopoFvMesh(const movingBodyTopoFvMesh&);
|
||||||
|
|
||||||
//- Disallow default bitwise assignment
|
//- Disallow default bitwise assignment
|
||||||
void operator=(const movingConeTopoFvMesh&);
|
void operator=(const movingBodyTopoFvMesh&);
|
||||||
|
|
||||||
|
|
||||||
//- Add mixer zones and modifiers
|
//- Add mixer zones and modifiers
|
||||||
void addZonesAndModifiers();
|
void addZonesAndModifiers();
|
||||||
|
|
||||||
//- Markup motion vertices
|
//- Mark motion vertices
|
||||||
tmp<scalarField> vertexMarkup
|
tmp<scalarField> calcMotionMask() const;
|
||||||
(
|
|
||||||
const pointField& p,
|
|
||||||
const scalar& curLeft,
|
|
||||||
const scalar& curRight
|
|
||||||
) const;
|
|
||||||
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
//- Runtime type information
|
//- Runtime type information
|
||||||
TypeName("movingConeTopoFvMesh");
|
TypeName("movingBodyTopoFvMesh");
|
||||||
|
|
||||||
|
|
||||||
// Constructors
|
// Constructors
|
||||||
|
|
||||||
//- Construct from database
|
//- Construct from database
|
||||||
explicit movingConeTopoFvMesh(const IOobject& io);
|
explicit movingBodyTopoFvMesh(const IOobject& io);
|
||||||
|
|
||||||
|
|
||||||
// Destructor
|
// Destructor
|
||||||
|
|
||||||
virtual ~movingConeTopoFvMesh();
|
virtual ~movingBodyTopoFvMesh();
|
||||||
|
|
||||||
|
|
||||||
// Member Functions
|
// Member Functions
|
|
@ -1,429 +0,0 @@
|
||||||
/*---------------------------------------------------------------------------*\
|
|
||||||
========= |
|
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
|
||||||
\\ / O peration |
|
|
||||||
\\ / A nd | Copyright held by original author
|
|
||||||
\\/ 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 2 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, write to the Free Software Foundation,
|
|
||||||
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
#include "movingConeTopoFvMesh.H"
|
|
||||||
#include "Time.H"
|
|
||||||
#include "mapPolyMesh.H"
|
|
||||||
#include "layerAdditionRemoval.H"
|
|
||||||
#include "addToRunTimeSelectionTable.H"
|
|
||||||
#include "volMesh.H"
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
namespace Foam
|
|
||||||
{
|
|
||||||
defineTypeNameAndDebug(movingConeTopoFvMesh, 0);
|
|
||||||
|
|
||||||
addToRunTimeSelectionTable
|
|
||||||
(
|
|
||||||
topoChangerFvMesh,
|
|
||||||
movingConeTopoFvMesh,
|
|
||||||
IOobject
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
|
||||||
|
|
||||||
Foam::tmp<Foam::scalarField> Foam::movingConeTopoFvMesh::vertexMarkup
|
|
||||||
(
|
|
||||||
const pointField& p,
|
|
||||||
const scalar& curLeft,
|
|
||||||
const scalar& curRight
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
Info<< "Updating vertex markup. curLeft: "
|
|
||||||
<< curLeft << " curRight: " << curRight << endl;
|
|
||||||
|
|
||||||
tmp<scalarField> tvertexMarkup(new scalarField(p.size()));
|
|
||||||
scalarField& vertexMarkup = tvertexMarkup();
|
|
||||||
|
|
||||||
forAll (p, pI)
|
|
||||||
{
|
|
||||||
if (p[pI].x() < curLeft - 1e-10)
|
|
||||||
{
|
|
||||||
vertexMarkup[pI] = -1;
|
|
||||||
}
|
|
||||||
else if (p[pI].x() > curRight + 1e-10)
|
|
||||||
{
|
|
||||||
vertexMarkup[pI] = 1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
vertexMarkup[pI] = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return tvertexMarkup;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Foam::movingConeTopoFvMesh::addZonesAndModifiers()
|
|
||||||
{
|
|
||||||
// Add zones and modifiers for motion action
|
|
||||||
|
|
||||||
if
|
|
||||||
(
|
|
||||||
pointZones().size() > 0
|
|
||||||
|| faceZones().size() > 0
|
|
||||||
|| cellZones().size() > 0
|
|
||||||
)
|
|
||||||
{
|
|
||||||
Info<< "void movingConeTopoFvMesh::addZonesAndModifiers() : "
|
|
||||||
<< "Zones and modifiers already present. Skipping."
|
|
||||||
<< endl;
|
|
||||||
|
|
||||||
if (topoChanger_.size() == 0)
|
|
||||||
{
|
|
||||||
FatalErrorIn
|
|
||||||
(
|
|
||||||
"void movingConeTopoFvMesh::addZonesAndModifiers()"
|
|
||||||
) << "Mesh modifiers not read properly"
|
|
||||||
<< abort(FatalError);
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Info<< "Time = " << time().timeName() << endl
|
|
||||||
<< "Adding zones and modifiers to the mesh" << endl;
|
|
||||||
|
|
||||||
const vectorField& fc = faceCentres();
|
|
||||||
const vectorField& fa = faceAreas();
|
|
||||||
|
|
||||||
labelList zone1(fc.size());
|
|
||||||
boolList flipZone1(fc.size(), false);
|
|
||||||
label nZoneFaces1 = 0;
|
|
||||||
|
|
||||||
labelList zone2(fc.size());
|
|
||||||
boolList flipZone2(fc.size(), false);
|
|
||||||
label nZoneFaces2 = 0;
|
|
||||||
|
|
||||||
forAll (fc, faceI)
|
|
||||||
{
|
|
||||||
if
|
|
||||||
(
|
|
||||||
fc[faceI].x() > -0.003501
|
|
||||||
&& fc[faceI].x() < -0.003499
|
|
||||||
)
|
|
||||||
{
|
|
||||||
if ((fa[faceI] & vector(1, 0, 0)) < 0)
|
|
||||||
{
|
|
||||||
flipZone1[nZoneFaces1] = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
zone1[nZoneFaces1] = faceI;
|
|
||||||
Info<< "face " << faceI << " for zone 1. Flip: "
|
|
||||||
<< flipZone1[nZoneFaces1] << endl;
|
|
||||||
nZoneFaces1++;
|
|
||||||
}
|
|
||||||
else if
|
|
||||||
(
|
|
||||||
fc[faceI].x() > -0.00701
|
|
||||||
&& fc[faceI].x() < -0.00699
|
|
||||||
)
|
|
||||||
{
|
|
||||||
zone2[nZoneFaces2] = faceI;
|
|
||||||
|
|
||||||
if ((fa[faceI] & vector(1, 0, 0)) > 0)
|
|
||||||
{
|
|
||||||
flipZone2[nZoneFaces2] = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
Info << "face " << faceI << " for zone 2. Flip: "
|
|
||||||
<< flipZone2[nZoneFaces2] << endl;
|
|
||||||
nZoneFaces2++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
zone1.setSize(nZoneFaces1);
|
|
||||||
flipZone1.setSize(nZoneFaces1);
|
|
||||||
|
|
||||||
zone2.setSize(nZoneFaces2);
|
|
||||||
flipZone2.setSize(nZoneFaces2);
|
|
||||||
|
|
||||||
Info << "zone: " << zone1 << endl;
|
|
||||||
Info << "zone: " << zone2 << endl;
|
|
||||||
|
|
||||||
List<pointZone*> pz(0);
|
|
||||||
List<faceZone*> fz(2);
|
|
||||||
List<cellZone*> cz(0);
|
|
||||||
|
|
||||||
label nFz = 0;
|
|
||||||
|
|
||||||
fz[nFz] =
|
|
||||||
new faceZone
|
|
||||||
(
|
|
||||||
"rightExtrusionFaces",
|
|
||||||
zone1,
|
|
||||||
flipZone1,
|
|
||||||
nFz,
|
|
||||||
faceZones()
|
|
||||||
);
|
|
||||||
nFz++;
|
|
||||||
|
|
||||||
fz[nFz] =
|
|
||||||
new faceZone
|
|
||||||
(
|
|
||||||
"leftExtrusionFaces",
|
|
||||||
zone2,
|
|
||||||
flipZone2,
|
|
||||||
nFz,
|
|
||||||
faceZones()
|
|
||||||
);
|
|
||||||
nFz++;
|
|
||||||
|
|
||||||
fz.setSize(nFz);
|
|
||||||
|
|
||||||
Info << "Adding mesh zones." << endl;
|
|
||||||
addZones(pz, fz, cz);
|
|
||||||
|
|
||||||
// Add layer addition/removal interfaces
|
|
||||||
|
|
||||||
topoChanger_.setSize(2);
|
|
||||||
label nMods = 0;
|
|
||||||
|
|
||||||
topoChanger_.set
|
|
||||||
(
|
|
||||||
0,
|
|
||||||
new layerAdditionRemoval
|
|
||||||
(
|
|
||||||
"right",
|
|
||||||
nMods,
|
|
||||||
topoChanger_,
|
|
||||||
"rightExtrusionFaces",
|
|
||||||
readScalar
|
|
||||||
(
|
|
||||||
motionDict_.subDict("right").lookup("minThickness")
|
|
||||||
),
|
|
||||||
readScalar
|
|
||||||
(
|
|
||||||
motionDict_.subDict("right").lookup("maxThickness")
|
|
||||||
)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
nMods++;
|
|
||||||
|
|
||||||
topoChanger_.set
|
|
||||||
(
|
|
||||||
1,
|
|
||||||
new layerAdditionRemoval
|
|
||||||
(
|
|
||||||
"left",
|
|
||||||
nMods,
|
|
||||||
topoChanger_,
|
|
||||||
"leftExtrusionFaces",
|
|
||||||
readScalar
|
|
||||||
(
|
|
||||||
motionDict_.subDict("left").lookup("minThickness")
|
|
||||||
),
|
|
||||||
readScalar
|
|
||||||
(
|
|
||||||
motionDict_.subDict("left").lookup("maxThickness")
|
|
||||||
)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
nMods++;
|
|
||||||
|
|
||||||
Info << "Adding " << nMods << " mesh modifiers" << endl;
|
|
||||||
|
|
||||||
// Write mesh and modifiers
|
|
||||||
topoChanger_.write();
|
|
||||||
write();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
// Construct from components
|
|
||||||
Foam::movingConeTopoFvMesh::movingConeTopoFvMesh(const IOobject& io)
|
|
||||||
:
|
|
||||||
topoChangerFvMesh(io),
|
|
||||||
motionDict_
|
|
||||||
(
|
|
||||||
IOdictionary
|
|
||||||
(
|
|
||||||
IOobject
|
|
||||||
(
|
|
||||||
"dynamicMeshDict",
|
|
||||||
time().constant(),
|
|
||||||
*this,
|
|
||||||
IOobject::MUST_READ,
|
|
||||||
IOobject::NO_WRITE
|
|
||||||
)
|
|
||||||
).subDict(typeName + "Coeffs")
|
|
||||||
),
|
|
||||||
motionVelAmplitude_(motionDict_.lookup("motionVelAmplitude")),
|
|
||||||
motionVelPeriod_(readScalar(motionDict_.lookup("motionVelPeriod"))),
|
|
||||||
curMotionVel_
|
|
||||||
(
|
|
||||||
motionVelAmplitude_*
|
|
||||||
Foam::sin(time().value()*M_PI/motionVelPeriod_)
|
|
||||||
),
|
|
||||||
leftEdge_(readScalar(motionDict_.lookup("leftEdge"))),
|
|
||||||
curLeft_(readScalar(motionDict_.lookup("leftObstacleEdge"))),
|
|
||||||
curRight_(readScalar(motionDict_.lookup("rightObstacleEdge"))),
|
|
||||||
motionMask_
|
|
||||||
(
|
|
||||||
vertexMarkup
|
|
||||||
(
|
|
||||||
points(),
|
|
||||||
curLeft_,
|
|
||||||
curRight_
|
|
||||||
)
|
|
||||||
)
|
|
||||||
{
|
|
||||||
addZonesAndModifiers();
|
|
||||||
|
|
||||||
curLeft_ = average
|
|
||||||
(
|
|
||||||
faceZones()
|
|
||||||
[
|
|
||||||
faceZones().findZoneID("leftExtrusionFaces")
|
|
||||||
]().localPoints()
|
|
||||||
).x();
|
|
||||||
|
|
||||||
curRight_ = average
|
|
||||||
(
|
|
||||||
faceZones()
|
|
||||||
[
|
|
||||||
faceZones().findZoneID("rightExtrusionFaces")
|
|
||||||
]().localPoints()
|
|
||||||
).x();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
Foam::movingConeTopoFvMesh::~movingConeTopoFvMesh()
|
|
||||||
{}
|
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
bool Foam::movingConeTopoFvMesh::update()
|
|
||||||
{
|
|
||||||
autoPtr<mapPolyMesh> topoChangeMap = topoChanger_.changeMesh();
|
|
||||||
|
|
||||||
// Calculate the new point positions depending on whether the
|
|
||||||
// topological change has happened or not
|
|
||||||
pointField newPoints;
|
|
||||||
|
|
||||||
vector curMotionVel_ =
|
|
||||||
motionVelAmplitude_*
|
|
||||||
Foam::sin(time().value()*M_PI/motionVelPeriod_);
|
|
||||||
|
|
||||||
bool meshChanged = topoChangeMap->morphing();
|
|
||||||
|
|
||||||
if (meshChanged)
|
|
||||||
{
|
|
||||||
Info << "Topology change. Calculating motion points" << endl;
|
|
||||||
|
|
||||||
if (topoChangeMap().hasMotionPoints())
|
|
||||||
{
|
|
||||||
motionMask_ =
|
|
||||||
vertexMarkup
|
|
||||||
(
|
|
||||||
topoChangeMap().preMotionPoints(),
|
|
||||||
curLeft_,
|
|
||||||
curRight_
|
|
||||||
);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
motionMask_ =
|
|
||||||
vertexMarkup
|
|
||||||
(
|
|
||||||
points(),
|
|
||||||
curLeft_,
|
|
||||||
curRight_
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create new points by moving old points but using the
|
|
||||||
// pre-motion points at the motion selector for the moving
|
|
||||||
// region
|
|
||||||
newPoints =
|
|
||||||
points()
|
|
||||||
+ (
|
|
||||||
pos(0.5 - mag(motionMask_)) // cells above the body
|
|
||||||
// + pos(motionMask_ - 0.5)* // cells in front of the body
|
|
||||||
// (
|
|
||||||
// points().component(vector::X)/curRight
|
|
||||||
// )
|
|
||||||
// + pos(-motionMask_ - 0.5)* // cells behind the body
|
|
||||||
// (
|
|
||||||
// (
|
|
||||||
// points().component(vector::X)
|
|
||||||
// - leftEdge
|
|
||||||
// )/
|
|
||||||
// (curLeft_ - leftEdge_)
|
|
||||||
// )
|
|
||||||
)*curMotionVel_*time().deltaT().value();
|
|
||||||
|
|
||||||
// Correct mesh motion for correct volume continuity
|
|
||||||
movePoints(topoChangeMap().preMotionPoints());
|
|
||||||
resetMotion();
|
|
||||||
setV0();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Info << "No topology change" << endl;
|
|
||||||
// Set the mesh motion
|
|
||||||
newPoints =
|
|
||||||
points()
|
|
||||||
+ (
|
|
||||||
pos(0.5 - mag(motionMask_)) // cells above the body
|
|
||||||
// + pos(motionMask_ - 0.5)* // cells in front of the body
|
|
||||||
// (
|
|
||||||
// points().component(vector::X)/curRight
|
|
||||||
// )
|
|
||||||
// + pos(-motionMask_ - 0.5)* // cells behind the body
|
|
||||||
// (
|
|
||||||
// (
|
|
||||||
// points().component(vector::X)
|
|
||||||
// - leftEdge
|
|
||||||
// )/
|
|
||||||
// (curLeft_ - leftEdge_)
|
|
||||||
// )
|
|
||||||
)*curMotionVel_*time().deltaT().value();
|
|
||||||
}
|
|
||||||
|
|
||||||
curLeft_ += curMotionVel_.x()*time().deltaT().value();
|
|
||||||
curRight_ += curMotionVel_.x()*time().deltaT().value();
|
|
||||||
|
|
||||||
// The mesh now contains the cells with zero volume
|
|
||||||
|
|
||||||
Info << "Executing mesh motion" << endl;
|
|
||||||
movePoints(newPoints);
|
|
||||||
|
|
||||||
// The mesh now has got non-zero volume cells
|
|
||||||
|
|
||||||
return meshChanged;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
|
|
@ -9,7 +9,6 @@
|
||||||
|
|
||||||
forAll(valves_, valveI)
|
forAll(valves_, valveI)
|
||||||
{
|
{
|
||||||
|
|
||||||
vector valveVel =
|
vector valveVel =
|
||||||
valves_[valveI].curVelocity()*valves_[valveI].cs().axis();
|
valves_[valveI].curVelocity()*valves_[valveI].cs().axis();
|
||||||
|
|
||||||
|
@ -17,10 +16,9 @@
|
||||||
{
|
{
|
||||||
valveVel = vector::zero;
|
valveVel = vector::zero;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|
||||||
// label movingPtsIndex = pZones.findZoneID("movingPointsV"+Foam::name(valveI + 1));
|
// label movingPtsIndex = pZones.findZoneID("movingPointsV"+Foam::name(valveI + 1));
|
||||||
// const labelList& movingPointsV = pZones[movingPtsIndex];
|
// const labelList& movingPointsV = pZones[movingPtsIndex];
|
||||||
/*
|
/*
|
||||||
|
@ -28,17 +26,17 @@
|
||||||
{
|
{
|
||||||
constrainedPoints.append(movingPointsV[mpI]);
|
constrainedPoints.append(movingPointsV[mpI]);
|
||||||
constrainedVelocity.append(valveVel);
|
constrainedVelocity.append(valveVel);
|
||||||
|
|
||||||
constraintSize++;
|
constraintSize++;
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
label movingCellsIndex = cZones.findZoneID("movingCellsZoneV"+Foam::name(valveI + 1));
|
label movingCellsIndex = cZones.findZoneID("movingCellsZoneV"+Foam::name(valveI + 1));
|
||||||
const labelList& movingCellsV = cZones[movingCellsIndex];
|
const labelList& movingCellsV = cZones[movingCellsIndex];
|
||||||
|
|
||||||
labelList movingPointsV;
|
labelList movingPointsV;
|
||||||
boolList count(newPoints.size(), false);
|
boolList count(newPoints.size(), false);
|
||||||
|
|
||||||
forAll(movingCellsV, cellI)
|
forAll(movingCellsV, cellI)
|
||||||
{
|
{
|
||||||
const labelList& curCellPoints = cp[movingCellsV[cellI]];
|
const labelList& curCellPoints = cp[movingCellsV[cellI]];
|
||||||
|
@ -76,17 +74,15 @@
|
||||||
{
|
{
|
||||||
constrainedPoints.append(movingPointsV[mpI]);
|
constrainedPoints.append(movingPointsV[mpI]);
|
||||||
constrainedVelocity.append(valveVel);
|
constrainedVelocity.append(valveVel);
|
||||||
|
|
||||||
constraintSize++;
|
constraintSize++;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|
||||||
// label staticPtsIndex = pZones.findZoneID("staticPointsV"+Foam::name(valveI + 1));
|
// label staticPtsIndex = pZones.findZoneID("staticPointsV"+Foam::name(valveI + 1));
|
||||||
// const labelList& staticPointsV = pZones[staticPtsIndex];
|
// const labelList& staticPointsV = pZones[staticPtsIndex];
|
||||||
/*
|
/*
|
||||||
forAll(staticPointsV, spI)
|
forAll(staticPointsV, spI)
|
||||||
{
|
{
|
||||||
constrainedPoints.append(staticPointsV[spI]);
|
constrainedPoints.append(staticPointsV[spI]);
|
||||||
|
@ -101,7 +97,7 @@
|
||||||
labelList staticPointsV;
|
labelList staticPointsV;
|
||||||
|
|
||||||
boolList count(newPoints.size(), false);
|
boolList count(newPoints.size(), false);
|
||||||
|
|
||||||
forAll(staticCellsV, cellI)
|
forAll(staticCellsV, cellI)
|
||||||
{
|
{
|
||||||
const labelList& curCellPoints = cp[staticCellsV[cellI]];
|
const labelList& curCellPoints = cp[staticCellsV[cellI]];
|
||||||
|
@ -134,7 +130,7 @@
|
||||||
nCounted++;
|
nCounted++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
forAll(staticPointsV, spI)
|
forAll(staticPointsV, spI)
|
||||||
{
|
{
|
||||||
constrainedPoints.append(staticPointsV[spI]);
|
constrainedPoints.append(staticPointsV[spI]);
|
||||||
|
@ -145,16 +141,16 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(piston().patchID().active())
|
if(piston().patchID().active())
|
||||||
{
|
{
|
||||||
vector pistonVel =
|
vector pistonVel =
|
||||||
piston().cs().axis()*engineTime_.pistonSpeed().value();
|
piston().cs().axis()*engineTime_.pistonSpeed().value();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
label pistonPtsIndex = pZones.findZoneID("movingPistonPoints");
|
label pistonPtsIndex = pZones.findZoneID("movingPistonPoints");
|
||||||
const labelList& movingPointsP = pZones[pistonPtsIndex];
|
const labelList& movingPointsP = pZones[pistonPtsIndex];
|
||||||
|
|
||||||
forAll(movingPointsP, mpI)
|
forAll(movingPointsP, mpI)
|
||||||
{
|
{
|
||||||
constrainedPoints.append(movingPointsP[mpI]);
|
constrainedPoints.append(movingPointsP[mpI]);
|
||||||
|
@ -165,11 +161,11 @@
|
||||||
|
|
||||||
label pistonCellsIndex = cZones.findZoneID("movingPistonCells");
|
label pistonCellsIndex = cZones.findZoneID("movingPistonCells");
|
||||||
const labelList& movingCellsP = cZones[pistonCellsIndex];
|
const labelList& movingCellsP = cZones[pistonCellsIndex];
|
||||||
|
|
||||||
labelList movingPointsP;
|
labelList movingPointsP;
|
||||||
|
|
||||||
boolList count(newPoints.size(), false);
|
boolList count(newPoints.size(), false);
|
||||||
|
|
||||||
forAll(movingCellsP, cellI)
|
forAll(movingCellsP, cellI)
|
||||||
{
|
{
|
||||||
const labelList& curCellPoints = cp[movingCellsP[cellI]];
|
const labelList& curCellPoints = cp[movingCellsP[cellI]];
|
||||||
|
@ -202,8 +198,7 @@
|
||||||
nCounted++;
|
nCounted++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
forAll(movingPointsP, mpI)
|
forAll(movingPointsP, mpI)
|
||||||
{
|
{
|
||||||
constrainedPoints.append(movingPointsP[mpI]);
|
constrainedPoints.append(movingPointsP[mpI]);
|
||||||
|
@ -213,6 +208,4 @@
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -301,8 +301,6 @@ void Foam::simpleTwoStroke::addZonesAndModifiers()
|
||||||
|
|
||||||
nFaceZones++;
|
nFaceZones++;
|
||||||
|
|
||||||
Info << "cut p" << endl;
|
|
||||||
|
|
||||||
pz[nPointZones] = new pointZone
|
pz[nPointZones] = new pointZone
|
||||||
(
|
(
|
||||||
"cutPointZone",
|
"cutPointZone",
|
||||||
|
|
|
@ -1,6 +1,11 @@
|
||||||
if (piston().patchID().active())
|
if (piston().patchID().active())
|
||||||
{
|
{
|
||||||
// add faces for piston layering
|
// Add faces for piston layering
|
||||||
|
// Note: because of operation of layer addition/removal
|
||||||
|
// (reduce function in layer addition/removal thickness)
|
||||||
|
// the layering modifier needs to be present on all processors
|
||||||
|
// even if the patch size is zero
|
||||||
|
// HJ, 7/Mar/2011
|
||||||
|
|
||||||
faceSet pistonFaceSet(*this, piston().pistonFaceSetName());
|
faceSet pistonFaceSet(*this, piston().pistonFaceSetName());
|
||||||
|
|
||||||
|
@ -23,7 +28,7 @@ if (piston().patchID().active())
|
||||||
Info << "nSet = " << nSet << endl;
|
Info << "nSet = " << nSet << endl;
|
||||||
Info << "nFlip = " << nFlip << endl;
|
Info << "nFlip = " << nFlip << endl;
|
||||||
|
|
||||||
fz.append
|
fz[nFaceZones] =
|
||||||
(
|
(
|
||||||
new faceZone
|
new faceZone
|
||||||
(
|
(
|
||||||
|
@ -37,27 +42,10 @@ if (piston().patchID().active())
|
||||||
|
|
||||||
nFaceZones++;
|
nFaceZones++;
|
||||||
|
|
||||||
// {
|
|
||||||
// pointSet movingPistonPoints(*this, piston().pistonPointSetName());
|
|
||||||
|
|
||||||
// pz.append
|
|
||||||
// (
|
|
||||||
// new pointZone
|
|
||||||
// (
|
|
||||||
// "pistonPoints",
|
|
||||||
// movingPistonPoints.toc(),
|
|
||||||
// nPointZones,
|
|
||||||
// pointZones()
|
|
||||||
// )
|
|
||||||
// );
|
|
||||||
|
|
||||||
// nPointZones++;
|
|
||||||
// }
|
|
||||||
|
|
||||||
cellSet movingPistonCells(*this, piston().pistonCellSetName());
|
cellSet movingPistonCells(*this, piston().pistonCellSetName());
|
||||||
|
|
||||||
Info<< "Adding piston cell set" << endl;
|
Info<< "Adding piston cell set" << endl;
|
||||||
cz.append
|
cz[nCellZones] =
|
||||||
(
|
(
|
||||||
new cellZone
|
new cellZone
|
||||||
(
|
(
|
|
@ -62,25 +62,24 @@ void Foam::twoStrokeEngine::addZonesAndModifiers()
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Info << "checkAndCalculate()" << endl;
|
|
||||||
checkAndCalculate();
|
checkAndCalculate();
|
||||||
|
|
||||||
Info<< "Time = " << engTime().theta() << endl
|
Info<< "Time = " << engTime().theta() << endl
|
||||||
<< "Adding zones to the engine mesh" << endl;
|
<< "Adding zones to the engine mesh" << endl;
|
||||||
|
|
||||||
|
// Zones to add
|
||||||
//fz = 4: virtual piston, outSidePort, insidePort, cutFaceZone
|
// fz = 4: virtual piston, outSidePort, insidePort, cutFaceZone
|
||||||
//pz = 2: piston points, cutPointZone
|
// pz = 2: piston points, cutPointZone
|
||||||
//cz = 1: moving mask
|
// cz = 1: moving mask
|
||||||
|
|
||||||
label nPorts = scavInCylPatches_.size();
|
label nPorts = scavInCylPatches_.size();
|
||||||
|
|
||||||
|
|
||||||
DynamicList<pointZone*> pz(2 + nPorts);
|
List<pointZone*> pz(nPorts + 2);
|
||||||
DynamicList<faceZone*> fz(3*nPorts + 1);
|
List<faceZone*> fz(3*nPorts + 1);
|
||||||
|
|
||||||
// Added piston cells and head cells
|
// Added piston cells and head cells
|
||||||
DynamicList<cellZone*> cz(3);
|
List<cellZone*> cz(3);
|
||||||
|
|
||||||
label nPointZones = 0;
|
label nPointZones = 0;
|
||||||
label nFaceZones = 0;
|
label nFaceZones = 0;
|
||||||
|
@ -88,24 +87,11 @@ void Foam::twoStrokeEngine::addZonesAndModifiers()
|
||||||
|
|
||||||
Info << "Adding piston layer faces" << endl;
|
Info << "Adding piston layer faces" << endl;
|
||||||
|
|
||||||
# include "addPistonLayerHrv.H"
|
# include "addPistonLayer.H"
|
||||||
|
|
||||||
// adding head points (does not move)
|
// Add head points that do not move
|
||||||
|
|
||||||
{
|
{
|
||||||
// pointSet headPointSet(*this, headPointsSetName_);
|
|
||||||
|
|
||||||
// pz[nPointZones] =
|
|
||||||
// new pointZone
|
|
||||||
// (
|
|
||||||
// "headPoints",
|
|
||||||
// headPointSet.toc(),
|
|
||||||
// nPointZones,
|
|
||||||
// pointZones()
|
|
||||||
// );
|
|
||||||
|
|
||||||
// nPointZones++;
|
|
||||||
|
|
||||||
cellSet headCellSet(*this, headCellsSetName_);
|
cellSet headCellSet(*this, headCellsSetName_);
|
||||||
|
|
||||||
cz[nCellZones] =
|
cz[nCellZones] =
|
||||||
|
@ -120,9 +106,9 @@ void Foam::twoStrokeEngine::addZonesAndModifiers()
|
||||||
nCellZones++;
|
nCellZones++;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sliding interface for scavenging ports
|
// Sliding interface for scavenging ports
|
||||||
|
|
||||||
if(nPorts > 0)
|
if (nPorts > 0)
|
||||||
{
|
{
|
||||||
forAll(scavInCylPatches_, patchi)
|
forAll(scavInCylPatches_, patchi)
|
||||||
{
|
{
|
||||||
|
@ -133,76 +119,85 @@ void Foam::twoStrokeEngine::addZonesAndModifiers()
|
||||||
boundaryMesh().findPatchID(scavInCylPatches_[patchi])
|
boundaryMesh().findPatchID(scavInCylPatches_[patchi])
|
||||||
];
|
];
|
||||||
|
|
||||||
labelList isf(innerScav.size());
|
|
||||||
|
|
||||||
forAll (isf, i)
|
|
||||||
{
|
|
||||||
isf[i] = innerScav.start() + i;
|
|
||||||
}
|
|
||||||
|
|
||||||
fz[nFaceZones] = new faceZone
|
|
||||||
(
|
|
||||||
scavInCylPatches_[patchi] + "Zone" + Foam::name(patchi + 1),
|
|
||||||
isf,
|
|
||||||
boolList(innerScav.size(), false),
|
|
||||||
nFaceZones,
|
|
||||||
faceZones()
|
|
||||||
);
|
|
||||||
|
|
||||||
nFaceZones++;
|
|
||||||
|
|
||||||
// Outer slider
|
// Outer slider
|
||||||
|
|
||||||
const polyPatch& outerScav =
|
const polyPatch& outerScav =
|
||||||
boundaryMesh()
|
boundaryMesh()
|
||||||
[
|
[
|
||||||
boundaryMesh().findPatchID(scavInPortPatches_[patchi])
|
boundaryMesh().findPatchID(scavInPortPatches_[patchi])
|
||||||
];
|
];
|
||||||
|
|
||||||
labelList osf(outerScav.size());
|
Pout<< "A: " << innerScav.size() << " " << outerScav.size()
|
||||||
|
<< endl;
|
||||||
forAll (osf, i)
|
// Add zone if both patches has got faces
|
||||||
|
if (!innerScav.empty() && !outerScav.empty())
|
||||||
{
|
{
|
||||||
osf[i] = outerScav.start() + i;
|
// Inner
|
||||||
|
labelList isf(innerScav.size());
|
||||||
|
|
||||||
|
forAll (isf, i)
|
||||||
|
{
|
||||||
|
isf[i] = innerScav.start() + i;
|
||||||
|
}
|
||||||
|
|
||||||
|
fz[nFaceZones] = new faceZone
|
||||||
|
(
|
||||||
|
scavInCylPatches_[patchi] + "Zone"
|
||||||
|
+ Foam::name(patchi + 1),
|
||||||
|
isf,
|
||||||
|
boolList(innerScav.size(), false),
|
||||||
|
nFaceZones,
|
||||||
|
faceZones()
|
||||||
|
);
|
||||||
|
|
||||||
|
nFaceZones++;
|
||||||
|
|
||||||
|
// Outer
|
||||||
|
labelList osf(outerScav.size());
|
||||||
|
|
||||||
|
forAll (osf, i)
|
||||||
|
{
|
||||||
|
osf[i] = outerScav.start() + i;
|
||||||
|
}
|
||||||
|
|
||||||
|
fz[nFaceZones] = new faceZone
|
||||||
|
(
|
||||||
|
scavInPortPatches_[patchi] + "Zone"
|
||||||
|
+ Foam::name(patchi + 1),
|
||||||
|
osf,
|
||||||
|
boolList(outerScav.size(), false),
|
||||||
|
nFaceZones,
|
||||||
|
faceZones()
|
||||||
|
);
|
||||||
|
|
||||||
|
nFaceZones++;
|
||||||
|
|
||||||
|
// Cut faces
|
||||||
|
fz[nFaceZones] = new faceZone
|
||||||
|
(
|
||||||
|
"cutFaceZone" + Foam::name(patchi + 1),
|
||||||
|
labelList(0),
|
||||||
|
boolList(0, false),
|
||||||
|
nFaceZones,
|
||||||
|
faceZones()
|
||||||
|
);
|
||||||
|
|
||||||
|
nFaceZones++;
|
||||||
|
|
||||||
|
// Cut points
|
||||||
|
pz[nPointZones] = new pointZone
|
||||||
|
(
|
||||||
|
"cutPointZone" + Foam::name(patchi + 1),
|
||||||
|
labelList(0),
|
||||||
|
nPointZones,
|
||||||
|
pointZones()
|
||||||
|
);
|
||||||
|
|
||||||
|
nPointZones++;
|
||||||
}
|
}
|
||||||
|
|
||||||
fz[nFaceZones] = new faceZone
|
|
||||||
(
|
|
||||||
scavInPortPatches_[patchi] + "Zone" + Foam::name(patchi + 1),
|
|
||||||
osf,
|
|
||||||
boolList(outerScav.size(), false),
|
|
||||||
nFaceZones,
|
|
||||||
faceZones()
|
|
||||||
);
|
|
||||||
|
|
||||||
nFaceZones++;
|
|
||||||
|
|
||||||
fz[nFaceZones] = new faceZone
|
|
||||||
(
|
|
||||||
"cutFaceZone" + Foam::name(patchi + 1),
|
|
||||||
labelList(0),
|
|
||||||
boolList(0, false),
|
|
||||||
nFaceZones,
|
|
||||||
faceZones()
|
|
||||||
);
|
|
||||||
|
|
||||||
nFaceZones++;
|
|
||||||
|
|
||||||
Info << "cut p" << endl;
|
|
||||||
|
|
||||||
pz[nPointZones] = new pointZone
|
|
||||||
(
|
|
||||||
"cutPointZone" + Foam::name(patchi + 1),
|
|
||||||
labelList(0),
|
|
||||||
nPointZones,
|
|
||||||
pointZones()
|
|
||||||
);
|
|
||||||
|
|
||||||
nPointZones++;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Info << "moving cells" << endl;
|
Info << "Adding moving cells zone" << endl;
|
||||||
|
|
||||||
{
|
{
|
||||||
cellSet movingCells(*this, movingCellSetName_);
|
cellSet movingCells(*this, movingCellSetName_);
|
||||||
|
@ -218,9 +213,7 @@ void Foam::twoStrokeEngine::addZonesAndModifiers()
|
||||||
nCellZones++;
|
nCellZones++;
|
||||||
}
|
}
|
||||||
|
|
||||||
Info << "moving cells added" << endl;
|
Pout<< "Adding " << nPointZones << " point, "
|
||||||
|
|
||||||
Info<< "Adding " << nPointZones << " point, "
|
|
||||||
<< nFaceZones << " face zones and " << nCellZones
|
<< nFaceZones << " face zones and " << nCellZones
|
||||||
<< " cell zones" << endl;
|
<< " cell zones" << endl;
|
||||||
|
|
||||||
|
@ -229,40 +222,64 @@ void Foam::twoStrokeEngine::addZonesAndModifiers()
|
||||||
cz.setSize(nCellZones);
|
cz.setSize(nCellZones);
|
||||||
addZones(pz, fz, cz);
|
addZones(pz, fz, cz);
|
||||||
|
|
||||||
List<polyMeshModifier*> tm(1 + nPorts);
|
List<polyMeshModifier*> tm(nPorts + 1);
|
||||||
label nMods = 0;
|
label nMods = 0;
|
||||||
|
|
||||||
// Add piston layer addition
|
// Add piston layer addition
|
||||||
|
|
||||||
# include "addPistonLayerAdditionRemovalMeshModifier.H"
|
# include "addPistonLayerAdditionRemovalMeshModifier.H"
|
||||||
|
|
||||||
if(nPorts > 0)
|
if (nPorts > 0)
|
||||||
{
|
{
|
||||||
forAll(scavInPortPatches_, i)
|
forAll (scavInPortPatches_, i)
|
||||||
{
|
{
|
||||||
topoChanger_.setSize(topoChanger_.size() + 1);
|
// Check if patches are present on local processor
|
||||||
|
const label sipID =
|
||||||
|
boundaryMesh().findPatchID(scavInPortPatches_[i]);
|
||||||
|
|
||||||
topoChanger_.set
|
const label sicID =
|
||||||
(
|
boundaryMesh().findPatchID(scavInCylPatches_[i]);
|
||||||
nMods,
|
|
||||||
new slidingInterface
|
if (sipID > -1 && sicID > -1)
|
||||||
|
{
|
||||||
|
if
|
||||||
(
|
(
|
||||||
"portCylinderInterface" + Foam::name(i + 1),
|
boundaryMesh()[sipID].size() > 0
|
||||||
nMods,
|
&& boundaryMesh()[sicID].size() > 0
|
||||||
topoChanger_,
|
|
||||||
scavInPortPatches_[i] + "Zone" + Foam::name(i + 1),
|
|
||||||
scavInCylPatches_[i] + "Zone" + Foam::name(i + 1),
|
|
||||||
"cutPointZone" + Foam::name(i + 1),
|
|
||||||
"cutFaceZone" + Foam::name(i + 1),
|
|
||||||
scavInPortPatches_[i],
|
|
||||||
scavInCylPatches_[i],
|
|
||||||
slidingInterface::INTEGRAL,
|
|
||||||
true, // Attach-detach action
|
|
||||||
intersection::VISIBLE // Projection algorithm
|
|
||||||
)
|
)
|
||||||
);
|
{
|
||||||
|
Pout<< "Adding slider for pair " << scavInPortPatches_[i]
|
||||||
|
<< " and " << scavInCylPatches_[i]
|
||||||
|
<< " with sizes "
|
||||||
|
<< boundaryMesh()[sipID].size() << " "
|
||||||
|
<< boundaryMesh()[sicID].size() << endl;
|
||||||
|
|
||||||
nMods++;
|
// Patches present. Add modifier
|
||||||
|
topoChanger_.setSize(topoChanger_.size() + 1);
|
||||||
|
|
||||||
|
topoChanger_.set
|
||||||
|
(
|
||||||
|
nMods,
|
||||||
|
new slidingInterface
|
||||||
|
(
|
||||||
|
"portCylinderInterface" + Foam::name(i + 1),
|
||||||
|
nMods,
|
||||||
|
topoChanger_,
|
||||||
|
scavInPortPatches_[i] + "Zone" + Foam::name(i + 1),
|
||||||
|
scavInCylPatches_[i] + "Zone" + Foam::name(i + 1),
|
||||||
|
"cutPointZone" + Foam::name(i + 1),
|
||||||
|
"cutFaceZone" + Foam::name(i + 1),
|
||||||
|
scavInPortPatches_[i],
|
||||||
|
scavInCylPatches_[i],
|
||||||
|
slidingInterface::INTEGRAL,
|
||||||
|
true, // Attach-detach action
|
||||||
|
intersection::VISIBLE // Projection algorithm
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
nMods++;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -152,13 +152,13 @@ void Foam::twoStrokeEngine::setBoundaryVelocity(volVectorField& U)
|
||||||
|
|
||||||
// On the piston movingWallVelocity is used.
|
// On the piston movingWallVelocity is used.
|
||||||
// There is no need to update the piston velocity
|
// There is no need to update the piston velocity
|
||||||
// U.boundaryField()[piston().patchID().index()] = pistonVel;
|
|
||||||
|
|
||||||
forAll(scavInPortPatches_, patchi)
|
forAll (scavInPortPatches_, patchi)
|
||||||
{
|
{
|
||||||
U.boundaryField()
|
const label curPatchID =
|
||||||
[boundaryMesh().findPatchID(scavInPortPatches_[patchi])] ==
|
boundaryMesh().findPatchID(scavInPortPatches_[patchi]);
|
||||||
pistonVel;
|
|
||||||
|
U.boundaryField()[curPatchID] == pistonVel;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -61,21 +61,26 @@ void Foam::twoStrokeEngine::calcMovingMasks() const
|
||||||
const cellList& c = cells();
|
const cellList& c = cells();
|
||||||
const faceList& f = allFaces();
|
const faceList& f = allFaces();
|
||||||
|
|
||||||
const labelList& cellAddr =
|
const label movingCellsID = cellZones().findZoneID("movingCells");
|
||||||
cellZones()[cellZones().findZoneID("movingCells")];
|
|
||||||
|
|
||||||
forAll (cellAddr, cellI)
|
// If moving cell zone is found, mark the vertices
|
||||||
|
if (movingCellsID > -1)
|
||||||
{
|
{
|
||||||
const cell& curCell = c[cellAddr[cellI]];
|
const labelList& cellAddr = cellZones()[movingCellsID];
|
||||||
|
|
||||||
forAll (curCell, faceI)
|
forAll (cellAddr, cellI)
|
||||||
{
|
{
|
||||||
// Mark all the points as moving
|
const cell& curCell = c[cellAddr[cellI]];
|
||||||
const face& curFace = f[curCell[faceI]];
|
|
||||||
|
|
||||||
forAll (curFace, pointI)
|
forAll (curCell, faceI)
|
||||||
{
|
{
|
||||||
movingPointsMask[curFace[pointI]] = 1;
|
// Mark all the points as moving
|
||||||
|
const face& curFace = f[curCell[faceI]];
|
||||||
|
|
||||||
|
forAll (curFace, pointI)
|
||||||
|
{
|
||||||
|
movingPointsMask[curFace[pointI]] = 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,9 +44,8 @@ void Foam::twoStrokeEngine::checkAndCalculate()
|
||||||
label cylinderHeadIndex = -1;
|
label cylinderHeadIndex = -1;
|
||||||
bool foundCylinderHead = false;
|
bool foundCylinderHead = false;
|
||||||
|
|
||||||
forAll(boundary(), i)
|
forAll (boundary(), i)
|
||||||
{
|
{
|
||||||
Info << boundary()[i].name() << endl;
|
|
||||||
if (boundary()[i].name() == "piston")
|
if (boundary()[i].name() == "piston")
|
||||||
{
|
{
|
||||||
pistonIndex = i;
|
pistonIndex = i;
|
||||||
|
@ -111,34 +110,31 @@ void Foam::twoStrokeEngine::checkAndCalculate()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Foam::twoStrokeEngine::setVirtualPistonPosition()
|
void Foam::twoStrokeEngine::setVirtualPistonPosition()
|
||||||
{
|
{
|
||||||
|
|
||||||
label pistonFaceIndex = faceZones().findZoneID("pistonLayerFaces");
|
label pistonFaceIndex = faceZones().findZoneID("pistonLayerFaces");
|
||||||
|
|
||||||
bool foundPistonFace = (pistonFaceIndex != -1);
|
if(pistonFaceIndex == -1)
|
||||||
|
|
||||||
Info << "piston face index = " << pistonFaceIndex << endl;
|
|
||||||
|
|
||||||
if(!foundPistonFace)
|
|
||||||
{
|
{
|
||||||
FatalErrorIn("Foam::twoStrokeEngine::setVirtualPistonPosition()")
|
FatalErrorIn("Foam::twoStrokeEngine::setVirtualPistonPosition()")
|
||||||
<< " : cannot find the pistonLayerFaces"
|
<< "Cannot find the pistonLayerFaces"
|
||||||
<< exit(FatalError);
|
<< abort(FatalError);
|
||||||
}
|
}
|
||||||
|
|
||||||
const labelList& pistonFaces = faceZones()[pistonFaceIndex];
|
const labelList& pistonPoints =
|
||||||
forAll(pistonFaces, i)
|
faceZones()[pistonFaceIndex]().meshPoints();
|
||||||
{
|
|
||||||
const face& f = faces()[pistonFaces[i]];
|
|
||||||
|
|
||||||
// should loop over facepoints...
|
const pointField& p = points();
|
||||||
forAll(f, j)
|
|
||||||
{
|
forAll (pistonPoints, i)
|
||||||
virtualPistonPosition() =
|
{
|
||||||
Foam::max(virtualPistonPosition(), points()[f[j]].z());
|
virtualPistonPosition() =
|
||||||
}
|
Foam::max(virtualPistonPosition_, p[pistonPoints[i]].z());
|
||||||
}
|
}
|
||||||
|
|
||||||
reduce(virtualPistonPosition(), maxOp<scalar>());
|
reduce(virtualPistonPosition(), maxOp<scalar>());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
|
|
|
@ -41,11 +41,11 @@ void Foam::twoStrokeEngine::makeLayersLive()
|
||||||
// Enable layering
|
// Enable layering
|
||||||
forAll (morphs, modI)
|
forAll (morphs, modI)
|
||||||
{
|
{
|
||||||
if (typeid(morphs[modI]) == typeid(layerAdditionRemoval))
|
if (isA<layerAdditionRemoval>(morphs[modI]))
|
||||||
{
|
{
|
||||||
morphs[modI].enable();
|
morphs[modI].enable();
|
||||||
}
|
}
|
||||||
else if (typeid(morphs[modI]) == typeid(slidingInterface))
|
else if (isA<slidingInterface>(morphs[modI]))
|
||||||
{
|
{
|
||||||
morphs[modI].disable();
|
morphs[modI].disable();
|
||||||
}
|
}
|
||||||
|
@ -59,6 +59,7 @@ void Foam::twoStrokeEngine::makeLayersLive()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Foam::twoStrokeEngine::makeSlidersLive()
|
void Foam::twoStrokeEngine::makeSlidersLive()
|
||||||
{
|
{
|
||||||
const polyTopoChanger& morphs = topoChanger_;
|
const polyTopoChanger& morphs = topoChanger_;
|
||||||
|
@ -66,11 +67,11 @@ void Foam::twoStrokeEngine::makeSlidersLive()
|
||||||
// Enable sliding interface
|
// Enable sliding interface
|
||||||
forAll (morphs, modI)
|
forAll (morphs, modI)
|
||||||
{
|
{
|
||||||
if (typeid(morphs[modI]) == typeid(layerAdditionRemoval))
|
if (isA<layerAdditionRemoval>(morphs[modI]))
|
||||||
{
|
{
|
||||||
morphs[modI].disable();
|
morphs[modI].disable();
|
||||||
}
|
}
|
||||||
else if (typeid(morphs[modI]) == typeid(slidingInterface))
|
else if (isA<slidingInterface>(morphs[modI]))
|
||||||
{
|
{
|
||||||
morphs[modI].enable();
|
morphs[modI].enable();
|
||||||
}
|
}
|
||||||
|
@ -93,10 +94,9 @@ bool Foam::twoStrokeEngine::attached() const
|
||||||
|
|
||||||
forAll (morphs, modI)
|
forAll (morphs, modI)
|
||||||
{
|
{
|
||||||
if (typeid(morphs[modI]) == typeid(slidingInterface))
|
if (isA<slidingInterface>(morphs[modI]))
|
||||||
{
|
{
|
||||||
result =
|
result = result
|
||||||
result
|
|
||||||
|| refCast<const slidingInterface>(morphs[modI]).attached();
|
|| refCast<const slidingInterface>(morphs[modI]).attached();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -104,7 +104,7 @@ bool Foam::twoStrokeEngine::attached() const
|
||||||
// Check thal all sliders are in sync (debug only)
|
// Check thal all sliders are in sync (debug only)
|
||||||
forAll (morphs, modI)
|
forAll (morphs, modI)
|
||||||
{
|
{
|
||||||
if (typeid(morphs[modI]) == typeid(slidingInterface))
|
if (isA<slidingInterface>(morphs[modI]))
|
||||||
{
|
{
|
||||||
if
|
if
|
||||||
(
|
(
|
||||||
|
@ -120,6 +120,9 @@ bool Foam::twoStrokeEngine::attached() const
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Sync across processors
|
||||||
|
reduce(result, orOp<bool>());
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -133,13 +136,25 @@ bool Foam::twoStrokeEngine::update()
|
||||||
makeSlidersLive();
|
makeSlidersLive();
|
||||||
|
|
||||||
// Changing topology by hand
|
// Changing topology by hand
|
||||||
autoPtr<mapPolyMesh> topoChangeMap5 = topoChanger_.changeMesh();
|
autoPtr<mapPolyMesh> topoChangeMap1 = topoChanger_.changeMesh();
|
||||||
|
|
||||||
if (topoChangeMap5->hasMotionPoints() && topoChangeMap5->morphing())
|
bool localMorphing1 = topoChangeMap1->morphing();
|
||||||
|
|
||||||
|
// Note: Since we are detaching, global morphing is always true
|
||||||
|
// HJ, 7/Mar/2011
|
||||||
|
|
||||||
|
if (localMorphing1)
|
||||||
{
|
{
|
||||||
Info << "Topology change; executing pre-motion after "
|
Info << "Topology change; executing pre-motion after "
|
||||||
<< "sliding detach" << endl;
|
<< "sliding detach" << endl;
|
||||||
movePoints(topoChangeMap5->preMotionPoints());
|
movePoints(topoChangeMap1->preMotionPoints());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pointField newPoints = allPoints();
|
||||||
|
|
||||||
|
// Dummy motion
|
||||||
|
movePoints(newPoints);
|
||||||
}
|
}
|
||||||
|
|
||||||
Info << "sliding interfaces successfully decoupled!!!" << endl;
|
Info << "sliding interfaces successfully decoupled!!!" << endl;
|
||||||
|
@ -154,25 +169,14 @@ bool Foam::twoStrokeEngine::update()
|
||||||
// Piston Layering
|
// Piston Layering
|
||||||
|
|
||||||
makeLayersLive();
|
makeLayersLive();
|
||||||
// Changing topology by hand
|
|
||||||
|
|
||||||
|
// Find piston mesh modifier if present on processor
|
||||||
// /* Tommaso, 23/5/2008
|
|
||||||
|
|
||||||
// Find piston mesh modifier
|
|
||||||
const label pistonLayerID =
|
const label pistonLayerID =
|
||||||
topoChanger_.findModifierID("pistonLayer");
|
topoChanger_.findModifierID("pistonLayer");
|
||||||
|
|
||||||
if (pistonLayerID < 0)
|
|
||||||
{
|
|
||||||
FatalErrorIn("void engineFvMesh::moveAndMorph()")
|
|
||||||
<< "Piston modifier not found."
|
|
||||||
<< abort(FatalError);
|
|
||||||
}
|
|
||||||
|
|
||||||
scalar minLayerThickness = piston().minLayer();
|
scalar minLayerThickness = piston().minLayer();
|
||||||
scalar deltaZ = engTime().pistonDisplacement().value();
|
scalar deltaZ = engTime().pistonDisplacement().value();
|
||||||
virtualPistonPosition() += deltaZ;
|
virtualPistonPosition_ += deltaZ;
|
||||||
|
|
||||||
Info << "virtualPistonPosition = " << virtualPistonPosition()
|
Info << "virtualPistonPosition = " << virtualPistonPosition()
|
||||||
<< ", deckHeight = " << deckHeight()
|
<< ", deckHeight = " << deckHeight()
|
||||||
|
@ -181,32 +185,45 @@ bool Foam::twoStrokeEngine::update()
|
||||||
if (realDeformation())
|
if (realDeformation())
|
||||||
{
|
{
|
||||||
// Dectivate piston layer
|
// Dectivate piston layer
|
||||||
Info << "Mesh deformation mode" << endl;
|
if (pistonLayerID > -1)
|
||||||
topoChanger_[pistonLayerID].disable();
|
{
|
||||||
|
Info << "Mesh deformation mode" << endl;
|
||||||
|
topoChanger_[pistonLayerID].disable();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Activate piston layer
|
// Activate piston layer
|
||||||
Info << "Piston layering mode" << endl;
|
if (pistonLayerID > -1)
|
||||||
topoChanger_[pistonLayerID].enable();
|
{
|
||||||
|
Info << "Piston layering mode" << endl;
|
||||||
|
topoChanger_[pistonLayerID].enable();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Changing topology by hand
|
// Changing topology by hand
|
||||||
autoPtr<mapPolyMesh> topoChangeMap = topoChanger_.changeMesh();
|
autoPtr<mapPolyMesh> topoChangeMap2 = topoChanger_.changeMesh();
|
||||||
|
|
||||||
|
bool localMorphing2 = topoChangeMap2->morphing();
|
||||||
|
bool globalMorphing2 = localMorphing2;
|
||||||
|
|
||||||
// Work array for new points position.
|
// Work array for new points position.
|
||||||
pointField newPoints = allPoints();
|
pointField newPoints = allPoints();
|
||||||
const pointField& refPoints = allPoints();
|
|
||||||
|
|
||||||
if (topoChangeMap->morphing())
|
if (globalMorphing2)
|
||||||
{
|
{
|
||||||
if (topoChangeMap->hasMotionPoints())
|
Info<< "Topology change; executing pre-motion after "
|
||||||
|
<< "dynamic layering" << endl;
|
||||||
|
|
||||||
|
if (localMorphing2)
|
||||||
{
|
{
|
||||||
Info<< "Topology change; executing pre-motion after "
|
movePoints(topoChangeMap2->preMotionPoints());
|
||||||
<< "dynamic layering" << endl;
|
newPoints = topoChangeMap2->preMotionPoints();
|
||||||
movePoints(topoChangeMap->preMotionPoints());
|
}
|
||||||
newPoints = topoChangeMap->preMotionPoints();
|
else
|
||||||
|
{
|
||||||
|
movePoints(newPoints);
|
||||||
}
|
}
|
||||||
|
|
||||||
setV0();
|
setV0();
|
||||||
|
@ -225,99 +242,92 @@ bool Foam::twoStrokeEngine::update()
|
||||||
labelList pistonPoints;
|
labelList pistonPoints;
|
||||||
labelList headPoints;
|
labelList headPoints;
|
||||||
{
|
{
|
||||||
label pistonCellIndex = cellZones().findZoneID("pistonCells");
|
// Get cell-point addressing
|
||||||
|
|
||||||
if (pistonCellIndex < 0)
|
|
||||||
{
|
|
||||||
FatalErrorIn("bool twoStrokeEngine::update()")
|
|
||||||
<< "Cannot find cell zone pistonCells"
|
|
||||||
<< abort(FatalError);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
const labelList& pistonCells = cellZones()[pistonCellIndex];
|
|
||||||
|
|
||||||
label headCellIndex = cellZones().findZoneID("headCells");
|
|
||||||
|
|
||||||
if (headCellIndex < 0)
|
|
||||||
{
|
|
||||||
FatalErrorIn("bool twoStrokeEngine::update()")
|
|
||||||
<< "Cannot find cell zone headCells"
|
|
||||||
<< abort(FatalError);
|
|
||||||
}
|
|
||||||
|
|
||||||
const labelList& headCells = cellZones()[headCellIndex];
|
|
||||||
|
|
||||||
const labelListList& cp = cellPoints();
|
const labelListList& cp = cellPoints();
|
||||||
|
|
||||||
boolList count(newPoints.size(), false);
|
boolList count(newPoints.size(), false);
|
||||||
|
|
||||||
forAll (pistonCells, cellI)
|
// Piston points
|
||||||
{
|
label pistonCellID = cellZones().findZoneID("pistonCells");
|
||||||
const labelList& curCellPoints = cp[pistonCells[cellI]];
|
|
||||||
|
|
||||||
forAll (curCellPoints, i)
|
if (pistonCellID > -1)
|
||||||
|
{
|
||||||
|
const labelList& pistonCells = cellZones()[pistonCellID];
|
||||||
|
|
||||||
|
forAll (pistonCells, cellI)
|
||||||
{
|
{
|
||||||
count[curCellPoints[i]] = true;
|
const labelList& curCellPoints = cp[pistonCells[cellI]];
|
||||||
|
|
||||||
|
forAll (curCellPoints, i)
|
||||||
|
{
|
||||||
|
count[curCellPoints[i]] = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Count the points
|
// Count the points
|
||||||
label nCounted = 0;
|
label nCounted = 0;
|
||||||
forAll (count, pointI)
|
forAll (count, pointI)
|
||||||
{
|
|
||||||
if (count[pointI] == true)
|
|
||||||
{
|
{
|
||||||
nCounted++;
|
if (count[pointI] == true)
|
||||||
|
{
|
||||||
|
nCounted++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
pistonPoints.setSize(nCounted);
|
pistonPoints.setSize(nCounted);
|
||||||
|
|
||||||
// Collect the points
|
// Collect the points
|
||||||
nCounted = 0;
|
nCounted = 0;
|
||||||
forAll (count, pointI)
|
forAll (count, pointI)
|
||||||
{
|
|
||||||
if (count[pointI] == true)
|
|
||||||
{
|
{
|
||||||
pistonPoints[nCounted] = pointI;
|
if (count[pointI] == true)
|
||||||
nCounted++;
|
{
|
||||||
|
pistonPoints[nCounted] = pointI;
|
||||||
|
nCounted++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Repeat for head points
|
// Repeat for head points
|
||||||
count = false;
|
count = false;
|
||||||
|
|
||||||
forAll (headCells, cellI)
|
const label headCellID = cellZones().findZoneID("headCells");
|
||||||
{
|
|
||||||
const labelList& curCellPoints = cp[pistonCells[cellI]];
|
|
||||||
|
|
||||||
forAll (curCellPoints, i)
|
if (headCellID > -1)
|
||||||
|
{
|
||||||
|
const labelList& headCells = cellZones()[headCellID];
|
||||||
|
|
||||||
|
forAll (headCells, cellI)
|
||||||
{
|
{
|
||||||
count[curCellPoints[i]] = true;
|
const labelList& curCellPoints = cp[headCells[cellI]];
|
||||||
|
|
||||||
|
forAll (curCellPoints, i)
|
||||||
|
{
|
||||||
|
count[curCellPoints[i]] = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Count the points
|
// Count the points
|
||||||
nCounted = 0;
|
label nCounted = 0;
|
||||||
forAll (count, pointI)
|
forAll (count, pointI)
|
||||||
{
|
|
||||||
if (count[pointI] == true)
|
|
||||||
{
|
{
|
||||||
nCounted++;
|
if (count[pointI] == true)
|
||||||
|
{
|
||||||
|
nCounted++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
headPoints.setSize(nCounted);
|
headPoints.setSize(nCounted);
|
||||||
|
|
||||||
// Collect the points
|
// Collect the points
|
||||||
nCounted = 0;
|
nCounted = 0;
|
||||||
forAll (count, pointI)
|
forAll (count, pointI)
|
||||||
{
|
|
||||||
if (count[pointI] == true)
|
|
||||||
{
|
{
|
||||||
headPoints[nCounted] = pointI;
|
if (count[pointI] == true)
|
||||||
nCounted++;
|
{
|
||||||
|
headPoints[nCounted] = pointI;
|
||||||
|
nCounted++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -325,12 +335,6 @@ bool Foam::twoStrokeEngine::update()
|
||||||
|
|
||||||
label nScaled = nPoints();
|
label nScaled = nPoints();
|
||||||
|
|
||||||
// label pistonPtsIndex = pointZones().findZoneID("pistonPoints");
|
|
||||||
// const labelList& pistonPoints = pointZones()[pistonPtsIndex];
|
|
||||||
|
|
||||||
// label headPtsIndex = pointZones().findZoneID("headPoints");
|
|
||||||
// const labelList& headPoints = pointZones()[headPtsIndex];
|
|
||||||
|
|
||||||
const scalarField& movingPointsM = movingPointsMask();
|
const scalarField& movingPointsM = movingPointsMask();
|
||||||
|
|
||||||
forAll(pistonPoints, i)
|
forAll(pistonPoints, i)
|
||||||
|
@ -377,6 +381,7 @@ bool Foam::twoStrokeEngine::update()
|
||||||
{
|
{
|
||||||
// Always move piston
|
// Always move piston
|
||||||
scalar pistonTopZ = -GREAT;
|
scalar pistonTopZ = -GREAT;
|
||||||
|
|
||||||
forAll(pistonPoints, i)
|
forAll(pistonPoints, i)
|
||||||
{
|
{
|
||||||
point& p = newPoints[pistonPoints[i]];
|
point& p = newPoints[pistonPoints[i]];
|
||||||
|
@ -406,15 +411,11 @@ bool Foam::twoStrokeEngine::update()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
movePoints(newPoints);
|
movePoints(newPoints);
|
||||||
deleteDemandDrivenData(movingPointsMaskPtr_);
|
deleteDemandDrivenData(movingPointsMaskPtr_);
|
||||||
|
|
||||||
pistonPosition() += deltaZ;
|
pistonPosition() += deltaZ;
|
||||||
|
|
||||||
//*/ //Tommaso, 23/5/2008
|
|
||||||
|
|
||||||
{
|
{
|
||||||
// Grab old points to correct the motion
|
// Grab old points to correct the motion
|
||||||
pointField oldPointsNew = oldAllPoints();
|
pointField oldPointsNew = oldAllPoints();
|
||||||
|
@ -424,73 +425,98 @@ bool Foam::twoStrokeEngine::update()
|
||||||
makeSlidersLive();
|
makeSlidersLive();
|
||||||
|
|
||||||
// Changing topology by hand
|
// Changing topology by hand
|
||||||
autoPtr<mapPolyMesh> topoChangeMap4 = topoChanger_.changeMesh();
|
autoPtr<mapPolyMesh> topoChangeMap3 = topoChanger_.changeMesh();
|
||||||
|
|
||||||
if (topoChangeMap4->morphing())
|
bool localMorphing3 = topoChangeMap3->morphing();
|
||||||
|
bool globalMorphing3 = localMorphing3;
|
||||||
|
|
||||||
|
reduce(globalMorphing3, orOp<bool>());
|
||||||
|
|
||||||
|
if (globalMorphing3)
|
||||||
{
|
{
|
||||||
if (topoChangeMap4->hasMotionPoints())
|
Info<< "Topology change; executing pre-motion after "
|
||||||
|
<< "sliding attach" << endl;
|
||||||
|
|
||||||
|
// Grab points
|
||||||
|
newPoints = allPoints();
|
||||||
|
|
||||||
|
if (localMorphing3)
|
||||||
{
|
{
|
||||||
Info<< "Topology change; executing pre-motion after "
|
// If there is layering, pick up correct points
|
||||||
<< "sliding attach" << endl;
|
if (topoChangeMap3->hasMotionPoints())
|
||||||
|
{
|
||||||
|
newPoints = topoChangeMap3->preMotionPoints();
|
||||||
|
}
|
||||||
|
|
||||||
// Info<< "topoChangeMap4->preMotionPoints().size() = "
|
// Prepare old points for the move
|
||||||
// << topoChangeMap4->preMotionPoints().size() << nl
|
|
||||||
// << "allPoints.size() = " << allPoints().size() << nl
|
|
||||||
// << "points.size() = " << points().size() << endl;
|
|
||||||
|
|
||||||
movePoints(topoChangeMap4->preMotionPoints());
|
|
||||||
newPoints = points();
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
pointField mappedOldPointsNew(allPoints().size());
|
pointField mappedOldPointsNew(allPoints().size());
|
||||||
|
|
||||||
mappedOldPointsNew.map
|
mappedOldPointsNew.map
|
||||||
(
|
(
|
||||||
oldPointsNew, topoChangeMap4->pointMap()
|
oldPointsNew, topoChangeMap3->pointMap()
|
||||||
);
|
);
|
||||||
|
|
||||||
forAll(scavInPortPatches_, patchi)
|
forAll(scavInPortPatches_, patchi)
|
||||||
{
|
{
|
||||||
const labelList& cutPointsAddressing =
|
// Find cut point zone ID
|
||||||
pointZones()
|
const label cutPointZoneID = pointZones().findZoneID
|
||||||
[
|
(
|
||||||
pointZones().findZoneID
|
"cutPointZone" + Foam::name(patchi + 1)
|
||||||
(
|
);
|
||||||
"cutPointZone" + Foam::name(patchi + 1)
|
|
||||||
)
|
|
||||||
];
|
|
||||||
|
|
||||||
forAll(cutPointsAddressing, i)
|
if (cutPointZoneID > -1)
|
||||||
{
|
{
|
||||||
mappedOldPointsNew[cutPointsAddressing[i]] =
|
const labelList& cutPointsAddressing =
|
||||||
newPoints[cutPointsAddressing[i]];
|
pointZones()[cutPointZoneID];
|
||||||
}
|
|
||||||
|
|
||||||
forAll(cutPointsAddressing, i)
|
forAll(cutPointsAddressing, i)
|
||||||
{
|
|
||||||
if
|
|
||||||
(
|
|
||||||
newPoints[cutPointsAddressing[i]].z()
|
|
||||||
> virtualPistonPosition()
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
mappedOldPointsNew[cutPointsAddressing[i]].z() =
|
mappedOldPointsNew[cutPointsAddressing[i]] =
|
||||||
newPoints[cutPointsAddressing[i]].z();
|
newPoints[cutPointsAddressing[i]];
|
||||||
}
|
}
|
||||||
else
|
|
||||||
|
forAll(cutPointsAddressing, i)
|
||||||
{
|
{
|
||||||
mappedOldPointsNew[cutPointsAddressing[i]].z() =
|
if
|
||||||
newPoints[cutPointsAddressing[i]].z() - deltaZ;
|
(
|
||||||
|
newPoints[cutPointsAddressing[i]].z()
|
||||||
|
> virtualPistonPosition()
|
||||||
|
)
|
||||||
|
{
|
||||||
|
mappedOldPointsNew
|
||||||
|
[cutPointsAddressing[i]].z() =
|
||||||
|
newPoints[cutPointsAddressing[i]].z();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mappedOldPointsNew
|
||||||
|
[cutPointsAddressing[i]].z() =
|
||||||
|
newPoints[cutPointsAddressing[i]].z()
|
||||||
|
- deltaZ;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pointField newPoints = allPoints();
|
|
||||||
|
|
||||||
|
// Move mesh into correct old configuration
|
||||||
movePoints(mappedOldPointsNew);
|
movePoints(mappedOldPointsNew);
|
||||||
|
|
||||||
resetMotion();
|
resetMotion();
|
||||||
setV0();
|
setV0();
|
||||||
|
|
||||||
|
// Set new point motion
|
||||||
|
movePoints(newPoints);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// No local topological change. Execute double motion for
|
||||||
|
// sync with topological changes
|
||||||
|
movePoints(oldPointsNew);
|
||||||
|
|
||||||
|
resetMotion();
|
||||||
|
setV0();
|
||||||
|
|
||||||
|
// Set new point motion
|
||||||
movePoints(newPoints);
|
movePoints(newPoints);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
// Add piston layer addition/removal
|
// Add piston layer addition/removal
|
||||||
if (piston().patchID().active())
|
if (piston().patchID().active())
|
||||||
{
|
{
|
||||||
|
Info<< "Adding a layer addition/removal mesh modifier to the piston"
|
||||||
|
<< endl;
|
||||||
|
|
||||||
|
topoChanger_.setSize(nMods + 1);
|
||||||
|
|
||||||
Info << "Adding a layer addition/removal mesh modifier to the piston" << endl;
|
|
||||||
|
|
||||||
topoChanger_.setSize(nMods+1);
|
|
||||||
|
|
||||||
topoChanger_.set
|
topoChanger_.set
|
||||||
(
|
(
|
||||||
nMods,
|
nMods,
|
||||||
|
@ -17,9 +17,9 @@
|
||||||
"pistonLayerFaces",
|
"pistonLayerFaces",
|
||||||
piston().minLayer(),
|
piston().minLayer(),
|
||||||
piston().maxLayer()
|
piston().maxLayer()
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
nMods++;
|
nMods++;
|
||||||
Info << "pistonLayer" << endl;
|
|
||||||
Info << nMods << endl;
|
Info << "pistonLayer modifier number " << nMods << endl;
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,8 @@
|
||||||
(
|
(
|
||||||
engineTopoChangerMesh::defaultRegion,
|
engineTopoChangerMesh::defaultRegion,
|
||||||
runTime.timeName(),
|
runTime.timeName(),
|
||||||
runTime
|
runTime,
|
||||||
|
IOobject::MUST_READ
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
|
@ -43,7 +43,7 @@ namespace Foam
|
||||||
|
|
||||||
addToRunTimeSelectionTable
|
addToRunTimeSelectionTable
|
||||||
(
|
(
|
||||||
topoChangerFvMesh,
|
engineTopoChangerMesh,
|
||||||
simpleEngineTopoFvMesh,
|
simpleEngineTopoFvMesh,
|
||||||
IOobject
|
IOobject
|
||||||
);
|
);
|
||||||
|
@ -211,7 +211,7 @@ bool Foam::simpleEngineTopoFvMesh::attached() const
|
||||||
{
|
{
|
||||||
if
|
if
|
||||||
(
|
(
|
||||||
result
|
result
|
||||||
!= refCast<const slidingInterface>(topoChanger_[modI]).attached()
|
!= refCast<const slidingInterface>(topoChanger_[modI]).attached()
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
@ -458,8 +458,7 @@ Foam::simpleEngineTopoFvMesh::simpleEngineTopoFvMesh
|
||||||
const IOobject& io
|
const IOobject& io
|
||||||
)
|
)
|
||||||
:
|
:
|
||||||
topoChangerFvMesh(io),
|
engineTopoChangerMesh(io),
|
||||||
engineTime_(refCast<const engineTime>(time())),
|
|
||||||
valves_(*this, engineTime_.engineDict().lookup("valves")),
|
valves_(*this, engineTime_.engineDict().lookup("valves")),
|
||||||
piston_(*this, engineTime_.engineDict().subDict("piston")),
|
piston_(*this, engineTime_.engineDict().subDict("piston")),
|
||||||
msPtr_(motionSolver::New(*this)),
|
msPtr_(motionSolver::New(*this)),
|
||||||
|
|
|
@ -27,8 +27,7 @@ License
|
||||||
#ifndef simpleEngineTopoFvMesh_H
|
#ifndef simpleEngineTopoFvMesh_H
|
||||||
#define simpleEngineTopoFvMesh_H
|
#define simpleEngineTopoFvMesh_H
|
||||||
|
|
||||||
#include "topoChangerFvMesh.H"
|
#include "engineTopoChangerMesh.H"
|
||||||
#include "engineTime.H"
|
|
||||||
#include "valveBank.H"
|
#include "valveBank.H"
|
||||||
#include "simpleEnginePiston.H"
|
#include "simpleEnginePiston.H"
|
||||||
#include "motionSolver.H"
|
#include "motionSolver.H"
|
||||||
|
@ -44,13 +43,10 @@ namespace Foam
|
||||||
|
|
||||||
class simpleEngineTopoFvMesh
|
class simpleEngineTopoFvMesh
|
||||||
:
|
:
|
||||||
public topoChangerFvMesh
|
public engineTopoChangerMesh
|
||||||
{
|
{
|
||||||
// Private data
|
// Private data
|
||||||
|
|
||||||
//- Engine database
|
|
||||||
const engineTime& engineTime_;
|
|
||||||
|
|
||||||
//- Engine valves
|
//- Engine valves
|
||||||
valveBank valves_;
|
valveBank valves_;
|
||||||
|
|
||||||
|
@ -76,6 +72,9 @@ class simpleEngineTopoFvMesh
|
||||||
void operator=(const simpleEngineTopoFvMesh&);
|
void operator=(const simpleEngineTopoFvMesh&);
|
||||||
|
|
||||||
|
|
||||||
|
//- Add valve and piston zones and modifiers
|
||||||
|
void addZonesAndModifiers();
|
||||||
|
|
||||||
//- Make layering modifiers live
|
//- Make layering modifiers live
|
||||||
void makeLayersLive();
|
void makeLayersLive();
|
||||||
|
|
||||||
|
@ -140,11 +139,12 @@ public:
|
||||||
&& engineTime_.thetaRevolution() < deformSwitch_;
|
&& engineTime_.thetaRevolution() < deformSwitch_;
|
||||||
}
|
}
|
||||||
|
|
||||||
//- Add valve and piston zones and modifiers
|
|
||||||
void addZonesAndModifiers();
|
|
||||||
|
|
||||||
//- Update the mesh for both mesh motion and topology change
|
//- Update the mesh for both mesh motion and topology change
|
||||||
virtual bool update();
|
virtual bool update();
|
||||||
|
|
||||||
|
//- Set boundary velocities
|
||||||
|
virtual void setBoundaryVelocity(volVectorField& U)
|
||||||
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -360,7 +360,7 @@ edgeInterpolationScheme<Type>::interpolate
|
||||||
|
|
||||||
for (label i=0; i<size; i++)
|
for (label i=0; i<size; i++)
|
||||||
{
|
{
|
||||||
const tensorField& curT =
|
const tensorField& curT =
|
||||||
mesh.edgeTransformTensors()[start + i];
|
mesh.edgeTransformTensors()[start + i];
|
||||||
|
|
||||||
const tensor& Te = curT[0];
|
const tensor& Te = curT[0];
|
||||||
|
@ -372,13 +372,13 @@ edgeInterpolationScheme<Type>::interpolate
|
||||||
(
|
(
|
||||||
Te.T(),
|
Te.T(),
|
||||||
pLambda[i]*transform(TP, pOwnVf[i])
|
pLambda[i]*transform(TP, pOwnVf[i])
|
||||||
+ (1.0 - pLambda[i])*transform(TN, pNgbVf[i])
|
+ (1 - pLambda[i])*transform(TN, pNgbVf[i])
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// tsf().boundaryField()[pi] =
|
// tsf().boundaryField()[pi] =
|
||||||
// pLambda*vf.boundaryField()[pi].patchInternalField()
|
// pLambda*vf.boundaryField()[pi].patchInternalField()
|
||||||
// + (1.0 - pLambda)*vf.boundaryField()[pi].patchNeighbourField();
|
// + (1 - pLambda)*vf.boundaryField()[pi].patchNeighbourField();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -118,7 +118,7 @@ void Foam::flowRateInletVelocityFvPatchVectorField::updateCoeffs()
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// a simpler way of doing this would be nice
|
// A simpler way of doing this would be nice
|
||||||
scalar avgU = -flowRate_/gSum(patch().magSf());
|
scalar avgU = -flowRate_/gSum(patch().magSf());
|
||||||
|
|
||||||
vectorField n = patch().nf();
|
vectorField n = patch().nf();
|
||||||
|
@ -128,7 +128,7 @@ void Foam::flowRateInletVelocityFvPatchVectorField::updateCoeffs()
|
||||||
|
|
||||||
if (phi.dimensions() == dimVelocity*dimArea)
|
if (phi.dimensions() == dimVelocity*dimArea)
|
||||||
{
|
{
|
||||||
// volumetric flow-rate
|
// Volumetric flow-rate
|
||||||
operator==(n*avgU);
|
operator==(n*avgU);
|
||||||
}
|
}
|
||||||
else if (phi.dimensions() == dimDensity*dimVelocity*dimArea)
|
else if (phi.dimensions() == dimDensity*dimVelocity*dimArea)
|
||||||
|
@ -136,7 +136,7 @@ void Foam::flowRateInletVelocityFvPatchVectorField::updateCoeffs()
|
||||||
const fvPatchField<scalar>& rhop =
|
const fvPatchField<scalar>& rhop =
|
||||||
patch().lookupPatchField<volScalarField, scalar>(rhoName_);
|
patch().lookupPatchField<volScalarField, scalar>(rhoName_);
|
||||||
|
|
||||||
// mass flow-rate
|
// Mass flow-rate
|
||||||
operator==(n*avgU/rhop);
|
operator==(n*avgU/rhop);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
|
@ -69,10 +69,10 @@ tmp<volScalarField> CoEulerDdtScheme<Type>::CorDeltaT() const
|
||||||
|
|
||||||
forAll(owner, faceI)
|
forAll(owner, faceI)
|
||||||
{
|
{
|
||||||
corDeltaT[owner[faceI]] =
|
corDeltaT[owner[faceI]] =
|
||||||
max(corDeltaT[owner[faceI]], cofrDeltaT[faceI]);
|
max(corDeltaT[owner[faceI]], cofrDeltaT[faceI]);
|
||||||
|
|
||||||
corDeltaT[neighbour[faceI]] =
|
corDeltaT[neighbour[faceI]] =
|
||||||
max(corDeltaT[neighbour[faceI]], cofrDeltaT[faceI]);
|
max(corDeltaT[neighbour[faceI]], cofrDeltaT[faceI]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -105,7 +105,7 @@ public:
|
||||||
public:
|
public:
|
||||||
|
|
||||||
// Constructors
|
// Constructors
|
||||||
|
|
||||||
fieldScheme
|
fieldScheme
|
||||||
(
|
(
|
||||||
const GeometricField<Type, fvPatchField, volMesh>& field,
|
const GeometricField<Type, fvPatchField, volMesh>& field,
|
||||||
|
|
|
@ -59,8 +59,7 @@ void Foam::processorTetPolyPatchCellDecomp::calcMeshPoints() const
|
||||||
masterFaces[faceI] = pp[faceI].reverseFace();
|
masterFaces[faceI] = pp[faceI].reverseFace();
|
||||||
}
|
}
|
||||||
|
|
||||||
mp =
|
mp = primitiveFacePatch
|
||||||
primitiveFacePatch
|
|
||||||
(
|
(
|
||||||
masterFaces,
|
masterFaces,
|
||||||
pp.points()
|
pp.points()
|
||||||
|
|
|
@ -63,6 +63,8 @@ solvers
|
||||||
SIMPLE
|
SIMPLE
|
||||||
{
|
{
|
||||||
nNonOrthogonalCorrectors 0;
|
nNonOrthogonalCorrectors 0;
|
||||||
|
|
||||||
|
convergence 1e-4;
|
||||||
}
|
}
|
||||||
|
|
||||||
relaxationFactors
|
relaxationFactors
|
||||||
|
|
|
@ -16,7 +16,14 @@ FoamFile
|
||||||
|
|
||||||
solvers
|
solvers
|
||||||
{
|
{
|
||||||
motionU ICCG 1e-9 0.001;
|
motionU
|
||||||
|
{
|
||||||
|
solver CG;
|
||||||
|
preconditioner Cholesky;
|
||||||
|
|
||||||
|
tolerance 1e-09;
|
||||||
|
relTol 0.001;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ************************************************************************* //
|
// ************************************************************************* //
|
||||||
|
|
Reference in a new issue