mirror of
https://develop.openfoam.com/Development/openfoam.git
synced 2025-11-28 03:28:01 +00:00
Merge branch 'develop-pre-release' of develop.openfoam.com:Development/OpenFOAM-plus into develop-pre-release
This commit is contained in:
@ -3,7 +3,7 @@ cd ${0%/*} || exit 1 # Run from this directory
|
|||||||
|
|
||||||
#------------------------------------------------------------------------------
|
#------------------------------------------------------------------------------
|
||||||
|
|
||||||
wmake libso CompressibleTwoPhaseMixtureTurbulenceModels
|
wmake $targetType CompressibleTwoPhaseMixtureTurbulenceModels
|
||||||
wmake
|
wmake $targetType
|
||||||
|
|
||||||
#------------------------------------------------------------------------------
|
#------------------------------------------------------------------------------
|
||||||
|
|||||||
@ -1,11 +1,10 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
cd ${0%/*} || exit 1 # Run from this directory
|
cd ${0%/*} || exit 1 # Run from this directory
|
||||||
targetType=libso # Preferred library type
|
|
||||||
. $WM_PROJECT_DIR/wmake/scripts/AllwmakeParseArguments
|
. $WM_PROJECT_DIR/wmake/scripts/AllwmakeParseArguments
|
||||||
|
|
||||||
#------------------------------------------------------------------------------
|
#------------------------------------------------------------------------------
|
||||||
|
|
||||||
wmake $targetType temperaturePhaseChangeTwoPhaseMixtures
|
wmake $targetType temperaturePhaseChangeTwoPhaseMixtures
|
||||||
wmake
|
wmake $targetType
|
||||||
|
|
||||||
#------------------------------------------------------------------------------
|
#------------------------------------------------------------------------------
|
||||||
|
|||||||
@ -12,8 +12,8 @@ if have_cgal
|
|||||||
then
|
then
|
||||||
wmake $targetType conformalVoronoiMesh
|
wmake $targetType conformalVoronoiMesh
|
||||||
wmake $targetType conformalVoronoi2DMesh
|
wmake $targetType conformalVoronoi2DMesh
|
||||||
wmake foamyQuadMesh
|
wmake $targetType foamyQuadMesh
|
||||||
wmake foamyHexMesh
|
wmake $targetType foamyHexMesh
|
||||||
# wmake foamyHexMeshBackgroundMesh
|
# wmake foamyHexMeshBackgroundMesh
|
||||||
# (cd foamyHexMeshSurfaceSimplify && ./Allwmake)
|
# (cd foamyHexMeshSurfaceSimplify && ./Allwmake)
|
||||||
# wmake cellSizeAndAlignmentGrid
|
# wmake cellSizeAndAlignmentGrid
|
||||||
|
|||||||
@ -356,6 +356,9 @@ int main(int argc, char *argv[])
|
|||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Give file handler a chance to determine the output directory
|
||||||
|
const_cast<fileOperation&>(fileHandler()).setNProcs(nDomains);
|
||||||
|
|
||||||
if (decomposeFieldsOnly)
|
if (decomposeFieldsOnly)
|
||||||
{
|
{
|
||||||
// Sanity check on previously decomposed case
|
// Sanity check on previously decomposed case
|
||||||
@ -395,22 +398,42 @@ int main(int argc, char *argv[])
|
|||||||
Info<< "Removing " << nProcs
|
Info<< "Removing " << nProcs
|
||||||
<< " existing processor directories" << endl;
|
<< " existing processor directories" << endl;
|
||||||
|
|
||||||
fileHandler().rmDir
|
// Remove existing processors directory
|
||||||
|
fileNameList dirs
|
||||||
(
|
(
|
||||||
runTime.path()/word("processors"),
|
fileHandler().readDir
|
||||||
true // silent (may not have been collated)
|
|
||||||
);
|
|
||||||
|
|
||||||
// remove existing processor dirs
|
|
||||||
// reverse order to avoid gaps if someone interrupts the process
|
|
||||||
for (label proci = nProcs-1; proci >= 0; --proci)
|
|
||||||
{
|
|
||||||
fileName procDir
|
|
||||||
(
|
(
|
||||||
runTime.path()/(word("processor") + name(proci))
|
runTime.path(),
|
||||||
);
|
fileName::Type::DIRECTORY
|
||||||
|
)
|
||||||
|
);
|
||||||
|
forAllReverse(dirs, diri)
|
||||||
|
{
|
||||||
|
const fileName& d = dirs[diri];
|
||||||
|
|
||||||
fileHandler().rmDir(procDir);
|
// Starts with 'processors'
|
||||||
|
if (d.find("processors") == 0)
|
||||||
|
{
|
||||||
|
if (fileHandler().exists(d))
|
||||||
|
{
|
||||||
|
fileHandler().rmDir(d);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Starts with 'processor'
|
||||||
|
if (d.find("processor") == 0)
|
||||||
|
{
|
||||||
|
// Check that integer after processor
|
||||||
|
fileName num(d.substr(9));
|
||||||
|
label proci = -1;
|
||||||
|
if (Foam::read(num.c_str(), proci))
|
||||||
|
{
|
||||||
|
if (fileHandler().exists(d))
|
||||||
|
{
|
||||||
|
fileHandler().rmDir(d);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
procDirsProblem = false;
|
procDirsProblem = false;
|
||||||
|
|||||||
@ -216,6 +216,9 @@ int main(int argc, char *argv[])
|
|||||||
<< exit(FatalError);
|
<< exit(FatalError);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Warn fileHandler of number of processors
|
||||||
|
const_cast<fileOperation&>(fileHandler()).setNProcs(nProcs);
|
||||||
|
|
||||||
// Create the processor databases
|
// Create the processor databases
|
||||||
PtrList<Time> databases(nProcs);
|
PtrList<Time> databases(nProcs);
|
||||||
|
|
||||||
|
|||||||
@ -33,6 +33,7 @@ License
|
|||||||
#include "Time.H"
|
#include "Time.H"
|
||||||
#include "patchZones.H"
|
#include "patchZones.H"
|
||||||
#include "IOobjectList.H"
|
#include "IOobjectList.H"
|
||||||
|
#include "collatedFileOperation.H"
|
||||||
|
|
||||||
// VTK includes
|
// VTK includes
|
||||||
#include "vtkDataArraySelection.h"
|
#include "vtkDataArraySelection.h"
|
||||||
@ -268,7 +269,7 @@ Foam::word Foam::vtkPVFoam::getReaderPartName(const int partId) const
|
|||||||
|
|
||||||
Foam::vtkPVFoam::vtkPVFoam
|
Foam::vtkPVFoam::vtkPVFoam
|
||||||
(
|
(
|
||||||
const char* const FileName,
|
const char* const vtkFileName,
|
||||||
vtkPVFoamReader* reader
|
vtkPVFoamReader* reader
|
||||||
)
|
)
|
||||||
:
|
:
|
||||||
@ -294,12 +295,19 @@ Foam::vtkPVFoam::vtkPVFoam
|
|||||||
{
|
{
|
||||||
if (debug)
|
if (debug)
|
||||||
{
|
{
|
||||||
Info<< "vtkPVFoam - " << FileName << nl;
|
Info<< "vtkPVFoam - " << vtkFileName << nl;
|
||||||
printMemory();
|
printMemory();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fileName FileName(vtkFileName);
|
||||||
|
|
||||||
|
// Make sure not to use the threaded version - it does not like
|
||||||
|
// being loaded as a shared library - static cleanup order is problematic.
|
||||||
|
// For now just disable the threaded writer.
|
||||||
|
fileOperations::collatedFileOperation::maxThreadFileBufferSize = 0;
|
||||||
|
|
||||||
// avoid argList and get rootPath/caseName directly from the file
|
// avoid argList and get rootPath/caseName directly from the file
|
||||||
fileName fullCasePath(fileName(FileName).path());
|
fileName fullCasePath(FileName.path());
|
||||||
|
|
||||||
if (!isDir(fullCasePath))
|
if (!isDir(fullCasePath))
|
||||||
{
|
{
|
||||||
@ -314,8 +322,20 @@ Foam::vtkPVFoam::vtkPVFoam
|
|||||||
setEnv("FOAM_EXECUTABLE", "paraview", false);
|
setEnv("FOAM_EXECUTABLE", "paraview", false);
|
||||||
|
|
||||||
// Set the case as an environment variable - some BCs might use this
|
// Set the case as an environment variable - some BCs might use this
|
||||||
|
if (fullCasePath.name().find("processors", 0) == 0)
|
||||||
|
{
|
||||||
|
// FileName e.g. "cavity/processors256/processor1.OpenFOAM
|
||||||
|
// Remove the processors section so it goes into processorDDD
|
||||||
|
// checking below.
|
||||||
|
fullCasePath = fullCasePath.path()/fileName(FileName.name()).lessExt();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
if (fullCasePath.name().find("processor", 0) == 0)
|
if (fullCasePath.name().find("processor", 0) == 0)
|
||||||
{
|
{
|
||||||
|
// Give filehandler opportunity to analyse number of processors
|
||||||
|
(void)fileHandler().filePath(fullCasePath);
|
||||||
|
|
||||||
const fileName globalCase = fullCasePath.path();
|
const fileName globalCase = fullCasePath.path();
|
||||||
|
|
||||||
setEnv("FOAM_CASE", globalCase, true);
|
setEnv("FOAM_CASE", globalCase, true);
|
||||||
|
|||||||
@ -2,6 +2,6 @@
|
|||||||
cd ${0%/*} || exit 1 # Run from this directory
|
cd ${0%/*} || exit 1 # Run from this directory
|
||||||
. $WM_PROJECT_DIR/wmake/scripts/AllwmakeParseArguments
|
. $WM_PROJECT_DIR/wmake/scripts/AllwmakeParseArguments
|
||||||
|
|
||||||
(wmake libso extractionMethod && wmake)
|
(wmake $targetType extractionMethod && wmake $targetType)
|
||||||
|
|
||||||
#------------------------------------------------------------------------------
|
#------------------------------------------------------------------------------
|
||||||
|
|||||||
@ -5,7 +5,7 @@
|
|||||||
| \\ / A nd | Web: www.OpenFOAM.com |
|
| \\ / A nd | Web: www.OpenFOAM.com |
|
||||||
| \\/ M anipulation | |
|
| \\/ M anipulation | |
|
||||||
\*---------------------------------------------------------------------------*/
|
\*---------------------------------------------------------------------------*/
|
||||||
// Insitu processing of finiteVolume fields with ParaView Catalyst
|
// Insitu processing with ParaView Catalyst
|
||||||
|
|
||||||
type catalyst;
|
type catalyst;
|
||||||
libs ("libcatalystFoam.so");
|
libs ("libcatalystFoam.so");
|
||||||
68
etc/caseDicts/insitu/catalyst/printChannels.py
Normal file
68
etc/caseDicts/insitu/catalyst/printChannels.py
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
from paraview.simple import *
|
||||||
|
from paraview import coprocessing
|
||||||
|
|
||||||
|
# The frequency to output everything
|
||||||
|
outputfrequency = 1
|
||||||
|
|
||||||
|
# Simply print out all channel names that our function object is producing
|
||||||
|
|
||||||
|
# ----------------------- CoProcessor definition -----------------------
|
||||||
|
|
||||||
|
def CreateCoProcessor():
|
||||||
|
def _CreatePipeline(coprocessor, datadescription):
|
||||||
|
class Pipeline:
|
||||||
|
for i in range(datadescription.GetNumberOfInputDescriptions()):
|
||||||
|
name = datadescription.GetInputDescriptionName(i)
|
||||||
|
input = coprocessor.CreateProducer(datadescription, name)
|
||||||
|
grid = input.GetClientSideObject().GetOutputDataObject(0)
|
||||||
|
print "Channel <" + name + "> is", grid.GetClassName()
|
||||||
|
|
||||||
|
return Pipeline()
|
||||||
|
|
||||||
|
class CoProcessor(coprocessing.CoProcessor):
|
||||||
|
def CreatePipeline(self, datadescription):
|
||||||
|
self.Pipeline = _CreatePipeline(self, datadescription)
|
||||||
|
|
||||||
|
return CoProcessor()
|
||||||
|
|
||||||
|
#--------------------------------------------------------------
|
||||||
|
# Global variables that will hold the pipeline for each timestep
|
||||||
|
# Creating the CoProcessor object, doesn't actually create the ParaView pipeline.
|
||||||
|
# It will be automatically setup when coprocessor.UpdateProducers() is called the
|
||||||
|
# first time.
|
||||||
|
coprocessor = CreateCoProcessor()
|
||||||
|
|
||||||
|
#--------------------------------------------------------------
|
||||||
|
# Enable Live-Visualizaton with ParaView
|
||||||
|
coprocessor.EnableLiveVisualization(False)
|
||||||
|
|
||||||
|
|
||||||
|
# ---------------------- Data Selection method ----------------------
|
||||||
|
|
||||||
|
def RequestDataDescription(datadescription):
|
||||||
|
"Callback to populate the request for current timestep"
|
||||||
|
global coprocessor
|
||||||
|
if datadescription.GetForceOutput() == True or datadescription.GetTimeStep() % outputfrequency == 0:
|
||||||
|
# We are just going to request all fields and meshes from the simulation
|
||||||
|
# code/adaptor.
|
||||||
|
for i in range(datadescription.GetNumberOfInputDescriptions()):
|
||||||
|
datadescription.GetInputDescription(i).AllFieldsOn()
|
||||||
|
datadescription.GetInputDescription(i).GenerateMeshOn()
|
||||||
|
return
|
||||||
|
|
||||||
|
# setup requests for all inputs based on the requirements of the
|
||||||
|
# pipeline.
|
||||||
|
coprocessor.LoadRequestedData(datadescription)
|
||||||
|
|
||||||
|
# ------------------------ Processing method ------------------------
|
||||||
|
|
||||||
|
def DoCoProcessing(datadescription):
|
||||||
|
"Callback to do co-processing for current timestep"
|
||||||
|
global coprocessor
|
||||||
|
|
||||||
|
# Update the coprocessor by providing it the newly generated simulation data.
|
||||||
|
# If the pipeline hasn't been setup yet, this will setup the pipeline.
|
||||||
|
coprocessor.UpdateProducers(datadescription)
|
||||||
|
|
||||||
|
# Write output data, if appropriate.
|
||||||
|
coprocessor.WriteData(datadescription);
|
||||||
77
etc/caseDicts/insitu/catalyst/writeAll.py
Normal file
77
etc/caseDicts/insitu/catalyst/writeAll.py
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
from paraview.simple import *
|
||||||
|
from paraview import coprocessing
|
||||||
|
|
||||||
|
# The frequency to output everything
|
||||||
|
outputfrequency = 5
|
||||||
|
|
||||||
|
# This is largely identical to the Catalyst allinputsgridwriter.py example
|
||||||
|
# but only handle vtkMultiBlockDataSet, since that is what we generate
|
||||||
|
|
||||||
|
# ----------------------- CoProcessor definition -----------------------
|
||||||
|
|
||||||
|
def CreateCoProcessor():
|
||||||
|
def _CreatePipeline(coprocessor, datadescription):
|
||||||
|
class Pipeline:
|
||||||
|
for i in range(datadescription.GetNumberOfInputDescriptions()):
|
||||||
|
name = datadescription.GetInputDescriptionName(i)
|
||||||
|
input = coprocessor.CreateProducer(datadescription, name)
|
||||||
|
grid = input.GetClientSideObject().GetOutputDataObject(0)
|
||||||
|
if grid.IsA('vtkMultiBlockDataSet'):
|
||||||
|
writer = servermanager.writers.XMLMultiBlockDataWriter(Input=input)
|
||||||
|
coprocessor.RegisterWriter(writer, filename=name+'_%t.vtm', freq=outputfrequency)
|
||||||
|
|
||||||
|
return Pipeline()
|
||||||
|
|
||||||
|
class CoProcessor(coprocessing.CoProcessor):
|
||||||
|
def CreatePipeline(self, datadescription):
|
||||||
|
self.Pipeline = _CreatePipeline(self, datadescription)
|
||||||
|
|
||||||
|
return CoProcessor()
|
||||||
|
|
||||||
|
#--------------------------------------------------------------
|
||||||
|
# Global variables that will hold the pipeline for each timestep
|
||||||
|
# Creating the CoProcessor object, doesn't actually create the ParaView pipeline.
|
||||||
|
# It will be automatically setup when coprocessor.UpdateProducers() is called the
|
||||||
|
# first time.
|
||||||
|
coprocessor = CreateCoProcessor()
|
||||||
|
|
||||||
|
#--------------------------------------------------------------
|
||||||
|
# Enable Live-Visualizaton with ParaView
|
||||||
|
coprocessor.EnableLiveVisualization(False)
|
||||||
|
|
||||||
|
|
||||||
|
# ---------------------- Data Selection method ----------------------
|
||||||
|
|
||||||
|
def RequestDataDescription(datadescription):
|
||||||
|
"Callback to populate the request for current timestep"
|
||||||
|
global coprocessor
|
||||||
|
if datadescription.GetForceOutput() == True or datadescription.GetTimeStep() % outputfrequency == 0:
|
||||||
|
# We are just going to request all fields and meshes from the simulation
|
||||||
|
# code/adaptor.
|
||||||
|
for i in range(datadescription.GetNumberOfInputDescriptions()):
|
||||||
|
datadescription.GetInputDescription(i).AllFieldsOn()
|
||||||
|
datadescription.GetInputDescription(i).GenerateMeshOn()
|
||||||
|
return
|
||||||
|
|
||||||
|
# setup requests for all inputs based on the requirements of the
|
||||||
|
# pipeline.
|
||||||
|
coprocessor.LoadRequestedData(datadescription)
|
||||||
|
|
||||||
|
# ------------------------ Processing method ------------------------
|
||||||
|
|
||||||
|
def DoCoProcessing(datadescription):
|
||||||
|
"Callback to do co-processing for current timestep"
|
||||||
|
global coprocessor
|
||||||
|
|
||||||
|
# Update the coprocessor by providing it the newly generated simulation data.
|
||||||
|
# If the pipeline hasn't been setup yet, this will setup the pipeline.
|
||||||
|
coprocessor.UpdateProducers(datadescription)
|
||||||
|
|
||||||
|
# Write output data, if appropriate.
|
||||||
|
coprocessor.WriteData(datadescription);
|
||||||
|
|
||||||
|
# Write image capture (Last arg: rescale lookup table), if appropriate.
|
||||||
|
coprocessor.WriteImages(datadescription, rescale_lookuptable=False)
|
||||||
|
|
||||||
|
# Live Visualization, if enabled.
|
||||||
|
coprocessor.DoLiveVisualization(datadescription, "localhost", 22222)
|
||||||
78
etc/caseDicts/insitu/catalyst/writeMesh.py
Normal file
78
etc/caseDicts/insitu/catalyst/writeMesh.py
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
from paraview.simple import *
|
||||||
|
from paraview import coprocessing
|
||||||
|
|
||||||
|
# The frequency to output everything
|
||||||
|
outputfrequency = 5
|
||||||
|
|
||||||
|
# As per writeAll, but only for "/mesh" sub-channels.
|
||||||
|
|
||||||
|
# ----------------------- CoProcessor definition -----------------------
|
||||||
|
|
||||||
|
def CreateCoProcessor():
|
||||||
|
def _CreatePipeline(coprocessor, datadescription):
|
||||||
|
class Pipeline:
|
||||||
|
for i in range(datadescription.GetNumberOfInputDescriptions()):
|
||||||
|
name = datadescription.GetInputDescriptionName(i)
|
||||||
|
if not name.endswith('/mesh'):
|
||||||
|
continue
|
||||||
|
input = coprocessor.CreateProducer(datadescription, name)
|
||||||
|
grid = input.GetClientSideObject().GetOutputDataObject(0)
|
||||||
|
if grid.IsA('vtkMultiBlockDataSet'):
|
||||||
|
writer = servermanager.writers.XMLMultiBlockDataWriter(Input=input)
|
||||||
|
coprocessor.RegisterWriter(writer, filename=name+'_%t.vtm', freq=outputfrequency)
|
||||||
|
|
||||||
|
return Pipeline()
|
||||||
|
|
||||||
|
class CoProcessor(coprocessing.CoProcessor):
|
||||||
|
def CreatePipeline(self, datadescription):
|
||||||
|
self.Pipeline = _CreatePipeline(self, datadescription)
|
||||||
|
|
||||||
|
return CoProcessor()
|
||||||
|
|
||||||
|
#--------------------------------------------------------------
|
||||||
|
# Global variables that will hold the pipeline for each timestep
|
||||||
|
# Creating the CoProcessor object, doesn't actually create the ParaView pipeline.
|
||||||
|
# It will be automatically setup when coprocessor.UpdateProducers() is called the
|
||||||
|
# first time.
|
||||||
|
coprocessor = CreateCoProcessor()
|
||||||
|
|
||||||
|
#--------------------------------------------------------------
|
||||||
|
# Enable Live-Visualizaton with ParaView
|
||||||
|
coprocessor.EnableLiveVisualization(False)
|
||||||
|
|
||||||
|
|
||||||
|
# ---------------------- Data Selection method ----------------------
|
||||||
|
|
||||||
|
def RequestDataDescription(datadescription):
|
||||||
|
"Callback to populate the request for current timestep"
|
||||||
|
global coprocessor
|
||||||
|
if datadescription.GetForceOutput() == True or datadescription.GetTimeStep() % outputfrequency == 0:
|
||||||
|
# We are just going to request all fields and meshes from the simulation
|
||||||
|
# code/adaptor.
|
||||||
|
for i in range(datadescription.GetNumberOfInputDescriptions()):
|
||||||
|
datadescription.GetInputDescription(i).AllFieldsOn()
|
||||||
|
datadescription.GetInputDescription(i).GenerateMeshOn()
|
||||||
|
return
|
||||||
|
|
||||||
|
# setup requests for all inputs based on the requirements of the
|
||||||
|
# pipeline.
|
||||||
|
coprocessor.LoadRequestedData(datadescription)
|
||||||
|
|
||||||
|
# ------------------------ Processing method ------------------------
|
||||||
|
|
||||||
|
def DoCoProcessing(datadescription):
|
||||||
|
"Callback to do co-processing for current timestep"
|
||||||
|
global coprocessor
|
||||||
|
|
||||||
|
# Update the coprocessor by providing it the newly generated simulation data.
|
||||||
|
# If the pipeline hasn't been setup yet, this will setup the pipeline.
|
||||||
|
coprocessor.UpdateProducers(datadescription)
|
||||||
|
|
||||||
|
# Write output data, if appropriate.
|
||||||
|
coprocessor.WriteData(datadescription);
|
||||||
|
|
||||||
|
# Write image capture (Last arg: rescale lookup table), if appropriate.
|
||||||
|
coprocessor.WriteImages(datadescription, rescale_lookuptable=False)
|
||||||
|
|
||||||
|
# Live Visualization, if enabled.
|
||||||
|
coprocessor.DoLiveVisualization(datadescription, "localhost", 22222)
|
||||||
78
etc/caseDicts/insitu/catalyst/writePatches.py
Normal file
78
etc/caseDicts/insitu/catalyst/writePatches.py
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
from paraview.simple import *
|
||||||
|
from paraview import coprocessing
|
||||||
|
|
||||||
|
# The frequency to output everything
|
||||||
|
outputfrequency = 5
|
||||||
|
|
||||||
|
# As per writeAll, but only for "/patches" sub-channels.
|
||||||
|
|
||||||
|
# ----------------------- CoProcessor definition -----------------------
|
||||||
|
|
||||||
|
def CreateCoProcessor():
|
||||||
|
def _CreatePipeline(coprocessor, datadescription):
|
||||||
|
class Pipeline:
|
||||||
|
for i in range(datadescription.GetNumberOfInputDescriptions()):
|
||||||
|
name = datadescription.GetInputDescriptionName(i)
|
||||||
|
if not name.endswith('/patches'):
|
||||||
|
continue
|
||||||
|
input = coprocessor.CreateProducer(datadescription, name)
|
||||||
|
grid = input.GetClientSideObject().GetOutputDataObject(0)
|
||||||
|
if grid.IsA('vtkMultiBlockDataSet'):
|
||||||
|
writer = servermanager.writers.XMLMultiBlockDataWriter(Input=input)
|
||||||
|
coprocessor.RegisterWriter(writer, filename=name+'_%t.vtm', freq=outputfrequency)
|
||||||
|
|
||||||
|
return Pipeline()
|
||||||
|
|
||||||
|
class CoProcessor(coprocessing.CoProcessor):
|
||||||
|
def CreatePipeline(self, datadescription):
|
||||||
|
self.Pipeline = _CreatePipeline(self, datadescription)
|
||||||
|
|
||||||
|
return CoProcessor()
|
||||||
|
|
||||||
|
#--------------------------------------------------------------
|
||||||
|
# Global variables that will hold the pipeline for each timestep
|
||||||
|
# Creating the CoProcessor object, doesn't actually create the ParaView pipeline.
|
||||||
|
# It will be automatically setup when coprocessor.UpdateProducers() is called the
|
||||||
|
# first time.
|
||||||
|
coprocessor = CreateCoProcessor()
|
||||||
|
|
||||||
|
#--------------------------------------------------------------
|
||||||
|
# Enable Live-Visualizaton with ParaView
|
||||||
|
coprocessor.EnableLiveVisualization(False)
|
||||||
|
|
||||||
|
|
||||||
|
# ---------------------- Data Selection method ----------------------
|
||||||
|
|
||||||
|
def RequestDataDescription(datadescription):
|
||||||
|
"Callback to populate the request for current timestep"
|
||||||
|
global coprocessor
|
||||||
|
if datadescription.GetForceOutput() == True or datadescription.GetTimeStep() % outputfrequency == 0:
|
||||||
|
# We are just going to request all fields and meshes from the simulation
|
||||||
|
# code/adaptor.
|
||||||
|
for i in range(datadescription.GetNumberOfInputDescriptions()):
|
||||||
|
datadescription.GetInputDescription(i).AllFieldsOn()
|
||||||
|
datadescription.GetInputDescription(i).GenerateMeshOn()
|
||||||
|
return
|
||||||
|
|
||||||
|
# setup requests for all inputs based on the requirements of the
|
||||||
|
# pipeline.
|
||||||
|
coprocessor.LoadRequestedData(datadescription)
|
||||||
|
|
||||||
|
# ------------------------ Processing method ------------------------
|
||||||
|
|
||||||
|
def DoCoProcessing(datadescription):
|
||||||
|
"Callback to do co-processing for current timestep"
|
||||||
|
global coprocessor
|
||||||
|
|
||||||
|
# Update the coprocessor by providing it the newly generated simulation data.
|
||||||
|
# If the pipeline hasn't been setup yet, this will setup the pipeline.
|
||||||
|
coprocessor.UpdateProducers(datadescription)
|
||||||
|
|
||||||
|
# Write output data, if appropriate.
|
||||||
|
coprocessor.WriteData(datadescription);
|
||||||
|
|
||||||
|
# Write image capture (Last arg: rescale lookup table), if appropriate.
|
||||||
|
coprocessor.WriteImages(datadescription, rescale_lookuptable=False)
|
||||||
|
|
||||||
|
# Live Visualization, if enabled.
|
||||||
|
coprocessor.DoLiveVisualization(datadescription, "localhost", 22222)
|
||||||
@ -13,8 +13,8 @@
|
|||||||
# config.csh/example/paraview
|
# config.csh/example/paraview
|
||||||
#
|
#
|
||||||
# Description
|
# Description
|
||||||
# Example of defining a different ParaView_VERSION but retaining
|
# Example of defining a different ParaView_VERSION but retaining the
|
||||||
# the standard config.csh/paraview mechanism
|
# standard config.csh/paraview mechanism
|
||||||
#
|
#
|
||||||
# Note
|
# Note
|
||||||
# This file could be copied to a user or site location, but should never
|
# This file could be copied to a user or site location, but should never
|
||||||
@ -25,7 +25,8 @@
|
|||||||
|
|
||||||
set pv=5.5.0
|
set pv=5.5.0
|
||||||
set pv=5.5.0-mpipy
|
set pv=5.5.0-mpipy
|
||||||
|
set qt=qt-5.9.0
|
||||||
|
|
||||||
eval `foamEtcFile -csh -config -mode=o paraview -- ParaView_VERSION=$pv`
|
eval `foamEtcFile -csh -config -mode=o paraview -- ParaView_VERSION=$pv ParaView_QT=$qt`
|
||||||
|
|
||||||
#------------------------------------------------------------------------------
|
#------------------------------------------------------------------------------
|
||||||
|
|||||||
@ -120,8 +120,16 @@ if ( $?ParaView_VERSION ) then
|
|||||||
#OBSOLETE? endif
|
#OBSOLETE? endif
|
||||||
|
|
||||||
# QT libraries as required
|
# QT libraries as required
|
||||||
|
# Set Qt5_DIR to root directory.
|
||||||
|
# Another possibility: "qtpaths --qt-version"
|
||||||
|
|
||||||
set qtDir="$archDir/$ParaView_QT"
|
set qtDir="$archDir/$ParaView_QT"
|
||||||
if ( -d "$qtDir" ) then
|
if ( -d "$qtDir" ) then
|
||||||
|
switch ($ParaView_QT)
|
||||||
|
case *-qt*:
|
||||||
|
setenv Qt5_DIR $qtDir
|
||||||
|
breaksw
|
||||||
|
endsw
|
||||||
foreach qtLibDir ("$qtDir/lib$WM_COMPILER_LIB_ARCH" "$qtDir/lib")
|
foreach qtLibDir ("$qtDir/lib$WM_COMPILER_LIB_ARCH" "$qtDir/lib")
|
||||||
if ( -d "$qtLibDir" ) then
|
if ( -d "$qtLibDir" ) then
|
||||||
setenv LD_LIBRARY_PATH "${qtLibDir}:${LD_LIBRARY_PATH}"
|
setenv LD_LIBRARY_PATH "${qtLibDir}:${LD_LIBRARY_PATH}"
|
||||||
|
|||||||
@ -111,6 +111,7 @@ unsetenv ParaView_INCLUDE_DIR
|
|||||||
unsetenv ParaView_VERSION
|
unsetenv ParaView_VERSION
|
||||||
unsetenv PV_PLUGIN_PATH
|
unsetenv PV_PLUGIN_PATH
|
||||||
unsetenv VTK_DIR
|
unsetenv VTK_DIR
|
||||||
|
unsetenv Qt5_DIR # Perhaps only unset if it is in WM_THIRD_PARTY_DIR?
|
||||||
|
|
||||||
#------------------------------------------------------------------------------
|
#------------------------------------------------------------------------------
|
||||||
# Unset other ThirdParty environment variables
|
# Unset other ThirdParty environment variables
|
||||||
|
|||||||
@ -13,8 +13,8 @@
|
|||||||
# config.sh/example/paraview
|
# config.sh/example/paraview
|
||||||
#
|
#
|
||||||
# Description
|
# Description
|
||||||
# Example of defining a different ParaView_VERSION but retaining
|
# Example of defining a different ParaView_VERSION but retaining the
|
||||||
# the standard config.sh/paraview mechanism
|
# standard config.sh/paraview mechanism
|
||||||
#
|
#
|
||||||
# Note
|
# Note
|
||||||
# This file could be copied to a user or site location, but should never
|
# This file could be copied to a user or site location, but should never
|
||||||
@ -25,7 +25,8 @@
|
|||||||
|
|
||||||
pv=5.5.0
|
pv=5.5.0
|
||||||
pv=5.5.0-mpipy
|
pv=5.5.0-mpipy
|
||||||
|
qt=qt-5.9.0
|
||||||
|
|
||||||
eval $(foamEtcFile -sh -config -mode=o paraview -- ParaView_VERSION=$pv)
|
eval $(foamEtcFile -sh -config -mode=o paraview -- ParaView_VERSION=$pv ParaView_QT=$qt)
|
||||||
|
|
||||||
#------------------------------------------------------------------------------
|
#------------------------------------------------------------------------------
|
||||||
|
|||||||
@ -127,10 +127,16 @@ then
|
|||||||
#OBSOLETE? export PYTHONPATH=$PYTHONPATH:${PYTHONPATH:+:}$pvPython:$pvLibDir
|
#OBSOLETE? export PYTHONPATH=$PYTHONPATH:${PYTHONPATH:+:}$pvPython:$pvLibDir
|
||||||
#OBSOLETE? fi
|
#OBSOLETE? fi
|
||||||
|
|
||||||
# QT libraries as required
|
# QT libraries as required, and Qt5_DIR for the root directory.
|
||||||
|
# Another possibility: "qtpaths --qt-version"
|
||||||
qtDir="$archDir/$ParaView_QT"
|
qtDir="$archDir/$ParaView_QT"
|
||||||
if [ -d "$qtDir" ]
|
if [ -d "$qtDir" ]
|
||||||
then
|
then
|
||||||
|
case "$ParaView_QT" in
|
||||||
|
*-5*)
|
||||||
|
export Qt5_DIR=$qtDir
|
||||||
|
;;
|
||||||
|
esac
|
||||||
for qtLibDir in $qtDir/lib$WM_COMPILER_LIB_ARCH $qtDir/lib
|
for qtLibDir in $qtDir/lib$WM_COMPILER_LIB_ARCH $qtDir/lib
|
||||||
do
|
do
|
||||||
if [ -d "$qtLibDir" ]
|
if [ -d "$qtLibDir" ]
|
||||||
|
|||||||
@ -97,7 +97,6 @@ then
|
|||||||
unset OPAL_PREFIX
|
unset OPAL_PREFIX
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
||||||
#------------------------------------------------------------------------------
|
#------------------------------------------------------------------------------
|
||||||
# Unset Ensight/ParaView-related environment variables
|
# Unset Ensight/ParaView-related environment variables
|
||||||
|
|
||||||
@ -108,6 +107,12 @@ unset ParaView_VERSION
|
|||||||
unset PV_PLUGIN_PATH
|
unset PV_PLUGIN_PATH
|
||||||
unset VTK_DIR
|
unset VTK_DIR
|
||||||
|
|
||||||
|
# Undefine Qt5_DIR if set to one of the paths on foamOldDirs
|
||||||
|
if [ -z "$($foamClean -env=Qt5_DIR "$foamOldDirs")" ]
|
||||||
|
then
|
||||||
|
unset Qt5_DIR
|
||||||
|
fi
|
||||||
|
|
||||||
#------------------------------------------------------------------------------
|
#------------------------------------------------------------------------------
|
||||||
# Unset other ThirdParty environment variables
|
# Unset other ThirdParty environment variables
|
||||||
|
|
||||||
|
|||||||
@ -39,8 +39,8 @@ InfoSwitches
|
|||||||
writeDictionaries 0;
|
writeDictionaries 0;
|
||||||
writeOptionalEntries 0;
|
writeOptionalEntries 0;
|
||||||
|
|
||||||
// Write lagrangian "positions" file in v1706 format (at earlier)
|
// Write lagrangian "positions" file in v1706 format (and earlier)
|
||||||
writeLagrangianPositions 0;
|
writeLagrangianPositions 1;
|
||||||
|
|
||||||
// Report hosts used (parallel)
|
// Report hosts used (parallel)
|
||||||
// - 0 = none
|
// - 0 = none
|
||||||
|
|||||||
Submodule modules/avalanche updated: 99e68179fa...6e6e105844
Submodule modules/catalyst updated: 3c0a2e7959...5828d45108
Submodule modules/cfmesh updated: 8f6e65ae7c...288f05e08f
@ -489,6 +489,10 @@ mode_t Foam::mode(const fileName& name, const bool followLink)
|
|||||||
if (POSIX::debug)
|
if (POSIX::debug)
|
||||||
{
|
{
|
||||||
Pout<< FUNCTION_NAME << " : name:" << name << endl;
|
Pout<< FUNCTION_NAME << " : name:" << name << endl;
|
||||||
|
if ((POSIX::debug & 2) && !Pstream::master())
|
||||||
|
{
|
||||||
|
error::printStack(Pout);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ignore an empty name => always 0
|
// Ignore an empty name => always 0
|
||||||
@ -516,10 +520,6 @@ Foam::fileName::Type Foam::type(const fileName& name, const bool followLink)
|
|||||||
if (POSIX::debug)
|
if (POSIX::debug)
|
||||||
{
|
{
|
||||||
Pout<< FUNCTION_NAME << " : name:" << name << endl;
|
Pout<< FUNCTION_NAME << " : name:" << name << endl;
|
||||||
if ((POSIX::debug & 2) && !Pstream::master())
|
|
||||||
{
|
|
||||||
error::printStack(Pout);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
mode_t m = mode(name, followLink);
|
mode_t m = mode(name, followLink);
|
||||||
@ -1678,142 +1678,4 @@ Foam::fileNameList Foam::dlLoaded()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static Foam::DynamicList<Foam::autoPtr<pthread_t>> threads_;
|
|
||||||
static Foam::DynamicList<Foam::autoPtr<pthread_mutex_t>> mutexes_;
|
|
||||||
|
|
||||||
Foam::label Foam::allocateThread()
|
|
||||||
{
|
|
||||||
forAll(threads_, i)
|
|
||||||
{
|
|
||||||
if (!threads_[i].valid())
|
|
||||||
{
|
|
||||||
if (POSIX::debug)
|
|
||||||
{
|
|
||||||
Pout<< FUNCTION_NAME << " : reusing index:" << i << endl;
|
|
||||||
}
|
|
||||||
// Reuse entry
|
|
||||||
threads_[i].reset(new pthread_t());
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const label index = threads_.size();
|
|
||||||
if (POSIX::debug)
|
|
||||||
{
|
|
||||||
Pout<< FUNCTION_NAME << " : new index:" << index << endl;
|
|
||||||
}
|
|
||||||
threads_.append(autoPtr<pthread_t>(new pthread_t()));
|
|
||||||
|
|
||||||
return index;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Foam::createThread
|
|
||||||
(
|
|
||||||
const label index,
|
|
||||||
void *(*start_routine) (void *),
|
|
||||||
void *arg
|
|
||||||
)
|
|
||||||
{
|
|
||||||
if (POSIX::debug)
|
|
||||||
{
|
|
||||||
Pout<< FUNCTION_NAME << " : index:" << index << endl;
|
|
||||||
}
|
|
||||||
if (pthread_create(&threads_[index](), nullptr, start_routine, arg))
|
|
||||||
{
|
|
||||||
FatalErrorInFunction
|
|
||||||
<< "Failed starting thread " << index << exit(FatalError);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Foam::joinThread(const label index)
|
|
||||||
{
|
|
||||||
if (POSIX::debug)
|
|
||||||
{
|
|
||||||
Pout<< FUNCTION_NAME << " : index:" << index << endl;
|
|
||||||
}
|
|
||||||
if (pthread_join(threads_[index](), nullptr))
|
|
||||||
{
|
|
||||||
FatalErrorInFunction << "Failed joining thread " << index
|
|
||||||
<< exit(FatalError);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Foam::freeThread(const label index)
|
|
||||||
{
|
|
||||||
if (POSIX::debug)
|
|
||||||
{
|
|
||||||
Pout<< FUNCTION_NAME << " : index:" << index << endl;
|
|
||||||
}
|
|
||||||
threads_[index].clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Foam::label Foam::allocateMutex()
|
|
||||||
{
|
|
||||||
forAll(mutexes_, i)
|
|
||||||
{
|
|
||||||
if (!mutexes_[i].valid())
|
|
||||||
{
|
|
||||||
if (POSIX::debug)
|
|
||||||
{
|
|
||||||
Pout<< FUNCTION_NAME << " : reusing index:" << i << endl;
|
|
||||||
}
|
|
||||||
// Reuse entry
|
|
||||||
mutexes_[i].reset(new pthread_mutex_t());
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const label index = mutexes_.size();
|
|
||||||
|
|
||||||
if (POSIX::debug)
|
|
||||||
{
|
|
||||||
Pout<< FUNCTION_NAME << " : new index:" << index << endl;
|
|
||||||
}
|
|
||||||
mutexes_.append(autoPtr<pthread_mutex_t>(new pthread_mutex_t()));
|
|
||||||
return index;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Foam::lockMutex(const label index)
|
|
||||||
{
|
|
||||||
if (POSIX::debug)
|
|
||||||
{
|
|
||||||
Pout<< FUNCTION_NAME << " : index:" << index << endl;
|
|
||||||
}
|
|
||||||
if (pthread_mutex_lock(&mutexes_[index]()))
|
|
||||||
{
|
|
||||||
FatalErrorInFunction << "Failed locking mutex " << index
|
|
||||||
<< exit(FatalError);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Foam::unlockMutex(const label index)
|
|
||||||
{
|
|
||||||
if (POSIX::debug)
|
|
||||||
{
|
|
||||||
Pout<< FUNCTION_NAME << " : index:" << index << endl;
|
|
||||||
}
|
|
||||||
if (pthread_mutex_unlock(&mutexes_[index]()))
|
|
||||||
{
|
|
||||||
FatalErrorInFunction << "Failed unlocking mutex " << index
|
|
||||||
<< exit(FatalError);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Foam::freeMutex(const label index)
|
|
||||||
{
|
|
||||||
if (POSIX::debug)
|
|
||||||
{
|
|
||||||
Pout<< FUNCTION_NAME << " : index:" << index << endl;
|
|
||||||
}
|
|
||||||
mutexes_[index].clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
// ************************************************************************* //
|
||||||
|
|||||||
@ -11,9 +11,11 @@ global/etcFiles/etcFiles.C
|
|||||||
|
|
||||||
fileOps = global/fileOperations
|
fileOps = global/fileOperations
|
||||||
$(fileOps)/fileOperation/fileOperation.C
|
$(fileOps)/fileOperation/fileOperation.C
|
||||||
|
$(fileOps)/fileOperationInitialise/fileOperationInitialise.C
|
||||||
$(fileOps)/uncollatedFileOperation/uncollatedFileOperation.C
|
$(fileOps)/uncollatedFileOperation/uncollatedFileOperation.C
|
||||||
$(fileOps)/masterUncollatedFileOperation/masterUncollatedFileOperation.C
|
$(fileOps)/masterUncollatedFileOperation/masterUncollatedFileOperation.C
|
||||||
$(fileOps)/collatedFileOperation/collatedFileOperation.C
|
$(fileOps)/collatedFileOperation/collatedFileOperation.C
|
||||||
|
$(fileOps)/collatedFileOperation/hostCollatedFileOperation.C
|
||||||
$(fileOps)/collatedFileOperation/threadedCollatedOFstream.C
|
$(fileOps)/collatedFileOperation/threadedCollatedOFstream.C
|
||||||
$(fileOps)/collatedFileOperation/OFstreamCollator.C
|
$(fileOps)/collatedFileOperation/OFstreamCollator.C
|
||||||
|
|
||||||
@ -288,7 +290,6 @@ $(Time)/TimeIO.C
|
|||||||
$(Time)/findTimes.C
|
$(Time)/findTimes.C
|
||||||
$(Time)/subCycleTime.C
|
$(Time)/subCycleTime.C
|
||||||
$(Time)/subLoopTime.C
|
$(Time)/subLoopTime.C
|
||||||
$(Time)/findInstance.C
|
|
||||||
$(Time)/timeSelector.C
|
$(Time)/timeSelector.C
|
||||||
|
|
||||||
$(Time)/instant/instant.C
|
$(Time)/instant/instant.C
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
========= |
|
========= |
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
\\ / O peration |
|
\\ / O peration |
|
||||||
\\ / A nd | Copyright (C) 2017 OpenFOAM Foundation
|
\\ / A nd | Copyright (C) 2017-2018 OpenFOAM Foundation
|
||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
@ -681,14 +681,15 @@ void Foam::decomposedBlockData::gather
|
|||||||
|
|
||||||
List<int> recvOffsets;
|
List<int> recvOffsets;
|
||||||
List<int> recvSizes;
|
List<int> recvSizes;
|
||||||
if (UPstream::master())
|
if (UPstream::master(comm))
|
||||||
{
|
{
|
||||||
recvOffsets.setSize(nProcs);
|
recvOffsets.setSize(nProcs);
|
||||||
forAll(recvOffsets, proci)
|
forAll(recvOffsets, proci)
|
||||||
{
|
{
|
||||||
|
// Note: truncating long int to int since UPstream::gather limited
|
||||||
|
// to ints
|
||||||
recvOffsets[proci] =
|
recvOffsets[proci] =
|
||||||
reinterpret_cast<char*>(&datas[proci])
|
int(reinterpret_cast<char*>(&datas[proci]) - data0Ptr);
|
||||||
- data0Ptr;
|
|
||||||
}
|
}
|
||||||
recvSizes.setSize(nProcs, sizeof(label));
|
recvSizes.setSize(nProcs, sizeof(label));
|
||||||
}
|
}
|
||||||
@ -748,7 +749,8 @@ void Foam::decomposedBlockData::gatherSlaveData
|
|||||||
&& (UPstream::myProcNo(comm) < startProc+nProcs)
|
&& (UPstream::myProcNo(comm) < startProc+nProcs)
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
nSend = data.byteSize();
|
// Note: UPstream::gather limited to int
|
||||||
|
nSend = int(data.byteSize());
|
||||||
}
|
}
|
||||||
|
|
||||||
UPstream::gather
|
UPstream::gather
|
||||||
@ -764,6 +766,46 @@ void Foam::decomposedBlockData::gatherSlaveData
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::label Foam::decomposedBlockData::calcNumProcs
|
||||||
|
(
|
||||||
|
const label comm,
|
||||||
|
const off_t maxBufferSize,
|
||||||
|
const labelUList& recvSizes,
|
||||||
|
const label startProci
|
||||||
|
)
|
||||||
|
{
|
||||||
|
const label nProcs = UPstream::nProcs(comm);
|
||||||
|
|
||||||
|
label nSendProcs = -1;
|
||||||
|
if (UPstream::master(comm))
|
||||||
|
{
|
||||||
|
off_t totalSize = recvSizes[startProci];
|
||||||
|
label proci = startProci+1;
|
||||||
|
while (proci < nProcs && (totalSize+recvSizes[proci] < maxBufferSize))
|
||||||
|
{
|
||||||
|
totalSize += recvSizes[proci];
|
||||||
|
proci++;
|
||||||
|
}
|
||||||
|
|
||||||
|
nSendProcs = proci-startProci;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Scatter nSendProcs
|
||||||
|
label n;
|
||||||
|
UPstream::scatter
|
||||||
|
(
|
||||||
|
reinterpret_cast<const char*>(&nSendProcs),
|
||||||
|
List<int>(nProcs, sizeof(nSendProcs)),
|
||||||
|
List<int>(nProcs, 0),
|
||||||
|
reinterpret_cast<char*>(&n),
|
||||||
|
sizeof(n),
|
||||||
|
comm
|
||||||
|
);
|
||||||
|
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool Foam::decomposedBlockData::writeBlocks
|
bool Foam::decomposedBlockData::writeBlocks
|
||||||
(
|
(
|
||||||
const label comm,
|
const label comm,
|
||||||
@ -772,8 +814,7 @@ bool Foam::decomposedBlockData::writeBlocks
|
|||||||
const UList<char>& data,
|
const UList<char>& data,
|
||||||
|
|
||||||
const labelUList& recvSizes,
|
const labelUList& recvSizes,
|
||||||
const bool haveSlaveData,
|
const PtrList<SubList<char>>& slaveData,
|
||||||
const List<char>& slaveData,
|
|
||||||
|
|
||||||
const UPstream::commsTypes commsType,
|
const UPstream::commsTypes commsType,
|
||||||
const bool syncReturnState
|
const bool syncReturnState
|
||||||
@ -784,17 +825,15 @@ bool Foam::decomposedBlockData::writeBlocks
|
|||||||
Pout<< "decomposedBlockData::writeBlocks:"
|
Pout<< "decomposedBlockData::writeBlocks:"
|
||||||
<< " stream:" << (osPtr.valid() ? osPtr().name() : "invalid")
|
<< " stream:" << (osPtr.valid() ? osPtr().name() : "invalid")
|
||||||
<< " data:" << data.size()
|
<< " data:" << data.size()
|
||||||
<< " haveSlaveData:" << haveSlaveData
|
|
||||||
<< " (master only) slaveData:" << slaveData.size()
|
<< " (master only) slaveData:" << slaveData.size()
|
||||||
<< " commsType:" << Pstream::commsTypeNames[commsType] << endl;
|
<< " commsType:" << Pstream::commsTypeNames[commsType] << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
const label nProcs = UPstream::nProcs(comm);
|
const label nProcs = UPstream::nProcs(comm);
|
||||||
|
|
||||||
|
|
||||||
bool ok = true;
|
bool ok = true;
|
||||||
|
|
||||||
if (haveSlaveData)
|
if (slaveData.size())
|
||||||
{
|
{
|
||||||
// Already have gathered the slave data. communicator only used to
|
// Already have gathered the slave data. communicator only used to
|
||||||
// check who is the master
|
// check who is the master
|
||||||
@ -821,8 +860,7 @@ bool Foam::decomposedBlockData::writeBlocks
|
|||||||
os << nl << nl << "// Processor" << proci << nl;
|
os << nl << nl << "// Processor" << proci << nl;
|
||||||
start[proci] = os.stdStream().tellp();
|
start[proci] = os.stdStream().tellp();
|
||||||
|
|
||||||
os << SubList<char>(slaveData, recvSizes[proci], slaveOffset);
|
os << slaveData[proci];
|
||||||
|
|
||||||
slaveOffset += recvSizes[proci];
|
slaveOffset += recvSizes[proci];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -897,44 +935,24 @@ bool Foam::decomposedBlockData::writeBlocks
|
|||||||
// maxMasterFileBufferSize
|
// maxMasterFileBufferSize
|
||||||
|
|
||||||
// Starting slave processor and number of processors
|
// Starting slave processor and number of processors
|
||||||
labelPair startAndSize(1, nProcs-1);
|
label startProc = 1;
|
||||||
|
label nSendProcs = nProcs-1;
|
||||||
|
|
||||||
while (startAndSize[1] > 0)
|
while (nSendProcs > 0)
|
||||||
{
|
{
|
||||||
labelPair masterData(startAndSize);
|
nSendProcs = calcNumProcs
|
||||||
if (UPstream::master(comm))
|
|
||||||
{
|
|
||||||
label totalSize = recvSizes[masterData[0]];
|
|
||||||
label proci = masterData[0]+1;
|
|
||||||
while
|
|
||||||
(
|
|
||||||
proci < nProcs
|
|
||||||
&& (
|
|
||||||
totalSize+recvSizes[proci]
|
|
||||||
< fileOperations::masterUncollatedFileOperation::
|
|
||||||
maxMasterFileBufferSize
|
|
||||||
)
|
|
||||||
)
|
|
||||||
{
|
|
||||||
totalSize += recvSizes[proci];
|
|
||||||
++proci;
|
|
||||||
}
|
|
||||||
|
|
||||||
masterData[1] = proci-masterData[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
// Scatter masterData
|
|
||||||
UPstream::scatter
|
|
||||||
(
|
(
|
||||||
reinterpret_cast<const char*>(masterData.cdata()),
|
comm,
|
||||||
List<int>(nProcs, sizeof(masterData)),
|
off_t
|
||||||
List<int>(nProcs, 0),
|
(
|
||||||
reinterpret_cast<char*>(startAndSize.data()),
|
fileOperations::masterUncollatedFileOperation::
|
||||||
sizeof(startAndSize),
|
maxMasterFileBufferSize
|
||||||
comm
|
),
|
||||||
|
recvSizes,
|
||||||
|
startProc
|
||||||
);
|
);
|
||||||
|
|
||||||
if (startAndSize[0] == nProcs || startAndSize[1] == 0)
|
if (startProc == nProcs || nSendProcs == 0)
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -949,8 +967,8 @@ bool Foam::decomposedBlockData::writeBlocks
|
|||||||
data,
|
data,
|
||||||
recvSizes,
|
recvSizes,
|
||||||
|
|
||||||
startAndSize[0], // startProc,
|
startProc, // startProc,
|
||||||
startAndSize[1], // nProcs,
|
nSendProcs, // nProcs,
|
||||||
|
|
||||||
sliceOffsets,
|
sliceOffsets,
|
||||||
recvData
|
recvData
|
||||||
@ -963,9 +981,9 @@ bool Foam::decomposedBlockData::writeBlocks
|
|||||||
// Write slaves
|
// Write slaves
|
||||||
for
|
for
|
||||||
(
|
(
|
||||||
label proci = startAndSize[0];
|
label proci = startProc;
|
||||||
proci < startAndSize[0]+startAndSize[1];
|
proci < startProc+nSendProcs;
|
||||||
++proci
|
proci++
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
os << nl << nl << "// Processor" << proci << nl;
|
os << nl << nl << "// Processor" << proci << nl;
|
||||||
@ -981,7 +999,7 @@ bool Foam::decomposedBlockData::writeBlocks
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
startAndSize[0] += startAndSize[1];
|
startProc += nSendProcs;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (UPstream::master(comm))
|
if (UPstream::master(comm))
|
||||||
@ -1027,7 +1045,7 @@ bool Foam::decomposedBlockData::writeData(Ostream& os) const
|
|||||||
);
|
);
|
||||||
|
|
||||||
IOobject io(*this);
|
IOobject io(*this);
|
||||||
if (Pstream::master())
|
if (Pstream::master(comm_))
|
||||||
{
|
{
|
||||||
IStringStream is
|
IStringStream is
|
||||||
(
|
(
|
||||||
@ -1043,7 +1061,7 @@ bool Foam::decomposedBlockData::writeData(Ostream& os) const
|
|||||||
|
|
||||||
// version
|
// version
|
||||||
string versionString(os.version().str());
|
string versionString(os.version().str());
|
||||||
Pstream::scatter(versionString);
|
Pstream::scatter(versionString, Pstream::msgType(), comm_);
|
||||||
|
|
||||||
// stream
|
// stream
|
||||||
string formatString;
|
string formatString;
|
||||||
@ -1051,21 +1069,21 @@ bool Foam::decomposedBlockData::writeData(Ostream& os) const
|
|||||||
OStringStream os;
|
OStringStream os;
|
||||||
os << os.format();
|
os << os.format();
|
||||||
formatString = os.str();
|
formatString = os.str();
|
||||||
Pstream::scatter(formatString);
|
Pstream::scatter(formatString, Pstream::msgType(), comm_);
|
||||||
}
|
}
|
||||||
|
|
||||||
//word masterName(name());
|
//word masterName(name());
|
||||||
//Pstream::scatter(masterName);
|
//Pstream::scatter(masterName, Pstream::msgType(), comm_);
|
||||||
|
|
||||||
Pstream::scatter(io.headerClassName());
|
Pstream::scatter(io.headerClassName(), Pstream::msgType(), comm_);
|
||||||
Pstream::scatter(io.note());
|
Pstream::scatter(io.note(), Pstream::msgType(), comm_);
|
||||||
//Pstream::scatter(io.instance(), Pstream::msgType(), comm);
|
//Pstream::scatter(io.instance(), Pstream::msgType(), comm);
|
||||||
//Pstream::scatter(io.local(), Pstream::msgType(), comm);
|
//Pstream::scatter(io.local(), Pstream::msgType(), comm);
|
||||||
|
|
||||||
fileName masterLocation(instance()/db().dbDir()/local());
|
fileName masterLocation(instance()/db().dbDir()/local());
|
||||||
Pstream::scatter(masterLocation);
|
Pstream::scatter(masterLocation, Pstream::msgType(), comm_);
|
||||||
|
|
||||||
if (!Pstream::master())
|
if (!Pstream::master(comm_))
|
||||||
{
|
{
|
||||||
writeHeader
|
writeHeader
|
||||||
(
|
(
|
||||||
@ -1081,7 +1099,7 @@ bool Foam::decomposedBlockData::writeData(Ostream& os) const
|
|||||||
|
|
||||||
os.writeQuoted(str, false);
|
os.writeQuoted(str, false);
|
||||||
|
|
||||||
if (!Pstream::master())
|
if (!Pstream::master(comm_))
|
||||||
{
|
{
|
||||||
IOobject::writeEndDivider(os);
|
IOobject::writeEndDivider(os);
|
||||||
}
|
}
|
||||||
@ -1108,10 +1126,10 @@ bool Foam::decomposedBlockData::writeObject
|
|||||||
}
|
}
|
||||||
|
|
||||||
labelList recvSizes;
|
labelList recvSizes;
|
||||||
gather(comm_, this->byteSize(), recvSizes);
|
gather(comm_, label(this->byteSize()), recvSizes);
|
||||||
|
|
||||||
List<std::streamoff> start;
|
List<std::streamoff> start;
|
||||||
List<char> slaveData; // dummy already received slave data
|
PtrList<SubList<char>> slaveData; // dummy slave data
|
||||||
return writeBlocks
|
return writeBlocks
|
||||||
(
|
(
|
||||||
comm_,
|
comm_,
|
||||||
@ -1119,7 +1137,6 @@ bool Foam::decomposedBlockData::writeObject
|
|||||||
start,
|
start,
|
||||||
*this,
|
*this,
|
||||||
recvSizes,
|
recvSizes,
|
||||||
false, // don't have slave data
|
|
||||||
slaveData,
|
slaveData,
|
||||||
commsType_
|
commsType_
|
||||||
);
|
);
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
========= |
|
========= |
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
\\ / O peration |
|
\\ / O peration |
|
||||||
\\ / A nd | Copyright (C) 2017 OpenFOAM Foundation
|
\\ / A nd | Copyright (C) 2017-2018 OpenFOAM Foundation
|
||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
@ -66,6 +66,16 @@ protected:
|
|||||||
|
|
||||||
// Protected member functions
|
// Protected member functions
|
||||||
|
|
||||||
|
//- Helper: determine number of processors whose recvSizes fits
|
||||||
|
// ito maxBufferSize
|
||||||
|
static label calcNumProcs
|
||||||
|
(
|
||||||
|
const label comm,
|
||||||
|
const off_t maxBufferSize,
|
||||||
|
const labelUList& recvSizes,
|
||||||
|
const label startProci
|
||||||
|
);
|
||||||
|
|
||||||
//- Read data into *this. ISstream is only valid on master.
|
//- Read data into *this. ISstream is only valid on master.
|
||||||
static bool readBlocks
|
static bool readBlocks
|
||||||
(
|
(
|
||||||
@ -202,12 +212,12 @@ public:
|
|||||||
const label comm,
|
const label comm,
|
||||||
autoPtr<OSstream>& osPtr,
|
autoPtr<OSstream>& osPtr,
|
||||||
List<std::streamoff>& start,
|
List<std::streamoff>& start,
|
||||||
const UList<char>&,
|
const UList<char>& masterData,
|
||||||
|
|
||||||
const labelUList& recvSizes,
|
const labelUList& recvSizes,
|
||||||
|
|
||||||
const bool haveSlaveData, // does master have slaveData
|
// optional slave data (on master)
|
||||||
const List<char>& slaveData, // optional slave data (on master)
|
const PtrList<SubList<char>>& slaveData,
|
||||||
|
|
||||||
const UPstream::commsTypes,
|
const UPstream::commsTypes,
|
||||||
const bool syncReturnState = true
|
const bool syncReturnState = true
|
||||||
|
|||||||
@ -372,10 +372,8 @@ public:
|
|||||||
static void addValidParOptions(HashTable<string>& validParOptions);
|
static void addValidParOptions(HashTable<string>& validParOptions);
|
||||||
|
|
||||||
//- Initialisation function called from main
|
//- Initialisation function called from main
|
||||||
// Spawns slave processes and initialises inter-communication.
|
// Spawns slave processes and initialises inter-communication
|
||||||
// \note warns if MPI has already been initialized.
|
static bool init(int& argc, char**& argv, const bool needsThread);
|
||||||
// Fatal if MPI has already been finalized.
|
|
||||||
static bool init(int& argc, char**& argv);
|
|
||||||
|
|
||||||
//- Special purpose initialisation function.
|
//- Special purpose initialisation function.
|
||||||
// Performs a basic MPI_Init without any other setup.
|
// Performs a basic MPI_Init without any other setup.
|
||||||
|
|||||||
@ -714,6 +714,36 @@ Foam::instantList Foam::Time::times() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::word Foam::Time::findInstance
|
||||||
|
(
|
||||||
|
const fileName& dir,
|
||||||
|
const word& name,
|
||||||
|
const IOobject::readOption rOpt,
|
||||||
|
const word& stopInstance
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
IOobject startIO
|
||||||
|
(
|
||||||
|
name, // name might be empty!
|
||||||
|
timeName(),
|
||||||
|
dir,
|
||||||
|
*this,
|
||||||
|
rOpt
|
||||||
|
);
|
||||||
|
|
||||||
|
IOobject io
|
||||||
|
(
|
||||||
|
fileHandler().findInstance
|
||||||
|
(
|
||||||
|
startIO,
|
||||||
|
timeOutputValue(),
|
||||||
|
stopInstance
|
||||||
|
)
|
||||||
|
);
|
||||||
|
return io.instance();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
Foam::word Foam::Time::findInstancePath
|
Foam::word Foam::Time::findInstancePath
|
||||||
(
|
(
|
||||||
const fileName& directory,
|
const fileName& directory,
|
||||||
|
|||||||
@ -196,9 +196,6 @@ protected:
|
|||||||
//- Read the control dictionary and set the write controls etc.
|
//- Read the control dictionary and set the write controls etc.
|
||||||
virtual void readDict();
|
virtual void readDict();
|
||||||
|
|
||||||
//- Find IOobject in the objectPath
|
|
||||||
static bool exists(IOobject& io);
|
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
|||||||
@ -1,236 +0,0 @@
|
|||||||
/*---------------------------------------------------------------------------*\
|
|
||||||
========= |
|
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
|
||||||
\\ / O peration |
|
|
||||||
\\ / A nd | Copyright (C) 2011-2017 OpenFOAM Foundation
|
|
||||||
\\/ M anipulation |
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
License
|
|
||||||
This file is part of OpenFOAM.
|
|
||||||
|
|
||||||
OpenFOAM is free software: you can redistribute it and/or modify it
|
|
||||||
under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
|
||||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
||||||
for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
Description
|
|
||||||
If "name" is empty: return the location of "directory"
|
|
||||||
If "name" is not empty: return the location of "directory" containing the
|
|
||||||
file "name".
|
|
||||||
Used in reading mesh data.
|
|
||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
#include "Time.H"
|
|
||||||
#include "IOobject.H"
|
|
||||||
#include "IOList.H"
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
bool Foam::Time::exists(IOobject& io)
|
|
||||||
{
|
|
||||||
// Generate filename for object
|
|
||||||
fileName objPath(fileHandler().objectPath(io, word::null));
|
|
||||||
|
|
||||||
// Test for either directory or a (valid) file & IOobject
|
|
||||||
bool ok;
|
|
||||||
if (io.name().empty())
|
|
||||||
{
|
|
||||||
ok = fileHandler().isDir(objPath);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ok =
|
|
||||||
fileHandler().isFile(objPath)
|
|
||||||
&& io.typeHeaderOk<IOList<label>>(false);// object with local scope
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!ok)
|
|
||||||
{
|
|
||||||
// Re-test with raw objectPath. This is for backwards
|
|
||||||
// compatibility
|
|
||||||
fileName originalPath(io.objectPath());
|
|
||||||
if (originalPath != objPath)
|
|
||||||
{
|
|
||||||
// Test for either directory or a (valid) file & IOobject
|
|
||||||
if (io.name().empty())
|
|
||||||
{
|
|
||||||
ok = fileHandler().isDir(originalPath);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ok =
|
|
||||||
fileHandler().isFile(originalPath)
|
|
||||||
&& io.typeHeaderOk<IOList<label>>(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return ok;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Foam::word Foam::Time::findInstance
|
|
||||||
(
|
|
||||||
const fileName& dir,
|
|
||||||
const word& name,
|
|
||||||
const IOobject::readOption rOpt,
|
|
||||||
const word& stopInstance
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
// Note: - if name is empty, just check the directory itself
|
|
||||||
// - check both for isFile and headerOk since the latter does a
|
|
||||||
// filePath so searches for the file.
|
|
||||||
// - check for an object with local file scope (so no looking up in
|
|
||||||
// parent directory in case of parallel)
|
|
||||||
|
|
||||||
{
|
|
||||||
IOobject io
|
|
||||||
(
|
|
||||||
name, // name might be empty!
|
|
||||||
timeName(),
|
|
||||||
dir,
|
|
||||||
*this
|
|
||||||
);
|
|
||||||
|
|
||||||
if (exists(io))
|
|
||||||
{
|
|
||||||
if (debug)
|
|
||||||
{
|
|
||||||
InfoInFunction
|
|
||||||
<< "Found exact match for \"" << name
|
|
||||||
<< "\" in " << timeName()/dir
|
|
||||||
<< endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
return timeName();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Search back through the time directories to find the time
|
|
||||||
// closest to and lower than current time
|
|
||||||
|
|
||||||
instantList ts = times();
|
|
||||||
label instanceI;
|
|
||||||
|
|
||||||
for (instanceI = ts.size()-1; instanceI >= 0; --instanceI)
|
|
||||||
{
|
|
||||||
if (ts[instanceI].value() <= timeOutputValue())
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// continue searching from here
|
|
||||||
for (; instanceI >= 0; --instanceI)
|
|
||||||
{
|
|
||||||
IOobject io
|
|
||||||
(
|
|
||||||
name, // name might be empty!
|
|
||||||
ts[instanceI].name(),
|
|
||||||
dir,
|
|
||||||
*this
|
|
||||||
);
|
|
||||||
|
|
||||||
if (exists(io))
|
|
||||||
{
|
|
||||||
if (debug)
|
|
||||||
{
|
|
||||||
InfoInFunction
|
|
||||||
<< "Found instance match for \"" << name
|
|
||||||
<< "\" in " << ts[instanceI].name()/dir
|
|
||||||
<< endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ts[instanceI].name();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if hit minimum instance
|
|
||||||
if (ts[instanceI].name() == stopInstance)
|
|
||||||
{
|
|
||||||
if (debug)
|
|
||||||
{
|
|
||||||
//InfoInFunction
|
|
||||||
Pout<< "findInstance : "
|
|
||||||
<< "Hit stopInstance " << stopInstance
|
|
||||||
<< endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
if
|
|
||||||
(
|
|
||||||
rOpt == IOobject::MUST_READ
|
|
||||||
|| rOpt == IOobject::MUST_READ_IF_MODIFIED
|
|
||||||
)
|
|
||||||
{
|
|
||||||
if (name.empty())
|
|
||||||
{
|
|
||||||
FatalErrorInFunction
|
|
||||||
<< "Cannot find directory "
|
|
||||||
<< dir << " in times " << timeName()
|
|
||||||
<< " down to " << stopInstance
|
|
||||||
<< exit(FatalError);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
FatalErrorInFunction
|
|
||||||
<< "Cannot find file \"" << name << "\" in directory "
|
|
||||||
<< dir << " in times " << timeName()
|
|
||||||
<< " down to " << stopInstance
|
|
||||||
<< exit(FatalError);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return ts[instanceI].name();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// not in any of the time directories, try constant
|
|
||||||
|
|
||||||
// Note. This needs to be a hard-coded constant, rather than the
|
|
||||||
// constant function of the time, because the latter points to
|
|
||||||
// the case constant directory in parallel cases
|
|
||||||
|
|
||||||
IOobject io
|
|
||||||
(
|
|
||||||
name,
|
|
||||||
constant(),
|
|
||||||
dir,
|
|
||||||
*this
|
|
||||||
);
|
|
||||||
|
|
||||||
if (exists(io))
|
|
||||||
{
|
|
||||||
if (debug)
|
|
||||||
{
|
|
||||||
InfoInFunction
|
|
||||||
<< "Found constant match for \"" << name
|
|
||||||
<< "\" in " << constant()/dir
|
|
||||||
<< endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
return constant();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (rOpt == IOobject::MUST_READ || rOpt == IOobject::MUST_READ_IF_MODIFIED)
|
|
||||||
{
|
|
||||||
FatalErrorInFunction
|
|
||||||
<< "Cannot find file \"" << name << "\" in directory "
|
|
||||||
<< dir << " in times " << timeName()
|
|
||||||
<< " down to " << constant()
|
|
||||||
<< exit(FatalError);
|
|
||||||
}
|
|
||||||
|
|
||||||
return constant();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
|
||||||
@ -236,7 +236,7 @@ void Foam::error::exit(const int errNo)
|
|||||||
{
|
{
|
||||||
Perr<< endl << *this << endl
|
Perr<< endl << *this << endl
|
||||||
<< "\nFOAM exiting\n" << endl;
|
<< "\nFOAM exiting\n" << endl;
|
||||||
::exit(1);
|
::exit(errNo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
========= |
|
========= |
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
\\ / O peration |
|
\\ / O peration |
|
||||||
\\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation
|
\\ / A nd | Copyright (C) 2011-2018 OpenFOAM Foundation
|
||||||
\\/ M anipulation | Copyright (C) 2015-2016 OpenCFD Ltd.
|
\\/ M anipulation | Copyright (C) 2015-2016 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
@ -183,7 +183,8 @@ void Foam::regIOobject::close()
|
|||||||
if (IFstream::debug)
|
if (IFstream::debug)
|
||||||
{
|
{
|
||||||
Pout<< "regIOobject::close() : "
|
Pout<< "regIOobject::close() : "
|
||||||
<< "finished reading " << isPtr_().name()
|
<< "finished reading "
|
||||||
|
<< (isPtr_.valid() ? isPtr_().name() : "dummy")
|
||||||
<< endl;
|
<< endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
========= |
|
========= |
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
\\ / O peration |
|
\\ / O peration |
|
||||||
\\ / A nd | Copyright (C) 2013 OpenFOAM Foundation
|
\\ / A nd | Copyright (C) 2013-2018 OpenFOAM Foundation
|
||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
@ -54,7 +54,7 @@ public:
|
|||||||
// Constructors
|
// Constructors
|
||||||
|
|
||||||
//- Construct given addressing
|
//- Construct given addressing
|
||||||
patchFieldSubset(const labelUList& directAddressing)
|
directFieldMapper(const labelUList& directAddressing)
|
||||||
:
|
:
|
||||||
directAddressing_(directAddressing),
|
directAddressing_(directAddressing),
|
||||||
hasUnmapped_(false)
|
hasUnmapped_(false)
|
||||||
|
|||||||
@ -3,7 +3,7 @@
|
|||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
\\ / O peration |
|
\\ / O peration |
|
||||||
\\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation
|
\\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation
|
||||||
\\/ M anipulation |
|
\\/ M anipulation | Copyright (C) 2018 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM.
|
This file is part of OpenFOAM.
|
||||||
@ -86,6 +86,7 @@ void pow
|
|||||||
gf.oriented() = pow(gf1.oriented(), r);
|
gf.oriented() = pow(gf1.oriented(), r);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template
|
template
|
||||||
<
|
<
|
||||||
class Type,
|
class Type,
|
||||||
@ -181,6 +182,7 @@ void sqr
|
|||||||
gf.oriented() = sqr(gf1.oriented());
|
gf.oriented() = sqr(gf1.oriented());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template<class Type, template<class> class PatchField, class GeoMesh>
|
template<class Type, template<class> class PatchField, class GeoMesh>
|
||||||
tmp
|
tmp
|
||||||
<
|
<
|
||||||
@ -217,6 +219,7 @@ sqr(const GeometricField<Type, PatchField, GeoMesh>& gf)
|
|||||||
return tSqr;
|
return tSqr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template<class Type, template<class> class PatchField, class GeoMesh>
|
template<class Type, template<class> class PatchField, class GeoMesh>
|
||||||
tmp
|
tmp
|
||||||
<
|
<
|
||||||
@ -270,6 +273,7 @@ void magSqr
|
|||||||
gsf.oriented() = magSqr(gf.oriented());
|
gsf.oriented() = magSqr(gf.oriented());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template<class Type, template<class> class PatchField, class GeoMesh>
|
template<class Type, template<class> class PatchField, class GeoMesh>
|
||||||
tmp<GeometricField<scalar, PatchField, GeoMesh>> magSqr
|
tmp<GeometricField<scalar, PatchField, GeoMesh>> magSqr
|
||||||
(
|
(
|
||||||
@ -343,6 +347,7 @@ void mag
|
|||||||
gsf.oriented() = mag(gf.oriented());
|
gsf.oriented() = mag(gf.oriented());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template<class Type, template<class> class PatchField, class GeoMesh>
|
template<class Type, template<class> class PatchField, class GeoMesh>
|
||||||
tmp<GeometricField<scalar, PatchField, GeoMesh>> mag
|
tmp<GeometricField<scalar, PatchField, GeoMesh>> mag
|
||||||
(
|
(
|
||||||
@ -458,6 +463,7 @@ cmptAv(const GeometricField<Type, PatchField, GeoMesh>& gf)
|
|||||||
return CmptAv;
|
return CmptAv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template<class Type, template<class> class PatchField, class GeoMesh>
|
template<class Type, template<class> class PatchField, class GeoMesh>
|
||||||
tmp
|
tmp
|
||||||
<
|
<
|
||||||
@ -500,7 +506,7 @@ cmptAv(const tmp<GeometricField<Type, PatchField, GeoMesh>>& tgf)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#define UNARY_REDUCTION_FUNCTION_WITH_BOUNDARY(returnType, func, gFunc) \
|
#define UNARY_REDUCTION_FUNCTION_WITH_BOUNDARY(returnType, func, binaryOp) \
|
||||||
\
|
\
|
||||||
template<class Type, template<class> class PatchField, class GeoMesh> \
|
template<class Type, template<class> class PatchField, class GeoMesh> \
|
||||||
dimensioned<returnType> func \
|
dimensioned<returnType> func \
|
||||||
@ -512,7 +518,15 @@ dimensioned<returnType> func \
|
|||||||
( \
|
( \
|
||||||
#func "(" + gf.name() + ')', \
|
#func "(" + gf.name() + ')', \
|
||||||
gf.dimensions(), \
|
gf.dimensions(), \
|
||||||
Foam::func(gFunc(gf.primitiveField()), gFunc(gf.boundaryField())) \
|
returnReduce \
|
||||||
|
( \
|
||||||
|
Foam::func \
|
||||||
|
( \
|
||||||
|
Foam::func(gf.primitiveField()), \
|
||||||
|
Foam::func(gf.boundaryField()) \
|
||||||
|
), \
|
||||||
|
binaryOp<Type>() \
|
||||||
|
) \
|
||||||
); \
|
); \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
@ -527,8 +541,8 @@ dimensioned<returnType> func \
|
|||||||
return res; \
|
return res; \
|
||||||
}
|
}
|
||||||
|
|
||||||
UNARY_REDUCTION_FUNCTION_WITH_BOUNDARY(Type, max, gMax)
|
UNARY_REDUCTION_FUNCTION_WITH_BOUNDARY(Type, max, maxOp)
|
||||||
UNARY_REDUCTION_FUNCTION_WITH_BOUNDARY(Type, min, gMin)
|
UNARY_REDUCTION_FUNCTION_WITH_BOUNDARY(Type, min, minOp)
|
||||||
|
|
||||||
#undef UNARY_REDUCTION_FUNCTION_WITH_BOUNDARY
|
#undef UNARY_REDUCTION_FUNCTION_WITH_BOUNDARY
|
||||||
|
|
||||||
|
|||||||
@ -3,7 +3,7 @@
|
|||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
\\ / O peration |
|
\\ / O peration |
|
||||||
\\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation
|
\\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation
|
||||||
\\/ M anipulation |
|
\\/ M anipulation | Copyright (C) 2018 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM.
|
This file is part of OpenFOAM.
|
||||||
@ -212,7 +212,7 @@ tmp
|
|||||||
cmptAv(const tmp<GeometricField<Type, PatchField, GeoMesh>>& tgf);
|
cmptAv(const tmp<GeometricField<Type, PatchField, GeoMesh>>& tgf);
|
||||||
|
|
||||||
|
|
||||||
#define UNARY_REDUCTION_FUNCTION_WITH_BOUNDARY(returnType, func, gFunc) \
|
#define UNARY_REDUCTION_FUNCTION_WITH_BOUNDARY(returnType, func, binaryOp) \
|
||||||
\
|
\
|
||||||
template<class Type, template<class> class PatchField, class GeoMesh> \
|
template<class Type, template<class> class PatchField, class GeoMesh> \
|
||||||
dimensioned<returnType> func \
|
dimensioned<returnType> func \
|
||||||
@ -226,8 +226,8 @@ dimensioned<returnType> func \
|
|||||||
const tmp<GeometricField<Type, PatchField, GeoMesh>>& tgf1 \
|
const tmp<GeometricField<Type, PatchField, GeoMesh>>& tgf1 \
|
||||||
);
|
);
|
||||||
|
|
||||||
UNARY_REDUCTION_FUNCTION_WITH_BOUNDARY(Type, max, gMax)
|
UNARY_REDUCTION_FUNCTION_WITH_BOUNDARY(Type, max, maxOp)
|
||||||
UNARY_REDUCTION_FUNCTION_WITH_BOUNDARY(Type, min, gMin)
|
UNARY_REDUCTION_FUNCTION_WITH_BOUNDARY(Type, min, minOp)
|
||||||
|
|
||||||
#undef UNARY_REDUCTION_FUNCTION_WITH_BOUNDARY
|
#undef UNARY_REDUCTION_FUNCTION_WITH_BOUNDARY
|
||||||
|
|
||||||
|
|||||||
@ -40,8 +40,9 @@ License
|
|||||||
#include "foamVersion.H"
|
#include "foamVersion.H"
|
||||||
#include "stringOps.H"
|
#include "stringOps.H"
|
||||||
#include "CStringList.H"
|
#include "CStringList.H"
|
||||||
#include "uncollatedFileOperation.H"
|
#include "stringListOps.H"
|
||||||
#include "masterUncollatedFileOperation.H"
|
#include "fileOperation.H"
|
||||||
|
#include "fileOperationInitialise.H"
|
||||||
#include "IOmanip.H"
|
#include "IOmanip.H"
|
||||||
|
|
||||||
#include <cctype>
|
#include <cctype>
|
||||||
@ -83,6 +84,12 @@ Foam::argList::initValidTables::initValidTables()
|
|||||||
"decomposeParDict", "file",
|
"decomposeParDict", "file",
|
||||||
"read decomposePar dictionary from specified location"
|
"read decomposePar dictionary from specified location"
|
||||||
);
|
);
|
||||||
|
argList::addOption
|
||||||
|
(
|
||||||
|
"hostRoots", "(((host1 dir1) .. (hostN dirN))",
|
||||||
|
"slave root directories (per host) for distributed running"
|
||||||
|
);
|
||||||
|
validParOptions.set("hostRoots", "((host1 dir1) .. (hostN dirN))");
|
||||||
|
|
||||||
argList::addBoolOption
|
argList::addBoolOption
|
||||||
(
|
(
|
||||||
@ -324,6 +331,7 @@ void Foam::argList::noParallel()
|
|||||||
removeOption("parallel");
|
removeOption("parallel");
|
||||||
removeOption("roots");
|
removeOption("roots");
|
||||||
removeOption("decomposeParDict");
|
removeOption("decomposeParDict");
|
||||||
|
removeOption("hostRoots");
|
||||||
validParOptions.clear();
|
validParOptions.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -687,6 +695,34 @@ Foam::argList::argList
|
|||||||
options_(argc),
|
options_(argc),
|
||||||
distributed_(false)
|
distributed_(false)
|
||||||
{
|
{
|
||||||
|
// Check for fileHandler
|
||||||
|
word handlerType(getEnv("FOAM_FILEHANDLER"));
|
||||||
|
for (int argI = 0; argI < argc; ++argI)
|
||||||
|
{
|
||||||
|
if (argv[argI][0] == '-')
|
||||||
|
{
|
||||||
|
const char *optionName = &argv[argI][1];
|
||||||
|
if (string(optionName) == "fileHandler")
|
||||||
|
{
|
||||||
|
handlerType = argv[argI+1];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (handlerType.empty())
|
||||||
|
{
|
||||||
|
handlerType = fileOperation::defaultFileHandler;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Detect any parallel options
|
||||||
|
bool needsThread = fileOperations::fileOperationInitialise::New
|
||||||
|
(
|
||||||
|
handlerType,
|
||||||
|
argc,
|
||||||
|
argv
|
||||||
|
)().needsThreading();
|
||||||
|
|
||||||
|
|
||||||
// Check if this run is a parallel run by searching for any parallel option
|
// Check if this run is a parallel run by searching for any parallel option
|
||||||
// If found call runPar which might filter argv
|
// If found call runPar which might filter argv
|
||||||
for (int argi = 1; argi < argc; ++argi)
|
for (int argi = 1; argi < argc; ++argi)
|
||||||
@ -697,7 +733,7 @@ Foam::argList::argList
|
|||||||
|
|
||||||
if (validParOptions.found(optName))
|
if (validParOptions.found(optName))
|
||||||
{
|
{
|
||||||
parRunControl_.runPar(argc, argv);
|
parRunControl_.runPar(argc, argv, needsThread);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -942,6 +978,58 @@ void Foam::argList::parse
|
|||||||
Foam::fileHandler(handler);
|
Foam::fileHandler(handler);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
stringList slaveProcs;
|
||||||
|
stringList slaveMachine;
|
||||||
|
const int writeHostsSwitch = debug::infoSwitch("writeHosts", 1);
|
||||||
|
|
||||||
|
// Collect slave machine/pid, and check that the build is identical
|
||||||
|
if (parRunControl_.parRun())
|
||||||
|
{
|
||||||
|
if (Pstream::master())
|
||||||
|
{
|
||||||
|
slaveProcs.setSize(Pstream::nProcs() - 1);
|
||||||
|
slaveMachine.setSize(Pstream::nProcs() - 1);
|
||||||
|
label proci = 0;
|
||||||
|
for
|
||||||
|
(
|
||||||
|
int slave = Pstream::firstSlave();
|
||||||
|
slave <= Pstream::lastSlave();
|
||||||
|
slave++
|
||||||
|
)
|
||||||
|
{
|
||||||
|
IPstream fromSlave(Pstream::commsTypes::scheduled, slave);
|
||||||
|
|
||||||
|
string slaveBuild;
|
||||||
|
label slavePid;
|
||||||
|
fromSlave >> slaveBuild >> slaveMachine[proci] >> slavePid;
|
||||||
|
slaveProcs[proci] = slaveMachine[proci] + "." + name(slavePid);
|
||||||
|
proci++;
|
||||||
|
|
||||||
|
// Check build string to make sure all processors are running
|
||||||
|
// the same build
|
||||||
|
if (slaveBuild != Foam::FOAMbuild)
|
||||||
|
{
|
||||||
|
FatalErrorIn(executable())
|
||||||
|
<< "Master is running version " << Foam::FOAMbuild
|
||||||
|
<< "; slave " << proci << " is running version "
|
||||||
|
<< slaveBuild
|
||||||
|
<< exit(FatalError);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
OPstream toMaster
|
||||||
|
(
|
||||||
|
Pstream::commsTypes::scheduled,
|
||||||
|
Pstream::masterNo()
|
||||||
|
);
|
||||||
|
toMaster << string(Foam::FOAMbuild) << hostName() << pid();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Case is a single processor run unless it is running parallel
|
// Case is a single processor run unless it is running parallel
|
||||||
int nProcs = 1;
|
int nProcs = 1;
|
||||||
|
|
||||||
@ -999,6 +1087,52 @@ void Foam::argList::parse
|
|||||||
dictNProcs = roots.size()+1;
|
dictNProcs = roots.size()+1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (options_.found("hostRoots"))
|
||||||
|
{
|
||||||
|
source = "-hostRoots";
|
||||||
|
IStringStream is(options_["hostRoots"]);
|
||||||
|
List<Tuple2<wordRe, fileName>> hostRoots(is);
|
||||||
|
|
||||||
|
roots.setSize(Pstream::nProcs()-1);
|
||||||
|
forAll(hostRoots, i)
|
||||||
|
{
|
||||||
|
const Tuple2<wordRe, fileName>& hostRoot = hostRoots[i];
|
||||||
|
const wordRe& re = hostRoot.first();
|
||||||
|
labelList matchedRoots(findStrings(re, slaveMachine));
|
||||||
|
forAll(matchedRoots, matchi)
|
||||||
|
{
|
||||||
|
label slavei = matchedRoots[matchi];
|
||||||
|
if (roots[slavei] != wordRe())
|
||||||
|
{
|
||||||
|
FatalErrorInFunction
|
||||||
|
<< "Slave " << slaveMachine[slavei]
|
||||||
|
<< " has multiple matching roots in "
|
||||||
|
<< hostRoots << exit(FatalError);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
roots[slavei] = hostRoot.second();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check
|
||||||
|
forAll(roots, slavei)
|
||||||
|
{
|
||||||
|
if (roots[slavei] == wordRe())
|
||||||
|
{
|
||||||
|
FatalErrorInFunction
|
||||||
|
<< "Slave " << slaveMachine[slavei]
|
||||||
|
<< " has no matching roots in "
|
||||||
|
<< hostRoots << exit(FatalError);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (roots.size() != 1)
|
||||||
|
{
|
||||||
|
dictNProcs = roots.size()+1;
|
||||||
|
}
|
||||||
|
}
|
||||||
else if (checkProcessorDirectories_)
|
else if (checkProcessorDirectories_)
|
||||||
{
|
{
|
||||||
// Use values from decomposeParDict, the location was already
|
// Use values from decomposeParDict, the location was already
|
||||||
@ -1172,55 +1306,6 @@ void Foam::argList::parse
|
|||||||
case_ = globalCase_;
|
case_ = globalCase_;
|
||||||
}
|
}
|
||||||
|
|
||||||
stringList slaveProcs;
|
|
||||||
const int writeHostsSwitch = debug::infoSwitch("writeHosts", 1);
|
|
||||||
|
|
||||||
// Collect slave machine/pid, and check that the build is identical
|
|
||||||
if (parRunControl_.parRun())
|
|
||||||
{
|
|
||||||
if (Pstream::master())
|
|
||||||
{
|
|
||||||
slaveProcs.setSize(Pstream::nProcs() - 1);
|
|
||||||
label proci = 0;
|
|
||||||
for
|
|
||||||
(
|
|
||||||
int slave = Pstream::firstSlave();
|
|
||||||
slave <= Pstream::lastSlave();
|
|
||||||
slave++
|
|
||||||
)
|
|
||||||
{
|
|
||||||
IPstream fromSlave(Pstream::commsTypes::scheduled, slave);
|
|
||||||
|
|
||||||
string slaveBuild;
|
|
||||||
string slaveMachine;
|
|
||||||
label slavePid;
|
|
||||||
fromSlave >> slaveBuild >> slaveMachine >> slavePid;
|
|
||||||
|
|
||||||
slaveProcs[proci++] = slaveMachine + "." + name(slavePid);
|
|
||||||
|
|
||||||
// Check build string to make sure all processors are running
|
|
||||||
// the same build
|
|
||||||
if (slaveBuild != Foam::FOAMbuild)
|
|
||||||
{
|
|
||||||
FatalErrorIn(executable())
|
|
||||||
<< "Master is running version " << Foam::FOAMbuild
|
|
||||||
<< "; slave " << proci << " is running version "
|
|
||||||
<< slaveBuild
|
|
||||||
<< exit(FatalError);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
OPstream toMaster
|
|
||||||
(
|
|
||||||
Pstream::commsTypes::scheduled,
|
|
||||||
Pstream::masterNo()
|
|
||||||
);
|
|
||||||
toMaster << string(Foam::FOAMbuild) << hostName() << pid();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Keep or discard slave and root information for reporting:
|
// Keep or discard slave and root information for reporting:
|
||||||
if (Pstream::master() && parRunControl_.parRun())
|
if (Pstream::master() && parRunControl_.parRun())
|
||||||
{
|
{
|
||||||
@ -1412,6 +1497,7 @@ bool Foam::argList::unsetOption(const word& optName)
|
|||||||
optName == "case"
|
optName == "case"
|
||||||
|| optName == "parallel"
|
|| optName == "parallel"
|
||||||
|| optName == "roots"
|
|| optName == "roots"
|
||||||
|
|| optName == "hostRoots"
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
FatalErrorInFunction
|
FatalErrorInFunction
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
========= |
|
========= |
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
\\ / O peration |
|
\\ / O peration |
|
||||||
\\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
|
\\ / A nd | Copyright (C) 2011-2018 OpenFOAM Foundation
|
||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
@ -70,11 +70,11 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
//- Initialize Pstream for a parallel run
|
//- Initialize Pstream for a parallel run
|
||||||
void runPar(int& argc, char**& argv)
|
void runPar(int& argc, char**& argv, const bool needsThread)
|
||||||
{
|
{
|
||||||
RunPar = true;
|
RunPar = true;
|
||||||
|
|
||||||
if (!Pstream::init(argc, argv))
|
if (!Pstream::init(argc, argv, needsThread))
|
||||||
{
|
{
|
||||||
Info<< "Failed to start parallel run" << endl;
|
Info<< "Failed to start parallel run" << endl;
|
||||||
Pstream::exit(1);
|
Pstream::exit(1);
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
========= |
|
========= |
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
\\ / O peration |
|
\\ / O peration |
|
||||||
\\ / A nd | Copyright (C) 2011-2017 OpenFOAM Foundation
|
\\ / A nd | Copyright (C) 2011-2018 OpenFOAM Foundation
|
||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
@ -95,21 +95,31 @@ Foam::dictionary& Foam::debug::controlDict()
|
|||||||
{
|
{
|
||||||
if (!controlDictPtr_)
|
if (!controlDictPtr_)
|
||||||
{
|
{
|
||||||
fileNameList controlDictFiles = findEtcFiles("controlDict", true);
|
string controlDictString(getEnv("FOAM_CONTROLDICT"));
|
||||||
controlDictPtr_ = new dictionary();
|
if (!controlDictString.empty())
|
||||||
forAllReverse(controlDictFiles, cdfi)
|
|
||||||
{
|
{
|
||||||
IFstream ifs(controlDictFiles[cdfi]);
|
// Read from environment
|
||||||
|
IStringStream is(controlDictString);
|
||||||
if (!ifs.good())
|
controlDictPtr_ = new dictionary(is);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fileNameList controlDictFiles = findEtcFiles("controlDict", true);
|
||||||
|
controlDictPtr_ = new dictionary();
|
||||||
|
forAllReverse(controlDictFiles, cdfi)
|
||||||
{
|
{
|
||||||
SafeFatalIOErrorInFunction
|
IFstream ifs(controlDictFiles[cdfi]);
|
||||||
(
|
|
||||||
ifs,
|
if (!ifs.good())
|
||||||
"Cannot open controlDict"
|
{
|
||||||
);
|
SafeFatalIOErrorInFunction
|
||||||
|
(
|
||||||
|
ifs,
|
||||||
|
"Cannot open controlDict"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
controlDictPtr_->merge(dictionary(ifs));
|
||||||
}
|
}
|
||||||
controlDictPtr_->merge(dictionary(ifs));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
========= |
|
========= |
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
\\ / O peration |
|
\\ / O peration |
|
||||||
\\ / A nd | Copyright (C) 2017 OpenFOAM Foundation
|
\\ / A nd | Copyright (C) 2017-2018 OpenFOAM Foundation
|
||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
@ -26,6 +26,7 @@ License
|
|||||||
#include "OFstreamCollator.H"
|
#include "OFstreamCollator.H"
|
||||||
#include "OFstream.H"
|
#include "OFstream.H"
|
||||||
#include "decomposedBlockData.H"
|
#include "decomposedBlockData.H"
|
||||||
|
#include "masterUncollatedFileOperation.H"
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||||
|
|
||||||
@ -44,8 +45,7 @@ bool Foam::OFstreamCollator::writeFile
|
|||||||
const fileName& fName,
|
const fileName& fName,
|
||||||
const string& masterData,
|
const string& masterData,
|
||||||
const labelUList& recvSizes,
|
const labelUList& recvSizes,
|
||||||
const bool haveSlaveData, // does master have slaveData
|
const PtrList<SubList<char>>& slaveData, // optional slave data
|
||||||
const UList<char>& slaveData, // on master: slave data
|
|
||||||
IOstream::streamFormat fmt,
|
IOstream::streamFormat fmt,
|
||||||
IOstream::versionNumber ver,
|
IOstream::versionNumber ver,
|
||||||
IOstream::compressionType cmp,
|
IOstream::compressionType cmp,
|
||||||
@ -54,9 +54,22 @@ bool Foam::OFstreamCollator::writeFile
|
|||||||
{
|
{
|
||||||
if (debug)
|
if (debug)
|
||||||
{
|
{
|
||||||
Pout<< "OFstreamCollator : Writing " << masterData.size()
|
Pout<< "OFstreamCollator : Writing master " << masterData.size()
|
||||||
<< " bytes to " << fName
|
<< " bytes to " << fName
|
||||||
<< " using comm " << comm << endl;
|
<< " using comm " << comm << endl;
|
||||||
|
if (slaveData.size())
|
||||||
|
{
|
||||||
|
Pout<< "OFstreamCollator : Slave data" << endl;
|
||||||
|
forAll(slaveData, proci)
|
||||||
|
{
|
||||||
|
if (slaveData.set(proci))
|
||||||
|
{
|
||||||
|
Pout<< " " << proci
|
||||||
|
<< " size:" << slaveData[proci].size()
|
||||||
|
<< endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
autoPtr<OSstream> osPtr;
|
autoPtr<OSstream> osPtr;
|
||||||
@ -76,17 +89,20 @@ bool Foam::OFstreamCollator::writeFile
|
|||||||
);
|
);
|
||||||
|
|
||||||
// We don't have IOobject so cannot use IOobject::writeHeader
|
// We don't have IOobject so cannot use IOobject::writeHeader
|
||||||
OSstream& os = osPtr();
|
if (!append)
|
||||||
decomposedBlockData::writeHeader
|
{
|
||||||
(
|
OSstream& os = osPtr();
|
||||||
os,
|
decomposedBlockData::writeHeader
|
||||||
ver,
|
(
|
||||||
fmt,
|
os,
|
||||||
typeName,
|
ver,
|
||||||
"",
|
fmt,
|
||||||
fName,
|
typeName,
|
||||||
fName.name()
|
"",
|
||||||
);
|
fName,
|
||||||
|
fName.name()
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -109,9 +125,13 @@ bool Foam::OFstreamCollator::writeFile
|
|||||||
start,
|
start,
|
||||||
slice,
|
slice,
|
||||||
recvSizes,
|
recvSizes,
|
||||||
haveSlaveData,
|
|
||||||
slaveData,
|
slaveData,
|
||||||
UPstream::commsTypes::nonBlocking, //scheduled,
|
(
|
||||||
|
fileOperations::masterUncollatedFileOperation::
|
||||||
|
maxMasterFileBufferSize == 0
|
||||||
|
? UPstream::commsTypes::scheduled
|
||||||
|
: UPstream::commsTypes::nonBlocking
|
||||||
|
),
|
||||||
false // do not reduce return state
|
false // do not reduce return state
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -132,7 +152,11 @@ bool Foam::OFstreamCollator::writeFile
|
|||||||
{
|
{
|
||||||
sum += recvSizes[i];
|
sum += recvSizes[i];
|
||||||
}
|
}
|
||||||
Pout<< " (overall " << sum << ")";
|
// Use ostringstream to display long int (until writing these is
|
||||||
|
// supported)
|
||||||
|
std::ostringstream os;
|
||||||
|
os << sum;
|
||||||
|
Pout<< " (overall " << os.str() << ")";
|
||||||
}
|
}
|
||||||
Pout<< " to " << fName
|
Pout<< " to " << fName
|
||||||
<< " using comm " << comm << endl;
|
<< " using comm " << comm << endl;
|
||||||
@ -151,12 +175,13 @@ void* Foam::OFstreamCollator::writeAll(void *threadarg)
|
|||||||
{
|
{
|
||||||
writeData* ptr = nullptr;
|
writeData* ptr = nullptr;
|
||||||
|
|
||||||
lockMutex(handler.mutex_);
|
|
||||||
if (handler.objects_.size())
|
|
||||||
{
|
{
|
||||||
ptr = handler.objects_.pop();
|
std::lock_guard<std::mutex> guard(handler.mutex_);
|
||||||
|
if (handler.objects_.size())
|
||||||
|
{
|
||||||
|
ptr = handler.objects_.pop();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
unlockMutex(handler.mutex_);
|
|
||||||
|
|
||||||
if (!ptr)
|
if (!ptr)
|
||||||
{
|
{
|
||||||
@ -164,6 +189,28 @@ void* Foam::OFstreamCollator::writeAll(void *threadarg)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
// Convert storage to pointers
|
||||||
|
PtrList<SubList<char>> slaveData;
|
||||||
|
if (ptr->slaveData_.size())
|
||||||
|
{
|
||||||
|
slaveData.setSize(ptr->slaveData_.size());
|
||||||
|
forAll(slaveData, proci)
|
||||||
|
{
|
||||||
|
if (ptr->slaveData_.set(proci))
|
||||||
|
{
|
||||||
|
slaveData.set
|
||||||
|
(
|
||||||
|
proci,
|
||||||
|
new SubList<char>
|
||||||
|
(
|
||||||
|
ptr->slaveData_[proci],
|
||||||
|
ptr->sizes_[proci]
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool ok = writeFile
|
bool ok = writeFile
|
||||||
(
|
(
|
||||||
ptr->comm_,
|
ptr->comm_,
|
||||||
@ -171,9 +218,7 @@ void* Foam::OFstreamCollator::writeAll(void *threadarg)
|
|||||||
ptr->pathName_,
|
ptr->pathName_,
|
||||||
ptr->data_,
|
ptr->data_,
|
||||||
ptr->sizes_,
|
ptr->sizes_,
|
||||||
ptr->haveSlaveData_,
|
slaveData,
|
||||||
ptr->slaveData_,
|
|
||||||
|
|
||||||
ptr->format_,
|
ptr->format_,
|
||||||
ptr->version_,
|
ptr->version_,
|
||||||
ptr->compression_,
|
ptr->compression_,
|
||||||
@ -196,9 +241,10 @@ void* Foam::OFstreamCollator::writeAll(void *threadarg)
|
|||||||
Pout<< "OFstreamCollator : Exiting write thread " << endl;
|
Pout<< "OFstreamCollator : Exiting write thread " << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
lockMutex(handler.mutex_);
|
{
|
||||||
handler.threadRunning_ = false;
|
std::lock_guard<std::mutex> guard(handler.mutex_);
|
||||||
unlockMutex(handler.mutex_);
|
handler.threadRunning_ = false;
|
||||||
|
}
|
||||||
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
@ -211,12 +257,13 @@ void Foam::OFstreamCollator::waitForBufferSpace(const off_t wantedSize) const
|
|||||||
// Count files to be written
|
// Count files to be written
|
||||||
off_t totalSize = 0;
|
off_t totalSize = 0;
|
||||||
|
|
||||||
lockMutex(mutex_);
|
|
||||||
forAllConstIter(FIFOStack<writeData*>, objects_, iter)
|
|
||||||
{
|
{
|
||||||
totalSize += iter()->size();
|
std::lock_guard<std::mutex> guard(mutex_);
|
||||||
|
forAllConstIter(FIFOStack<writeData*>, objects_, iter)
|
||||||
|
{
|
||||||
|
totalSize += iter()->size();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
unlockMutex(mutex_);
|
|
||||||
|
|
||||||
if (totalSize == 0 || (totalSize+wantedSize) <= maxBufferSize_)
|
if (totalSize == 0 || (totalSize+wantedSize) <= maxBufferSize_)
|
||||||
{
|
{
|
||||||
@ -225,13 +272,12 @@ void Foam::OFstreamCollator::waitForBufferSpace(const off_t wantedSize) const
|
|||||||
|
|
||||||
if (debug)
|
if (debug)
|
||||||
{
|
{
|
||||||
lockMutex(mutex_);
|
std::lock_guard<std::mutex> guard(mutex_);
|
||||||
Pout<< "OFstreamCollator : Waiting for buffer space."
|
Pout<< "OFstreamCollator : Waiting for buffer space."
|
||||||
<< " Currently in use:" << totalSize
|
<< " Currently in use:" << totalSize
|
||||||
<< " limit:" << maxBufferSize_
|
<< " limit:" << maxBufferSize_
|
||||||
<< " files:" << objects_.size()
|
<< " files:" << objects_.size()
|
||||||
<< endl;
|
<< endl;
|
||||||
unlockMutex(mutex_);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sleep(5);
|
sleep(5);
|
||||||
@ -244,25 +290,34 @@ void Foam::OFstreamCollator::waitForBufferSpace(const off_t wantedSize) const
|
|||||||
Foam::OFstreamCollator::OFstreamCollator(const off_t maxBufferSize)
|
Foam::OFstreamCollator::OFstreamCollator(const off_t maxBufferSize)
|
||||||
:
|
:
|
||||||
maxBufferSize_(maxBufferSize),
|
maxBufferSize_(maxBufferSize),
|
||||||
mutex_
|
|
||||||
(
|
|
||||||
maxBufferSize_ > 0
|
|
||||||
? allocateMutex()
|
|
||||||
: -1
|
|
||||||
),
|
|
||||||
thread_
|
|
||||||
(
|
|
||||||
maxBufferSize_ > 0
|
|
||||||
? allocateThread()
|
|
||||||
: -1
|
|
||||||
),
|
|
||||||
threadRunning_(false),
|
threadRunning_(false),
|
||||||
comm_
|
localComm_(UPstream::worldComm),
|
||||||
|
threadComm_
|
||||||
(
|
(
|
||||||
UPstream::allocateCommunicator
|
UPstream::allocateCommunicator
|
||||||
(
|
(
|
||||||
UPstream::worldComm,
|
localComm_,
|
||||||
identity(UPstream::nProcs(UPstream::worldComm))
|
identity(UPstream::nProcs(localComm_))
|
||||||
|
)
|
||||||
|
)
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::OFstreamCollator::OFstreamCollator
|
||||||
|
(
|
||||||
|
const off_t maxBufferSize,
|
||||||
|
const label comm
|
||||||
|
)
|
||||||
|
:
|
||||||
|
maxBufferSize_(maxBufferSize),
|
||||||
|
threadRunning_(false),
|
||||||
|
localComm_(comm),
|
||||||
|
threadComm_
|
||||||
|
(
|
||||||
|
UPstream::allocateCommunicator
|
||||||
|
(
|
||||||
|
localComm_,
|
||||||
|
identity(UPstream::nProcs(localComm_))
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
{}
|
{}
|
||||||
@ -272,26 +327,19 @@ Foam::OFstreamCollator::OFstreamCollator(const off_t maxBufferSize)
|
|||||||
|
|
||||||
Foam::OFstreamCollator::~OFstreamCollator()
|
Foam::OFstreamCollator::~OFstreamCollator()
|
||||||
{
|
{
|
||||||
if (threadRunning_)
|
if (thread_.valid())
|
||||||
{
|
{
|
||||||
if (debug)
|
if (debug)
|
||||||
{
|
{
|
||||||
Pout<< "~OFstreamCollator : Waiting for write thread" << endl;
|
Pout<< "~OFstreamCollator : Waiting for write thread" << endl;
|
||||||
}
|
}
|
||||||
|
thread_().join();
|
||||||
|
thread_.clear();
|
||||||
|
}
|
||||||
|
|
||||||
joinThread(thread_);
|
if (threadComm_ != -1)
|
||||||
}
|
|
||||||
if (thread_ != -1)
|
|
||||||
{
|
{
|
||||||
freeThread(thread_);
|
UPstream::freeCommunicator(threadComm_);
|
||||||
}
|
|
||||||
if (mutex_ != -1)
|
|
||||||
{
|
|
||||||
freeMutex(mutex_);
|
|
||||||
}
|
|
||||||
if (comm_ != -1)
|
|
||||||
{
|
|
||||||
UPstream::freeCommunicator(comm_);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -312,7 +360,8 @@ bool Foam::OFstreamCollator::write
|
|||||||
// Determine (on master) sizes to receive. Note: do NOT use thread
|
// Determine (on master) sizes to receive. Note: do NOT use thread
|
||||||
// communicator
|
// communicator
|
||||||
labelList recvSizes;
|
labelList recvSizes;
|
||||||
decomposedBlockData::gather(Pstream::worldComm, data.size(), recvSizes);
|
decomposedBlockData::gather(localComm_, label(data.size()), recvSizes);
|
||||||
|
|
||||||
off_t totalSize = 0;
|
off_t totalSize = 0;
|
||||||
label maxLocalSize = 0;
|
label maxLocalSize = 0;
|
||||||
{
|
{
|
||||||
@ -321,8 +370,8 @@ bool Foam::OFstreamCollator::write
|
|||||||
totalSize += recvSizes[proci];
|
totalSize += recvSizes[proci];
|
||||||
maxLocalSize = max(maxLocalSize, recvSizes[proci]);
|
maxLocalSize = max(maxLocalSize, recvSizes[proci]);
|
||||||
}
|
}
|
||||||
Pstream::scatter(totalSize, Pstream::msgType(), Pstream::worldComm);
|
Pstream::scatter(totalSize, Pstream::msgType(), localComm_);
|
||||||
Pstream::scatter(maxLocalSize, Pstream::msgType(), Pstream::worldComm);
|
Pstream::scatter(maxLocalSize, Pstream::msgType(), localComm_);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (maxBufferSize_ == 0 || maxLocalSize > maxBufferSize_)
|
if (maxBufferSize_ == 0 || maxLocalSize > maxBufferSize_)
|
||||||
@ -330,18 +379,17 @@ bool Foam::OFstreamCollator::write
|
|||||||
if (debug)
|
if (debug)
|
||||||
{
|
{
|
||||||
Pout<< "OFstreamCollator : non-thread gather and write of " << fName
|
Pout<< "OFstreamCollator : non-thread gather and write of " << fName
|
||||||
<< " using worldComm" << endl;
|
<< " using local comm " << localComm_ << endl;
|
||||||
}
|
}
|
||||||
// Direct collating and writing (so master blocks until all written!)
|
// Direct collating and writing (so master blocks until all written!)
|
||||||
const List<char> dummySlaveData;
|
const PtrList<SubList<char>> dummySlaveData;
|
||||||
return writeFile
|
return writeFile
|
||||||
(
|
(
|
||||||
UPstream::worldComm,
|
localComm_,
|
||||||
typeName,
|
typeName,
|
||||||
fName,
|
fName,
|
||||||
data,
|
data,
|
||||||
recvSizes,
|
recvSizes,
|
||||||
false, // no slave data provided yet
|
|
||||||
dummySlaveData,
|
dummySlaveData,
|
||||||
fmt,
|
fmt,
|
||||||
ver,
|
ver,
|
||||||
@ -360,22 +408,28 @@ bool Foam::OFstreamCollator::write
|
|||||||
<< fName << endl;
|
<< fName << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Pstream::master())
|
if (Pstream::master(localComm_))
|
||||||
{
|
{
|
||||||
waitForBufferSpace(totalSize);
|
waitForBufferSpace(totalSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Allocate local buffer for all collated data
|
|
||||||
|
// Receive in chunks of labelMax (2^31-1) since this is the maximum
|
||||||
|
// size that a List can be
|
||||||
|
|
||||||
autoPtr<writeData> fileAndDataPtr
|
autoPtr<writeData> fileAndDataPtr
|
||||||
(
|
(
|
||||||
new writeData
|
new writeData
|
||||||
(
|
(
|
||||||
comm_, // Note: comm not actually used anymore
|
threadComm_, // Note: comm not actually used anymore
|
||||||
typeName,
|
typeName,
|
||||||
fName,
|
fName,
|
||||||
data,
|
(
|
||||||
|
Pstream::master(localComm_)
|
||||||
|
? data // Only used on master
|
||||||
|
: string::null
|
||||||
|
),
|
||||||
recvSizes,
|
recvSizes,
|
||||||
true, // have slave data (collected below)
|
|
||||||
fmt,
|
fmt,
|
||||||
ver,
|
ver,
|
||||||
cmp,
|
cmp,
|
||||||
@ -384,40 +438,84 @@ bool Foam::OFstreamCollator::write
|
|||||||
);
|
);
|
||||||
writeData& fileAndData = fileAndDataPtr();
|
writeData& fileAndData = fileAndDataPtr();
|
||||||
|
|
||||||
// Gather the slave data and insert into fileAndData
|
PtrList<List<char>>& slaveData = fileAndData.slaveData_;
|
||||||
|
|
||||||
UList<char> slice(const_cast<char*>(data.data()), label(data.size()));
|
UList<char> slice(const_cast<char*>(data.data()), label(data.size()));
|
||||||
List<int> slaveOffsets;
|
|
||||||
decomposedBlockData::gatherSlaveData
|
|
||||||
(
|
|
||||||
Pstream::worldComm, // Note: using simulation thread
|
|
||||||
slice,
|
|
||||||
recvSizes,
|
|
||||||
|
|
||||||
1, // startProc,
|
slaveData.setSize(recvSizes.size());
|
||||||
Pstream::nProcs()-1, // n procs
|
|
||||||
|
|
||||||
slaveOffsets,
|
// Gather all data onto master. Is done in local communicator since
|
||||||
fileAndData.slaveData_
|
// not in write thread. Note that we do not store in contiguous
|
||||||
);
|
// buffer since that would limit to 2G chars.
|
||||||
|
label startOfRequests = Pstream::nRequests();
|
||||||
// Append to thread buffer
|
if (Pstream::master(localComm_))
|
||||||
lockMutex(mutex_);
|
|
||||||
objects_.push(fileAndDataPtr.ptr());
|
|
||||||
unlockMutex(mutex_);
|
|
||||||
|
|
||||||
// Start thread if not running
|
|
||||||
lockMutex(mutex_);
|
|
||||||
if (!threadRunning_)
|
|
||||||
{
|
{
|
||||||
createThread(thread_, writeAll, this);
|
for (label proci = 1; proci < slaveData.size(); proci++)
|
||||||
if (debug)
|
|
||||||
{
|
{
|
||||||
Pout<< "OFstreamCollator : Started write thread "
|
slaveData.set(proci, new List<char>(recvSizes[proci]));
|
||||||
<< thread_ << endl;
|
UIPstream::read
|
||||||
|
(
|
||||||
|
UPstream::commsTypes::nonBlocking,
|
||||||
|
proci,
|
||||||
|
reinterpret_cast<char*>(slaveData[proci].begin()),
|
||||||
|
slaveData[proci].byteSize(),
|
||||||
|
Pstream::msgType(),
|
||||||
|
localComm_
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if
|
||||||
|
(
|
||||||
|
!UOPstream::write
|
||||||
|
(
|
||||||
|
UPstream::commsTypes::nonBlocking,
|
||||||
|
0,
|
||||||
|
reinterpret_cast<const char*>(slice.begin()),
|
||||||
|
slice.byteSize(),
|
||||||
|
Pstream::msgType(),
|
||||||
|
localComm_
|
||||||
|
)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
FatalErrorInFunction
|
||||||
|
<< "Cannot send outgoing message. "
|
||||||
|
<< "to:" << 0 << " nBytes:"
|
||||||
|
<< label(slice.byteSize())
|
||||||
|
<< Foam::abort(FatalError);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Pstream::waitRequests(startOfRequests);
|
||||||
|
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> guard(mutex_);
|
||||||
|
|
||||||
|
// Append to thread buffer
|
||||||
|
objects_.push(fileAndDataPtr.ptr());
|
||||||
|
|
||||||
|
// Start thread if not running
|
||||||
|
if (!threadRunning_)
|
||||||
|
{
|
||||||
|
if (thread_.valid())
|
||||||
|
{
|
||||||
|
if (debug)
|
||||||
|
{
|
||||||
|
Pout<< "OFstreamCollator : Waiting for write thread"
|
||||||
|
<< endl;
|
||||||
|
}
|
||||||
|
thread_().join();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (debug)
|
||||||
|
{
|
||||||
|
Pout<< "OFstreamCollator : Starting write thread"
|
||||||
|
<< endl;
|
||||||
|
}
|
||||||
|
thread_.reset(new std::thread(writeAll, this));
|
||||||
|
threadRunning_ = true;
|
||||||
}
|
}
|
||||||
threadRunning_ = true;
|
|
||||||
}
|
}
|
||||||
unlockMutex(mutex_);
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -426,57 +524,65 @@ bool Foam::OFstreamCollator::write
|
|||||||
if (debug)
|
if (debug)
|
||||||
{
|
{
|
||||||
Pout<< "OFstreamCollator : thread gather and write of " << fName
|
Pout<< "OFstreamCollator : thread gather and write of " << fName
|
||||||
<< " in thread " << thread_
|
<< " using communicator " << threadComm_ << endl;
|
||||||
<< " using communicator " << comm_ << endl;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!UPstream::haveThreads())
|
if (!UPstream::haveThreads())
|
||||||
{
|
{
|
||||||
FatalErrorInFunction
|
FatalErrorInFunction
|
||||||
<< "mpi does not seem to have thread support."
|
<< "mpi does not seem to have thread support."
|
||||||
<< "Please increase the buffer size 'maxThreadFileBufferSize'"
|
<< " Make sure to set buffer size 'maxThreadFileBufferSize'"
|
||||||
<< " to at least " << totalSize
|
<< " to at least " << totalSize
|
||||||
<< " to be able to do the collating before threading."
|
<< " to be able to do the collating before threading."
|
||||||
<< exit(FatalError);
|
<< exit(FatalError);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Pstream::master())
|
if (Pstream::master(localComm_))
|
||||||
{
|
{
|
||||||
waitForBufferSpace(data.size());
|
waitForBufferSpace(data.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
lockMutex(mutex_);
|
|
||||||
// Push all file info on buffer. Note that no slave data provided
|
|
||||||
// so it will trigger communication inside the thread
|
|
||||||
objects_.push
|
|
||||||
(
|
|
||||||
new writeData
|
|
||||||
(
|
|
||||||
comm_,
|
|
||||||
typeName,
|
|
||||||
fName,
|
|
||||||
data,
|
|
||||||
recvSizes,
|
|
||||||
false, // Have no slave data; collect in thread
|
|
||||||
fmt,
|
|
||||||
ver,
|
|
||||||
cmp,
|
|
||||||
append
|
|
||||||
)
|
|
||||||
);
|
|
||||||
unlockMutex(mutex_);
|
|
||||||
|
|
||||||
lockMutex(mutex_);
|
|
||||||
if (!threadRunning_)
|
|
||||||
{
|
{
|
||||||
createThread(thread_, writeAll, this);
|
std::lock_guard<std::mutex> guard(mutex_);
|
||||||
if (debug)
|
|
||||||
|
// Push all file info on buffer. Note that no slave data provided
|
||||||
|
// so it will trigger communication inside the thread
|
||||||
|
objects_.push
|
||||||
|
(
|
||||||
|
new writeData
|
||||||
|
(
|
||||||
|
threadComm_,
|
||||||
|
typeName,
|
||||||
|
fName,
|
||||||
|
data,
|
||||||
|
recvSizes,
|
||||||
|
fmt,
|
||||||
|
ver,
|
||||||
|
cmp,
|
||||||
|
append
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!threadRunning_)
|
||||||
{
|
{
|
||||||
Pout<< "OFstreamCollator : Started write thread " << endl;
|
if (thread_.valid())
|
||||||
|
{
|
||||||
|
if (debug)
|
||||||
|
{
|
||||||
|
Pout<< "OFstreamCollator : Waiting for write thread"
|
||||||
|
<< endl;
|
||||||
|
}
|
||||||
|
thread_().join();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (debug)
|
||||||
|
{
|
||||||
|
Pout<< "OFstreamCollator : Starting write thread" << endl;
|
||||||
|
}
|
||||||
|
thread_.reset(new std::thread(writeAll, this));
|
||||||
|
threadRunning_ = true;
|
||||||
}
|
}
|
||||||
threadRunning_ = true;
|
|
||||||
}
|
}
|
||||||
unlockMutex(mutex_);
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
========= |
|
========= |
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
\\ / O peration |
|
\\ / O peration |
|
||||||
\\ / A nd | Copyright (C) 2017 OpenFOAM Foundation
|
\\ / A nd | Copyright (C) 2017-2018 OpenFOAM Foundation
|
||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
@ -51,9 +51,12 @@ SourceFiles
|
|||||||
#ifndef OFstreamCollator_H
|
#ifndef OFstreamCollator_H
|
||||||
#define OFstreamCollator_H
|
#define OFstreamCollator_H
|
||||||
|
|
||||||
|
#include <thread>
|
||||||
|
#include <mutex>
|
||||||
#include "IOstream.H"
|
#include "IOstream.H"
|
||||||
#include "labelList.H"
|
#include "labelList.H"
|
||||||
#include "FIFOStack.H"
|
#include "FIFOStack.H"
|
||||||
|
#include "SubList.H"
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
@ -77,10 +80,7 @@ class OFstreamCollator
|
|||||||
const fileName pathName_;
|
const fileName pathName_;
|
||||||
const string data_;
|
const string data_;
|
||||||
const labelList sizes_;
|
const labelList sizes_;
|
||||||
|
PtrList<List<char>> slaveData_;
|
||||||
const bool haveSlaveData_;
|
|
||||||
List<char> slaveData_;
|
|
||||||
|
|
||||||
const IOstream::streamFormat format_;
|
const IOstream::streamFormat format_;
|
||||||
const IOstream::versionNumber version_;
|
const IOstream::versionNumber version_;
|
||||||
const IOstream::compressionType compression_;
|
const IOstream::compressionType compression_;
|
||||||
@ -93,7 +93,6 @@ class OFstreamCollator
|
|||||||
const fileName& pathName,
|
const fileName& pathName,
|
||||||
const string& data,
|
const string& data,
|
||||||
const labelList& sizes,
|
const labelList& sizes,
|
||||||
const bool haveSlaveData,
|
|
||||||
IOstream::streamFormat format,
|
IOstream::streamFormat format,
|
||||||
IOstream::versionNumber version,
|
IOstream::versionNumber version,
|
||||||
IOstream::compressionType compression,
|
IOstream::compressionType compression,
|
||||||
@ -105,7 +104,6 @@ class OFstreamCollator
|
|||||||
pathName_(pathName),
|
pathName_(pathName),
|
||||||
data_(data),
|
data_(data),
|
||||||
sizes_(sizes),
|
sizes_(sizes),
|
||||||
haveSlaveData_(haveSlaveData),
|
|
||||||
slaveData_(0),
|
slaveData_(0),
|
||||||
format_(format),
|
format_(format),
|
||||||
version_(version),
|
version_(version),
|
||||||
@ -116,27 +114,39 @@ class OFstreamCollator
|
|||||||
//- (approximate) size of master + any optional slave data
|
//- (approximate) size of master + any optional slave data
|
||||||
off_t size() const
|
off_t size() const
|
||||||
{
|
{
|
||||||
return data_.size() + slaveData_.size();
|
off_t sz = data_.size();
|
||||||
|
forAll(slaveData_, i)
|
||||||
|
{
|
||||||
|
if (slaveData_.set(i))
|
||||||
|
{
|
||||||
|
sz += slaveData_[i].size();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return sz;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// Private data
|
// Private data
|
||||||
|
|
||||||
|
//- Total amount of storage to use for object stack below
|
||||||
const off_t maxBufferSize_;
|
const off_t maxBufferSize_;
|
||||||
|
|
||||||
//pthread_mutex_t mutex_;
|
mutable std::mutex mutex_;
|
||||||
label mutex_;
|
|
||||||
|
|
||||||
//pthread_t thread_;
|
autoPtr<std::thread> thread_;
|
||||||
label thread_;
|
|
||||||
|
|
||||||
|
//- Stack of files to write + contents
|
||||||
FIFOStack<writeData*> objects_;
|
FIFOStack<writeData*> objects_;
|
||||||
|
|
||||||
|
//- Whether thread is running (and not exited)
|
||||||
bool threadRunning_;
|
bool threadRunning_;
|
||||||
|
|
||||||
//- Communicator to use for all parallel ops
|
//- Communicator to use for all parallel ops (in simulation thread)
|
||||||
label comm_;
|
label localComm_;
|
||||||
|
|
||||||
|
//- Communicator to use for all parallel ops (in write thread)
|
||||||
|
label threadComm_;
|
||||||
|
|
||||||
|
|
||||||
// Private Member Functions
|
// Private Member Functions
|
||||||
@ -149,8 +159,7 @@ class OFstreamCollator
|
|||||||
const fileName& fName,
|
const fileName& fName,
|
||||||
const string& masterData,
|
const string& masterData,
|
||||||
const labelUList& recvSizes,
|
const labelUList& recvSizes,
|
||||||
const bool haveSlaveData, // (does master) have slave data
|
const PtrList<SubList<char>>& slaveData,
|
||||||
const UList<char>& slaveData, // (on master) all slave data
|
|
||||||
IOstream::streamFormat fmt,
|
IOstream::streamFormat fmt,
|
||||||
IOstream::versionNumber ver,
|
IOstream::versionNumber ver,
|
||||||
IOstream::compressionType cmp,
|
IOstream::compressionType cmp,
|
||||||
@ -176,6 +185,10 @@ public:
|
|||||||
//- Construct from buffer size. 0 = do not use thread
|
//- Construct from buffer size. 0 = do not use thread
|
||||||
OFstreamCollator(const off_t maxBufferSize);
|
OFstreamCollator(const off_t maxBufferSize);
|
||||||
|
|
||||||
|
//- Construct from buffer size (0 = do not use thread) and local
|
||||||
|
// thread
|
||||||
|
OFstreamCollator(const off_t maxBufferSize, const label comm);
|
||||||
|
|
||||||
|
|
||||||
//- Destructor
|
//- Destructor
|
||||||
virtual ~OFstreamCollator();
|
virtual ~OFstreamCollator();
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
========= |
|
========= |
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
\\ / O peration |
|
\\ / O peration |
|
||||||
\\ / A nd | Copyright (C) 2017 OpenFOAM Foundation
|
\\ / A nd | Copyright (C) 2017-2018 OpenFOAM Foundation
|
||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
@ -57,12 +57,63 @@ namespace fileOperations
|
|||||||
float,
|
float,
|
||||||
collatedFileOperation::maxThreadFileBufferSize
|
collatedFileOperation::maxThreadFileBufferSize
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Mark as needing threaded mpi
|
||||||
|
addNamedToRunTimeSelectionTable
|
||||||
|
(
|
||||||
|
fileOperationInitialise,
|
||||||
|
collatedFileOperationInitialise,
|
||||||
|
word,
|
||||||
|
collated
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Foam::labelList Foam::fileOperations::collatedFileOperation::ioRanks()
|
||||||
|
{
|
||||||
|
labelList ioRanks;
|
||||||
|
|
||||||
|
string ioRanksString(getEnv("FOAM_IORANKS"));
|
||||||
|
if (!ioRanksString.empty())
|
||||||
|
{
|
||||||
|
IStringStream is(ioRanksString);
|
||||||
|
is >> ioRanks;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ioRanks;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Foam::fileOperations::collatedFileOperation::isMasterRank
|
||||||
|
(
|
||||||
|
const label proci
|
||||||
|
)
|
||||||
|
const
|
||||||
|
{
|
||||||
|
if (Pstream::parRun())
|
||||||
|
{
|
||||||
|
return Pstream::master(comm_);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Use any IO ranks
|
||||||
|
if (ioRanks_.size())
|
||||||
|
{
|
||||||
|
// Find myself in IO rank
|
||||||
|
return findIndex(ioRanks_, proci) != -1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Assume all in single communicator
|
||||||
|
return proci == 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool Foam::fileOperations::collatedFileOperation::appendObject
|
bool Foam::fileOperations::collatedFileOperation::appendObject
|
||||||
(
|
(
|
||||||
const regIOobject& io,
|
const regIOobject& io,
|
||||||
@ -74,14 +125,12 @@ bool Foam::fileOperations::collatedFileOperation::appendObject
|
|||||||
{
|
{
|
||||||
// Append to processors/ file
|
// Append to processors/ file
|
||||||
|
|
||||||
fileName prefix;
|
label proci = detectProcessorPath(io.objectPath());
|
||||||
fileName postfix;
|
|
||||||
label proci = splitProcessorPath(io.objectPath(), prefix, postfix);
|
|
||||||
|
|
||||||
if (debug)
|
if (debug)
|
||||||
{
|
{
|
||||||
Pout<< "writeObject:" << " : For local object : "
|
Pout<< "collatedFileOperation::writeObject :"
|
||||||
<< io.name()
|
<< " For local object : " << io.name()
|
||||||
<< " appending processor " << proci
|
<< " appending processor " << proci
|
||||||
<< " data to " << pathName << endl;
|
<< " data to " << pathName << endl;
|
||||||
}
|
}
|
||||||
@ -93,12 +142,35 @@ bool Foam::fileOperations::collatedFileOperation::appendObject
|
|||||||
<< exit(FatalError);
|
<< exit(FatalError);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const bool isMaster = isMasterRank(proci);
|
||||||
|
|
||||||
|
// Determine the local rank if the pathName is a per-rank one
|
||||||
|
label localProci = proci;
|
||||||
|
{
|
||||||
|
fileName path, procDir, local;
|
||||||
|
label groupStart, groupSize, nProcs;
|
||||||
|
splitProcessorPath
|
||||||
|
(
|
||||||
|
pathName,
|
||||||
|
path,
|
||||||
|
procDir,
|
||||||
|
local,
|
||||||
|
groupStart,
|
||||||
|
groupSize,
|
||||||
|
nProcs
|
||||||
|
);
|
||||||
|
if (groupSize > 0 && groupStart != -1)
|
||||||
|
{
|
||||||
|
localProci = proci-groupStart;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Create string from all data to write
|
// Create string from all data to write
|
||||||
string buf;
|
string buf;
|
||||||
{
|
{
|
||||||
OStringStream os(fmt, ver);
|
OStringStream os(fmt, ver);
|
||||||
if (proci == 0)
|
if (isMaster)
|
||||||
{
|
{
|
||||||
if (!io.writeHeader(os))
|
if (!io.writeHeader(os))
|
||||||
{
|
{
|
||||||
@ -112,7 +184,7 @@ bool Foam::fileOperations::collatedFileOperation::appendObject
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (proci == 0)
|
if (isMaster)
|
||||||
{
|
{
|
||||||
IOobject::writeEndDivider(os);
|
IOobject::writeEndDivider(os);
|
||||||
}
|
}
|
||||||
@ -121,8 +193,6 @@ bool Foam::fileOperations::collatedFileOperation::appendObject
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool append = (proci > 0);
|
|
||||||
|
|
||||||
// Note: cannot do append + compression. This is a limitation
|
// Note: cannot do append + compression. This is a limitation
|
||||||
// of ogzstream (or rather most compressed formats)
|
// of ogzstream (or rather most compressed formats)
|
||||||
|
|
||||||
@ -132,7 +202,7 @@ bool Foam::fileOperations::collatedFileOperation::appendObject
|
|||||||
IOstream::BINARY,
|
IOstream::BINARY,
|
||||||
ver,
|
ver,
|
||||||
IOstream::UNCOMPRESSED, // no compression
|
IOstream::UNCOMPRESSED, // no compression
|
||||||
append
|
!isMaster
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!os.good())
|
if (!os.good())
|
||||||
@ -142,7 +212,7 @@ bool Foam::fileOperations::collatedFileOperation::appendObject
|
|||||||
<< exit(FatalIOError);
|
<< exit(FatalIOError);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (proci == 0)
|
if (isMaster)
|
||||||
{
|
{
|
||||||
IOobject::writeBanner(os)
|
IOobject::writeBanner(os)
|
||||||
<< "FoamFile\n{\n"
|
<< "FoamFile\n{\n"
|
||||||
@ -162,7 +232,7 @@ bool Foam::fileOperations::collatedFileOperation::appendObject
|
|||||||
const_cast<char*>(buf.data()),
|
const_cast<char*>(buf.data()),
|
||||||
label(buf.size())
|
label(buf.size())
|
||||||
);
|
);
|
||||||
os << nl << "// Processor" << proci << nl << slice << nl;
|
os << nl << "// Processor" << localProci << nl << slice << nl;
|
||||||
|
|
||||||
return os.good();
|
return os.good();
|
||||||
}
|
}
|
||||||
@ -175,8 +245,23 @@ Foam::fileOperations::collatedFileOperation::collatedFileOperation
|
|||||||
const bool verbose
|
const bool verbose
|
||||||
)
|
)
|
||||||
:
|
:
|
||||||
masterUncollatedFileOperation(false),
|
masterUncollatedFileOperation
|
||||||
writer_(maxThreadFileBufferSize)
|
(
|
||||||
|
(
|
||||||
|
ioRanks().size()
|
||||||
|
? UPstream::allocateCommunicator
|
||||||
|
(
|
||||||
|
UPstream::worldComm,
|
||||||
|
subRanks(Pstream::nProcs())
|
||||||
|
)
|
||||||
|
: UPstream::worldComm
|
||||||
|
),
|
||||||
|
false
|
||||||
|
),
|
||||||
|
myComm_(comm_),
|
||||||
|
writer_(maxThreadFileBufferSize, comm_),
|
||||||
|
nProcs_(Pstream::nProcs()),
|
||||||
|
ioRanks_(ioRanks())
|
||||||
{
|
{
|
||||||
if (verbose)
|
if (verbose)
|
||||||
{
|
{
|
||||||
@ -195,12 +280,97 @@ Foam::fileOperations::collatedFileOperation::collatedFileOperation
|
|||||||
{
|
{
|
||||||
Info<< " Threading activated "
|
Info<< " Threading activated "
|
||||||
"since maxThreadFileBufferSize > 0." << nl
|
"since maxThreadFileBufferSize > 0." << nl
|
||||||
<< " Requires thread support enabled in MPI, "
|
<< " Requires large enough buffer to collect all data"
|
||||||
"otherwise the simulation" << nl
|
" or thread support " << nl
|
||||||
<< " may \"hang\". If thread support cannot be "
|
<< " enabled in MPI. If thread support cannot be "
|
||||||
"enabled, deactivate threading" << nl
|
"enabled, deactivate" << nl
|
||||||
<< " by setting maxThreadFileBufferSize to 0 in "
|
<< " threading by setting maxThreadFileBufferSize "
|
||||||
"the OpenFOAM etc/controlDict"
|
"to 0 in" << nl
|
||||||
|
<< " $FOAM_ETC/controlDict"
|
||||||
|
<< endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ioRanks_.size())
|
||||||
|
{
|
||||||
|
// Print a bit of information
|
||||||
|
stringList ioRanks(Pstream::nProcs());
|
||||||
|
if (Pstream::master(comm_))
|
||||||
|
{
|
||||||
|
ioRanks[Pstream::myProcNo()] = hostName()+"."+name(pid());
|
||||||
|
}
|
||||||
|
Pstream::gatherList(ioRanks);
|
||||||
|
|
||||||
|
Info<< " IO nodes:" << endl;
|
||||||
|
forAll(ioRanks, proci)
|
||||||
|
{
|
||||||
|
if (!ioRanks[proci].empty())
|
||||||
|
{
|
||||||
|
Info<< " " << ioRanks[proci] << endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if
|
||||||
|
(
|
||||||
|
regIOobject::fileModificationChecking
|
||||||
|
== regIOobject::inotifyMaster
|
||||||
|
)
|
||||||
|
{
|
||||||
|
WarningInFunction
|
||||||
|
<< "Resetting fileModificationChecking to inotify" << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
if
|
||||||
|
(
|
||||||
|
regIOobject::fileModificationChecking
|
||||||
|
== regIOobject::timeStampMaster
|
||||||
|
)
|
||||||
|
{
|
||||||
|
WarningInFunction
|
||||||
|
<< "Resetting fileModificationChecking to timeStamp" << endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::fileOperations::collatedFileOperation::collatedFileOperation
|
||||||
|
(
|
||||||
|
const label comm,
|
||||||
|
const labelList& ioRanks,
|
||||||
|
const word& typeName,
|
||||||
|
const bool verbose
|
||||||
|
)
|
||||||
|
:
|
||||||
|
masterUncollatedFileOperation(comm, false),
|
||||||
|
myComm_(-1),
|
||||||
|
writer_(maxThreadFileBufferSize, comm),
|
||||||
|
nProcs_(Pstream::nProcs()),
|
||||||
|
ioRanks_(ioRanks)
|
||||||
|
{
|
||||||
|
if (verbose)
|
||||||
|
{
|
||||||
|
Info<< "I/O : " << typeName
|
||||||
|
<< " (maxThreadFileBufferSize " << maxThreadFileBufferSize
|
||||||
|
<< ')' << endl;
|
||||||
|
|
||||||
|
if (maxThreadFileBufferSize == 0)
|
||||||
|
{
|
||||||
|
Info<< " Threading not activated "
|
||||||
|
"since maxThreadFileBufferSize = 0." << nl
|
||||||
|
<< " Writing may run slowly for large file sizes."
|
||||||
|
<< endl;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Info<< " Threading activated "
|
||||||
|
"since maxThreadFileBufferSize > 0." << nl
|
||||||
|
<< " Requires large enough buffer to collect all data"
|
||||||
|
" or thread support " << nl
|
||||||
|
<< " enabled in MPI. If thread support cannot be "
|
||||||
|
"enabled, deactivate" << nl
|
||||||
|
<< " threading by setting maxThreadFileBufferSize "
|
||||||
|
"to 0 in the OpenFOAM etc/controlDict" << nl
|
||||||
<< endl;
|
<< endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -227,6 +397,17 @@ Foam::fileOperations::collatedFileOperation::collatedFileOperation
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Foam::fileOperations::collatedFileOperation::~collatedFileOperation()
|
||||||
|
{
|
||||||
|
if (myComm_ != -1 && myComm_ != UPstream::worldComm)
|
||||||
|
{
|
||||||
|
UPstream::freeCommunicator(myComm_);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||||
|
|
||||||
Foam::fileName Foam::fileOperations::collatedFileOperation::objectPath
|
Foam::fileName Foam::fileOperations::collatedFileOperation::objectPath
|
||||||
@ -238,19 +419,21 @@ Foam::fileName Foam::fileOperations::collatedFileOperation::objectPath
|
|||||||
// Replacement for objectPath
|
// Replacement for objectPath
|
||||||
if (io.time().processorCase())
|
if (io.time().processorCase())
|
||||||
{
|
{
|
||||||
return masterUncollatedFileOperation::objectPath
|
return masterUncollatedFileOperation::localObjectPath
|
||||||
(
|
(
|
||||||
io,
|
io,
|
||||||
fileOperation::PROCESSORSOBJECT,
|
fileOperation::PROCOBJECT,
|
||||||
|
"dummy", // not used for processorsobject
|
||||||
io.instance()
|
io.instance()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return masterUncollatedFileOperation::objectPath
|
return masterUncollatedFileOperation::localObjectPath
|
||||||
(
|
(
|
||||||
io,
|
io,
|
||||||
fileOperation::OBJECT,
|
fileOperation::OBJECT,
|
||||||
|
word::null,
|
||||||
io.instance()
|
io.instance()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -276,8 +459,8 @@ bool Foam::fileOperations::collatedFileOperation::writeObject
|
|||||||
|
|
||||||
if (debug)
|
if (debug)
|
||||||
{
|
{
|
||||||
Pout<< "writeObject:"
|
Pout<< "collatedFileOperation::writeObject :"
|
||||||
<< " : For object : " << io.name()
|
<< " For object : " << io.name()
|
||||||
<< " falling back to master-only output to " << io.path()
|
<< " falling back to master-only output to " << io.path()
|
||||||
<< endl;
|
<< endl;
|
||||||
}
|
}
|
||||||
@ -313,7 +496,7 @@ bool Foam::fileOperations::collatedFileOperation::writeObject
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Construct the equivalent processors/ directory
|
// Construct the equivalent processors/ directory
|
||||||
fileName path(processorsPath(io, inst));
|
fileName path(processorsPath(io, inst, processorsDir(io)));
|
||||||
|
|
||||||
mkDir(path);
|
mkDir(path);
|
||||||
fileName pathName(path/io.name());
|
fileName pathName(path/io.name());
|
||||||
@ -322,7 +505,8 @@ bool Foam::fileOperations::collatedFileOperation::writeObject
|
|||||||
{
|
{
|
||||||
if (debug)
|
if (debug)
|
||||||
{
|
{
|
||||||
Pout<< "writeObject:" << " : For global object : " << io.name()
|
Pout<< "collatedFileOperation::writeObject :"
|
||||||
|
<< " For global object : " << io.name()
|
||||||
<< " falling back to master-only output to " << pathName
|
<< " falling back to master-only output to " << pathName
|
||||||
<< endl;
|
<< endl;
|
||||||
}
|
}
|
||||||
@ -359,11 +543,11 @@ bool Foam::fileOperations::collatedFileOperation::writeObject
|
|||||||
else if (!Pstream::parRun())
|
else if (!Pstream::parRun())
|
||||||
{
|
{
|
||||||
// Special path for e.g. decomposePar. Append to
|
// Special path for e.g. decomposePar. Append to
|
||||||
// processors/ file
|
// processorsDDD/ file
|
||||||
if (debug)
|
if (debug)
|
||||||
{
|
{
|
||||||
Pout<< "writeObject:"
|
Pout<< "collatedFileOperation::writeObject :"
|
||||||
<< " : For object : " << io.name()
|
<< " For object : " << io.name()
|
||||||
<< " appending to " << pathName << endl;
|
<< " appending to " << pathName << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -373,8 +557,8 @@ bool Foam::fileOperations::collatedFileOperation::writeObject
|
|||||||
{
|
{
|
||||||
if (debug)
|
if (debug)
|
||||||
{
|
{
|
||||||
Pout<< "writeObject:"
|
Pout<< "collatedFileOperation::writeObject :"
|
||||||
<< " : For object : " << io.name()
|
<< " For object : " << io.name()
|
||||||
<< " starting collating output to " << pathName << endl;
|
<< " starting collating output to " << pathName << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -386,7 +570,7 @@ bool Foam::fileOperations::collatedFileOperation::writeObject
|
|||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (Pstream::master() && !io.writeHeader(os))
|
if (Pstream::master(comm_) && !io.writeHeader(os))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -395,7 +579,7 @@ bool Foam::fileOperations::collatedFileOperation::writeObject
|
|||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (Pstream::master())
|
if (Pstream::master(comm_))
|
||||||
{
|
{
|
||||||
IOobject::writeEndDivider(os);
|
IOobject::writeEndDivider(os);
|
||||||
}
|
}
|
||||||
@ -406,4 +590,89 @@ bool Foam::fileOperations::collatedFileOperation::writeObject
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::word Foam::fileOperations::collatedFileOperation::processorsDir
|
||||||
|
(
|
||||||
|
const fileName& fName
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
if (Pstream::parRun())
|
||||||
|
{
|
||||||
|
const List<int>& procs(UPstream::procID(comm_));
|
||||||
|
|
||||||
|
word procDir(processorsBaseDir+Foam::name(Pstream::nProcs()));
|
||||||
|
|
||||||
|
if (procs.size() != Pstream::nProcs())
|
||||||
|
{
|
||||||
|
procDir +=
|
||||||
|
+ "_"
|
||||||
|
+ Foam::name(procs[0])
|
||||||
|
+ "-"
|
||||||
|
+ Foam::name(procs.last());
|
||||||
|
}
|
||||||
|
return procDir;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
word procDir(processorsBaseDir+Foam::name(nProcs_));
|
||||||
|
|
||||||
|
if (ioRanks_.size())
|
||||||
|
{
|
||||||
|
// Detect current processor number
|
||||||
|
label proci = detectProcessorPath(fName);
|
||||||
|
|
||||||
|
if (proci != -1)
|
||||||
|
{
|
||||||
|
// Find lowest io rank
|
||||||
|
label minProc = 0;
|
||||||
|
label maxProc = nProcs_-1;
|
||||||
|
forAll(ioRanks_, i)
|
||||||
|
{
|
||||||
|
if (ioRanks_[i] >= nProcs_)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else if (ioRanks_[i] <= proci)
|
||||||
|
{
|
||||||
|
minProc = ioRanks_[i];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
maxProc = ioRanks_[i]-1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
procDir +=
|
||||||
|
+ "_"
|
||||||
|
+ Foam::name(minProc)
|
||||||
|
+ "-"
|
||||||
|
+ Foam::name(maxProc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return procDir;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::word Foam::fileOperations::collatedFileOperation::processorsDir
|
||||||
|
(
|
||||||
|
const IOobject& io
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
return processorsDir(io.objectPath());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::fileOperations::collatedFileOperation::setNProcs(const label nProcs)
|
||||||
|
{
|
||||||
|
nProcs_ = nProcs;
|
||||||
|
|
||||||
|
if (debug)
|
||||||
|
{
|
||||||
|
Pout<< "collatedFileOperation::setNProcs :"
|
||||||
|
<< " Setting number of processors to " << nProcs_ << endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
// ************************************************************************* //
|
||||||
|
|||||||
@ -43,6 +43,7 @@ SourceFiles
|
|||||||
|
|
||||||
#include "masterUncollatedFileOperation.H"
|
#include "masterUncollatedFileOperation.H"
|
||||||
#include "OFstreamCollator.H"
|
#include "OFstreamCollator.H"
|
||||||
|
#include "fileOperationInitialise.H"
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
@ -59,14 +60,33 @@ class collatedFileOperation
|
|||||||
:
|
:
|
||||||
public masterUncollatedFileOperation
|
public masterUncollatedFileOperation
|
||||||
{
|
{
|
||||||
// Private data
|
protected:
|
||||||
|
|
||||||
|
// Protected data
|
||||||
|
|
||||||
|
//- Any communicator allocated by me
|
||||||
|
const label myComm_;
|
||||||
|
|
||||||
//- Threaded writer
|
//- Threaded writer
|
||||||
mutable OFstreamCollator writer_;
|
mutable OFstreamCollator writer_;
|
||||||
|
|
||||||
|
// For non-parallel operation
|
||||||
|
|
||||||
|
//- Number of processors (overall)
|
||||||
|
label nProcs_;
|
||||||
|
|
||||||
|
//- Ranks of IO handlers
|
||||||
|
const labelList ioRanks_;
|
||||||
|
|
||||||
|
|
||||||
// Private Member Functions
|
// Private Member Functions
|
||||||
|
|
||||||
|
static labelList ioRanks();
|
||||||
|
|
||||||
|
//- Is proci master of communicator (in parallel) or master of
|
||||||
|
// the io ranks (non-parallel)
|
||||||
|
bool isMasterRank(const label proci) const;
|
||||||
|
|
||||||
//- Append to processors/ file
|
//- Append to processors/ file
|
||||||
bool appendObject
|
bool appendObject
|
||||||
(
|
(
|
||||||
@ -97,9 +117,18 @@ public:
|
|||||||
//- Construct null
|
//- Construct null
|
||||||
collatedFileOperation(const bool verbose);
|
collatedFileOperation(const bool verbose);
|
||||||
|
|
||||||
|
//- Construct from user communicator
|
||||||
|
collatedFileOperation
|
||||||
|
(
|
||||||
|
const label comm,
|
||||||
|
const labelList& ioRanks,
|
||||||
|
const word& typeName,
|
||||||
|
const bool verbose
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
//- Destructor
|
//- Destructor
|
||||||
virtual ~collatedFileOperation() = default;
|
virtual ~collatedFileOperation();
|
||||||
|
|
||||||
|
|
||||||
// Member Functions
|
// Member Functions
|
||||||
@ -123,6 +152,54 @@ public:
|
|||||||
IOstream::compressionType compression=IOstream::UNCOMPRESSED,
|
IOstream::compressionType compression=IOstream::UNCOMPRESSED,
|
||||||
const bool valid = true
|
const bool valid = true
|
||||||
) const;
|
) const;
|
||||||
|
|
||||||
|
// Other
|
||||||
|
|
||||||
|
//- Actual name of processors dir
|
||||||
|
virtual word processorsDir(const IOobject&) const;
|
||||||
|
|
||||||
|
//- Actual name of processors dir
|
||||||
|
virtual word processorsDir(const fileName&) const;
|
||||||
|
|
||||||
|
//- Set number of processor directories/results. Only used in
|
||||||
|
// decomposePar
|
||||||
|
virtual void setNProcs(const label nProcs);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
Class collatedFileOperationInitialise Declaration
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
class collatedFileOperationInitialise
|
||||||
|
:
|
||||||
|
public masterUncollatedFileOperationInitialise
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
// Constructors
|
||||||
|
|
||||||
|
//- Construct from components
|
||||||
|
collatedFileOperationInitialise(int& argc, char**& argv)
|
||||||
|
:
|
||||||
|
masterUncollatedFileOperationInitialise(argc, argv)
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
//- Destructor
|
||||||
|
virtual ~collatedFileOperationInitialise()
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
// Member Functions
|
||||||
|
|
||||||
|
//- Needs threading
|
||||||
|
virtual bool needsThreading() const
|
||||||
|
{
|
||||||
|
return
|
||||||
|
collatedFileOperation::maxThreadFileBufferSize
|
||||||
|
> 0;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -0,0 +1,176 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | Copyright (C) 2017-2018 OpenFOAM Foundation
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
License
|
||||||
|
This file is part of OpenFOAM.
|
||||||
|
|
||||||
|
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#include "hostCollatedFileOperation.H"
|
||||||
|
#include "addToRunTimeSelectionTable.H"
|
||||||
|
#include "bitSet.H"
|
||||||
|
|
||||||
|
/* * * * * * * * * * * * * * * Static Member Data * * * * * * * * * * * * * */
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
namespace fileOperations
|
||||||
|
{
|
||||||
|
defineTypeNameAndDebug(hostCollatedFileOperation, 0);
|
||||||
|
addToRunTimeSelectionTable
|
||||||
|
(
|
||||||
|
fileOperation,
|
||||||
|
hostCollatedFileOperation,
|
||||||
|
word
|
||||||
|
);
|
||||||
|
|
||||||
|
// Register initialisation routine. Signals need for threaded mpi and
|
||||||
|
// handles command line arguments
|
||||||
|
addNamedToRunTimeSelectionTable
|
||||||
|
(
|
||||||
|
fileOperationInitialise,
|
||||||
|
hostCollatedFileOperationInitialise,
|
||||||
|
word,
|
||||||
|
hostCollated
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Foam::labelList Foam::fileOperations::hostCollatedFileOperation::subRanks
|
||||||
|
(
|
||||||
|
const label n
|
||||||
|
)
|
||||||
|
{
|
||||||
|
DynamicList<label> subRanks(64);
|
||||||
|
|
||||||
|
string ioRanksString(getEnv("FOAM_IORANKS"));
|
||||||
|
if (!ioRanksString.empty())
|
||||||
|
{
|
||||||
|
IStringStream is(ioRanksString);
|
||||||
|
labelList ioRanks(is);
|
||||||
|
|
||||||
|
if (findIndex(ioRanks, 0) == -1)
|
||||||
|
{
|
||||||
|
FatalErrorInFunction
|
||||||
|
<< "Rank 0 (master) should be in the IO ranks. Currently "
|
||||||
|
<< ioRanks << exit(FatalError);
|
||||||
|
}
|
||||||
|
|
||||||
|
// The lowest numbered rank is the IO rank
|
||||||
|
const bitSet isIOrank(n, ioRanks);
|
||||||
|
|
||||||
|
for (label proci = Pstream::myProcNo(); proci >= 0; --proci)
|
||||||
|
{
|
||||||
|
if (isIOrank[proci])
|
||||||
|
{
|
||||||
|
// Found my master. Collect all processors with same master
|
||||||
|
subRanks.append(proci);
|
||||||
|
for
|
||||||
|
(
|
||||||
|
label rank = proci+1;
|
||||||
|
rank < n && !isIOrank[rank];
|
||||||
|
++rank
|
||||||
|
)
|
||||||
|
{
|
||||||
|
subRanks.append(rank);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Normal operation: one lowest rank per hostname is the writer
|
||||||
|
const string myHostName(hostName());
|
||||||
|
|
||||||
|
stringList hosts(Pstream::nProcs());
|
||||||
|
hosts[Pstream::myProcNo()] = myHostName;
|
||||||
|
Pstream::gatherList(hosts);
|
||||||
|
Pstream::scatterList(hosts);
|
||||||
|
|
||||||
|
// Collect procs with same hostname
|
||||||
|
forAll(hosts, proci)
|
||||||
|
{
|
||||||
|
if (hosts[proci] == myHostName)
|
||||||
|
{
|
||||||
|
subRanks.append(proci);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return subRanks;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Foam::fileOperations::hostCollatedFileOperation::hostCollatedFileOperation
|
||||||
|
(
|
||||||
|
const bool verbose
|
||||||
|
)
|
||||||
|
:
|
||||||
|
collatedFileOperation
|
||||||
|
(
|
||||||
|
UPstream::allocateCommunicator
|
||||||
|
(
|
||||||
|
UPstream::worldComm,
|
||||||
|
subRanks(Pstream::nProcs())
|
||||||
|
),
|
||||||
|
(Pstream::parRun() ? labelList(0) : ioRanks()), // processor dirs
|
||||||
|
typeName,
|
||||||
|
verbose
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (verbose)
|
||||||
|
{
|
||||||
|
// Print a bit of information
|
||||||
|
stringList ioRanks(Pstream::nProcs());
|
||||||
|
if (Pstream::master(comm_))
|
||||||
|
{
|
||||||
|
ioRanks[Pstream::myProcNo()] = hostName()+"."+name(pid());
|
||||||
|
}
|
||||||
|
Pstream::gatherList(ioRanks);
|
||||||
|
|
||||||
|
Info<< " IO nodes:" << endl;
|
||||||
|
forAll(ioRanks, proci)
|
||||||
|
{
|
||||||
|
if (!ioRanks[proci].empty())
|
||||||
|
{
|
||||||
|
Info<< " " << ioRanks[proci] << endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Foam::fileOperations::hostCollatedFileOperation::~hostCollatedFileOperation()
|
||||||
|
{
|
||||||
|
if (comm_ != -1 && comm_ != UPstream::worldComm)
|
||||||
|
{
|
||||||
|
UPstream::freeCommunicator(comm_);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -0,0 +1,134 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | Copyright (C) 2017-2018 OpenFOAM Foundation
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
License
|
||||||
|
This file is part of OpenFOAM.
|
||||||
|
|
||||||
|
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
Class
|
||||||
|
Foam::fileOperations::hostCollatedFileOperation
|
||||||
|
|
||||||
|
Description
|
||||||
|
Version of collatedFileOperation with multiple read/write ranks.
|
||||||
|
|
||||||
|
In parallel it will assume ranks are sorted according to hostname
|
||||||
|
and the lowest rank per hostname will be the IO rank. The output directories
|
||||||
|
will get a unique name processors<N>_<low>-<high> where N is the overall
|
||||||
|
number of processors and low and high is the range of ranks contained
|
||||||
|
in the files. Each of these subsets uses its own communicator.
|
||||||
|
|
||||||
|
Instead of using the hostnames the IO ranks can be assigned using the
|
||||||
|
FOAM_IORANKS environment variable (also when running non-parallel), e.g.
|
||||||
|
when decomposing into 4:
|
||||||
|
|
||||||
|
FOAM_IORANKS='(0 2)' decomposePar -fileHandler hostCollated
|
||||||
|
|
||||||
|
will generate
|
||||||
|
|
||||||
|
processors4_0-1/
|
||||||
|
containing data for processors 0 to 1
|
||||||
|
processors4_2-3/
|
||||||
|
containing data for processors 2 to 3
|
||||||
|
|
||||||
|
See also
|
||||||
|
collatedFileOperation
|
||||||
|
|
||||||
|
SourceFiles
|
||||||
|
hostCollatedFileOperation.C
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef fileOperations_hostCollatedFileOperation_H
|
||||||
|
#define fileOperations_hostCollatedFileOperation_H
|
||||||
|
|
||||||
|
#include "collatedFileOperation.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
namespace fileOperations
|
||||||
|
{
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
Class hostCollatedFileOperation Declaration
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
class hostCollatedFileOperation
|
||||||
|
:
|
||||||
|
public collatedFileOperation
|
||||||
|
{
|
||||||
|
// Private Member Functions
|
||||||
|
|
||||||
|
//- Get the list of processors part of this set
|
||||||
|
static labelList subRanks(const label n);
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
//- Runtime type information
|
||||||
|
TypeName("hostCollated");
|
||||||
|
|
||||||
|
|
||||||
|
// Constructors
|
||||||
|
|
||||||
|
//- Construct null
|
||||||
|
hostCollatedFileOperation(const bool verbose);
|
||||||
|
|
||||||
|
|
||||||
|
//- Destructor
|
||||||
|
virtual ~hostCollatedFileOperation();
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
Class hostCollatedFileOperationInitialise Declaration
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
class hostCollatedFileOperationInitialise
|
||||||
|
:
|
||||||
|
public collatedFileOperationInitialise
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
// Constructors
|
||||||
|
|
||||||
|
//- Construct from components
|
||||||
|
hostCollatedFileOperationInitialise(int& argc, char**& argv)
|
||||||
|
:
|
||||||
|
collatedFileOperationInitialise(argc, argv)
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
//- Destructor
|
||||||
|
virtual ~hostCollatedFileOperationInitialise()
|
||||||
|
{}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
} // End namespace fileOperations
|
||||||
|
} // End namespace Foam
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -2,7 +2,7 @@
|
|||||||
========= |
|
========= |
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
\\ / O peration |
|
\\ / O peration |
|
||||||
\\ / A nd | Copyright (C) 2017 OpenFOAM Foundation
|
\\ / A nd | Copyright (C) 2017-2018 OpenFOAM Foundation
|
||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
@ -28,11 +28,11 @@ License
|
|||||||
#include "regIOobject.H"
|
#include "regIOobject.H"
|
||||||
#include "argList.H"
|
#include "argList.H"
|
||||||
#include "HashSet.H"
|
#include "HashSet.H"
|
||||||
#include "masterUncollatedFileOperation.H"
|
|
||||||
#include "objectRegistry.H"
|
#include "objectRegistry.H"
|
||||||
#include "decomposedBlockData.H"
|
#include "decomposedBlockData.H"
|
||||||
#include "polyMesh.H"
|
#include "polyMesh.H"
|
||||||
#include "registerSwitch.H"
|
#include "registerSwitch.H"
|
||||||
|
#include "Time.H"
|
||||||
|
|
||||||
/* * * * * * * * * * * * * * * Static Member Data * * * * * * * * * * * * * */
|
/* * * * * * * * * * * * * * * Static Member Data * * * * * * * * * * * * * */
|
||||||
|
|
||||||
@ -43,6 +43,28 @@ namespace Foam
|
|||||||
defineTypeNameAndDebug(fileOperation, 0);
|
defineTypeNameAndDebug(fileOperation, 0);
|
||||||
defineRunTimeSelectionTable(fileOperation, word);
|
defineRunTimeSelectionTable(fileOperation, word);
|
||||||
|
|
||||||
|
template<>
|
||||||
|
const char* Foam::NamedEnum
|
||||||
|
<
|
||||||
|
fileOperation::pathType,
|
||||||
|
12
|
||||||
|
>::names[] =
|
||||||
|
{
|
||||||
|
"notFound",
|
||||||
|
"absolute",
|
||||||
|
"objectPath",
|
||||||
|
"writeObject",
|
||||||
|
"uncollatedProc",
|
||||||
|
"globalProc",
|
||||||
|
"localProc",
|
||||||
|
"parentObjectPath",
|
||||||
|
"findInstance",
|
||||||
|
"uncollatedProcInstance",
|
||||||
|
"globalProcInstance",
|
||||||
|
"localProcInstance"
|
||||||
|
};
|
||||||
|
const NamedEnum<fileOperation::pathType, 12> fileOperation::pathTypeNames_;
|
||||||
|
|
||||||
word fileOperation::defaultFileHandler
|
word fileOperation::defaultFileHandler
|
||||||
(
|
(
|
||||||
debug::optimisationSwitches().lookupOrAddDefault
|
debug::optimisationSwitches().lookupOrAddDefault
|
||||||
@ -56,7 +78,7 @@ namespace Foam
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Foam::word Foam::fileOperation::processorsDir = "processors";
|
Foam::word Foam::fileOperation::processorsBaseDir = "processors";
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||||
@ -133,6 +155,80 @@ Foam::instantList Foam::fileOperation::sortTimes
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::fileOperation::mergeTimes
|
||||||
|
(
|
||||||
|
const instantList& extraTimes,
|
||||||
|
const word& constantName,
|
||||||
|
instantList& times
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (extraTimes.size())
|
||||||
|
{
|
||||||
|
bool haveConstant =
|
||||||
|
(
|
||||||
|
times.size() > 0
|
||||||
|
&& times[0].name() == constantName
|
||||||
|
);
|
||||||
|
|
||||||
|
bool haveExtraConstant =
|
||||||
|
(
|
||||||
|
extraTimes.size() > 0
|
||||||
|
&& extraTimes[0].name() == constantName
|
||||||
|
);
|
||||||
|
|
||||||
|
// Combine times
|
||||||
|
instantList combinedTimes(times.size()+extraTimes.size());
|
||||||
|
label sz = 0;
|
||||||
|
label extrai = 0;
|
||||||
|
if (haveExtraConstant)
|
||||||
|
{
|
||||||
|
extrai = 1;
|
||||||
|
if (!haveConstant)
|
||||||
|
{
|
||||||
|
combinedTimes[sz++] = extraTimes[0]; // constant
|
||||||
|
}
|
||||||
|
}
|
||||||
|
forAll(times, i)
|
||||||
|
{
|
||||||
|
combinedTimes[sz++] = times[i];
|
||||||
|
}
|
||||||
|
for (; extrai < extraTimes.size(); extrai++)
|
||||||
|
{
|
||||||
|
combinedTimes[sz++] = extraTimes[extrai];
|
||||||
|
}
|
||||||
|
combinedTimes.setSize(sz);
|
||||||
|
times.transfer(combinedTimes);
|
||||||
|
|
||||||
|
// Sort
|
||||||
|
if (times.size() > 1)
|
||||||
|
{
|
||||||
|
label starti = 0;
|
||||||
|
if (times[0].name() == constantName)
|
||||||
|
{
|
||||||
|
starti = 1;
|
||||||
|
}
|
||||||
|
std::sort(×[starti], times.end(), instant::less());
|
||||||
|
|
||||||
|
// Filter out duplicates
|
||||||
|
label newi = starti+1;
|
||||||
|
for (label i = newi; i < times.size(); i++)
|
||||||
|
{
|
||||||
|
if (times[i].value() != times[i-1].value())
|
||||||
|
{
|
||||||
|
if (newi != i)
|
||||||
|
{
|
||||||
|
times[newi] = times[i];
|
||||||
|
}
|
||||||
|
newi++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
times.setSize(newi);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool Foam::fileOperation::isFileOrDir(const bool isFile, const fileName& f)
|
bool Foam::fileOperation::isFileOrDir(const bool isFile, const fileName& f)
|
||||||
{
|
{
|
||||||
return
|
return
|
||||||
@ -141,8 +237,182 @@ bool Foam::fileOperation::isFileOrDir(const bool isFile, const fileName& f)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::tmpNrc<Foam::fileOperation::dirIndexList>
|
||||||
|
Foam::fileOperation::lookupProcessorsPath(const fileName& fName) const
|
||||||
|
{
|
||||||
|
// If path is local to a processor (e.g. contains 'processor2')
|
||||||
|
// find the corresponding actual processor directory (e.g. 'processors4')
|
||||||
|
// and index (2)
|
||||||
|
|
||||||
|
fileName path;
|
||||||
|
fileName pDir;
|
||||||
|
fileName local;
|
||||||
|
label gStart;
|
||||||
|
label gSz;
|
||||||
|
label numProcs;
|
||||||
|
label proci =
|
||||||
|
splitProcessorPath(fName, path, pDir, local, gStart, gSz, numProcs);
|
||||||
|
|
||||||
|
if (proci != -1)
|
||||||
|
{
|
||||||
|
const fileName procPath(path/pDir);
|
||||||
|
|
||||||
|
HashTable<dirIndexList>::const_iterator iter =
|
||||||
|
procsDirs_.find(procPath);
|
||||||
|
|
||||||
|
if (iter != procsDirs_.end())
|
||||||
|
{
|
||||||
|
return iter();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read all directories to see any beginning with processor
|
||||||
|
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
DynamicList<dirIndex> procDirs;
|
||||||
|
|
||||||
|
// Note: use parallel synchronised reading so cache will be same
|
||||||
|
// order on all processors
|
||||||
|
fileNameList dirNames(readDir(path, fileName::Type::DIRECTORY));
|
||||||
|
|
||||||
|
// Extract info from processorsDDD or processorDDD:
|
||||||
|
// - highest processor number
|
||||||
|
// - directory+offset containing data for proci
|
||||||
|
label maxProc = -1;
|
||||||
|
|
||||||
|
forAll(dirNames, i)
|
||||||
|
{
|
||||||
|
const fileName& dirN = dirNames[i];
|
||||||
|
|
||||||
|
// Analyse directory name
|
||||||
|
fileName rp, rd, rl;
|
||||||
|
label rStart, rSize, rNum;
|
||||||
|
label readProci =
|
||||||
|
splitProcessorPath(dirN, rp, rd, rl, rStart, rSize, rNum);
|
||||||
|
maxProc = max(maxProc, readProci);
|
||||||
|
|
||||||
|
if (proci == readProci)
|
||||||
|
{
|
||||||
|
// Found "processorDDD". No need for index.
|
||||||
|
procDirs.append
|
||||||
|
(
|
||||||
|
dirIndex
|
||||||
|
(
|
||||||
|
dirN,
|
||||||
|
Tuple2<pathType, label>(PROCUNCOLLATED, -1)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else if (proci >= rStart && proci < rStart+rSize)
|
||||||
|
{
|
||||||
|
// "processorsDDD_start-end"
|
||||||
|
// Found the file that contains the data for proci
|
||||||
|
procDirs.append
|
||||||
|
(
|
||||||
|
dirIndex
|
||||||
|
(
|
||||||
|
dirN,
|
||||||
|
Tuple2<pathType, label>(PROCOBJECT, proci-rStart)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (rNum != -1)
|
||||||
|
{
|
||||||
|
// Direct detection of processorsDDD
|
||||||
|
maxProc = rNum-1;
|
||||||
|
|
||||||
|
if (rStart == -1)
|
||||||
|
{
|
||||||
|
// "processorsDDD"
|
||||||
|
procDirs.append
|
||||||
|
(
|
||||||
|
dirIndex
|
||||||
|
(
|
||||||
|
dirN,
|
||||||
|
Tuple2<pathType, label>(PROCBASEOBJECT, proci)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!Pstream::parRun())
|
||||||
|
{
|
||||||
|
// If (as a side effect) we found the number of decompositions
|
||||||
|
// use it
|
||||||
|
if (maxProc != -1)
|
||||||
|
{
|
||||||
|
const_cast<fileOperation&>(*this).setNProcs(maxProc+1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (returnReduce(procDirs.size(), sumOp<label>()))
|
||||||
|
{
|
||||||
|
procsDirs_.insert(procPath, procDirs);
|
||||||
|
|
||||||
|
if (debug)
|
||||||
|
{
|
||||||
|
Pout<< "fileOperation::lookupProcessorsPath : For:" << procPath
|
||||||
|
<< " detected:" << procDirs << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make sure to return a reference
|
||||||
|
return procsDirs_[procPath];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return tmpNrc<dirIndexList>(new dirIndexList(0, dirIndex()));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Foam::fileOperation::exists(IOobject& io) const
|
||||||
|
{
|
||||||
|
// Generate output filename for object
|
||||||
|
fileName objPath(objectPath(io, word::null));
|
||||||
|
|
||||||
|
// Test for either directory or a (valid) file & IOobject
|
||||||
|
bool ok;
|
||||||
|
if (io.name().empty())
|
||||||
|
{
|
||||||
|
ok = isDir(objPath);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ok =
|
||||||
|
isFile(objPath)
|
||||||
|
&& io.typeHeaderOk<IOList<label>>(false);// object with local scope
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ok)
|
||||||
|
{
|
||||||
|
// Re-test with searched for objectPath. This is for backwards
|
||||||
|
// compatibility
|
||||||
|
fileName originalPath(filePath(io.objectPath()));
|
||||||
|
if (originalPath != objPath)
|
||||||
|
{
|
||||||
|
// Test for either directory or a (valid) file & IOobject
|
||||||
|
if (io.name().empty())
|
||||||
|
{
|
||||||
|
ok = isDir(originalPath);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ok =
|
||||||
|
isFile(originalPath)
|
||||||
|
&& io.typeHeaderOk<IOList<label>>(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ok;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Foam::fileOperation::fileOperation(label comm)
|
||||||
|
:
|
||||||
|
comm_(comm)
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
Foam::autoPtr<Foam::fileOperation> Foam::fileOperation::New
|
Foam::autoPtr<Foam::fileOperation> Foam::fileOperation::New
|
||||||
(
|
(
|
||||||
const word& handlerType,
|
const word& handlerType,
|
||||||
@ -238,37 +508,64 @@ bool Foam::fileOperation::writeObject
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//Foam::fileName Foam::fileOperation::objectPath(const fileName& fName) const
|
|
||||||
//{
|
|
||||||
// return fName;
|
|
||||||
//}
|
|
||||||
|
|
||||||
|
|
||||||
Foam::fileName Foam::fileOperation::filePath(const fileName& fName) const
|
Foam::fileName Foam::fileOperation::filePath(const fileName& fName) const
|
||||||
{
|
{
|
||||||
fileName path;
|
if (debug)
|
||||||
fileName local;
|
{
|
||||||
label proci = fileOperations::masterUncollatedFileOperation::
|
Pout<< "fileOperation::filePath :" << " fName:" << fName << endl;
|
||||||
splitProcessorPath
|
}
|
||||||
(
|
|
||||||
fName,
|
|
||||||
path,
|
|
||||||
local
|
|
||||||
);
|
|
||||||
|
|
||||||
fileName procsName(path/processorsDir/local);
|
fileName path;
|
||||||
|
fileName pDir;
|
||||||
|
fileName local;
|
||||||
|
label gStart;
|
||||||
|
label gSz;
|
||||||
|
label numProcs;
|
||||||
|
label proci =
|
||||||
|
splitProcessorPath(fName, path, pDir, local, gStart, gSz, numProcs);
|
||||||
|
|
||||||
|
if (numProcs != -1)
|
||||||
|
{
|
||||||
|
WarningInFunction << "Filename is already adapted:" << fName << endl;
|
||||||
|
}
|
||||||
|
|
||||||
// Give preference to processors variant
|
// Give preference to processors variant
|
||||||
if (proci != -1 && exists(procsName))
|
if (proci != -1)
|
||||||
{
|
{
|
||||||
return procsName;
|
// Get all processor directories
|
||||||
}
|
tmpNrc<dirIndexList> procDirs(lookupProcessorsPath(fName));
|
||||||
else if (exists(fName))
|
forAll(procDirs(), i)
|
||||||
{
|
{
|
||||||
return fName;
|
const fileName& procDir = procDirs()[i].first();
|
||||||
|
|
||||||
|
fileName collatedName(path/procDir/local);
|
||||||
|
if (exists(collatedName))
|
||||||
|
{
|
||||||
|
if (debug)
|
||||||
|
{
|
||||||
|
Pout<< "fileOperation::filePath : " << collatedName << endl;
|
||||||
|
}
|
||||||
|
return collatedName;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return fileName::null;
|
if (exists(fName))
|
||||||
|
{
|
||||||
|
if (debug)
|
||||||
|
{
|
||||||
|
Pout<< "fileOperation::filePath : " << fName << endl;
|
||||||
|
}
|
||||||
|
return fName;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (debug)
|
||||||
|
{
|
||||||
|
Pout<< "fileOperation::filePath : Not found" << endl;
|
||||||
|
}
|
||||||
|
return fileName::null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -377,8 +674,8 @@ Foam::instantList Foam::fileOperation::findTimes
|
|||||||
{
|
{
|
||||||
if (debug)
|
if (debug)
|
||||||
{
|
{
|
||||||
Pout<< FUNCTION_NAME
|
Pout<< "fileOperation::findTimes : Finding times in directory "
|
||||||
<< " : Finding times in directory " << directory << endl;
|
<< directory << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read directory entries into a list
|
// Read directory entries into a list
|
||||||
@ -393,103 +690,188 @@ Foam::instantList Foam::fileOperation::findTimes
|
|||||||
|
|
||||||
instantList times = sortTimes(dirEntries, constantName);
|
instantList times = sortTimes(dirEntries, constantName);
|
||||||
|
|
||||||
// Check if directory is processorXXX
|
|
||||||
fileName procsDir
|
|
||||||
(
|
|
||||||
fileOperations::masterUncollatedFileOperation::processorsPath
|
|
||||||
(
|
|
||||||
directory
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
if (!procsDir.empty() && procsDir != directory)
|
// Get all processor directories
|
||||||
|
tmpNrc<dirIndexList> procDirs(lookupProcessorsPath(directory));
|
||||||
|
forAll(procDirs(), i)
|
||||||
{
|
{
|
||||||
fileNameList extraEntries
|
const fileName& procDir = procDirs()[i].first();
|
||||||
(
|
fileName collDir(processorsPath(directory, procDir));
|
||||||
Foam::readDir
|
if (!collDir.empty() && collDir != directory)
|
||||||
(
|
|
||||||
procsDir,
|
|
||||||
fileName::DIRECTORY
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
instantList extraTimes = sortTimes(extraEntries, constantName);
|
|
||||||
|
|
||||||
if (extraTimes.size())
|
|
||||||
{
|
{
|
||||||
bool haveConstant =
|
fileNameList extraEntries
|
||||||
(
|
(
|
||||||
times.size() > 0
|
Foam::readDir
|
||||||
&& times[0].name() == constantName
|
(
|
||||||
|
collDir,
|
||||||
|
fileName::DIRECTORY
|
||||||
|
)
|
||||||
);
|
);
|
||||||
|
mergeTimes
|
||||||
bool haveExtraConstant =
|
|
||||||
(
|
(
|
||||||
extraTimes.size() > 0
|
sortTimes(extraEntries, constantName),
|
||||||
&& extraTimes[0].name() == constantName
|
constantName,
|
||||||
|
times
|
||||||
);
|
);
|
||||||
|
|
||||||
// Combine times
|
|
||||||
instantList combinedTimes(times.size()+extraTimes.size());
|
|
||||||
label sz = 0;
|
|
||||||
label extrai = 0;
|
|
||||||
if (haveExtraConstant)
|
|
||||||
{
|
|
||||||
extrai = 1;
|
|
||||||
if (!haveConstant)
|
|
||||||
{
|
|
||||||
combinedTimes[sz++] = extraTimes[0]; // constant
|
|
||||||
}
|
|
||||||
}
|
|
||||||
forAll(times, i)
|
|
||||||
{
|
|
||||||
combinedTimes[sz++] = times[i];
|
|
||||||
}
|
|
||||||
for (; extrai < extraTimes.size(); extrai++)
|
|
||||||
{
|
|
||||||
combinedTimes[sz++] = extraTimes[extrai];
|
|
||||||
}
|
|
||||||
combinedTimes.setSize(sz);
|
|
||||||
times.transfer(combinedTimes);
|
|
||||||
|
|
||||||
// Sort
|
|
||||||
if (times.size() > 1)
|
|
||||||
{
|
|
||||||
label starti = 0;
|
|
||||||
if (times[0].name() == constantName)
|
|
||||||
{
|
|
||||||
starti = 1;
|
|
||||||
}
|
|
||||||
std::sort(×[starti], times.end(), instant::less());
|
|
||||||
|
|
||||||
// Filter out duplicates
|
|
||||||
label newi = starti+1;
|
|
||||||
for (label i = newi; i < times.size(); i++)
|
|
||||||
{
|
|
||||||
if (times[i].value() != times[i-1].value())
|
|
||||||
{
|
|
||||||
if (newi != i)
|
|
||||||
{
|
|
||||||
times[newi] = times[i];
|
|
||||||
}
|
|
||||||
newi++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
times.setSize(newi);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (debug)
|
if (debug)
|
||||||
{
|
{
|
||||||
Pout<< FUNCTION_NAME
|
Pout<< "fileOperation::findTimes : Found times:" << times << endl;
|
||||||
<< " : Found times:" << times << endl;
|
|
||||||
}
|
}
|
||||||
return times;
|
return times;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::IOobject Foam::fileOperation::findInstance
|
||||||
|
(
|
||||||
|
const IOobject& startIO,
|
||||||
|
const scalar startValue,
|
||||||
|
const word& stopInstance
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
const Time& time = startIO.time();
|
||||||
|
|
||||||
|
IOobject io(startIO);
|
||||||
|
|
||||||
|
// Note: - if name is empty, just check the directory itself
|
||||||
|
// - check both for isFile and headerOk since the latter does a
|
||||||
|
// filePath so searches for the file.
|
||||||
|
// - check for an object with local file scope (so no looking up in
|
||||||
|
// parent directory in case of parallel)
|
||||||
|
|
||||||
|
if (exists(io))
|
||||||
|
{
|
||||||
|
if (debug)
|
||||||
|
{
|
||||||
|
InfoInFunction
|
||||||
|
<< "Found exact match for \"" << io.name()
|
||||||
|
<< "\" in " << io.instance()/io.local()
|
||||||
|
<< endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
return io;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Search back through the time directories to find the time
|
||||||
|
// closest to and lower than current time
|
||||||
|
|
||||||
|
instantList ts = time.times();
|
||||||
|
label instanceI;
|
||||||
|
|
||||||
|
for (instanceI = ts.size()-1; instanceI >= 0; --instanceI)
|
||||||
|
{
|
||||||
|
if (ts[instanceI].value() <= startValue)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// continue searching from here
|
||||||
|
for (; instanceI >= 0; --instanceI)
|
||||||
|
{
|
||||||
|
// Shortcut: if actual directory is the timeName we've already tested it
|
||||||
|
if (ts[instanceI].name() == startIO.instance())
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
io.instance() = ts[instanceI].name();
|
||||||
|
if (exists(io))
|
||||||
|
{
|
||||||
|
if (debug)
|
||||||
|
{
|
||||||
|
InfoInFunction
|
||||||
|
<< "Found exact match for \"" << io.name()
|
||||||
|
<< "\" in " << io.instance()/io.local()
|
||||||
|
<< endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
return io;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if hit minimum instance
|
||||||
|
if (ts[instanceI].name() == stopInstance)
|
||||||
|
{
|
||||||
|
if (debug)
|
||||||
|
{
|
||||||
|
InfoInFunction
|
||||||
|
<< "Hit stopInstance " << stopInstance << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
if
|
||||||
|
(
|
||||||
|
startIO.readOpt() == IOobject::MUST_READ
|
||||||
|
|| startIO.readOpt() == IOobject::MUST_READ_IF_MODIFIED
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (io.name().empty())
|
||||||
|
{
|
||||||
|
FatalErrorInFunction
|
||||||
|
<< "Cannot find directory "
|
||||||
|
<< io.local() << " in times " << startIO.instance()
|
||||||
|
<< " down to " << stopInstance
|
||||||
|
<< exit(FatalError);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
FatalErrorInFunction
|
||||||
|
<< "Cannot find file \"" << io.name()
|
||||||
|
<< "\" in directory " << io.local()
|
||||||
|
<< " in times " << startIO.instance()
|
||||||
|
<< " down to " << stopInstance
|
||||||
|
<< exit(FatalError);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return io;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// times() usually already includes the constant() so would have been
|
||||||
|
// checked above. Re-test if
|
||||||
|
// - times() is empty. Sometimes this can happen (e.g. decomposePar with
|
||||||
|
// collated)
|
||||||
|
// - times()[0] is not constant
|
||||||
|
if (!ts.size() || ts[0].name() != time.constant())
|
||||||
|
{
|
||||||
|
// Note. This needs to be a hard-coded constant, rather than the
|
||||||
|
// constant function of the time, because the latter points to
|
||||||
|
// the case constant directory in parallel cases
|
||||||
|
|
||||||
|
io.instance() = time.constant();
|
||||||
|
if (exists(io))
|
||||||
|
{
|
||||||
|
if (debug)
|
||||||
|
{
|
||||||
|
InfoInFunction
|
||||||
|
<< "Found constant match for \"" << io.name()
|
||||||
|
<< "\" in " << io.instance()/io.local()
|
||||||
|
<< endl;
|
||||||
|
}
|
||||||
|
return io;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if
|
||||||
|
(
|
||||||
|
startIO.readOpt() == IOobject::MUST_READ
|
||||||
|
|| startIO.readOpt() == IOobject::MUST_READ_IF_MODIFIED
|
||||||
|
)
|
||||||
|
{
|
||||||
|
FatalErrorInFunction
|
||||||
|
<< "Cannot find file \"" << io.name() << "\" in directory "
|
||||||
|
<< io.local() << " in times " << startIO.instance()
|
||||||
|
<< " down to " << time.constant()
|
||||||
|
<< exit(FatalError);
|
||||||
|
}
|
||||||
|
|
||||||
|
return io;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
Foam::fileNameList Foam::fileOperation::readObjects
|
Foam::fileNameList Foam::fileOperation::readObjects
|
||||||
(
|
(
|
||||||
const objectRegistry& db,
|
const objectRegistry& db,
|
||||||
@ -518,19 +900,9 @@ Foam::fileNameList Foam::fileOperation::readObjects
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Get processors equivalent of path
|
// Get processors equivalent of path
|
||||||
|
fileName procsPath(filePath(path));
|
||||||
|
|
||||||
fileName prefix;
|
if (!procsPath.empty())
|
||||||
fileName postfix;
|
|
||||||
label proci = fileOperations::masterUncollatedFileOperation::
|
|
||||||
splitProcessorPath
|
|
||||||
(
|
|
||||||
path,
|
|
||||||
prefix,
|
|
||||||
postfix
|
|
||||||
);
|
|
||||||
fileName procsPath(prefix/processorsDir/postfix);
|
|
||||||
|
|
||||||
if (proci != -1 && Foam::isDir(procsPath))
|
|
||||||
{
|
{
|
||||||
newInstance = instance;
|
newInstance = instance;
|
||||||
objectNames = Foam::readDir(procsPath, fileName::FILE);
|
objectNames = Foam::readDir(procsPath, fileName::FILE);
|
||||||
@ -540,46 +912,252 @@ Foam::fileNameList Foam::fileOperation::readObjects
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::fileOperation::setNProcs(const label nProcs)
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
Foam::label Foam::fileOperation::nProcs
|
Foam::label Foam::fileOperation::nProcs
|
||||||
(
|
(
|
||||||
const fileName& dir,
|
const fileName& dir,
|
||||||
const fileName& local
|
const fileName& local
|
||||||
) const
|
) const
|
||||||
{
|
{
|
||||||
if (Foam::isDir(dir/processorsDir))
|
label nProcs = 0;
|
||||||
|
if (Pstream::master(comm_))
|
||||||
{
|
{
|
||||||
fileName pointsFile
|
fileNameList dirNames(Foam::readDir(dir, fileName::Type::DIRECTORY));
|
||||||
(
|
|
||||||
dir
|
|
||||||
/processorsDir
|
|
||||||
/"constant"
|
|
||||||
/local
|
|
||||||
/polyMesh::meshSubDir
|
|
||||||
/"points"
|
|
||||||
);
|
|
||||||
|
|
||||||
if (Foam::isFile(pointsFile))
|
// Detect any processorsDDD or processorDDD
|
||||||
|
label maxProc = -1;
|
||||||
|
forAll(dirNames, i)
|
||||||
{
|
{
|
||||||
return decomposedBlockData::numBlocks(pointsFile);
|
const fileName& dirN = dirNames[i];
|
||||||
|
|
||||||
|
fileName path, pDir, local;
|
||||||
|
label start, size, n;
|
||||||
|
maxProc = max
|
||||||
|
(
|
||||||
|
maxProc,
|
||||||
|
splitProcessorPath(dirN, path, pDir, local, start, size, n)
|
||||||
|
);
|
||||||
|
if (n != -1)
|
||||||
|
{
|
||||||
|
// Direct detection of processorsDDD
|
||||||
|
maxProc = n-1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
nProcs = maxProc+1;
|
||||||
|
|
||||||
|
|
||||||
|
if (nProcs == 0 && Foam::isDir(dir/processorsBaseDir))
|
||||||
|
{
|
||||||
|
fileName pointsFile
|
||||||
|
(
|
||||||
|
dir
|
||||||
|
/processorsBaseDir
|
||||||
|
/"constant"
|
||||||
|
/local
|
||||||
|
/polyMesh::meshSubDir
|
||||||
|
/"points"
|
||||||
|
);
|
||||||
|
|
||||||
|
if (Foam::isFile(pointsFile))
|
||||||
|
{
|
||||||
|
nProcs = decomposedBlockData::numBlocks(pointsFile);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
WarningInFunction << "Cannot read file " << pointsFile
|
||||||
|
<< " to determine the number of decompositions."
|
||||||
|
<< " Returning 1" << endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Pstream::scatter(nProcs, Pstream::msgType(), comm_);
|
||||||
|
return nProcs;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::fileName Foam::fileOperation::processorsCasePath
|
||||||
|
(
|
||||||
|
const IOobject& io,
|
||||||
|
const word& procsDir
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
return io.rootPath()/io.time().globalCaseName()/procsDir;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::fileName Foam::fileOperation::processorsPath
|
||||||
|
(
|
||||||
|
const IOobject& io,
|
||||||
|
const word& instance,
|
||||||
|
const word& procsDir
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
return
|
||||||
|
processorsCasePath(io, procsDir)
|
||||||
|
/instance
|
||||||
|
/io.db().dbDir()
|
||||||
|
/io.local();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::fileName Foam::fileOperation::processorsPath
|
||||||
|
(
|
||||||
|
const fileName& dir,
|
||||||
|
const word& procsDir
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
// Check if directory is processorDDD
|
||||||
|
word caseName(dir.name());
|
||||||
|
|
||||||
|
std::string::size_type pos = caseName.find("processor");
|
||||||
|
if (pos == 0)
|
||||||
|
{
|
||||||
|
if (caseName.size() <= 9 || caseName[9] == 's')
|
||||||
|
{
|
||||||
|
WarningInFunction << "Directory " << dir
|
||||||
|
<< " does not end in old-style processorDDD" << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
return dir.path()/procsDir;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return fileName::null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::label Foam::fileOperation::splitProcessorPath
|
||||||
|
(
|
||||||
|
const fileName& objectPath,
|
||||||
|
fileName& path,
|
||||||
|
fileName& procDir,
|
||||||
|
fileName& local,
|
||||||
|
|
||||||
|
label& groupStart,
|
||||||
|
label& groupSize,
|
||||||
|
|
||||||
|
label& nProcs
|
||||||
|
)
|
||||||
|
{
|
||||||
|
path.clear();
|
||||||
|
procDir.clear();
|
||||||
|
local.clear();
|
||||||
|
|
||||||
|
// Potentially detected start of number of processors in local group
|
||||||
|
groupStart = -1;
|
||||||
|
groupSize = 0;
|
||||||
|
|
||||||
|
// Potentially detected number of processors
|
||||||
|
nProcs = -1;
|
||||||
|
|
||||||
|
// Search for processor at start of line or /processor
|
||||||
|
std::string::size_type pos = objectPath.find("processor");
|
||||||
|
if (pos == string::npos)
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// "processorDDD"
|
||||||
|
// "processorsNNN"
|
||||||
|
// "processorsNNN_AA-BB"
|
||||||
|
|
||||||
|
|
||||||
|
if (pos > 0 && objectPath[pos-1] != '/')
|
||||||
|
{
|
||||||
|
// Directory not starting with "processor" e.g. "somenamewithprocessor"
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
procDir = objectPath;
|
||||||
|
|
||||||
|
// Strip leading directory
|
||||||
|
if (pos > 0)
|
||||||
|
{
|
||||||
|
path = objectPath.substr(0, pos-1);
|
||||||
|
procDir = objectPath.substr(pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Strip trailing local directory
|
||||||
|
pos = procDir.find('/');
|
||||||
|
if (pos != string::npos)
|
||||||
|
{
|
||||||
|
local = procDir.substr(pos+1);
|
||||||
|
procDir = procDir.substr(0, pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now procDir is e.g.
|
||||||
|
// - processor0
|
||||||
|
// - processors0
|
||||||
|
// - processorBananas
|
||||||
|
|
||||||
|
// Look for number after "processor"
|
||||||
|
|
||||||
|
fileName f(procDir.substr(9));
|
||||||
|
|
||||||
|
if (f.size() && f[0] == 's')
|
||||||
|
{
|
||||||
|
// "processsorsNNN"
|
||||||
|
|
||||||
|
f = f.substr(1);
|
||||||
|
|
||||||
|
// Detect "processorsNNN_AA-BB"
|
||||||
|
{
|
||||||
|
std::string::size_type fromStart = f.find("_");
|
||||||
|
std::string::size_type toStart = f.find("-");
|
||||||
|
if (fromStart != string::npos && toStart != string::npos)
|
||||||
|
{
|
||||||
|
string nProcsName(f.substr(0, fromStart));
|
||||||
|
string fromName(f.substr(fromStart+1, toStart-(fromStart+1)));
|
||||||
|
string toName(f.substr(toStart+1));
|
||||||
|
|
||||||
|
label groupEnd = -1;
|
||||||
|
if
|
||||||
|
(
|
||||||
|
Foam::read(fromName.c_str(), groupStart)
|
||||||
|
&& Foam::read(toName.c_str(), groupEnd)
|
||||||
|
&& Foam::read(nProcsName.c_str(), nProcs)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
groupSize = groupEnd-groupStart+1;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Detect "processorsN"
|
||||||
|
label n;
|
||||||
|
if (Foam::read(f.c_str(), n))
|
||||||
|
{
|
||||||
|
nProcs = n;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Detect "processorN"
|
||||||
|
label proci;
|
||||||
|
if (Foam::read(f.c_str(), proci))
|
||||||
|
{
|
||||||
|
return proci;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
WarningInFunction << "Cannot read file " << pointsFile
|
return -1;
|
||||||
<< " to determine the number of decompositions."
|
|
||||||
<< " Falling back to looking for processor.*" << endl;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
label nProcs = 0;
|
|
||||||
while
|
|
||||||
(
|
|
||||||
isDir(dir/(word("processor") + name(nProcs)))
|
|
||||||
)
|
|
||||||
{
|
|
||||||
++nProcs;
|
|
||||||
}
|
|
||||||
|
|
||||||
return nProcs;
|
Foam::label Foam::fileOperation::detectProcessorPath(const fileName& fName)
|
||||||
|
{
|
||||||
|
fileName path, pDir, local;
|
||||||
|
label start, size, nProcs;
|
||||||
|
return splitProcessorPath(fName, path, pDir, local, start, size, nProcs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -45,6 +45,10 @@ Description
|
|||||||
#include "instantList.H"
|
#include "instantList.H"
|
||||||
#include "fileMonitor.H"
|
#include "fileMonitor.H"
|
||||||
#include "labelList.H"
|
#include "labelList.H"
|
||||||
|
#include "Switch.H"
|
||||||
|
#include "tmpNrc.H"
|
||||||
|
#include "NamedEnum.H"
|
||||||
|
#include "Tuple2.H"
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
@ -56,16 +60,55 @@ class regIOobject;
|
|||||||
class objectRegistry;
|
class objectRegistry;
|
||||||
class Time;
|
class Time;
|
||||||
|
|
||||||
|
// Description of processor directory naming:
|
||||||
|
// - processor directory naming
|
||||||
|
// - whether directory contains a range (so differs on different processors)
|
||||||
|
// - index in range
|
||||||
|
//typedef Tuple2<fileName, Tuple2<bool, label>> dirIndex;
|
||||||
|
//typedef List<dirIndex> dirIndexList;
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*\
|
/*---------------------------------------------------------------------------*\
|
||||||
Class fileOperation Declaration
|
Class fileOperation Declaration
|
||||||
\*---------------------------------------------------------------------------*/
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
class fileOperation
|
class fileOperation
|
||||||
{
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
//- Enumeration for the location of an IOobject
|
||||||
|
enum pathType
|
||||||
|
{
|
||||||
|
NOTFOUND, // not found
|
||||||
|
ABSOLUTE, // instance is absolute directory
|
||||||
|
OBJECT, // io.objectPath() exists
|
||||||
|
WRITEOBJECT, // write path exists
|
||||||
|
PROCUNCOLLATED, // objectPath exists in processor0
|
||||||
|
PROCBASEOBJECT, // objectPath exists in specified, constant
|
||||||
|
// processorsDir (usually 'processorsDDD')
|
||||||
|
PROCOBJECT, // objectPath exists in locally differing
|
||||||
|
// processorsDir (e.g. 'processorsDDD_0-1')
|
||||||
|
PARENTOBJECT, // parent of object path
|
||||||
|
FINDINSTANCE, // file found in time directory
|
||||||
|
PROCUNCOLLATEDINSTANCE, // as PROCUNCOLLATED but with instance
|
||||||
|
PROCBASEINSTANCE, // as PROCBASEOBJECT but with instance
|
||||||
|
PROCINSTANCE // as PROCOBJECT but with instance
|
||||||
|
};
|
||||||
|
static const NamedEnum<pathType, 12> pathTypeNames_;
|
||||||
|
|
||||||
|
typedef Tuple2<fileName, Tuple2<pathType, label>> dirIndex;
|
||||||
|
typedef List<dirIndex> dirIndexList;
|
||||||
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
// Protected data
|
// Protected data
|
||||||
|
|
||||||
|
//- Communicator to use
|
||||||
|
const label comm_;
|
||||||
|
|
||||||
|
//- Detected processors directories
|
||||||
|
mutable HashTable<dirIndexList> procsDirs_;
|
||||||
|
|
||||||
//- file-change monitor for all registered files
|
//- file-change monitor for all registered files
|
||||||
mutable autoPtr<fileMonitor> monitorPtr_;
|
mutable autoPtr<fileMonitor> monitorPtr_;
|
||||||
|
|
||||||
@ -77,15 +120,35 @@ protected:
|
|||||||
//- Sort directory entries according to time value
|
//- Sort directory entries according to time value
|
||||||
static instantList sortTimes(const fileNameList&, const word&);
|
static instantList sortTimes(const fileNameList&, const word&);
|
||||||
|
|
||||||
|
//- Merge two times
|
||||||
|
static void mergeTimes
|
||||||
|
(
|
||||||
|
const instantList& extraTimes,
|
||||||
|
const word& constantName,
|
||||||
|
instantList& times
|
||||||
|
);
|
||||||
|
|
||||||
//- Helper: check for file (isFile) or directory (!isFile)
|
//- Helper: check for file (isFile) or directory (!isFile)
|
||||||
static bool isFileOrDir(const bool isFile, const fileName&);
|
static bool isFileOrDir(const bool isFile, const fileName&);
|
||||||
|
|
||||||
|
//- Detect presence of processorsDDD
|
||||||
|
void cacheProcessorsPath(const fileName& fName) const;
|
||||||
|
|
||||||
|
//- Lookup name of processorsDDD using cache. Return empty fileName
|
||||||
|
// if not found
|
||||||
|
tmpNrc<dirIndexList> lookupProcessorsPath(const fileName&) const;
|
||||||
|
|
||||||
|
//- Does ioobject exist. Is either a directory (empty name()) or
|
||||||
|
// a file
|
||||||
|
bool exists(IOobject& io) const;
|
||||||
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
// Static data
|
// Static data
|
||||||
|
|
||||||
//- The processors directory name (usually "processors")
|
//- Return the processors directory name (usually "processors")
|
||||||
static word processorsDir;
|
static word processorsBaseDir;
|
||||||
|
|
||||||
//- Default fileHandler
|
//- Default fileHandler
|
||||||
static word defaultFileHandler;
|
static word defaultFileHandler;
|
||||||
@ -93,19 +156,6 @@ public:
|
|||||||
|
|
||||||
// Public data types
|
// Public data types
|
||||||
|
|
||||||
//- Enumeration for the location of an IOobject
|
|
||||||
enum pathType
|
|
||||||
{
|
|
||||||
NOTFOUND, // not found
|
|
||||||
ABSOLUTE, // instance is absolute directory
|
|
||||||
OBJECT, // objectPath exists
|
|
||||||
PROCESSORSOBJECT, // objectPath exists in processors/
|
|
||||||
PARENTOBJECT, // parent of object path
|
|
||||||
FINDINSTANCE, // file found in time directory
|
|
||||||
PROCESSORSFINDINSTANCE // as above but in processors/
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
//- Runtime type information
|
//- Runtime type information
|
||||||
TypeName("fileOperation");
|
TypeName("fileOperation");
|
||||||
|
|
||||||
@ -116,8 +166,8 @@ public:
|
|||||||
|
|
||||||
// Constructors
|
// Constructors
|
||||||
|
|
||||||
//- Construct null
|
//- Construct from communicator
|
||||||
fileOperation() = default;
|
explicit fileOperation(const label comm);
|
||||||
|
|
||||||
|
|
||||||
// Declare run-time constructor selection table
|
// Declare run-time constructor selection table
|
||||||
@ -413,6 +463,24 @@ public:
|
|||||||
|
|
||||||
// Other
|
// Other
|
||||||
|
|
||||||
|
//- Actual name of processors dir (for use in mode PROCOBJECT,
|
||||||
|
// PROCINSTANCE)
|
||||||
|
virtual word processorsDir(const IOobject& io) const
|
||||||
|
{
|
||||||
|
return processorsBaseDir;
|
||||||
|
}
|
||||||
|
|
||||||
|
//- Actual name of processors dir (for use in mode PROCOBJECT,
|
||||||
|
// PROCINSTANCE)
|
||||||
|
virtual word processorsDir(const fileName&) const
|
||||||
|
{
|
||||||
|
return processorsBaseDir;
|
||||||
|
}
|
||||||
|
|
||||||
|
//- Set number of processor directories/results. Only used in
|
||||||
|
// decomposePar
|
||||||
|
virtual void setNProcs(const label nProcs);
|
||||||
|
|
||||||
//- Get number of processor directories/results. Used for e.g.
|
//- Get number of processor directories/results. Used for e.g.
|
||||||
// reconstructPar, argList checking
|
// reconstructPar, argList checking
|
||||||
virtual label nProcs
|
virtual label nProcs
|
||||||
@ -424,9 +492,59 @@ public:
|
|||||||
//- Get sorted list of times
|
//- Get sorted list of times
|
||||||
virtual instantList findTimes(const fileName&, const word&) const;
|
virtual instantList findTimes(const fileName&, const word&) const;
|
||||||
|
|
||||||
|
//- Find instance where IOobject is. Fails if cannot be found
|
||||||
|
// and readOpt() is MUST_READ/MUST_READ_IF_MODIFIED. Otherwise
|
||||||
|
// returns stopInstance.
|
||||||
|
virtual IOobject findInstance
|
||||||
|
(
|
||||||
|
const IOobject& io,
|
||||||
|
const scalar startValue,
|
||||||
|
const word& stopInstance
|
||||||
|
) const;
|
||||||
|
|
||||||
//- Callback for time change
|
//- Callback for time change
|
||||||
virtual void setTime(const Time&) const
|
virtual void setTime(const Time&) const
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
//- Generate path (like io.path) from root+casename with any
|
||||||
|
// 'processorXXX' replaced by procDir (usually 'processsors')
|
||||||
|
fileName processorsCasePath
|
||||||
|
(
|
||||||
|
const IOobject&,
|
||||||
|
const word& procDir
|
||||||
|
) const;
|
||||||
|
|
||||||
|
//- Generate path (like io.path) with provided instance and any
|
||||||
|
// 'processorXXX' replaced by procDir (usually 'processsors')
|
||||||
|
fileName processorsPath
|
||||||
|
(
|
||||||
|
const IOobject&,
|
||||||
|
const word& instance,
|
||||||
|
const word& procDir
|
||||||
|
) const;
|
||||||
|
|
||||||
|
//- Operating on fileName: replace processorXXX with procDir
|
||||||
|
fileName processorsPath(const fileName&, const word& procDir) const;
|
||||||
|
|
||||||
|
//- Split fileName into part before 'processor' and part after.
|
||||||
|
// Returns -1 or processor number and optionally number
|
||||||
|
// of processors. Use with care.
|
||||||
|
// - path/"processor"+Foam::name(proci)/local reconstructs input
|
||||||
|
// - path/"processors"+Foam::name(nProcs)/local reconstructs
|
||||||
|
// collated processors equivalence
|
||||||
|
static label splitProcessorPath
|
||||||
|
(
|
||||||
|
const fileName&,
|
||||||
|
fileName& path,
|
||||||
|
fileName& procDir,
|
||||||
|
fileName& local,
|
||||||
|
label& groupStart,
|
||||||
|
label& groupSize,
|
||||||
|
label& nProcs
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Detect processor number from '/aa/bb/processorDDD/cc'
|
||||||
|
static label detectProcessorPath(const fileName&);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -0,0 +1,88 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | Copyright (C) 2017-2018 OpenFOAM Foundation
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
License
|
||||||
|
This file is part of OpenFOAM.
|
||||||
|
|
||||||
|
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#include "fileOperationInitialise.H"
|
||||||
|
#include "addToRunTimeSelectionTable.H"
|
||||||
|
#include "OSspecific.H"
|
||||||
|
|
||||||
|
/* * * * * * * * * * * * * * * Static Member Data * * * * * * * * * * * * * */
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
namespace fileOperations
|
||||||
|
{
|
||||||
|
defineTypeNameAndDebug(fileOperationInitialise, 0);
|
||||||
|
defineRunTimeSelectionTable(fileOperationInitialise, word);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Foam::fileOperations::fileOperationInitialise::fileOperationInitialise
|
||||||
|
(
|
||||||
|
int& argc,
|
||||||
|
char**& argv
|
||||||
|
)
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::autoPtr<Foam::fileOperations::fileOperationInitialise>
|
||||||
|
Foam::fileOperations::fileOperationInitialise::New
|
||||||
|
(
|
||||||
|
const word& type,
|
||||||
|
int& argc,
|
||||||
|
char**& argv
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (debug)
|
||||||
|
{
|
||||||
|
InfoInFunction << "Constructing fileOperationInitialise" << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
wordConstructorTable::iterator cstrIter =
|
||||||
|
wordConstructorTablePtr_->find(type);
|
||||||
|
|
||||||
|
if (cstrIter == wordConstructorTablePtr_->end())
|
||||||
|
{
|
||||||
|
FatalErrorInFunction
|
||||||
|
<< "Unknown fileOperationInitialise type "
|
||||||
|
<< type << nl << nl
|
||||||
|
<< "Valid fileOperationInitialise types are" << endl
|
||||||
|
<< wordConstructorTablePtr_->sortedToc()
|
||||||
|
<< abort(FatalError);
|
||||||
|
}
|
||||||
|
|
||||||
|
return autoPtr<fileOperationInitialise>(cstrIter()(argc, argv));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Foam::fileOperations::fileOperationInitialise::~fileOperationInitialise()
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -0,0 +1,102 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | Copyright (C) 2017-2018 OpenFOAM Foundation
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
License
|
||||||
|
This file is part of OpenFOAM.
|
||||||
|
|
||||||
|
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
Class
|
||||||
|
Foam::fileOperationInitialise
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef fileOperationInitialise_H
|
||||||
|
#define fileOperationInitialise_H
|
||||||
|
|
||||||
|
#include "runTimeSelectionTables.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
namespace fileOperations
|
||||||
|
{
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
Class fileOperationInitialise Declaration
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
class fileOperationInitialise
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
//- Runtime type information
|
||||||
|
TypeName("fileOperationInitialise");
|
||||||
|
|
||||||
|
|
||||||
|
// Constructors
|
||||||
|
|
||||||
|
//- Construct components
|
||||||
|
fileOperationInitialise(int& argc, char**& argv);
|
||||||
|
|
||||||
|
|
||||||
|
// Declare run-time constructor selection table
|
||||||
|
|
||||||
|
declareRunTimeSelectionTable
|
||||||
|
(
|
||||||
|
autoPtr,
|
||||||
|
fileOperationInitialise,
|
||||||
|
word,
|
||||||
|
(
|
||||||
|
int& argc, char**& argv
|
||||||
|
),
|
||||||
|
(argc, argv)
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
// Selectors
|
||||||
|
|
||||||
|
//- Select type
|
||||||
|
static autoPtr<fileOperationInitialise> New
|
||||||
|
(
|
||||||
|
const word& type, int& argc, char**& argv
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
//- Destructor
|
||||||
|
virtual ~fileOperationInitialise();
|
||||||
|
|
||||||
|
|
||||||
|
// Member Functions
|
||||||
|
|
||||||
|
//- Needs threading
|
||||||
|
virtual bool needsThreading() const = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
} // End namespace fileOperations
|
||||||
|
} // End namespace Foam
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -0,0 +1,84 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | Copyright (C) 2017-2018 OpenFOAM Foundation
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
License
|
||||||
|
This file is part of OpenFOAM.
|
||||||
|
|
||||||
|
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
Class
|
||||||
|
Foam::unthreadedInitialise
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef unthreadedInitialise_H
|
||||||
|
#define unthreadedInitialise_H
|
||||||
|
|
||||||
|
#include "fileOperationInitialise.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
namespace fileOperations
|
||||||
|
{
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
Class unthreadedInitialise Declaration
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
class unthreadedInitialise
|
||||||
|
:
|
||||||
|
public fileOperationInitialise
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
// Constructors
|
||||||
|
|
||||||
|
//- Construct from components
|
||||||
|
unthreadedInitialise(int& argc, char**& argv)
|
||||||
|
:
|
||||||
|
fileOperationInitialise(argc, argv)
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
//- Destructor
|
||||||
|
virtual ~unthreadedInitialise()
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
// Member Functions
|
||||||
|
|
||||||
|
//- Needs threading
|
||||||
|
virtual bool needsThreading() const
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
} // End namespace fileOperations
|
||||||
|
} // End namespace Foam
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
File diff suppressed because it is too large
Load Diff
@ -28,6 +28,31 @@ Description
|
|||||||
fileOperations that performs all file operations on the master processor.
|
fileOperations that performs all file operations on the master processor.
|
||||||
Requires the calls to be parallel synchronised!
|
Requires the calls to be parallel synchronised!
|
||||||
|
|
||||||
|
Limitations: - no /processor in filename
|
||||||
|
- no /uniform/ in the filename
|
||||||
|
|
||||||
|
The main logic is in ::filePath which returns a
|
||||||
|
- same path on all processors. This can either be a global file
|
||||||
|
(system/controlDict, processorXXX/0/uniform/) or a collated file
|
||||||
|
(processors/0/p)
|
||||||
|
- same path on all processors of the local communicator
|
||||||
|
(processors4_0-1/0/p)
|
||||||
|
- different path on all processors (processor0/0/p)
|
||||||
|
|
||||||
|
system/controlDict:
|
||||||
|
filePath worldmaster: <globalRoot>/system/controlDict
|
||||||
|
localmaster: ,,
|
||||||
|
slave : ,,
|
||||||
|
|
||||||
|
processor0/uniform/time
|
||||||
|
filePath worldmaster: <globalRoot>/processorXXX/uniform/time
|
||||||
|
localmaster: ,,
|
||||||
|
slave : ,,
|
||||||
|
|
||||||
|
processors0/0/p
|
||||||
|
processors10/0/p
|
||||||
|
processors10_2-4/0/p
|
||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
#ifndef fileOperations_masterUncollatedFileOperation_H
|
#ifndef fileOperations_masterUncollatedFileOperation_H
|
||||||
@ -36,6 +61,9 @@ Description
|
|||||||
#include "fileOperation.H"
|
#include "fileOperation.H"
|
||||||
#include "OSspecific.H"
|
#include "OSspecific.H"
|
||||||
#include "HashPtrTable.H"
|
#include "HashPtrTable.H"
|
||||||
|
#include "Switch.H"
|
||||||
|
#include "unthreadedInitialise.H"
|
||||||
|
#include "boolList.H"
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
@ -59,6 +87,9 @@ protected:
|
|||||||
|
|
||||||
// Protected data
|
// Protected data
|
||||||
|
|
||||||
|
//- Any communicator allocated by me
|
||||||
|
const label myComm_;
|
||||||
|
|
||||||
//- Cached times for a given directory
|
//- Cached times for a given directory
|
||||||
mutable HashPtrTable<instantList> times_;
|
mutable HashPtrTable<instantList> times_;
|
||||||
|
|
||||||
@ -354,18 +385,29 @@ protected:
|
|||||||
|
|
||||||
// Private Member Functions
|
// Private Member Functions
|
||||||
|
|
||||||
|
//- Get the list of processors that are part of this communicator
|
||||||
|
static labelList subRanks(const label n);
|
||||||
|
|
||||||
template<class Type>
|
template<class Type>
|
||||||
Type scatterList(const UList<Type>&) const;
|
Type scatterList(const UList<Type>&, const int, const label comm) const;
|
||||||
|
|
||||||
template<class Type, class fileOp>
|
template<class Type, class fileOp>
|
||||||
Type masterOp(const fileName&, const fileOp& fop) const;
|
Type masterOp
|
||||||
|
(
|
||||||
|
const fileName&,
|
||||||
|
const fileOp& fop,
|
||||||
|
const int tag,
|
||||||
|
const label comm
|
||||||
|
) const;
|
||||||
|
|
||||||
template<class Type, class fileOp>
|
template<class Type, class fileOp>
|
||||||
Type masterOp
|
Type masterOp
|
||||||
(
|
(
|
||||||
const fileName&,
|
const fileName&,
|
||||||
const fileName&,
|
const fileName&,
|
||||||
const fileOp& fop
|
const fileOp& fop,
|
||||||
|
const int tag,
|
||||||
|
const label comm
|
||||||
) const;
|
) const;
|
||||||
|
|
||||||
//- Equivalent of Time::findInstance
|
//- Equivalent of Time::findInstance
|
||||||
@ -375,26 +417,32 @@ protected:
|
|||||||
const instant& t
|
const instant& t
|
||||||
);
|
);
|
||||||
|
|
||||||
//- Search for object; return info on how it was found
|
//- Search (locally!) for object; return info on how it was found.
|
||||||
|
// Does not do any parallel communication.
|
||||||
// checkGlobal : also check undecomposed case
|
// checkGlobal : also check undecomposed case
|
||||||
// isFile : true:check for file; false:check for directory
|
// isFile : true:check for file false:check for directory
|
||||||
fileName filePathInfo
|
// searchType : how was found
|
||||||
|
// processorsDir : name of processor directory
|
||||||
|
// instance : instance
|
||||||
|
virtual fileName filePathInfo
|
||||||
(
|
(
|
||||||
const bool checkGlobal,
|
const bool checkGlobal,
|
||||||
const bool isFile,
|
const bool isFile,
|
||||||
const IOobject& io,
|
const IOobject&,
|
||||||
const bool search,
|
const bool search,
|
||||||
pathType&,
|
pathType& searchType,
|
||||||
word&
|
word& processorsDir,
|
||||||
|
word& instance
|
||||||
) const;
|
) const;
|
||||||
|
|
||||||
//- Construct filePath
|
//- Construct filePath
|
||||||
static fileName objectPath
|
fileName localObjectPath
|
||||||
(
|
(
|
||||||
const IOobject&,
|
const IOobject&,
|
||||||
const pathType&,
|
const pathType& searchType,
|
||||||
const word&
|
const word& processorsDir,
|
||||||
);
|
const word& instancePath
|
||||||
|
) const;
|
||||||
|
|
||||||
//- Read file contents and send to processors
|
//- Read file contents and send to processors
|
||||||
static void readAndSend
|
static void readAndSend
|
||||||
@ -405,6 +453,29 @@ protected:
|
|||||||
PstreamBuffers& pBufs
|
PstreamBuffers& pBufs
|
||||||
);
|
);
|
||||||
|
|
||||||
|
//- Detect file (possibly compressed), read file contents and send
|
||||||
|
// to processors
|
||||||
|
static void readAndSend
|
||||||
|
(
|
||||||
|
const fileName& fName,
|
||||||
|
const labelUList& procs,
|
||||||
|
PstreamBuffers& pBufs
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Read files on comms master
|
||||||
|
static autoPtr<ISstream> read
|
||||||
|
(
|
||||||
|
IOobject& io,
|
||||||
|
const label comm,
|
||||||
|
const bool uniform, // on comms master only
|
||||||
|
const fileNameList& filePaths, // on comms master only
|
||||||
|
const boolList& procValid // on comms master only
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Helper: check IO for local existence. Like filePathInfo but
|
||||||
|
// without parent searchign and instance searching
|
||||||
|
bool exists(const dirIndexList&, IOobject& io) const;
|
||||||
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
@ -425,9 +496,12 @@ public:
|
|||||||
//- Construct null
|
//- Construct null
|
||||||
masterUncollatedFileOperation(const bool verbose);
|
masterUncollatedFileOperation(const bool verbose);
|
||||||
|
|
||||||
|
//- Construct from communicator
|
||||||
|
masterUncollatedFileOperation(const label comm, const bool verbose);
|
||||||
|
|
||||||
|
|
||||||
//- Destructor
|
//- Destructor
|
||||||
virtual ~masterUncollatedFileOperation() = default;
|
virtual ~masterUncollatedFileOperation();
|
||||||
|
|
||||||
|
|
||||||
// Member Functions
|
// Member Functions
|
||||||
@ -682,30 +756,19 @@ public:
|
|||||||
//- Get sorted list of times
|
//- Get sorted list of times
|
||||||
virtual instantList findTimes(const fileName&, const word&) const;
|
virtual instantList findTimes(const fileName&, const word&) const;
|
||||||
|
|
||||||
|
//- Find instance where IOobject is. Fails if cannot be found
|
||||||
|
// and readOpt() is MUST_READ/MUST_READ_IF_MODIFIED. Otherwise
|
||||||
|
// returns stopInstance.
|
||||||
|
virtual IOobject findInstance
|
||||||
|
(
|
||||||
|
const IOobject& io,
|
||||||
|
const scalar startValue,
|
||||||
|
const word& stopInstance
|
||||||
|
) const;
|
||||||
|
|
||||||
//- Callback for time change
|
//- Callback for time change
|
||||||
virtual void setTime(const Time&) const;
|
virtual void setTime(const Time&) const;
|
||||||
|
|
||||||
//- root+casename with any 'processorXXX' replaced by 'processsors'
|
|
||||||
static fileName processorsCasePath(const IOobject&);
|
|
||||||
|
|
||||||
//- Like io.path with provided instance and any 'processorXXX'
|
|
||||||
// replaced by 'processsors'
|
|
||||||
static fileName processorsPath(const IOobject&, const word&);
|
|
||||||
|
|
||||||
//- Operating on fileName: replace processorXXX with processors
|
|
||||||
static fileName processorsPath(const fileName&);
|
|
||||||
|
|
||||||
//- Split fileName into part before processor and part after.
|
|
||||||
// Returns -1 or processor number. Use with care.
|
|
||||||
// - path/"processor" + Foam::name(proci)/local reconstructs input
|
|
||||||
// - path/"processors"/local reconstructs processors equivalence
|
|
||||||
static label splitProcessorPath
|
|
||||||
(
|
|
||||||
const fileName&,
|
|
||||||
fileName& path,
|
|
||||||
fileName& local
|
|
||||||
);
|
|
||||||
|
|
||||||
//- Return cached times
|
//- Return cached times
|
||||||
const HashPtrTable<instantList>& times() const
|
const HashPtrTable<instantList>& times() const
|
||||||
{
|
{
|
||||||
@ -714,6 +777,28 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
Class masterUncollatedFileOperationInitialise Declaration
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
class masterUncollatedFileOperationInitialise
|
||||||
|
:
|
||||||
|
public unthreadedInitialise
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
// Constructors
|
||||||
|
|
||||||
|
//- Construct from components
|
||||||
|
masterUncollatedFileOperationInitialise(int& argc, char**& argv);
|
||||||
|
|
||||||
|
|
||||||
|
//- Destructor
|
||||||
|
virtual ~masterUncollatedFileOperationInitialise()
|
||||||
|
{}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
} // End namespace fileOperations
|
} // End namespace fileOperations
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
========= |
|
========= |
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
\\ / O peration |
|
\\ / O peration |
|
||||||
\\ / A nd | Copyright (C) 2017 OpenFOAM Foundation
|
\\ / A nd | Copyright (C) 2017-2018 OpenFOAM Foundation
|
||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
@ -31,14 +31,16 @@ License
|
|||||||
template<class Type>
|
template<class Type>
|
||||||
Type Foam::fileOperations::masterUncollatedFileOperation::scatterList
|
Type Foam::fileOperations::masterUncollatedFileOperation::scatterList
|
||||||
(
|
(
|
||||||
const UList<Type>& masterLst
|
const UList<Type>& masterLst,
|
||||||
|
const int tag,
|
||||||
|
const label comm
|
||||||
) const
|
) const
|
||||||
{
|
{
|
||||||
// TBD: more efficient scatter
|
// TBD: more efficient scatter
|
||||||
PstreamBuffers pBufs(UPstream::commsTypes::nonBlocking);
|
PstreamBuffers pBufs(UPstream::commsTypes::nonBlocking, tag, comm);
|
||||||
if (Pstream::master())
|
if (Pstream::master(comm))
|
||||||
{
|
{
|
||||||
for (label proci = 1; proci < Pstream::nProcs(); proci++)
|
for (label proci = 1; proci < Pstream::nProcs(comm); proci++)
|
||||||
{
|
{
|
||||||
UOPstream os(proci, pBufs);
|
UOPstream os(proci, pBufs);
|
||||||
os << masterLst[proci];
|
os << masterLst[proci];
|
||||||
@ -48,9 +50,9 @@ Type Foam::fileOperations::masterUncollatedFileOperation::scatterList
|
|||||||
|
|
||||||
Type myResult;
|
Type myResult;
|
||||||
|
|
||||||
if (Pstream::master())
|
if (Pstream::master(comm))
|
||||||
{
|
{
|
||||||
myResult = masterLst[Pstream::myProcNo()];
|
myResult = masterLst[Pstream::myProcNo(comm)];
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -65,21 +67,25 @@ template<class Type, class fileOp>
|
|||||||
Type Foam::fileOperations::masterUncollatedFileOperation::masterOp
|
Type Foam::fileOperations::masterUncollatedFileOperation::masterOp
|
||||||
(
|
(
|
||||||
const fileName& fName,
|
const fileName& fName,
|
||||||
const fileOp& fop
|
const fileOp& fop,
|
||||||
|
const int tag,
|
||||||
|
const label comm
|
||||||
) const
|
) const
|
||||||
{
|
{
|
||||||
if (IFstream::debug)
|
if (IFstream::debug)
|
||||||
{
|
{
|
||||||
Pout<< "masterUncollatedFileOperation : Operation on " << fName << endl;
|
Pout<< "masterUncollatedFileOperation::masterOp : Operation "
|
||||||
|
<< typeid(fileOp).name()
|
||||||
|
<< " on " << fName << endl;
|
||||||
}
|
}
|
||||||
if (Pstream::parRun())
|
if (Pstream::parRun())
|
||||||
{
|
{
|
||||||
List<fileName> filePaths(Pstream::nProcs());
|
List<fileName> filePaths(Pstream::nProcs(comm));
|
||||||
filePaths[Pstream::myProcNo()] = fName;
|
filePaths[Pstream::myProcNo(comm)] = fName;
|
||||||
Pstream::gatherList(filePaths);
|
Pstream::gatherList(filePaths, tag, comm);
|
||||||
|
|
||||||
List<Type> result(Pstream::nProcs());
|
List<Type> result(filePaths.size());
|
||||||
if (Pstream::master())
|
if (Pstream::master(comm))
|
||||||
{
|
{
|
||||||
result = fop(filePaths[0]);
|
result = fop(filePaths[0]);
|
||||||
for (label i = 1; i < filePaths.size(); i++)
|
for (label i = 1; i < filePaths.size(); i++)
|
||||||
@ -91,7 +97,7 @@ Type Foam::fileOperations::masterUncollatedFileOperation::masterOp
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return scatterList(result);
|
return scatterList(result, tag, comm);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -105,7 +111,9 @@ Type Foam::fileOperations::masterUncollatedFileOperation::masterOp
|
|||||||
(
|
(
|
||||||
const fileName& src,
|
const fileName& src,
|
||||||
const fileName& dest,
|
const fileName& dest,
|
||||||
const fileOp& fop
|
const fileOp& fop,
|
||||||
|
const int tag,
|
||||||
|
const label comm
|
||||||
) const
|
) const
|
||||||
{
|
{
|
||||||
if (IFstream::debug)
|
if (IFstream::debug)
|
||||||
@ -115,16 +123,16 @@ Type Foam::fileOperations::masterUncollatedFileOperation::masterOp
|
|||||||
}
|
}
|
||||||
if (Pstream::parRun())
|
if (Pstream::parRun())
|
||||||
{
|
{
|
||||||
List<fileName> srcs(Pstream::nProcs());
|
List<fileName> srcs(Pstream::nProcs(comm));
|
||||||
srcs[Pstream::myProcNo()] = src;
|
srcs[Pstream::myProcNo(comm)] = src;
|
||||||
Pstream::gatherList(srcs);
|
Pstream::gatherList(srcs, tag, comm);
|
||||||
|
|
||||||
List<fileName> dests(Pstream::nProcs());
|
List<fileName> dests(srcs.size());
|
||||||
dests[Pstream::myProcNo()] = dest;
|
dests[Pstream::myProcNo(comm)] = dest;
|
||||||
Pstream::gatherList(dests);
|
Pstream::gatherList(dests, tag, comm);
|
||||||
|
|
||||||
List<Type> result(Pstream::nProcs());
|
List<Type> result(Pstream::nProcs(comm));
|
||||||
if (Pstream::master())
|
if (Pstream::master(comm))
|
||||||
{
|
{
|
||||||
result = fop(srcs[0], dests[0]);
|
result = fop(srcs[0], dests[0]);
|
||||||
for (label i = 1; i < srcs.size(); i++)
|
for (label i = 1; i < srcs.size(); i++)
|
||||||
@ -136,7 +144,7 @@ Type Foam::fileOperations::masterUncollatedFileOperation::masterOp
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return scatterList(result);
|
return scatterList(result, tag, comm);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|||||||
@ -27,9 +27,9 @@ License
|
|||||||
#include "Time.H"
|
#include "Time.H"
|
||||||
#include "Fstream.H"
|
#include "Fstream.H"
|
||||||
#include "addToRunTimeSelectionTable.H"
|
#include "addToRunTimeSelectionTable.H"
|
||||||
#include "masterUncollatedFileOperation.H"
|
|
||||||
#include "decomposedBlockData.H"
|
#include "decomposedBlockData.H"
|
||||||
#include "dummyISstream.H"
|
#include "dummyISstream.H"
|
||||||
|
#include "unthreadedInitialise.H"
|
||||||
|
|
||||||
/* * * * * * * * * * * * * * * Static Member Data * * * * * * * * * * * * * */
|
/* * * * * * * * * * * * * * * Static Member Data * * * * * * * * * * * * * */
|
||||||
|
|
||||||
@ -39,6 +39,15 @@ namespace fileOperations
|
|||||||
{
|
{
|
||||||
defineTypeNameAndDebug(uncollatedFileOperation, 0);
|
defineTypeNameAndDebug(uncollatedFileOperation, 0);
|
||||||
addToRunTimeSelectionTable(fileOperation, uncollatedFileOperation, word);
|
addToRunTimeSelectionTable(fileOperation, uncollatedFileOperation, word);
|
||||||
|
|
||||||
|
// Mark as not needing threaded mpi
|
||||||
|
addNamedToRunTimeSelectionTable
|
||||||
|
(
|
||||||
|
fileOperationInitialise,
|
||||||
|
unthreadedInitialise,
|
||||||
|
word,
|
||||||
|
uncollated
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -102,17 +111,20 @@ Foam::fileName Foam::fileOperations::uncollatedFileOperation::filePathInfo
|
|||||||
// Check if parallel "procesors" directory
|
// Check if parallel "procesors" directory
|
||||||
if (io.time().processorCase())
|
if (io.time().processorCase())
|
||||||
{
|
{
|
||||||
fileName path = fileOperations::masterUncollatedFileOperation::
|
tmpNrc<dirIndexList> pDirs
|
||||||
processorsPath
|
|
||||||
(
|
(
|
||||||
io,
|
lookupProcessorsPath(io.objectPath())
|
||||||
io.instance()
|
|
||||||
);
|
);
|
||||||
fileName objectPath = path/io.name();
|
forAll(pDirs(), i)
|
||||||
|
|
||||||
if (isFileOrDir(isFile, objectPath))
|
|
||||||
{
|
{
|
||||||
return objectPath;
|
const fileName& pDir = pDirs()[i].first();
|
||||||
|
fileName objPath =
|
||||||
|
processorsPath(io, io.instance(), pDir)
|
||||||
|
/io.name();
|
||||||
|
if (objPath != objectPath && isFileOrDir(isFile, objPath))
|
||||||
|
{
|
||||||
|
return objPath;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -153,6 +165,8 @@ Foam::fileOperations::uncollatedFileOperation::uncollatedFileOperation
|
|||||||
(
|
(
|
||||||
const bool verbose
|
const bool verbose
|
||||||
)
|
)
|
||||||
|
:
|
||||||
|
fileOperation(Pstream::worldComm)
|
||||||
{
|
{
|
||||||
if (verbose)
|
if (verbose)
|
||||||
{
|
{
|
||||||
@ -533,15 +547,7 @@ Foam::fileOperations::uncollatedFileOperation::readStream
|
|||||||
{
|
{
|
||||||
// Analyse the objectpath to find out the processor we're trying
|
// Analyse the objectpath to find out the processor we're trying
|
||||||
// to access
|
// to access
|
||||||
fileName path;
|
label proci = detectProcessorPath(io.objectPath());
|
||||||
fileName local;
|
|
||||||
label proci = fileOperations::masterUncollatedFileOperation::
|
|
||||||
splitProcessorPath
|
|
||||||
(
|
|
||||||
io.objectPath(),
|
|
||||||
path,
|
|
||||||
local
|
|
||||||
);
|
|
||||||
|
|
||||||
if (proci == -1)
|
if (proci == -1)
|
||||||
{
|
{
|
||||||
@ -551,6 +557,26 @@ Foam::fileOperations::uncollatedFileOperation::readStream
|
|||||||
<< exit(FatalIOError);
|
<< exit(FatalIOError);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Analyse the fileName for any processor subset. Note: this
|
||||||
|
// should really be part of filePath() which should return
|
||||||
|
// both file and index in file.
|
||||||
|
fileName path, procDir, local;
|
||||||
|
label groupStart, groupSize, nProcs;
|
||||||
|
splitProcessorPath
|
||||||
|
(
|
||||||
|
fName,
|
||||||
|
path,
|
||||||
|
procDir,
|
||||||
|
local,
|
||||||
|
groupStart,
|
||||||
|
groupSize,
|
||||||
|
nProcs
|
||||||
|
);
|
||||||
|
if (groupStart != -1 && groupSize > 0)
|
||||||
|
{
|
||||||
|
proci = proci-groupStart;
|
||||||
|
}
|
||||||
|
|
||||||
// Read data and return as stream
|
// Read data and return as stream
|
||||||
return decomposedBlockData::readBlock(proci, isPtr(), io);
|
return decomposedBlockData::readBlock(proci, isPtr(), io);
|
||||||
}
|
}
|
||||||
@ -570,8 +596,8 @@ bool Foam::fileOperations::uncollatedFileOperation::read
|
|||||||
{
|
{
|
||||||
if (debug)
|
if (debug)
|
||||||
{
|
{
|
||||||
Pout<< "uncollatedFileOperation::read() : "
|
Pout<< "uncollatedFileOperation::read :"
|
||||||
<< "reading object " << io.objectPath()
|
<< " Reading object " << io.objectPath()
|
||||||
<< " from file " << endl;
|
<< " from file " << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -256,33 +256,6 @@ bool dlSymFound(void* handle, const std::string& symbol);
|
|||||||
fileNameList dlLoaded();
|
fileNameList dlLoaded();
|
||||||
|
|
||||||
|
|
||||||
// Thread handling
|
|
||||||
|
|
||||||
//- Allocate a thread
|
|
||||||
label allocateThread();
|
|
||||||
|
|
||||||
//- Start a thread
|
|
||||||
void createThread(const label, void *(*start_routine) (void *), void *arg);
|
|
||||||
|
|
||||||
//- Wait for thread
|
|
||||||
void joinThread(const label);
|
|
||||||
|
|
||||||
//- Delete a thread
|
|
||||||
void freeThread(const label);
|
|
||||||
|
|
||||||
//- Allocate a mutex variable
|
|
||||||
label allocateMutex();
|
|
||||||
|
|
||||||
//- Lock a mutex variable
|
|
||||||
void lockMutex(const label);
|
|
||||||
|
|
||||||
//- Unlock a mutex variable
|
|
||||||
void unlockMutex(const label);
|
|
||||||
|
|
||||||
//- Free a mutex variable
|
|
||||||
void freeMutex(const label);
|
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
} // End namespace Foam
|
} // End namespace Foam
|
||||||
|
|||||||
@ -67,7 +67,7 @@ class tmpNrc
|
|||||||
mutable T* ptr_;
|
mutable T* ptr_;
|
||||||
|
|
||||||
//- The type (managed pointer | const-reference object)
|
//- The type (managed pointer | const-reference object)
|
||||||
refType type_;
|
mutable refType type_;
|
||||||
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@ -160,6 +160,9 @@ public:
|
|||||||
//- delete object and set pointer to nullptr
|
//- delete object and set pointer to nullptr
|
||||||
inline void clear() const;
|
inline void clear() const;
|
||||||
|
|
||||||
|
//- Swaps the managed object with other tmpNrc.
|
||||||
|
inline void swap(tmpNrc<T>& other) noexcept;
|
||||||
|
|
||||||
|
|
||||||
// Member operators
|
// Member operators
|
||||||
|
|
||||||
|
|||||||
@ -266,7 +266,7 @@ Foam::faceZone::faceZone
|
|||||||
(
|
(
|
||||||
const word& name,
|
const word& name,
|
||||||
const labelUList& addr,
|
const labelUList& addr,
|
||||||
const boolList& fm,
|
const boolUList& fm,
|
||||||
const label index,
|
const label index,
|
||||||
const faceZoneMesh& zm
|
const faceZoneMesh& zm
|
||||||
)
|
)
|
||||||
@ -328,7 +328,7 @@ Foam::faceZone::faceZone
|
|||||||
(
|
(
|
||||||
const faceZone& origZone,
|
const faceZone& origZone,
|
||||||
const labelUList& addr,
|
const labelUList& addr,
|
||||||
const boolList& fm,
|
const boolUList& fm,
|
||||||
const label index,
|
const label index,
|
||||||
const faceZoneMesh& zm
|
const faceZoneMesh& zm
|
||||||
)
|
)
|
||||||
@ -468,7 +468,7 @@ void Foam::faceZone::resetAddressing
|
|||||||
void Foam::faceZone::resetAddressing
|
void Foam::faceZone::resetAddressing
|
||||||
(
|
(
|
||||||
const labelUList& addr,
|
const labelUList& addr,
|
||||||
const boolList& flipMap
|
const boolUList& flipMap
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
clearAddressing();
|
clearAddressing();
|
||||||
|
|||||||
@ -177,7 +177,7 @@ public:
|
|||||||
(
|
(
|
||||||
const word& name,
|
const word& name,
|
||||||
const labelUList& addr,
|
const labelUList& addr,
|
||||||
const boolList& fm,
|
const boolUList& fm,
|
||||||
const label index,
|
const label index,
|
||||||
const faceZoneMesh& zm
|
const faceZoneMesh& zm
|
||||||
);
|
);
|
||||||
@ -208,7 +208,7 @@ public:
|
|||||||
(
|
(
|
||||||
const faceZone& origZone,
|
const faceZone& origZone,
|
||||||
const labelUList& addr,
|
const labelUList& addr,
|
||||||
const boolList& fm,
|
const boolUList& fm,
|
||||||
const label index,
|
const label index,
|
||||||
const faceZoneMesh& zm
|
const faceZoneMesh& zm
|
||||||
);
|
);
|
||||||
@ -236,7 +236,7 @@ public:
|
|||||||
virtual autoPtr<faceZone> clone
|
virtual autoPtr<faceZone> clone
|
||||||
(
|
(
|
||||||
const labelUList& addr,
|
const labelUList& addr,
|
||||||
const boolList& fm,
|
const boolUList& fm,
|
||||||
const label index,
|
const label index,
|
||||||
const faceZoneMesh& zm
|
const faceZoneMesh& zm
|
||||||
) const
|
) const
|
||||||
@ -309,7 +309,7 @@ public:
|
|||||||
virtual void resetAddressing
|
virtual void resetAddressing
|
||||||
(
|
(
|
||||||
const labelUList& addr,
|
const labelUList& addr,
|
||||||
const boolList& flipMap
|
const boolUList& flipMap
|
||||||
);
|
);
|
||||||
|
|
||||||
//- Move reset addressing - use uniform flip map value
|
//- Move reset addressing - use uniform flip map value
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
========= |
|
========= |
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
\\ / O peration |
|
\\ / O peration |
|
||||||
\\ / A nd | Copyright (C) 2011-2017 OpenFOAM Foundation
|
\\ / A nd | Copyright (C) 2011-2018 OpenFOAM Foundation
|
||||||
\\/ M anipulation | Copyright (C) 2016 OpenCFD Ltd.
|
\\/ M anipulation | Copyright (C) 2016 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
@ -42,7 +42,7 @@ bool Foam::UPstream::initNull()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool Foam::UPstream::init(int& argc, char**& argv)
|
bool Foam::UPstream::init(int& argc, char**& argv, const bool needsThread)
|
||||||
{
|
{
|
||||||
FatalErrorInFunction
|
FatalErrorInFunction
|
||||||
<< "The dummy Pstream library cannot be used in parallel mode"
|
<< "The dummy Pstream library cannot be used in parallel mode"
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
sinclude $(GENERAL_RULES)/mplib$(WM_MPLIB)
|
sinclude $(GENERAL_RULES)/mplib$(WM_MPLIB)
|
||||||
sinclude $(RULES)/mplib$(WM_MPLIB)
|
sinclude $(DEFAULT_RULES)/mplib$(WM_MPLIB)
|
||||||
|
|
||||||
EXE_INC = $(PFLAGS) $(PINC) $(c++LESSWARN)
|
EXE_INC = $(PFLAGS) $(PINC) $(c++LESSWARN)
|
||||||
LIB_LIBS = $(PLIBS)
|
LIB_LIBS = $(PLIBS)
|
||||||
|
|||||||
@ -101,7 +101,7 @@ bool Foam::UPstream::initNull()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool Foam::UPstream::init(int& argc, char**& argv)
|
bool Foam::UPstream::init(int& argc, char**& argv, const bool needsThread)
|
||||||
{
|
{
|
||||||
int flag = 0;
|
int flag = 0;
|
||||||
|
|
||||||
@ -129,17 +129,16 @@ bool Foam::UPstream::init(int& argc, char**& argv)
|
|||||||
|
|
||||||
|
|
||||||
//MPI_Init(&argc, &argv);
|
//MPI_Init(&argc, &argv);
|
||||||
int wanted_thread_support = MPI_THREAD_SINGLE;
|
|
||||||
if (fileOperations::collatedFileOperation::maxThreadFileBufferSize > 0)
|
|
||||||
{
|
|
||||||
wanted_thread_support = MPI_THREAD_MULTIPLE;
|
|
||||||
}
|
|
||||||
int provided_thread_support;
|
int provided_thread_support;
|
||||||
MPI_Init_thread
|
MPI_Init_thread
|
||||||
(
|
(
|
||||||
&argc,
|
&argc,
|
||||||
&argv,
|
&argv,
|
||||||
wanted_thread_support,
|
(
|
||||||
|
needsThread
|
||||||
|
? MPI_THREAD_MULTIPLE
|
||||||
|
: MPI_THREAD_SINGLE
|
||||||
|
),
|
||||||
&provided_thread_support
|
&provided_thread_support
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@ -571,7 +571,8 @@ void Foam::vtk::vtuSizing::populateArrays
|
|||||||
if (output == contentType::LEGACY)
|
if (output == contentType::LEGACY)
|
||||||
{
|
{
|
||||||
// Update size for legacy face stream
|
// Update size for legacy face stream
|
||||||
faceOutput[startLabel] = (faceIndexer - startLabel);
|
// (subtract 1 to avoid counting the storage location)
|
||||||
|
faceOutput[startLabel] = (faceIndexer - 1 - startLabel);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
========= |
|
========= |
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
\\ / O peration |
|
\\ / O peration |
|
||||||
\\ / A nd | Copyright (C) 2011-2017 OpenFOAM Foundation
|
\\ / A nd | Copyright (C) 2011-2018 OpenFOAM Foundation
|
||||||
\\/ M anipulation | Copyright (C) 2015-2018 OpenCFD Ltd.
|
\\/ M anipulation | Copyright (C) 2015-2018 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
@ -42,6 +42,7 @@ License
|
|||||||
#include "fvMeshTools.H"
|
#include "fvMeshTools.H"
|
||||||
#include "labelPairHashes.H"
|
#include "labelPairHashes.H"
|
||||||
#include "ListOps.H"
|
#include "ListOps.H"
|
||||||
|
#include "globalIndex.H"
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||||
|
|
||||||
@ -688,25 +689,54 @@ Foam::autoPtr<Foam::mapPolyMesh> Foam::fvMeshDistribute::repatch
|
|||||||
// merge those points.
|
// merge those points.
|
||||||
Foam::autoPtr<Foam::mapPolyMesh> Foam::fvMeshDistribute::mergeSharedPoints
|
Foam::autoPtr<Foam::mapPolyMesh> Foam::fvMeshDistribute::mergeSharedPoints
|
||||||
(
|
(
|
||||||
|
const labelList& pointToGlobalMaster,
|
||||||
labelListList& constructPointMap
|
labelListList& constructPointMap
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
// Find out which sets of points get merged and create a map from
|
// Find out which sets of points get merged and create a map from
|
||||||
// mesh point to unique point.
|
// mesh point to unique point.
|
||||||
Map<label> pointToMaster
|
|
||||||
(
|
label nShared = 0;
|
||||||
fvMeshAdder::findSharedPoints
|
forAll(pointToGlobalMaster, pointi)
|
||||||
(
|
{
|
||||||
mesh_,
|
if (pointToGlobalMaster[pointi] != -1)
|
||||||
mergeTol_
|
{
|
||||||
)
|
nShared++;
|
||||||
);
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<label> globalMasterToLocalMaster(2*nShared);
|
||||||
|
Map<label> pointToMaster(2*nShared);
|
||||||
|
|
||||||
|
forAll(pointToGlobalMaster, pointi)
|
||||||
|
{
|
||||||
|
label globali = pointToGlobalMaster[pointi];
|
||||||
|
if (globali != -1)
|
||||||
|
{
|
||||||
|
Map<label>::const_iterator iter = globalMasterToLocalMaster.find
|
||||||
|
(
|
||||||
|
globali
|
||||||
|
);
|
||||||
|
|
||||||
|
if (iter == globalMasterToLocalMaster.end())
|
||||||
|
{
|
||||||
|
// Found first point. Designate as master
|
||||||
|
globalMasterToLocalMaster.insert(globali, pointi);
|
||||||
|
pointToMaster.insert(pointi, pointi);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pointToMaster.insert(pointi, iter());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (returnReduce(pointToMaster.size(), sumOp<label>()) == 0)
|
if (returnReduce(pointToMaster.size(), sumOp<label>()) == 0)
|
||||||
{
|
{
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
polyTopoChange meshMod(mesh_);
|
polyTopoChange meshMod(mesh_);
|
||||||
|
|
||||||
fvMeshAdder::mergePoints(mesh_, pointToMaster, meshMod);
|
fvMeshAdder::mergePoints(mesh_, pointToMaster, meshMod);
|
||||||
@ -750,16 +780,19 @@ Foam::autoPtr<Foam::mapPolyMesh> Foam::fvMeshDistribute::mergeSharedPoints
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Construct the local environment of all boundary faces.
|
void Foam::fvMeshDistribute::getCouplingData
|
||||||
void Foam::fvMeshDistribute::getNeighbourData
|
|
||||||
(
|
(
|
||||||
const labelList& distribution,
|
const labelList& distribution,
|
||||||
labelList& sourceFace,
|
labelList& sourceFace,
|
||||||
labelList& sourceProc,
|
labelList& sourceProc,
|
||||||
labelList& sourcePatch,
|
labelList& sourcePatch,
|
||||||
labelList& sourceNewNbrProc
|
labelList& sourceNewNbrProc,
|
||||||
|
labelList& sourcePointMaster
|
||||||
) const
|
) const
|
||||||
{
|
{
|
||||||
|
// Construct the coupling information for all (boundary) faces and
|
||||||
|
// points
|
||||||
|
|
||||||
label nBnd = mesh_.nFaces() - mesh_.nInternalFaces();
|
label nBnd = mesh_.nFaces() - mesh_.nInternalFaces();
|
||||||
sourceFace.setSize(nBnd);
|
sourceFace.setSize(nBnd);
|
||||||
sourceProc.setSize(nBnd);
|
sourceProc.setSize(nBnd);
|
||||||
@ -890,13 +923,62 @@ void Foam::fvMeshDistribute::getNeighbourData
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Collect coupled (collocated) points
|
||||||
|
sourcePointMaster.setSize(mesh_.nPoints());
|
||||||
|
sourcePointMaster = -1;
|
||||||
|
{
|
||||||
|
// Assign global master point
|
||||||
|
const globalIndex globalPoints(mesh_.nPoints());
|
||||||
|
|
||||||
|
const globalMeshData& gmd = mesh_.globalData();
|
||||||
|
const indirectPrimitivePatch& cpp = gmd.coupledPatch();
|
||||||
|
const labelList& meshPoints = cpp.meshPoints();
|
||||||
|
const mapDistribute& slavesMap = gmd.globalCoPointSlavesMap();
|
||||||
|
const labelListList& slaves = gmd.globalCoPointSlaves();
|
||||||
|
|
||||||
|
labelList elems(slavesMap.constructSize(), -1);
|
||||||
|
forAll(meshPoints, pointi)
|
||||||
|
{
|
||||||
|
const labelList& slots = slaves[pointi];
|
||||||
|
|
||||||
|
if (slots.size())
|
||||||
|
{
|
||||||
|
// pointi is a master. Assign a unique label.
|
||||||
|
|
||||||
|
label globalPointi = globalPoints.toGlobal(meshPoints[pointi]);
|
||||||
|
elems[pointi] = globalPointi;
|
||||||
|
forAll(slots, i)
|
||||||
|
{
|
||||||
|
label sloti = slots[i];
|
||||||
|
if (sloti >= meshPoints.size())
|
||||||
|
{
|
||||||
|
// Filter out local collocated points. We don't want
|
||||||
|
// to merge these
|
||||||
|
elems[slots[i]] = globalPointi;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Push slave-slot data back to slaves
|
||||||
|
slavesMap.reverseDistribute(elems.size(), elems, false);
|
||||||
|
|
||||||
|
// Extract back onto mesh
|
||||||
|
forAll(meshPoints, pointi)
|
||||||
|
{
|
||||||
|
sourcePointMaster[meshPoints[pointi]] = elems[pointi];
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Subset the neighbourCell/neighbourProc fields
|
// Subset the neighbourCell/neighbourProc fields
|
||||||
void Foam::fvMeshDistribute::subsetBoundaryData
|
void Foam::fvMeshDistribute::subsetCouplingData
|
||||||
(
|
(
|
||||||
const fvMesh& mesh,
|
const fvMesh& mesh,
|
||||||
|
const labelList& pointMap,
|
||||||
const labelList& faceMap,
|
const labelList& faceMap,
|
||||||
const labelList& cellMap,
|
const labelList& cellMap,
|
||||||
|
|
||||||
@ -909,11 +991,13 @@ void Foam::fvMeshDistribute::subsetBoundaryData
|
|||||||
const labelList& sourceProc,
|
const labelList& sourceProc,
|
||||||
const labelList& sourcePatch,
|
const labelList& sourcePatch,
|
||||||
const labelList& sourceNewNbrProc,
|
const labelList& sourceNewNbrProc,
|
||||||
|
const labelList& sourcePointMaster,
|
||||||
|
|
||||||
labelList& subFace,
|
labelList& subFace,
|
||||||
labelList& subProc,
|
labelList& subProc,
|
||||||
labelList& subPatch,
|
labelList& subPatch,
|
||||||
labelList& subNewNbrProc
|
labelList& subNewNbrProc,
|
||||||
|
labelList& subPointMaster
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
subFace.setSize(mesh.nFaces() - mesh.nInternalFaces());
|
subFace.setSize(mesh.nFaces() - mesh.nInternalFaces());
|
||||||
@ -959,6 +1043,9 @@ void Foam::fvMeshDistribute::subsetBoundaryData
|
|||||||
subNewNbrProc[newBFacei] = sourceNewNbrProc[oldBFacei];
|
subNewNbrProc[newBFacei] = sourceNewNbrProc[oldBFacei];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
subPointMaster = UIndirectList<label>(sourcePointMaster, pointMap);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1042,9 +1129,9 @@ Foam::labelList Foam::fvMeshDistribute::mapBoundaryData
|
|||||||
(
|
(
|
||||||
const primitiveMesh& mesh, // mesh after adding
|
const primitiveMesh& mesh, // mesh after adding
|
||||||
const mapAddedPolyMesh& map,
|
const mapAddedPolyMesh& map,
|
||||||
const labelList& boundaryData0, // mesh before adding
|
const labelList& boundaryData0, // on mesh before adding
|
||||||
const label nInternalFaces1,
|
const label nInternalFaces1,
|
||||||
const labelList& boundaryData1 // added mesh
|
const labelList& boundaryData1 // on added mesh
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
labelList newBoundaryData(mesh.nFaces() - mesh.nInternalFaces());
|
labelList newBoundaryData(mesh.nFaces() - mesh.nInternalFaces());
|
||||||
@ -1076,6 +1163,41 @@ Foam::labelList Foam::fvMeshDistribute::mapBoundaryData
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::labelList Foam::fvMeshDistribute::mapPointData
|
||||||
|
(
|
||||||
|
const primitiveMesh& mesh, // mesh after adding
|
||||||
|
const mapAddedPolyMesh& map,
|
||||||
|
const labelList& boundaryData0, // on mesh before adding
|
||||||
|
const labelList& boundaryData1 // on added mesh
|
||||||
|
)
|
||||||
|
{
|
||||||
|
labelList newBoundaryData(mesh.nPoints());
|
||||||
|
|
||||||
|
forAll(boundaryData0, oldPointi)
|
||||||
|
{
|
||||||
|
label newPointi = map.oldPointMap()[oldPointi];
|
||||||
|
|
||||||
|
// Point still exists (is necessary?)
|
||||||
|
if (newPointi >= 0)
|
||||||
|
{
|
||||||
|
newBoundaryData[newPointi] = boundaryData0[oldPointi];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
forAll(boundaryData1, addedPointi)
|
||||||
|
{
|
||||||
|
label newPointi = map.addedPointMap()[addedPointi];
|
||||||
|
|
||||||
|
if (newPointi >= 0)
|
||||||
|
{
|
||||||
|
newBoundaryData[newPointi] = boundaryData1[addedPointi];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return newBoundaryData;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Remove cells. Add all exposed faces to patch oldInternalPatchi
|
// Remove cells. Add all exposed faces to patch oldInternalPatchi
|
||||||
Foam::autoPtr<Foam::mapPolyMesh> Foam::fvMeshDistribute::doRemoveCells
|
Foam::autoPtr<Foam::mapPolyMesh> Foam::fvMeshDistribute::doRemoveCells
|
||||||
(
|
(
|
||||||
@ -1297,6 +1419,7 @@ void Foam::fvMeshDistribute::sendMesh
|
|||||||
const labelList& sourceProc,
|
const labelList& sourceProc,
|
||||||
const labelList& sourcePatch,
|
const labelList& sourcePatch,
|
||||||
const labelList& sourceNewNbrProc,
|
const labelList& sourceNewNbrProc,
|
||||||
|
const labelList& sourcePointMaster,
|
||||||
Ostream& toDomain
|
Ostream& toDomain
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
@ -1433,7 +1556,8 @@ void Foam::fvMeshDistribute::sendMesh
|
|||||||
<< sourceFace
|
<< sourceFace
|
||||||
<< sourceProc
|
<< sourceProc
|
||||||
<< sourcePatch
|
<< sourcePatch
|
||||||
<< sourceNewNbrProc;
|
<< sourceNewNbrProc
|
||||||
|
<< sourcePointMaster;
|
||||||
|
|
||||||
|
|
||||||
if (debug)
|
if (debug)
|
||||||
@ -1456,6 +1580,7 @@ Foam::autoPtr<Foam::fvMesh> Foam::fvMeshDistribute::receiveMesh
|
|||||||
labelList& domainSourceProc,
|
labelList& domainSourceProc,
|
||||||
labelList& domainSourcePatch,
|
labelList& domainSourcePatch,
|
||||||
labelList& domainSourceNewNbrProc,
|
labelList& domainSourceNewNbrProc,
|
||||||
|
labelList& domainSourcePointMaster,
|
||||||
Istream& fromNbr
|
Istream& fromNbr
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
@ -1474,7 +1599,8 @@ Foam::autoPtr<Foam::fvMesh> Foam::fvMeshDistribute::receiveMesh
|
|||||||
>> domainSourceFace
|
>> domainSourceFace
|
||||||
>> domainSourceProc
|
>> domainSourceProc
|
||||||
>> domainSourcePatch
|
>> domainSourcePatch
|
||||||
>> domainSourceNewNbrProc;
|
>> domainSourceNewNbrProc
|
||||||
|
>> domainSourcePointMaster;
|
||||||
|
|
||||||
// Construct fvMesh
|
// Construct fvMesh
|
||||||
auto domainMeshPtr = autoPtr<fvMesh>::New
|
auto domainMeshPtr = autoPtr<fvMesh>::New
|
||||||
@ -1709,13 +1835,15 @@ Foam::autoPtr<Foam::mapDistributePolyMesh> Foam::fvMeshDistribute::distribute
|
|||||||
labelList sourceFace;
|
labelList sourceFace;
|
||||||
labelList sourceProc;
|
labelList sourceProc;
|
||||||
labelList sourceNewNbrProc;
|
labelList sourceNewNbrProc;
|
||||||
getNeighbourData
|
labelList sourcePointMaster;
|
||||||
|
getCouplingData
|
||||||
(
|
(
|
||||||
distribution,
|
distribution,
|
||||||
sourceFace,
|
sourceFace,
|
||||||
sourceProc,
|
sourceProc,
|
||||||
sourcePatch,
|
sourcePatch,
|
||||||
sourceNewNbrProc
|
sourceNewNbrProc,
|
||||||
|
sourcePointMaster
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
@ -1924,11 +2052,13 @@ Foam::autoPtr<Foam::mapDistributePolyMesh> Foam::fvMeshDistribute::distribute
|
|||||||
labelList procSourceProc;
|
labelList procSourceProc;
|
||||||
labelList procSourcePatch;
|
labelList procSourcePatch;
|
||||||
labelList procSourceNewNbrProc;
|
labelList procSourceNewNbrProc;
|
||||||
|
labelList procSourcePointMaster;
|
||||||
|
|
||||||
subsetBoundaryData
|
subsetCouplingData
|
||||||
(
|
(
|
||||||
subsetter.subMesh(),
|
subsetter.subMesh(),
|
||||||
subsetter.faceMap(), // from subMesh to mesh
|
subsetter.pointMap(), // from subMesh to mesh
|
||||||
|
subsetter.faceMap(), // ,, ,,
|
||||||
subsetter.cellMap(), // ,, ,,
|
subsetter.cellMap(), // ,, ,,
|
||||||
|
|
||||||
distribution, // old mesh distribution
|
distribution, // old mesh distribution
|
||||||
@ -1940,15 +2070,16 @@ Foam::autoPtr<Foam::mapDistributePolyMesh> Foam::fvMeshDistribute::distribute
|
|||||||
sourceProc,
|
sourceProc,
|
||||||
sourcePatch,
|
sourcePatch,
|
||||||
sourceNewNbrProc,
|
sourceNewNbrProc,
|
||||||
|
sourcePointMaster,
|
||||||
|
|
||||||
procSourceFace,
|
procSourceFace,
|
||||||
procSourceProc,
|
procSourceProc,
|
||||||
procSourcePatch,
|
procSourcePatch,
|
||||||
procSourceNewNbrProc
|
procSourceNewNbrProc,
|
||||||
|
procSourcePointMaster
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Send to neighbour
|
// Send to neighbour
|
||||||
sendMesh
|
sendMesh
|
||||||
(
|
(
|
||||||
@ -1963,6 +2094,8 @@ Foam::autoPtr<Foam::mapDistributePolyMesh> Foam::fvMeshDistribute::distribute
|
|||||||
procSourceProc,
|
procSourceProc,
|
||||||
procSourcePatch,
|
procSourcePatch,
|
||||||
procSourceNewNbrProc,
|
procSourceNewNbrProc,
|
||||||
|
procSourcePointMaster,
|
||||||
|
|
||||||
str
|
str
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -2121,10 +2254,12 @@ Foam::autoPtr<Foam::mapDistributePolyMesh> Foam::fvMeshDistribute::distribute
|
|||||||
labelList domainSourceProc;
|
labelList domainSourceProc;
|
||||||
labelList domainSourcePatch;
|
labelList domainSourcePatch;
|
||||||
labelList domainSourceNewNbrProc;
|
labelList domainSourceNewNbrProc;
|
||||||
|
labelList domainSourcePointMaster;
|
||||||
|
|
||||||
subsetBoundaryData
|
subsetCouplingData
|
||||||
(
|
(
|
||||||
mesh_, // new mesh
|
mesh_, // new mesh
|
||||||
|
subMap().pointMap(), // from new to original mesh
|
||||||
subMap().faceMap(), // from new to original mesh
|
subMap().faceMap(), // from new to original mesh
|
||||||
subMap().cellMap(),
|
subMap().cellMap(),
|
||||||
|
|
||||||
@ -2137,17 +2272,20 @@ Foam::autoPtr<Foam::mapDistributePolyMesh> Foam::fvMeshDistribute::distribute
|
|||||||
sourceProc,
|
sourceProc,
|
||||||
sourcePatch,
|
sourcePatch,
|
||||||
sourceNewNbrProc,
|
sourceNewNbrProc,
|
||||||
|
sourcePointMaster,
|
||||||
|
|
||||||
domainSourceFace,
|
domainSourceFace,
|
||||||
domainSourceProc,
|
domainSourceProc,
|
||||||
domainSourcePatch,
|
domainSourcePatch,
|
||||||
domainSourceNewNbrProc
|
domainSourceNewNbrProc,
|
||||||
|
domainSourcePointMaster
|
||||||
);
|
);
|
||||||
|
|
||||||
sourceFace.transfer(domainSourceFace);
|
sourceFace.transfer(domainSourceFace);
|
||||||
sourceProc.transfer(domainSourceProc);
|
sourceProc.transfer(domainSourceProc);
|
||||||
sourcePatch.transfer(domainSourcePatch);
|
sourcePatch.transfer(domainSourcePatch);
|
||||||
sourceNewNbrProc.transfer(domainSourceNewNbrProc);
|
sourceNewNbrProc.transfer(domainSourceNewNbrProc);
|
||||||
|
sourcePointMaster.transfer(domainSourcePointMaster);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -2205,6 +2343,7 @@ Foam::autoPtr<Foam::mapDistributePolyMesh> Foam::fvMeshDistribute::distribute
|
|||||||
labelList domainSourceProc;
|
labelList domainSourceProc;
|
||||||
labelList domainSourcePatch;
|
labelList domainSourcePatch;
|
||||||
labelList domainSourceNewNbrProc;
|
labelList domainSourceNewNbrProc;
|
||||||
|
labelList domainSourcePointMaster;
|
||||||
|
|
||||||
autoPtr<fvMesh> domainMeshPtr;
|
autoPtr<fvMesh> domainMeshPtr;
|
||||||
|
|
||||||
@ -2241,6 +2380,7 @@ Foam::autoPtr<Foam::mapDistributePolyMesh> Foam::fvMeshDistribute::distribute
|
|||||||
domainSourceProc,
|
domainSourceProc,
|
||||||
domainSourcePatch,
|
domainSourcePatch,
|
||||||
domainSourceNewNbrProc,
|
domainSourceNewNbrProc,
|
||||||
|
domainSourcePointMaster,
|
||||||
str
|
str
|
||||||
);
|
);
|
||||||
fvMesh& domainMesh = domainMeshPtr();
|
fvMesh& domainMesh = domainMeshPtr();
|
||||||
@ -2508,6 +2648,15 @@ Foam::autoPtr<Foam::mapDistributePolyMesh> Foam::fvMeshDistribute::distribute
|
|||||||
domainMesh.nInternalFaces(),
|
domainMesh.nInternalFaces(),
|
||||||
domainSourceNewNbrProc
|
domainSourceNewNbrProc
|
||||||
);
|
);
|
||||||
|
// Update pointMaster data
|
||||||
|
sourcePointMaster = mapPointData
|
||||||
|
(
|
||||||
|
mesh_,
|
||||||
|
map(),
|
||||||
|
sourcePointMaster,
|
||||||
|
domainSourcePointMaster
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
// Update all addressing so xxProcAddressing points to correct
|
// Update all addressing so xxProcAddressing points to correct
|
||||||
// item in masterMesh.
|
// item in masterMesh.
|
||||||
@ -2621,6 +2770,10 @@ Foam::autoPtr<Foam::mapDistributePolyMesh> Foam::fvMeshDistribute::distribute
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// See if any originally shared points need to be merged. Note: does
|
||||||
|
// parallel comms. After this points and edges should again be consistent.
|
||||||
|
mergeSharedPoints(sourcePointMaster, constructPointMap);
|
||||||
|
|
||||||
|
|
||||||
// Add processorPatches
|
// Add processorPatches
|
||||||
// ~~~~~~~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~~~~~~~
|
||||||
@ -2650,16 +2803,8 @@ Foam::autoPtr<Foam::mapDistributePolyMesh> Foam::fvMeshDistribute::distribute
|
|||||||
|
|
||||||
// Change patches. Since this might change ordering of coupled faces
|
// Change patches. Since this might change ordering of coupled faces
|
||||||
// we also need to adapt our constructMaps.
|
// we also need to adapt our constructMaps.
|
||||||
// NOTE: there is one very particular problem with this structure.
|
|
||||||
// We first create the processor patches and use these to merge out
|
|
||||||
// shared points (see mergeSharedPoints below). So temporarily points
|
|
||||||
// and edges do not match!
|
|
||||||
repatch(newPatchID, constructFaceMap);
|
repatch(newPatchID, constructFaceMap);
|
||||||
|
|
||||||
// See if any geometrically shared points need to be merged. Note: does
|
|
||||||
// parallel comms. After this points and edges should again be consistent.
|
|
||||||
mergeSharedPoints(constructPointMap);
|
|
||||||
|
|
||||||
// Bit of hack: processorFvPatchField does not get reset since created
|
// Bit of hack: processorFvPatchField does not get reset since created
|
||||||
// from nothing so explicitly reset.
|
// from nothing so explicitly reset.
|
||||||
initPatchFields<volScalarField, processorFvPatchField<scalar>>
|
initPatchFields<volScalarField, processorFvPatchField<scalar>>
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
========= |
|
========= |
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
\\ / O peration |
|
\\ / O peration |
|
||||||
\\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation
|
\\ / A nd | Copyright (C) 2011-2018 OpenFOAM Foundation
|
||||||
\\/ M anipulation | Copyright (C) 2016 OpenCFD Ltd.
|
\\/ M anipulation | Copyright (C) 2016 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
@ -163,11 +163,11 @@ class fvMeshDistribute
|
|||||||
labelListList& constructFaceMap
|
labelListList& constructFaceMap
|
||||||
);
|
);
|
||||||
|
|
||||||
//- Merge any shared points that are geometrically shared. Needs
|
//- Merge any local points that were remotely coupled.
|
||||||
// parallel valid mesh - uses globalMeshData.
|
|
||||||
// constructPointMap is adapted for the new point labels.
|
// constructPointMap is adapted for the new point labels.
|
||||||
autoPtr<mapPolyMesh> mergeSharedPoints
|
autoPtr<mapPolyMesh> mergeSharedPoints
|
||||||
(
|
(
|
||||||
|
const labelList& pointToGlobalMaster,
|
||||||
labelListList& constructPointMap
|
labelListList& constructPointMap
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -175,19 +175,21 @@ class fvMeshDistribute
|
|||||||
// Coupling information
|
// Coupling information
|
||||||
|
|
||||||
//- Construct the local environment of all boundary faces.
|
//- Construct the local environment of all boundary faces.
|
||||||
void getNeighbourData
|
void getCouplingData
|
||||||
(
|
(
|
||||||
const labelList& distribution,
|
const labelList& distribution,
|
||||||
labelList& sourceFace,
|
labelList& sourceFace,
|
||||||
labelList& sourceProc,
|
labelList& sourceProc,
|
||||||
labelList& sourcePatch,
|
labelList& sourcePatch,
|
||||||
labelList& sourceNewProc
|
labelList& sourceNewProc,
|
||||||
|
labelList& sourcePointMaster
|
||||||
) const;
|
) const;
|
||||||
|
|
||||||
// Subset the neighbourCell/neighbourProc fields
|
// Subset the neighbourCell/neighbourProc fields
|
||||||
static void subsetBoundaryData
|
static void subsetCouplingData
|
||||||
(
|
(
|
||||||
const fvMesh& mesh,
|
const fvMesh& mesh,
|
||||||
|
const labelList& pointMap,
|
||||||
const labelList& faceMap,
|
const labelList& faceMap,
|
||||||
const labelList& cellMap,
|
const labelList& cellMap,
|
||||||
|
|
||||||
@ -200,11 +202,13 @@ class fvMeshDistribute
|
|||||||
const labelList& sourceProc,
|
const labelList& sourceProc,
|
||||||
const labelList& sourcePatch,
|
const labelList& sourcePatch,
|
||||||
const labelList& sourceNewProc,
|
const labelList& sourceNewProc,
|
||||||
|
const labelList& sourcePointMaster,
|
||||||
|
|
||||||
labelList& subFace,
|
labelList& subFace,
|
||||||
labelList& subProc,
|
labelList& subProc,
|
||||||
labelList& subPatch,
|
labelList& subPatch,
|
||||||
labelList& subNewProc
|
labelList& subNewProc,
|
||||||
|
labelList& subPointMaster
|
||||||
);
|
);
|
||||||
|
|
||||||
//- Find cells on mesh whose faceID/procID match the neighbour
|
//- Find cells on mesh whose faceID/procID match the neighbour
|
||||||
@ -237,6 +241,14 @@ class fvMeshDistribute
|
|||||||
const labelList& boundaryData1 // added mesh
|
const labelList& boundaryData1 // added mesh
|
||||||
);
|
);
|
||||||
|
|
||||||
|
//- Map point data to new mesh (resulting from adding two meshes)
|
||||||
|
static labelList mapPointData
|
||||||
|
(
|
||||||
|
const primitiveMesh& mesh, // mesh after adding
|
||||||
|
const mapAddedPolyMesh& map,
|
||||||
|
const labelList& boundaryData0, // on mesh before adding
|
||||||
|
const labelList& boundaryData1 // on added mesh
|
||||||
|
);
|
||||||
|
|
||||||
// Other
|
// Other
|
||||||
|
|
||||||
@ -276,6 +288,7 @@ class fvMeshDistribute
|
|||||||
const labelList& sourceProc,
|
const labelList& sourceProc,
|
||||||
const labelList& sourcePatch,
|
const labelList& sourcePatch,
|
||||||
const labelList& sourceNewProc,
|
const labelList& sourceNewProc,
|
||||||
|
const labelList& sourcePointMaster,
|
||||||
Ostream& toDomain
|
Ostream& toDomain
|
||||||
);
|
);
|
||||||
//- Send subset of fields
|
//- Send subset of fields
|
||||||
@ -300,6 +313,7 @@ class fvMeshDistribute
|
|||||||
labelList& domainSourceProc,
|
labelList& domainSourceProc,
|
||||||
labelList& domainSourcePatch,
|
labelList& domainSourcePatch,
|
||||||
labelList& domainSourceNewProc,
|
labelList& domainSourceNewProc,
|
||||||
|
labelList& domainSourcePointMaster,
|
||||||
Istream& fromNbr
|
Istream& fromNbr
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@ -154,6 +154,7 @@ $(derivedFvPatchFields)/flowRateInletVelocity/flowRateInletVelocityFvPatchVector
|
|||||||
$(derivedFvPatchFields)/flowRateOutletVelocity/flowRateOutletVelocityFvPatchVectorField.C
|
$(derivedFvPatchFields)/flowRateOutletVelocity/flowRateOutletVelocityFvPatchVectorField.C
|
||||||
$(derivedFvPatchFields)/fluxCorrectedVelocity/fluxCorrectedVelocityFvPatchVectorField.C
|
$(derivedFvPatchFields)/fluxCorrectedVelocity/fluxCorrectedVelocityFvPatchVectorField.C
|
||||||
$(derivedFvPatchFields)/freestream/freestreamFvPatchFields.C
|
$(derivedFvPatchFields)/freestream/freestreamFvPatchFields.C
|
||||||
|
$(derivedFvPatchFields)/freestreamVelocity/freestreamVelocityFvPatchVectorField.C
|
||||||
$(derivedFvPatchFields)/freestreamPressure/freestreamPressureFvPatchScalarField.C
|
$(derivedFvPatchFields)/freestreamPressure/freestreamPressureFvPatchScalarField.C
|
||||||
$(derivedFvPatchFields)/inletOutlet/inletOutletFvPatchFields.C
|
$(derivedFvPatchFields)/inletOutlet/inletOutletFvPatchFields.C
|
||||||
$(derivedFvPatchFields)/inletOutletTotalTemperature/inletOutletTotalTemperatureFvPatchScalarField.C
|
$(derivedFvPatchFields)/inletOutletTotalTemperature/inletOutletTotalTemperatureFvPatchScalarField.C
|
||||||
@ -168,6 +169,7 @@ $(derivedFvPatchFields)/noSlip/noSlipFvPatchVectorField.C
|
|||||||
$(derivedFvPatchFields)/movingWallVelocity/movingWallVelocityFvPatchVectorField.C
|
$(derivedFvPatchFields)/movingWallVelocity/movingWallVelocityFvPatchVectorField.C
|
||||||
$(derivedFvPatchFields)/outletInlet/outletInletFvPatchFields.C
|
$(derivedFvPatchFields)/outletInlet/outletInletFvPatchFields.C
|
||||||
$(derivedFvPatchFields)/outletMappedUniformInlet/outletMappedUniformInletFvPatchFields.C
|
$(derivedFvPatchFields)/outletMappedUniformInlet/outletMappedUniformInletFvPatchFields.C
|
||||||
|
$(derivedFvPatchFields)/fixedMeanOutletInlet/fixedMeanOutletInletFvPatchFields.C
|
||||||
$(derivedFvPatchFields)/partialSlip/partialSlipFvPatchFields.C
|
$(derivedFvPatchFields)/partialSlip/partialSlipFvPatchFields.C
|
||||||
$(derivedFvPatchFields)/phaseHydrostaticPressure/phaseHydrostaticPressureFvPatchScalarField.C
|
$(derivedFvPatchFields)/phaseHydrostaticPressure/phaseHydrostaticPressureFvPatchScalarField.C
|
||||||
$(derivedFvPatchFields)/pressureDirectedInletOutletVelocity/pressureDirectedInletOutletVelocityFvPatchVectorField.C
|
$(derivedFvPatchFields)/pressureDirectedInletOutletVelocity/pressureDirectedInletOutletVelocityFvPatchVectorField.C
|
||||||
|
|||||||
@ -0,0 +1,148 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | Copyright (C) 2018 OpenFOAM Foundation
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
License
|
||||||
|
This file is part of OpenFOAM.
|
||||||
|
|
||||||
|
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#include "fixedMeanOutletInletFvPatchField.H"
|
||||||
|
#include "volFields.H"
|
||||||
|
#include "surfaceFields.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
template<class Type>
|
||||||
|
Foam::fixedMeanOutletInletFvPatchField<Type>::fixedMeanOutletInletFvPatchField
|
||||||
|
(
|
||||||
|
const fvPatch& p,
|
||||||
|
const DimensionedField<Type, volMesh>& iF
|
||||||
|
)
|
||||||
|
:
|
||||||
|
outletInletFvPatchField<Type>(p, iF),
|
||||||
|
meanValue_()
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
template<class Type>
|
||||||
|
Foam::fixedMeanOutletInletFvPatchField<Type>::fixedMeanOutletInletFvPatchField
|
||||||
|
(
|
||||||
|
const fvPatch& p,
|
||||||
|
const DimensionedField<Type, volMesh>& iF,
|
||||||
|
const dictionary& dict
|
||||||
|
)
|
||||||
|
:
|
||||||
|
outletInletFvPatchField<Type>(p, iF),
|
||||||
|
meanValue_(Function1<Type>::New("meanValue", dict))
|
||||||
|
{
|
||||||
|
this->phiName_ = dict.lookupOrDefault<word>("phi", "phi");
|
||||||
|
|
||||||
|
fvPatchField<Type>::operator=
|
||||||
|
(
|
||||||
|
Field<Type>("value", dict, p.size())
|
||||||
|
);
|
||||||
|
|
||||||
|
this->refValue() = *this;
|
||||||
|
this->refGrad() = Zero;
|
||||||
|
this->valueFraction() = 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class Type>
|
||||||
|
Foam::fixedMeanOutletInletFvPatchField<Type>::fixedMeanOutletInletFvPatchField
|
||||||
|
(
|
||||||
|
const fixedMeanOutletInletFvPatchField<Type>& ptf,
|
||||||
|
const fvPatch& p,
|
||||||
|
const DimensionedField<Type, volMesh>& iF,
|
||||||
|
const fvPatchFieldMapper& mapper
|
||||||
|
)
|
||||||
|
:
|
||||||
|
outletInletFvPatchField<Type>(ptf, p, iF, mapper),
|
||||||
|
meanValue_(ptf.meanValue_.clone())
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
template<class Type>
|
||||||
|
Foam::fixedMeanOutletInletFvPatchField<Type>::fixedMeanOutletInletFvPatchField
|
||||||
|
(
|
||||||
|
const fixedMeanOutletInletFvPatchField<Type>& ptf
|
||||||
|
)
|
||||||
|
:
|
||||||
|
outletInletFvPatchField<Type>(ptf),
|
||||||
|
meanValue_(ptf.meanValue_.clone())
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
template<class Type>
|
||||||
|
Foam::fixedMeanOutletInletFvPatchField<Type>::fixedMeanOutletInletFvPatchField
|
||||||
|
(
|
||||||
|
const fixedMeanOutletInletFvPatchField<Type>& ptf,
|
||||||
|
const DimensionedField<Type, volMesh>& iF
|
||||||
|
)
|
||||||
|
:
|
||||||
|
outletInletFvPatchField<Type>(ptf, iF),
|
||||||
|
meanValue_(ptf.meanValue_.clone())
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
template<class Type>
|
||||||
|
void Foam::fixedMeanOutletInletFvPatchField<Type>::updateCoeffs()
|
||||||
|
{
|
||||||
|
if (this->updated())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const scalar t = this->db().time().timeOutputValue();
|
||||||
|
Type meanValue = meanValue_->value(t);
|
||||||
|
|
||||||
|
Field<Type> newValues(this->patchInternalField());
|
||||||
|
|
||||||
|
Type meanValuePsi =
|
||||||
|
gSum(this->patch().magSf()*newValues)
|
||||||
|
/gSum(this->patch().magSf());
|
||||||
|
|
||||||
|
if (mag(meanValue) > SMALL && mag(meanValuePsi)/mag(meanValue) > 0.5)
|
||||||
|
{
|
||||||
|
newValues *= mag(meanValue)/mag(meanValuePsi);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
newValues += (meanValue - meanValuePsi);
|
||||||
|
}
|
||||||
|
|
||||||
|
this->refValue() = newValues;
|
||||||
|
|
||||||
|
outletInletFvPatchField<Type>::updateCoeffs();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class Type>
|
||||||
|
void Foam::fixedMeanOutletInletFvPatchField<Type>::write(Ostream& os) const
|
||||||
|
{
|
||||||
|
fvPatchField<Type>::write(os);
|
||||||
|
meanValue_->writeData(os);
|
||||||
|
this->writeEntry("value", os);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -0,0 +1,185 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | Copyright (C) 2018 OpenFOAM Foundation
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
License
|
||||||
|
This file is part of OpenFOAM.
|
||||||
|
|
||||||
|
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
Class
|
||||||
|
Foam::fixedMeanOutletInletFvPatchField
|
||||||
|
|
||||||
|
Group
|
||||||
|
grpInletBoundaryConditions
|
||||||
|
|
||||||
|
Description
|
||||||
|
This boundary condition extrapolates field to the patch using the near-cell
|
||||||
|
values and adjusts the distribution to match the specified, optionally
|
||||||
|
time-varying, mean value. This extrapolated field is applied as a
|
||||||
|
fixedValue for outflow faces but zeroGradient is applied to inflow faces.
|
||||||
|
|
||||||
|
This boundary condition can be applied to pressure when inletOutlet is
|
||||||
|
applied to the velocity so that a zeroGradient condition is applied to the
|
||||||
|
pressure at inflow faces where the velocity is specified to avoid an
|
||||||
|
unphysical over-specification of the set of boundary conditions.
|
||||||
|
|
||||||
|
Usage
|
||||||
|
\table
|
||||||
|
Property | Description | Required | Default value
|
||||||
|
meanValue | mean value Function1 | yes |
|
||||||
|
phi | Flux field name | no | phi
|
||||||
|
\endtable
|
||||||
|
|
||||||
|
Example of the boundary condition specification:
|
||||||
|
\verbatim
|
||||||
|
<patchName>
|
||||||
|
{
|
||||||
|
type fixedMeanOutletInlet;
|
||||||
|
meanValue 1.0;
|
||||||
|
}
|
||||||
|
\endverbatim
|
||||||
|
|
||||||
|
See also
|
||||||
|
Foam::fixedMeanFvPatchField
|
||||||
|
Foam::outletInletFvPatchField
|
||||||
|
Foam::Function1Types
|
||||||
|
|
||||||
|
SourceFiles
|
||||||
|
fixedMeanOutletInletFvPatchField.C
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef fixedMeanOutletInletFvPatchField_H
|
||||||
|
#define fixedMeanOutletInletFvPatchField_H
|
||||||
|
|
||||||
|
#include "outletInletFvPatchFields.H"
|
||||||
|
#include "Function1.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
Class fixedMeanOutletInletFvPatchField Declaration
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
template<class Type>
|
||||||
|
class fixedMeanOutletInletFvPatchField
|
||||||
|
:
|
||||||
|
public outletInletFvPatchField<Type>
|
||||||
|
{
|
||||||
|
// Private data
|
||||||
|
|
||||||
|
//- MeanValue value the field is adjusted to maintain
|
||||||
|
autoPtr<Function1<Type>> meanValue_;
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
//- Runtime type information
|
||||||
|
TypeName("fixedMeanOutletInlet");
|
||||||
|
|
||||||
|
|
||||||
|
// Constructors
|
||||||
|
|
||||||
|
//- Construct from patch and internal field
|
||||||
|
fixedMeanOutletInletFvPatchField
|
||||||
|
(
|
||||||
|
const fvPatch&,
|
||||||
|
const DimensionedField<Type, volMesh>&
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Construct from patch, internal field and dictionary
|
||||||
|
fixedMeanOutletInletFvPatchField
|
||||||
|
(
|
||||||
|
const fvPatch&,
|
||||||
|
const DimensionedField<Type, volMesh>&,
|
||||||
|
const dictionary&
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Construct by mapping given fixedMeanOutletInletFvPatchField
|
||||||
|
// onto a new patch
|
||||||
|
fixedMeanOutletInletFvPatchField
|
||||||
|
(
|
||||||
|
const fixedMeanOutletInletFvPatchField<Type>&,
|
||||||
|
const fvPatch&,
|
||||||
|
const DimensionedField<Type, volMesh>&,
|
||||||
|
const fvPatchFieldMapper&
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Construct as copy
|
||||||
|
fixedMeanOutletInletFvPatchField
|
||||||
|
(
|
||||||
|
const fixedMeanOutletInletFvPatchField<Type>&
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Construct and return a clone
|
||||||
|
virtual tmp<fvPatchField<Type>> clone() const
|
||||||
|
{
|
||||||
|
return tmp<fvPatchField<Type>>
|
||||||
|
(
|
||||||
|
new fixedMeanOutletInletFvPatchField<Type>(*this)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
//- Construct as copy setting internal field reference
|
||||||
|
fixedMeanOutletInletFvPatchField
|
||||||
|
(
|
||||||
|
const fixedMeanOutletInletFvPatchField<Type>&,
|
||||||
|
const DimensionedField<Type, volMesh>&
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Construct and return a clone setting internal field reference
|
||||||
|
virtual tmp<fvPatchField<Type>> clone
|
||||||
|
(
|
||||||
|
const DimensionedField<Type, volMesh>& iF
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
return tmp<fvPatchField<Type>>
|
||||||
|
(
|
||||||
|
new fixedMeanOutletInletFvPatchField<Type>(*this, iF)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Member functions
|
||||||
|
|
||||||
|
//- Update the coefficients associated with the patch field
|
||||||
|
virtual void updateCoeffs();
|
||||||
|
|
||||||
|
//- Write
|
||||||
|
virtual void write(Ostream&) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
} // End namespace Foam
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
#ifdef NoRepository
|
||||||
|
#include "fixedMeanOutletInletFvPatchField.C"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -0,0 +1,43 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | Copyright (C) 2018 OpenFOAM Foundation
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
License
|
||||||
|
This file is part of OpenFOAM.
|
||||||
|
|
||||||
|
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#include "fixedMeanOutletInletFvPatchFields.H"
|
||||||
|
#include "volMesh.H"
|
||||||
|
#include "addToRunTimeSelectionTable.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
makePatchFields(fixedMeanOutletInlet);
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
} // End namespace Foam
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -0,0 +1,49 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | Copyright (C) 2018 OpenFOAM Foundation
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
License
|
||||||
|
This file is part of OpenFOAM.
|
||||||
|
|
||||||
|
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef fixedMeanOutletInletFvPatchFields_H
|
||||||
|
#define fixedMeanOutletInletFvPatchFields_H
|
||||||
|
|
||||||
|
#include "fixedMeanOutletInletFvPatchField.H"
|
||||||
|
#include "fieldTypes.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
makePatchTypeFieldTypedefs(fixedMeanOutletInlet);
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
} // End namespace Foam
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -0,0 +1,50 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | Copyright (C) 2018 OpenFOAM Foundation
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
License
|
||||||
|
This file is part of OpenFOAM.
|
||||||
|
|
||||||
|
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef fixedMeanOutletInletFvPatchFieldsFwd_H
|
||||||
|
#define fixedMeanOutletInletFvPatchFieldsFwd_H
|
||||||
|
|
||||||
|
#include "fieldTypes.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
template<class Type> class fixedMeanOutletInletFvPatchField;
|
||||||
|
|
||||||
|
makePatchTypeFieldTypedefs(fixedMeanOutletInlet);
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
} // End namespace Foam
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -2,7 +2,7 @@
|
|||||||
========= |
|
========= |
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
\\ / O peration |
|
\\ / O peration |
|
||||||
\\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation
|
\\ / A nd | Copyright (C) 2011-2018 OpenFOAM Foundation
|
||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
@ -45,7 +45,7 @@ Usage
|
|||||||
<patchName>
|
<patchName>
|
||||||
{
|
{
|
||||||
type freestream;
|
type freestream;
|
||||||
phi phi;
|
freestreamValue uniform (300 0 0);
|
||||||
}
|
}
|
||||||
\endverbatim
|
\endverbatim
|
||||||
|
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
========= |
|
========= |
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
\\ / O peration |
|
\\ / O peration |
|
||||||
\\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation
|
\\ / A nd | Copyright (C) 2011-2018 OpenFOAM Foundation
|
||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
@ -24,10 +24,7 @@ License
|
|||||||
\*---------------------------------------------------------------------------*/
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
#include "freestreamPressureFvPatchScalarField.H"
|
#include "freestreamPressureFvPatchScalarField.H"
|
||||||
#include "freestreamFvPatchFields.H"
|
|
||||||
#include "fvPatchFieldMapper.H"
|
|
||||||
#include "volFields.H"
|
#include "volFields.H"
|
||||||
#include "surfaceFields.H"
|
|
||||||
#include "addToRunTimeSelectionTable.H"
|
#include "addToRunTimeSelectionTable.H"
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||||
@ -39,10 +36,8 @@ freestreamPressureFvPatchScalarField
|
|||||||
const DimensionedField<scalar, volMesh>& iF
|
const DimensionedField<scalar, volMesh>& iF
|
||||||
)
|
)
|
||||||
:
|
:
|
||||||
zeroGradientFvPatchScalarField(p, iF),
|
mixedFvPatchScalarField(p, iF),
|
||||||
UName_("U"),
|
UName_("U")
|
||||||
phiName_("phi"),
|
|
||||||
rhoName_("rho")
|
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
|
||||||
@ -54,11 +49,26 @@ freestreamPressureFvPatchScalarField
|
|||||||
const dictionary& dict
|
const dictionary& dict
|
||||||
)
|
)
|
||||||
:
|
:
|
||||||
zeroGradientFvPatchScalarField(p, iF, dict),
|
mixedFvPatchScalarField(p, iF),
|
||||||
UName_(dict.lookupOrDefault<word>("U", "U")),
|
UName_(dict.lookupOrDefault<word>("U", "U"))
|
||||||
phiName_(dict.lookupOrDefault<word>("phi", "phi")),
|
{
|
||||||
rhoName_(dict.lookupOrDefault<word>("rho", "rho"))
|
freestreamValue() = scalarField("freestreamValue", dict, p.size());
|
||||||
{}
|
|
||||||
|
if (dict.found("value"))
|
||||||
|
{
|
||||||
|
fvPatchScalarField::operator=
|
||||||
|
(
|
||||||
|
scalarField("value", dict, p.size())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fvPatchScalarField::operator=(freestreamValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
refGrad() = Zero;
|
||||||
|
valueFraction() = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
Foam::freestreamPressureFvPatchScalarField::
|
Foam::freestreamPressureFvPatchScalarField::
|
||||||
@ -70,10 +80,8 @@ freestreamPressureFvPatchScalarField
|
|||||||
const fvPatchFieldMapper& mapper
|
const fvPatchFieldMapper& mapper
|
||||||
)
|
)
|
||||||
:
|
:
|
||||||
zeroGradientFvPatchScalarField(ptf, p, iF, mapper),
|
mixedFvPatchScalarField(ptf, p, iF, mapper),
|
||||||
UName_(ptf.UName_),
|
UName_(ptf.UName_)
|
||||||
phiName_(ptf.phiName_),
|
|
||||||
rhoName_(ptf.rhoName_)
|
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
|
||||||
@ -83,10 +91,8 @@ freestreamPressureFvPatchScalarField
|
|||||||
const freestreamPressureFvPatchScalarField& wbppsf
|
const freestreamPressureFvPatchScalarField& wbppsf
|
||||||
)
|
)
|
||||||
:
|
:
|
||||||
zeroGradientFvPatchScalarField(wbppsf),
|
mixedFvPatchScalarField(wbppsf),
|
||||||
UName_(wbppsf.UName_),
|
UName_(wbppsf.UName_)
|
||||||
phiName_(wbppsf.phiName_),
|
|
||||||
rhoName_(wbppsf.rhoName_)
|
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
|
||||||
@ -97,10 +103,8 @@ freestreamPressureFvPatchScalarField
|
|||||||
const DimensionedField<scalar, volMesh>& iF
|
const DimensionedField<scalar, volMesh>& iF
|
||||||
)
|
)
|
||||||
:
|
:
|
||||||
zeroGradientFvPatchScalarField(wbppsf, iF),
|
mixedFvPatchScalarField(wbppsf, iF),
|
||||||
UName_(wbppsf.UName_),
|
UName_(wbppsf.UName_)
|
||||||
phiName_(wbppsf.phiName_),
|
|
||||||
rhoName_(wbppsf.rhoName_)
|
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
|
||||||
@ -113,43 +117,15 @@ void Foam::freestreamPressureFvPatchScalarField::updateCoeffs()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const freestreamFvPatchVectorField& Up =
|
const Field<vector>& Up =
|
||||||
refCast<const freestreamFvPatchVectorField>
|
patch().template lookupPatchField<volVectorField, vector>
|
||||||
(
|
(
|
||||||
patch().lookupPatchField<volVectorField, vector>(UName_)
|
UName_
|
||||||
);
|
);
|
||||||
|
|
||||||
const surfaceScalarField& phi =
|
valueFraction() = 0.5 + 0.5*(Up & patch().nf())/mag(Up);
|
||||||
db().lookupObject<surfaceScalarField>(phiName_);
|
|
||||||
|
|
||||||
fvsPatchField<scalar>& phip =
|
mixedFvPatchField<scalar>::updateCoeffs();
|
||||||
const_cast<fvsPatchField<scalar>&>
|
|
||||||
(
|
|
||||||
patch().patchField<surfaceScalarField, scalar>(phi)
|
|
||||||
);
|
|
||||||
|
|
||||||
if (phi.dimensions() == dimVelocity*dimArea)
|
|
||||||
{
|
|
||||||
phip = patch().Sf() & Up.freestreamValue();
|
|
||||||
}
|
|
||||||
else if (phi.dimensions() == dimDensity*dimVelocity*dimArea)
|
|
||||||
{
|
|
||||||
const fvPatchField<scalar>& rhop =
|
|
||||||
patch().lookupPatchField<volScalarField, scalar>(rhoName_);
|
|
||||||
|
|
||||||
phip = rhop*(patch().Sf() & Up.freestreamValue());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
FatalErrorInFunction
|
|
||||||
<< "dimensions of phi are not correct"
|
|
||||||
<< "\n on patch " << this->patch().name()
|
|
||||||
<< " of field " << this->internalField().name()
|
|
||||||
<< " in file " << this->internalField().objectPath()
|
|
||||||
<< exit(FatalError);
|
|
||||||
}
|
|
||||||
|
|
||||||
zeroGradientFvPatchScalarField::updateCoeffs();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -157,8 +133,7 @@ void Foam::freestreamPressureFvPatchScalarField::write(Ostream& os) const
|
|||||||
{
|
{
|
||||||
fvPatchScalarField::write(os);
|
fvPatchScalarField::write(os);
|
||||||
os.writeEntryIfDifferent<word>("U", "U", UName_);
|
os.writeEntryIfDifferent<word>("U", "U", UName_);
|
||||||
os.writeEntryIfDifferent<word>("phi", "phi", phiName_);
|
freestreamValue().writeEntry("freestreamValue", os);
|
||||||
os.writeEntryIfDifferent<word>("rho", "rho", rhoName_);
|
|
||||||
writeEntry("value", os);
|
writeEntry("value", os);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -29,15 +29,16 @@ Group
|
|||||||
|
|
||||||
Description
|
Description
|
||||||
This boundary condition provides a free-stream condition for pressure.
|
This boundary condition provides a free-stream condition for pressure.
|
||||||
It is a zero-gradient condition that constrains the flux across the patch
|
|
||||||
based on the free-stream velocity.
|
It is an outlet-inlet condition that uses the velocity orientation to
|
||||||
|
continuously blend between zero gradient for normal inlet and fixed value
|
||||||
|
for normal outlet flow.
|
||||||
|
|
||||||
Usage
|
Usage
|
||||||
\table
|
\table
|
||||||
Property | Description | Required | Default value
|
Property | Description | Required | Default value
|
||||||
U | velocity field name | no | U
|
U | velocity field name | no | U
|
||||||
phi | flux field name | no | phi
|
freestreamValue | freestream pressure | yes |
|
||||||
rho | density field name | no | none
|
|
||||||
\endtable
|
\endtable
|
||||||
|
|
||||||
Example of the boundary condition specification:
|
Example of the boundary condition specification:
|
||||||
@ -45,14 +46,15 @@ Usage
|
|||||||
<patchName>
|
<patchName>
|
||||||
{
|
{
|
||||||
type freestreamPressure;
|
type freestreamPressure;
|
||||||
|
freestreamValue uniform 1e5;
|
||||||
}
|
}
|
||||||
\endverbatim
|
\endverbatim
|
||||||
|
|
||||||
Note
|
Note
|
||||||
This condition is designed to operate with a freestream velocity condition
|
This condition is designed to operate with a freestreamVelocity condition
|
||||||
|
|
||||||
See also
|
See also
|
||||||
Foam::zeroGradientFvPatchField
|
Foam::mixedFvPatchField
|
||||||
Foam::freestreamFvPatchField
|
Foam::freestreamFvPatchField
|
||||||
|
|
||||||
SourceFiles
|
SourceFiles
|
||||||
@ -64,7 +66,7 @@ SourceFiles
|
|||||||
#define freestreamPressureFvPatchScalarField_H
|
#define freestreamPressureFvPatchScalarField_H
|
||||||
|
|
||||||
#include "fvPatchFields.H"
|
#include "fvPatchFields.H"
|
||||||
#include "zeroGradientFvPatchFields.H"
|
#include "mixedFvPatchFields.H"
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
@ -77,20 +79,13 @@ namespace Foam
|
|||||||
|
|
||||||
class freestreamPressureFvPatchScalarField
|
class freestreamPressureFvPatchScalarField
|
||||||
:
|
:
|
||||||
public zeroGradientFvPatchScalarField
|
public mixedFvPatchScalarField
|
||||||
{
|
{
|
||||||
// Private data
|
// Private data
|
||||||
|
|
||||||
//- Name of the velocity field
|
//- Name of the velocity field
|
||||||
word UName_;
|
word UName_;
|
||||||
|
|
||||||
//- Name of the flux transporting the field
|
|
||||||
word phiName_;
|
|
||||||
|
|
||||||
//- Name of the density field used to normalise the mass flux
|
|
||||||
//- if necessary
|
|
||||||
word rhoName_;
|
|
||||||
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
@ -162,6 +157,17 @@ public:
|
|||||||
|
|
||||||
// Member functions
|
// Member functions
|
||||||
|
|
||||||
|
const scalarField& freestreamValue() const
|
||||||
|
{
|
||||||
|
return refValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
scalarField& freestreamValue()
|
||||||
|
{
|
||||||
|
return refValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Evaluation functions
|
// Evaluation functions
|
||||||
|
|
||||||
//- Update the coefficients associated with the patch field
|
//- Update the coefficients associated with the patch field
|
||||||
|
|||||||
@ -0,0 +1,136 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | Copyright (C) 2018 OpenFOAM Foundation
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
License
|
||||||
|
This file is part of OpenFOAM.
|
||||||
|
|
||||||
|
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#include "freestreamVelocityFvPatchVectorField.H"
|
||||||
|
#include "addToRunTimeSelectionTable.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Foam::freestreamVelocityFvPatchVectorField::freestreamVelocityFvPatchVectorField
|
||||||
|
(
|
||||||
|
const fvPatch& p,
|
||||||
|
const DimensionedField<vector, volMesh>& iF
|
||||||
|
)
|
||||||
|
:
|
||||||
|
mixedFvPatchVectorField(p, iF)
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::freestreamVelocityFvPatchVectorField::freestreamVelocityFvPatchVectorField
|
||||||
|
(
|
||||||
|
const fvPatch& p,
|
||||||
|
const DimensionedField<vector, volMesh>& iF,
|
||||||
|
const dictionary& dict
|
||||||
|
)
|
||||||
|
:
|
||||||
|
mixedFvPatchVectorField(p, iF)
|
||||||
|
{
|
||||||
|
freestreamValue() = vectorField("freestreamValue", dict, p.size());
|
||||||
|
|
||||||
|
if (dict.found("value"))
|
||||||
|
{
|
||||||
|
fvPatchVectorField::operator=
|
||||||
|
(
|
||||||
|
vectorField("value", dict, p.size())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fvPatchVectorField::operator=(freestreamValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
refGrad() = Zero;
|
||||||
|
valueFraction() = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::freestreamVelocityFvPatchVectorField::freestreamVelocityFvPatchVectorField
|
||||||
|
(
|
||||||
|
const freestreamVelocityFvPatchVectorField& ptf,
|
||||||
|
const fvPatch& p,
|
||||||
|
const DimensionedField<vector, volMesh>& iF,
|
||||||
|
const fvPatchFieldMapper& mapper
|
||||||
|
)
|
||||||
|
:
|
||||||
|
mixedFvPatchVectorField(ptf, p, iF, mapper)
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::freestreamVelocityFvPatchVectorField::freestreamVelocityFvPatchVectorField
|
||||||
|
(
|
||||||
|
const freestreamVelocityFvPatchVectorField& wbppsf
|
||||||
|
)
|
||||||
|
:
|
||||||
|
mixedFvPatchVectorField(wbppsf)
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::freestreamVelocityFvPatchVectorField::freestreamVelocityFvPatchVectorField
|
||||||
|
(
|
||||||
|
const freestreamVelocityFvPatchVectorField& wbppsf,
|
||||||
|
const DimensionedField<vector, volMesh>& iF
|
||||||
|
)
|
||||||
|
:
|
||||||
|
mixedFvPatchVectorField(wbppsf, iF)
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
void Foam::freestreamVelocityFvPatchVectorField::updateCoeffs()
|
||||||
|
{
|
||||||
|
if (updated())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const Field<vector>& Up = *this;
|
||||||
|
|
||||||
|
valueFraction() = 0.5 - 0.5*(Up & patch().nf())/mag(Up);
|
||||||
|
|
||||||
|
mixedFvPatchField<vector>::updateCoeffs();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::freestreamVelocityFvPatchVectorField::write(Ostream& os) const
|
||||||
|
{
|
||||||
|
fvPatchVectorField::write(os);
|
||||||
|
freestreamValue().writeEntry("freestreamValue", os);
|
||||||
|
writeEntry("value", os);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
makePatchTypeField
|
||||||
|
(
|
||||||
|
fvPatchVectorField,
|
||||||
|
freestreamVelocityFvPatchVectorField
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -0,0 +1,184 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | Copyright (C) 2018 OpenFOAM Foundation
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
License
|
||||||
|
This file is part of OpenFOAM.
|
||||||
|
|
||||||
|
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
Class
|
||||||
|
Foam::freestreamVelocityFvPatchVectorField
|
||||||
|
|
||||||
|
Group
|
||||||
|
grpInletBoundaryConditions grpOutletBoundaryConditions
|
||||||
|
|
||||||
|
Description
|
||||||
|
This boundary condition provides a free-stream condition for velocity.
|
||||||
|
|
||||||
|
It is an inlet-outlet condition that uses the velocity orientation to
|
||||||
|
continuously blend between fixed value for normal inlet and zero gradient
|
||||||
|
for normal outlet flow.
|
||||||
|
|
||||||
|
Usage
|
||||||
|
\table
|
||||||
|
Property | Description | Required | Default value
|
||||||
|
freestreamValue | freestream velocity | yes |
|
||||||
|
\endtable
|
||||||
|
|
||||||
|
Example of the boundary condition specification:
|
||||||
|
\verbatim
|
||||||
|
<patchName>
|
||||||
|
{
|
||||||
|
type freestreamVelocity;
|
||||||
|
freestreamValue uniform (300 0 0);
|
||||||
|
}
|
||||||
|
\endverbatim
|
||||||
|
|
||||||
|
Note
|
||||||
|
This condition is designed to operate with the freestreamPressure condition
|
||||||
|
|
||||||
|
See also
|
||||||
|
Foam::mixedFvPatchField
|
||||||
|
Foam::freestreamFvPatchField
|
||||||
|
|
||||||
|
SourceFiles
|
||||||
|
freestreamVelocityFvPatchVectorField.C
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef freestreamVelocityFvPatchVectorField_H
|
||||||
|
#define freestreamVelocityFvPatchVectorField_H
|
||||||
|
|
||||||
|
#include "fvPatchFields.H"
|
||||||
|
#include "mixedFvPatchFields.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
Class freestreamVelocityFvPatchVectorField Declaration
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
class freestreamVelocityFvPatchVectorField
|
||||||
|
:
|
||||||
|
public mixedFvPatchVectorField
|
||||||
|
{
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
//- Runtime type information
|
||||||
|
TypeName("freestreamVelocity");
|
||||||
|
|
||||||
|
|
||||||
|
// Constructors
|
||||||
|
|
||||||
|
//- Construct from patch and internal field
|
||||||
|
freestreamVelocityFvPatchVectorField
|
||||||
|
(
|
||||||
|
const fvPatch&,
|
||||||
|
const DimensionedField<vector, volMesh>&
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Construct from patch, internal field and dictionary
|
||||||
|
freestreamVelocityFvPatchVectorField
|
||||||
|
(
|
||||||
|
const fvPatch&,
|
||||||
|
const DimensionedField<vector, volMesh>&,
|
||||||
|
const dictionary&
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Construct by mapping given freestreamVelocityFvPatchVectorField onto
|
||||||
|
// a new patch
|
||||||
|
freestreamVelocityFvPatchVectorField
|
||||||
|
(
|
||||||
|
const freestreamVelocityFvPatchVectorField&,
|
||||||
|
const fvPatch&,
|
||||||
|
const DimensionedField<vector, volMesh>&,
|
||||||
|
const fvPatchFieldMapper&
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Construct as copy
|
||||||
|
freestreamVelocityFvPatchVectorField
|
||||||
|
(
|
||||||
|
const freestreamVelocityFvPatchVectorField&
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Construct and return a clone
|
||||||
|
virtual tmp<fvPatchVectorField> clone() const
|
||||||
|
{
|
||||||
|
return tmp<fvPatchVectorField>
|
||||||
|
(
|
||||||
|
new freestreamVelocityFvPatchVectorField(*this)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
//- Construct as copy setting internal field reference
|
||||||
|
freestreamVelocityFvPatchVectorField
|
||||||
|
(
|
||||||
|
const freestreamVelocityFvPatchVectorField&,
|
||||||
|
const DimensionedField<vector, volMesh>&
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Construct and return a clone setting internal field reference
|
||||||
|
virtual tmp<fvPatchVectorField> clone
|
||||||
|
(
|
||||||
|
const DimensionedField<vector, volMesh>& iF
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
return tmp<fvPatchVectorField>
|
||||||
|
(
|
||||||
|
new freestreamVelocityFvPatchVectorField(*this, iF)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Member functions
|
||||||
|
|
||||||
|
const vectorField& freestreamValue() const
|
||||||
|
{
|
||||||
|
return refValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
vectorField& freestreamValue()
|
||||||
|
{
|
||||||
|
return refValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Evaluation functions
|
||||||
|
|
||||||
|
//- Update the coefficients associated with the patch field
|
||||||
|
virtual void updateCoeffs();
|
||||||
|
|
||||||
|
|
||||||
|
//- Write
|
||||||
|
virtual void write(Ostream&) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
} // End namespace Foam
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -75,7 +75,7 @@ swirlFlowRateInletVelocityFvPatchVectorField
|
|||||||
dict.lookupOrDefault
|
dict.lookupOrDefault
|
||||||
(
|
(
|
||||||
"axis",
|
"axis",
|
||||||
patch().size()
|
returnReduce(patch().size(), maxOp<label>())
|
||||||
? -gSum(patch().Sf())/gSum(patch().magSf())
|
? -gSum(patch().Sf())/gSum(patch().magSf())
|
||||||
: Zero
|
: Zero
|
||||||
)
|
)
|
||||||
@ -145,48 +145,53 @@ void Foam::swirlFlowRateInletVelocityFvPatchVectorField::updateCoeffs()
|
|||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const scalar t = this->db().time().timeOutputValue();
|
|
||||||
const scalar flowRate = flowRate_->value(t);
|
|
||||||
const scalar rpm = rpm_->value(t);
|
|
||||||
|
|
||||||
const scalar totArea = gSum(patch().magSf());
|
const scalar totArea = gSum(patch().magSf());
|
||||||
const scalar avgU = -flowRate/totArea;
|
|
||||||
|
|
||||||
const vector axisHat = axis_/mag(axis_);
|
if (totArea > ROOTVSMALL && axis_ != vector(Zero))
|
||||||
|
|
||||||
// Update angular velocity - convert [rpm] to [rad/s]
|
|
||||||
tmp<vectorField> tangentialVelocity
|
|
||||||
(
|
|
||||||
axisHat ^ (rpm*constant::mathematical::pi/30.0)*(patch().Cf() - origin_)
|
|
||||||
);
|
|
||||||
|
|
||||||
tmp<vectorField> n = patch().nf();
|
|
||||||
|
|
||||||
const surfaceScalarField& phi =
|
|
||||||
db().lookupObject<surfaceScalarField>(phiName_);
|
|
||||||
|
|
||||||
if (phi.dimensions() == dimVelocity*dimArea)
|
|
||||||
{
|
{
|
||||||
// volumetric flow-rate
|
const scalar t = this->db().time().timeOutputValue();
|
||||||
operator==(tangentialVelocity + n*avgU);
|
const scalar flowRate = flowRate_->value(t);
|
||||||
}
|
const scalar rpm = rpm_->value(t);
|
||||||
else if (phi.dimensions() == dimDensity*dimVelocity*dimArea)
|
|
||||||
{
|
|
||||||
const fvPatchField<scalar>& rhop =
|
|
||||||
patch().lookupPatchField<volScalarField, scalar>(rhoName_);
|
|
||||||
|
|
||||||
// mass flow-rate
|
const scalar avgU = -flowRate/totArea;
|
||||||
operator==(tangentialVelocity + n*avgU/rhop);
|
|
||||||
}
|
const vector axisHat = axis_/mag(axis_);
|
||||||
else
|
|
||||||
{
|
// Update angular velocity - convert [rpm] to [rad/s]
|
||||||
FatalErrorInFunction
|
tmp<vectorField> tangentialVelocity
|
||||||
<< "dimensions of " << phiName_ << " are incorrect" << nl
|
(
|
||||||
<< " on patch " << this->patch().name()
|
axisHat
|
||||||
<< " of field " << this->internalField().name()
|
^(rpm*constant::mathematical::pi/30.0)
|
||||||
<< " in file " << this->internalField().objectPath()
|
*(patch().Cf() - origin_)
|
||||||
<< nl << exit(FatalError);
|
);
|
||||||
|
|
||||||
|
tmp<vectorField> n = patch().nf();
|
||||||
|
|
||||||
|
const surfaceScalarField& phi =
|
||||||
|
db().lookupObject<surfaceScalarField>(phiName_);
|
||||||
|
|
||||||
|
if (phi.dimensions() == dimVelocity*dimArea)
|
||||||
|
{
|
||||||
|
// volumetric flow-rate
|
||||||
|
operator==(tangentialVelocity + n*avgU);
|
||||||
|
}
|
||||||
|
else if (phi.dimensions() == dimDensity*dimVelocity*dimArea)
|
||||||
|
{
|
||||||
|
const fvPatchField<scalar>& rhop =
|
||||||
|
patch().lookupPatchField<volScalarField, scalar>(rhoName_);
|
||||||
|
|
||||||
|
// mass flow-rate
|
||||||
|
operator==(tangentialVelocity + n*avgU/rhop);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
FatalErrorInFunction
|
||||||
|
<< "dimensions of " << phiName_ << " are incorrect" << nl
|
||||||
|
<< " on patch " << this->patch().name()
|
||||||
|
<< " of field " << this->internalField().name()
|
||||||
|
<< " in file " << this->internalField().objectPath()
|
||||||
|
<< nl << exit(FatalError);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fixedValueFvPatchField<vector>::updateCoeffs();
|
fixedValueFvPatchField<vector>::updateCoeffs();
|
||||||
|
|||||||
@ -261,7 +261,7 @@ EulerDdtScheme<Type>::fvcDdt
|
|||||||
new GeometricField<Type, fvPatchField, volMesh>
|
new GeometricField<Type, fvPatchField, volMesh>
|
||||||
(
|
(
|
||||||
ddtIOobject,
|
ddtIOobject,
|
||||||
rDeltaT.value()*
|
rDeltaT*
|
||||||
(
|
(
|
||||||
alpha()
|
alpha()
|
||||||
*rho()
|
*rho()
|
||||||
|
|||||||
@ -0,0 +1,230 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | Copyright (C) 2018 OpenFOAM Foundation
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
License
|
||||||
|
This file is part of OpenFOAM.
|
||||||
|
|
||||||
|
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#include "cellLimitedGrad.H"
|
||||||
|
#include "gaussGrad.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
template<class Type, class Limiter>
|
||||||
|
void Foam::fv::cellLimitedGrad<Type, Limiter>::limitGradient
|
||||||
|
(
|
||||||
|
const Field<scalar>& limiter,
|
||||||
|
Field<vector>& gIf
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
gIf *= limiter;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class Type, class Limiter>
|
||||||
|
void Foam::fv::cellLimitedGrad<Type, Limiter>::limitGradient
|
||||||
|
(
|
||||||
|
const Field<vector>& limiter,
|
||||||
|
Field<tensor>& gIf
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
forAll(gIf, celli)
|
||||||
|
{
|
||||||
|
gIf[celli] = tensor
|
||||||
|
(
|
||||||
|
cmptMultiply(limiter[celli], gIf[celli].x()),
|
||||||
|
cmptMultiply(limiter[celli], gIf[celli].y()),
|
||||||
|
cmptMultiply(limiter[celli], gIf[celli].z())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class Type, class Limiter>
|
||||||
|
Foam::tmp
|
||||||
|
<
|
||||||
|
Foam::GeometricField
|
||||||
|
<
|
||||||
|
typename Foam::outerProduct<Foam::vector, Type>::type,
|
||||||
|
Foam::fvPatchField,
|
||||||
|
Foam::volMesh
|
||||||
|
>
|
||||||
|
>
|
||||||
|
Foam::fv::cellLimitedGrad<Type, Limiter>::calcGrad
|
||||||
|
(
|
||||||
|
const GeometricField<Type, fvPatchField, volMesh>& vsf,
|
||||||
|
const word& name
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
const fvMesh& mesh = vsf.mesh();
|
||||||
|
|
||||||
|
tmp
|
||||||
|
<
|
||||||
|
GeometricField
|
||||||
|
<typename outerProduct<vector, Type>::type, fvPatchField, volMesh>
|
||||||
|
> tGrad = basicGradScheme_().calcGrad(vsf, name);
|
||||||
|
|
||||||
|
if (k_ < SMALL)
|
||||||
|
{
|
||||||
|
return tGrad;
|
||||||
|
}
|
||||||
|
|
||||||
|
GeometricField
|
||||||
|
<
|
||||||
|
typename outerProduct<vector, Type>::type,
|
||||||
|
fvPatchField,
|
||||||
|
volMesh
|
||||||
|
>& g = tGrad.ref();
|
||||||
|
|
||||||
|
const labelUList& owner = mesh.owner();
|
||||||
|
const labelUList& neighbour = mesh.neighbour();
|
||||||
|
|
||||||
|
const volVectorField& C = mesh.C();
|
||||||
|
const surfaceVectorField& Cf = mesh.Cf();
|
||||||
|
|
||||||
|
Field<Type> maxVsf(vsf.primitiveField());
|
||||||
|
Field<Type> minVsf(vsf.primitiveField());
|
||||||
|
|
||||||
|
forAll(owner, facei)
|
||||||
|
{
|
||||||
|
label own = owner[facei];
|
||||||
|
label nei = neighbour[facei];
|
||||||
|
|
||||||
|
const Type& vsfOwn = vsf[own];
|
||||||
|
const Type& vsfNei = vsf[nei];
|
||||||
|
|
||||||
|
maxVsf[own] = max(maxVsf[own], vsfNei);
|
||||||
|
minVsf[own] = min(minVsf[own], vsfNei);
|
||||||
|
|
||||||
|
maxVsf[nei] = max(maxVsf[nei], vsfOwn);
|
||||||
|
minVsf[nei] = min(minVsf[nei], vsfOwn);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const typename GeometricField<Type, fvPatchField, volMesh>::Boundary& bsf =
|
||||||
|
vsf.boundaryField();
|
||||||
|
|
||||||
|
forAll(bsf, patchi)
|
||||||
|
{
|
||||||
|
const fvPatchField<Type>& psf = bsf[patchi];
|
||||||
|
const labelUList& pOwner = mesh.boundary()[patchi].faceCells();
|
||||||
|
|
||||||
|
if (psf.coupled())
|
||||||
|
{
|
||||||
|
const Field<Type> psfNei(psf.patchNeighbourField());
|
||||||
|
|
||||||
|
forAll(pOwner, pFacei)
|
||||||
|
{
|
||||||
|
label own = pOwner[pFacei];
|
||||||
|
const Type& vsfNei = psfNei[pFacei];
|
||||||
|
|
||||||
|
maxVsf[own] = max(maxVsf[own], vsfNei);
|
||||||
|
minVsf[own] = min(minVsf[own], vsfNei);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
forAll(pOwner, pFacei)
|
||||||
|
{
|
||||||
|
label own = pOwner[pFacei];
|
||||||
|
const Type& vsfNei = psf[pFacei];
|
||||||
|
|
||||||
|
maxVsf[own] = max(maxVsf[own], vsfNei);
|
||||||
|
minVsf[own] = min(minVsf[own], vsfNei);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
maxVsf -= vsf;
|
||||||
|
minVsf -= vsf;
|
||||||
|
|
||||||
|
if (k_ < 1.0)
|
||||||
|
{
|
||||||
|
const Field<Type> maxMinVsf((1.0/k_ - 1.0)*(maxVsf - minVsf));
|
||||||
|
maxVsf += maxMinVsf;
|
||||||
|
minVsf -= maxMinVsf;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Create limiter initialized to 1
|
||||||
|
// Note: the limiter is not permitted to be > 1
|
||||||
|
Field<Type> limiter(vsf.primitiveField().size(), pTraits<Type>::one);
|
||||||
|
|
||||||
|
forAll(owner, facei)
|
||||||
|
{
|
||||||
|
label own = owner[facei];
|
||||||
|
label nei = neighbour[facei];
|
||||||
|
|
||||||
|
// owner side
|
||||||
|
limitFace
|
||||||
|
(
|
||||||
|
limiter[own],
|
||||||
|
maxVsf[own],
|
||||||
|
minVsf[own],
|
||||||
|
(Cf[facei] - C[own]) & g[own]
|
||||||
|
);
|
||||||
|
|
||||||
|
// neighbour side
|
||||||
|
limitFace
|
||||||
|
(
|
||||||
|
limiter[nei],
|
||||||
|
maxVsf[nei],
|
||||||
|
minVsf[nei],
|
||||||
|
(Cf[facei] - C[nei]) & g[nei]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
forAll(bsf, patchi)
|
||||||
|
{
|
||||||
|
const labelUList& pOwner = mesh.boundary()[patchi].faceCells();
|
||||||
|
const vectorField& pCf = Cf.boundaryField()[patchi];
|
||||||
|
|
||||||
|
forAll(pOwner, pFacei)
|
||||||
|
{
|
||||||
|
label own = pOwner[pFacei];
|
||||||
|
|
||||||
|
limitFace
|
||||||
|
(
|
||||||
|
limiter[own],
|
||||||
|
maxVsf[own],
|
||||||
|
minVsf[own],
|
||||||
|
((pCf[pFacei] - C[own]) & g[own])
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fv::debug)
|
||||||
|
{
|
||||||
|
Info<< "gradient limiter for: " << vsf.name()
|
||||||
|
<< " max = " << gMax(limiter)
|
||||||
|
<< " min = " << gMin(limiter)
|
||||||
|
<< " average: " << gAverage(limiter) << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
limitGradient(limiter, g);
|
||||||
|
g.correctBoundaryConditions();
|
||||||
|
gaussGrad<Type>::correctBoundaryConditions(vsf, g);
|
||||||
|
|
||||||
|
return tGrad;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -44,14 +44,13 @@ SourceFiles
|
|||||||
#define cellLimitedGrad_H
|
#define cellLimitedGrad_H
|
||||||
|
|
||||||
#include "gradScheme.H"
|
#include "gradScheme.H"
|
||||||
|
#include "Field.H"
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
namespace Foam
|
namespace Foam
|
||||||
{
|
{
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
namespace fv
|
namespace fv
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -59,10 +58,11 @@ namespace fv
|
|||||||
Class cellLimitedGrad Declaration
|
Class cellLimitedGrad Declaration
|
||||||
\*---------------------------------------------------------------------------*/
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
template<class Type>
|
template<class Type, class Limiter>
|
||||||
class cellLimitedGrad
|
class cellLimitedGrad
|
||||||
:
|
:
|
||||||
public fv::gradScheme<Type>
|
public fv::gradScheme<Type>,
|
||||||
|
public Limiter
|
||||||
{
|
{
|
||||||
// Private Data
|
// Private Data
|
||||||
|
|
||||||
@ -74,6 +74,18 @@ class cellLimitedGrad
|
|||||||
|
|
||||||
// Private Member Functions
|
// Private Member Functions
|
||||||
|
|
||||||
|
void limitGradient
|
||||||
|
(
|
||||||
|
const Field<scalar>& limiter,
|
||||||
|
Field<vector>& gIf
|
||||||
|
) const;
|
||||||
|
|
||||||
|
void limitGradient
|
||||||
|
(
|
||||||
|
const Field<vector>& limiter,
|
||||||
|
Field<tensor>& gIf
|
||||||
|
) const;
|
||||||
|
|
||||||
//- Disallow default bitwise copy construct
|
//- Disallow default bitwise copy construct
|
||||||
cellLimitedGrad(const cellLimitedGrad&);
|
cellLimitedGrad(const cellLimitedGrad&);
|
||||||
|
|
||||||
@ -93,6 +105,7 @@ public:
|
|||||||
cellLimitedGrad(const fvMesh& mesh, Istream& schemeData)
|
cellLimitedGrad(const fvMesh& mesh, Istream& schemeData)
|
||||||
:
|
:
|
||||||
gradScheme<Type>(mesh),
|
gradScheme<Type>(mesh),
|
||||||
|
Limiter(schemeData),
|
||||||
basicGradScheme_(fv::gradScheme<Type>::New(mesh, schemeData)),
|
basicGradScheme_(fv::gradScheme<Type>::New(mesh, schemeData)),
|
||||||
k_(readScalar(schemeData))
|
k_(readScalar(schemeData))
|
||||||
{
|
{
|
||||||
@ -110,13 +123,21 @@ public:
|
|||||||
|
|
||||||
// Member Functions
|
// Member Functions
|
||||||
|
|
||||||
static inline void limitFace
|
inline void limitFaceCmpt
|
||||||
|
(
|
||||||
|
scalar& limiter,
|
||||||
|
const scalar maxDelta,
|
||||||
|
const scalar minDelta,
|
||||||
|
const scalar extrapolate
|
||||||
|
) const;
|
||||||
|
|
||||||
|
inline void limitFace
|
||||||
(
|
(
|
||||||
Type& limiter,
|
Type& limiter,
|
||||||
const Type& maxDelta,
|
const Type& maxDelta,
|
||||||
const Type& minDelta,
|
const Type& minDelta,
|
||||||
const Type& extrapolate
|
const Type& extrapolate
|
||||||
);
|
) const;
|
||||||
|
|
||||||
//- Return the gradient of the given field to the gradScheme::grad
|
//- Return the gradient of the given field to the gradScheme::grad
|
||||||
// for optional caching
|
// for optional caching
|
||||||
@ -134,73 +155,67 @@ public:
|
|||||||
|
|
||||||
// * * * * * * * * * * * * Inline Member Function * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * Inline Member Function * * * * * * * * * * * * * //
|
||||||
|
|
||||||
template<>
|
template<class Type, class Limiter>
|
||||||
inline void cellLimitedGrad<scalar>::limitFace
|
inline void cellLimitedGrad<Type, Limiter>::limitFaceCmpt
|
||||||
(
|
(
|
||||||
scalar& limiter,
|
scalar& limiter,
|
||||||
const scalar& maxDelta,
|
const scalar maxDelta,
|
||||||
const scalar& minDelta,
|
const scalar minDelta,
|
||||||
const scalar& extrapolate
|
const scalar extrapolate
|
||||||
)
|
) const
|
||||||
{
|
{
|
||||||
if (extrapolate > maxDelta + VSMALL)
|
scalar r = 1;
|
||||||
|
|
||||||
|
if (extrapolate > SMALL)
|
||||||
{
|
{
|
||||||
limiter = min(limiter, maxDelta/extrapolate);
|
r = maxDelta/extrapolate;
|
||||||
}
|
}
|
||||||
else if (extrapolate < minDelta - VSMALL)
|
else if (extrapolate < -SMALL)
|
||||||
{
|
{
|
||||||
limiter = min(limiter, minDelta/extrapolate);
|
r = minDelta/extrapolate;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
limiter = min(limiter, Limiter::limiter(r));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template<class Type>
|
template<class Type, class Limiter>
|
||||||
inline void cellLimitedGrad<Type>::limitFace
|
inline void cellLimitedGrad<Type, Limiter>::limitFace
|
||||||
(
|
(
|
||||||
Type& limiter,
|
Type& limiter,
|
||||||
const Type& maxDelta,
|
const Type& maxDelta,
|
||||||
const Type& minDelta,
|
const Type& minDelta,
|
||||||
const Type& extrapolate
|
const Type& extrapolate
|
||||||
)
|
) const
|
||||||
{
|
{
|
||||||
for (direction cmpt=0; cmpt<Type::nComponents; cmpt++)
|
for (direction cmpt=0; cmpt<pTraits<Type>::nComponents; ++cmpt)
|
||||||
{
|
{
|
||||||
cellLimitedGrad<scalar>::limitFace
|
limitFaceCmpt
|
||||||
(
|
(
|
||||||
limiter.component(cmpt),
|
setComponent(limiter, cmpt),
|
||||||
maxDelta.component(cmpt),
|
component(maxDelta, cmpt),
|
||||||
minDelta.component(cmpt),
|
component(minDelta, cmpt),
|
||||||
extrapolate.component(cmpt)
|
component(extrapolate, cmpt)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * Template Member Function Specialisations * * * * * * * * //
|
|
||||||
|
|
||||||
template<>
|
|
||||||
tmp<volVectorField> cellLimitedGrad<scalar>::calcGrad
|
|
||||||
(
|
|
||||||
const volScalarField& vsf,
|
|
||||||
const word& name
|
|
||||||
) const;
|
|
||||||
|
|
||||||
|
|
||||||
template<>
|
|
||||||
tmp<volTensorField> cellLimitedGrad<vector>::calcGrad
|
|
||||||
(
|
|
||||||
const volVectorField& vsf,
|
|
||||||
const word& name
|
|
||||||
) const;
|
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
} // End namespace fv
|
} // End namespace fv
|
||||||
|
|
||||||
|
} // End namespace Foam
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
} // End namespace Foam
|
#ifdef NoRepository
|
||||||
|
#include "cellLimitedGrad.C"
|
||||||
|
#endif
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
|||||||
@ -24,335 +24,49 @@ License
|
|||||||
\*---------------------------------------------------------------------------*/
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
#include "cellLimitedGrad.H"
|
#include "cellLimitedGrad.H"
|
||||||
#include "gaussGrad.H"
|
#include "minmodGradientLimiter.H"
|
||||||
#include "fvMesh.H"
|
#include "VenkatakrishnanGradientLimiter.H"
|
||||||
#include "volMesh.H"
|
#include "cubicGradientLimiter.H"
|
||||||
#include "surfaceMesh.H"
|
|
||||||
#include "volFields.H"
|
|
||||||
#include "fixedValueFvPatchFields.H"
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
makeFvGradScheme(cellLimitedGrad)
|
#define makeNamedFvLimitedGradTypeScheme(SS, Type, Limiter, Name) \
|
||||||
|
typedef Foam::fv::SS<Foam::Type, Foam::fv::gradientLimiters::Limiter> \
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
SS##Type##Limiter##_; \
|
||||||
|
\
|
||||||
template<>
|
defineTemplateTypeNameAndDebugWithName \
|
||||||
Foam::tmp<Foam::volVectorField>
|
( \
|
||||||
Foam::fv::cellLimitedGrad<Foam::scalar>::calcGrad
|
SS##Type##Limiter##_, \
|
||||||
(
|
Name, \
|
||||||
const volScalarField& vsf,
|
0 \
|
||||||
const word& name
|
); \
|
||||||
) const
|
\
|
||||||
{
|
namespace Foam \
|
||||||
const fvMesh& mesh = vsf.mesh();
|
{ \
|
||||||
|
namespace fv \
|
||||||
tmp<volVectorField> tGrad = basicGradScheme_().calcGrad(vsf, name);
|
{ \
|
||||||
|
gradScheme<Type>::addIstreamConstructorToTable \
|
||||||
if (k_ < SMALL)
|
< \
|
||||||
{
|
SS<Type, gradientLimiters::Limiter> \
|
||||||
return tGrad;
|
> add##SS##Type##Limiter##IstreamConstructorToTable_; \
|
||||||
|
} \
|
||||||
}
|
}
|
||||||
|
|
||||||
volVectorField& g = tGrad.ref();
|
#define makeFvLimitedGradTypeScheme(SS, Type, Limiter) \
|
||||||
|
makeNamedFvLimitedGradTypeScheme(SS##Grad, Type, Limiter, #SS"<"#Limiter">")
|
||||||
|
|
||||||
const labelUList& owner = mesh.owner();
|
#define makeFvLimitedGradScheme(SS, Limiter) \
|
||||||
const labelUList& neighbour = mesh.neighbour();
|
\
|
||||||
|
makeFvLimitedGradTypeScheme(SS, scalar, Limiter) \
|
||||||
|
makeFvLimitedGradTypeScheme(SS, vector, Limiter)
|
||||||
|
|
||||||
const volVectorField& C = mesh.C();
|
|
||||||
const surfaceVectorField& Cf = mesh.Cf();
|
|
||||||
|
|
||||||
scalarField maxVsf(vsf.primitiveField());
|
// Default limiter in minmod specified without the limiter name
|
||||||
scalarField minVsf(vsf.primitiveField());
|
// for backward compatibility
|
||||||
|
makeNamedFvLimitedGradTypeScheme(cellLimitedGrad, scalar, minmod, "cellLimited")
|
||||||
forAll(owner, facei)
|
makeNamedFvLimitedGradTypeScheme(cellLimitedGrad, vector, minmod, "cellLimited")
|
||||||
{
|
|
||||||
label own = owner[facei];
|
|
||||||
label nei = neighbour[facei];
|
|
||||||
|
|
||||||
scalar vsfOwn = vsf[own];
|
|
||||||
scalar vsfNei = vsf[nei];
|
|
||||||
|
|
||||||
maxVsf[own] = max(maxVsf[own], vsfNei);
|
|
||||||
minVsf[own] = min(minVsf[own], vsfNei);
|
|
||||||
|
|
||||||
maxVsf[nei] = max(maxVsf[nei], vsfOwn);
|
|
||||||
minVsf[nei] = min(minVsf[nei], vsfOwn);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
const volScalarField::Boundary& bsf = vsf.boundaryField();
|
|
||||||
|
|
||||||
forAll(bsf, patchi)
|
|
||||||
{
|
|
||||||
const fvPatchScalarField& psf = bsf[patchi];
|
|
||||||
|
|
||||||
const labelUList& pOwner = mesh.boundary()[patchi].faceCells();
|
|
||||||
|
|
||||||
if (psf.coupled())
|
|
||||||
{
|
|
||||||
const scalarField psfNei(psf.patchNeighbourField());
|
|
||||||
|
|
||||||
forAll(pOwner, pFacei)
|
|
||||||
{
|
|
||||||
label own = pOwner[pFacei];
|
|
||||||
scalar vsfNei = psfNei[pFacei];
|
|
||||||
|
|
||||||
maxVsf[own] = max(maxVsf[own], vsfNei);
|
|
||||||
minVsf[own] = min(minVsf[own], vsfNei);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
forAll(pOwner, pFacei)
|
|
||||||
{
|
|
||||||
label own = pOwner[pFacei];
|
|
||||||
scalar vsfNei = psf[pFacei];
|
|
||||||
|
|
||||||
maxVsf[own] = max(maxVsf[own], vsfNei);
|
|
||||||
minVsf[own] = min(minVsf[own], vsfNei);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
maxVsf -= vsf;
|
|
||||||
minVsf -= vsf;
|
|
||||||
|
|
||||||
if (k_ < 1.0)
|
|
||||||
{
|
|
||||||
const scalarField maxMinVsf((1.0/k_ - 1.0)*(maxVsf - minVsf));
|
|
||||||
maxVsf += maxMinVsf;
|
|
||||||
minVsf -= maxMinVsf;
|
|
||||||
|
|
||||||
//maxVsf *= 1.0/k_;
|
|
||||||
//minVsf *= 1.0/k_;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// create limiter
|
|
||||||
scalarField limiter(vsf.primitiveField().size(), 1.0);
|
|
||||||
|
|
||||||
forAll(owner, facei)
|
|
||||||
{
|
|
||||||
label own = owner[facei];
|
|
||||||
label nei = neighbour[facei];
|
|
||||||
|
|
||||||
// owner side
|
|
||||||
limitFace
|
|
||||||
(
|
|
||||||
limiter[own],
|
|
||||||
maxVsf[own],
|
|
||||||
minVsf[own],
|
|
||||||
(Cf[facei] - C[own]) & g[own]
|
|
||||||
);
|
|
||||||
|
|
||||||
// neighbour side
|
|
||||||
limitFace
|
|
||||||
(
|
|
||||||
limiter[nei],
|
|
||||||
maxVsf[nei],
|
|
||||||
minVsf[nei],
|
|
||||||
(Cf[facei] - C[nei]) & g[nei]
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
forAll(bsf, patchi)
|
|
||||||
{
|
|
||||||
const labelUList& pOwner = mesh.boundary()[patchi].faceCells();
|
|
||||||
const vectorField& pCf = Cf.boundaryField()[patchi];
|
|
||||||
|
|
||||||
forAll(pOwner, pFacei)
|
|
||||||
{
|
|
||||||
label own = pOwner[pFacei];
|
|
||||||
|
|
||||||
limitFace
|
|
||||||
(
|
|
||||||
limiter[own],
|
|
||||||
maxVsf[own],
|
|
||||||
minVsf[own],
|
|
||||||
(pCf[pFacei] - C[own]) & g[own]
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fv::debug)
|
|
||||||
{
|
|
||||||
Info<< "gradient limiter for: " << vsf.name()
|
|
||||||
<< " max = " << gMax(limiter)
|
|
||||||
<< " min = " << gMin(limiter)
|
|
||||||
<< " average: " << gAverage(limiter) << endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
g.primitiveFieldRef() *= limiter;
|
|
||||||
g.correctBoundaryConditions();
|
|
||||||
gaussGrad<scalar>::correctBoundaryConditions(vsf, g);
|
|
||||||
|
|
||||||
return tGrad;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template<>
|
|
||||||
Foam::tmp<Foam::volTensorField>
|
|
||||||
Foam::fv::cellLimitedGrad<Foam::vector>::calcGrad
|
|
||||||
(
|
|
||||||
const volVectorField& vsf,
|
|
||||||
const word& name
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
const fvMesh& mesh = vsf.mesh();
|
|
||||||
|
|
||||||
tmp<volTensorField> tGrad = basicGradScheme_().calcGrad(vsf, name);
|
|
||||||
|
|
||||||
if (k_ < SMALL)
|
|
||||||
{
|
|
||||||
return tGrad;
|
|
||||||
}
|
|
||||||
|
|
||||||
volTensorField& g = tGrad.ref();
|
|
||||||
|
|
||||||
const labelUList& owner = mesh.owner();
|
|
||||||
const labelUList& neighbour = mesh.neighbour();
|
|
||||||
|
|
||||||
const volVectorField& C = mesh.C();
|
|
||||||
const surfaceVectorField& Cf = mesh.Cf();
|
|
||||||
|
|
||||||
vectorField maxVsf(vsf.primitiveField());
|
|
||||||
vectorField minVsf(vsf.primitiveField());
|
|
||||||
|
|
||||||
forAll(owner, facei)
|
|
||||||
{
|
|
||||||
label own = owner[facei];
|
|
||||||
label nei = neighbour[facei];
|
|
||||||
|
|
||||||
const vector& vsfOwn = vsf[own];
|
|
||||||
const vector& vsfNei = vsf[nei];
|
|
||||||
|
|
||||||
maxVsf[own] = max(maxVsf[own], vsfNei);
|
|
||||||
minVsf[own] = min(minVsf[own], vsfNei);
|
|
||||||
|
|
||||||
maxVsf[nei] = max(maxVsf[nei], vsfOwn);
|
|
||||||
minVsf[nei] = min(minVsf[nei], vsfOwn);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
const volVectorField::Boundary& bsf = vsf.boundaryField();
|
|
||||||
|
|
||||||
forAll(bsf, patchi)
|
|
||||||
{
|
|
||||||
const fvPatchVectorField& psf = bsf[patchi];
|
|
||||||
const labelUList& pOwner = mesh.boundary()[patchi].faceCells();
|
|
||||||
|
|
||||||
if (psf.coupled())
|
|
||||||
{
|
|
||||||
const vectorField psfNei(psf.patchNeighbourField());
|
|
||||||
|
|
||||||
forAll(pOwner, pFacei)
|
|
||||||
{
|
|
||||||
label own = pOwner[pFacei];
|
|
||||||
const vector& vsfNei = psfNei[pFacei];
|
|
||||||
|
|
||||||
maxVsf[own] = max(maxVsf[own], vsfNei);
|
|
||||||
minVsf[own] = min(minVsf[own], vsfNei);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
forAll(pOwner, pFacei)
|
|
||||||
{
|
|
||||||
label own = pOwner[pFacei];
|
|
||||||
const vector& vsfNei = psf[pFacei];
|
|
||||||
|
|
||||||
maxVsf[own] = max(maxVsf[own], vsfNei);
|
|
||||||
minVsf[own] = min(minVsf[own], vsfNei);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
maxVsf -= vsf;
|
|
||||||
minVsf -= vsf;
|
|
||||||
|
|
||||||
if (k_ < 1.0)
|
|
||||||
{
|
|
||||||
const vectorField maxMinVsf((1.0/k_ - 1.0)*(maxVsf - minVsf));
|
|
||||||
maxVsf += maxMinVsf;
|
|
||||||
minVsf -= maxMinVsf;
|
|
||||||
|
|
||||||
//maxVsf *= 1.0/k_;
|
|
||||||
//minVsf *= 1.0/k_;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// create limiter
|
|
||||||
vectorField limiter(vsf.primitiveField().size(), vector::one);
|
|
||||||
|
|
||||||
forAll(owner, facei)
|
|
||||||
{
|
|
||||||
label own = owner[facei];
|
|
||||||
label nei = neighbour[facei];
|
|
||||||
|
|
||||||
// owner side
|
|
||||||
limitFace
|
|
||||||
(
|
|
||||||
limiter[own],
|
|
||||||
maxVsf[own],
|
|
||||||
minVsf[own],
|
|
||||||
(Cf[facei] - C[own]) & g[own]
|
|
||||||
);
|
|
||||||
|
|
||||||
// neighbour side
|
|
||||||
limitFace
|
|
||||||
(
|
|
||||||
limiter[nei],
|
|
||||||
maxVsf[nei],
|
|
||||||
minVsf[nei],
|
|
||||||
(Cf[facei] - C[nei]) & g[nei]
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
forAll(bsf, patchi)
|
|
||||||
{
|
|
||||||
const labelUList& pOwner = mesh.boundary()[patchi].faceCells();
|
|
||||||
const vectorField& pCf = Cf.boundaryField()[patchi];
|
|
||||||
|
|
||||||
forAll(pOwner, pFacei)
|
|
||||||
{
|
|
||||||
label own = pOwner[pFacei];
|
|
||||||
|
|
||||||
limitFace
|
|
||||||
(
|
|
||||||
limiter[own],
|
|
||||||
maxVsf[own],
|
|
||||||
minVsf[own],
|
|
||||||
((pCf[pFacei] - C[own]) & g[own])
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fv::debug)
|
|
||||||
{
|
|
||||||
Info<< "gradient limiter for: " << vsf.name()
|
|
||||||
<< " max = " << gMax(limiter)
|
|
||||||
<< " min = " << gMin(limiter)
|
|
||||||
<< " average: " << gAverage(limiter) << endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
tensorField& gIf = g.primitiveFieldRef();
|
|
||||||
|
|
||||||
forAll(gIf, celli)
|
|
||||||
{
|
|
||||||
gIf[celli] = tensor
|
|
||||||
(
|
|
||||||
cmptMultiply(limiter[celli], gIf[celli].x()),
|
|
||||||
cmptMultiply(limiter[celli], gIf[celli].y()),
|
|
||||||
cmptMultiply(limiter[celli], gIf[celli].z())
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
g.correctBoundaryConditions();
|
|
||||||
gaussGrad<vector>::correctBoundaryConditions(vsf, g);
|
|
||||||
|
|
||||||
return tGrad;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
makeFvLimitedGradScheme(cellLimited, Venkatakrishnan)
|
||||||
|
makeFvLimitedGradScheme(cellLimited, cubic)
|
||||||
|
|
||||||
// ************************************************************************* //
|
// ************************************************************************* //
|
||||||
|
|||||||
@ -0,0 +1,113 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | Copyright (C) 2018 OpenFOAM Foundation
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
License
|
||||||
|
This file is part of OpenFOAM.
|
||||||
|
|
||||||
|
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
Class
|
||||||
|
Foam::fv::gradientLimiters::Venkatakrishnan
|
||||||
|
|
||||||
|
Description
|
||||||
|
Venkatakrishnan gradient limiter
|
||||||
|
|
||||||
|
to be used with the Foam::fv::cellLimitedGrad limited gradient.
|
||||||
|
|
||||||
|
Reference:
|
||||||
|
\verbatim
|
||||||
|
Venkatakrishnan, V. (1993).
|
||||||
|
On the accuracy of limiters and convergence to steady state solutions.
|
||||||
|
In 31st Aerospace Sciences Meeting (p. 880).
|
||||||
|
\endverbatim
|
||||||
|
|
||||||
|
Example:
|
||||||
|
\verbatim
|
||||||
|
gradSchemes
|
||||||
|
{
|
||||||
|
default Gauss linear;
|
||||||
|
limited cellLimited<Venkatakrishnan> Gauss linear 1;
|
||||||
|
}
|
||||||
|
\endverbatim
|
||||||
|
|
||||||
|
Note: this limiter formally allows the limiter function to slightly exceed 1
|
||||||
|
which is generally not a good idea and can cause unboundedness. To avoid
|
||||||
|
this problem the limiter function is clipped to 1 which is likely to be
|
||||||
|
better behaved but is then not differentiable and so no longer conforms to
|
||||||
|
the basic principles of this kind of limiter function. All these issues are
|
||||||
|
resolved in a consistent and differentiable manner by the
|
||||||
|
Foam::fv::gradientLimiters::cubic limiter which is recommended in
|
||||||
|
preference to the Foam::fv::gradientLimiters::Venkatakrishnan limiter.
|
||||||
|
|
||||||
|
See also
|
||||||
|
Foam::fv::cellLimitedGrad
|
||||||
|
Foam::fv::gradientLimiters::cubic
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef VenkatakrishnanGradientLimiter_H
|
||||||
|
#define VenkatakrishnanGradientLimiter_H
|
||||||
|
|
||||||
|
#include "Istream.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
|
||||||
|
namespace fv
|
||||||
|
{
|
||||||
|
|
||||||
|
namespace gradientLimiters
|
||||||
|
{
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
class Venkatakrishnan
|
||||||
|
{
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
// Constructors
|
||||||
|
|
||||||
|
Venkatakrishnan(Istream&)
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
// Member Functions
|
||||||
|
|
||||||
|
inline scalar limiter(const scalar r) const
|
||||||
|
{
|
||||||
|
return (sqr(r) + 2*r)/(sqr(r) + r + 2);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
} // End namespace gradientLimiters
|
||||||
|
|
||||||
|
} // End namespace fv
|
||||||
|
|
||||||
|
} // End namespace Foam
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -0,0 +1,146 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | Copyright (C) 2018 OpenFOAM Foundation
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
License
|
||||||
|
This file is part of OpenFOAM.
|
||||||
|
|
||||||
|
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
Class
|
||||||
|
Foam::fv::gradientLimiters::minmod
|
||||||
|
|
||||||
|
Description
|
||||||
|
Cubic gradient limiter
|
||||||
|
|
||||||
|
to be used with the Foam::fv::cellLimitedGrad limited gradient. This
|
||||||
|
limiter function is similar to Foam::fv::gradientLimiters::Venkatakrishnan
|
||||||
|
but is a fit to obey the value and gradient constraints and avoids the
|
||||||
|
problem of the limiter exceeding 1 present in the Venkatakrishnan function.
|
||||||
|
|
||||||
|
The transition point at which the limiter function reaches 1 is an input
|
||||||
|
parameter and should be set to a value between 1 and 2 although values
|
||||||
|
larger than 2 are physical but likely to significantly reduce the accuracy
|
||||||
|
of the scheme.
|
||||||
|
|
||||||
|
Reference:
|
||||||
|
\verbatim
|
||||||
|
Michalak, K., & Ollivier-Gooch, C. (2008).
|
||||||
|
Limiters for unstructured higher-order accurate solutions
|
||||||
|
of the Euler equations.
|
||||||
|
In 46th AIAA Aerospace Sciences Meeting and Exhibit (p. 776).
|
||||||
|
\endverbatim
|
||||||
|
|
||||||
|
Example:
|
||||||
|
\verbatim
|
||||||
|
gradSchemes
|
||||||
|
{
|
||||||
|
default Gauss linear;
|
||||||
|
limited cellLimited<cubic> 1.5 Gauss linear 1;
|
||||||
|
}
|
||||||
|
\endverbatim
|
||||||
|
|
||||||
|
See also
|
||||||
|
Foam::fv::cellLimitedGrad
|
||||||
|
Foam::fv::gradientLimiters::Venkatakrishnan
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef cubicGradientLimiter_H
|
||||||
|
#define cubicGradientLimiter_H
|
||||||
|
|
||||||
|
#include "Istream.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
|
||||||
|
namespace fv
|
||||||
|
{
|
||||||
|
|
||||||
|
namespace gradientLimiters
|
||||||
|
{
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
class cubic
|
||||||
|
{
|
||||||
|
// Private Data
|
||||||
|
|
||||||
|
//- Limiter transition point at which the limiter function -> 1
|
||||||
|
// Must be > 1
|
||||||
|
const scalar rt_;
|
||||||
|
|
||||||
|
//- Coefficient of the r^3 term (evaluated from rt)
|
||||||
|
const scalar a_;
|
||||||
|
|
||||||
|
// - Coefficient of the r^2 term (evaluated from rt)
|
||||||
|
const scalar b_;
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
// Constructors
|
||||||
|
|
||||||
|
cubic(Istream& schemeData)
|
||||||
|
:
|
||||||
|
rt_(readScalar(schemeData)),
|
||||||
|
a_(2.0/sqr(rt_) - 2.0/pow3(rt_)),
|
||||||
|
b_(-(3.0/2.0)*a_*rt_)
|
||||||
|
{
|
||||||
|
if (rt_ < 1)
|
||||||
|
{
|
||||||
|
FatalIOErrorInFunction
|
||||||
|
(
|
||||||
|
schemeData
|
||||||
|
) << "coefficient = " << rt_
|
||||||
|
<< " should be > 1"
|
||||||
|
<< exit(FatalIOError);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Member Functions
|
||||||
|
|
||||||
|
inline scalar limiter(const scalar r) const
|
||||||
|
{
|
||||||
|
if (r < rt_)
|
||||||
|
{
|
||||||
|
return ((a_*r + b_)*r + 1)*r;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
} // End namespace gradientLimiters
|
||||||
|
|
||||||
|
} // End namespace fv
|
||||||
|
|
||||||
|
} // End namespace Foam
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -0,0 +1,99 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | Copyright (C) 2018 OpenFOAM Foundation
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
License
|
||||||
|
This file is part of OpenFOAM.
|
||||||
|
|
||||||
|
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
Class
|
||||||
|
Foam::fv::gradientLimiters::minmod
|
||||||
|
|
||||||
|
Description
|
||||||
|
Minmod gradient limiter
|
||||||
|
|
||||||
|
This is the default gradient limiter which clips the gradient to remove cell
|
||||||
|
to face extrapolation unboundedness. It corresponds to the original
|
||||||
|
cellLimitedGrad implementation before the addition of run-time select-able
|
||||||
|
limiter functions.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
\verbatim
|
||||||
|
gradSchemes
|
||||||
|
{
|
||||||
|
default Gauss linear;
|
||||||
|
limited cellLimited Gauss linear 1;
|
||||||
|
}
|
||||||
|
\endverbatim
|
||||||
|
|
||||||
|
See also
|
||||||
|
Foam::fv::cellLimitedGrad
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef minmodGradientLimiter_H
|
||||||
|
#define minmodGradientLimiter_H
|
||||||
|
|
||||||
|
#include "Istream.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
|
||||||
|
namespace fv
|
||||||
|
{
|
||||||
|
|
||||||
|
namespace gradientLimiters
|
||||||
|
{
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
class minmod
|
||||||
|
{
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
// Constructors
|
||||||
|
|
||||||
|
minmod(Istream&)
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
// Member Functions
|
||||||
|
|
||||||
|
inline scalar limiter(const scalar r) const
|
||||||
|
{
|
||||||
|
return min(r, 1);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
} // End namespace gradientLimiters
|
||||||
|
|
||||||
|
} // End namespace fv
|
||||||
|
|
||||||
|
} // End namespace Foam
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -61,7 +61,8 @@ Foam::functionObjects::turbulenceFields::compressibleFieldNames_
|
|||||||
{ compressibleField::cfAlphaEff, "alphaEff" },
|
{ compressibleField::cfAlphaEff, "alphaEff" },
|
||||||
{ compressibleField::cfR, "R" },
|
{ compressibleField::cfR, "R" },
|
||||||
{ compressibleField::cfDevRhoReff, "devRhoReff" },
|
{ compressibleField::cfDevRhoReff, "devRhoReff" },
|
||||||
{ compressibleField::cfL, "L" }
|
{ compressibleField::cfL, "L" },
|
||||||
|
{ compressibleField::cfI, "I" }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -80,6 +81,7 @@ Foam::functionObjects::turbulenceFields::incompressibleFieldNames_
|
|||||||
{ incompressibleField::ifR, "R" },
|
{ incompressibleField::ifR, "R" },
|
||||||
{ incompressibleField::ifDevReff, "devReff" },
|
{ incompressibleField::ifDevReff, "devReff" },
|
||||||
{ incompressibleField::ifL, "L" },
|
{ incompressibleField::ifL, "L" },
|
||||||
|
{ incompressibleField::ifI, "I" }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -236,6 +238,11 @@ bool Foam::functionObjects::turbulenceFields::execute()
|
|||||||
processField<scalar>(f, L(model));
|
processField<scalar>(f, L(model));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case cfI:
|
||||||
|
{
|
||||||
|
processField<scalar>(f, I(model));
|
||||||
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
FatalErrorInFunction
|
FatalErrorInFunction
|
||||||
@ -298,6 +305,11 @@ bool Foam::functionObjects::turbulenceFields::execute()
|
|||||||
processField<scalar>(f, L(model));
|
processField<scalar>(f, L(model));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case ifI:
|
||||||
|
{
|
||||||
|
processField<scalar>(f, I(model));
|
||||||
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
FatalErrorInFunction
|
FatalErrorInFunction
|
||||||
|
|||||||
@ -76,6 +76,7 @@ Usage
|
|||||||
devReff | Deviatoric part of the effective Reynolds stress
|
devReff | Deviatoric part of the effective Reynolds stress
|
||||||
devRhoReff | Divergence of the Reynolds stress
|
devRhoReff | Divergence of the Reynolds stress
|
||||||
L | turbulence length scale
|
L | turbulence length scale
|
||||||
|
I | turbulence intensity
|
||||||
\endplaintable
|
\endplaintable
|
||||||
|
|
||||||
See also
|
See also
|
||||||
@ -125,7 +126,8 @@ public:
|
|||||||
cfAlphaEff,
|
cfAlphaEff,
|
||||||
cfR,
|
cfR,
|
||||||
cfDevRhoReff,
|
cfDevRhoReff,
|
||||||
cfL
|
cfL,
|
||||||
|
cfI
|
||||||
};
|
};
|
||||||
static const Enum<compressibleField> compressibleFieldNames_;
|
static const Enum<compressibleField> compressibleFieldNames_;
|
||||||
|
|
||||||
@ -139,7 +141,8 @@ public:
|
|||||||
ifNuEff,
|
ifNuEff,
|
||||||
ifR,
|
ifR,
|
||||||
ifDevReff,
|
ifDevReff,
|
||||||
ifL
|
ifL,
|
||||||
|
ifI
|
||||||
};
|
};
|
||||||
static const Enum<incompressibleField> incompressibleFieldNames_;
|
static const Enum<incompressibleField> incompressibleFieldNames_;
|
||||||
|
|
||||||
@ -179,6 +182,10 @@ protected:
|
|||||||
template<class Model>
|
template<class Model>
|
||||||
tmp<volScalarField> L(const Model& model) const;
|
tmp<volScalarField> L(const Model& model) const;
|
||||||
|
|
||||||
|
//- Return I calculated from k and U
|
||||||
|
template<class Model>
|
||||||
|
tmp<volScalarField> I(const Model& model) const;
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
|||||||
@ -85,19 +85,16 @@ Foam::functionObjects::turbulenceFields::omega
|
|||||||
const volScalarField k(model.k());
|
const volScalarField k(model.k());
|
||||||
const volScalarField epsilon(model.epsilon());
|
const volScalarField epsilon(model.epsilon());
|
||||||
|
|
||||||
return tmp<volScalarField>
|
return tmp<volScalarField>::New
|
||||||
(
|
(
|
||||||
new volScalarField
|
IOobject
|
||||||
(
|
(
|
||||||
IOobject
|
"omega.tmp",
|
||||||
(
|
k.mesh().time().timeName(),
|
||||||
"omega.tmp",
|
k.mesh()
|
||||||
k.mesh().time().timeName(),
|
),
|
||||||
k.mesh()
|
epsilon/(Cmu*k),
|
||||||
),
|
epsilon.boundaryField().types()
|
||||||
epsilon/(Cmu*k),
|
|
||||||
epsilon.boundaryField().types()
|
|
||||||
)
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -109,9 +106,10 @@ Foam::functionObjects::turbulenceFields::nuTilda
|
|||||||
const Model& model
|
const Model& model
|
||||||
) const
|
) const
|
||||||
{
|
{
|
||||||
return tmp<volScalarField>
|
return tmp<volScalarField>::New
|
||||||
(
|
(
|
||||||
new volScalarField("nuTilda.tmp", model.k()/omega(model))
|
"nuTilda.tmp",
|
||||||
|
model.k()/omega(model)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -130,15 +128,30 @@ Foam::functionObjects::turbulenceFields::L
|
|||||||
const volScalarField epsilon(model.epsilon());
|
const volScalarField epsilon(model.epsilon());
|
||||||
const dimensionedScalar eps0("eps0", epsilon.dimensions(), SMALL);
|
const dimensionedScalar eps0("eps0", epsilon.dimensions(), SMALL);
|
||||||
|
|
||||||
return tmp<volScalarField>
|
return tmp<volScalarField>::New
|
||||||
(
|
(
|
||||||
new volScalarField
|
"L.tmp",
|
||||||
(
|
pow(Cmu, 0.75)*pow(k, 1.5)/(epsilon + eps0)
|
||||||
"L.tmp",
|
|
||||||
pow(Cmu, 0.75)*pow(k, 1.5)/(epsilon + eps0)
|
|
||||||
)
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class Model>
|
||||||
|
Foam::tmp<Foam::volScalarField>
|
||||||
|
Foam::functionObjects::turbulenceFields::I
|
||||||
|
(
|
||||||
|
const Model& model
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
// Assume k is available
|
||||||
|
const volScalarField uPrime(sqrt((2.0/3.0)*model.k()));
|
||||||
|
const dimensionedScalar U0("U0", dimVelocity, SMALL);
|
||||||
|
|
||||||
|
return tmp<volScalarField>::New
|
||||||
|
(
|
||||||
|
"I.tmp",
|
||||||
|
uPrime/max(max(uPrime, mag(model.U())), U0)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
// ************************************************************************* //
|
// ************************************************************************* //
|
||||||
|
|||||||
@ -353,7 +353,7 @@ Foam::functionObjects::forces::devRhoReff() const
|
|||||||
const dictionary& transportProperties =
|
const dictionary& transportProperties =
|
||||||
lookupObject<dictionary>("transportProperties");
|
lookupObject<dictionary>("transportProperties");
|
||||||
|
|
||||||
dimensionedScalar nu(transportProperties.lookup("nu"));
|
dimensionedScalar nu("nu", dimViscosity, transportProperties);
|
||||||
|
|
||||||
const volVectorField& U = lookupObject<volVectorField>(UName_);
|
const volVectorField& U = lookupObject<volVectorField>(UName_);
|
||||||
|
|
||||||
|
|||||||
@ -108,6 +108,7 @@ bool Foam::functionObjects::vtkWrite::read(const dictionary& dict)
|
|||||||
//
|
//
|
||||||
dict.readIfPresent("directory", dirName_);
|
dict.readIfPresent("directory", dirName_);
|
||||||
|
|
||||||
|
decompose_ = dict.lookupOrDefault("decompose", false);
|
||||||
writeIds_ = dict.lookupOrDefault("writeIds", false);
|
writeIds_ = dict.lookupOrDefault("writeIds", false);
|
||||||
|
|
||||||
|
|
||||||
@ -185,7 +186,7 @@ bool Foam::functionObjects::vtkWrite::write()
|
|||||||
(
|
(
|
||||||
mesh_,
|
mesh_,
|
||||||
writeOpts_,
|
writeOpts_,
|
||||||
true // decompose
|
decompose_
|
||||||
);
|
);
|
||||||
|
|
||||||
// Write mesh
|
// Write mesh
|
||||||
|
|||||||
@ -44,6 +44,7 @@ Description
|
|||||||
writeInterval 1;
|
writeInterval 1;
|
||||||
format binary;
|
format binary;
|
||||||
legacy false;
|
legacy false;
|
||||||
|
decompose false;
|
||||||
...
|
...
|
||||||
fields (U p);
|
fields (U p);
|
||||||
}
|
}
|
||||||
@ -51,14 +52,15 @@ Description
|
|||||||
|
|
||||||
Usage
|
Usage
|
||||||
\table
|
\table
|
||||||
Property | Description | Required | Default value
|
Property | Description | Required | Default
|
||||||
type | Type name: vtkWrite | yes |
|
type | Type name: vtkWrite | yes |
|
||||||
fields | Fields to output | yes |
|
fields | Fields to output | yes |
|
||||||
writeControl | Output control | recommended | timeStep
|
writeControl | Output control | recommended | timeStep
|
||||||
directory | The output directory name | no | "VTK"
|
directory | The output directory name | no | "VTK"
|
||||||
format | ASCII or binary format | no | binary
|
format | ASCII or binary format | no | binary
|
||||||
legacy | Legacy VTK output | no | false
|
legacy | Legacy VTK output | no | false
|
||||||
writeIds | Write cell ids as field | no | true
|
decompose | decompose polyhedra | no | false
|
||||||
|
writeIds | Write cell ids as field | no | true
|
||||||
\endtable
|
\endtable
|
||||||
|
|
||||||
See also
|
See also
|
||||||
@ -106,6 +108,9 @@ class vtkWrite
|
|||||||
//- Output directory name
|
//- Output directory name
|
||||||
fileName dirName_;
|
fileName dirName_;
|
||||||
|
|
||||||
|
//- Decompose polyhedra
|
||||||
|
bool decompose_;
|
||||||
|
|
||||||
//- Write cell ids field
|
//- Write cell ids field
|
||||||
bool writeIds_;
|
bool writeIds_;
|
||||||
|
|
||||||
@ -119,7 +124,11 @@ class vtkWrite
|
|||||||
|
|
||||||
//- Write selected fields for GeoField type.
|
//- Write selected fields for GeoField type.
|
||||||
template<class GeoField>
|
template<class GeoField>
|
||||||
label writeFields(vtk::internalWriter& writer, bool verbose=true) const;
|
label writeFields
|
||||||
|
(
|
||||||
|
vtk::internalWriter& writer,
|
||||||
|
bool verbose=true
|
||||||
|
) const;
|
||||||
|
|
||||||
|
|
||||||
//- Write selected fields for GeoField type.
|
//- Write selected fields for GeoField type.
|
||||||
@ -131,10 +140,10 @@ class vtkWrite
|
|||||||
) const;
|
) const;
|
||||||
|
|
||||||
|
|
||||||
//- Disallow default bitwise copy construct
|
//- No copy construct
|
||||||
vtkWrite(const vtkWrite&) = delete;
|
vtkWrite(const vtkWrite&) = delete;
|
||||||
|
|
||||||
//- Disallow default bitwise assignment
|
//- No copy assignment
|
||||||
void operator=(const vtkWrite&) = delete;
|
void operator=(const vtkWrite&) = delete;
|
||||||
|
|
||||||
|
|
||||||
@ -150,7 +159,7 @@ public:
|
|||||||
vtkWrite
|
vtkWrite
|
||||||
(
|
(
|
||||||
const word& name,
|
const word& name,
|
||||||
const Time& t,
|
const Time& runTime,
|
||||||
const dictionary& dict
|
const dictionary& dict
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@ -57,34 +57,6 @@ registerInfoSwitch
|
|||||||
|
|
||||||
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||||
|
|
||||||
void Foam::particle::stationaryTetGeometry
|
|
||||||
(
|
|
||||||
vector& centre,
|
|
||||||
vector& base,
|
|
||||||
vector& vertex1,
|
|
||||||
vector& vertex2
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
const triFace triIs(currentTetIndices().faceTriIs(mesh_));
|
|
||||||
const vectorField& ccs = mesh_.cellCentres();
|
|
||||||
const pointField& pts = mesh_.points();
|
|
||||||
|
|
||||||
centre = ccs[celli_];
|
|
||||||
base = pts[triIs[0]];
|
|
||||||
vertex1 = pts[triIs[1]];
|
|
||||||
vertex2 = pts[triIs[2]];
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Foam::barycentricTensor Foam::particle::stationaryTetTransform() const
|
|
||||||
{
|
|
||||||
vector centre, base, vertex1, vertex2;
|
|
||||||
stationaryTetGeometry(centre, base, vertex1, vertex2);
|
|
||||||
|
|
||||||
return barycentricTensor(centre, base, vertex1, vertex2);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Foam::particle::stationaryTetReverseTransform
|
void Foam::particle::stationaryTetReverseTransform
|
||||||
(
|
(
|
||||||
vector& centre,
|
vector& centre,
|
||||||
@ -114,61 +86,6 @@ void Foam::particle::stationaryTetReverseTransform
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Foam::particle::movingTetGeometry
|
|
||||||
(
|
|
||||||
const scalar fraction,
|
|
||||||
Pair<vector>& centre,
|
|
||||||
Pair<vector>& base,
|
|
||||||
Pair<vector>& vertex1,
|
|
||||||
Pair<vector>& vertex2
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
const triFace triIs(currentTetIndices().faceTriIs(mesh_));
|
|
||||||
const pointField& ptsOld = mesh_.oldPoints();
|
|
||||||
const pointField& ptsNew = mesh_.points();
|
|
||||||
|
|
||||||
// !!! <-- We would be better off using mesh_.cellCentres() here. However,
|
|
||||||
// we need to put a mesh_.oldCellCentres() method in for this to work. The
|
|
||||||
// values obtained from the mesh and those obtained from the cell do not
|
|
||||||
// necessarily match. See mantis #1993.
|
|
||||||
const vector ccOld = mesh_.cells()[celli_].centre(ptsOld, mesh_.faces());
|
|
||||||
const vector ccNew = mesh_.cells()[celli_].centre(ptsNew, mesh_.faces());
|
|
||||||
|
|
||||||
// Old and new points and cell centres are not sub-cycled. If we are sub-
|
|
||||||
// cycling, then we have to account for the timestep change here by
|
|
||||||
// modifying the fractions that we take of the old and new geometry.
|
|
||||||
const Pair<scalar> s = stepFractionSpan();
|
|
||||||
const scalar f0 = s[0] + stepFraction_*s[1], f1 = fraction*s[1];
|
|
||||||
|
|
||||||
centre[0] = ccOld + f0*(ccNew - ccOld);
|
|
||||||
base[0] = ptsOld[triIs[0]] + f0*(ptsNew[triIs[0]] - ptsOld[triIs[0]]);
|
|
||||||
vertex1[0] = ptsOld[triIs[1]] + f0*(ptsNew[triIs[1]] - ptsOld[triIs[1]]);
|
|
||||||
vertex2[0] = ptsOld[triIs[2]] + f0*(ptsNew[triIs[2]] - ptsOld[triIs[2]]);
|
|
||||||
|
|
||||||
centre[1] = f1*(ccNew - ccOld);
|
|
||||||
base[1] = f1*(ptsNew[triIs[0]] - ptsOld[triIs[0]]);
|
|
||||||
vertex1[1] = f1*(ptsNew[triIs[1]] - ptsOld[triIs[1]]);
|
|
||||||
vertex2[1] = f1*(ptsNew[triIs[2]] - ptsOld[triIs[2]]);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Foam::Pair<Foam::barycentricTensor> Foam::particle::movingTetTransform
|
|
||||||
(
|
|
||||||
const scalar fraction
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
Pair<vector> centre, base, vertex1, vertex2;
|
|
||||||
movingTetGeometry(fraction, centre, base, vertex1, vertex2);
|
|
||||||
|
|
||||||
return
|
|
||||||
Pair<barycentricTensor>
|
|
||||||
(
|
|
||||||
barycentricTensor(centre[0], base[0], vertex1[0], vertex2[0]),
|
|
||||||
barycentricTensor(centre[1], base[1], vertex1[1], vertex2[1])
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Foam::particle::movingTetReverseTransform
|
void Foam::particle::movingTetReverseTransform
|
||||||
(
|
(
|
||||||
const scalar fraction,
|
const scalar fraction,
|
||||||
@ -1013,47 +930,6 @@ Foam::vector Foam::particle::deviationFromMeshCentre() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Foam::particle::patchData(vector& n, vector& U) const
|
|
||||||
{
|
|
||||||
if (!onBoundaryFace())
|
|
||||||
{
|
|
||||||
FatalErrorInFunction
|
|
||||||
<< "Patch data was requested for a particle that isn't on a patch"
|
|
||||||
<< exit(FatalError);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mesh_.moving())
|
|
||||||
{
|
|
||||||
Pair<vector> centre, base, vertex1, vertex2;
|
|
||||||
movingTetGeometry(1, centre, base, vertex1, vertex2);
|
|
||||||
|
|
||||||
n = triPointRef(base[0], vertex1[0], vertex2[0]).normal();
|
|
||||||
n /= mag(n);
|
|
||||||
|
|
||||||
// Interpolate the motion of the three face vertices to the current
|
|
||||||
// coordinates
|
|
||||||
U =
|
|
||||||
coordinates_.b()*base[1]
|
|
||||||
+ coordinates_.c()*vertex1[1]
|
|
||||||
+ coordinates_.d()*vertex2[1];
|
|
||||||
|
|
||||||
// The movingTetGeometry method gives the motion as a displacement
|
|
||||||
// across the time-step, so we divide by the time-step to get velocity
|
|
||||||
U /= mesh_.time().deltaTValue();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
vector centre, base, vertex1, vertex2;
|
|
||||||
stationaryTetGeometry(centre, base, vertex1, vertex2);
|
|
||||||
|
|
||||||
n = triPointRef(base, vertex1, vertex2).normal();
|
|
||||||
n /= mag(n);
|
|
||||||
|
|
||||||
U = Zero;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Foam::particle::transformProperties(const tensor&)
|
void Foam::particle::transformProperties(const tensor&)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
|||||||
@ -180,7 +180,7 @@ private:
|
|||||||
// Tetrahedra functions
|
// Tetrahedra functions
|
||||||
|
|
||||||
//- Get the vertices of the current tet
|
//- Get the vertices of the current tet
|
||||||
void stationaryTetGeometry
|
inline void stationaryTetGeometry
|
||||||
(
|
(
|
||||||
vector& centre,
|
vector& centre,
|
||||||
vector& base,
|
vector& base,
|
||||||
@ -193,7 +193,7 @@ private:
|
|||||||
// Cartesian position in the global coordinate system. The
|
// Cartesian position in the global coordinate system. The
|
||||||
// conversion is x = A & y, where x is the Cartesian position, y is
|
// conversion is x = A & y, where x is the Cartesian position, y is
|
||||||
// the barycentric position and A is the transformation tensor.
|
// the barycentric position and A is the transformation tensor.
|
||||||
barycentricTensor stationaryTetTransform() const;
|
inline barycentricTensor stationaryTetTransform() const;
|
||||||
|
|
||||||
//- Get the reverse transform associated with the current tet. The
|
//- Get the reverse transform associated with the current tet. The
|
||||||
// conversion is detA*y = (x - centre) & T. The variables x, y and
|
// conversion is detA*y = (x - centre) & T. The variables x, y and
|
||||||
@ -212,7 +212,7 @@ private:
|
|||||||
//- Get the vertices of the current moving tet. Two values are
|
//- Get the vertices of the current moving tet. Two values are
|
||||||
// returned for each vertex. The first is a constant, and the
|
// returned for each vertex. The first is a constant, and the
|
||||||
// second is a linear coefficient of the track fraction.
|
// second is a linear coefficient of the track fraction.
|
||||||
void movingTetGeometry
|
inline void movingTetGeometry
|
||||||
(
|
(
|
||||||
const scalar endStepFraction,
|
const scalar endStepFraction,
|
||||||
Pair<vector>& centre,
|
Pair<vector>& centre,
|
||||||
@ -225,7 +225,7 @@ private:
|
|||||||
// This is of the same form as for the static case. As with the
|
// This is of the same form as for the static case. As with the
|
||||||
// moving geometry, a linear function of the tracking fraction is
|
// moving geometry, a linear function of the tracking fraction is
|
||||||
// returned for each component.
|
// returned for each component.
|
||||||
Pair<barycentricTensor> movingTetTransform
|
inline Pair<barycentricTensor> movingTetTransform
|
||||||
(
|
(
|
||||||
const scalar endStepFraction
|
const scalar endStepFraction
|
||||||
) const;
|
) const;
|
||||||
@ -625,7 +625,7 @@ public:
|
|||||||
// Patch data
|
// Patch data
|
||||||
|
|
||||||
//- Get the normal and velocity of the current patch location
|
//- Get the normal and velocity of the current patch location
|
||||||
void patchData(vector& n, vector& U) const;
|
inline void patchData(vector& n, vector& U) const;
|
||||||
|
|
||||||
|
|
||||||
// Transformations
|
// Transformations
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
========= |
|
========= |
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
\\ / O peration |
|
\\ / O peration |
|
||||||
\\ / A nd | Copyright (C) 2011-2017 OpenFOAM Foundation
|
\\ / A nd | Copyright (C) 2011-2018 OpenFOAM Foundation
|
||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
@ -26,6 +26,91 @@ License
|
|||||||
#include "polyMesh.H"
|
#include "polyMesh.H"
|
||||||
#include "Time.H"
|
#include "Time.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||||
|
|
||||||
|
void Foam::particle::stationaryTetGeometry
|
||||||
|
(
|
||||||
|
vector& centre,
|
||||||
|
vector& base,
|
||||||
|
vector& vertex1,
|
||||||
|
vector& vertex2
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
const triFace triIs(currentTetIndices().faceTriIs(mesh_));
|
||||||
|
const vectorField& ccs = mesh_.cellCentres();
|
||||||
|
const pointField& pts = mesh_.points();
|
||||||
|
|
||||||
|
centre = ccs[celli_];
|
||||||
|
base = pts[triIs[0]];
|
||||||
|
vertex1 = pts[triIs[1]];
|
||||||
|
vertex2 = pts[triIs[2]];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline Foam::barycentricTensor Foam::particle::stationaryTetTransform() const
|
||||||
|
{
|
||||||
|
vector centre, base, vertex1, vertex2;
|
||||||
|
stationaryTetGeometry(centre, base, vertex1, vertex2);
|
||||||
|
|
||||||
|
return barycentricTensor(centre, base, vertex1, vertex2);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline void Foam::particle::movingTetGeometry
|
||||||
|
(
|
||||||
|
const scalar fraction,
|
||||||
|
Pair<vector>& centre,
|
||||||
|
Pair<vector>& base,
|
||||||
|
Pair<vector>& vertex1,
|
||||||
|
Pair<vector>& vertex2
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
const triFace triIs(currentTetIndices().faceTriIs(mesh_));
|
||||||
|
const pointField& ptsOld = mesh_.oldPoints();
|
||||||
|
const pointField& ptsNew = mesh_.points();
|
||||||
|
|
||||||
|
// !!! <-- We would be better off using mesh_.cellCentres() here. However,
|
||||||
|
// we need to put a mesh_.oldCellCentres() method in for this to work. The
|
||||||
|
// values obtained from the mesh and those obtained from the cell do not
|
||||||
|
// necessarily match. See mantis #1993.
|
||||||
|
const vector ccOld = mesh_.cells()[celli_].centre(ptsOld, mesh_.faces());
|
||||||
|
const vector ccNew = mesh_.cells()[celli_].centre(ptsNew, mesh_.faces());
|
||||||
|
|
||||||
|
// Old and new points and cell centres are not sub-cycled. If we are sub-
|
||||||
|
// cycling, then we have to account for the timestep change here by
|
||||||
|
// modifying the fractions that we take of the old and new geometry.
|
||||||
|
const Pair<scalar> s = stepFractionSpan();
|
||||||
|
const scalar f0 = s[0] + stepFraction_*s[1], f1 = fraction*s[1];
|
||||||
|
|
||||||
|
centre[0] = ccOld + f0*(ccNew - ccOld);
|
||||||
|
base[0] = ptsOld[triIs[0]] + f0*(ptsNew[triIs[0]] - ptsOld[triIs[0]]);
|
||||||
|
vertex1[0] = ptsOld[triIs[1]] + f0*(ptsNew[triIs[1]] - ptsOld[triIs[1]]);
|
||||||
|
vertex2[0] = ptsOld[triIs[2]] + f0*(ptsNew[triIs[2]] - ptsOld[triIs[2]]);
|
||||||
|
|
||||||
|
centre[1] = f1*(ccNew - ccOld);
|
||||||
|
base[1] = f1*(ptsNew[triIs[0]] - ptsOld[triIs[0]]);
|
||||||
|
vertex1[1] = f1*(ptsNew[triIs[1]] - ptsOld[triIs[1]]);
|
||||||
|
vertex2[1] = f1*(ptsNew[triIs[2]] - ptsOld[triIs[2]]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline Foam::Pair<Foam::barycentricTensor> Foam::particle::movingTetTransform
|
||||||
|
(
|
||||||
|
const scalar fraction
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
Pair<vector> centre, base, vertex1, vertex2;
|
||||||
|
movingTetGeometry(fraction, centre, base, vertex1, vertex2);
|
||||||
|
|
||||||
|
return
|
||||||
|
Pair<barycentricTensor>
|
||||||
|
(
|
||||||
|
barycentricTensor(centre[0], base[0], vertex1[0], vertex2[0]),
|
||||||
|
barycentricTensor(centre[1], base[1], vertex1[1], vertex2[1])
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||||
|
|
||||||
inline Foam::label Foam::particle::getNewParticleID() const
|
inline Foam::label Foam::particle::getNewParticleID() const
|
||||||
@ -231,4 +316,45 @@ inline Foam::vector Foam::particle::position() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::particle::patchData(vector& n, vector& U) const
|
||||||
|
{
|
||||||
|
if (!onBoundaryFace())
|
||||||
|
{
|
||||||
|
FatalErrorInFunction
|
||||||
|
<< "Patch data was requested for a particle that isn't on a patch"
|
||||||
|
<< exit(FatalError);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mesh_.moving())
|
||||||
|
{
|
||||||
|
Pair<vector> centre, base, vertex1, vertex2;
|
||||||
|
movingTetGeometry(1, centre, base, vertex1, vertex2);
|
||||||
|
|
||||||
|
n = triPointRef(base[0], vertex1[0], vertex2[0]).normal();
|
||||||
|
n /= mag(n);
|
||||||
|
|
||||||
|
// Interpolate the motion of the three face vertices to the current
|
||||||
|
// coordinates
|
||||||
|
U =
|
||||||
|
coordinates_.b()*base[1]
|
||||||
|
+ coordinates_.c()*vertex1[1]
|
||||||
|
+ coordinates_.d()*vertex2[1];
|
||||||
|
|
||||||
|
// The movingTetGeometry method gives the motion as a displacement
|
||||||
|
// across the time-step, so we divide by the time-step to get velocity
|
||||||
|
U /= mesh_.time().deltaTValue();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
vector centre, base, vertex1, vertex2;
|
||||||
|
stationaryTetGeometry(centre, base, vertex1, vertex2);
|
||||||
|
|
||||||
|
n = triPointRef(base, vertex1, vertex2).normal();
|
||||||
|
n /= mag(n);
|
||||||
|
|
||||||
|
U = Zero;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
// ************************************************************************* //
|
||||||
|
|||||||
@ -156,6 +156,8 @@ void Foam::particle::hitFace
|
|||||||
}
|
}
|
||||||
else if (onBoundaryFace())
|
else if (onBoundaryFace())
|
||||||
{
|
{
|
||||||
|
changeToMasterPatch();
|
||||||
|
|
||||||
if (!p.hitPatch(cloud, ttd))
|
if (!p.hitPatch(cloud, ttd))
|
||||||
{
|
{
|
||||||
const polyPatch& patch = mesh_.boundaryMesh()[p.patch()];
|
const polyPatch& patch = mesh_.boundaryMesh()[p.patch()];
|
||||||
@ -212,11 +214,6 @@ void Foam::particle::trackToAndHitFace
|
|||||||
{
|
{
|
||||||
trackToFace(direction, fraction);
|
trackToFace(direction, fraction);
|
||||||
|
|
||||||
if (onBoundaryFace())
|
|
||||||
{
|
|
||||||
changeToMasterPatch();
|
|
||||||
}
|
|
||||||
|
|
||||||
hitFace(direction, cloud, td);
|
hitFace(direction, cloud, td);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
========= |
|
========= |
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
\\ / O peration |
|
\\ / O peration |
|
||||||
\\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation
|
\\ / A nd | Copyright (C) 2011-2018 OpenFOAM Foundation
|
||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
@ -34,6 +34,7 @@ License
|
|||||||
#include "ParticleErosion.H"
|
#include "ParticleErosion.H"
|
||||||
#include "ParticleTracks.H"
|
#include "ParticleTracks.H"
|
||||||
#include "ParticleTrap.H"
|
#include "ParticleTrap.H"
|
||||||
|
#include "PatchCollisionDensity.H"
|
||||||
#include "PatchPostProcessing.H"
|
#include "PatchPostProcessing.H"
|
||||||
#include "VoidFraction.H"
|
#include "VoidFraction.H"
|
||||||
|
|
||||||
@ -48,6 +49,7 @@ License
|
|||||||
makeCloudFunctionObjectType(ParticleErosion, CloudType); \
|
makeCloudFunctionObjectType(ParticleErosion, CloudType); \
|
||||||
makeCloudFunctionObjectType(ParticleTracks, CloudType); \
|
makeCloudFunctionObjectType(ParticleTracks, CloudType); \
|
||||||
makeCloudFunctionObjectType(ParticleTrap, CloudType); \
|
makeCloudFunctionObjectType(ParticleTrap, CloudType); \
|
||||||
|
makeCloudFunctionObjectType(PatchCollisionDensity, CloudType); \
|
||||||
makeCloudFunctionObjectType(PatchPostProcessing, CloudType); \
|
makeCloudFunctionObjectType(PatchPostProcessing, CloudType); \
|
||||||
makeCloudFunctionObjectType(VoidFraction, CloudType);
|
makeCloudFunctionObjectType(VoidFraction, CloudType);
|
||||||
|
|
||||||
|
|||||||
@ -0,0 +1,168 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | Copyright (C) 2018 OpenFOAM Foundation
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
License
|
||||||
|
This file is part of OpenFOAM.
|
||||||
|
|
||||||
|
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#include "PatchCollisionDensity.H"
|
||||||
|
#include "Pstream.H"
|
||||||
|
#include "stringListOps.H"
|
||||||
|
#include "ListOps.H"
|
||||||
|
#include "ListListOps.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * //
|
||||||
|
|
||||||
|
template<class CloudType>
|
||||||
|
void Foam::PatchCollisionDensity<CloudType>::write()
|
||||||
|
{
|
||||||
|
const scalarField z(this->owner().mesh().nCells(), 0);
|
||||||
|
|
||||||
|
volScalarField
|
||||||
|
(
|
||||||
|
IOobject
|
||||||
|
(
|
||||||
|
this->owner().name() + ":collisionDensity",
|
||||||
|
this->owner().mesh().time().timeName(),
|
||||||
|
this->owner().mesh()
|
||||||
|
),
|
||||||
|
this->owner().mesh(),
|
||||||
|
dimless/dimArea,
|
||||||
|
z,
|
||||||
|
collisionDensity_
|
||||||
|
)
|
||||||
|
.write();
|
||||||
|
|
||||||
|
volScalarField
|
||||||
|
(
|
||||||
|
IOobject
|
||||||
|
(
|
||||||
|
this->owner().name() + ":collisionDensityRate",
|
||||||
|
this->owner().mesh().time().timeName(),
|
||||||
|
this->owner().mesh()
|
||||||
|
),
|
||||||
|
this->owner().mesh(),
|
||||||
|
dimless/dimArea/dimTime,
|
||||||
|
z,
|
||||||
|
(collisionDensity_ - collisionDensity0_)
|
||||||
|
/(this->owner().mesh().time().value() - time0_)
|
||||||
|
)
|
||||||
|
.write();
|
||||||
|
|
||||||
|
collisionDensity0_ == collisionDensity_;
|
||||||
|
time0_ = this->owner().mesh().time().value();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
template<class CloudType>
|
||||||
|
Foam::PatchCollisionDensity<CloudType>::PatchCollisionDensity
|
||||||
|
(
|
||||||
|
const dictionary& dict,
|
||||||
|
CloudType& owner,
|
||||||
|
const word& modelName
|
||||||
|
)
|
||||||
|
:
|
||||||
|
CloudFunctionObject<CloudType>(dict, owner, modelName, typeName),
|
||||||
|
minSpeed_(dict.lookupOrDefault<scalar>("minSpeed", -1)),
|
||||||
|
collisionDensity_
|
||||||
|
(
|
||||||
|
this->owner().mesh().boundary(),
|
||||||
|
volScalarField::Internal::null(),
|
||||||
|
calculatedFvPatchField<scalar>::typeName
|
||||||
|
),
|
||||||
|
collisionDensity0_
|
||||||
|
(
|
||||||
|
this->owner().mesh().boundary(),
|
||||||
|
volScalarField::Internal::null(),
|
||||||
|
calculatedFvPatchField<scalar>::typeName
|
||||||
|
),
|
||||||
|
time0_(this->owner().mesh().time().value())
|
||||||
|
{
|
||||||
|
collisionDensity_ == 0;
|
||||||
|
collisionDensity0_ == 0;
|
||||||
|
|
||||||
|
IOobject io
|
||||||
|
(
|
||||||
|
this->owner().name() + ":collisionDensity",
|
||||||
|
this->owner().mesh().time().timeName(),
|
||||||
|
this->owner().mesh(),
|
||||||
|
IOobject::MUST_READ,
|
||||||
|
IOobject::NO_WRITE
|
||||||
|
);
|
||||||
|
|
||||||
|
if (io.typeHeaderOk<volScalarField>())
|
||||||
|
{
|
||||||
|
const volScalarField collisionDensity(io, this->owner().mesh());
|
||||||
|
collisionDensity_ == collisionDensity.boundaryField();
|
||||||
|
collisionDensity0_ == collisionDensity.boundaryField();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class CloudType>
|
||||||
|
Foam::PatchCollisionDensity<CloudType>::PatchCollisionDensity
|
||||||
|
(
|
||||||
|
const PatchCollisionDensity<CloudType>& ppm
|
||||||
|
)
|
||||||
|
:
|
||||||
|
CloudFunctionObject<CloudType>(ppm),
|
||||||
|
minSpeed_(ppm.minSpeed_),
|
||||||
|
collisionDensity_(ppm.collisionDensity_),
|
||||||
|
collisionDensity0_(ppm.collisionDensity0_),
|
||||||
|
time0_(ppm.time0_)
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
template<class CloudType>
|
||||||
|
Foam::PatchCollisionDensity<CloudType>::~PatchCollisionDensity()
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
template<class CloudType>
|
||||||
|
void Foam::PatchCollisionDensity<CloudType>::postPatch
|
||||||
|
(
|
||||||
|
const parcelType& p,
|
||||||
|
const polyPatch& pp,
|
||||||
|
bool&
|
||||||
|
)
|
||||||
|
{
|
||||||
|
const label patchi = pp.index();
|
||||||
|
const label patchFacei = p.face() - pp.start();
|
||||||
|
|
||||||
|
vector nw, Up;
|
||||||
|
this->owner().patchData(p, pp, nw, Up);
|
||||||
|
|
||||||
|
const scalar speed = (p.U() - Up) & nw;
|
||||||
|
if (speed > minSpeed_)
|
||||||
|
{
|
||||||
|
collisionDensity_[patchi][patchFacei] +=
|
||||||
|
1/this->owner().mesh().magSf().boundaryField()[patchi][patchFacei];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -0,0 +1,152 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | Copyright (C) 2018 OpenFOAM Foundation
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
License
|
||||||
|
This file is part of OpenFOAM.
|
||||||
|
|
||||||
|
OpenFOAM is free software: you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
Class
|
||||||
|
Foam::PatchCollisionDensity
|
||||||
|
|
||||||
|
Description
|
||||||
|
Function object which generates fields of the number and rate of collisions
|
||||||
|
per unit area on all patches. Can optionally take a minimum speed below
|
||||||
|
which a collision is not counted.
|
||||||
|
|
||||||
|
Example usage:
|
||||||
|
\verbatim
|
||||||
|
patchCollisionDensity1
|
||||||
|
{
|
||||||
|
type patchCollisionDensity;
|
||||||
|
minSpeed 1e-3;
|
||||||
|
}
|
||||||
|
\endverbatim
|
||||||
|
|
||||||
|
SourceFiles
|
||||||
|
PatchCollisionDensity.C
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef PatchCollisionDensity_H
|
||||||
|
#define PatchCollisionDensity_H
|
||||||
|
|
||||||
|
#include "CloudFunctionObject.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
Class PatchCollisionDensity Declaration
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
template<class CloudType>
|
||||||
|
class PatchCollisionDensity
|
||||||
|
:
|
||||||
|
public CloudFunctionObject<CloudType>
|
||||||
|
{
|
||||||
|
// Private data
|
||||||
|
|
||||||
|
typedef typename CloudType::particleType parcelType;
|
||||||
|
|
||||||
|
//- The threshold for a collision
|
||||||
|
const scalar minSpeed_;
|
||||||
|
|
||||||
|
//- The field of the number of collisions per unit area
|
||||||
|
volScalarField::Boundary collisionDensity_;
|
||||||
|
|
||||||
|
//- The field of the number of collisions per unit area at the last
|
||||||
|
// output
|
||||||
|
volScalarField::Boundary collisionDensity0_;
|
||||||
|
|
||||||
|
//- The time at the last output
|
||||||
|
scalar time0_;
|
||||||
|
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
// Protected Member Functions
|
||||||
|
|
||||||
|
//- Write post-processing info
|
||||||
|
void write();
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
//- Runtime type information
|
||||||
|
TypeName("patchCollisionDensity");
|
||||||
|
|
||||||
|
|
||||||
|
// Constructors
|
||||||
|
|
||||||
|
//- Construct from dictionary
|
||||||
|
PatchCollisionDensity
|
||||||
|
(
|
||||||
|
const dictionary& dict,
|
||||||
|
CloudType& owner,
|
||||||
|
const word& modelName
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Construct copy
|
||||||
|
PatchCollisionDensity(const PatchCollisionDensity<CloudType>& ppm);
|
||||||
|
|
||||||
|
//- Construct and return a clone
|
||||||
|
virtual autoPtr<CloudFunctionObject<CloudType>> clone() const
|
||||||
|
{
|
||||||
|
return autoPtr<CloudFunctionObject<CloudType>>
|
||||||
|
(
|
||||||
|
new PatchCollisionDensity<CloudType>(*this)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//- Destructor
|
||||||
|
virtual ~PatchCollisionDensity();
|
||||||
|
|
||||||
|
|
||||||
|
// Member Functions
|
||||||
|
|
||||||
|
// Evaluation
|
||||||
|
|
||||||
|
//- Post-patch hook
|
||||||
|
virtual void postPatch
|
||||||
|
(
|
||||||
|
const parcelType& p,
|
||||||
|
const polyPatch& pp,
|
||||||
|
bool& keepParticle
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
} // End namespace Foam
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
#ifdef NoRepository
|
||||||
|
#include "PatchCollisionDensity.C"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -250,7 +250,7 @@ void Foam::lumpedPointDisplacementPointPatchVectorField::updateCoeffs()
|
|||||||
|
|
||||||
if (Pstream::master())
|
if (Pstream::master())
|
||||||
{
|
{
|
||||||
movement().writeData(forces, moments);
|
movement().writeData(forces, moments, &(db().time()));
|
||||||
|
|
||||||
// Signal external source to execute
|
// Signal external source to execute
|
||||||
movement().coupler().useSlave();
|
movement().coupler().useSlave();
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
========= |
|
========= |
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
\\ / O peration |
|
\\ / O peration |
|
||||||
\\ / A nd | Copyright (C) 2016-2017 OpenCFD Ltd.
|
\\ / A nd | Copyright (C) 2016-2018 OpenCFD Ltd.
|
||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
@ -48,29 +48,65 @@ Foam::lumpedPointMovement::formatNames
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
const Foam::Enum
|
||||||
|
<
|
||||||
|
Foam::lumpedPointMovement::scalingType
|
||||||
|
>
|
||||||
|
Foam::lumpedPointMovement::scalingNames
|
||||||
|
{
|
||||||
|
{ scalingType::LENGTH, "plain" },
|
||||||
|
{ scalingType::FORCE, "force" },
|
||||||
|
{ scalingType::MOMENT, "moment" }
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
const Foam::word
|
const Foam::word
|
||||||
Foam::lumpedPointMovement::dictionaryName("lumpedPointMovement");
|
Foam::lumpedPointMovement::dictionaryName("lumpedPointMovement");
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
namespace Foam
|
namespace Foam
|
||||||
{
|
{
|
||||||
|
|
||||||
|
//! \cond fileScope
|
||||||
|
//- Space-separated vector value (ASCII)
|
||||||
|
static inline Ostream& putPlain(Ostream& os, const vector& val)
|
||||||
|
{
|
||||||
|
os << val.x() << ' ' << val.y() << ' ' << val.z();
|
||||||
|
return os;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//! \cond fileScope
|
||||||
|
//- Space-separated vector value (ASCII)
|
||||||
|
static inline Ostream& putTime(Ostream& os, const Time& t)
|
||||||
|
{
|
||||||
|
os <<"Time index=" << t.timeIndex()
|
||||||
|
<< " value=" << t.timeOutputValue();
|
||||||
|
|
||||||
|
return os;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//! \cond fileScope
|
//! \cond fileScope
|
||||||
//- Write list content with size, bracket, content, bracket one-per-line.
|
//- Write list content with size, bracket, content, bracket one-per-line.
|
||||||
// This makes for consistent for parsing, regardless of the list length.
|
// This makes for consistent for parsing, regardless of the list length.
|
||||||
template <class T>
|
template <class T>
|
||||||
static void writeList(Ostream& os, const string& header, const UList<T>& lst)
|
static void writeList(Ostream& os, const string& header, const UList<T>& list)
|
||||||
{
|
{
|
||||||
|
const label len = list.size();
|
||||||
|
|
||||||
// Header string
|
// Header string
|
||||||
os << header.c_str() << nl;
|
os << header.c_str() << nl;
|
||||||
|
|
||||||
// Write size and start delimiter
|
// Write size and start delimiter
|
||||||
os << lst.size() << nl
|
os << len << nl << token::BEGIN_LIST << nl;
|
||||||
<< token::BEGIN_LIST << nl;
|
|
||||||
|
|
||||||
// Write contents
|
// Write contents
|
||||||
forAll(lst, i)
|
for (label i=0; i < len; ++i)
|
||||||
{
|
{
|
||||||
os << lst[i] << nl;
|
os << list[i] << nl;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write end delimiter
|
// Write end delimiter
|
||||||
@ -165,8 +201,11 @@ Foam::lumpedPointMovement::lumpedPointMovement()
|
|||||||
coupler_(),
|
coupler_(),
|
||||||
inputName_("positions.in"),
|
inputName_("positions.in"),
|
||||||
outputName_("forces.out"),
|
outputName_("forces.out"),
|
||||||
|
logName_("movement.log"),
|
||||||
inputFormat_(lumpedPointState::inputFormatType::DICTIONARY),
|
inputFormat_(lumpedPointState::inputFormatType::DICTIONARY),
|
||||||
outputFormat_(outputFormatType::DICTIONARY),
|
outputFormat_(outputFormatType::DICTIONARY),
|
||||||
|
scaleInput_(-1.0),
|
||||||
|
scaleOutput_(-1.0),
|
||||||
state0_(),
|
state0_(),
|
||||||
state_(),
|
state_(),
|
||||||
thresholdPtr_(0),
|
thresholdPtr_(0),
|
||||||
@ -198,6 +237,11 @@ Foam::lumpedPointMovement::lumpedPointMovement
|
|||||||
autoCentre_(true),
|
autoCentre_(true),
|
||||||
forcesDict_(),
|
forcesDict_(),
|
||||||
coupler_(),
|
coupler_(),
|
||||||
|
inputName_("positions.in"),
|
||||||
|
outputName_("forces.out"),
|
||||||
|
logName_("movement.log"),
|
||||||
|
scaleInput_(-1.0),
|
||||||
|
scaleOutput_(-1.0),
|
||||||
state0_(),
|
state0_(),
|
||||||
state_(),
|
state_(),
|
||||||
thresholdPtr_(0),
|
thresholdPtr_(0),
|
||||||
@ -262,6 +306,7 @@ void Foam::lumpedPointMovement::readDict(const dictionary& dict)
|
|||||||
|
|
||||||
commDict.lookup("inputName") >> inputName_;
|
commDict.lookup("inputName") >> inputName_;
|
||||||
commDict.lookup("outputName") >> outputName_;
|
commDict.lookup("outputName") >> outputName_;
|
||||||
|
commDict.readIfPresent("logName", logName_);
|
||||||
|
|
||||||
inputFormat_ = lumpedPointState::formatNames.lookup
|
inputFormat_ = lumpedPointState::formatNames.lookup
|
||||||
(
|
(
|
||||||
@ -274,6 +319,47 @@ void Foam::lumpedPointMovement::readDict(const dictionary& dict)
|
|||||||
"outputFormat",
|
"outputFormat",
|
||||||
commDict
|
commDict
|
||||||
);
|
);
|
||||||
|
|
||||||
|
scaleInput_ = -1;
|
||||||
|
scaleOutput_ = -1;
|
||||||
|
|
||||||
|
const dictionary* scaleDict = nullptr;
|
||||||
|
|
||||||
|
if ((scaleDict = commDict.subDictPtr("scaleInput")))
|
||||||
|
{
|
||||||
|
for (int i=0; i < scaleInput_.size(); ++i)
|
||||||
|
{
|
||||||
|
const word& key = scalingNames[scalingType(i)];
|
||||||
|
|
||||||
|
if
|
||||||
|
(
|
||||||
|
scaleDict->readIfPresent(key, scaleInput_[i])
|
||||||
|
&& scaleInput_[i] > 0
|
||||||
|
)
|
||||||
|
{
|
||||||
|
Info<<"Using input " << key << " multiplier: "
|
||||||
|
<< scaleInput_[i] << nl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((scaleDict = commDict.subDictPtr("scaleOutput")))
|
||||||
|
{
|
||||||
|
for (int i=0; i < scaleOutput_.size(); ++i)
|
||||||
|
{
|
||||||
|
const word& key = scalingNames[scalingType(i)];
|
||||||
|
|
||||||
|
if
|
||||||
|
(
|
||||||
|
scaleDict->readIfPresent(key, scaleOutput_[i])
|
||||||
|
&& scaleOutput_[i] > 0
|
||||||
|
)
|
||||||
|
{
|
||||||
|
Info<<"Using output " << key << " multiplier: "
|
||||||
|
<< scaleOutput_[i] << nl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -638,6 +724,8 @@ bool Foam::lumpedPointMovement::readState()
|
|||||||
coupler().resolveFile(inputName_)
|
coupler().resolveFile(inputName_)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
state_.scalePoints(scaleInput_[scalingType::LENGTH]);
|
||||||
|
|
||||||
state_.relax(relax_, prev);
|
state_.relax(relax_, prev);
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
@ -646,45 +734,114 @@ bool Foam::lumpedPointMovement::readState()
|
|||||||
|
|
||||||
bool Foam::lumpedPointMovement::writeData
|
bool Foam::lumpedPointMovement::writeData
|
||||||
(
|
(
|
||||||
const UList<vector>& forces
|
Ostream& os,
|
||||||
|
const UList<vector>& forces,
|
||||||
|
const UList<vector>& moments,
|
||||||
|
const outputFormatType fmt,
|
||||||
|
const Time* timeinfo
|
||||||
) const
|
) const
|
||||||
{
|
{
|
||||||
if (!Pstream::master())
|
const bool writeMoments = (moments.size() == forces.size());
|
||||||
|
|
||||||
|
if (fmt == outputFormatType::PLAIN)
|
||||||
{
|
{
|
||||||
return false;
|
os <<"########" << nl;
|
||||||
}
|
if (timeinfo)
|
||||||
|
|
||||||
const fileName output(coupler().resolveFile(outputName_));
|
|
||||||
OFstream os(output); // ASCII
|
|
||||||
|
|
||||||
if (outputFormat_ == outputFormatType::PLAIN)
|
|
||||||
{
|
|
||||||
os <<"# output from OpenFOAM" << nl
|
|
||||||
<<"# N, points, forces" << nl
|
|
||||||
<< this->size() << nl;
|
|
||||||
|
|
||||||
const char* zeroVector = "0 0 0";
|
|
||||||
|
|
||||||
forAll(locations_, i)
|
|
||||||
{
|
{
|
||||||
const vector pos = locations_[i] * axis_;
|
os <<"# ";
|
||||||
|
putTime(os, *timeinfo) << nl;
|
||||||
|
}
|
||||||
|
os <<"# size=" << this->size() << nl
|
||||||
|
<<"# columns (points) (forces)";
|
||||||
|
|
||||||
os << pos.x() << ' '
|
if (writeMoments)
|
||||||
<< pos.y() << ' '
|
{
|
||||||
<< pos.z() << ' ';
|
os << " (moments)";
|
||||||
|
}
|
||||||
|
|
||||||
if (i < forces.size())
|
os << nl;
|
||||||
|
|
||||||
|
bool report = false;
|
||||||
|
scalar scaleLength = scaleOutput_[scalingType::LENGTH];
|
||||||
|
scalar scaleForce = scaleOutput_[scalingType::FORCE];
|
||||||
|
scalar scaleMoment = scaleOutput_[scalingType::MOMENT];
|
||||||
|
|
||||||
|
if (scaleLength > 0)
|
||||||
|
{
|
||||||
|
report = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
scaleLength = 1.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (scaleForce > 0)
|
||||||
|
{
|
||||||
|
report = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
scaleForce = 1.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (writeMoments)
|
||||||
|
{
|
||||||
|
if (scaleMoment > 0)
|
||||||
{
|
{
|
||||||
os << forces[i].x() << ' '
|
report = true;
|
||||||
<< forces[i].y() << ' '
|
|
||||||
<< forces[i].z();
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
os << zeroVector;
|
scaleMoment = 1.0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (report)
|
||||||
|
{
|
||||||
|
os <<"# scaling points=" << scaleLength
|
||||||
|
<<" forces=" << scaleForce;
|
||||||
|
|
||||||
|
if (writeMoments)
|
||||||
|
{
|
||||||
|
os <<" moments=" << scaleMoment;
|
||||||
}
|
}
|
||||||
|
|
||||||
os << nl;
|
os << nl;
|
||||||
|
}
|
||||||
|
|
||||||
|
os <<"########" << nl;
|
||||||
|
|
||||||
|
forAll(locations_, i)
|
||||||
|
{
|
||||||
|
const vector pos = scaleLength * (locations_[i] * axis_);
|
||||||
|
|
||||||
|
putPlain(os, pos) << ' ';
|
||||||
|
|
||||||
|
if (i < forces.size())
|
||||||
|
{
|
||||||
|
const vector val(scaleForce * forces[i]);
|
||||||
|
putPlain(os, val);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
putPlain(os, vector::zero);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (writeMoments)
|
||||||
|
{
|
||||||
|
os << ' ';
|
||||||
|
if (i < moments.size())
|
||||||
|
{
|
||||||
|
const vector val(scaleMoment * moments[i]);
|
||||||
|
putPlain(os, val);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
putPlain(os, vector::zero);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
os << nl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -693,10 +850,21 @@ bool Foam::lumpedPointMovement::writeData
|
|||||||
// - exclude the usual OpenFOAM 'FoamFile' header
|
// - exclude the usual OpenFOAM 'FoamFile' header
|
||||||
// - ensure lists have consistent format
|
// - ensure lists have consistent format
|
||||||
|
|
||||||
os <<"// output from OpenFOAM" << nl << nl;
|
os <<"////////" << nl;
|
||||||
|
if (timeinfo)
|
||||||
|
{
|
||||||
|
os <<"// ";
|
||||||
|
putTime(os, *timeinfo) << nl;
|
||||||
|
}
|
||||||
|
os << nl;
|
||||||
|
|
||||||
writeList(os, "points", (locations_*axis_)());
|
writeList(os, "points", (locations_*axis_)());
|
||||||
writeList(os, "forces", forces);
|
writeList(os, "forces", forces);
|
||||||
|
|
||||||
|
if (writeMoments)
|
||||||
|
{
|
||||||
|
writeList(os, "moments", moments);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@ -706,7 +874,8 @@ bool Foam::lumpedPointMovement::writeData
|
|||||||
bool Foam::lumpedPointMovement::writeData
|
bool Foam::lumpedPointMovement::writeData
|
||||||
(
|
(
|
||||||
const UList<vector>& forces,
|
const UList<vector>& forces,
|
||||||
const UList<vector>& moments
|
const UList<vector>& moments,
|
||||||
|
const Time* timeinfo
|
||||||
) const
|
) const
|
||||||
{
|
{
|
||||||
if (!Pstream::master())
|
if (!Pstream::master())
|
||||||
@ -714,60 +883,28 @@ bool Foam::lumpedPointMovement::writeData
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const fileName output(coupler().resolveFile(outputName_));
|
// Regular output
|
||||||
OFstream os(output); // ASCII
|
|
||||||
|
|
||||||
if (outputFormat_ == outputFormatType::PLAIN)
|
|
||||||
{
|
{
|
||||||
os <<"# output from OpenFOAM" << nl
|
const fileName output(coupler().resolveFile(outputName_));
|
||||||
<<"# N, points, forces, moments" << nl
|
OFstream os(output, IOstream::ASCII);
|
||||||
<< this->size() << nl;
|
|
||||||
|
|
||||||
const char* zeroVector = "0 0 0";
|
writeData(os, forces, moments, outputFormat_, timeinfo);
|
||||||
|
|
||||||
forAll(locations_, i)
|
|
||||||
{
|
|
||||||
const vector pos = locations_[i] * axis_;
|
|
||||||
|
|
||||||
os << pos.x() << ' '
|
|
||||||
<< pos.y() << ' '
|
|
||||||
<< pos.z() << ' ';
|
|
||||||
|
|
||||||
if (i < forces.size())
|
|
||||||
{
|
|
||||||
os << forces[i].x() << ' '
|
|
||||||
<< forces[i].y() << ' '
|
|
||||||
<< forces[i].z() << ' ';
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
os << zeroVector << ' ';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (i < moments.size())
|
|
||||||
{
|
|
||||||
os << moments[i].x() << ' '
|
|
||||||
<< moments[i].y() << ' '
|
|
||||||
<< moments[i].z();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
os << zeroVector;
|
|
||||||
}
|
|
||||||
os << nl;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
|
||||||
|
// Log output
|
||||||
{
|
{
|
||||||
// Make it easier for external programs to parse
|
const fileName output(coupler().resolveFile(logName_));
|
||||||
// - exclude the usual OpenFOAM 'FoamFile' header
|
|
||||||
// - ensure lists have consistent format
|
|
||||||
|
|
||||||
os <<"// output from OpenFOAM" << nl << nl;
|
OFstream os
|
||||||
|
(
|
||||||
|
output,
|
||||||
|
IOstream::ASCII,
|
||||||
|
IOstream::currentVersion,
|
||||||
|
IOstream::UNCOMPRESSED,
|
||||||
|
true // append mode
|
||||||
|
);
|
||||||
|
|
||||||
writeList(os, "points", (locations_*axis_)());
|
writeData(os, forces, moments, outputFormatType::PLAIN, timeinfo);
|
||||||
writeList(os, "forces", forces);
|
|
||||||
writeList(os, "moments", moments);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
========= |
|
========= |
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
\\ / O peration |
|
\\ / O peration |
|
||||||
\\ / A nd | Copyright (C) 2016-2017 OpenCFD Ltd.
|
\\ / A nd | Copyright (C) 2016-2018 OpenCFD Ltd.
|
||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
@ -60,8 +60,10 @@ SourceFiles
|
|||||||
|
|
||||||
namespace Foam
|
namespace Foam
|
||||||
{
|
{
|
||||||
|
|
||||||
// Forward declarations
|
// Forward declarations
|
||||||
class polyMesh;
|
class polyMesh;
|
||||||
|
class Time;
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*\
|
/*---------------------------------------------------------------------------*\
|
||||||
Class lumpedPointMovement Declaration
|
Class lumpedPointMovement Declaration
|
||||||
@ -78,11 +80,22 @@ public:
|
|||||||
DICTIONARY
|
DICTIONARY
|
||||||
};
|
};
|
||||||
|
|
||||||
|
//- Output format types
|
||||||
|
enum scalingType
|
||||||
|
{
|
||||||
|
LENGTH = 0,
|
||||||
|
FORCE,
|
||||||
|
MOMENT
|
||||||
|
};
|
||||||
|
|
||||||
// Static data
|
// Static data
|
||||||
|
|
||||||
//- Names for the output format types
|
//- Names for the output format types
|
||||||
static const Enum<outputFormatType> formatNames;
|
static const Enum<outputFormatType> formatNames;
|
||||||
|
|
||||||
|
//- Names for the scaling types
|
||||||
|
static const Enum<scalingType> scalingNames;
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
@ -125,9 +138,15 @@ private:
|
|||||||
//- File io
|
//- File io
|
||||||
word inputName_;
|
word inputName_;
|
||||||
word outputName_;
|
word outputName_;
|
||||||
|
word logName_;
|
||||||
|
|
||||||
lumpedPointState::inputFormatType inputFormat_;
|
lumpedPointState::inputFormatType inputFormat_;
|
||||||
outputFormatType outputFormat_;
|
outputFormatType outputFormat_;
|
||||||
|
|
||||||
|
//- Optional scale factors for input/output files
|
||||||
|
FixedList<scalar, 1> scaleInput_;
|
||||||
|
FixedList<scalar, 3> scaleOutput_;
|
||||||
|
|
||||||
|
|
||||||
// Demand-driven private data
|
// Demand-driven private data
|
||||||
|
|
||||||
@ -246,6 +265,9 @@ public:
|
|||||||
//- The output (forces) file name
|
//- The output (forces) file name
|
||||||
inline const word& outputName() const;
|
inline const word& outputName() const;
|
||||||
|
|
||||||
|
//- The log file name
|
||||||
|
inline const word& logName() const;
|
||||||
|
|
||||||
//- The input (state) file format
|
//- The input (state) file format
|
||||||
inline lumpedPointState::inputFormatType inputFormat() const;
|
inline lumpedPointState::inputFormatType inputFormat() const;
|
||||||
|
|
||||||
@ -324,21 +346,24 @@ public:
|
|||||||
//- Write axis, locations, division as a dictionary
|
//- Write axis, locations, division as a dictionary
|
||||||
void writeDict(Ostream& os) const;
|
void writeDict(Ostream& os) const;
|
||||||
|
|
||||||
|
//- Write points, forces, moments. Only call from the master process
|
||||||
//- Write points, forces
|
|
||||||
bool writeData
|
bool writeData
|
||||||
(
|
(
|
||||||
const UList<vector>& forces
|
Ostream& os,
|
||||||
|
const UList<vector>& forces,
|
||||||
|
const UList<vector>& moments,
|
||||||
|
const outputFormatType fmt = outputFormatType::PLAIN,
|
||||||
|
const Time* timeinfo = nullptr
|
||||||
) const;
|
) const;
|
||||||
|
|
||||||
//- Write points, forces, moments
|
//- Write points, forces, moments
|
||||||
bool writeData
|
bool writeData
|
||||||
(
|
(
|
||||||
const UList<vector>& forces,
|
const UList<vector>& forces,
|
||||||
const UList<vector>& moments
|
const UList<vector>& moments = List<vector>(),
|
||||||
|
const Time* timeinfo = nullptr
|
||||||
) const;
|
) const;
|
||||||
|
|
||||||
|
|
||||||
//- Read state from file, applying relaxation as requested
|
//- Read state from file, applying relaxation as requested
|
||||||
bool readState();
|
bool readState();
|
||||||
|
|
||||||
|
|||||||
100
src/lumpedPointMotion/lumpedPointMovement.dict
Normal file
100
src/lumpedPointMotion/lumpedPointMovement.dict
Normal file
@ -0,0 +1,100 @@
|
|||||||
|
/*--------------------------------*- C++ -*----------------------------------*\
|
||||||
|
| ========= | |
|
||||||
|
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
|
||||||
|
| \\ / O peration | Version: plus |
|
||||||
|
| \\ / A nd | Web: www.OpenFOAM.com |
|
||||||
|
| \\/ M anipulation | |
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
FoamFile
|
||||||
|
{
|
||||||
|
version 2.0;
|
||||||
|
format ascii;
|
||||||
|
class dictionary;
|
||||||
|
location "system";
|
||||||
|
object lumpedPointMovement;
|
||||||
|
}
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
// Reference axis for the locations
|
||||||
|
axis (0 0 1);
|
||||||
|
|
||||||
|
// Locations of the lumped points
|
||||||
|
locations 11(0 0.05 0.1 0.15 0.2 0.25 0.3 0.35 0.4 0.45 0.5);
|
||||||
|
|
||||||
|
// Division for pressure forces (0-1)
|
||||||
|
division 0.5;
|
||||||
|
|
||||||
|
//- If present, the offset of patch points compared to the locations
|
||||||
|
// Otherwise determined from the bounding box
|
||||||
|
// centre (0 0 0);
|
||||||
|
|
||||||
|
//- The interpolation scheme
|
||||||
|
interpolationScheme linear;
|
||||||
|
|
||||||
|
//- Relaxation/scaling factor when updating positions
|
||||||
|
relax 1.0;
|
||||||
|
|
||||||
|
|
||||||
|
forces
|
||||||
|
{
|
||||||
|
//- The pressure name (default: p)
|
||||||
|
p p;
|
||||||
|
|
||||||
|
//- Reference pressure [Pa] (default: 0)
|
||||||
|
pRef 0;
|
||||||
|
|
||||||
|
//- Reference density for incompressible calculations (default: 1)
|
||||||
|
rhoRef 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
communication
|
||||||
|
{
|
||||||
|
commsDir "comms";
|
||||||
|
|
||||||
|
log on;
|
||||||
|
|
||||||
|
waitInterval 1;
|
||||||
|
|
||||||
|
timeOut 100;
|
||||||
|
|
||||||
|
initByExternal false;
|
||||||
|
|
||||||
|
// Input file of positions/rotation, written by external application
|
||||||
|
inputName positions.in;
|
||||||
|
|
||||||
|
// Output file of forces, written by OpenFOAM
|
||||||
|
outputName forces.out;
|
||||||
|
|
||||||
|
// Log of points/forces/moments during the simulation
|
||||||
|
logName movement.log;
|
||||||
|
|
||||||
|
inputFormat dictionary;
|
||||||
|
outputFormat dictionary;
|
||||||
|
|
||||||
|
debugTable "$FOAM_CASE/output.txt";
|
||||||
|
|
||||||
|
|
||||||
|
// Scaling applied to values read from 'inputName'
|
||||||
|
scaleInput
|
||||||
|
{
|
||||||
|
//- Length multiplier (to metres). Eg 0.001 for [mm] -> [m]
|
||||||
|
length 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Scaling applied to values written to 'outputName'
|
||||||
|
scaleOutput
|
||||||
|
{
|
||||||
|
//- Length multiplier (from metres). Eg 1000 for [m] -> [mm]
|
||||||
|
length 1;
|
||||||
|
|
||||||
|
//- Force units multiplier (from Pa)
|
||||||
|
force 1;
|
||||||
|
|
||||||
|
//- Moment units multiplier (from N.m)
|
||||||
|
moment 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -2,7 +2,7 @@
|
|||||||
========= |
|
========= |
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
\\ / O peration |
|
\\ / O peration |
|
||||||
\\ / A nd | Copyright (C) 2017 OpenCFD Ltd.
|
\\ / A nd | Copyright (C) 2017-2018 OpenCFD Ltd.
|
||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
@ -133,6 +133,12 @@ inline const Foam::word& Foam::lumpedPointMovement::outputName() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline const Foam::word& Foam::lumpedPointMovement::logName() const
|
||||||
|
{
|
||||||
|
return logName_;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
inline Foam::lumpedPointState::inputFormatType
|
inline Foam::lumpedPointState::inputFormatType
|
||||||
Foam::lumpedPointMovement::inputFormat() const
|
Foam::lumpedPointMovement::inputFormat() const
|
||||||
{
|
{
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user