Merge remote-tracking branch 'origin/feature/multisolver' into nextRelease
This commit is contained in:
commit
6aef940d91
51 changed files with 7218 additions and 0 deletions
8
.gitignore
vendored
8
.gitignore
vendored
|
@ -181,4 +181,12 @@ src/lduSolvers/amg/amgPolicy/samgPolicy.H
|
||||||
src/lduSolvers/amg/amgPolicy/aamgPolicy.C
|
src/lduSolvers/amg/amgPolicy/aamgPolicy.C
|
||||||
src/lduSolvers/amg/amgPolicy/aamgPolicy.H
|
src/lduSolvers/amg/amgPolicy/aamgPolicy.H
|
||||||
|
|
||||||
|
# The following files are blacklisted because of a DMCA complaint by ANSYS.
|
||||||
|
src/lduSolvers/tools/PriorityArray.C
|
||||||
|
src/lduSolvers/tools/PriorityArray.H
|
||||||
|
src/lduSolvers/amg/amgPolicy/samgPolicy.C
|
||||||
|
src/lduSolvers/amg/amgPolicy/samgPolicy.H
|
||||||
|
src/lduSolvers/amg/amgPolicy/aamgPolicy.C
|
||||||
|
src/lduSolvers/amg/amgPolicy/aamgPolicy.H
|
||||||
|
|
||||||
# end-of-file
|
# end-of-file
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
multiSolverDemo.C
|
||||||
|
|
||||||
|
EXE = $(FOAM_APPBIN)/multiSolverDemo
|
|
@ -0,0 +1,9 @@
|
||||||
|
EXE_INC = \
|
||||||
|
-I$(LIB_SRC)/finiteVolume/lnInclude \
|
||||||
|
-I$(LIB_SRC)/multiSolver/lnInclude \
|
||||||
|
-I$(LIB_SRC)/multiSolver/multiSolver
|
||||||
|
|
||||||
|
EXE_LIBS = \
|
||||||
|
-lfiniteVolume \
|
||||||
|
-L$(FOAM_USER_LIBBIN) \
|
||||||
|
-lmultiSolver
|
|
@ -0,0 +1,55 @@
|
||||||
|
Info<< "Reading transportProperties\n" << endl;
|
||||||
|
|
||||||
|
IOdictionary transportProperties
|
||||||
|
(
|
||||||
|
IOobject
|
||||||
|
(
|
||||||
|
"transportProperties",
|
||||||
|
runTime.constant(),
|
||||||
|
mesh,
|
||||||
|
IOobject::MUST_READ,
|
||||||
|
IOobject::NO_WRITE
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
dimensionedScalar nu
|
||||||
|
(
|
||||||
|
transportProperties.lookup("nu")
|
||||||
|
);
|
||||||
|
|
||||||
|
Info<< "Reading field p\n" << endl;
|
||||||
|
volScalarField p
|
||||||
|
(
|
||||||
|
IOobject
|
||||||
|
(
|
||||||
|
"p",
|
||||||
|
runTime.timeName(),
|
||||||
|
mesh,
|
||||||
|
IOobject::MUST_READ,
|
||||||
|
IOobject::AUTO_WRITE
|
||||||
|
),
|
||||||
|
mesh
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
Info<< "Reading field U\n" << endl;
|
||||||
|
volVectorField U
|
||||||
|
(
|
||||||
|
IOobject
|
||||||
|
(
|
||||||
|
"U",
|
||||||
|
runTime.timeName(),
|
||||||
|
mesh,
|
||||||
|
IOobject::MUST_READ,
|
||||||
|
IOobject::AUTO_WRITE
|
||||||
|
),
|
||||||
|
mesh
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
# include "createPhi.H"
|
||||||
|
|
||||||
|
|
||||||
|
label pRefCell = 0;
|
||||||
|
scalar pRefValue = 0.0;
|
||||||
|
setRefCell(p, mesh.solutionDict().subDict("PISO"), pRefCell, pRefValue);
|
|
@ -0,0 +1,55 @@
|
||||||
|
Info<< "Reading field T\n" << endl;
|
||||||
|
|
||||||
|
volScalarField T
|
||||||
|
(
|
||||||
|
IOobject
|
||||||
|
(
|
||||||
|
"T",
|
||||||
|
runTime.timeName(),
|
||||||
|
mesh,
|
||||||
|
IOobject::MUST_READ,
|
||||||
|
IOobject::AUTO_WRITE
|
||||||
|
),
|
||||||
|
mesh
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
Info<< "Reading field U\n" << endl;
|
||||||
|
|
||||||
|
volVectorField U
|
||||||
|
(
|
||||||
|
IOobject
|
||||||
|
(
|
||||||
|
"U",
|
||||||
|
runTime.timeName(),
|
||||||
|
mesh,
|
||||||
|
IOobject::MUST_READ,
|
||||||
|
IOobject::AUTO_WRITE
|
||||||
|
),
|
||||||
|
mesh
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
Info<< "Reading transportProperties\n" << endl;
|
||||||
|
|
||||||
|
IOdictionary transportProperties
|
||||||
|
(
|
||||||
|
IOobject
|
||||||
|
(
|
||||||
|
"transportProperties",
|
||||||
|
runTime.constant(),
|
||||||
|
mesh,
|
||||||
|
IOobject::MUST_READ,
|
||||||
|
IOobject::NO_WRITE
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
Info<< "Reading diffusivity D\n" << endl;
|
||||||
|
|
||||||
|
dimensionedScalar DT
|
||||||
|
(
|
||||||
|
transportProperties.lookup("DT")
|
||||||
|
);
|
||||||
|
|
||||||
|
# include "createPhi.H"
|
||||||
|
|
|
@ -0,0 +1,86 @@
|
||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / 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
|
||||||
|
|
||||||
|
Application
|
||||||
|
multiSolverDemo
|
||||||
|
|
||||||
|
Description
|
||||||
|
Demonstration multiSolver-enabled application.
|
||||||
|
|
||||||
|
Author
|
||||||
|
David L. F. Gaden
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#include "fvCFD.H"
|
||||||
|
#include "multiSolver.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
|
||||||
|
# include "setRootCase.H"
|
||||||
|
|
||||||
|
# include "createMultiSolver.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * icoFoam1 * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Info << "*** Switching to icoFoam1 ***\n" << endl;
|
||||||
|
solverDomain = "icoFoam1";
|
||||||
|
# include "setSolverDomain.H"
|
||||||
|
|
||||||
|
# include "solverIcoFoam.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * scalarTransportFoam * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Info << "*** Switching to scalarTransportFoam ***\n" << endl;
|
||||||
|
solverDomain = "scalarTransportFoam";
|
||||||
|
# include "setSolverDomain.H"
|
||||||
|
|
||||||
|
# include "solverScalarTransportFoam.H"
|
||||||
|
|
||||||
|
multiRun++;
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * icoFoam2 * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Info << "*** Switching to icoFoam2 ***\n" << endl;
|
||||||
|
solverDomain = "icoFoam2";
|
||||||
|
# include "setSolverDomain.H"
|
||||||
|
|
||||||
|
# include "solverIcoFoam.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * scalarTransportFoam * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Info << "*** Switching to scalarTransportFoam ***\n" << endl;
|
||||||
|
solverDomain = "scalarTransportFoam";
|
||||||
|
# include "setSolverDomain.H"
|
||||||
|
|
||||||
|
# include "solverScalarTransportFoam.H"
|
||||||
|
|
||||||
|
# include "endMultiSolver.H"
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
|
@ -0,0 +1,69 @@
|
||||||
|
|
||||||
|
# include "createTime.H"
|
||||||
|
# include "createMesh.H"
|
||||||
|
# include "createFields_icoFoam.H"
|
||||||
|
# include "initContinuityErrs.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Info<< "\nStarting time loop\n" << endl;
|
||||||
|
|
||||||
|
for (runTime++; !runTime.end(); runTime++)
|
||||||
|
{
|
||||||
|
Info<< "Time = " << runTime.timeName() << nl << endl;
|
||||||
|
|
||||||
|
# include "readPISOControls.H"
|
||||||
|
# include "CourantNo.H"
|
||||||
|
|
||||||
|
fvVectorMatrix UEqn
|
||||||
|
(
|
||||||
|
fvm::ddt(U)
|
||||||
|
+ fvm::div(phi, U)
|
||||||
|
- fvm::laplacian(nu, U)
|
||||||
|
);
|
||||||
|
|
||||||
|
solve(UEqn == -fvc::grad(p));
|
||||||
|
|
||||||
|
// --- PISO loop
|
||||||
|
|
||||||
|
for (int corr=0; corr<nCorr; corr++)
|
||||||
|
{
|
||||||
|
volScalarField rUA = 1.0/UEqn.A();
|
||||||
|
|
||||||
|
U = rUA*UEqn.H();
|
||||||
|
phi = (fvc::interpolate(U) & mesh.Sf())
|
||||||
|
+ fvc::ddtPhiCorr(rUA, U, phi);
|
||||||
|
|
||||||
|
adjustPhi(phi, U, p);
|
||||||
|
|
||||||
|
for (int nonOrth=0; nonOrth<=nNonOrthCorr; nonOrth++)
|
||||||
|
{
|
||||||
|
fvScalarMatrix pEqn
|
||||||
|
(
|
||||||
|
fvm::laplacian(rUA, p) == fvc::div(phi)
|
||||||
|
);
|
||||||
|
|
||||||
|
pEqn.setReference(pRefCell, pRefValue);
|
||||||
|
pEqn.solve();
|
||||||
|
|
||||||
|
if (nonOrth == nNonOrthCorr)
|
||||||
|
{
|
||||||
|
phi -= pEqn.flux();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# include "continuityErrs.H"
|
||||||
|
|
||||||
|
U -= rUA*fvc::grad(p);
|
||||||
|
U.correctBoundaryConditions();
|
||||||
|
}
|
||||||
|
|
||||||
|
runTime.write();
|
||||||
|
|
||||||
|
Info<< "ExecutionTime = " << runTime.elapsedCpuTime() << " s"
|
||||||
|
<< " ClockTime = " << runTime.elapsedClockTime() << " s"
|
||||||
|
<< nl << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
Info<< "End\n" << endl;
|
||||||
|
|
|
@ -0,0 +1,31 @@
|
||||||
|
# include "createTime.H"
|
||||||
|
# include "createMesh.H"
|
||||||
|
# include "createFields_scalarTransportFoam.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Info<< "\nCalculating scalar transport\n" << endl;
|
||||||
|
|
||||||
|
# include "CourantNo.H"
|
||||||
|
|
||||||
|
for (runTime++; !runTime.end(); runTime++)
|
||||||
|
{
|
||||||
|
Info<< "Time = " << runTime.timeName() << nl << endl;
|
||||||
|
|
||||||
|
# include "readSIMPLEControls.H"
|
||||||
|
|
||||||
|
for (int nonOrth=0; nonOrth<=nNonOrthCorr; nonOrth++)
|
||||||
|
{
|
||||||
|
solve
|
||||||
|
(
|
||||||
|
fvm::ddt(T)
|
||||||
|
+ fvm::div(phi, T)
|
||||||
|
- fvm::laplacian(DT, T)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
runTime.write();
|
||||||
|
}
|
||||||
|
|
||||||
|
Info<< "End\n" << endl;
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
multiSolver.C
|
||||||
|
|
||||||
|
EXE = $(FOAM_APPBIN)/multiSolver
|
|
@ -0,0 +1,10 @@
|
||||||
|
EXE_INC = \
|
||||||
|
-I$(LIB_SRC)/finiteVolume/lnInclude \
|
||||||
|
-I$(LIB_SRC)/multiSolver/lnInclude \
|
||||||
|
-I$(LIB_SRC)/multiSolver/multiSolver
|
||||||
|
|
||||||
|
EXE_LIBS = \
|
||||||
|
-lfiniteVolume \
|
||||||
|
-L$(FOAM_USER_LIBBIN) \
|
||||||
|
-lmultiSolver
|
||||||
|
|
779
applications/utilities/postProcessing/multiSolver/multiSolver.C
Normal file
779
applications/utilities/postProcessing/multiSolver/multiSolver.C
Normal file
|
@ -0,0 +1,779 @@
|
||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / 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
|
||||||
|
|
||||||
|
Application
|
||||||
|
multiSolver
|
||||||
|
|
||||||
|
Description
|
||||||
|
Post-processor utility required for working with multiSolver-enabled
|
||||||
|
applications. These applications store data output in a different
|
||||||
|
location than usual. This utility loads and unloads data from that
|
||||||
|
location to where post-processors expect it.
|
||||||
|
|
||||||
|
Author
|
||||||
|
David L. F. Gaden
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#include "fvCFD.H"
|
||||||
|
#include "multiSolver.H"
|
||||||
|
|
||||||
|
void parseOptions
|
||||||
|
(
|
||||||
|
wordList * ptrSolverDomains,
|
||||||
|
labelList * ptrSuperLoops,
|
||||||
|
string options
|
||||||
|
)
|
||||||
|
{
|
||||||
|
IStringStream optionsStream(options);
|
||||||
|
label nSolverDomains(0);
|
||||||
|
label nSuperLoops(0);
|
||||||
|
|
||||||
|
// Get solverDomainNames, if any
|
||||||
|
while (not optionsStream.eof())
|
||||||
|
{
|
||||||
|
token nextOption(optionsStream);
|
||||||
|
if (nextOption.isLabel())
|
||||||
|
{
|
||||||
|
ptrSuperLoops->setSize(++nSuperLoops);
|
||||||
|
ptrSuperLoops->operator[](nSuperLoops - 1)
|
||||||
|
= nextOption.labelToken();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (nextOption.isWord())
|
||||||
|
{
|
||||||
|
ptrSolverDomains->setSize(++nSolverDomains);
|
||||||
|
ptrSolverDomains->operator[](nSolverDomains - 1)
|
||||||
|
= nextOption.wordToken();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// not word, not label, fail
|
||||||
|
FatalErrorIn("multiSolver::parseOptions")
|
||||||
|
<< "Expecting word or label. Neither found at position "
|
||||||
|
<< nSolverDomains - 1 << " in " << options
|
||||||
|
<< abort(FatalError);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get superLoopList
|
||||||
|
while (not optionsStream.eof())
|
||||||
|
{
|
||||||
|
token nextOption(optionsStream);
|
||||||
|
if (nextOption.isLabel())
|
||||||
|
{
|
||||||
|
ptrSuperLoops->setSize(++nSuperLoops);
|
||||||
|
ptrSuperLoops->operator[](nSuperLoops - 1)
|
||||||
|
= nextOption.labelToken();
|
||||||
|
}
|
||||||
|
else if (nSuperLoops > 0)
|
||||||
|
{
|
||||||
|
// might be a range -> label : label
|
||||||
|
|
||||||
|
if (nextOption.isPunctuation())
|
||||||
|
{
|
||||||
|
token::punctuationToken p(nextOption.pToken());
|
||||||
|
if (p == token::COLON)
|
||||||
|
{
|
||||||
|
token nextNextOption(optionsStream);
|
||||||
|
if (nextNextOption.isLabel())
|
||||||
|
{
|
||||||
|
label toValue(nextNextOption.labelToken());
|
||||||
|
label fromValue
|
||||||
|
(
|
||||||
|
ptrSuperLoops->operator[](nSuperLoops - 1)
|
||||||
|
);
|
||||||
|
|
||||||
|
if (toValue > fromValue)
|
||||||
|
{
|
||||||
|
// correct range format
|
||||||
|
for (label i = fromValue + 1; i <= toValue; i++)
|
||||||
|
{
|
||||||
|
ptrSuperLoops->setSize(++nSuperLoops);
|
||||||
|
ptrSuperLoops->operator[](nSuperLoops - 1) = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// greater than / less than, range
|
||||||
|
FatalErrorIn("multiSolver::parseOptions")
|
||||||
|
<< "superLoop range incorrect order. 'from : "
|
||||||
|
<< "to' where 'from' should be less than "
|
||||||
|
<< "'to'. Values read are '" << fromValue
|
||||||
|
<< " : " << toValue
|
||||||
|
<< abort(FatalError);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// nextNext not label
|
||||||
|
FatalErrorIn("multiSolver::parseOptions")
|
||||||
|
<< "Incorrect syntax. Expecting label after ':' "
|
||||||
|
<< "in " << options
|
||||||
|
<< abort(FatalError);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// non : punctuation
|
||||||
|
FatalErrorIn("multiSolver::parseOptions")
|
||||||
|
<< "Incorrect syntax. Expecting label, word, or ':' "
|
||||||
|
<< "in " << options
|
||||||
|
<< abort(FatalError);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// not punctuation
|
||||||
|
FatalErrorIn("multiSolver::parseOptions")
|
||||||
|
<< "Incorrect syntax. Expecting label, word, or ':' "
|
||||||
|
<< "in " << options
|
||||||
|
<< abort(FatalError);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// not label, not word
|
||||||
|
FatalErrorIn("multiSolver::parseOptions")
|
||||||
|
<< "Incorrect syntax. Expecting label, word, or ':' "
|
||||||
|
<< "in " << options
|
||||||
|
<< abort(FatalError);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
argList::validOptions.insert("list","");
|
||||||
|
argList::validOptions.insert
|
||||||
|
(
|
||||||
|
"load","<[solverDomainName] [superLoopNumber(s)]>"
|
||||||
|
);
|
||||||
|
argList::validOptions.insert
|
||||||
|
(
|
||||||
|
"purge","<[solverDomainName] [superLoopNumber(s)]>"
|
||||||
|
);
|
||||||
|
argList::validOptions.insert("set","<solverDomainName>");
|
||||||
|
argList::validOptions.insert("preDecompose", "");
|
||||||
|
argList::validOptions.insert("postDecompose", "");
|
||||||
|
argList::validOptions.insert("preReconstruct", "");
|
||||||
|
argList::validOptions.insert("postReconstruct", "");
|
||||||
|
|
||||||
|
argList::validOptions.insert("global","");
|
||||||
|
argList::validOptions.insert("local","");
|
||||||
|
|
||||||
|
// default behaviour is purge the case/[time] directory before '-load'
|
||||||
|
// command. '-noPurge' prevents this. Allows for more complicated
|
||||||
|
// load data selections by executing multiSolver several times
|
||||||
|
argList::validOptions.insert("noPurge","");
|
||||||
|
|
||||||
|
// default behaviour is: if there is only one solverDomain specified, use
|
||||||
|
// setSolverDomain() on it. Same as multiSolver -set solverDomain.
|
||||||
|
// '-noSet' prevents this.
|
||||||
|
argList::validOptions.insert("noSet","");
|
||||||
|
|
||||||
|
// default behaviour is: if there are storeFields defined, when loading, it
|
||||||
|
// will copy the store fields into every time instance where they are
|
||||||
|
// absent. '-noStore' will prevent this.
|
||||||
|
argList::validOptions.insert("noStore","");
|
||||||
|
|
||||||
|
# include "setRootCase.H"
|
||||||
|
|
||||||
|
enum commandType
|
||||||
|
{
|
||||||
|
list,
|
||||||
|
load,
|
||||||
|
purge,
|
||||||
|
set,
|
||||||
|
preDecompose,
|
||||||
|
postDecompose,
|
||||||
|
preReconstruct,
|
||||||
|
postReconstruct
|
||||||
|
};
|
||||||
|
commandType command;
|
||||||
|
string options;
|
||||||
|
bool global = false;
|
||||||
|
bool local = false;
|
||||||
|
bool all = false;
|
||||||
|
bool root = false;
|
||||||
|
bool noPurge = false;
|
||||||
|
bool noSet = false;
|
||||||
|
bool noStore = false;
|
||||||
|
label nCommands(0);
|
||||||
|
|
||||||
|
// Read arguments
|
||||||
|
if (args.optionFound("list"))
|
||||||
|
{
|
||||||
|
nCommands++;
|
||||||
|
command = list;
|
||||||
|
}
|
||||||
|
if (args.optionFound("load"))
|
||||||
|
{
|
||||||
|
nCommands++;
|
||||||
|
command = load;
|
||||||
|
options = args.options()["load"];
|
||||||
|
}
|
||||||
|
if (args.optionFound("purge"))
|
||||||
|
{
|
||||||
|
nCommands++;
|
||||||
|
command = purge;
|
||||||
|
options = args.options()["purge"];
|
||||||
|
}
|
||||||
|
if (args.optionFound("set"))
|
||||||
|
{
|
||||||
|
nCommands++;
|
||||||
|
command = set;
|
||||||
|
options = args.options()["set"];
|
||||||
|
}
|
||||||
|
if (args.optionFound("preDecompose"))
|
||||||
|
{
|
||||||
|
nCommands++;
|
||||||
|
command = preDecompose;
|
||||||
|
}
|
||||||
|
if (args.optionFound("postDecompose"))
|
||||||
|
{
|
||||||
|
nCommands++;
|
||||||
|
command = postDecompose;
|
||||||
|
}
|
||||||
|
if (args.optionFound("preReconstruct"))
|
||||||
|
{
|
||||||
|
nCommands++;
|
||||||
|
command = preReconstruct;
|
||||||
|
}
|
||||||
|
if (args.optionFound("postReconstruct"))
|
||||||
|
{
|
||||||
|
nCommands++;
|
||||||
|
command = postReconstruct;
|
||||||
|
}
|
||||||
|
if (args.optionFound("global"))
|
||||||
|
{
|
||||||
|
global = true;
|
||||||
|
}
|
||||||
|
if (args.optionFound("local"))
|
||||||
|
{
|
||||||
|
local = true;
|
||||||
|
}
|
||||||
|
if (args.optionFound("noPurge"))
|
||||||
|
{
|
||||||
|
noPurge = true;
|
||||||
|
}
|
||||||
|
if (args.optionFound("noSet"))
|
||||||
|
{
|
||||||
|
noSet = true;
|
||||||
|
}
|
||||||
|
if (args.optionFound("noStore"))
|
||||||
|
{
|
||||||
|
noStore = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Error checking
|
||||||
|
if (nCommands == 0)
|
||||||
|
{
|
||||||
|
FatalErrorIn("multiSolver::main")
|
||||||
|
<< "multiSolver - nothing to do. Use 'multiSolver -help' for assistance."
|
||||||
|
<< abort(FatalError);
|
||||||
|
}
|
||||||
|
else if (nCommands > 1)
|
||||||
|
{
|
||||||
|
FatalErrorIn("multiSolver::main")
|
||||||
|
<< "More than one command found. Use only one of:"
|
||||||
|
<< "\n\t-list"
|
||||||
|
<< "\n\t-purge"
|
||||||
|
<< "\n\t-set"
|
||||||
|
<< "\n\t-preDecompose"
|
||||||
|
<< "\n\t-postDecompose"
|
||||||
|
<< "\n\t-preReconstruct"
|
||||||
|
<< "\n\t-postReconstruct\n"
|
||||||
|
<< abort(FatalError);
|
||||||
|
}
|
||||||
|
if (global && local)
|
||||||
|
{
|
||||||
|
FatalErrorIn("multiSolver::main")
|
||||||
|
<< "Options global and local both specified. Use only one or "
|
||||||
|
<< "none."
|
||||||
|
<< abort(FatalError);
|
||||||
|
}
|
||||||
|
if ((command != load) && (noPurge || noSet || noStore))
|
||||||
|
{
|
||||||
|
FatalErrorIn("multiSolver::main")
|
||||||
|
<< "'noPurge', 'noSet' and 'noStore' can only be used with the "
|
||||||
|
<< "'-load' command."
|
||||||
|
<< abort(FatalError);
|
||||||
|
}
|
||||||
|
|
||||||
|
multiSolver multiRun
|
||||||
|
(
|
||||||
|
Foam::multiSolver::multiControlDictName,
|
||||||
|
args.rootPath(),
|
||||||
|
args.caseName()
|
||||||
|
);
|
||||||
|
|
||||||
|
const IOdictionary& mcd(multiRun.multiControlDict());
|
||||||
|
wordList solverDomains(0);
|
||||||
|
labelList superLoops(0);
|
||||||
|
if
|
||||||
|
(
|
||||||
|
(command != list)
|
||||||
|
&& (command != preDecompose)
|
||||||
|
&& (command != postDecompose)
|
||||||
|
&& (command != preReconstruct)
|
||||||
|
&& (command != postReconstruct)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
parseOptions(&solverDomains, &superLoops, options);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Special words - all, root
|
||||||
|
if (solverDomains.size() == 1)
|
||||||
|
{
|
||||||
|
if (solverDomains[0] == "all")
|
||||||
|
{
|
||||||
|
all = true;
|
||||||
|
}
|
||||||
|
else if (solverDomains[0] == "root")
|
||||||
|
{
|
||||||
|
root = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// More error checking
|
||||||
|
if (root && ((command == load) || (command == set)))
|
||||||
|
{
|
||||||
|
FatalErrorIn("multiSolver::main")
|
||||||
|
<< "'root' is not a valid option with '-load' or '-set'"
|
||||||
|
<< abort(FatalError);
|
||||||
|
}
|
||||||
|
if (all && (command == set))
|
||||||
|
{
|
||||||
|
FatalErrorIn("multiSolver::main")
|
||||||
|
<< "'all' is not a valid option with '-set'"
|
||||||
|
<< abort(FatalError);
|
||||||
|
}
|
||||||
|
if ((command == set) && ((solverDomains.size() > 1) || superLoops.size()))
|
||||||
|
{
|
||||||
|
FatalErrorIn("multiSolver::main")
|
||||||
|
<< "'-set' can only have a single solverDomain name as an option."
|
||||||
|
<< abort(FatalError);
|
||||||
|
}
|
||||||
|
if (all && superLoops.size())
|
||||||
|
{
|
||||||
|
FatalErrorIn("multiSolver::main")
|
||||||
|
<< "'all' cannot be followed by superLoop numbers. To specify "
|
||||||
|
<< "a superLoop range for all solverDomains, omit the solverDomain"
|
||||||
|
<< " name entirely. e.g. multiSolver -load '0:4 6'"
|
||||||
|
<< abort(FatalError);
|
||||||
|
}
|
||||||
|
if (root && superLoops.size())
|
||||||
|
{
|
||||||
|
FatalErrorIn("multiSolver::main")
|
||||||
|
<< "'root' cannot be followed by superLoop numbers. 'root' refers"
|
||||||
|
<< " to case/[time] directories. There are no superLoops here."
|
||||||
|
<< abort(FatalError);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check for correct solverDomain names
|
||||||
|
if
|
||||||
|
(
|
||||||
|
!all
|
||||||
|
&& !root
|
||||||
|
&& (command != list)
|
||||||
|
&& (command != preDecompose)
|
||||||
|
&& (command != postDecompose)
|
||||||
|
&& (command != preReconstruct)
|
||||||
|
&& (command != postReconstruct)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
forAll(solverDomains, i)
|
||||||
|
{
|
||||||
|
if (solverDomains[i] == "default")
|
||||||
|
{
|
||||||
|
// default not permitted
|
||||||
|
FatalErrorIn("multiSolver::main")
|
||||||
|
<< "'default' is not a permitted solverDomain name."
|
||||||
|
<< abort(FatalError);
|
||||||
|
}
|
||||||
|
if (!mcd.subDict("solverDomains").found(solverDomains[i]))
|
||||||
|
{
|
||||||
|
// Incorrect solver domain name
|
||||||
|
FatalErrorIn("multiSolver::main")
|
||||||
|
<< "solverDomainName " << solverDomains[i] << " is not "
|
||||||
|
<< "found."
|
||||||
|
<< abort(FatalError);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Load specified timeClusterLists
|
||||||
|
timeClusterList tclSource(0);
|
||||||
|
|
||||||
|
if (all)
|
||||||
|
{
|
||||||
|
// read all
|
||||||
|
tclSource = multiRun.readAllTimes();
|
||||||
|
forAll(tclSource, i)
|
||||||
|
{
|
||||||
|
if (tclSource[i].superLoop() == -1)
|
||||||
|
{
|
||||||
|
tclSource[i].times().clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
tclSource.purgeEmpties();
|
||||||
|
}
|
||||||
|
else if
|
||||||
|
(
|
||||||
|
!superLoops.size()
|
||||||
|
&& (command != set)
|
||||||
|
&& (command != list)
|
||||||
|
&& (command != preDecompose)
|
||||||
|
&& (command != postDecompose)
|
||||||
|
&& (command != preReconstruct)
|
||||||
|
&& (command != postReconstruct)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
// no superLoops specified - read entire solverDomains
|
||||||
|
forAll (solverDomains, sd)
|
||||||
|
{
|
||||||
|
tclSource.append
|
||||||
|
(
|
||||||
|
multiRun.readSolverDomainTimes(solverDomains[sd])
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if
|
||||||
|
(
|
||||||
|
!root
|
||||||
|
&& (command != set)
|
||||||
|
&& (command != list)
|
||||||
|
&& (command != preDecompose)
|
||||||
|
&& (command != postDecompose)
|
||||||
|
&& (command != preReconstruct)
|
||||||
|
&& (command != postReconstruct)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
// read individual superLoops
|
||||||
|
if (!solverDomains.size())
|
||||||
|
{
|
||||||
|
solverDomains = mcd.subDict("solverDomains").toc();
|
||||||
|
}
|
||||||
|
forAll(superLoops, sl)
|
||||||
|
{
|
||||||
|
forAll(solverDomains, sd)
|
||||||
|
{
|
||||||
|
if (solverDomains[sd] == "default") continue;
|
||||||
|
tclSource.append
|
||||||
|
(
|
||||||
|
multiRun.readSuperLoopTimes
|
||||||
|
(
|
||||||
|
solverDomains[sd],
|
||||||
|
superLoops[sl]
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tclSource.size())
|
||||||
|
{
|
||||||
|
if (!tclSource.purgeEmpties())
|
||||||
|
{
|
||||||
|
FatalErrorIn("multiSolver::main")
|
||||||
|
<< "No data found with specified parameters."
|
||||||
|
<< abort(FatalError);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (command)
|
||||||
|
{
|
||||||
|
case list:
|
||||||
|
{
|
||||||
|
Info << "Listing available data:\n" << endl;
|
||||||
|
Info << "superLoops by solverDomain:" << endl;
|
||||||
|
solverDomains = mcd.subDict("solverDomains").toc();
|
||||||
|
fileName listPath
|
||||||
|
(
|
||||||
|
multiRun.multiDictRegistry().path()/"multiSolver"
|
||||||
|
);
|
||||||
|
|
||||||
|
forAll(solverDomains, i)
|
||||||
|
{
|
||||||
|
if (solverDomains[i] == "default") continue;
|
||||||
|
Info << solverDomains[i] << ":" << endl;
|
||||||
|
Info << multiRun.findSuperLoops(listPath/solverDomains[i])
|
||||||
|
<< endl;
|
||||||
|
}
|
||||||
|
Info << endl;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case load:
|
||||||
|
{
|
||||||
|
// Default behaviour - use local time unless overlapping, then use
|
||||||
|
// global time; if global overlaps, fail. -local and -global force
|
||||||
|
// the behaviour
|
||||||
|
bool localOverlap(!multiRun.nonOverlapping(tclSource, false));
|
||||||
|
bool globalOverlap(!multiRun.nonOverlapping(tclSource, true));
|
||||||
|
if (local && localOverlap)
|
||||||
|
{
|
||||||
|
FatalErrorIn("multiSolver::main")
|
||||||
|
<< "'-local' option used for data with overlapping local "
|
||||||
|
<< "values. Try using a single solverDomain / superLoop, "
|
||||||
|
<< "or leave '-local' off."
|
||||||
|
<< abort(FatalError);
|
||||||
|
}
|
||||||
|
if (globalOverlap)
|
||||||
|
{
|
||||||
|
FatalErrorIn("multiSolver::main")
|
||||||
|
<< "globalTime values are overlapping. This should not "
|
||||||
|
<< "happen. Ensure you have not specified the same "
|
||||||
|
<< "solverDomain and/or superLoop more than once. If "
|
||||||
|
<< "that fails, try using 'multiSolver -purge all' and "
|
||||||
|
<< "rerunning the simulation. If the problem persists, "
|
||||||
|
<< "it is a bug."
|
||||||
|
<< abort(FatalError);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!noPurge)
|
||||||
|
{
|
||||||
|
Info << "Purging existing time directories in case root"
|
||||||
|
<< endl;
|
||||||
|
multiRun.purgeTimeDirs(multiRun.multiDictRegistry().path());
|
||||||
|
}
|
||||||
|
|
||||||
|
Info << "Loading data from multiSolver directories to case root"
|
||||||
|
<< endl;
|
||||||
|
if
|
||||||
|
(
|
||||||
|
!multiRun.loadTimeClusterList
|
||||||
|
(
|
||||||
|
tclSource,
|
||||||
|
global || localOverlap,
|
||||||
|
!noStore
|
||||||
|
)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
FatalErrorIn("multiRun::main")
|
||||||
|
<< "loadTimeClusterList failed. timeClusterList contents: "
|
||||||
|
<< tclSource
|
||||||
|
<< abort(FatalError);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case purge:
|
||||||
|
if (root)
|
||||||
|
{
|
||||||
|
Info << "Purging time directories from case root" << endl;
|
||||||
|
multiRun.purgeTimeDirs(multiRun.multiDictRegistry().path());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Info << "Purging time directories from multiSolver directories"
|
||||||
|
<< endl;
|
||||||
|
forAll(tclSource, i)
|
||||||
|
{
|
||||||
|
// do not purge 'initial' directory, even if specified
|
||||||
|
if (tclSource[i].superLoop() < 0) continue;
|
||||||
|
fileName purgePath
|
||||||
|
(
|
||||||
|
multiRun.findInstancePath(tclSource[i], 0).path()
|
||||||
|
);
|
||||||
|
rmDir(purgePath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case set:
|
||||||
|
// do nothing here
|
||||||
|
break;
|
||||||
|
case preDecompose:
|
||||||
|
{
|
||||||
|
Info << "Performing preDecompose" << endl;
|
||||||
|
multiRun.preCondition();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case postDecompose:
|
||||||
|
{
|
||||||
|
Info << "Performing postDecompose" << endl;
|
||||||
|
|
||||||
|
fileNameList dirEntries
|
||||||
|
(
|
||||||
|
readDir
|
||||||
|
(
|
||||||
|
multiRun.multiDictRegistry().path(), fileName::DIRECTORY
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
forAll(dirEntries, de)
|
||||||
|
{
|
||||||
|
if (dirEntries[de](9) == "processor")
|
||||||
|
{
|
||||||
|
Info << "Reading " << dirEntries[de] << endl;
|
||||||
|
|
||||||
|
multiRun.postCondition
|
||||||
|
(
|
||||||
|
dirEntries[de]
|
||||||
|
);
|
||||||
|
|
||||||
|
// Copy system to processorN
|
||||||
|
cp
|
||||||
|
(
|
||||||
|
multiRun.multiDictRegistry().path()
|
||||||
|
/multiRun.multiDictRegistry().system(),
|
||||||
|
multiRun.multiDictRegistry().path()/dirEntries[de]
|
||||||
|
);
|
||||||
|
|
||||||
|
// Copy constant/files to processorN/constant
|
||||||
|
fileNameList constantContents
|
||||||
|
(
|
||||||
|
readDir
|
||||||
|
(
|
||||||
|
multiRun.multiDictRegistry().path()
|
||||||
|
/multiRun.multiDictRegistry().constant(),
|
||||||
|
fileName::FILE
|
||||||
|
)
|
||||||
|
);
|
||||||
|
forAll(constantContents, cc)
|
||||||
|
{
|
||||||
|
cp
|
||||||
|
(
|
||||||
|
multiRun.multiDictRegistry().path()
|
||||||
|
/multiRun.multiDictRegistry().constant()
|
||||||
|
/constantContents[cc],
|
||||||
|
multiRun.multiDictRegistry().path()/dirEntries[de]
|
||||||
|
/multiRun.multiDictRegistry().constant()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Copy constant/directories to processorN/constant
|
||||||
|
constantContents = readDir
|
||||||
|
(
|
||||||
|
multiRun.multiDictRegistry().path()
|
||||||
|
/multiRun.multiDictRegistry().constant(),
|
||||||
|
fileName::DIRECTORY
|
||||||
|
);
|
||||||
|
forAll(constantContents, cc)
|
||||||
|
{
|
||||||
|
// Ingore mesh directory
|
||||||
|
if (constantContents[cc] == "polyMesh")
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
cp
|
||||||
|
(
|
||||||
|
multiRun.multiDictRegistry().path()
|
||||||
|
/multiRun.multiDictRegistry().constant()
|
||||||
|
/constantContents[cc],
|
||||||
|
multiRun.multiDictRegistry().path()/dirEntries[de]
|
||||||
|
/multiRun.multiDictRegistry().constant()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
multiRun.purgeTimeDirs(multiRun.multiDictRegistry().path());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case preReconstruct:
|
||||||
|
{
|
||||||
|
Info << "Performing preReconstruct" << endl;
|
||||||
|
fileNameList dirEntries
|
||||||
|
(
|
||||||
|
readDir
|
||||||
|
(
|
||||||
|
multiRun.multiDictRegistry().path(), fileName::DIRECTORY
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
forAll(dirEntries, de)
|
||||||
|
{
|
||||||
|
if (dirEntries[de](9) == "processor")
|
||||||
|
{
|
||||||
|
Info << "Reading " << dirEntries[de] << endl;
|
||||||
|
multiRun.preCondition
|
||||||
|
(
|
||||||
|
dirEntries[de]
|
||||||
|
);
|
||||||
|
// Fix missing 0.00000e+00 directory if it exists
|
||||||
|
mkDir
|
||||||
|
(
|
||||||
|
multiRun.multiDictRegistry().path()/dirEntries[de]/"0"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case postReconstruct:
|
||||||
|
{
|
||||||
|
Info << "Performing postReconstruct" << endl;
|
||||||
|
|
||||||
|
Info << "Reading preconditioned time directories" << endl;
|
||||||
|
multiRun.postCondition();
|
||||||
|
|
||||||
|
Info << "Purging preconditioned time directories"
|
||||||
|
<< endl;
|
||||||
|
|
||||||
|
// Clean up extra time directories
|
||||||
|
fileNameList dirEntries
|
||||||
|
(
|
||||||
|
readDir
|
||||||
|
(
|
||||||
|
multiRun.multiDictRegistry().path(), fileName::DIRECTORY
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
forAll(dirEntries, de)
|
||||||
|
{
|
||||||
|
if (dirEntries[de](9) == "processor")
|
||||||
|
{
|
||||||
|
multiRun.purgeTimeDirs
|
||||||
|
(
|
||||||
|
multiRun.multiDictRegistry().path()/dirEntries[de]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Execute set command - either from an explicit '-set' or from a '-load'
|
||||||
|
// with only one solverDomain as an option
|
||||||
|
|
||||||
|
if
|
||||||
|
(
|
||||||
|
(command == set)
|
||||||
|
|| (
|
||||||
|
(command == load)
|
||||||
|
&& (solverDomains.size() == 1)
|
||||||
|
&& (!all)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
Info << "Changing to " << solverDomains[0] << " settings." << endl;
|
||||||
|
multiRun.setSolverDomainPostProcessing(solverDomains[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
Info << "\nCommand completed successfully.\n" << endl;
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
|
@ -22,6 +22,8 @@ Pstream/Allwmake
|
||||||
wmake libo OSspecific/$WM_OSTYPE
|
wmake libo OSspecific/$WM_OSTYPE
|
||||||
wmake libso OpenFOAM
|
wmake libso OpenFOAM
|
||||||
|
|
||||||
|
wmake libso multiSolver
|
||||||
|
|
||||||
# Decomposition methods needed by meshTools
|
# Decomposition methods needed by meshTools
|
||||||
decompositionMethods/AllwmakeLnInclude
|
decompositionMethods/AllwmakeLnInclude
|
||||||
decompositionMethods/Allwmake
|
decompositionMethods/Allwmake
|
||||||
|
|
6
src/multiSolver/Make/files
Normal file
6
src/multiSolver/Make/files
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
dummyControlDict/dummyControlDict.C
|
||||||
|
multiSolver/multiSolver.C
|
||||||
|
timeCluster/timeCluster.C
|
||||||
|
timeCluster/timeClusterList.C
|
||||||
|
|
||||||
|
LIB = $(FOAM_LIBBIN)/libmultiSolver
|
6
src/multiSolver/Make/options
Normal file
6
src/multiSolver/Make/options
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
EXE_INC = \
|
||||||
|
-I$(LIB_SRC)/finiteVolume/lnInclude \
|
||||||
|
-Ituple2Lists
|
||||||
|
|
||||||
|
LIB_LIBS = \
|
||||||
|
-lfiniteVolume
|
111
src/multiSolver/dummyControlDict/dummyControlDict.C
Normal file
111
src/multiSolver/dummyControlDict/dummyControlDict.C
Normal file
|
@ -0,0 +1,111 @@
|
||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / 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 "dummyControlDict.H"
|
||||||
|
#include "IFstream.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * Static Member Data * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
defineTypeNameAndDebug(dummyControlDict, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Foam::dummyControlDict::dummyControlDict()
|
||||||
|
{
|
||||||
|
this->set("deltaT", 1);
|
||||||
|
this->set("writeFrequency", 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::dummyControlDict::dummyControlDict(const fileName& mcdFile)
|
||||||
|
{
|
||||||
|
this->set("deltaT", 1);
|
||||||
|
this->set("writeFrequency", 1);
|
||||||
|
|
||||||
|
IFstream mcdStream(mcdFile);
|
||||||
|
if (!mcdStream.good())
|
||||||
|
{
|
||||||
|
FatalErrorIn("dummyControlDict::dummyControlDict")
|
||||||
|
<< "Cannot find the multiControlDict file " << mcdFile << "."
|
||||||
|
<< abort(FatalError);
|
||||||
|
}
|
||||||
|
dictionary mcdDict(mcdStream);
|
||||||
|
if (mcdDict.subDict("multiSolverControl").found("timeFormat"))
|
||||||
|
{
|
||||||
|
word tf(mcdDict.subDict("multiSolverControl").lookup("timeFormat"));
|
||||||
|
this->set("timeFormat", tf);
|
||||||
|
}
|
||||||
|
if (mcdDict.subDict("multiSolverControl").found("timePrecision"))
|
||||||
|
{
|
||||||
|
label tp
|
||||||
|
(
|
||||||
|
readLabel
|
||||||
|
(
|
||||||
|
mcdDict.subDict("multiSolverControl").lookup("timePrecision")
|
||||||
|
)
|
||||||
|
);
|
||||||
|
this->set("timePrecision", tp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::dummyControlDict::dummyControlDict(const dictionary& mcdDict)
|
||||||
|
{
|
||||||
|
this->set("deltaT", 1);
|
||||||
|
this->set("writeFrequency", 1);
|
||||||
|
|
||||||
|
if (mcdDict.subDict("multiSolverControl").found("timeFormat"))
|
||||||
|
{
|
||||||
|
word tf(mcdDict.subDict("multiSolverControl").lookup("timeFormat"));
|
||||||
|
this->set("timeFormat", tf);
|
||||||
|
}
|
||||||
|
if (mcdDict.subDict("multiSolverControl").found("timePrecision"))
|
||||||
|
{
|
||||||
|
label tp
|
||||||
|
(
|
||||||
|
readLabel
|
||||||
|
(
|
||||||
|
mcdDict.subDict("multiSolverControl").lookup("timePrecision")
|
||||||
|
)
|
||||||
|
);
|
||||||
|
this->set("timePrecision", tp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Foam::dummyControlDict::~dummyControlDict()
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
92
src/multiSolver/dummyControlDict/dummyControlDict.H
Normal file
92
src/multiSolver/dummyControlDict/dummyControlDict.H
Normal file
|
@ -0,0 +1,92 @@
|
||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / 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::dummyControlDict
|
||||||
|
|
||||||
|
Description
|
||||||
|
This class is a workaround that allows a class to have its own independent
|
||||||
|
objectRegistry. That requires the creation of a new Time object, which
|
||||||
|
requires a controlDict for construction. dummyControlDict creates a dummy
|
||||||
|
controlDict to feed the new Time object. The only dictionary values it
|
||||||
|
handles are deltaT, writeFrequency, and optionally, the Time class statics,
|
||||||
|
format and precision.
|
||||||
|
|
||||||
|
SourceFiles
|
||||||
|
dummyControlDict.C
|
||||||
|
|
||||||
|
Author
|
||||||
|
David L. F. Gaden
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef dummyControlDict_H
|
||||||
|
#define dummyControlDict_H
|
||||||
|
|
||||||
|
#include "dictionary.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
Class dummyControlDict Declaration
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
class dummyControlDict
|
||||||
|
:
|
||||||
|
public dictionary
|
||||||
|
{
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
TypeName("dummyControlDict");
|
||||||
|
|
||||||
|
|
||||||
|
// Constructors
|
||||||
|
|
||||||
|
//- Construct, creating the bare minimum controlDict
|
||||||
|
dummyControlDict();
|
||||||
|
|
||||||
|
//- Construct, reading the multiControlDict data from a file
|
||||||
|
explicit dummyControlDict(const fileName&);
|
||||||
|
|
||||||
|
//- Construct given the multiControlDict dictionary
|
||||||
|
explicit dummyControlDict(const dictionary&);
|
||||||
|
|
||||||
|
|
||||||
|
// Destructor
|
||||||
|
virtual ~dummyControlDict();
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
} // End namespace Foam
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
#endif
|
12
src/multiSolver/include/createMultiSolver.H
Normal file
12
src/multiSolver/include/createMultiSolver.H
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
word solverDomain;
|
||||||
|
|
||||||
|
multiSolver multiRun
|
||||||
|
(
|
||||||
|
multiSolver::multiControlDictName,
|
||||||
|
args.rootPath(),
|
||||||
|
args.caseName()
|
||||||
|
);
|
||||||
|
|
||||||
|
while (multiRun.run())
|
||||||
|
{ // While brace
|
||||||
|
{ // dummy brace
|
3
src/multiSolver/include/endMultiSolver.H
Normal file
3
src/multiSolver/include/endMultiSolver.H
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
} // previous solver domain goes out of scope
|
||||||
|
multiRun++;
|
||||||
|
} // end While loop
|
10
src/multiSolver/include/setSolverDomain.H
Normal file
10
src/multiSolver/include/setSolverDomain.H
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
} // previous solver domain goes out of scope
|
||||||
|
multiRun.setSolverDomain(solverDomain);
|
||||||
|
|
||||||
|
// Clear defines that may interfere with other solver domains
|
||||||
|
#undef createPhi_H
|
||||||
|
#undef createPhiV_H
|
||||||
|
#undef initContinuityErrs_H
|
||||||
|
|
||||||
|
if (multiRun.run())
|
||||||
|
{ // next solver domain comes into scope
|
1402
src/multiSolver/multiSolver/multiSolver.C
Normal file
1402
src/multiSolver/multiSolver/multiSolver.C
Normal file
File diff suppressed because it is too large
Load diff
562
src/multiSolver/multiSolver/multiSolver.H
Normal file
562
src/multiSolver/multiSolver/multiSolver.H
Normal file
|
@ -0,0 +1,562 @@
|
||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / 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::multiSolver
|
||||||
|
|
||||||
|
Description
|
||||||
|
Manages multiple solvers within one master-solver. Allows for multiple
|
||||||
|
definitions of time. Works by changing the case directory as required by
|
||||||
|
each solver.
|
||||||
|
|
||||||
|
SourceFiles
|
||||||
|
multiSolverI.H
|
||||||
|
multiSolver.C
|
||||||
|
multiSolverSetControls.C
|
||||||
|
multiSolverSetInitialSolverDomain.C
|
||||||
|
multiSolverSetNextSolverDomain.C
|
||||||
|
multiSolverTimeFunctions.C
|
||||||
|
|
||||||
|
Author
|
||||||
|
David L. F. Gaden
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef multiSolver_H
|
||||||
|
#define multiSolver_H
|
||||||
|
|
||||||
|
#include "Time.H"
|
||||||
|
#include "dummyControlDict.H"
|
||||||
|
#include "timeClusterList.H"
|
||||||
|
#include "IFstream.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
Class multiSolver Declaration
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
class multiSolver
|
||||||
|
{
|
||||||
|
|
||||||
|
// Private data
|
||||||
|
|
||||||
|
// A dummy controlDict, required to initialize multiDictRegistry
|
||||||
|
dummyControlDict dcd_;
|
||||||
|
|
||||||
|
// A mini-objectRegistry for the dictionaries - done this way to allow
|
||||||
|
// run-time modification of dictionaries
|
||||||
|
Time multiDictRegistry_;
|
||||||
|
|
||||||
|
// Main control dictionary for multiSolver
|
||||||
|
IOdictionary multiControlDict_;
|
||||||
|
|
||||||
|
// All multiDicts contained in the case directory
|
||||||
|
PtrList<IOdictionary> multiDicts_;
|
||||||
|
|
||||||
|
// Reference to multiSolverControl subdictionary in multiControlDict
|
||||||
|
dictionary& multiSolverControl_;
|
||||||
|
|
||||||
|
// Reference to solverDomains subdictionary in multiControlDict
|
||||||
|
dictionary& solverDomains_;
|
||||||
|
|
||||||
|
// Current solverDomain dictionary
|
||||||
|
dictionary currentSolverDomainDict_;
|
||||||
|
|
||||||
|
// List of all the solver domain prefixes
|
||||||
|
wordList prefixes_;
|
||||||
|
|
||||||
|
// True when the end condition has been met
|
||||||
|
bool finished_;
|
||||||
|
|
||||||
|
// True when superLoop++ just happened, but the previous solverDomain
|
||||||
|
// has not yet been saved (to prevent the first solverDomain from
|
||||||
|
// saving to the *next* superLoop.
|
||||||
|
bool noSaveSinceSuperLoopIncrement_;
|
||||||
|
|
||||||
|
// True if this is the lowest number on a local shared drive - parallel
|
||||||
|
// only.
|
||||||
|
bool manageLocalRoot_;
|
||||||
|
|
||||||
|
|
||||||
|
// Private member functions
|
||||||
|
|
||||||
|
// Set manageLocalRoot_ flags on all processors (parallel only)
|
||||||
|
void setUpParallel();
|
||||||
|
|
||||||
|
// Ensure all processors are synchronized (parallel only)
|
||||||
|
void synchronizeParallel() const;
|
||||||
|
|
||||||
|
// Load initial data and controls
|
||||||
|
// *** Located in multiSolverSetInitialSolverDomain.C ***
|
||||||
|
void setInitialSolverDomain(const word& solverDomainName);
|
||||||
|
|
||||||
|
// Load data and controls of a subsequent solver domain
|
||||||
|
// *** Located in multiSolverSetNextSolverDomain.C ***
|
||||||
|
void setNextSolverDomain(const word& solverDomainName);
|
||||||
|
|
||||||
|
// Sets controls from the multiSolverControl subdictionary in the
|
||||||
|
// multiControlDict
|
||||||
|
// *** Located in multiSolverSetControls.C ***
|
||||||
|
void setMultiSolverControls();
|
||||||
|
|
||||||
|
// Sets controls from the solverDomains subdictionary in the
|
||||||
|
// multiControlDict
|
||||||
|
// *** Located in multiSolverSetControls.C ***
|
||||||
|
void setSolverDomainControls(const word& solverDomainName);
|
||||||
|
|
||||||
|
// Use stopAt and finalStopAt settings to determine the endTime for
|
||||||
|
// the current solverDomain. Returns the controlDict's stopAt word,
|
||||||
|
// which may differ from that in multiControlDict. Sets finished_ to
|
||||||
|
// true if the end condition will be met.
|
||||||
|
word setLocalEndTime();
|
||||||
|
|
||||||
|
// Looks for case/multiSolver/solverDomain/initial/0. Fail if missing.
|
||||||
|
void checkTimeDirectories() const;
|
||||||
|
|
||||||
|
// Change all catalogued multiDicts to another solverDomain
|
||||||
|
void swapDictionaries(const word& solverDomainName);
|
||||||
|
|
||||||
|
// When setting up for a different solverDomain, the boundary
|
||||||
|
// conditions are allowed to change. This function copies all valid
|
||||||
|
// case/intoSolverDomain/inital/0 files, and overwrites the
|
||||||
|
// internalField with those found in the corresponding file in
|
||||||
|
// dataSourcePath. The result is placed in case/[time].
|
||||||
|
void swapBoundaryConditions
|
||||||
|
(
|
||||||
|
const fileName& dataSourcePath,
|
||||||
|
const word& intoSolverDomain
|
||||||
|
);
|
||||||
|
|
||||||
|
// Read multiDict files into the multiDictRegistry. Loads:
|
||||||
|
// - case/system/multi*
|
||||||
|
// - case/system/[local]/multi*, where [local] is anything
|
||||||
|
// - case/constant/multi*
|
||||||
|
// - case/constant/[local]/multi*
|
||||||
|
void readAllMultiDicts();
|
||||||
|
|
||||||
|
// Scan a directory for multi*; read them into the multiDictRegistry
|
||||||
|
void readMultiDictDirectory
|
||||||
|
(
|
||||||
|
const fileName& sourcePath,
|
||||||
|
const word& local = word::null
|
||||||
|
);
|
||||||
|
|
||||||
|
// Rereads modified dictionaries and sets the controls
|
||||||
|
void readIfModified();
|
||||||
|
|
||||||
|
// Converts a fileName with the naming convention:
|
||||||
|
// solverDomain@superLoop@globalOffset@fileName
|
||||||
|
// to a timeCluster
|
||||||
|
timeCluster parseConditionedFile
|
||||||
|
(
|
||||||
|
const word& pcFile,
|
||||||
|
const instant& inst
|
||||||
|
) const;
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
// multiSolverControl enumerations
|
||||||
|
|
||||||
|
//- Read initial data control options
|
||||||
|
enum initialStartFromControls
|
||||||
|
{
|
||||||
|
misFirstTime,
|
||||||
|
misFirstTimeInStartDomain,
|
||||||
|
misFirstTimeInStartDomainInStartSuperLoop,
|
||||||
|
misStartTime,
|
||||||
|
misStartTimeInStartDomain,
|
||||||
|
misStartTimeInStartDomainInStartSuperLoop,
|
||||||
|
misLatestTime,
|
||||||
|
misLatestTimeInStartDomain,
|
||||||
|
misLatestTimeInStartDomainInStartSuperLoop
|
||||||
|
};
|
||||||
|
|
||||||
|
//- Final stop at control options
|
||||||
|
enum finalStopAtControls
|
||||||
|
{
|
||||||
|
mfsEndTime,
|
||||||
|
mfsEndTimeInEndDomain,
|
||||||
|
mfsEndTimeInEndDomainInEndSuperLoop,
|
||||||
|
mfsEndSuperLoop,
|
||||||
|
mfsWriteNow,
|
||||||
|
mfsNoWriteNow,
|
||||||
|
mfsNextWrite
|
||||||
|
};
|
||||||
|
|
||||||
|
// solverDomains enumerations
|
||||||
|
|
||||||
|
//- Time value start from control options
|
||||||
|
enum startFromControls
|
||||||
|
{
|
||||||
|
mtsFirstTime,
|
||||||
|
mtsStartTime,
|
||||||
|
mtsLatestTimeThisDomain,
|
||||||
|
mtsLatestTimeAllDomains
|
||||||
|
};
|
||||||
|
|
||||||
|
//- Stop at control options
|
||||||
|
enum stopAtControls
|
||||||
|
{
|
||||||
|
msaEndTime,
|
||||||
|
msaNoWriteNow,
|
||||||
|
msaWriteNow,
|
||||||
|
msaNextWrite,
|
||||||
|
msaIterations,
|
||||||
|
msaSolverSignal,
|
||||||
|
msaElapsedTime
|
||||||
|
};
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
// multiSolverControl data
|
||||||
|
|
||||||
|
label superLoop_;
|
||||||
|
|
||||||
|
word currentSolverDomain_;
|
||||||
|
|
||||||
|
static const NamedEnum<initialStartFromControls, 9>
|
||||||
|
initialStartFromControlsNames_;
|
||||||
|
initialStartFromControls initialStartFrom_;
|
||||||
|
|
||||||
|
scalar initialStartTime_;
|
||||||
|
|
||||||
|
word startDomain_;
|
||||||
|
|
||||||
|
label startSuperLoop_;
|
||||||
|
|
||||||
|
static const NamedEnum<finalStopAtControls, 7>
|
||||||
|
finalStopAtControlsNames_;
|
||||||
|
finalStopAtControls finalStopAt_;
|
||||||
|
|
||||||
|
word endDomain_;
|
||||||
|
|
||||||
|
scalar finalEndTime_;
|
||||||
|
|
||||||
|
label endSuperLoop_;
|
||||||
|
|
||||||
|
bool multiDictsRunTimeModifiable_;
|
||||||
|
|
||||||
|
scalar globalTimeOffset_;
|
||||||
|
|
||||||
|
|
||||||
|
// solverDomains data
|
||||||
|
// This data is transient, changing between solver domains
|
||||||
|
|
||||||
|
static const NamedEnum<startFromControls, 4>
|
||||||
|
startFromControlsNames_;
|
||||||
|
startFromControls startFrom_;
|
||||||
|
|
||||||
|
scalar startTime_;
|
||||||
|
|
||||||
|
static const NamedEnum<stopAtControls, 7> stopAtControlsNames_;
|
||||||
|
stopAtControls stopAt_;
|
||||||
|
|
||||||
|
scalar endTime_;
|
||||||
|
|
||||||
|
label purgeWriteSuperLoops_;
|
||||||
|
|
||||||
|
scalar deltaT_;
|
||||||
|
|
||||||
|
label iterations_;
|
||||||
|
|
||||||
|
scalar elapsedTime_;
|
||||||
|
|
||||||
|
wordList storeFields_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
TypeName("multiSolver");
|
||||||
|
|
||||||
|
//- The default multiSolver dictionary name
|
||||||
|
static word multiControlDictName;
|
||||||
|
|
||||||
|
/* Not implemented yet
|
||||||
|
//- Indicates whether the 'solverSignal' option for the finalStopAt setting
|
||||||
|
// in the multiControlDict is permitted. Default false. Set this to true
|
||||||
|
// in the global space of a solver that does support solverSignal.
|
||||||
|
static bool supportsSolverSignal;
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Constructors
|
||||||
|
|
||||||
|
//- Construct given the multiControlDict
|
||||||
|
multiSolver
|
||||||
|
(
|
||||||
|
const dictionary& dict,
|
||||||
|
const fileName& rootPath,
|
||||||
|
const fileName& caseName,
|
||||||
|
const word& systemName = "system",
|
||||||
|
const word& constantName = "constant"
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Construct reading the multiControlDict from file
|
||||||
|
multiSolver
|
||||||
|
(
|
||||||
|
const word& multiControlDictName,
|
||||||
|
const fileName& rootPath,
|
||||||
|
const fileName& caseName,
|
||||||
|
const word& systemName = "system",
|
||||||
|
const word& constantName = "constant"
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
// Destructor
|
||||||
|
virtual ~multiSolver();
|
||||||
|
|
||||||
|
|
||||||
|
// Member functions
|
||||||
|
|
||||||
|
// Access
|
||||||
|
|
||||||
|
// Database
|
||||||
|
|
||||||
|
inline const Time& multiDictRegistry() const;
|
||||||
|
|
||||||
|
inline const IOdictionary multiControlDict() const;
|
||||||
|
|
||||||
|
|
||||||
|
// multiSolverControl data
|
||||||
|
|
||||||
|
inline const label& superLoop() const;
|
||||||
|
|
||||||
|
inline const word& currentSolverDomain() const;
|
||||||
|
|
||||||
|
inline const initialStartFromControls& initialStartFrom() const;
|
||||||
|
|
||||||
|
inline const word& startDomain() const;
|
||||||
|
|
||||||
|
inline const scalar& initialStartTime() const;
|
||||||
|
|
||||||
|
inline const finalStopAtControls& finalStopAt() const;
|
||||||
|
|
||||||
|
inline const word& endDomain() const;
|
||||||
|
|
||||||
|
inline const scalar& finalEndTime() const;
|
||||||
|
|
||||||
|
inline const label& startSuperLoop() const;
|
||||||
|
|
||||||
|
inline const label& endSuperLoop() const;
|
||||||
|
|
||||||
|
inline const bool& multiDictsRunTimeModifiable() const;
|
||||||
|
|
||||||
|
inline const scalar& globalTimeOffset() const;
|
||||||
|
|
||||||
|
// Write permission
|
||||||
|
inline scalar& globalTimeOffset();
|
||||||
|
|
||||||
|
// solverDomains data
|
||||||
|
inline const startFromControls& startFrom() const;
|
||||||
|
|
||||||
|
inline const stopAtControls& stopAt() const;
|
||||||
|
|
||||||
|
inline const scalar& startTime() const;
|
||||||
|
|
||||||
|
inline const scalar& endTime() const;
|
||||||
|
|
||||||
|
inline const label& iterations() const;
|
||||||
|
|
||||||
|
inline const scalar& elapsedTime() const;
|
||||||
|
|
||||||
|
inline const wordList& storeFields() const;
|
||||||
|
|
||||||
|
inline const label& purgeWriteSuperLoops() const;
|
||||||
|
|
||||||
|
inline const scalar& deltaT() const;
|
||||||
|
|
||||||
|
|
||||||
|
// Solver (and pre/post-processor) interface functions
|
||||||
|
|
||||||
|
// Pre-condition the directory for decomposePar or reconstructPar
|
||||||
|
void preCondition(const word& processor = word::null);
|
||||||
|
|
||||||
|
// Post-condition the directory after decomposePar or
|
||||||
|
// reconstructPar
|
||||||
|
void postCondition(const word& processor = word::null);
|
||||||
|
|
||||||
|
// Switch to another solver domain
|
||||||
|
void setSolverDomain(const word& solverDomainName);
|
||||||
|
|
||||||
|
// Switch to another solver domain for post-processing only
|
||||||
|
void setSolverDomainPostProcessing(const word& solverDomainName);
|
||||||
|
|
||||||
|
// Stop the run at the next setSolverDomain
|
||||||
|
inline void setFinished();
|
||||||
|
|
||||||
|
// Increment the superLoop (prefix)
|
||||||
|
multiSolver& operator++();
|
||||||
|
|
||||||
|
// Increment the superLoop (postfix)
|
||||||
|
multiSolver& operator++(int);
|
||||||
|
|
||||||
|
|
||||||
|
// Check
|
||||||
|
|
||||||
|
//- Return true if run should continue
|
||||||
|
bool run() const;
|
||||||
|
|
||||||
|
//- Return true if end of run
|
||||||
|
bool end() const;
|
||||||
|
|
||||||
|
|
||||||
|
// Time functions
|
||||||
|
// The multiSolver time directory structure should have the form:
|
||||||
|
// case
|
||||||
|
// '-multiSolver
|
||||||
|
// |-prefix1 {solverDomain}
|
||||||
|
// | |-initial {initial directory, superLoop -1}
|
||||||
|
// | |-0 {superLoop}
|
||||||
|
// | |-1 {superLoop}
|
||||||
|
// | | '-multiSolverTime {auto-generated dictionary}
|
||||||
|
// | '-2, etc..
|
||||||
|
// |-prefix2, etc..
|
||||||
|
//
|
||||||
|
// *** All time functions are located in ***
|
||||||
|
// *** multiSolverTimeFunctions.C ***
|
||||||
|
|
||||||
|
// Create a list of all superLoops in a directory, (usually in
|
||||||
|
// case/prefix). Only looks for integer directory names, does not
|
||||||
|
// check for valid time subdirectories.
|
||||||
|
static labelList findSuperLoops(const fileName& path);
|
||||||
|
|
||||||
|
// Find the closest global time to a given value in a
|
||||||
|
// timeClusterList. Assumes timeClusters do not overlap global time
|
||||||
|
// values (as they shouldn't). If exact is true, this function
|
||||||
|
// throws a FatalError when no exact match is found.
|
||||||
|
static timeCluster findClosestGlobalTime
|
||||||
|
(
|
||||||
|
const scalar value,
|
||||||
|
const timeClusterList& tcl,
|
||||||
|
const bool& exact = false
|
||||||
|
);
|
||||||
|
|
||||||
|
// Find the closest local time to a given value in a
|
||||||
|
// timeClusterList. Unlike global times, local times can overlap.
|
||||||
|
// If overlaps exist, it uses only the latest superloop. If exact
|
||||||
|
// is true, this function throws a FatalError when no exact match
|
||||||
|
// is found.
|
||||||
|
static timeCluster findClosestLocalTime
|
||||||
|
(
|
||||||
|
const scalar value,
|
||||||
|
const timeClusterList& tcl,
|
||||||
|
const bool& exact = false
|
||||||
|
);
|
||||||
|
|
||||||
|
// Find the latest global time
|
||||||
|
static timeCluster findLatestGlobalTime
|
||||||
|
(
|
||||||
|
const timeClusterList& tcl
|
||||||
|
);
|
||||||
|
|
||||||
|
// Find the latest global time
|
||||||
|
static timeCluster findLatestLocalTime
|
||||||
|
(
|
||||||
|
const timeClusterList& tcl
|
||||||
|
);
|
||||||
|
|
||||||
|
// Find the path to a specific entry in a time cluster
|
||||||
|
fileName findInstancePath
|
||||||
|
(
|
||||||
|
const timeCluster& tc,
|
||||||
|
const label& index
|
||||||
|
) const;
|
||||||
|
|
||||||
|
// Find the largest superLoop
|
||||||
|
static label findMaxSuperLoopValue(const timeClusterList& tcl);
|
||||||
|
|
||||||
|
// Find the timeClusterList index for the timeClusterList that has
|
||||||
|
// the largest superLoop
|
||||||
|
static labelList findMaxSuperLoopIndices(const timeClusterList& tcl);
|
||||||
|
|
||||||
|
// Checks if any of the time ranges overlap one another in a
|
||||||
|
// timeClusterList. (If startTime = previous end, this is okay.)
|
||||||
|
// True means they do not overlap.
|
||||||
|
static bool nonOverlapping
|
||||||
|
(
|
||||||
|
const timeClusterList& tcl,
|
||||||
|
const bool useGlobalTime = false
|
||||||
|
);
|
||||||
|
|
||||||
|
// Maps the time directories in a single superLoop directory
|
||||||
|
// Include a processor name, and it uses the processorN directory
|
||||||
|
timeCluster readSuperLoopTimes
|
||||||
|
(
|
||||||
|
const word& solverDomain,
|
||||||
|
const label superLoop,
|
||||||
|
const word& processor = word::null
|
||||||
|
) const;
|
||||||
|
|
||||||
|
// Maps the time directories in a single solverDomain
|
||||||
|
// Include a processor name, and it uses the processorN directory
|
||||||
|
timeClusterList readSolverDomainTimes
|
||||||
|
(
|
||||||
|
const word& solverDomain,
|
||||||
|
const word processor = word::null
|
||||||
|
) const;
|
||||||
|
|
||||||
|
// Create a snapshot of all the multiSolver time directories
|
||||||
|
// Give it a processor name, and it searches instead in the
|
||||||
|
// processor directory
|
||||||
|
timeClusterList readAllTimes
|
||||||
|
(
|
||||||
|
const word processor = word::null
|
||||||
|
) const;
|
||||||
|
|
||||||
|
// Move or copy all output time directories that are catalogued by
|
||||||
|
// a timeClusterList to case/[timeValue] format. Returns false if
|
||||||
|
// time values overlap when forced to useGlobalTime.
|
||||||
|
// loadStoreFields will copy storeFields into every time folder
|
||||||
|
// even though they do not change.
|
||||||
|
bool loadTimeClusterList
|
||||||
|
(
|
||||||
|
const timeClusterList& tcl,
|
||||||
|
const bool useGlobalTime = true,
|
||||||
|
const bool loadStoreFields = true
|
||||||
|
) const;
|
||||||
|
|
||||||
|
// Move all the time directories from sourcePath to archivePath
|
||||||
|
static void archiveTimeDirs
|
||||||
|
(
|
||||||
|
const fileName& sourcePath,
|
||||||
|
const fileName& archivePath,
|
||||||
|
const label& purgeWrite
|
||||||
|
);
|
||||||
|
|
||||||
|
// Delete all time directories in path, do not delete "constant"
|
||||||
|
static void purgeTimeDirs(const fileName& path);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
} // End namespace Foam
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
#include "multiSolverI.H"
|
||||||
|
|
||||||
|
#endif
|
182
src/multiSolver/multiSolver/multiSolverI.H
Normal file
182
src/multiSolver/multiSolver/multiSolverI.H
Normal file
|
@ -0,0 +1,182 @@
|
||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / 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
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
|
||||||
|
inline const Time& multiSolver::multiDictRegistry() const
|
||||||
|
{
|
||||||
|
return multiDictRegistry_;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline const IOdictionary multiSolver::multiControlDict() const
|
||||||
|
{
|
||||||
|
return multiControlDict_;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline const label& multiSolver::superLoop() const
|
||||||
|
{
|
||||||
|
return superLoop_;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline const word& multiSolver::currentSolverDomain() const
|
||||||
|
{
|
||||||
|
return currentSolverDomain_;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline const multiSolver::initialStartFromControls& multiSolver::initialStartFrom() const
|
||||||
|
{
|
||||||
|
return initialStartFrom_;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline const word& multiSolver::startDomain() const
|
||||||
|
{
|
||||||
|
return startDomain_;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline const scalar& multiSolver::initialStartTime() const
|
||||||
|
{
|
||||||
|
return initialStartTime_;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline const multiSolver::finalStopAtControls& multiSolver::finalStopAt() const
|
||||||
|
{
|
||||||
|
return finalStopAt_;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline const word& multiSolver::endDomain() const
|
||||||
|
{
|
||||||
|
return endDomain_;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline const scalar& multiSolver::finalEndTime() const
|
||||||
|
{
|
||||||
|
return finalEndTime_;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline const label& multiSolver::startSuperLoop() const
|
||||||
|
{
|
||||||
|
return startSuperLoop_;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline const label& multiSolver::endSuperLoop() const
|
||||||
|
{
|
||||||
|
return endSuperLoop_;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline const bool& multiSolver::multiDictsRunTimeModifiable() const
|
||||||
|
{
|
||||||
|
return multiDictsRunTimeModifiable_;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline const scalar& multiSolver::globalTimeOffset() const
|
||||||
|
{
|
||||||
|
return globalTimeOffset_;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline scalar& multiSolver::globalTimeOffset()
|
||||||
|
{
|
||||||
|
return globalTimeOffset_;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline const multiSolver::startFromControls& multiSolver::startFrom() const
|
||||||
|
{
|
||||||
|
return startFrom_;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const multiSolver::stopAtControls& multiSolver::stopAt() const
|
||||||
|
{
|
||||||
|
return stopAt_;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline const scalar& multiSolver::startTime() const
|
||||||
|
{
|
||||||
|
return startTime_;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const scalar& multiSolver::endTime() const
|
||||||
|
{
|
||||||
|
return endTime_;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline const label& multiSolver::iterations() const
|
||||||
|
{
|
||||||
|
return iterations_;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline const scalar& multiSolver::elapsedTime() const
|
||||||
|
{
|
||||||
|
return elapsedTime_;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline const wordList& multiSolver::storeFields() const
|
||||||
|
{
|
||||||
|
return storeFields_;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline const label& multiSolver::purgeWriteSuperLoops() const
|
||||||
|
{
|
||||||
|
return purgeWriteSuperLoops_;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline const scalar& multiSolver::deltaT() const
|
||||||
|
{
|
||||||
|
return deltaT_;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::multiSolver::setFinished()
|
||||||
|
{
|
||||||
|
finished_ = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // End namespace Foam
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
39
src/multiSolver/multiSolver/multiSolverInit.H
Normal file
39
src/multiSolver/multiSolver/multiSolverInit.H
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
// Common elements in the constructor initialization list for multiSolver
|
||||||
|
|
||||||
|
multiDicts_(NULL),
|
||||||
|
|
||||||
|
multiSolverControl_(multiControlDict_.subDict("multiSolverControl")),
|
||||||
|
solverDomains_(multiControlDict_.subDict("solverDomains")),
|
||||||
|
currentSolverDomainDict_(),
|
||||||
|
prefixes_(solverDomains_.toc()),
|
||||||
|
finished_(false),
|
||||||
|
noSaveSinceSuperLoopIncrement_(false),
|
||||||
|
manageLocalRoot_(false),
|
||||||
|
|
||||||
|
superLoop_(0),
|
||||||
|
currentSolverDomain_("default"),
|
||||||
|
|
||||||
|
initialStartFrom_(misLatestTime),
|
||||||
|
// startDomain_,
|
||||||
|
initialStartTime_(0),
|
||||||
|
startSuperLoop_(0),
|
||||||
|
finalStopAt_(mfsEndTime),
|
||||||
|
// endDomain_,
|
||||||
|
finalEndTime_(0),
|
||||||
|
|
||||||
|
endSuperLoop_(0),
|
||||||
|
|
||||||
|
multiDictsRunTimeModifiable_(true),
|
||||||
|
|
||||||
|
globalTimeOffset_(0),
|
||||||
|
|
||||||
|
purgeWriteSuperLoops_(prefixes_.size()),
|
||||||
|
|
||||||
|
// timeValueStartFrom_,
|
||||||
|
// scalar startTime_,
|
||||||
|
// stopAtControls stopAt_,
|
||||||
|
// scalar endTime_,
|
||||||
|
// label endIterations_
|
||||||
|
|
||||||
|
storeFields_(0)
|
||||||
|
|
359
src/multiSolver/multiSolver/multiSolverSetControls.C
Normal file
359
src/multiSolver/multiSolver/multiSolverSetControls.C
Normal file
|
@ -0,0 +1,359 @@
|
||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / 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
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::multiSolver::setMultiSolverControls()
|
||||||
|
{
|
||||||
|
initialStartFrom_ = misLatestTime;
|
||||||
|
if (multiSolverControl_.found("initialStartFrom"))
|
||||||
|
{
|
||||||
|
initialStartFrom_ = initialStartFromControlsNames_.read
|
||||||
|
(
|
||||||
|
multiSolverControl_.lookup("initialStartFrom")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (multiSolverControl_.found("startTime"))
|
||||||
|
{
|
||||||
|
initialStartTime_ = readScalar(multiSolverControl_.lookup("startTime"));
|
||||||
|
if (initialStartTime_ < 0)
|
||||||
|
{
|
||||||
|
FatalErrorIn("multiSolver::setMultiSolverControls")
|
||||||
|
<< "'startTime' in multiControlDict/multiSolverControl cannot "
|
||||||
|
<< "be negative."
|
||||||
|
<< abort(FatalError);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if
|
||||||
|
(
|
||||||
|
(initialStartFrom_ == misStartTime)
|
||||||
|
|| (initialStartFrom_ == misStartTimeInStartDomain)
|
||||||
|
|| (initialStartFrom_ == misStartTimeInStartDomainInStartSuperLoop)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
FatalIOErrorIn
|
||||||
|
(
|
||||||
|
"multiSolver::setMultiSolverControls", multiSolverControl_
|
||||||
|
)
|
||||||
|
<< "'startTime' is required in multiControlDict/multiSolverControl "
|
||||||
|
<< "if 'initialStartFrom' is set to 'startTime', "
|
||||||
|
<< "'startTimeInStartDomain', or "
|
||||||
|
<< "'startTimeInStartDomainInStartStuperLoop'"
|
||||||
|
<< exit(FatalIOError);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (multiSolverControl_.found("startDomain"))
|
||||||
|
{
|
||||||
|
startDomain_ = word(multiSolverControl_.lookup("startDomain"));
|
||||||
|
}
|
||||||
|
else if
|
||||||
|
(
|
||||||
|
(initialStartFrom_ == misFirstTimeInStartDomain)
|
||||||
|
|| (initialStartFrom_ == misFirstTimeInStartDomainInStartSuperLoop)
|
||||||
|
|| (initialStartFrom_ == misStartTimeInStartDomain)
|
||||||
|
|| (initialStartFrom_ == misStartTimeInStartDomainInStartSuperLoop)
|
||||||
|
|| (initialStartFrom_ == misLatestTimeInStartDomain)
|
||||||
|
|| (initialStartFrom_ == misLatestTimeInStartDomainInStartSuperLoop)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
FatalIOErrorIn("multiSolver::setMultiSolverControls", multiSolverControl_)
|
||||||
|
<< "'startDomain' is required in "
|
||||||
|
<< "multiControlDict/multiSolverControl if 'initialStartFrom' is "
|
||||||
|
<< "set to 'firstTimeInStartDomain', "
|
||||||
|
<< "'firstTimeInStartDomainInStartSuperLoop', "
|
||||||
|
<< "'startTimeInStartDomain', "
|
||||||
|
<< "'startTimeInStartDomainInStartSuperLoop', "
|
||||||
|
<< "'latestTimeInStartDomain', or "
|
||||||
|
<< "'latestTimeInStartDomainInStartSuperLoop'."
|
||||||
|
<< abort(FatalError);
|
||||||
|
}
|
||||||
|
|
||||||
|
finalStopAt_ = mfsEndTime;
|
||||||
|
if (multiSolverControl_.found("finalStopAt"))
|
||||||
|
{
|
||||||
|
finalStopAt_ = finalStopAtControlsNames_.read
|
||||||
|
(
|
||||||
|
multiSolverControl_.lookup("finalStopAt")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (multiSolverControl_.found("endDomain"))
|
||||||
|
{
|
||||||
|
endDomain_ = word(multiSolverControl_.lookup("endDomain"));
|
||||||
|
}
|
||||||
|
else if
|
||||||
|
(
|
||||||
|
(finalStopAt_ == mfsEndTimeInEndDomain)
|
||||||
|
|| (finalStopAt_ == mfsEndTimeInEndDomainInEndSuperLoop)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
FatalErrorIn("multiSolver::setMultiSolverControls")
|
||||||
|
<< "endTime is required in multiControlDict/multiSolverControl if "
|
||||||
|
<< "finalStopAt is set to 'endTimeInEndDomain', or "
|
||||||
|
<< "'endTimeInEndDomainInEndSuperLoop'."
|
||||||
|
<< abort(FatalError);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (multiSolverControl_.found("endTime"))
|
||||||
|
{
|
||||||
|
finalEndTime_ =
|
||||||
|
readScalar(multiSolverControl_.lookup("endTime"));
|
||||||
|
}
|
||||||
|
else if
|
||||||
|
(
|
||||||
|
(finalStopAt_ == mfsEndTime)
|
||||||
|
|| (finalStopAt_ == mfsEndTimeInEndDomain)
|
||||||
|
|| (finalStopAt_ == mfsEndTimeInEndDomainInEndSuperLoop)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
FatalErrorIn("multiSolver::setMultiSolverControls")
|
||||||
|
<< "'endTime' is required in "
|
||||||
|
<< "multiControlDict/multiSolverControl if 'finalStopAt' is set to "
|
||||||
|
<< "'endTime', 'endTimeInEndDomain', or "
|
||||||
|
<< "'endTimeInEndDomainInEndSuperLoop'."
|
||||||
|
<< abort(FatalError);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (multiSolverControl_.found("startSuperLoop"))
|
||||||
|
{
|
||||||
|
startSuperLoop_ =
|
||||||
|
readLabel(multiSolverControl_.lookup("startSuperLoop"));
|
||||||
|
}
|
||||||
|
else if
|
||||||
|
(
|
||||||
|
(initialStartFrom_ == misFirstTimeInStartDomainInStartSuperLoop)
|
||||||
|
|| (initialStartFrom_ == misStartTimeInStartDomainInStartSuperLoop)
|
||||||
|
|| (initialStartFrom_ == misLatestTimeInStartDomainInStartSuperLoop)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
FatalErrorIn("multiSolver::setMultiSolverControls")
|
||||||
|
<< "'startSuperLoop' is required in "
|
||||||
|
<< "multiControlDict/multiSolverControl if 'initialStartFrom' is "
|
||||||
|
<< "set to 'firstTimeInStartDomainInSuperLoop', "
|
||||||
|
<< "'startTimeInStartDomainInStartSuperLoop', or "
|
||||||
|
<< "'latestTimeInStartDomainInStartSuperLoop'."
|
||||||
|
<< abort(FatalError);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (multiSolverControl_.found("endSuperLoop"))
|
||||||
|
{
|
||||||
|
endSuperLoop_ =
|
||||||
|
readLabel(multiSolverControl_.lookup("endSuperLoop"));
|
||||||
|
}
|
||||||
|
else if
|
||||||
|
(
|
||||||
|
(finalStopAt_ == mfsEndSuperLoop)
|
||||||
|
|| (finalStopAt_ == mfsEndTimeInEndDomainInEndSuperLoop)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
FatalErrorIn("multiSolver::setMultiSolverControls")
|
||||||
|
<< "'endSuperLoops' is required in "
|
||||||
|
<< "multiControlDict/multiSolverControl if 'finalStopAt' is set to "
|
||||||
|
<< "'endSuperLoop' or 'endTimeInEndDomainInEndSuperLoop'."
|
||||||
|
<< abort(FatalError);
|
||||||
|
}
|
||||||
|
|
||||||
|
multiDictsRunTimeModifiable_ = true;
|
||||||
|
if (multiSolverControl_.found("multiDictsRunTimeModifiable"))
|
||||||
|
{
|
||||||
|
multiDictsRunTimeModifiable_ =
|
||||||
|
multiSolverControl_.lookup("multiDictsRunTimeModifiable");
|
||||||
|
}
|
||||||
|
|
||||||
|
prefixes_.clear();
|
||||||
|
prefixes_ = solverDomains_.toc();
|
||||||
|
if
|
||||||
|
(
|
||||||
|
(prefixes_.size() == 0)
|
||||||
|
|| ((prefixes_.size() == 1) && (prefixes_[0] == "default"))
|
||||||
|
)
|
||||||
|
{
|
||||||
|
FatalErrorIn("multiSolver::setMultiSolverControls")
|
||||||
|
<< "No solver domains found in multiControlDict. Expecting "
|
||||||
|
<< "subdictionary solverDomains to contain at least one entry "
|
||||||
|
<< "other than 'default'."
|
||||||
|
<< abort(FatalError);
|
||||||
|
}
|
||||||
|
|
||||||
|
dictionary solverDomainsDefault
|
||||||
|
(
|
||||||
|
solverDomains_.found("default")
|
||||||
|
? solverDomains_.subDict("default")
|
||||||
|
: dictionary()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::multiSolver::setSolverDomainControls(const word& solverDomainName)
|
||||||
|
{
|
||||||
|
currentSolverDomainDict_.clear();
|
||||||
|
if (solverDomains_.found("default"))
|
||||||
|
{
|
||||||
|
currentSolverDomainDict_.merge(solverDomains_.subDict("default"));
|
||||||
|
}
|
||||||
|
currentSolverDomainDict_.merge(solverDomains_.subDict(solverDomainName));
|
||||||
|
|
||||||
|
startFrom_ = mtsLatestTimeAllDomains;
|
||||||
|
if (currentSolverDomainDict_.found("startFrom"))
|
||||||
|
{
|
||||||
|
startFrom_ = startFromControlsNames_.read
|
||||||
|
(
|
||||||
|
currentSolverDomainDict_.lookup("startFrom")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentSolverDomainDict_.found("startTime"))
|
||||||
|
{
|
||||||
|
startTime_ = readScalar(currentSolverDomainDict_.lookup("startTime"));
|
||||||
|
if (startTime_ < 0)
|
||||||
|
{
|
||||||
|
FatalErrorIn("multiSolver::setSolverDomainControls")
|
||||||
|
<< "'startTime' in multiControlDict/solverDomains/"
|
||||||
|
<< solverDomainName << " cannot be negative."
|
||||||
|
<< abort(FatalError);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (startFrom_ == mtsStartTime)
|
||||||
|
{
|
||||||
|
FatalErrorIn("multiSolver::setSolverDomainControls")
|
||||||
|
<< "'startTime' not defined in solverDomain '" << solverDomainName
|
||||||
|
<< "' or 'default'. startTime is required when startFrom "
|
||||||
|
<< "is set to 'startTime'."
|
||||||
|
<< abort(FatalError);
|
||||||
|
}
|
||||||
|
|
||||||
|
stopAt_ = msaEndTime;
|
||||||
|
if (currentSolverDomainDict_.found("stopAt"))
|
||||||
|
{
|
||||||
|
stopAt_ = stopAtControlsNames_.read
|
||||||
|
(
|
||||||
|
currentSolverDomainDict_.lookup("stopAt")
|
||||||
|
);
|
||||||
|
if
|
||||||
|
(
|
||||||
|
(stopAt_ == msaIterations)
|
||||||
|
&& (currentSolverDomainDict_.found("adjustTimeStep"))
|
||||||
|
&& (
|
||||||
|
readBool(currentSolverDomainDict_.lookup
|
||||||
|
("adjustTimeStep")) == true
|
||||||
|
)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
FatalErrorIn("multiSolver::setSolverDomainControls")
|
||||||
|
<< "'stopAt' in multiControlDict/sovlerDomains cannot be set "
|
||||||
|
<< "to 'iterations' when 'adjustTimeStep' is 'true'."
|
||||||
|
<< abort(FatalError);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
endTime_ = 0;
|
||||||
|
if (currentSolverDomainDict_.found("endTime"))
|
||||||
|
{
|
||||||
|
endTime_ = readScalar(currentSolverDomainDict_.lookup("endTime"));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentSolverDomainDict_.found("iterations"))
|
||||||
|
{
|
||||||
|
iterations_ = readLabel
|
||||||
|
(
|
||||||
|
currentSolverDomainDict_.lookup("iterations")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else if (stopAt_ == msaIterations)
|
||||||
|
{
|
||||||
|
FatalErrorIn("multiSolver::setSolverDomainControls")
|
||||||
|
<< "'iterations' not defined in solverDomain '"
|
||||||
|
<< solverDomainName << "' or 'default'. iterations is required "
|
||||||
|
<< "when stopAt is set to iterations."
|
||||||
|
<< abort(FatalError);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentSolverDomainDict_.found("elapsedTime"))
|
||||||
|
{
|
||||||
|
elapsedTime_ = readScalar(currentSolverDomainDict_.lookup("elapsedTime"));
|
||||||
|
}
|
||||||
|
else if (stopAt_ == msaElapsedTime)
|
||||||
|
{
|
||||||
|
FatalErrorIn("multiSolver::setSolverDomainControls")
|
||||||
|
<< "'elapsedTime' not defined in solverDomain '"
|
||||||
|
<< solverDomainName << "' or 'default'. elapsedTime is required "
|
||||||
|
<< "when stopAt is set to elapsedTime."
|
||||||
|
<< abort(FatalError);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentSolverDomainDict_.found("storeFields"))
|
||||||
|
{
|
||||||
|
storeFields_ = wordList
|
||||||
|
(
|
||||||
|
currentSolverDomainDict_.lookup("storeFields")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
purgeWriteSuperLoops_ = 0;
|
||||||
|
if (currentSolverDomainDict_.found("purgeWriteSuperLoops"))
|
||||||
|
{
|
||||||
|
purgeWriteSuperLoops_ = readLabel
|
||||||
|
(
|
||||||
|
currentSolverDomainDict_.lookup("purgeWriteSuperLoops")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentSolverDomainDict_.found("deltaT"))
|
||||||
|
{
|
||||||
|
deltaT_ = readScalar
|
||||||
|
(
|
||||||
|
currentSolverDomainDict_.lookup("deltaT")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
FatalErrorIn("multiSolver::setSolverDomainControls")
|
||||||
|
<< "'deltaT' not defined in solverDomain '"
|
||||||
|
<< solverDomainName << "' or 'default'. deltaT is required."
|
||||||
|
<< abort(FatalError);
|
||||||
|
}
|
||||||
|
|
||||||
|
if
|
||||||
|
(
|
||||||
|
currentSolverDomainDict_.found("timeFormat")
|
||||||
|
|| currentSolverDomainDict_.found("timePrecision")
|
||||||
|
)
|
||||||
|
{
|
||||||
|
WarningIn("multiSolver::setSolverDomainControls")
|
||||||
|
<< "Dictionary entry 'timeFormat' or 'timePrecision' found in "
|
||||||
|
<< "multiControlDict/solverDomain subdictionaries and will be "
|
||||||
|
<< "ignored. This setting must be applied universally in "
|
||||||
|
<< "multiControlDict/multiSolverControl."
|
||||||
|
<< endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
265
src/multiSolver/multiSolver/multiSolverSetInitialSolverDomain.C
Normal file
265
src/multiSolver/multiSolver/multiSolverSetInitialSolverDomain.C
Normal file
|
@ -0,0 +1,265 @@
|
||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / 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
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::multiSolver::setInitialSolverDomain(const word& solverDomainName)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (!solverDomains_.found(solverDomainName))
|
||||||
|
{
|
||||||
|
FatalErrorIn("multiSolver::setInitialSolverDomain")
|
||||||
|
<< "Initial solverDomainName '" << solverDomainName << "' does"
|
||||||
|
<< " not exist in multiSolver dictionary. Found entries are: "
|
||||||
|
<< solverDomains_.toc()
|
||||||
|
<< abort(FatalError);
|
||||||
|
}
|
||||||
|
|
||||||
|
currentSolverDomain_ = solverDomainName;
|
||||||
|
|
||||||
|
setSolverDomainControls(currentSolverDomain_);
|
||||||
|
|
||||||
|
// Purge all time directories from case directory root
|
||||||
|
purgeTimeDirs(multiDictRegistry_.path());
|
||||||
|
|
||||||
|
// Read initial settings and determine data source (from which path the
|
||||||
|
// initial data is copied, the starting superLoop_, and the current
|
||||||
|
// globalTime (used to determine globalOffset). Rules that are applied:
|
||||||
|
//
|
||||||
|
// 1. superLoop_ = data source superLoop
|
||||||
|
// a. unless data source solverDomain != currentSolverDomain_, in
|
||||||
|
// which case, superLoop_ = data source superLoop + 1
|
||||||
|
// 2. globalTime = data source globalTime. globalTime does not increment
|
||||||
|
// when swapping solver domains.
|
||||||
|
// 3. startTime = data source local time
|
||||||
|
// a. unless data source solverDomain != currentSolverDomain_, in
|
||||||
|
// which case, startTime is dictated by the solverDomains
|
||||||
|
// subdictionary.
|
||||||
|
// 4. endTime is determined by the solverDomains subdictionary
|
||||||
|
// a. unless the finalStopAt trumps it
|
||||||
|
timeCluster tcSource;
|
||||||
|
switch (initialStartFrom_)
|
||||||
|
{
|
||||||
|
case misFirstTime:
|
||||||
|
tcSource = findClosestGlobalTime
|
||||||
|
(
|
||||||
|
0, readSuperLoopTimes(currentSolverDomain_, -1)
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
case misFirstTimeInStartDomain:
|
||||||
|
tcSource = findClosestGlobalTime
|
||||||
|
(
|
||||||
|
0, readSuperLoopTimes(startDomain_, -1)
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
case misFirstTimeInStartDomainInStartSuperLoop:
|
||||||
|
tcSource = findClosestGlobalTime
|
||||||
|
(
|
||||||
|
0, readSuperLoopTimes(startDomain_, startSuperLoop_)
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
case misStartTime:
|
||||||
|
if (initialStartTime_ == 0)
|
||||||
|
{
|
||||||
|
tcSource = findClosestGlobalTime
|
||||||
|
(
|
||||||
|
initialStartTime_,
|
||||||
|
readSuperLoopTimes(currentSolverDomain_, -1)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
tcSource = findClosestGlobalTime
|
||||||
|
(
|
||||||
|
initialStartTime_, readAllTimes()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case misStartTimeInStartDomain:
|
||||||
|
tcSource = findClosestLocalTime
|
||||||
|
(
|
||||||
|
initialStartTime_, readSolverDomainTimes(startDomain_)
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
case misStartTimeInStartDomainInStartSuperLoop:
|
||||||
|
tcSource = findClosestLocalTime
|
||||||
|
(
|
||||||
|
initialStartTime_,
|
||||||
|
readSuperLoopTimes(startDomain_, startSuperLoop_)
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
case misLatestTime:
|
||||||
|
tcSource = findLatestGlobalTime(readAllTimes());
|
||||||
|
break;
|
||||||
|
case misLatestTimeInStartDomain:
|
||||||
|
tcSource = findLatestLocalTime(readSolverDomainTimes(startDomain_));
|
||||||
|
break;
|
||||||
|
case misLatestTimeInStartDomainInStartSuperLoop:
|
||||||
|
tcSource = findLatestLocalTime
|
||||||
|
(
|
||||||
|
readSuperLoopTimes(startDomain_, startSuperLoop_)
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!tcSource.times().size())
|
||||||
|
{
|
||||||
|
// No relevant data found, set to initial conditions
|
||||||
|
tcSource = timeCluster
|
||||||
|
(
|
||||||
|
Time::findTimes
|
||||||
|
(
|
||||||
|
multiDictRegistry_.path()/"multiSolver"/currentSolverDomain_
|
||||||
|
/"initial"
|
||||||
|
),
|
||||||
|
0,
|
||||||
|
-1, // superLoop of -1 signifies "initial" directory
|
||||||
|
currentSolverDomain_
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
fileName sourcePath(findInstancePath(tcSource, 0));
|
||||||
|
superLoop_ = tcSource.superLoop();
|
||||||
|
// If starting from initial conditions, superLoop_ = -1
|
||||||
|
if (superLoop_ < 0) superLoop_ = 0;
|
||||||
|
scalar globalTime(tcSource.globalValue(0));
|
||||||
|
scalar localStartTime(tcSource.localValue(0));
|
||||||
|
|
||||||
|
// Now to apply the exceptions if currentSolverDomain_ != data source
|
||||||
|
// solverDomain (see long comment above).
|
||||||
|
if (sourcePath.path().path().name() != currentSolverDomain_)
|
||||||
|
{
|
||||||
|
superLoop_++;
|
||||||
|
|
||||||
|
switch (startFrom_)
|
||||||
|
{
|
||||||
|
case mtsFirstTime:
|
||||||
|
localStartTime = 0;
|
||||||
|
break;
|
||||||
|
case mtsStartTime:
|
||||||
|
localStartTime = startTime_;
|
||||||
|
break;
|
||||||
|
case mtsLatestTimeThisDomain:
|
||||||
|
{
|
||||||
|
timeCluster tcTemp
|
||||||
|
(
|
||||||
|
findLatestLocalTime
|
||||||
|
(
|
||||||
|
readSolverDomainTimes(currentSolverDomain_)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
localStartTime = tcTemp.localValue(0);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case mtsLatestTimeAllDomains:
|
||||||
|
localStartTime = globalTime;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
startTime_ = localStartTime;
|
||||||
|
|
||||||
|
globalTimeOffset_ = globalTime - startTime_;
|
||||||
|
|
||||||
|
// Give multiDictRegistry a time value (required for regIOobject::write()
|
||||||
|
// to case/[timeValue]
|
||||||
|
multiDictRegistry_.setTime(startTime_, 0);
|
||||||
|
|
||||||
|
// Copy the source data to case/[localTime]
|
||||||
|
cp(sourcePath, multiDictRegistry_.path());
|
||||||
|
mv
|
||||||
|
(
|
||||||
|
multiDictRegistry_.path()/sourcePath.name(),
|
||||||
|
multiDictRegistry_.path()/Time::timeName(startTime_)
|
||||||
|
);
|
||||||
|
|
||||||
|
// If the source data was in a different domain, swap the boundary conditions
|
||||||
|
if (sourcePath.path().path().name() != currentSolverDomain_)
|
||||||
|
{
|
||||||
|
swapBoundaryConditions
|
||||||
|
(
|
||||||
|
multiDictRegistry_.path()/Time::timeName(startTime_),
|
||||||
|
currentSolverDomain_
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Determine localEndTime and stopAtSetting
|
||||||
|
word stopAtSetting(setLocalEndTime());
|
||||||
|
|
||||||
|
// Build the new controlDict
|
||||||
|
IOdictionary newControlDict
|
||||||
|
(
|
||||||
|
IOobject
|
||||||
|
(
|
||||||
|
Time::controlDictName,
|
||||||
|
multiDictRegistry_.system(),
|
||||||
|
multiDictRegistry_,
|
||||||
|
IOobject::NO_READ,
|
||||||
|
IOobject::AUTO_WRITE,
|
||||||
|
false
|
||||||
|
),
|
||||||
|
currentSolverDomainDict_
|
||||||
|
);
|
||||||
|
|
||||||
|
// Remove multiSolver-specific values from dictionary
|
||||||
|
newControlDict.remove("startFrom");
|
||||||
|
newControlDict.remove("startTime");
|
||||||
|
newControlDict.remove("stopAt");
|
||||||
|
newControlDict.remove("endTime");
|
||||||
|
newControlDict.remove("iterations");
|
||||||
|
newControlDict.remove("purgeWriteSuperLoops");
|
||||||
|
newControlDict.remove("timeFormat");
|
||||||
|
newControlDict.remove("timePrecision");
|
||||||
|
newControlDict.remove("storeFields");
|
||||||
|
newControlDict.remove("elapsedTime");
|
||||||
|
|
||||||
|
// Add values to obtain the desired behaviour
|
||||||
|
newControlDict.set("startFrom", "startTime");
|
||||||
|
newControlDict.set("startTime", startTime_);
|
||||||
|
newControlDict.set("stopAt", stopAtSetting);
|
||||||
|
newControlDict.set("endTime", endTime_);
|
||||||
|
if (multiSolverControl_.found("timeFormat"))
|
||||||
|
{
|
||||||
|
newControlDict.set
|
||||||
|
(
|
||||||
|
"timeFormat",
|
||||||
|
word(multiSolverControl_.lookup("timeFormat"))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (multiSolverControl_.found("timePrecision"))
|
||||||
|
{
|
||||||
|
newControlDict.set
|
||||||
|
(
|
||||||
|
"timePrecision",
|
||||||
|
readScalar(multiSolverControl_.lookup("timePrecision"))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write the dictionary to the case directory
|
||||||
|
newControlDict.regIOobject::write();
|
||||||
|
|
||||||
|
swapDictionaries(currentSolverDomain_);
|
||||||
|
}
|
||||||
|
|
277
src/multiSolver/multiSolver/multiSolverSetNextSolverDomain.C
Normal file
277
src/multiSolver/multiSolver/multiSolverSetNextSolverDomain.C
Normal file
|
@ -0,0 +1,277 @@
|
||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / 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
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::multiSolver::setNextSolverDomain(const word& solverDomainName)
|
||||||
|
{
|
||||||
|
if (!solverDomains_.found(solverDomainName))
|
||||||
|
{
|
||||||
|
FatalErrorIn("multiSolver::setNextSolverDomain")
|
||||||
|
<< "Next solverDomainName '" << solverDomainName << "' does"
|
||||||
|
<< " not exist in multiSolver dictionary. Found entries are: "
|
||||||
|
<< solverDomains_.toc()
|
||||||
|
<< abort(FatalError);
|
||||||
|
}
|
||||||
|
|
||||||
|
readIfModified();
|
||||||
|
|
||||||
|
// Check if superLoop was just incremented to prevent saving the initial
|
||||||
|
// solverDomain data to the *next* superLoop
|
||||||
|
label saveToSuperLoop(superLoop_);
|
||||||
|
if (noSaveSinceSuperLoopIncrement_)
|
||||||
|
{
|
||||||
|
saveToSuperLoop--;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create archive path
|
||||||
|
fileName archivePath
|
||||||
|
(
|
||||||
|
multiDictRegistry_.path()/"multiSolver"/currentSolverDomain_/name
|
||||||
|
(
|
||||||
|
saveToSuperLoop
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
// Move all case/[time] to case/multiSolver/prefix/superloop/time
|
||||||
|
archiveTimeDirs
|
||||||
|
(
|
||||||
|
multiDictRegistry_.path(),
|
||||||
|
archivePath,
|
||||||
|
purgeWriteSuperLoops_
|
||||||
|
);
|
||||||
|
|
||||||
|
// Create multiSolverTime dictionary
|
||||||
|
IOdictionary multiSolverTime
|
||||||
|
(
|
||||||
|
IOobject
|
||||||
|
(
|
||||||
|
"multiSolverTime",
|
||||||
|
multiDictRegistry_.constant(),
|
||||||
|
multiDictRegistry_,
|
||||||
|
IOobject::NO_READ,
|
||||||
|
IOobject::AUTO_WRITE,
|
||||||
|
false
|
||||||
|
)
|
||||||
|
);
|
||||||
|
multiSolverTime.set("globalOffset", globalTimeOffset_);
|
||||||
|
|
||||||
|
// Write multiSolverTime to the case/constant directory, then move to
|
||||||
|
// archivePath
|
||||||
|
multiSolverTime.regIOobject::write();
|
||||||
|
mv(multiDictRegistry_.constantPath()/"multiSolverTime", archivePath);
|
||||||
|
|
||||||
|
// tcSource is where the latest data has been moved to
|
||||||
|
timeCluster tcSource
|
||||||
|
(
|
||||||
|
findLatestLocalTime
|
||||||
|
(
|
||||||
|
readSuperLoopTimes(currentSolverDomain_, saveToSuperLoop)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
// Copy previous solverDomain data for use later (needed for storeFields)
|
||||||
|
wordList previousStoreFields(storeFields_);
|
||||||
|
word previousSolverDomain = currentSolverDomain_;
|
||||||
|
|
||||||
|
// Change all solverDomain data to the new solverDomain
|
||||||
|
currentSolverDomain_ = solverDomainName;
|
||||||
|
setSolverDomainControls(currentSolverDomain_);
|
||||||
|
|
||||||
|
fileName sourcePath(findInstancePath(tcSource, 0));
|
||||||
|
scalar globalTime(tcSource.globalValue(0));
|
||||||
|
scalar localStartTime(0);
|
||||||
|
|
||||||
|
switch (startFrom_)
|
||||||
|
{
|
||||||
|
case mtsFirstTime:
|
||||||
|
localStartTime = 0;
|
||||||
|
break;
|
||||||
|
case mtsStartTime:
|
||||||
|
localStartTime = startTime_;
|
||||||
|
break;
|
||||||
|
case mtsLatestTimeThisDomain:
|
||||||
|
{
|
||||||
|
timeCluster tcTemp
|
||||||
|
(
|
||||||
|
findLatestLocalTime
|
||||||
|
(
|
||||||
|
readSolverDomainTimes(currentSolverDomain_)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
localStartTime = tcTemp.localValue(0);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case mtsLatestTimeAllDomains:
|
||||||
|
localStartTime = globalTime;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
startTime_ = localStartTime;
|
||||||
|
globalTimeOffset_ = globalTime - startTime_;
|
||||||
|
|
||||||
|
// Give multiDictRegistry a time value (required for regIOobject::write()
|
||||||
|
// to case/[timeValue]
|
||||||
|
multiDictRegistry_.setTime(startTime_, 0);
|
||||||
|
|
||||||
|
word stopAtSetting("endTime");
|
||||||
|
|
||||||
|
if (!finished_)
|
||||||
|
{
|
||||||
|
// Copy the source data to case/[localTime]
|
||||||
|
cp(sourcePath, multiDictRegistry_.path());
|
||||||
|
mv
|
||||||
|
(
|
||||||
|
multiDictRegistry_.path()/sourcePath.name(),
|
||||||
|
multiDictRegistry_.path()/Time::timeName(startTime_)
|
||||||
|
);
|
||||||
|
|
||||||
|
// Copy the previous domain's storeFields from its first timestep to
|
||||||
|
// current time directory
|
||||||
|
if (previousStoreFields.size())
|
||||||
|
{
|
||||||
|
fileName storedSourcePath
|
||||||
|
(
|
||||||
|
findInstancePath
|
||||||
|
(
|
||||||
|
findClosestLocalTime
|
||||||
|
(
|
||||||
|
0,
|
||||||
|
readSuperLoopTimes
|
||||||
|
(
|
||||||
|
previousSolverDomain,
|
||||||
|
saveToSuperLoop
|
||||||
|
)
|
||||||
|
),
|
||||||
|
0
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
forAll (previousStoreFields, i)
|
||||||
|
{
|
||||||
|
// Copy the stored fields to case/[localTime].
|
||||||
|
if (exists(storedSourcePath/previousStoreFields[i]))
|
||||||
|
{
|
||||||
|
fileName storedSource(storedSourcePath/previousStoreFields[i]);
|
||||||
|
|
||||||
|
cp
|
||||||
|
(
|
||||||
|
storedSource,
|
||||||
|
multiDictRegistry_.path()/Time::timeName(startTime_)
|
||||||
|
/previousStoreFields[i]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
FatalErrorIn("multiSolver::setNextSolverDomain")
|
||||||
|
<< "Attempting to copy stored field "
|
||||||
|
<< previousStoreFields[i] << " from "
|
||||||
|
<< previousSolverDomain << " to "
|
||||||
|
<< currentSolverDomain_ << " in superLoop "
|
||||||
|
<< saveToSuperLoop << ". File not found. This may occur "
|
||||||
|
<< "if " << previousSolverDomain << " is the first "
|
||||||
|
<< "solverDomain to be initialized, and you did not put "
|
||||||
|
<< "the stored fields into its 0/0 directory."
|
||||||
|
<< abort(FatalError);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
swapBoundaryConditions
|
||||||
|
(
|
||||||
|
multiDictRegistry_.path()/Time::timeName(startTime_),
|
||||||
|
currentSolverDomain_
|
||||||
|
);
|
||||||
|
|
||||||
|
// Determine localEndTime and stopAtSetting
|
||||||
|
stopAtSetting = setLocalEndTime();
|
||||||
|
}
|
||||||
|
else //finished_
|
||||||
|
{
|
||||||
|
stopAtSetting = "noWriteNow";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Build the new controlDict
|
||||||
|
IOdictionary newControlDict
|
||||||
|
(
|
||||||
|
IOobject
|
||||||
|
(
|
||||||
|
Time::controlDictName,
|
||||||
|
multiDictRegistry_.system(),
|
||||||
|
multiDictRegistry_,
|
||||||
|
IOobject::NO_READ,
|
||||||
|
IOobject::AUTO_WRITE,
|
||||||
|
false
|
||||||
|
),
|
||||||
|
currentSolverDomainDict_
|
||||||
|
);
|
||||||
|
|
||||||
|
// Remove multiSolver-specific values from dictionary
|
||||||
|
newControlDict.remove("startFrom");
|
||||||
|
newControlDict.remove("startTime");
|
||||||
|
newControlDict.remove("stopAt");
|
||||||
|
newControlDict.remove("endTime");
|
||||||
|
newControlDict.remove("iterations");
|
||||||
|
newControlDict.remove("purgeWriteSuperLoops");
|
||||||
|
newControlDict.remove("timeFormat");
|
||||||
|
newControlDict.remove("timePrecision");
|
||||||
|
newControlDict.remove("storeFields");
|
||||||
|
newControlDict.remove("elapsedTime");
|
||||||
|
|
||||||
|
// Add values to obtain the desired behaviour
|
||||||
|
newControlDict.set("startFrom", "startTime");
|
||||||
|
newControlDict.set("startTime", startTime_);
|
||||||
|
newControlDict.set("stopAt", stopAtSetting);
|
||||||
|
newControlDict.set("endTime", endTime_);
|
||||||
|
if (multiSolverControl_.found("timeFormat"))
|
||||||
|
{
|
||||||
|
newControlDict.set
|
||||||
|
(
|
||||||
|
"timeFormat",
|
||||||
|
word(multiSolverControl_.lookup("timeFormat"))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (multiSolverControl_.found("timePrecision"))
|
||||||
|
{
|
||||||
|
newControlDict.set
|
||||||
|
(
|
||||||
|
"timePrecision",
|
||||||
|
readScalar(multiSolverControl_.lookup("timePrecision"))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write the dictionary to the case directory
|
||||||
|
newControlDict.regIOobject::write();
|
||||||
|
|
||||||
|
// Change all the dictionaries
|
||||||
|
swapDictionaries(currentSolverDomain_);
|
||||||
|
|
||||||
|
// Remove noSaves flag
|
||||||
|
if (noSaveSinceSuperLoopIncrement_)
|
||||||
|
{
|
||||||
|
noSaveSinceSuperLoopIncrement_ = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
758
src/multiSolver/multiSolver/multiSolverTimeFunctions.C
Normal file
758
src/multiSolver/multiSolver/multiSolverTimeFunctions.C
Normal file
|
@ -0,0 +1,758 @@
|
||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / 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
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
|
||||||
|
Foam::labelList Foam::multiSolver::findSuperLoops(const fileName& path)
|
||||||
|
{
|
||||||
|
fileNameList dirEntries(readDir(path, fileName::DIRECTORY));
|
||||||
|
|
||||||
|
labelList superLoopList(dirEntries.size());
|
||||||
|
label nSuperLoops(0);
|
||||||
|
|
||||||
|
// Loop through dirEntries, checking for valid integers, sort entries
|
||||||
|
forAll(dirEntries, de)
|
||||||
|
{
|
||||||
|
// Check if directory is "initial"
|
||||||
|
if (dirEntries[de] == "initial")
|
||||||
|
{
|
||||||
|
superLoopList[nSuperLoops++] = -1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
IStringStream superLoopStream(dirEntries[de]);
|
||||||
|
token superLoopToken(superLoopStream);
|
||||||
|
|
||||||
|
// Check if directory is an integer
|
||||||
|
if (superLoopToken.isLabel() && superLoopStream.eof())
|
||||||
|
{
|
||||||
|
superLoopList[nSuperLoops++] = superLoopToken.labelToken();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
superLoopList.setSize(nSuperLoops);
|
||||||
|
sort(superLoopList);
|
||||||
|
return superLoopList;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::timeCluster Foam::multiSolver::findClosestGlobalTime
|
||||||
|
(
|
||||||
|
const Foam::scalar value,
|
||||||
|
const Foam::timeClusterList& tcl,
|
||||||
|
const bool& exact
|
||||||
|
)
|
||||||
|
{
|
||||||
|
scalar maxDiff(-VGREAT);
|
||||||
|
scalar minDiff(VGREAT);
|
||||||
|
label underShoot(-1);
|
||||||
|
label best(-1);
|
||||||
|
label initial(-1);
|
||||||
|
|
||||||
|
// Find closest global minimum that does not exceed value
|
||||||
|
forAll(tcl, i)
|
||||||
|
{
|
||||||
|
if (!tcl[i].times().size()) continue;
|
||||||
|
scalar diff(tcl[i].globalMinValue() - value);
|
||||||
|
if ((diff <= 0) && (diff >= maxDiff))
|
||||||
|
{
|
||||||
|
// "initial" directory may be a duplicate match - others take
|
||||||
|
// priority.
|
||||||
|
if ((tcl[i].superLoop() < 0) && (diff > maxDiff))
|
||||||
|
{
|
||||||
|
initial = i;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
initial = -1;
|
||||||
|
best = i;
|
||||||
|
}
|
||||||
|
maxDiff = diff;
|
||||||
|
}
|
||||||
|
else if ((diff > 0) && (diff < minDiff))
|
||||||
|
{
|
||||||
|
// This is in case all timeClusters exceed value - then we have to
|
||||||
|
// return the closest minValue
|
||||||
|
minDiff = diff;
|
||||||
|
underShoot = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (initial != -1)
|
||||||
|
{
|
||||||
|
// "initial" directory is the only match
|
||||||
|
best = initial;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (best == -1)
|
||||||
|
{
|
||||||
|
if (minDiff != -1)
|
||||||
|
{
|
||||||
|
// All timeClusters exceed value, return closest minValue
|
||||||
|
best = underShoot;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
|
||||||
|
FatalErrorIn("multiSolver::findClosestGlobalTime")
|
||||||
|
<< "The timeClusterList passed to this function has no non-"
|
||||||
|
<< "empty instantLists. Use timeClusterList::purgeEmpties "
|
||||||
|
<< "and check its return value to prevent this."
|
||||||
|
<< abort(FatalError);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
label timeIndex
|
||||||
|
(
|
||||||
|
Time::findClosestTimeIndex
|
||||||
|
(
|
||||||
|
tcl[best].times(), value - tcl[best].globalOffset()
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
if (exact && (maxDiff < -VSMALL))
|
||||||
|
{
|
||||||
|
FatalErrorIn("multiSolver::findClosestGlobalTime")
|
||||||
|
<< "No exact match found for global time = " << value
|
||||||
|
<< abort(FatalError);
|
||||||
|
}
|
||||||
|
|
||||||
|
return tcl[best](timeIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::timeCluster Foam::multiSolver::findClosestLocalTime
|
||||||
|
(
|
||||||
|
const Foam::scalar value,
|
||||||
|
const Foam::timeClusterList& tcl,
|
||||||
|
const bool& exact
|
||||||
|
)
|
||||||
|
{
|
||||||
|
scalar maxDiff(-VGREAT);
|
||||||
|
scalar minDiff(VGREAT);
|
||||||
|
label underShoot(-1);
|
||||||
|
label best(-1);
|
||||||
|
label initial(-1);
|
||||||
|
timeClusterList tclDummy;
|
||||||
|
const timeClusterList * tclPtr;
|
||||||
|
|
||||||
|
if (nonOverlapping(tcl))
|
||||||
|
{
|
||||||
|
tclPtr = & tcl;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
tclDummy = tcl.selectiveSubList(findMaxSuperLoopIndices(tcl));
|
||||||
|
tclPtr = & tclDummy;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (label i = 0; i < tclPtr->size(); i++)
|
||||||
|
{
|
||||||
|
if (!tclPtr->operator[](i).times().size()) continue;
|
||||||
|
scalar diff(tclPtr->operator[](i).localMinValue() - value);
|
||||||
|
|
||||||
|
if ((diff <= 0) && (diff >= maxDiff))
|
||||||
|
{
|
||||||
|
// "initial" directory may be a duplicate match - others take
|
||||||
|
// priority.
|
||||||
|
|
||||||
|
if ((tclPtr->operator[](i).superLoop() < 0) && (diff > maxDiff))
|
||||||
|
{
|
||||||
|
initial = i;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
initial = -1;
|
||||||
|
best = i;
|
||||||
|
}
|
||||||
|
maxDiff = diff;
|
||||||
|
}
|
||||||
|
else if ((diff > 0) && (diff < minDiff))
|
||||||
|
{
|
||||||
|
// This is in case all timeClusters exceed value - then we have to
|
||||||
|
// return the closest minValue
|
||||||
|
minDiff = diff;
|
||||||
|
underShoot = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (initial != -1)
|
||||||
|
{
|
||||||
|
// "initial" directory is the only match
|
||||||
|
best = initial;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (best == -1)
|
||||||
|
{
|
||||||
|
if (minDiff != -1)
|
||||||
|
{
|
||||||
|
// All timeClusters exceed value, return closest minValue
|
||||||
|
best = underShoot;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
|
||||||
|
FatalErrorIn("multiSolver::findClosestLocalTime")
|
||||||
|
<< "The timeClusterList passed to this function has no non-"
|
||||||
|
<< "empty instantLists. Use timeClusterList::purgeEmpties "
|
||||||
|
<< "and check its return value to prevent this."
|
||||||
|
<< abort(FatalError);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
label timeIndex
|
||||||
|
(
|
||||||
|
Time::findClosestTimeIndex
|
||||||
|
(
|
||||||
|
tclPtr->operator[](best).times(), value
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
if (exact && (maxDiff < -VSMALL))
|
||||||
|
{
|
||||||
|
FatalErrorIn("multiSolver::findClosestLocalTime")
|
||||||
|
<< "No exact match found for local time = " << value
|
||||||
|
<< abort(FatalError);
|
||||||
|
}
|
||||||
|
|
||||||
|
return tclPtr->operator[](best)(timeIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::timeCluster Foam::multiSolver::findLatestGlobalTime
|
||||||
|
(
|
||||||
|
const Foam::timeClusterList& tcl
|
||||||
|
)
|
||||||
|
{
|
||||||
|
timeCluster bestMax(0);
|
||||||
|
|
||||||
|
timeCluster currentMax;
|
||||||
|
|
||||||
|
forAll(tcl, i)
|
||||||
|
{
|
||||||
|
if (tcl[i].times().size() == 0) continue;
|
||||||
|
|
||||||
|
currentMax = tcl[i](tcl[i].globalMaxIndex());
|
||||||
|
if
|
||||||
|
(
|
||||||
|
(currentMax.globalValue(0) > bestMax.globalValue(0))
|
||||||
|
|| (
|
||||||
|
(currentMax.globalValue(0) == bestMax.globalValue(0))
|
||||||
|
&& (currentMax.superLoop() != -1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
bestMax = currentMax;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bestMax.solverDomainName() == word::null)
|
||||||
|
{
|
||||||
|
FatalErrorIn("multiSolver::findLatestGlobalTime")
|
||||||
|
<< "The timeClusterList passed to this function has no non-empty "
|
||||||
|
<< "instantLists. Use timeClusterList::purgeEmpties and check its"
|
||||||
|
<< " return value to prevent this."
|
||||||
|
<< abort(FatalError);
|
||||||
|
}
|
||||||
|
return bestMax;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::timeCluster Foam::multiSolver::findLatestLocalTime
|
||||||
|
(
|
||||||
|
const Foam::timeClusterList& tcl
|
||||||
|
)
|
||||||
|
{
|
||||||
|
timeClusterList dummyTcl;
|
||||||
|
const timeClusterList * tclPtr;
|
||||||
|
timeCluster bestMax(0);
|
||||||
|
timeCluster currentMax;
|
||||||
|
|
||||||
|
if (nonOverlapping(tcl))
|
||||||
|
{
|
||||||
|
tclPtr = & tcl;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
dummyTcl = tcl.selectiveSubList(findMaxSuperLoopIndices(tcl));
|
||||||
|
tclPtr = & dummyTcl;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (label i = 0; i < tclPtr->size(); i++)
|
||||||
|
{
|
||||||
|
if (tclPtr->operator[](i).times().size() == 0) continue;
|
||||||
|
|
||||||
|
currentMax =
|
||||||
|
tclPtr->operator[](i)(tclPtr->operator[](i).localMaxIndex());
|
||||||
|
|
||||||
|
if
|
||||||
|
(
|
||||||
|
(currentMax.localValue(0) > bestMax.localValue(0))
|
||||||
|
|| (
|
||||||
|
(currentMax.localValue(0) == bestMax.localValue(0))
|
||||||
|
&& (currentMax.superLoop() != -1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
bestMax = currentMax;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bestMax.solverDomainName() == word::null)
|
||||||
|
{
|
||||||
|
FatalErrorIn("multiSolver::findLatestLocalTime")
|
||||||
|
<< "The timeClusterList passed to this function has no non-empty "
|
||||||
|
<< "instantLists. Use timeClusterList::purgeEmpties and check its"
|
||||||
|
<< " return value to prevent this."
|
||||||
|
<< abort(FatalError);
|
||||||
|
}
|
||||||
|
|
||||||
|
return bestMax;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::fileName Foam::multiSolver::findInstancePath
|
||||||
|
(
|
||||||
|
const timeCluster& tc,
|
||||||
|
const label& index
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
if (!tc.times().size())
|
||||||
|
{
|
||||||
|
FatalErrorIn("multiSolver::findInstancePath")
|
||||||
|
<< "The timeClusterList passed to this function has no non-empty "
|
||||||
|
<< "instantLists. Use timeClusterList::purgeEmpties and check its"
|
||||||
|
<< " return value to prevent this."
|
||||||
|
<< abort(FatalError);
|
||||||
|
}
|
||||||
|
if (tc.superLoop() < 0)
|
||||||
|
{
|
||||||
|
// Initial directory
|
||||||
|
return fileName
|
||||||
|
(
|
||||||
|
multiDictRegistry_.path()/"multiSolver"/tc.solverDomainName()
|
||||||
|
/"initial"/tc[index].name()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return fileName
|
||||||
|
(
|
||||||
|
multiDictRegistry_.path()/"multiSolver"/tc.solverDomainName()
|
||||||
|
/name(tc.superLoop())/tc[index].name()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::label Foam::multiSolver::findMaxSuperLoopValue(const timeClusterList& tcl)
|
||||||
|
{
|
||||||
|
if (!tcl.size())
|
||||||
|
{
|
||||||
|
FatalErrorIn("multiSolver::findMaxSuperLoopValue")
|
||||||
|
<< "The timeClusterList passed to this function is empty. Use "
|
||||||
|
<< "timeClusterList::purgeEmpties and check its return value to "
|
||||||
|
<< "prevent this."
|
||||||
|
<< abort(FatalError);
|
||||||
|
}
|
||||||
|
return tcl[findMaxSuperLoopIndices(tcl)[0]].superLoop();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::labelList Foam::multiSolver::findMaxSuperLoopIndices(const timeClusterList& tcl)
|
||||||
|
{
|
||||||
|
label currentMax(-2);
|
||||||
|
labelList bestIndices(0);
|
||||||
|
label maxesFound(0);
|
||||||
|
|
||||||
|
forAll(tcl, i)
|
||||||
|
{
|
||||||
|
if (!tcl[i].times().size()) continue;
|
||||||
|
if (currentMax == tcl[i].superLoop())
|
||||||
|
{
|
||||||
|
bestIndices.setSize(++maxesFound);
|
||||||
|
bestIndices[maxesFound - 1] = i;
|
||||||
|
}
|
||||||
|
else if (currentMax < tcl[i].superLoop())
|
||||||
|
{
|
||||||
|
currentMax = tcl[i].superLoop();
|
||||||
|
maxesFound = 1;
|
||||||
|
bestIndices.setSize(1);
|
||||||
|
bestIndices[0] = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bestIndices.size() == 0)
|
||||||
|
{
|
||||||
|
FatalErrorIn("multiSolver::findMaxSuperLoopIndices")
|
||||||
|
<< "The timeClusterList passed to this function is empty. Use "
|
||||||
|
<< "timeClusterList::purgeEmpties and check its return value to "
|
||||||
|
<< "prevent this."
|
||||||
|
<< abort(FatalError);
|
||||||
|
}
|
||||||
|
return bestIndices;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Foam::multiSolver::nonOverlapping
|
||||||
|
(
|
||||||
|
|
||||||
|
const Foam::timeClusterList& tcl,
|
||||||
|
const bool useGlobalTime
|
||||||
|
)
|
||||||
|
{
|
||||||
|
// see tuple2Lists.H
|
||||||
|
scalarScalarList range(tcl.size());
|
||||||
|
|
||||||
|
if (useGlobalTime)
|
||||||
|
{
|
||||||
|
forAll(tcl, i)
|
||||||
|
{
|
||||||
|
if (!tcl[i].times().size())
|
||||||
|
{
|
||||||
|
range[i].first() = 0;
|
||||||
|
range[i].second() = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
range[i].first() = tcl[i].globalMinValue();
|
||||||
|
range[i].second() = tcl[i].globalMaxValue();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
forAll(tcl, i)
|
||||||
|
{
|
||||||
|
if (!tcl[i].times().size())
|
||||||
|
{
|
||||||
|
range[i].first() = 0;
|
||||||
|
range[i].second() = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
range[i].first() = tcl[i].localMinValue();
|
||||||
|
range[i].second() = tcl[i].localMaxValue();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sortTuple2ListBy1stThen2nd(range);
|
||||||
|
|
||||||
|
for (label i = 0; i < (range.size() - 1); i++)
|
||||||
|
{
|
||||||
|
// Using '-SMALL' below is a temporary bug fix
|
||||||
|
if (range[i + 1].first() - range[i].second() < -SMALL)
|
||||||
|
{
|
||||||
|
// timeClusters overlap
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::timeCluster Foam::multiSolver::readSuperLoopTimes
|
||||||
|
(
|
||||||
|
const Foam::word& solverDomain,
|
||||||
|
const Foam::label superLoop,
|
||||||
|
const Foam::word& processor
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
fileName currentPath;
|
||||||
|
if (processor.size())
|
||||||
|
{
|
||||||
|
currentPath = multiDictRegistry_.path()/processor;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
currentPath = multiDictRegistry_.path();
|
||||||
|
}
|
||||||
|
if (superLoop < 0)
|
||||||
|
{
|
||||||
|
currentPath = currentPath/"multiSolver"/solverDomain
|
||||||
|
/"initial";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
currentPath = currentPath/"multiSolver"/solverDomain
|
||||||
|
/name(superLoop);
|
||||||
|
}
|
||||||
|
|
||||||
|
fileName mstFileName
|
||||||
|
(
|
||||||
|
currentPath/"multiSolverTime"
|
||||||
|
);
|
||||||
|
IFstream mstFile(mstFileName);
|
||||||
|
|
||||||
|
bool mstFileGood(false);
|
||||||
|
scalar globalOffset(0);
|
||||||
|
|
||||||
|
if (mstFile.good())
|
||||||
|
{
|
||||||
|
dictionary mstDict(mstFile);
|
||||||
|
if (mstDict.found("globalOffset"))
|
||||||
|
{
|
||||||
|
globalOffset =
|
||||||
|
readScalar(mstDict.lookup("globalOffset"));
|
||||||
|
mstFileGood = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((!mstFileGood) && (superLoop != -1))
|
||||||
|
{
|
||||||
|
WarningIn("multiSolver::readSuperLoopTimes")
|
||||||
|
<< "Bad or missing multiSolverTime dictionary (auto-"
|
||||||
|
<< "generated) in case/multiSolver/" << solverDomain
|
||||||
|
<< "/" << superLoop << ". Assuming globalOffset = 0"
|
||||||
|
<< endl;
|
||||||
|
}
|
||||||
|
timeCluster tc
|
||||||
|
(
|
||||||
|
Time::findTimes(currentPath),
|
||||||
|
globalOffset,
|
||||||
|
superLoop,
|
||||||
|
solverDomain
|
||||||
|
);
|
||||||
|
return tc;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::timeClusterList Foam::multiSolver::readSolverDomainTimes
|
||||||
|
(
|
||||||
|
const word& solverDomain,
|
||||||
|
const word processor
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
timeClusterList tcl(0);
|
||||||
|
label nTimeClusters(0);
|
||||||
|
|
||||||
|
fileName locale;
|
||||||
|
if (processor.size())
|
||||||
|
{
|
||||||
|
locale = processor/"multiSolver";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
locale = "multiSolver";
|
||||||
|
}
|
||||||
|
fileName currentPath
|
||||||
|
(
|
||||||
|
multiDictRegistry_.path()/locale/solverDomain
|
||||||
|
);
|
||||||
|
|
||||||
|
labelList superLoopList(multiSolver::findSuperLoops(currentPath));
|
||||||
|
|
||||||
|
// Loop through superLoopList, check for valid data, store in tcl
|
||||||
|
forAll(superLoopList, sl)
|
||||||
|
{
|
||||||
|
timeCluster tc
|
||||||
|
(
|
||||||
|
readSuperLoopTimes(solverDomain, superLoopList[sl], processor)
|
||||||
|
);
|
||||||
|
|
||||||
|
// If there are no time directories, ignore this superLoop
|
||||||
|
if (tc.times().size() == 0) continue;
|
||||||
|
|
||||||
|
// Store timeCluster
|
||||||
|
tcl.setSize(++nTimeClusters);
|
||||||
|
tcl[nTimeClusters - 1] = tc;
|
||||||
|
}
|
||||||
|
return tcl;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::timeClusterList Foam::multiSolver::readAllTimes
|
||||||
|
(
|
||||||
|
const word processor
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
timeClusterList tcl(0);
|
||||||
|
|
||||||
|
// Loop through solverDomains
|
||||||
|
forAll(prefixes_, pf)
|
||||||
|
{
|
||||||
|
if (prefixes_[pf] == "default") continue;
|
||||||
|
|
||||||
|
timeClusterList tclIn(readSolverDomainTimes(prefixes_[pf], processor));
|
||||||
|
tcl.append(tclIn);
|
||||||
|
}
|
||||||
|
return tcl;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Foam::multiSolver::loadTimeClusterList
|
||||||
|
(
|
||||||
|
const Foam::timeClusterList& tcl,
|
||||||
|
const bool useGlobalTime,
|
||||||
|
const bool loadStoreFields
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
if (!nonOverlapping(tcl, useGlobalTime)) return false;
|
||||||
|
|
||||||
|
wordList storeFields;
|
||||||
|
|
||||||
|
forAll(tcl, i)
|
||||||
|
{
|
||||||
|
fileName currentPath
|
||||||
|
(
|
||||||
|
findInstancePath(tcl[i], 0).path()
|
||||||
|
);
|
||||||
|
|
||||||
|
instantList il(Time::findTimes(currentPath));
|
||||||
|
fileName storeFieldsPath
|
||||||
|
(
|
||||||
|
currentPath/il[Time::findClosestTimeIndex(il, -1.0)].name()
|
||||||
|
);
|
||||||
|
|
||||||
|
if
|
||||||
|
(
|
||||||
|
loadStoreFields
|
||||||
|
&& solverDomains_
|
||||||
|
.subDict(tcl[i].solverDomainName())
|
||||||
|
.found("storeFields")
|
||||||
|
)
|
||||||
|
{
|
||||||
|
storeFields = wordList(solverDomains_
|
||||||
|
.subDict(tcl[i].solverDomainName())
|
||||||
|
.lookup("storeFields"));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
storeFields.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
forAll(tcl[i].times(), j)
|
||||||
|
{
|
||||||
|
fileName storeFieldsDestination
|
||||||
|
(
|
||||||
|
multiDictRegistry_.path()/tcl[i].times()[j].name()
|
||||||
|
);
|
||||||
|
|
||||||
|
cp
|
||||||
|
(
|
||||||
|
currentPath/tcl[i].times()[j].name(),
|
||||||
|
multiDictRegistry_.path()
|
||||||
|
);
|
||||||
|
if (useGlobalTime)
|
||||||
|
{
|
||||||
|
storeFieldsDestination = multiDictRegistry_.path()/
|
||||||
|
Time::timeName
|
||||||
|
(
|
||||||
|
tcl[i].globalValue(j)
|
||||||
|
);
|
||||||
|
|
||||||
|
mv
|
||||||
|
(
|
||||||
|
multiDictRegistry_.path()/tcl[i].times()[j].name(),
|
||||||
|
storeFieldsDestination
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if
|
||||||
|
(
|
||||||
|
loadStoreFields
|
||||||
|
&& (storeFieldsPath != storeFieldsDestination)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
forAll(storeFields, j)
|
||||||
|
{
|
||||||
|
cp
|
||||||
|
(
|
||||||
|
storeFieldsPath/storeFields[j],
|
||||||
|
storeFieldsDestination
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} // end cycle through instants
|
||||||
|
} // end cycle through timeClusters
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::multiSolver::archiveTimeDirs
|
||||||
|
(
|
||||||
|
const Foam::fileName& sourcePath,
|
||||||
|
const Foam::fileName& archivePath,
|
||||||
|
const Foam::label& purgeWrite
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (archivePath.name() == "initial")
|
||||||
|
{
|
||||||
|
FatalErrorIn("multiSolver::archiveTimeDirs")
|
||||||
|
<< "Attempting to archive to the 'initial' directory. This is "
|
||||||
|
<< "not permitted. sourcePath = " << sourcePath << ", archivePath"
|
||||||
|
<< " = " << archivePath
|
||||||
|
<< abort(FatalError);
|
||||||
|
}
|
||||||
|
if (exists(archivePath))
|
||||||
|
{
|
||||||
|
purgeTimeDirs(archivePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
mkDir(archivePath);
|
||||||
|
|
||||||
|
// Perform purgeWrite of superLoop directories
|
||||||
|
if (purgeWrite)
|
||||||
|
{
|
||||||
|
labelList allSL(findSuperLoops(archivePath.path()));
|
||||||
|
label currentSL(atoi(archivePath.name().c_str()));
|
||||||
|
|
||||||
|
sort(allSL);
|
||||||
|
label i = 0;
|
||||||
|
while (allSL[i] < currentSL)
|
||||||
|
{
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (label j = 1; j <= (i - purgeWrite); j++)
|
||||||
|
{
|
||||||
|
rmDir(archivePath.path()/name(allSL[j]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
instantList timeDirs(Time::findTimes(sourcePath));
|
||||||
|
|
||||||
|
forAll(timeDirs, i)
|
||||||
|
{
|
||||||
|
if (timeDirs[i].name() == "constant") continue;
|
||||||
|
mv(sourcePath/timeDirs[i].name(), archivePath/timeDirs[i].name());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Foam::multiSolver::purgeTimeDirs(const Foam::fileName& path)
|
||||||
|
{
|
||||||
|
instantList timeDirs(Time::findTimes(path));
|
||||||
|
|
||||||
|
forAll(timeDirs, i)
|
||||||
|
{
|
||||||
|
if (timeDirs[i].name() == "constant") continue;
|
||||||
|
rmDir(path/timeDirs[i].name());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
243
src/multiSolver/timeCluster/timeCluster.C
Normal file
243
src/multiSolver/timeCluster/timeCluster.C
Normal file
|
@ -0,0 +1,243 @@
|
||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / 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 "timeClusterList.H"
|
||||||
|
#include "Time.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
const char* const Foam::timeCluster::typeName = "timeCluster";
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Foam::timeCluster::timeCluster()
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::timeCluster::timeCluster
|
||||||
|
(
|
||||||
|
const instantList& times,
|
||||||
|
const scalar globalOffset,
|
||||||
|
const label superLoop,
|
||||||
|
const word& solverDomainName,
|
||||||
|
const word& preConName
|
||||||
|
)
|
||||||
|
:
|
||||||
|
instantList(times),
|
||||||
|
globalOffset_(globalOffset),
|
||||||
|
superLoop_(superLoop),
|
||||||
|
solverDomainName_(solverDomainName),
|
||||||
|
preConName_(preConName)
|
||||||
|
{}
|
||||||
|
|
||||||
|
Foam::timeCluster::timeCluster
|
||||||
|
(
|
||||||
|
const timeCluster& tc,
|
||||||
|
const label index
|
||||||
|
)
|
||||||
|
:
|
||||||
|
instantList(1, tc[index]),
|
||||||
|
globalOffset_(tc.globalOffset_),
|
||||||
|
superLoop_(tc.superLoop_),
|
||||||
|
solverDomainName_(tc.solverDomainName_),
|
||||||
|
preConName_(tc.preConName_)
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::timeCluster::timeCluster(const Foam::scalar t)
|
||||||
|
:
|
||||||
|
instantList(1, instant(0)),
|
||||||
|
globalOffset_(0),
|
||||||
|
superLoop_(0),
|
||||||
|
solverDomainName_(word::null),
|
||||||
|
preConName_(word::null)
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Foam::scalar Foam::timeCluster::globalValue(const label& index) const
|
||||||
|
{
|
||||||
|
return this->operator[](index).value() + globalOffset_;
|
||||||
|
}
|
||||||
|
|
||||||
|
Foam::scalar Foam::timeCluster::globalMinValue() const
|
||||||
|
{
|
||||||
|
return this->localMinValue() + globalOffset_;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::scalar Foam::timeCluster::globalMaxValue() const
|
||||||
|
{
|
||||||
|
return this->localMaxValue() + globalOffset_;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::label Foam::timeCluster::globalMinIndex() const
|
||||||
|
{
|
||||||
|
return this->localMinIndex();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::label Foam::timeCluster::globalMaxIndex() const
|
||||||
|
{
|
||||||
|
return this->localMaxIndex();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::scalar Foam::timeCluster::globalFindClosestTimeValue
|
||||||
|
(
|
||||||
|
const scalar timeValue
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
return this->operator[]
|
||||||
|
(
|
||||||
|
Foam::Time::findClosestTimeIndex
|
||||||
|
(
|
||||||
|
this->times(), timeValue - globalOffset_
|
||||||
|
)
|
||||||
|
).value() + globalOffset_;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::label Foam::timeCluster::globalFindClosestTimeIndex
|
||||||
|
(
|
||||||
|
const scalar timeValue
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
return Foam::Time::findClosestTimeIndex
|
||||||
|
(
|
||||||
|
this->times(), timeValue - globalOffset_
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::scalar Foam::timeCluster::localValue(const label& index) const
|
||||||
|
{
|
||||||
|
return this->operator[](index).value();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::scalar Foam::timeCluster::localMinValue() const
|
||||||
|
{
|
||||||
|
return this->operator[](this->localMinIndex()).value();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::scalar Foam::timeCluster::localMaxValue() const
|
||||||
|
{
|
||||||
|
return this->operator[](this->localMaxIndex()).value();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::label Foam::timeCluster::localMinIndex() const
|
||||||
|
{
|
||||||
|
label bestIndex(0);
|
||||||
|
scalar min(VGREAT);
|
||||||
|
forAll(*this, i)
|
||||||
|
{
|
||||||
|
if (this->operator[](i).value() < min)
|
||||||
|
{
|
||||||
|
min = this->operator[](i).value();
|
||||||
|
bestIndex = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return bestIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::label Foam::timeCluster::localMaxIndex() const
|
||||||
|
{
|
||||||
|
label bestIndex(0);
|
||||||
|
scalar max(0);
|
||||||
|
forAll(*this, i)
|
||||||
|
{
|
||||||
|
if (this->operator[](i).value() > max)
|
||||||
|
{
|
||||||
|
max = this->operator[](i).value();
|
||||||
|
bestIndex = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return bestIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::scalar Foam::timeCluster::localFindClosestTimeValue
|
||||||
|
(
|
||||||
|
const scalar timeValue
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
return this->operator[]
|
||||||
|
(
|
||||||
|
Foam::Time::findClosestTimeIndex
|
||||||
|
(
|
||||||
|
this->times(), timeValue
|
||||||
|
)
|
||||||
|
).value();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::label Foam::timeCluster::localFindClosestTimeIndex
|
||||||
|
(
|
||||||
|
const scalar timeValue
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
return Foam::Time::findClosestTimeIndex
|
||||||
|
(
|
||||||
|
this->times(), timeValue
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::timeCluster Foam::timeCluster::operator()(const Foam::label index) const
|
||||||
|
{
|
||||||
|
return timeCluster(*this, index);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * Friend IOstream Operators * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Foam::Istream& Foam::operator>>(Istream& is, timeCluster& I)
|
||||||
|
{
|
||||||
|
return is >> I.globalOffset_
|
||||||
|
>> I.superLoop_
|
||||||
|
>> I.solverDomainName_
|
||||||
|
>> I.preConName_
|
||||||
|
>> I.times();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::Ostream& Foam::operator<<(Ostream& os, const timeCluster& I)
|
||||||
|
{
|
||||||
|
return os << "/* globalOffset: */\t" << I.globalOffset_ << nl
|
||||||
|
<< "/* superLoop: */\t" << I.superLoop_ << nl
|
||||||
|
<< "/* solverDomain: */\t" << I.solverDomainName_ << nl
|
||||||
|
<< "/* preConName: */\t" << I.preConName_ << nl
|
||||||
|
<< "/* Instant list: */\t" << I.times();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
233
src/multiSolver/timeCluster/timeCluster.H
Normal file
233
src/multiSolver/timeCluster/timeCluster.H
Normal file
|
@ -0,0 +1,233 @@
|
||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / 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::timeCluster
|
||||||
|
|
||||||
|
Description
|
||||||
|
A cluster of time instances, used with multiSolver. Catalogues all the
|
||||||
|
time directories within a superLoop, within a solverDomain. A single
|
||||||
|
time cluster describes what would be analogous to all the time directories
|
||||||
|
for a solver that does not use multiSolver.
|
||||||
|
|
||||||
|
SourceFiles
|
||||||
|
timeCluster.C
|
||||||
|
|
||||||
|
Author
|
||||||
|
David L. F. Gaden
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef timeCluster_H
|
||||||
|
#define timeCluster_H
|
||||||
|
|
||||||
|
#include "word.H"
|
||||||
|
#include "scalar.H"
|
||||||
|
#include "instantList.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
|
||||||
|
// Forward declaration of friend functions and operators
|
||||||
|
|
||||||
|
class timeCluster;
|
||||||
|
|
||||||
|
// Friend IOstream Operators
|
||||||
|
|
||||||
|
Istream& operator>>(Istream&, timeCluster&);
|
||||||
|
Ostream& operator<<(Ostream&, const timeCluster&);
|
||||||
|
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
Class timeCluster Declaration
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
class timeCluster
|
||||||
|
:
|
||||||
|
public instantList
|
||||||
|
{
|
||||||
|
// Private data
|
||||||
|
|
||||||
|
scalar globalOffset_;
|
||||||
|
label superLoop_;
|
||||||
|
word solverDomainName_;
|
||||||
|
|
||||||
|
// PreConditioned file name - used only for pre and post conditioning
|
||||||
|
// a data set for parallel runs
|
||||||
|
word preConName_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
// Public classes
|
||||||
|
|
||||||
|
//- Less function class used in sorting timeClusters
|
||||||
|
class less
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
bool operator()(const timeCluster& one, const timeCluster& two) const
|
||||||
|
{
|
||||||
|
return one.globalMinValue() < two.globalMinValue();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// Static data members
|
||||||
|
|
||||||
|
static const char* const typeName;
|
||||||
|
|
||||||
|
|
||||||
|
// Constructors
|
||||||
|
|
||||||
|
//- Construct null
|
||||||
|
timeCluster();
|
||||||
|
|
||||||
|
//- Construct from components
|
||||||
|
timeCluster
|
||||||
|
(
|
||||||
|
const instantList& times,
|
||||||
|
const scalar globalOffset,
|
||||||
|
const label superLoop,
|
||||||
|
const word& solverDomainName,
|
||||||
|
const word& preConName = word::null
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Construct given a timeCluster and an index
|
||||||
|
// This creates a 'timeCluster' that holds a single instant
|
||||||
|
// in time, whose other values match those of tc.
|
||||||
|
timeCluster
|
||||||
|
(
|
||||||
|
const timeCluster& tc,
|
||||||
|
const label index
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Construct a time cluster given a scalar value. This constructs
|
||||||
|
// a timeCluster with a single instant of time at value t, and whose
|
||||||
|
// other values are zero or empty.
|
||||||
|
explicit timeCluster(const scalar t);
|
||||||
|
|
||||||
|
// Member Functions
|
||||||
|
|
||||||
|
// Access
|
||||||
|
|
||||||
|
//- Times
|
||||||
|
inline const instantList& times() const;
|
||||||
|
|
||||||
|
inline instantList& times();
|
||||||
|
|
||||||
|
//- Global offset
|
||||||
|
inline scalar globalOffset() const;
|
||||||
|
|
||||||
|
inline scalar& globalOffset();
|
||||||
|
|
||||||
|
//- SuperLoop
|
||||||
|
inline label superLoop() const;
|
||||||
|
|
||||||
|
inline label& superLoop();
|
||||||
|
|
||||||
|
//- Solver domain name
|
||||||
|
inline const word& solverDomainName() const;
|
||||||
|
|
||||||
|
inline word& solverDomainName();
|
||||||
|
|
||||||
|
//- Solver domain name
|
||||||
|
inline const word& preConName() const;
|
||||||
|
|
||||||
|
inline word& preConName();
|
||||||
|
|
||||||
|
// Derived values
|
||||||
|
|
||||||
|
//- Global value at index
|
||||||
|
scalar globalValue(const label& index) const;
|
||||||
|
|
||||||
|
//- Search for and return global min value. If empty,
|
||||||
|
// returns VGREAT.
|
||||||
|
scalar globalMinValue() const;
|
||||||
|
|
||||||
|
//- Search for and return global max value. If empty,
|
||||||
|
// returns 0.
|
||||||
|
scalar globalMaxValue() const;
|
||||||
|
|
||||||
|
//- Search for and return index of global min value
|
||||||
|
label globalMinIndex() const;
|
||||||
|
|
||||||
|
//- Search for and return index of global max value
|
||||||
|
label globalMaxIndex() const;
|
||||||
|
|
||||||
|
//- Global closest time
|
||||||
|
scalar globalFindClosestTimeValue(const scalar) const;
|
||||||
|
|
||||||
|
//- Global closest time index
|
||||||
|
label globalFindClosestTimeIndex(const scalar) const;
|
||||||
|
|
||||||
|
//- Local value at index
|
||||||
|
scalar localValue(const label& index) const;
|
||||||
|
|
||||||
|
//- Search for and return local min value
|
||||||
|
scalar localMinValue() const;
|
||||||
|
|
||||||
|
//- Search for and return local max value
|
||||||
|
scalar localMaxValue() const;
|
||||||
|
|
||||||
|
//- Search for and return index of global min value. If empty,
|
||||||
|
// returns VGREAT
|
||||||
|
label localMinIndex() const;
|
||||||
|
|
||||||
|
//- Search for and return index of global max value. If empty,
|
||||||
|
// returns 0.
|
||||||
|
label localMaxIndex() const;
|
||||||
|
|
||||||
|
//-Local closest time
|
||||||
|
scalar localFindClosestTimeValue(const scalar) const;
|
||||||
|
|
||||||
|
//-Local closest time index
|
||||||
|
label localFindClosestTimeIndex(const scalar) const;
|
||||||
|
|
||||||
|
// Operators
|
||||||
|
|
||||||
|
//- Chip off a single instant given an index, return as timeCluster
|
||||||
|
// This retains superLoop, solverDomain, etc.. with a timevalue
|
||||||
|
timeCluster operator()(const label index) const;
|
||||||
|
|
||||||
|
|
||||||
|
// Friend IOstream Operators
|
||||||
|
|
||||||
|
friend Istream& operator>>(Istream&, timeCluster&);
|
||||||
|
friend Ostream& operator<<(Ostream&, const timeCluster&);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
} // End namespace Foam
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
#include "timeClusterI.H"
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
88
src/multiSolver/timeCluster/timeClusterI.H
Normal file
88
src/multiSolver/timeCluster/timeClusterI.H
Normal file
|
@ -0,0 +1,88 @@
|
||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / 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
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
|
||||||
|
inline const instantList& timeCluster::times() const
|
||||||
|
{
|
||||||
|
const instantList& times(*this);
|
||||||
|
return times;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline instantList& timeCluster::times()
|
||||||
|
{
|
||||||
|
instantList& times(*this);
|
||||||
|
return times;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline scalar timeCluster::globalOffset() const
|
||||||
|
{
|
||||||
|
return globalOffset_;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline scalar& timeCluster::globalOffset()
|
||||||
|
{
|
||||||
|
return globalOffset_;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline label timeCluster::superLoop() const
|
||||||
|
{
|
||||||
|
return superLoop_;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline label& timeCluster::superLoop()
|
||||||
|
{
|
||||||
|
return superLoop_;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const word& timeCluster::solverDomainName() const
|
||||||
|
{
|
||||||
|
return solverDomainName_;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline word& timeCluster::solverDomainName()
|
||||||
|
{
|
||||||
|
return solverDomainName_;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const word& timeCluster::preConName() const
|
||||||
|
{
|
||||||
|
return preConName_;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline word& timeCluster::preConName()
|
||||||
|
{
|
||||||
|
return preConName_;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
} // End namespace Foam
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
156
src/multiSolver/timeCluster/timeClusterList.C
Normal file
156
src/multiSolver/timeCluster/timeClusterList.C
Normal file
|
@ -0,0 +1,156 @@
|
||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / 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 "timeClusterList.H"
|
||||||
|
#include "Time.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
const char* const Foam::timeClusterList::typeName = "timeClusterList";
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Foam::timeClusterList::timeClusterList()
|
||||||
|
:
|
||||||
|
List<timeCluster>()
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::timeClusterList::timeClusterList(const Foam::label size)
|
||||||
|
:
|
||||||
|
List<timeCluster>(size)
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::timeClusterList::timeClusterList(const timeCluster& tcIn)
|
||||||
|
:
|
||||||
|
List<timeCluster>(1, tcIn)
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::timeClusterList::timeClusterList(const Foam::label size, const Foam::timeCluster& tcIn)
|
||||||
|
:
|
||||||
|
List<timeCluster>(size, tcIn)
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::timeClusterList::timeClusterList(const labelList& subIndices, const timeClusterList& tclIn)
|
||||||
|
:
|
||||||
|
List<timeCluster>(subIndices.size())
|
||||||
|
{
|
||||||
|
forAll(subIndices, i)
|
||||||
|
{
|
||||||
|
this->operator[](i) = tclIn[subIndices[i]];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::timeClusterList::timeClusterList(Foam::Istream& is)
|
||||||
|
:
|
||||||
|
List<timeCluster>(is)
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
void Foam::timeClusterList::globalSort()
|
||||||
|
{
|
||||||
|
Foam::sort(*this, timeCluster::less());
|
||||||
|
}
|
||||||
|
|
||||||
|
void Foam::timeClusterList::append(const timeClusterList& tclIn)
|
||||||
|
{
|
||||||
|
label wasSize = this->size();
|
||||||
|
this->setSize(tclIn.size() + this->size());
|
||||||
|
|
||||||
|
for (label i = 0; i < tclIn.size(); i++)
|
||||||
|
{
|
||||||
|
this->operator[](i + wasSize) = tclIn[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::timeClusterList::append(const timeCluster& tcIn)
|
||||||
|
{
|
||||||
|
label wasSize = this->size();
|
||||||
|
this->setSize(this->size() + 1);
|
||||||
|
|
||||||
|
this->operator[](wasSize) = tcIn;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Foam::timeClusterList::purgeEmpties()
|
||||||
|
{
|
||||||
|
if (!this->size()) return false;
|
||||||
|
|
||||||
|
label empties(0);
|
||||||
|
for (label i = 0; i < this->size(); i++)
|
||||||
|
{
|
||||||
|
if (!this->operator[](i).times().size())
|
||||||
|
{
|
||||||
|
empties++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (empties)
|
||||||
|
{
|
||||||
|
this->operator[](i - empties) = this->operator[](i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (empties)
|
||||||
|
{
|
||||||
|
this->setSize(this->size() - empties);
|
||||||
|
}
|
||||||
|
if (!this->size()) return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
Foam::timeClusterList Foam::timeClusterList::selectiveSubList
|
||||||
|
(
|
||||||
|
const labelList& indices
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
timeClusterList tcl(indices.size());
|
||||||
|
|
||||||
|
forAll(indices, i)
|
||||||
|
{
|
||||||
|
if (indices[i] > this->size())
|
||||||
|
{
|
||||||
|
FatalErrorIn("timeClusterList::selectiveSubList")
|
||||||
|
<< "Out of range index passed to this function. Indices "
|
||||||
|
<< "passed are: \n" << indices << "\nFailure at index " << i
|
||||||
|
<< ", with value " << indices[i] << ".\n This timeClusterList "
|
||||||
|
<< "has size " << this->size() << "."
|
||||||
|
<< abort(FatalError);
|
||||||
|
}
|
||||||
|
|
||||||
|
tcl[i] = this->operator[](indices[i]);
|
||||||
|
}
|
||||||
|
return tcl;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
110
src/multiSolver/timeCluster/timeClusterList.H
Normal file
110
src/multiSolver/timeCluster/timeClusterList.H
Normal file
|
@ -0,0 +1,110 @@
|
||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / 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::timeClusterList
|
||||||
|
|
||||||
|
Description
|
||||||
|
List of timeClusters with some additional functions
|
||||||
|
|
||||||
|
SourceFiles
|
||||||
|
timeClusterList.C
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef timeClusterList_H
|
||||||
|
#define timeClusterList_H
|
||||||
|
|
||||||
|
#include "timeCluster.H"
|
||||||
|
#include "labelList.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
Class timeClusterList Declaration
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
class timeClusterList
|
||||||
|
:
|
||||||
|
public List<timeCluster>
|
||||||
|
{
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
// Static data members
|
||||||
|
|
||||||
|
static const char* const typeName;
|
||||||
|
|
||||||
|
// Constructors
|
||||||
|
|
||||||
|
//- Null constructor
|
||||||
|
timeClusterList();
|
||||||
|
|
||||||
|
//- Construct with given size.
|
||||||
|
explicit timeClusterList(const label);
|
||||||
|
|
||||||
|
//- Construct from a timeCluster.
|
||||||
|
timeClusterList(const timeCluster&);
|
||||||
|
|
||||||
|
//- Construct with given size and value for all elements.
|
||||||
|
timeClusterList(const label, const timeCluster&);
|
||||||
|
|
||||||
|
//- Construct as a sublist of another timeClusterList. This is not
|
||||||
|
// like the SubList in that this is not a new class, rather it is only
|
||||||
|
// producing a new copy that contains the specified entries.
|
||||||
|
timeClusterList(const labelList&, const timeClusterList&);
|
||||||
|
|
||||||
|
//- Construct from Istream.
|
||||||
|
timeClusterList(Istream&);
|
||||||
|
|
||||||
|
// Member functions
|
||||||
|
|
||||||
|
//- Sort by global time
|
||||||
|
void globalSort();
|
||||||
|
|
||||||
|
//- Append another timeClusterList on the end of this one
|
||||||
|
void append(const timeClusterList& tclIn);
|
||||||
|
|
||||||
|
//- Append a timeCluster on the end of this list
|
||||||
|
void append(const timeCluster& tcIn);
|
||||||
|
|
||||||
|
//- Remove timeClusters with empty instantLists return false if all are
|
||||||
|
// empty
|
||||||
|
bool purgeEmpties();
|
||||||
|
|
||||||
|
//- Return a sublist using the specified indexes
|
||||||
|
timeClusterList selectiveSubList(const labelList&) const;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
} // End namespace Foam
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
113
src/multiSolver/tuple2Lists/tuple2Lists.H
Normal file
113
src/multiSolver/tuple2Lists/tuple2Lists.H
Normal file
|
@ -0,0 +1,113 @@
|
||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / 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
|
||||||
|
|
||||||
|
Typedef
|
||||||
|
Foam::tuple2List
|
||||||
|
|
||||||
|
Description
|
||||||
|
List of paired values, with sorting capability
|
||||||
|
|
||||||
|
Author
|
||||||
|
David L. F. Gaden
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef tuple2Lists_H
|
||||||
|
#define tuple2Lists_H
|
||||||
|
|
||||||
|
#include "Tuple2.H"
|
||||||
|
#include "List.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
typedef List<Tuple2<label, label> > labelLabelList;
|
||||||
|
typedef List<Tuple2<label, scalar> > labelScalarList;
|
||||||
|
typedef List<Tuple2<scalar, label> > scalarLabelList;
|
||||||
|
typedef List<Tuple2<scalar, scalar> > scalarScalarList;
|
||||||
|
|
||||||
|
template<class type1, class type2>
|
||||||
|
bool lessFirst(Tuple2<type1, type2> t1, Tuple2<type1, type2> t2)
|
||||||
|
{
|
||||||
|
return (t1.first() < t2.first());
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class type1, class type2>
|
||||||
|
bool lessFirstSecond(Tuple2<type1, type2> t1, Tuple2<type1, type2> t2)
|
||||||
|
{
|
||||||
|
return
|
||||||
|
(
|
||||||
|
(t1.first() < t2.first())
|
||||||
|
|| ((t1.first() == t2.first()) && (t1.second() < t2.second()))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class type1, class type2>
|
||||||
|
bool lessSecond(Tuple2<type1, type2> t1, Tuple2<type1, type2> t2)
|
||||||
|
{
|
||||||
|
return (t1.second() < t2.second());
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class type1, class type2>
|
||||||
|
bool lessSecondFirst(Tuple2<type1, type2> t1, Tuple2<type1, type2> t2)
|
||||||
|
{
|
||||||
|
return
|
||||||
|
(
|
||||||
|
(t2.first() < t1.first())
|
||||||
|
|| ((t2.first() == t1.first()) && (t2.second() < t1.second()))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class type1, class type2>
|
||||||
|
void sortTuple2ListBy1st(List<Tuple2<type1, type2> >& t2l)
|
||||||
|
{
|
||||||
|
sort(t2l, lessFirst<type1, type2>);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class type1, class type2>
|
||||||
|
void sortTuple2ListBy2nd(List<Tuple2<type1, type2> >& t2l)
|
||||||
|
{
|
||||||
|
sort(t2l, lessSecond<type1, type2>);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class type1, class type2>
|
||||||
|
void sortTuple2ListBy1stThen2nd(List<Tuple2<type1, type2> >& t2l)
|
||||||
|
{
|
||||||
|
sort(t2l, lessFirstSecond<type1, type2>);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class type1, class type2>
|
||||||
|
void sortTuple2ListBy2ndThen1st(List<Tuple2<type1, type2> >& t2l)
|
||||||
|
{
|
||||||
|
sort(t2l, lessSecondFirst<type1, type2>);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // End namespace Foam
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
|
@ -0,0 +1,32 @@
|
||||||
|
/*--------------------------------*- C++ -*----------------------------------*\
|
||||||
|
| ========= | |
|
||||||
|
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
|
||||||
|
| \\ / O peration | Version: 1.5-dev |
|
||||||
|
| \\ / A nd | Web: http://www.OpenFOAM.org |
|
||||||
|
| \\/ M anipulation | |
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
FoamFile
|
||||||
|
{
|
||||||
|
version 2.0;
|
||||||
|
format ascii;
|
||||||
|
class dictionary;
|
||||||
|
object multiTransportProperties;
|
||||||
|
}
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
dictionaryName transportProperties;
|
||||||
|
|
||||||
|
multiSolver
|
||||||
|
{
|
||||||
|
scalarTransportFoam
|
||||||
|
{
|
||||||
|
DT DT [0 2 -1 0 0 0 0] 0.0;
|
||||||
|
}
|
||||||
|
icoFoam1
|
||||||
|
{
|
||||||
|
nu nu [0 2 -1 0 0 0 0] 0.01;
|
||||||
|
}
|
||||||
|
icoFoam2
|
||||||
|
{
|
||||||
|
nu nu [0 2 -1 0 0 0 0] 0.01;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,90 @@
|
||||||
|
/*--------------------------------*- C++ -*----------------------------------*\
|
||||||
|
| ========= | |
|
||||||
|
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
|
||||||
|
| \\ / O peration | Version: 1.5 |
|
||||||
|
| \\ / A nd | Web: http://www.OpenFOAM.org |
|
||||||
|
| \\/ M anipulation | |
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
FoamFile
|
||||||
|
{
|
||||||
|
version 2.0;
|
||||||
|
format ascii;
|
||||||
|
class dictionary;
|
||||||
|
object blockMeshDict;
|
||||||
|
}
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
convertToMeters 0.1;
|
||||||
|
|
||||||
|
vertices
|
||||||
|
(
|
||||||
|
(0 0 0)
|
||||||
|
(1.5 0 0)
|
||||||
|
(1.5 1 0)
|
||||||
|
(0 1 0)
|
||||||
|
(2.5 0 0)
|
||||||
|
(4 0 0)
|
||||||
|
(4 1 0)
|
||||||
|
(2.5 1 0)
|
||||||
|
(1.5 2.5 0)
|
||||||
|
(2.5 2.5 0)
|
||||||
|
|
||||||
|
(0 0 0.1)
|
||||||
|
(1.5 0 0.1)
|
||||||
|
(1.5 1 0.1)
|
||||||
|
(0 1 0.1)
|
||||||
|
(2.5 0 0.1)
|
||||||
|
(4 0 0.1)
|
||||||
|
(4 1 0.1)
|
||||||
|
(2.5 1 0.1)
|
||||||
|
(1.5 2.5 0.1)
|
||||||
|
(2.5 2.5 0.1)
|
||||||
|
|
||||||
|
);
|
||||||
|
|
||||||
|
blocks
|
||||||
|
(
|
||||||
|
hex (0 1 2 3 10 11 12 13) (20 20 1) simpleGrading (1 1 1)
|
||||||
|
hex (1 4 7 2 11 14 17 12) (20 20 1) simpleGrading (1 1 1)
|
||||||
|
hex (4 5 6 7 14 15 16 17) (20 20 1) simpleGrading (1 1 1)
|
||||||
|
hex (2 7 9 8 12 17 19 18) (20 20 1) simpleGrading (1 1 1)
|
||||||
|
);
|
||||||
|
|
||||||
|
edges
|
||||||
|
(
|
||||||
|
);
|
||||||
|
|
||||||
|
patches
|
||||||
|
(
|
||||||
|
wall steetWalls
|
||||||
|
(
|
||||||
|
(1 0 10 11)
|
||||||
|
(4 1 11 14)
|
||||||
|
(5 4 14 15)
|
||||||
|
(2 3 13 12)
|
||||||
|
(6 7 17 16)
|
||||||
|
)
|
||||||
|
wall branchWalls
|
||||||
|
(
|
||||||
|
(8 2 12 18)
|
||||||
|
(7 9 19 17)
|
||||||
|
)
|
||||||
|
patch westStreet
|
||||||
|
(
|
||||||
|
(3 0 10 13)
|
||||||
|
)
|
||||||
|
patch eastStreet
|
||||||
|
(
|
||||||
|
(5 6 16 15)
|
||||||
|
)
|
||||||
|
patch northBranch
|
||||||
|
(
|
||||||
|
(9 8 18 19)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
mergePatchPairs
|
||||||
|
(
|
||||||
|
);
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
|
@ -0,0 +1,58 @@
|
||||||
|
/*--------------------------------*- C++ -*----------------------------------*\
|
||||||
|
| ========= | |
|
||||||
|
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
|
||||||
|
| \\ / O peration | Version: 1.5-dev |
|
||||||
|
| \\ / A nd | Revision: exported |
|
||||||
|
| \\/ M anipulation | Web: http://www.OpenFOAM.org |
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
FoamFile
|
||||||
|
{
|
||||||
|
version 2.0;
|
||||||
|
format ascii;
|
||||||
|
class polyBoundaryMesh;
|
||||||
|
location "constant/polyMesh";
|
||||||
|
object boundary;
|
||||||
|
}
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
6
|
||||||
|
(
|
||||||
|
steetWalls
|
||||||
|
{
|
||||||
|
type wall;
|
||||||
|
nFaces 100;
|
||||||
|
startFace 3100;
|
||||||
|
}
|
||||||
|
branchWalls
|
||||||
|
{
|
||||||
|
type wall;
|
||||||
|
nFaces 40;
|
||||||
|
startFace 3200;
|
||||||
|
}
|
||||||
|
westStreet
|
||||||
|
{
|
||||||
|
type patch;
|
||||||
|
nFaces 20;
|
||||||
|
startFace 3240;
|
||||||
|
}
|
||||||
|
eastStreet
|
||||||
|
{
|
||||||
|
type patch;
|
||||||
|
nFaces 20;
|
||||||
|
startFace 3260;
|
||||||
|
}
|
||||||
|
northBranch
|
||||||
|
{
|
||||||
|
type patch;
|
||||||
|
nFaces 20;
|
||||||
|
startFace 3280;
|
||||||
|
}
|
||||||
|
defaultFaces
|
||||||
|
{
|
||||||
|
type empty;
|
||||||
|
nFaces 3200;
|
||||||
|
startFace 3300;
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
|
@ -0,0 +1,21 @@
|
||||||
|
/*--------------------------------*- C++ -*----------------------------------*\
|
||||||
|
| ========= | |
|
||||||
|
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
|
||||||
|
| \\ / O peration | Version: 1.7.1 |
|
||||||
|
| \\ / A nd | Web: www.OpenFOAM.com |
|
||||||
|
| \\/ M anipulation | |
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
FoamFile
|
||||||
|
{
|
||||||
|
version 2.0;
|
||||||
|
format ascii;
|
||||||
|
class dictionary;
|
||||||
|
location "constant";
|
||||||
|
object transportProperties;
|
||||||
|
}
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
nu nu [ 0 2 -1 0 0 0 0 ] 0.01;
|
||||||
|
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
|
@ -0,0 +1,50 @@
|
||||||
|
/*--------------------------------*- C++ -*----------------------------------*\
|
||||||
|
| ========= | |
|
||||||
|
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
|
||||||
|
| \\ / O peration | Version: 1.5 |
|
||||||
|
| \\ / A nd | Web: http://www.OpenFOAM.org |
|
||||||
|
| \\/ M anipulation | |
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
FoamFile
|
||||||
|
{
|
||||||
|
version 2.0;
|
||||||
|
format ascii;
|
||||||
|
class volScalarField;
|
||||||
|
object p;
|
||||||
|
}
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
dimensions [0 0 0 1 0 0 0];
|
||||||
|
|
||||||
|
internalField uniform 0;
|
||||||
|
|
||||||
|
boundaryField
|
||||||
|
{
|
||||||
|
steetWalls
|
||||||
|
{
|
||||||
|
type zeroGradient;
|
||||||
|
}
|
||||||
|
branchWalls
|
||||||
|
{
|
||||||
|
type zeroGradient;
|
||||||
|
}
|
||||||
|
westStreet
|
||||||
|
{
|
||||||
|
type zeroGradient;
|
||||||
|
}
|
||||||
|
eastStreet
|
||||||
|
{
|
||||||
|
type zeroGradient;
|
||||||
|
}
|
||||||
|
northBranch // inlet
|
||||||
|
{
|
||||||
|
type fixedValue;
|
||||||
|
value uniform 1;
|
||||||
|
}
|
||||||
|
defaultFaces
|
||||||
|
{
|
||||||
|
type empty;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
|
@ -0,0 +1,53 @@
|
||||||
|
/*--------------------------------*- C++ -*----------------------------------*\
|
||||||
|
| ========= | |
|
||||||
|
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
|
||||||
|
| \\ / O peration | Version: 1.5 |
|
||||||
|
| \\ / A nd | Web: http://www.OpenFOAM.org |
|
||||||
|
| \\/ M anipulation | |
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
FoamFile
|
||||||
|
{
|
||||||
|
version 2.0;
|
||||||
|
format ascii;
|
||||||
|
class volVectorField;
|
||||||
|
object U;
|
||||||
|
}
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
dimensions [0 1 -1 0 0 0 0];
|
||||||
|
|
||||||
|
internalField uniform (0 0 0);
|
||||||
|
|
||||||
|
boundaryField
|
||||||
|
{
|
||||||
|
steetWalls
|
||||||
|
{
|
||||||
|
type fixedValue;
|
||||||
|
value uniform (0 0 0);
|
||||||
|
}
|
||||||
|
branchWalls
|
||||||
|
{
|
||||||
|
type fixedValue;
|
||||||
|
value uniform (0 0 0);
|
||||||
|
}
|
||||||
|
westStreet // closed
|
||||||
|
{
|
||||||
|
type fixedValue;
|
||||||
|
value uniform (0 0 0);
|
||||||
|
}
|
||||||
|
eastStreet // outlet
|
||||||
|
{
|
||||||
|
type zeroGradient;
|
||||||
|
}
|
||||||
|
northBranch // inlet
|
||||||
|
{
|
||||||
|
type fixedValue;
|
||||||
|
value uniform (0 -1 0);
|
||||||
|
}
|
||||||
|
defaultFaces
|
||||||
|
{
|
||||||
|
type empty;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
|
@ -0,0 +1,50 @@
|
||||||
|
/*--------------------------------*- C++ -*----------------------------------*\
|
||||||
|
| ========= | |
|
||||||
|
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
|
||||||
|
| \\ / O peration | Version: 1.5 |
|
||||||
|
| \\ / A nd | Web: http://www.OpenFOAM.org |
|
||||||
|
| \\/ M anipulation | |
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
FoamFile
|
||||||
|
{
|
||||||
|
version 2.0;
|
||||||
|
format ascii;
|
||||||
|
class volScalarField;
|
||||||
|
object p;
|
||||||
|
}
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
dimensions [0 2 -2 0 0 0 0];
|
||||||
|
|
||||||
|
internalField uniform 0;
|
||||||
|
|
||||||
|
boundaryField
|
||||||
|
{
|
||||||
|
steetWalls
|
||||||
|
{
|
||||||
|
type zeroGradient;
|
||||||
|
}
|
||||||
|
branchWalls
|
||||||
|
{
|
||||||
|
type zeroGradient;
|
||||||
|
}
|
||||||
|
westStreet // closed
|
||||||
|
{
|
||||||
|
type zeroGradient;
|
||||||
|
}
|
||||||
|
eastStreet // outlet
|
||||||
|
{
|
||||||
|
type fixedValue;
|
||||||
|
value uniform 0;
|
||||||
|
}
|
||||||
|
northBranch // inlet
|
||||||
|
{
|
||||||
|
type zeroGradient;
|
||||||
|
}
|
||||||
|
defaultFaces
|
||||||
|
{
|
||||||
|
type empty;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
|
@ -0,0 +1,50 @@
|
||||||
|
/*--------------------------------*- C++ -*----------------------------------*\
|
||||||
|
| ========= | |
|
||||||
|
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
|
||||||
|
| \\ / O peration | Version: 1.5 |
|
||||||
|
| \\ / A nd | Web: http://www.OpenFOAM.org |
|
||||||
|
| \\/ M anipulation | |
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
FoamFile
|
||||||
|
{
|
||||||
|
version 2.0;
|
||||||
|
format ascii;
|
||||||
|
class volScalarField;
|
||||||
|
object p;
|
||||||
|
}
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
dimensions [0 0 0 1 0 0 0];
|
||||||
|
|
||||||
|
internalField uniform 0;
|
||||||
|
|
||||||
|
boundaryField
|
||||||
|
{
|
||||||
|
steetWalls
|
||||||
|
{
|
||||||
|
type zeroGradient;
|
||||||
|
}
|
||||||
|
branchWalls
|
||||||
|
{
|
||||||
|
type zeroGradient;
|
||||||
|
}
|
||||||
|
westStreet
|
||||||
|
{
|
||||||
|
type zeroGradient;
|
||||||
|
}
|
||||||
|
eastStreet
|
||||||
|
{
|
||||||
|
type zeroGradient;
|
||||||
|
}
|
||||||
|
northBranch
|
||||||
|
{
|
||||||
|
type fixedValue;
|
||||||
|
value uniform 1;
|
||||||
|
}
|
||||||
|
defaultFaces
|
||||||
|
{
|
||||||
|
type empty;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
|
@ -0,0 +1,52 @@
|
||||||
|
/*--------------------------------*- C++ -*----------------------------------*\
|
||||||
|
| ========= | |
|
||||||
|
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
|
||||||
|
| \\ / O peration | Version: 1.5 |
|
||||||
|
| \\ / A nd | Web: http://www.OpenFOAM.org |
|
||||||
|
| \\/ M anipulation | |
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
FoamFile
|
||||||
|
{
|
||||||
|
version 2.0;
|
||||||
|
format ascii;
|
||||||
|
class volVectorField;
|
||||||
|
object U;
|
||||||
|
}
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
dimensions [0 1 -1 0 0 0 0];
|
||||||
|
|
||||||
|
internalField uniform (0 0 0);
|
||||||
|
|
||||||
|
boundaryField
|
||||||
|
{
|
||||||
|
steetWalls
|
||||||
|
{
|
||||||
|
type fixedValue;
|
||||||
|
value uniform (0 0 0);
|
||||||
|
}
|
||||||
|
branchWalls
|
||||||
|
{
|
||||||
|
type fixedValue;
|
||||||
|
value uniform (0 0 0);
|
||||||
|
}
|
||||||
|
westStreet // outlet
|
||||||
|
{
|
||||||
|
type zeroGradient;
|
||||||
|
}
|
||||||
|
eastStreet // inlet
|
||||||
|
{
|
||||||
|
type fixedValue;
|
||||||
|
value uniform (-1 0 0);
|
||||||
|
}
|
||||||
|
northBranch // outlet
|
||||||
|
{
|
||||||
|
type zeroGradient;
|
||||||
|
}
|
||||||
|
defaultFaces
|
||||||
|
{
|
||||||
|
type empty;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
|
@ -0,0 +1,51 @@
|
||||||
|
/*--------------------------------*- C++ -*----------------------------------*\
|
||||||
|
| ========= | |
|
||||||
|
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
|
||||||
|
| \\ / O peration | Version: 1.5 |
|
||||||
|
| \\ / A nd | Web: http://www.OpenFOAM.org |
|
||||||
|
| \\/ M anipulation | |
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
FoamFile
|
||||||
|
{
|
||||||
|
version 2.0;
|
||||||
|
format ascii;
|
||||||
|
class volScalarField;
|
||||||
|
object p;
|
||||||
|
}
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
dimensions [0 2 -2 0 0 0 0];
|
||||||
|
|
||||||
|
internalField uniform 0;
|
||||||
|
|
||||||
|
boundaryField
|
||||||
|
{
|
||||||
|
steetWalls
|
||||||
|
{
|
||||||
|
type zeroGradient;
|
||||||
|
}
|
||||||
|
branchWalls
|
||||||
|
{
|
||||||
|
type zeroGradient;
|
||||||
|
}
|
||||||
|
westStreet // outlet
|
||||||
|
{
|
||||||
|
type fixedValue;
|
||||||
|
value uniform 0;
|
||||||
|
}
|
||||||
|
eastStreet // inlet
|
||||||
|
{
|
||||||
|
type zeroGradient;
|
||||||
|
}
|
||||||
|
northBranch // outlet
|
||||||
|
{
|
||||||
|
type fixedValue;
|
||||||
|
value uniform 0;
|
||||||
|
}
|
||||||
|
defaultFaces
|
||||||
|
{
|
||||||
|
type empty;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
|
@ -0,0 +1,50 @@
|
||||||
|
/*--------------------------------*- C++ -*----------------------------------*\
|
||||||
|
| ========= | |
|
||||||
|
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
|
||||||
|
| \\ / O peration | Version: 1.5 |
|
||||||
|
| \\ / A nd | Web: http://www.OpenFOAM.org |
|
||||||
|
| \\/ M anipulation | |
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
FoamFile
|
||||||
|
{
|
||||||
|
version 2.0;
|
||||||
|
format ascii;
|
||||||
|
class volScalarField;
|
||||||
|
object p;
|
||||||
|
}
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
dimensions [0 0 0 1 0 0 0];
|
||||||
|
|
||||||
|
internalField uniform 0;
|
||||||
|
|
||||||
|
boundaryField
|
||||||
|
{
|
||||||
|
steetWalls
|
||||||
|
{
|
||||||
|
type zeroGradient;
|
||||||
|
}
|
||||||
|
branchWalls
|
||||||
|
{
|
||||||
|
type zeroGradient;
|
||||||
|
}
|
||||||
|
westStreet
|
||||||
|
{
|
||||||
|
type zeroGradient;
|
||||||
|
}
|
||||||
|
eastStreet
|
||||||
|
{
|
||||||
|
type zeroGradient;
|
||||||
|
}
|
||||||
|
northBranch // inlet
|
||||||
|
{
|
||||||
|
type fixedValue;
|
||||||
|
value uniform 1;
|
||||||
|
}
|
||||||
|
defaultFaces
|
||||||
|
{
|
||||||
|
type empty;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
|
@ -0,0 +1,52 @@
|
||||||
|
/*--------------------------------*- C++ -*----------------------------------*\
|
||||||
|
| ========= | |
|
||||||
|
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
|
||||||
|
| \\ / O peration | Version: 1.5 |
|
||||||
|
| \\ / A nd | Web: http://www.OpenFOAM.org |
|
||||||
|
| \\/ M anipulation | |
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
FoamFile
|
||||||
|
{
|
||||||
|
version 2.0;
|
||||||
|
format ascii;
|
||||||
|
class volVectorField;
|
||||||
|
object U;
|
||||||
|
}
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
dimensions [0 1 -1 0 0 0 0];
|
||||||
|
|
||||||
|
internalField uniform (0 0 0);
|
||||||
|
|
||||||
|
boundaryField
|
||||||
|
{
|
||||||
|
steetWalls
|
||||||
|
{
|
||||||
|
type fixedValue;
|
||||||
|
value uniform (0 0 0);
|
||||||
|
}
|
||||||
|
branchWalls
|
||||||
|
{
|
||||||
|
type fixedValue;
|
||||||
|
value uniform (0 0 0);
|
||||||
|
}
|
||||||
|
westStreet // outlet
|
||||||
|
{
|
||||||
|
type zeroGradient;
|
||||||
|
}
|
||||||
|
eastStreet // closed
|
||||||
|
{
|
||||||
|
type zeroGradient;
|
||||||
|
}
|
||||||
|
northBranch // inlet
|
||||||
|
{
|
||||||
|
type fixedValue;
|
||||||
|
value uniform (0 -1 0);
|
||||||
|
}
|
||||||
|
defaultFaces
|
||||||
|
{
|
||||||
|
type empty;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
|
@ -0,0 +1,47 @@
|
||||||
|
/*--------------------------------*- C++ -*----------------------------------*\
|
||||||
|
| ========= | |
|
||||||
|
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
|
||||||
|
| \\ / O peration | Version: 1.7.1 |
|
||||||
|
| \\ / A nd | Web: www.OpenFOAM.com |
|
||||||
|
| \\/ M anipulation | |
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
FoamFile
|
||||||
|
{
|
||||||
|
version 2.0;
|
||||||
|
format ascii;
|
||||||
|
class dictionary;
|
||||||
|
location "system";
|
||||||
|
object controlDict;
|
||||||
|
}
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
writeFormat ascii;
|
||||||
|
|
||||||
|
writePrecision 6;
|
||||||
|
|
||||||
|
writeCompression uncompressed;
|
||||||
|
|
||||||
|
runTimeModifiable yes;
|
||||||
|
|
||||||
|
application icoFoam;
|
||||||
|
|
||||||
|
deltaT 0.01;
|
||||||
|
|
||||||
|
writeControl timeStep;
|
||||||
|
|
||||||
|
writeInterval 1;
|
||||||
|
|
||||||
|
startFrom startTime;
|
||||||
|
|
||||||
|
startTime 0.1;
|
||||||
|
|
||||||
|
stopAt endTime;
|
||||||
|
|
||||||
|
endTime 0.1;
|
||||||
|
|
||||||
|
timeFormat scientific;
|
||||||
|
|
||||||
|
timePrecision 6;
|
||||||
|
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
|
@ -0,0 +1,60 @@
|
||||||
|
/*--------------------------------*- C++ -*----------------------------------*\
|
||||||
|
| ========= | |
|
||||||
|
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
|
||||||
|
| \\ / O peration | Version: 1.7.1 |
|
||||||
|
| \\ / A nd | Web: www.OpenFOAM.com |
|
||||||
|
| \\/ M anipulation | |
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
FoamFile
|
||||||
|
{
|
||||||
|
version 2.0;
|
||||||
|
format ascii;
|
||||||
|
class dictionary;
|
||||||
|
location "system";
|
||||||
|
object fvSchemes;
|
||||||
|
}
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
ddtSchemes
|
||||||
|
{
|
||||||
|
default Euler;
|
||||||
|
}
|
||||||
|
|
||||||
|
gradSchemes
|
||||||
|
{
|
||||||
|
default Gauss linear;
|
||||||
|
grad(p) Gauss linear;
|
||||||
|
}
|
||||||
|
|
||||||
|
divSchemes
|
||||||
|
{
|
||||||
|
default none;
|
||||||
|
div(phi,U) Gauss linear;
|
||||||
|
}
|
||||||
|
|
||||||
|
laplacianSchemes
|
||||||
|
{
|
||||||
|
default none;
|
||||||
|
laplacian(nu,U) Gauss linear corrected;
|
||||||
|
laplacian((1|A(U)),p) Gauss linear corrected;
|
||||||
|
}
|
||||||
|
|
||||||
|
interpolationSchemes
|
||||||
|
{
|
||||||
|
default linear;
|
||||||
|
interpolate(HbyA) linear;
|
||||||
|
}
|
||||||
|
|
||||||
|
snGradSchemes
|
||||||
|
{
|
||||||
|
default corrected;
|
||||||
|
}
|
||||||
|
|
||||||
|
fluxRequired
|
||||||
|
{
|
||||||
|
default no;
|
||||||
|
p ;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
|
@ -0,0 +1,45 @@
|
||||||
|
/*--------------------------------*- C++ -*----------------------------------*\
|
||||||
|
| ========= | |
|
||||||
|
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
|
||||||
|
| \\ / O peration | Version: 1.7.1 |
|
||||||
|
| \\ / A nd | Web: www.OpenFOAM.com |
|
||||||
|
| \\/ M anipulation | |
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
FoamFile
|
||||||
|
{
|
||||||
|
version 2.0;
|
||||||
|
format ascii;
|
||||||
|
class dictionary;
|
||||||
|
location "system";
|
||||||
|
object fvSolution;
|
||||||
|
}
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
solvers
|
||||||
|
{
|
||||||
|
p
|
||||||
|
{
|
||||||
|
solver PCG;
|
||||||
|
preconditioner DIC;
|
||||||
|
tolerance 1e-06;
|
||||||
|
relTol 0;
|
||||||
|
}
|
||||||
|
U
|
||||||
|
{
|
||||||
|
solver PBiCG;
|
||||||
|
preconditioner DILU;
|
||||||
|
tolerance 1e-05;
|
||||||
|
relTol 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
PISO
|
||||||
|
{
|
||||||
|
nCorrectors 2;
|
||||||
|
nNonOrthogonalCorrectors 0;
|
||||||
|
pRefCell 0;
|
||||||
|
pRefValue 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
|
@ -0,0 +1,70 @@
|
||||||
|
/*--------------------------------*- C++ -*----------------------------------*\
|
||||||
|
| ========= | |
|
||||||
|
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
|
||||||
|
| \\ / O peration | Version: 1.5-dev |
|
||||||
|
| \\ / A nd | Web: http://www.OpenFOAM.org |
|
||||||
|
| \\/ M anipulation | |
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
FoamFile
|
||||||
|
{
|
||||||
|
version 2.0;
|
||||||
|
format ascii;
|
||||||
|
class dictionary;
|
||||||
|
object multiSolverDict;
|
||||||
|
}
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
multiSolverControl
|
||||||
|
{
|
||||||
|
initialStartFrom startTime;
|
||||||
|
startTime 0;
|
||||||
|
finalStopAt endSuperLoop;
|
||||||
|
endSuperLoop 3;
|
||||||
|
timeFormat scientific;
|
||||||
|
timePrecision 6;
|
||||||
|
}
|
||||||
|
|
||||||
|
solverDomains
|
||||||
|
{
|
||||||
|
icoFoam1
|
||||||
|
{
|
||||||
|
application icoFoam;
|
||||||
|
startFrom startTime;
|
||||||
|
startTime 0;
|
||||||
|
stopAt endTime;
|
||||||
|
endTime 0.1;
|
||||||
|
deltaT 0.01;
|
||||||
|
writeControl timeStep;
|
||||||
|
writeInterval 1;
|
||||||
|
storeFields ( T );
|
||||||
|
}
|
||||||
|
icoFoam2
|
||||||
|
{
|
||||||
|
application icoFoam;
|
||||||
|
startFrom startTime;
|
||||||
|
startTime 0;
|
||||||
|
stopAt endTime;
|
||||||
|
endTime 0.1;
|
||||||
|
deltaT 0.01;
|
||||||
|
writeControl timeStep;
|
||||||
|
writeInterval 1;
|
||||||
|
storeFields ( T );
|
||||||
|
}
|
||||||
|
scalarTransportFoam
|
||||||
|
{
|
||||||
|
application scalarTransportFoam;
|
||||||
|
startFrom latestTimeAllDomains;
|
||||||
|
stopAt elapsedTime;
|
||||||
|
elapsedTime 1;
|
||||||
|
deltaT 0.1;
|
||||||
|
writeControl timeStep;
|
||||||
|
writeInterval 1;
|
||||||
|
storeFields ( p );
|
||||||
|
}
|
||||||
|
default
|
||||||
|
{
|
||||||
|
writeFormat ascii;
|
||||||
|
writePrecision 6;
|
||||||
|
writeCompression uncompressed;
|
||||||
|
runTimeModifiable yes;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,150 @@
|
||||||
|
/*--------------------------------*- C++ -*----------------------------------*\
|
||||||
|
| ========= | |
|
||||||
|
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
|
||||||
|
| \\ / O peration | Version: 1.5-dev |
|
||||||
|
| \\ / A nd | Web: http://www.OpenFOAM.org |
|
||||||
|
| \\/ M anipulation | |
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
FoamFile
|
||||||
|
{
|
||||||
|
version 2.0;
|
||||||
|
format ascii;
|
||||||
|
class dictionary;
|
||||||
|
object multiFvSchemes;
|
||||||
|
}
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
dictionaryName fvSchemes;
|
||||||
|
|
||||||
|
multiSolver
|
||||||
|
{
|
||||||
|
icoFoam1
|
||||||
|
{
|
||||||
|
ddtSchemes
|
||||||
|
{
|
||||||
|
default Euler;
|
||||||
|
}
|
||||||
|
|
||||||
|
gradSchemes
|
||||||
|
{
|
||||||
|
default Gauss linear;
|
||||||
|
grad(p) Gauss linear;
|
||||||
|
}
|
||||||
|
|
||||||
|
divSchemes
|
||||||
|
{
|
||||||
|
default none;
|
||||||
|
div(phi,U) Gauss linear;
|
||||||
|
}
|
||||||
|
|
||||||
|
laplacianSchemes
|
||||||
|
{
|
||||||
|
default none;
|
||||||
|
laplacian(nu,U) Gauss linear corrected;
|
||||||
|
laplacian((1|A(U)),p) Gauss linear corrected;
|
||||||
|
}
|
||||||
|
|
||||||
|
interpolationSchemes
|
||||||
|
{
|
||||||
|
default linear;
|
||||||
|
interpolate(HbyA) linear;
|
||||||
|
}
|
||||||
|
|
||||||
|
snGradSchemes
|
||||||
|
{
|
||||||
|
default corrected;
|
||||||
|
}
|
||||||
|
|
||||||
|
fluxRequired
|
||||||
|
{
|
||||||
|
default no;
|
||||||
|
p;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
icoFoam2
|
||||||
|
{
|
||||||
|
ddtSchemes
|
||||||
|
{
|
||||||
|
default Euler;
|
||||||
|
}
|
||||||
|
|
||||||
|
gradSchemes
|
||||||
|
{
|
||||||
|
default Gauss linear;
|
||||||
|
grad(p) Gauss linear;
|
||||||
|
}
|
||||||
|
|
||||||
|
divSchemes
|
||||||
|
{
|
||||||
|
default none;
|
||||||
|
div(phi,U) Gauss linear;
|
||||||
|
}
|
||||||
|
|
||||||
|
laplacianSchemes
|
||||||
|
{
|
||||||
|
default none;
|
||||||
|
laplacian(nu,U) Gauss linear corrected;
|
||||||
|
laplacian((1|A(U)),p) Gauss linear corrected;
|
||||||
|
}
|
||||||
|
|
||||||
|
interpolationSchemes
|
||||||
|
{
|
||||||
|
default linear;
|
||||||
|
interpolate(HbyA) linear;
|
||||||
|
}
|
||||||
|
|
||||||
|
snGradSchemes
|
||||||
|
{
|
||||||
|
default corrected;
|
||||||
|
}
|
||||||
|
|
||||||
|
fluxRequired
|
||||||
|
{
|
||||||
|
default no;
|
||||||
|
p;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
scalarTransportFoam
|
||||||
|
{
|
||||||
|
ddtSchemes
|
||||||
|
{
|
||||||
|
default none;
|
||||||
|
ddt(T) Euler;
|
||||||
|
}
|
||||||
|
|
||||||
|
gradSchemes
|
||||||
|
{
|
||||||
|
default Gauss linear;
|
||||||
|
}
|
||||||
|
|
||||||
|
divSchemes
|
||||||
|
{
|
||||||
|
default none;
|
||||||
|
div(phi,T) Gauss upwind;
|
||||||
|
}
|
||||||
|
|
||||||
|
laplacianSchemes
|
||||||
|
{
|
||||||
|
default none;
|
||||||
|
laplacian(DT,T) Gauss linear corrected;
|
||||||
|
}
|
||||||
|
|
||||||
|
interpolationSchemes
|
||||||
|
{
|
||||||
|
default linear;
|
||||||
|
}
|
||||||
|
|
||||||
|
snGradSchemes
|
||||||
|
{
|
||||||
|
default corrected;
|
||||||
|
}
|
||||||
|
|
||||||
|
fluxRequired
|
||||||
|
{
|
||||||
|
default no;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
|
@ -0,0 +1,100 @@
|
||||||
|
/*--------------------------------*- C++ -*----------------------------------*\
|
||||||
|
| ========= | |
|
||||||
|
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
|
||||||
|
| \\ / O peration | Version: 1.5-dev |
|
||||||
|
| \\ / A nd | Web: http://www.OpenFOAM.org |
|
||||||
|
| \\/ M anipulation | |
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
FoamFile
|
||||||
|
{
|
||||||
|
version 2.0;
|
||||||
|
format ascii;
|
||||||
|
class dictionary;
|
||||||
|
object multiFvSolution;
|
||||||
|
}
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
dictionaryName fvSolution;
|
||||||
|
|
||||||
|
multiSolver
|
||||||
|
{
|
||||||
|
icoFoam1
|
||||||
|
{
|
||||||
|
solvers
|
||||||
|
{
|
||||||
|
p
|
||||||
|
{
|
||||||
|
solver PCG;
|
||||||
|
preconditioner DIC;
|
||||||
|
tolerance 1e-06;
|
||||||
|
relTol 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
U
|
||||||
|
{
|
||||||
|
solver PBiCG;
|
||||||
|
preconditioner DILU;
|
||||||
|
tolerance 1e-05;
|
||||||
|
relTol 0;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
PISO
|
||||||
|
{
|
||||||
|
nCorrectors 2;
|
||||||
|
nNonOrthogonalCorrectors 0;
|
||||||
|
pRefCell 0;
|
||||||
|
pRefValue 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
icoFoam2
|
||||||
|
{
|
||||||
|
solvers
|
||||||
|
{
|
||||||
|
p
|
||||||
|
{
|
||||||
|
solver PCG;
|
||||||
|
preconditioner DIC;
|
||||||
|
tolerance 1e-06;
|
||||||
|
relTol 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
U
|
||||||
|
{
|
||||||
|
solver PBiCG;
|
||||||
|
preconditioner DILU;
|
||||||
|
tolerance 1e-05;
|
||||||
|
relTol 0;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
PISO
|
||||||
|
{
|
||||||
|
nCorrectors 2;
|
||||||
|
nNonOrthogonalCorrectors 0;
|
||||||
|
pRefCell 0;
|
||||||
|
pRefValue 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
scalarTransportFoam
|
||||||
|
{
|
||||||
|
solvers
|
||||||
|
{
|
||||||
|
T
|
||||||
|
{
|
||||||
|
solver PBiCG;
|
||||||
|
preconditioner DILU;
|
||||||
|
tolerance 1e-05;
|
||||||
|
relTol 0;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
SIMPLE
|
||||||
|
{
|
||||||
|
nNonOrthogonalCorrectors 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
Reference in a new issue