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.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
|
||||
|
|
|
@ -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 libso OpenFOAM
|
||||
|
||||
wmake libso multiSolver
|
||||
|
||||
# Decomposition methods needed by meshTools
|
||||
decompositionMethods/AllwmakeLnInclude
|
||||
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