Merge branch 'master' of ssh://dm/home/dm4/OpenFOAM/OpenFOAM-dev

This commit is contained in:
Henry
2011-12-28 17:46:59 +00:00
46 changed files with 1526 additions and 410 deletions

View File

@ -433,7 +433,7 @@ mtype {space}"MTYPE:"{space}
} }
else else
{ {
curGroupID = readLabel(groupStream);; curGroupID = readLabel(groupStream);
} }
BEGIN(cellStreams); BEGIN(cellStreams);

View File

@ -11,4 +11,4 @@ EXE_LIBS = \
-lfiniteVolume \ -lfiniteVolume \
-lgenericPatchFields \ -lgenericPatchFields \
-lrenumberMethods \ -lrenumberMethods \
-ldecompositionMethods -ldecompositionMethods -L$(FOAM_LIBBIN)/dummy -lmetisDecomp -lscotchDecomp

View File

@ -29,7 +29,7 @@ Description
renumbering all fields from all the time directories. renumbering all fields from all the time directories.
By default uses bandCompression (CuthillMcKee) but will By default uses bandCompression (CuthillMcKee) but will
read system/renumberMeshDict if present and use the method from there. read system/renumberMeshDict if -dict option is present
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
@ -45,6 +45,7 @@ Description
#include "renumberMethod.H" #include "renumberMethod.H"
#include "zeroGradientFvPatchFields.H" #include "zeroGradientFvPatchFields.H"
#include "CuthillMcKeeRenumber.H" #include "CuthillMcKeeRenumber.H"
#include "fvMeshSubset.H"
using namespace Foam; using namespace Foam;
@ -455,6 +456,69 @@ autoPtr<mapPolyMesh> reorderMesh
} }
// Return new to old cell numbering
labelList regionRenumber
(
const renumberMethod& method,
const fvMesh& mesh,
const labelList& cellToRegion
)
{
Info<< "Determining cell order:" << endl;
labelList cellOrder(cellToRegion.size());
label nRegions = max(cellToRegion)+1;
labelListList regionToCells(invertOneToMany(nRegions, cellToRegion));
label cellI = 0;
forAll(regionToCells, regionI)
{
Info<< " region " << regionI << " starts at " << cellI << endl;
// Make sure no parallel comms
bool oldParRun = UPstream::parRun();
UPstream::parRun() = false;
// Per region do a reordering.
fvMeshSubset subsetter(mesh);
subsetter.setLargeCellSubset(cellToRegion, regionI);
const fvMesh& subMesh = subsetter.subMesh();
labelList subReverseCellOrder = method.renumber
(
subMesh,
subMesh.cellCentres()
);
labelList subCellOrder
(
invert
(
subMesh.nCells(),
subReverseCellOrder
)
);
// Restore state
UPstream::parRun() = oldParRun;
const labelList& cellMap = subsetter.cellMap();
forAll(subCellOrder, i)
{
cellOrder[cellI++] = cellMap[subCellOrder[i]];
}
}
Info<< endl;
return cellOrder;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
int main(int argc, char *argv[]) int main(int argc, char *argv[])
@ -505,23 +569,28 @@ int main(int argc, char *argv[])
label blockSize = 0; label blockSize = 0;
// Construct renumberMethod // Construct renumberMethod
autoPtr<IOdictionary> renumberDictPtr;
autoPtr<renumberMethod> renumberPtr; autoPtr<renumberMethod> renumberPtr;
if (readDict) if (readDict)
{ {
Info<< "Renumber according to renumberMeshDict." << nl << endl; Info<< "Renumber according to renumberMeshDict." << nl << endl;
IOdictionary renumberDict renumberDictPtr.reset
( (
IOobject new IOdictionary
( (
"renumberMeshDict", IOobject
runTime.system(), (
mesh, "renumberMeshDict",
IOobject::MUST_READ_IF_MODIFIED, runTime.system(),
IOobject::NO_WRITE mesh,
IOobject::MUST_READ_IF_MODIFIED,
IOobject::NO_WRITE
)
) )
); );
const IOdictionary renumberDict = renumberDictPtr();
renumberPtr = renumberMethod::New(renumberDict); renumberPtr = renumberMethod::New(renumberDict);
@ -562,7 +631,7 @@ int main(int argc, char *argv[])
<< endl; << endl;
} }
writeMaps = readLabel(renumberDict.lookup("writeMaps")); renumberDict.lookup("writeMaps") >> writeMaps;
if (writeMaps) if (writeMaps)
{ {
Info<< "Writing renumber maps (new to old) to polyMesh." << nl Info<< "Writing renumber maps (new to old) to polyMesh." << nl
@ -683,22 +752,15 @@ int main(int argc, char *argv[])
// fields is done correctly! // fields is done correctly!
label nBlocks = mesh.nCells() / blockSize; label nBlocks = mesh.nCells() / blockSize;
Info<< "nBlocks = " << nBlocks << endl; Info<< "nBlocks = " << nBlocks << endl;
// Read decomposePar dictionary // Read decompositionMethod dictionary
IOdictionary decomposeDict dictionary decomposeDict(renumberDictPtr().subDict("blockCoeffs"));
(
IOobject
(
"decomposeParDict",
runTime.system(),
mesh,
IOobject::MUST_READ_IF_MODIFIED,
IOobject::NO_WRITE
)
);
decomposeDict.set("numberOfSubdomains", nBlocks); decomposeDict.set("numberOfSubdomains", nBlocks);
bool oldParRun = UPstream::parRun();
UPstream::parRun() = false;
autoPtr<decompositionMethod> decomposePtr = decompositionMethod::New autoPtr<decompositionMethod> decomposePtr = decompositionMethod::New
( (
decomposeDict decomposeDict
@ -713,6 +775,9 @@ int main(int argc, char *argv[])
) )
); );
// Restore state
UPstream::parRun() = oldParRun;
// For debugging: write out region // For debugging: write out region
createScalarField createScalarField
( (
@ -726,23 +791,7 @@ int main(int argc, char *argv[])
<< nl << endl; << nl << endl;
// Find point per region cellOrder = regionRenumber(renumberPtr(), mesh, cellToRegion);
pointField regionPoints(nBlocks, vector::zero);
forAll(cellToRegion, cellI)
{
regionPoints[cellToRegion[cellI]] = mesh.cellCentres()[cellI];
}
// Use block based renumbering.
// Detemines old to new cell ordering
labelList reverseCellOrder = renumberPtr().renumber
(
mesh,
cellToRegion,
regionPoints
);
cellOrder = invert(mesh.nCells(), reverseCellOrder);
// Determine new to old face order with new cell numbering // Determine new to old face order with new cell numbering
faceOrder = getRegionFaceOrder faceOrder = getRegionFaceOrder

View File

@ -22,10 +22,14 @@ writeMaps true;
// e.g. nonBlockingGaussSeidel. // e.g. nonBlockingGaussSeidel.
sortCoupledFaceCells false; sortCoupledFaceCells false;
// Optional entry: renumber on a block-by-block basis. This can be used on // Optional entry: renumber on a block-by-block basis. It uses a
// large cases to keep the blocks fitting in cache with all the the cache // blockCoeffs dictionary to construct a decompositionMethod to do
// missed bunched at the end. // a block subdivision) and then applies the renumberMethod to each
//blockSize 0; // block in turn. This can be used in large cases to keep the blocks
// fitting in cache with all the the cache misses bunched at the end.
// This number is the approximate size of the blocks - this gets converted
// to a number of blocks that is the input to the decomposition method.
//blockSize 1000;
// Optional entry: sort points into internal and boundary points // Optional entry: sort points into internal and boundary points
//orderPoints false; //orderPoints false;
@ -37,11 +41,11 @@ method CuthillMcKee;
//method random; //method random;
//method spring; //method spring;
CuthillMcKeeCoeffs //CuthillMcKeeCoeffs
{ //{
// Reverse CuthillMcKee (RCM) or plain // // Reverse CuthillMcKee (RCM) or plain
reverse true; // reverse true;
} //}
manualCoeffs manualCoeffs
@ -65,4 +69,17 @@ springCoeffs
} }
blockCoeffs
{
method scotch;
//method hierarchical;
//hierarchicalCoeffs
//{
// n (1 2 1);
// delta 0.001;
// order xyz;
//}
}
// ************************************************************************* // // ************************************************************************* //

View File

@ -528,7 +528,7 @@ int main(int argc, char *argv[])
<< "Cell number should be between 0 and " << "Cell number should be between 0 and "
<< mesh.nCells()-1 << nl << mesh.nCells()-1 << nl
<< "On this mesh the particle should be in cell " << "On this mesh the particle should be in cell "
<< mesh.findCell(iter().position()) << mesh.findCell(iter().position())
<< exit(FatalError); << exit(FatalError);
} }
@ -789,6 +789,14 @@ int main(int argc, char *argv[])
// Point fields // Point fields
if
(
pointScalarFields.size()
|| pointVectorFields.size()
|| pointSphericalTensorFields.size()
|| pointSymmTensorFields.size()
|| pointTensorFields.size()
)
{ {
labelIOList pointProcAddressing labelIOList pointProcAddressing
( (

View File

@ -795,9 +795,9 @@ int main(int argc, char *argv[])
); );
fvMesh& mesh = meshPtr(); fvMesh& mesh = meshPtr();
//Pout<< "Read mesh:" << endl; // Print some statistics
//printMeshData(Pout, mesh); Info<< "Before distribution:" << endl;
//Pout<< endl; printMeshData(mesh);
@ -1022,7 +1022,6 @@ int main(int argc, char *argv[])
//map().distributeFaceData(faceCc); //map().distributeFaceData(faceCc);
// Print a bit
// Print some statistics // Print some statistics
Info<< "After distribution:" << endl; Info<< "After distribution:" << endl;
printMeshData(mesh); printMeshData(mesh);

View File

@ -1,6 +1,6 @@
#!/bin/sh #!/bin/sh
cd ${0%/*} || exit 1 # run from this directory cd ${0%/*} || exit 1 # run from this directory
set -x #set -x
if [ -d "$ParaView_DIR" -a -r "$ParaView_DIR" ] if [ -d "$ParaView_DIR" -a -r "$ParaView_DIR" ]
then then
@ -15,6 +15,8 @@ then
wmake libso vtkPV3Readers wmake libso vtkPV3Readers
PV3blockMeshReader/Allwmake PV3blockMeshReader/Allwmake
PV3FoamReader/Allwmake PV3FoamReader/Allwmake
else
echo "ERROR: ParaView not found in $ParaView_DIR"
fi fi
# ----------------------------------------------------------------- end-of-file # ----------------------------------------------------------------- end-of-file

View File

@ -9,5 +9,5 @@ int USERD_get_number_of_files_in_dataset(void)
// use 1 insted of 0 which gives an un-necessary warning. // use 1 insted of 0 which gives an un-necessary warning.
Num_dataset_files = 1; Num_dataset_files = 1;
return Num_dataset_files;; return Num_dataset_files;
} }

View File

@ -1,11 +1,14 @@
EXE_INC = \ EXE_INC = \
-I$(LIB_SRC)/transportModels \ -I$(LIB_SRC)/transportModels \
-I$(LIB_SRC)/turbulenceModels \ -I$(LIB_SRC)/turbulenceModels \
-I$(LIB_SRC)/turbulenceModels/incompressible/RAS/RASModel \ -I$(LIB_SRC)/thermophysicalModels/basic/lnInclude \
-I$(LIB_SRC)/finiteVolume/lnInclude -I$(LIB_SRC)/finiteVolume/lnInclude
EXE_LIBS = \ EXE_LIBS = \
-lincompressibleRASModels \
-lincompressibleTransportModels \ -lincompressibleTransportModels \
-lincompressibleRASModels \
-lbasicThermophysicalModels \
-lspecie \
-lcompressibleRASModels \
-lfiniteVolume \ -lfiniteVolume \
-lgenericPatchFields -lgenericPatchFields

View File

@ -1,22 +0,0 @@
Info<< "Reading field U\n" << endl;
volVectorField U
(
IOobject
(
"U",
runTime.timeName(),
mesh,
IOobject::MUST_READ,
IOobject::AUTO_WRITE
),
mesh
);
# include "createPhi.H"
singlePhaseTransportModel laminarTransport(U, phi);
autoPtr<incompressible::RASModel> RASModel
(
incompressible::RASModel::New(U, phi, laminarTransport)
);

View File

@ -25,23 +25,130 @@ Application
wallShearStress wallShearStress
Description Description
Calculates and writes the wall shear stress, for the specified times. Calculates and reports wall shear stress for all patches, for the
specified times when using RAS turbulence models.
Default behaviour assumes operating in incompressible mode.
Use the -compressible option for compressible RAS cases.
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#include "fvCFD.H" #include "fvCFD.H"
#include "incompressible/singlePhaseTransportModel/singlePhaseTransportModel.H" #include "incompressible/singlePhaseTransportModel/singlePhaseTransportModel.H"
#include "RASModel.H" #include "incompressible/RAS/RASModel/RASModel.H"
#include "basicPsiThermo.H"
#include "compressible/RAS/RASModel/RASModel.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
void calcIncompressible
(
const fvMesh& mesh,
const Time& runTime,
const volVectorField& U,
volVectorField& wallShearStress
)
{
#include "createPhi.H"
singlePhaseTransportModel laminarTransport(U, phi);
autoPtr<incompressible::RASModel> model
(
incompressible::RASModel::New(U, phi, laminarTransport)
);
const volSymmTensorField Reff(model->devReff());
forAll(wallShearStress.boundaryField(), patchI)
{
wallShearStress.boundaryField()[patchI] =
(
-mesh.Sf().boundaryField()[patchI]
/mesh.magSf().boundaryField()[patchI]
) & Reff.boundaryField()[patchI];
}
}
void calcCompressible
(
const fvMesh& mesh,
const Time& runTime,
const volVectorField& U,
volVectorField& wallShearStress
)
{
IOobject rhoHeader
(
"rho",
runTime.timeName(),
mesh,
IOobject::MUST_READ,
IOobject::NO_WRITE
);
if (!rhoHeader.headerOk())
{
Info<< " no rho field" << endl;
return;
}
Info<< "Reading field rho\n" << endl;
volScalarField rho(rhoHeader, mesh);
#include "compressibleCreatePhi.H"
autoPtr<basicPsiThermo> pThermo
(
basicPsiThermo::New(mesh)
);
basicPsiThermo& thermo = pThermo();
autoPtr<compressible::RASModel> model
(
compressible::RASModel::New
(
rho,
U,
phi,
thermo
)
);
const volSymmTensorField Reff(model->devRhoReff());
forAll(wallShearStress.boundaryField(), patchI)
{
wallShearStress.boundaryField()[patchI] =
(
-mesh.Sf().boundaryField()[patchI]
/mesh.magSf().boundaryField()[patchI]
) & Reff.boundaryField()[patchI];
}
}
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
timeSelector::addOptions(); timeSelector::addOptions();
#include "addRegionOption.H"
argList::addBoolOption
(
"compressible",
"calculate compressible wall shear stress"
);
#include "setRootCase.H" #include "setRootCase.H"
#include "createTime.H" #include "createTime.H"
instantList timeDirs = timeSelector::select0(runTime, args); instantList timeDirs = timeSelector::select0(runTime, args);
#include "createMesh.H" #include "createNamedMesh.H"
const bool compressible = args.optionFound("compressible");
forAll(timeDirs, timeI) forAll(timeDirs, timeI)
{ {
@ -49,10 +156,6 @@ int main(int argc, char *argv[])
Info<< "Time = " << runTime.timeName() << endl; Info<< "Time = " << runTime.timeName() << endl;
mesh.readUpdate(); mesh.readUpdate();
#include "createFields.H"
volSymmTensorField Reff(RASModel->devReff());
volVectorField wallShearStress volVectorField wallShearStress
( (
IOobject IOobject
@ -67,19 +170,41 @@ int main(int argc, char *argv[])
dimensionedVector dimensionedVector
( (
"wallShearStress", "wallShearStress",
Reff.dimensions(), sqr(dimLength)/sqr(dimTime),
vector::zero vector::zero
) )
); );
forAll(wallShearStress.boundaryField(), patchi) IOobject UHeader
(
"U",
runTime.timeName(),
mesh,
IOobject::MUST_READ,
IOobject::NO_WRITE
);
if (UHeader.headerOk())
{ {
wallShearStress.boundaryField()[patchi] = Info<< "Reading field U\n" << endl;
( volVectorField U(UHeader, mesh);
-mesh.Sf().boundaryField()[patchi]
/mesh.magSf().boundaryField()[patchi] if (compressible)
) & Reff.boundaryField()[patchi]; {
calcCompressible(mesh, runTime, U, wallShearStress);
}
else
{
calcIncompressible(mesh, runTime, U, wallShearStress);
}
} }
else
{
Info<< " no U field" << endl;
}
Info<< "Writing wall shear stress to field " << wallShearStress.name()
<< nl << endl;
wallShearStress.write(); wallShearStress.write();
} }

View File

@ -35,12 +35,13 @@ License
namespace Foam namespace Foam
{ {
template<class Type> template<class Type, class CombineOp>
void MapConsistentVolFields void MapConsistentVolFields
( (
const IOobjectList& objects, const IOobjectList& objects,
const meshToMesh& meshToMeshInterp, const meshToMesh& meshToMeshInterp,
const meshToMesh::order& mapOrder const meshToMesh::order& mapOrder,
const CombineOp& cop
) )
{ {
const fvMesh& meshSource = meshToMeshInterp.fromMesh(); const fvMesh& meshSource = meshToMeshInterp.fromMesh();
@ -84,7 +85,13 @@ void MapConsistentVolFields
); );
// Interpolate field // Interpolate field
meshToMeshInterp.interpolate(fieldTarget, fieldSource, mapOrder); meshToMeshInterp.interpolate//<Type, eqOp<Type> >
(
fieldTarget,
fieldSource,
mapOrder,
cop
);
// Write field // Write field
fieldTarget.write(); fieldTarget.write();
@ -97,7 +104,12 @@ void MapConsistentVolFields
GeometricField<Type, fvPatchField, volMesh> fieldTarget GeometricField<Type, fvPatchField, volMesh> fieldTarget
( (
fieldTargetIOobject, fieldTargetIOobject,
meshToMeshInterp.interpolate(fieldSource, mapOrder) meshToMeshInterp.interpolate//<Type, eqOp<Type> >
(
fieldSource,
mapOrder,
cop
)
); );
// Write field // Write field

View File

@ -0,0 +1,263 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#ifndef MapMeshes_H
#define MapMeshes_H
#include "MapVolFields.H"
#include "MapConsistentVolFields.H"
#include "mapLagrangian.H"
#include "UnMapped.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
template<template<class> class CombineOp>
void MapConsistentMesh
(
const fvMesh& meshSource,
const fvMesh& meshTarget,
const meshToMesh::order& mapOrder
)
{
// Create the interpolation scheme
meshToMesh meshToMeshInterp(meshSource, meshTarget);
Info<< nl
<< "Consistently creating and mapping fields for time "
<< meshSource.time().timeName() << nl << endl;
{
// Search for list of objects for this time
IOobjectList objects(meshSource, meshSource.time().timeName());
// Map volFields
// ~~~~~~~~~~~~~
MapConsistentVolFields<scalar>
(
objects,
meshToMeshInterp,
mapOrder,
CombineOp<scalar>()
);
MapConsistentVolFields<vector>
(
objects,
meshToMeshInterp,
mapOrder,
CombineOp<vector>()
);
MapConsistentVolFields<sphericalTensor>
(
objects,
meshToMeshInterp,
mapOrder,
CombineOp<sphericalTensor>()
);
MapConsistentVolFields<symmTensor>
(
objects,
meshToMeshInterp,
mapOrder,
CombineOp<symmTensor>()
);
MapConsistentVolFields<tensor>
(
objects,
meshToMeshInterp,
mapOrder,
CombineOp<tensor>()
);
}
{
// Search for list of target objects for this time
IOobjectList objects(meshTarget, meshTarget.time().timeName());
// Mark surfaceFields as unmapped
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
UnMapped<surfaceScalarField>(objects);
UnMapped<surfaceVectorField>(objects);
UnMapped<surfaceSphericalTensorField>(objects);
UnMapped<surfaceSymmTensorField>(objects);
UnMapped<surfaceTensorField>(objects);
// Mark pointFields as unmapped
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
UnMapped<pointScalarField>(objects);
UnMapped<pointVectorField>(objects);
UnMapped<pointSphericalTensorField>(objects);
UnMapped<pointSymmTensorField>(objects);
UnMapped<pointTensorField>(objects);
}
mapLagrangian(meshToMeshInterp);
}
template<template<class> class CombineOp>
void MapSubMesh
(
const fvMesh& meshSource,
const fvMesh& meshTarget,
const HashTable<word>& patchMap,
const wordList& cuttingPatches,
const meshToMesh::order& mapOrder
)
{
// Create the interpolation scheme
meshToMesh meshToMeshInterp
(
meshSource,
meshTarget,
patchMap,
cuttingPatches
);
Info<< nl
<< "Mapping fields for time " << meshSource.time().timeName()
<< nl << endl;
{
// Search for list of source objects for this time
IOobjectList objects(meshSource, meshSource.time().timeName());
// Map volFields
// ~~~~~~~~~~~~~
MapVolFields<scalar>
(
objects,
meshToMeshInterp,
mapOrder,
CombineOp<scalar>()
);
MapVolFields<vector>
(
objects,
meshToMeshInterp,
mapOrder,
CombineOp<vector>()
);
MapVolFields<sphericalTensor>
(
objects,
meshToMeshInterp,
mapOrder,
CombineOp<sphericalTensor>()
);
MapVolFields<symmTensor>
(
objects,
meshToMeshInterp,
mapOrder,
CombineOp<symmTensor>()
);
MapVolFields<tensor>
(
objects,
meshToMeshInterp,
mapOrder,
CombineOp<tensor>()
);
}
{
// Search for list of target objects for this time
IOobjectList objects(meshTarget, meshTarget.time().timeName());
// Mark surfaceFields as unmapped
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
UnMapped<surfaceScalarField>(objects);
UnMapped<surfaceVectorField>(objects);
UnMapped<surfaceSphericalTensorField>(objects);
UnMapped<surfaceSymmTensorField>(objects);
UnMapped<surfaceTensorField>(objects);
// Mark pointFields as unmapped
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
UnMapped<pointScalarField>(objects);
UnMapped<pointVectorField>(objects);
UnMapped<pointSphericalTensorField>(objects);
UnMapped<pointSymmTensorField>(objects);
UnMapped<pointTensorField>(objects);
}
mapLagrangian(meshToMeshInterp);
}
template<template<class> class CombineOp>
void MapConsistentSubMesh
(
const fvMesh& meshSource,
const fvMesh& meshTarget,
const meshToMesh::order& mapOrder
)
{
HashTable<word> patchMap;
HashTable<label> cuttingPatchTable;
forAll(meshTarget.boundary(), patchi)
{
if (!isA<processorFvPatch>(meshTarget.boundary()[patchi]))
{
patchMap.insert
(
meshTarget.boundary()[patchi].name(),
meshTarget.boundary()[patchi].name()
);
}
else
{
cuttingPatchTable.insert
(
meshTarget.boundaryMesh()[patchi].name(),
-1
);
}
}
MapSubMesh<CombineOp>
(
meshSource,
meshTarget,
patchMap,
cuttingPatchTable.toc(),
mapOrder
);
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -35,12 +35,13 @@ License
namespace Foam namespace Foam
{ {
template<class Type> template<class Type, class CombineOp>
void MapVolFields void MapVolFields
( (
const IOobjectList& objects, const IOobjectList& objects,
const meshToMesh& meshToMeshInterp, const meshToMesh& meshToMeshInterp,
const meshToMesh::order& mapOrder const meshToMesh::order& mapOrder,
const CombineOp& cop
) )
{ {
const fvMesh& meshSource = meshToMeshInterp.fromMesh(); const fvMesh& meshSource = meshToMeshInterp.fromMesh();
@ -84,7 +85,13 @@ void MapVolFields
); );
// Interpolate field // Interpolate field
meshToMeshInterp.interpolate(fieldTarget, fieldSource, mapOrder); meshToMeshInterp.interpolate//<Type, eqOp<Type> >
(
fieldTarget,
fieldSource,
mapOrder,
cop
);
// Write field // Write field
fieldTarget.write(); fieldTarget.write();

View File

@ -34,11 +34,8 @@ Description
#include "fvCFD.H" #include "fvCFD.H"
#include "meshToMesh.H" #include "meshToMesh.H"
#include "MapVolFields.H"
#include "MapConsistentVolFields.H"
#include "UnMapped.H"
#include "processorFvPatch.H" #include "processorFvPatch.H"
#include "mapLagrangian.H" #include "MapMeshes.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -46,56 +43,28 @@ void mapConsistentMesh
( (
const fvMesh& meshSource, const fvMesh& meshSource,
const fvMesh& meshTarget, const fvMesh& meshTarget,
const meshToMesh::order& mapOrder const meshToMesh::order& mapOrder,
const bool subtract
) )
{ {
// Create the interpolation scheme if (subtract)
meshToMesh meshToMeshInterp(meshSource, meshTarget);
Info<< nl
<< "Consistently creating and mapping fields for time "
<< meshSource.time().timeName() << nl << endl;
{ {
// Search for list of objects for this time MapConsistentMesh<minusEqOp>
IOobjectList objects(meshSource, meshSource.time().timeName());
// Map volFields
// ~~~~~~~~~~~~~
MapConsistentVolFields<scalar>(objects, meshToMeshInterp, mapOrder);
MapConsistentVolFields<vector>(objects, meshToMeshInterp, mapOrder);
MapConsistentVolFields<sphericalTensor>
( (
objects, meshSource,
meshToMeshInterp, meshTarget,
mapOrder mapOrder
); );
MapConsistentVolFields<symmTensor>(objects, meshToMeshInterp, mapOrder);
MapConsistentVolFields<tensor>(objects, meshToMeshInterp, mapOrder);
} }
else
{ {
// Search for list of target objects for this time MapConsistentMesh<eqOp>
IOobjectList objects(meshTarget, meshTarget.time().timeName()); (
meshSource,
// Mark surfaceFields as unmapped meshTarget,
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ mapOrder
UnMapped<surfaceScalarField>(objects); );
UnMapped<surfaceVectorField>(objects);
UnMapped<surfaceSphericalTensorField>(objects);
UnMapped<surfaceSymmTensorField>(objects);
UnMapped<surfaceTensorField>(objects);
// Mark pointFields as unmapped
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
UnMapped<pointScalarField>(objects);
UnMapped<pointVectorField>(objects);
UnMapped<pointSphericalTensorField>(objects);
UnMapped<pointSymmTensorField>(objects);
UnMapped<pointTensorField>(objects);
} }
mapLagrangian(meshToMeshInterp);
} }
@ -105,57 +74,32 @@ void mapSubMesh
const fvMesh& meshTarget, const fvMesh& meshTarget,
const HashTable<word>& patchMap, const HashTable<word>& patchMap,
const wordList& cuttingPatches, const wordList& cuttingPatches,
const meshToMesh::order& mapOrder const meshToMesh::order& mapOrder,
const bool subtract
) )
{ {
// Create the interpolation scheme if (subtract)
meshToMesh meshToMeshInterp
(
meshSource,
meshTarget,
patchMap,
cuttingPatches
);
Info<< nl
<< "Mapping fields for time " << meshSource.time().timeName()
<< nl << endl;
{ {
// Search for list of source objects for this time MapSubMesh<minusEqOp>
IOobjectList objects(meshSource, meshSource.time().timeName()); (
meshSource,
// Map volFields meshTarget,
// ~~~~~~~~~~~~~ patchMap,
MapVolFields<scalar>(objects, meshToMeshInterp, mapOrder); cuttingPatches,
MapVolFields<vector>(objects, meshToMeshInterp, mapOrder); mapOrder
MapVolFields<sphericalTensor>(objects, meshToMeshInterp, mapOrder); );
MapVolFields<symmTensor>(objects, meshToMeshInterp, mapOrder);
MapVolFields<tensor>(objects, meshToMeshInterp, mapOrder);
} }
else
{ {
// Search for list of target objects for this time MapSubMesh<eqOp>
IOobjectList objects(meshTarget, meshTarget.time().timeName()); (
meshSource,
// Mark surfaceFields as unmapped meshTarget,
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ patchMap,
UnMapped<surfaceScalarField>(objects); cuttingPatches,
UnMapped<surfaceVectorField>(objects); mapOrder
UnMapped<surfaceSphericalTensorField>(objects); );
UnMapped<surfaceSymmTensorField>(objects);
UnMapped<surfaceTensorField>(objects);
// Mark pointFields as unmapped
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
UnMapped<pointScalarField>(objects);
UnMapped<pointVectorField>(objects);
UnMapped<pointSphericalTensorField>(objects);
UnMapped<pointSymmTensorField>(objects);
UnMapped<pointTensorField>(objects);
} }
mapLagrangian(meshToMeshInterp);
} }
@ -163,40 +107,28 @@ void mapConsistentSubMesh
( (
const fvMesh& meshSource, const fvMesh& meshSource,
const fvMesh& meshTarget, const fvMesh& meshTarget,
const meshToMesh::order& mapOrder const meshToMesh::order& mapOrder,
const bool subtract
) )
{ {
HashTable<word> patchMap; if (subtract)
HashTable<label> cuttingPatchTable;
forAll(meshTarget.boundary(), patchi)
{ {
if (!isA<processorFvPatch>(meshTarget.boundary()[patchi])) MapConsistentSubMesh<minusEqOp>
{ (
patchMap.insert meshSource,
( meshTarget,
meshTarget.boundary()[patchi].name(), mapOrder
meshTarget.boundary()[patchi].name() );
); }
} else
else {
{ MapConsistentSubMesh<eqOp>
cuttingPatchTable.insert (
( meshSource,
meshTarget.boundaryMesh()[patchi].name(), meshTarget,
-1 mapOrder
); );
}
} }
mapSubMesh
(
meshSource,
meshTarget,
patchMap,
cuttingPatchTable.toc(),
mapOrder
);
} }
@ -288,6 +220,11 @@ int main(int argc, char *argv[])
"word", "word",
"specify the mapping method" "specify the mapping method"
); );
argList::addBoolOption
(
"subtract",
"subtract mapped source from target"
);
argList args(argc, argv); argList args(argc, argv);
@ -350,6 +287,13 @@ int main(int argc, char *argv[])
Info<< "Mapping method: " << mapMethod << endl; Info<< "Mapping method: " << mapMethod << endl;
} }
const bool subtract = args.optionFound("subtract");
if (subtract)
{
Info<< "Subtracting mapped source field from target" << endl;
}
#include "createTimes.H" #include "createTimes.H"
HashTable<word> patchMap; HashTable<word> patchMap;
@ -431,7 +375,13 @@ int main(int argc, char *argv[])
if (consistent) if (consistent)
{ {
mapConsistentSubMesh(meshSource, meshTarget, mapOrder); mapConsistentSubMesh
(
meshSource,
meshTarget,
mapOrder,
subtract
);
} }
else else
{ {
@ -441,7 +391,8 @@ int main(int argc, char *argv[])
meshTarget, meshTarget,
patchMap, patchMap,
cuttingPatches, cuttingPatches,
mapOrder mapOrder,
subtract
); );
} }
} }
@ -503,7 +454,13 @@ int main(int argc, char *argv[])
if (consistent) if (consistent)
{ {
mapConsistentSubMesh(meshSource, meshTarget, mapOrder); mapConsistentSubMesh
(
meshSource,
meshTarget,
mapOrder,
subtract
);
} }
else else
{ {
@ -513,7 +470,8 @@ int main(int argc, char *argv[])
meshTarget, meshTarget,
patchMap, patchMap,
addProcessorPatches(meshTarget, cuttingPatches), addProcessorPatches(meshTarget, cuttingPatches),
mapOrder mapOrder,
subtract
); );
} }
} }
@ -629,7 +587,8 @@ int main(int argc, char *argv[])
( (
meshSource, meshSource,
meshTarget, meshTarget,
mapOrder mapOrder,
subtract
); );
} }
else else
@ -640,7 +599,8 @@ int main(int argc, char *argv[])
meshTarget, meshTarget,
patchMap, patchMap,
addProcessorPatches(meshTarget, cuttingPatches), addProcessorPatches(meshTarget, cuttingPatches),
mapOrder mapOrder,
subtract
); );
} }
} }
@ -679,7 +639,7 @@ int main(int argc, char *argv[])
if (consistent) if (consistent)
{ {
mapConsistentMesh(meshSource, meshTarget, mapOrder); mapConsistentMesh(meshSource, meshTarget, mapOrder, subtract);
} }
else else
{ {
@ -689,7 +649,8 @@ int main(int argc, char *argv[])
meshTarget, meshTarget,
patchMap, patchMap,
cuttingPatches, cuttingPatches,
mapOrder mapOrder,
subtract
); );
} }
} }

View File

@ -46,7 +46,7 @@ wmake $makeType genericPatchFields
# Build the proper scotchDecomp, metisDecomp etc. # Build the proper scotchDecomp, metisDecomp etc.
parallel/Allwmake $* parallel/Allwmake $*
wmake $makeType renumberMethods renumber/Allwmake $*
wmake $makeType conversion wmake $makeType conversion

View File

@ -144,11 +144,13 @@ public:
inline tetPointRef oldTet(const polyMesh& mesh) const; inline tetPointRef oldTet(const polyMesh& mesh) const;
//- Return the geometry corresponding to the tri on the //- Return the geometry corresponding to the tri on the
// mesh face for this tet from the supplied mesh // mesh face for this tet from the supplied mesh. Normal of
// the tri points out of the cell.
inline triPointRef faceTri(const polyMesh& mesh) const; inline triPointRef faceTri(const polyMesh& mesh) const;
//- Return the point indices corresponding to the tri on the mesh //- Return the point indices corresponding to the tri on the mesh
// face for this tet from the supplied mesh // face for this tet from the supplied mesh. Normal of
// the tri points out of the cell.
inline triFace faceTriIs(const polyMesh& mesh) const; inline triFace faceTriIs(const polyMesh& mesh) const;
//- Return the geometry corresponding to the tri on the //- Return the geometry corresponding to the tri on the

View File

@ -277,9 +277,9 @@ Foam::scalar Foam::triangle<Point, PointRef>::barycentric
bary.setSize(3); bary.setSize(3);
bary[0] = (d11*d20 - d01*d21)/denom; bary[1] = (d11*d20 - d01*d21)/denom;
bary[1] = (d00*d21 - d01*d20)/denom; bary[2] = (d00*d21 - d01*d20)/denom;
bary[2] = 1.0 - bary[0] - bary[1]; bary[0] = 1.0 - bary[1] - bary[2];
return denom; return denom;
} }

View File

@ -196,9 +196,10 @@ bool Foam::pimpleControl::loop()
bool completed = false; bool completed = false;
if (criteriaSatisfied()) if (criteriaSatisfied())
{ {
Info<< algorithmName_ << ": converged in " << corr_ << " iterations" Info<< algorithmName_ << ": converged in " << corr_ - 1 << " iterations"
<< endl; << endl;
completed = true; completed = true;
corr_ = 0;
} }
else else
{ {

View File

@ -83,8 +83,8 @@ void Foam::cellPointWeight::findTetrahedron
) )
{ {
faceVertices_[0] = f[tetIs.faceBasePt()]; faceVertices_[0] = f[tetIs.faceBasePt()];
faceVertices_[1] = f[tetIs.facePtA()];; faceVertices_[1] = f[tetIs.facePtA()];
faceVertices_[2] = f[tetIs.facePtB()];; faceVertices_[2] = f[tetIs.facePtB()];
return; return;
} }
@ -191,8 +191,8 @@ void Foam::cellPointWeight::findTriangle
weights_[3] = triWeights[2]; weights_[3] = triWeights[2];
faceVertices_[0] = f[tetIs.faceBasePt()]; faceVertices_[0] = f[tetIs.faceBasePt()];
faceVertices_[1] = f[tetIs.facePtA()];; faceVertices_[1] = f[tetIs.facePtA()];
faceVertices_[2] = f[tetIs.facePtB()];; faceVertices_[2] = f[tetIs.facePtB()];
return; return;
} }

View File

@ -286,6 +286,10 @@ bool Foam::meshRefinement::isCollapsedFace
const label faceI const label faceI
) const ) const
{ {
// Severe nonorthogonality threshold
const scalar severeNonorthogonalityThreshold =
::cos(degToRad(maxNonOrtho));
vector s = mesh_.faces()[faceI].normal(points); vector s = mesh_.faces()[faceI].normal(points);
scalar magS = mag(s); scalar magS = mag(s);
@ -301,11 +305,11 @@ bool Foam::meshRefinement::isCollapsedFace
if (mesh_.isInternalFace(faceI)) if (mesh_.isInternalFace(faceI))
{ {
label nei = mesh_.faceNeighbour()[faceI]; label nei = mesh_.faceNeighbour()[faceI];
vector d = ownCc - mesh_.cellCentres()[nei]; vector d = mesh_.cellCentres()[nei] - ownCc;
scalar dDotS = (d & s)/(mag(d)*magS + VSMALL); scalar dDotS = (d & s)/(mag(d)*magS + VSMALL);
if (dDotS < maxNonOrtho) if (dDotS < severeNonorthogonalityThreshold)
{ {
return true; return true;
} }
@ -320,11 +324,11 @@ bool Foam::meshRefinement::isCollapsedFace
if (mesh_.boundaryMesh()[patchI].coupled()) if (mesh_.boundaryMesh()[patchI].coupled())
{ {
vector d = ownCc - neiCc[faceI-mesh_.nInternalFaces()]; vector d = neiCc[faceI-mesh_.nInternalFaces()] - ownCc;
scalar dDotS = (d & s)/(mag(d)*magS + VSMALL); scalar dDotS = (d & s)/(mag(d)*magS + VSMALL);
if (dDotS < maxNonOrtho) if (dDotS < severeNonorthogonalityThreshold)
{ {
return true; return true;
} }
@ -337,7 +341,7 @@ bool Foam::meshRefinement::isCollapsedFace
{ {
// Collapsing normal boundary face does not cause problems with // Collapsing normal boundary face does not cause problems with
// non-orthogonality // non-orthogonality
return true; return false;
} }
} }
} }
@ -663,7 +667,8 @@ Foam::labelList Foam::meshRefinement::markFacesOnProblemCells
) )
{ {
nPrevented++; nPrevented++;
//Pout<< "Preventing collapse of 8 anchor point cell " //Pout<< "Preventing baffling/removal of 8 anchor point"
// << " cell "
// << cellI << " at " << mesh_.cellCentres()[cellI] // << cellI << " at " << mesh_.cellCentres()[cellI]
// << " since new volume " // << " since new volume "
// << mesh_.cells()[cellI].mag(newPoints, mesh_.faces()) // << mesh_.cells()[cellI].mag(newPoints, mesh_.faces())
@ -747,7 +752,7 @@ Foam::labelList Foam::meshRefinement::markFacesOnProblemCells
) )
{ {
nPrevented++; nPrevented++;
//Pout<< "Preventing collapse of 7 anchor cell " //Pout<< "Preventing baffling of 7 anchor cell "
// << cellI // << cellI
// << " at " << mesh_.cellCentres()[cellI] // << " at " << mesh_.cellCentres()[cellI]
// << " since new volume " // << " since new volume "
@ -853,7 +858,8 @@ Foam::labelList Foam::meshRefinement::markFacesOnProblemCells
) )
{ {
nPrevented++; nPrevented++;
//Pout<< "Preventing collapse of face " << faceI //Pout<< "Preventing baffling (to avoid collapse) of face "
// << faceI
// << " with all boundary edges " // << " with all boundary edges "
// << " at " << mesh_.faceCentres()[faceI] // << " at " << mesh_.faceCentres()[faceI]
// << endl; // << endl;
@ -909,7 +915,7 @@ Foam::labelList Foam::meshRefinement::markFacesOnProblemCells
) )
{ {
nPrevented++; nPrevented++;
//Pout<< "Preventing collapse of coupled face " //Pout<< "Preventing baffling of coupled face "
// << faceI // << faceI
// << " with all boundary edges " // << " with all boundary edges "
// << " at " << mesh_.faceCentres()[faceI] // << " at " << mesh_.faceCentres()[faceI]
@ -943,7 +949,7 @@ Foam::labelList Foam::meshRefinement::markFacesOnProblemCells
{ {
Info<< "markFacesOnProblemCells : prevented " Info<< "markFacesOnProblemCells : prevented "
<< returnReduce(nPrevented, sumOp<label>()) << returnReduce(nPrevented, sumOp<label>())
<< " internal faces fom getting converted into baffles." << " internal faces from getting converted into baffles."
<< endl; << endl;
} }

View File

@ -236,8 +236,8 @@ void Foam::decompositionMethod::calcCellCells
label globalNei = globalNeighbour[bFaceI]; label globalNei = globalNeighbour[bFaceI];
if if
( (
globalAgglom.isLocal(globalNei) !globalAgglom.isLocal(globalNei)
&& globalAgglom.toLocal(globalNei) != own || globalAgglom.toLocal(globalNei) != own
) )
{ {
nFacesPerCell[own]++; nFacesPerCell[own]++;
@ -285,10 +285,11 @@ void Foam::decompositionMethod::calcCellCells
label own = agglom[faceOwner[faceI]]; label own = agglom[faceOwner[faceI]];
label globalNei = globalNeighbour[bFaceI]; label globalNei = globalNeighbour[bFaceI];
if if
( (
globalAgglom.isLocal(globalNei) !globalAgglom.isLocal(globalNei)
&& globalAgglom.toLocal(globalNei) != own || globalAgglom.toLocal(globalNei) != own
) )
{ {
m[offsets[own] + nFacesPerCell[own]++] = globalNei; m[offsets[own] + nFacesPerCell[own]++] = globalNei;
@ -304,15 +305,15 @@ void Foam::decompositionMethod::calcCellCells
// Check for duplicates connections between cells // Check for duplicates connections between cells
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Done as postprocessing step since we now have cellCells. // Done as postprocessing step since we now have cellCells.
label startIndex = 0;
label newIndex = 0; label newIndex = 0;
labelHashSet nbrCells; labelHashSet nbrCells;
forAll(cellCells, cellI) forAll(cellCells, cellI)
{ {
nbrCells.clear(); nbrCells.clear();
nbrCells.insert(cellI); nbrCells.insert(globalAgglom.toGlobal(cellI));
label& endIndex = cellCells.offsets()[cellI+1]; label startIndex = cellCells.offsets()[cellI];
label endIndex = cellCells.offsets()[cellI+1];
for (label i = startIndex; i < endIndex; i++) for (label i = startIndex; i < endIndex; i++)
{ {
@ -321,9 +322,7 @@ void Foam::decompositionMethod::calcCellCells
cellCells.m()[newIndex++] = cellCells.m()[i]; cellCells.m()[newIndex++] = cellCells.m()[i];
} }
} }
cellCells.offsets()[cellI+1] = newIndex;
startIndex = endIndex;
endIndex = newIndex;
} }
cellCells.m().setSize(newIndex); cellCells.m().setSize(newIndex);

View File

@ -371,29 +371,6 @@ Foam::label Foam::ptscotchDecomp::decompose
Pout<< "ptscotchDecomp : entering with xadj:" << xadj.size() << endl; Pout<< "ptscotchDecomp : entering with xadj:" << xadj.size() << endl;
} }
if (debug)
{
Pout<< "nProcessors_:" << nProcessors_ << endl;
globalIndex globalCells(xadj.size()-1);
Pout<< "Xadj:" << endl;
for (label cellI = 0; cellI < xadj.size()-1; cellI++)
{
Pout<< "cell:" << cellI
<< " global:" << globalCells.toGlobal(cellI)
<< " connected to:" << endl;
label start = xadj[cellI];
label end = xadj[cellI+1];
for (label i = start; i < end; i++)
{
Pout<< " cell:" << adjncy[i] << endl;
}
}
Pout<< endl;
}
// Dump graph // Dump graph
if (decompositionDict_.found("ptscotchCoeffs")) if (decompositionDict_.found("ptscotchCoeffs"))
{ {

View File

@ -34,6 +34,7 @@ License
#include "globalIndex.H" #include "globalIndex.H"
#include "mapDistribute.H" #include "mapDistribute.H"
#include "interpolationCellPoint.H" #include "interpolationCellPoint.H"
#include "PatchTools.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
@ -41,6 +42,57 @@ defineTypeNameAndDebug(Foam::streamLine, 0);
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
Foam::autoPtr<Foam::indirectPrimitivePatch>
Foam::streamLine::wallPatch() const
{
const fvMesh& mesh = dynamic_cast<const fvMesh&>(obr_);
const polyBoundaryMesh& patches = mesh.boundaryMesh();
label nFaces = 0;
forAll(patches, patchI)
{
//if (!polyPatch::constraintType(patches[patchI].type()))
if (isA<wallPolyPatch>(patches[patchI]))
{
nFaces += patches[patchI].size();
}
}
labelList addressing(nFaces);
nFaces = 0;
forAll(patches, patchI)
{
//if (!polyPatch::constraintType(patches[patchI].type()))
if (isA<wallPolyPatch>(patches[patchI]))
{
const polyPatch& pp = patches[patchI];
forAll(pp, i)
{
addressing[nFaces++] = pp.start()+i;
}
}
}
return autoPtr<indirectPrimitivePatch>
(
new indirectPrimitivePatch
(
IndirectList<face>
(
mesh.faces(),
addressing
),
mesh.points()
)
);
}
void Foam::streamLine::track() void Foam::streamLine::track()
{ {
const Time& runTime = obr_.time(); const Time& runTime = obr_.time();
@ -72,7 +124,7 @@ void Foam::streamLine::track()
label nSeeds = returnReduce(particles.size(), sumOp<label>()); label nSeeds = returnReduce(particles.size(), sumOp<label>());
Info<< "Seeded " << nSeeds << " particles." << endl; Info<< type() << " : seeded " << nSeeds << " particles." << endl;
// Read or lookup fields // Read or lookup fields
PtrList<volScalarField> vsFlds; PtrList<volScalarField> vsFlds;
@ -163,7 +215,6 @@ void Foam::streamLine::track()
vsInterp.set vsInterp.set
( (
nScalar++, nScalar++,
//new interpolationCellPoint<scalar>(f)
interpolation<scalar>::New interpolation<scalar>::New
( (
interpolationScheme_, interpolationScheme_,
@ -186,7 +237,6 @@ void Foam::streamLine::track()
vvInterp.set vvInterp.set
( (
nVector++, nVector++,
//new interpolationCellPoint<vector>(f)
interpolation<vector>::New interpolation<vector>::New
( (
interpolationScheme_, interpolationScheme_,
@ -241,6 +291,120 @@ void Foam::streamLine::track()
allVectors_[i].setCapacity(nSeeds); allVectors_[i].setCapacity(nSeeds);
} }
//- For surface following: per face the normal to constrain the velocity
// with.
pointField patchNormals;
if (followSurface_)
{
// Determine geometric data on the non-constraint patches
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// - point normals
// - neighbouring cells
autoPtr<indirectPrimitivePatch> boundaryPatch(wallPatch());
// Calculate parallel consistent normal (on boundaryPatch points only)
pointField boundaryNormals
(
PatchTools::pointNormals
(
mesh,
boundaryPatch(),
boundaryPatch().addressing()
)
);
// Make sure all points know about point normal. There might be points
// which are not on boundaryPatch() but coupled to points that are.
pointField pointNormals(mesh.nPoints(), vector::zero);
UIndirectList<point>
(
pointNormals,
boundaryPatch().meshPoints()
) = boundaryNormals;
boundaryNormals.clear();
mesh.globalData().syncPointData
(
pointNormals,
maxMagSqrEqOp<point>(),
mapDistribute::transform()
);
// Calculate per-face a single constraint normal:
// - faces on patch: face-normal
// - faces on cell with point on patch: point-normal
// - rest: vector::zero
//
// Note: the disadvantage is that we can only handle faces with one
// point on the patch - otherwise we might pick up the wrong
// velocity.
patchNormals.setSize(mesh.nFaces(), vector::zero);
label nPointNormals = 0;
// 1. faces on patch
UIndirectList<point>(patchNormals, boundaryPatch().addressing()) =
boundaryPatch().faceNormals();
// 2. faces with a point on the patch
forAll(mesh.faces(), faceI)
{
if (patchNormals[faceI] == vector::zero)
{
const face& f = mesh.faces()[faceI];
forAll(f, fp)
{
label pointI = f[fp];
if (pointNormals[pointI] != vector::zero)
{
patchNormals[faceI] = pointNormals[pointI];
nPointNormals++;
}
}
}
}
// 3. cells on faces with a point on the patch
forAll(mesh.points(), pointI)
{
if (pointNormals[pointI] != vector::zero)
{
const labelList& pCells = mesh.pointCells(pointI);
forAll(pCells, i)
{
const cell& cFaces = mesh.cells()[pCells[i]];
forAll(cFaces, j)
{
label faceI = cFaces[j];
if (patchNormals[faceI] == vector::zero)
{
patchNormals[faceI] = pointNormals[pointI];
nPointNormals++;
}
}
}
}
}
Info<< type() << " : calculated constrained-tracking normals" << nl
<< "Number of faces in mesh : "
<< returnReduce(mesh.nFaces(), sumOp<label>()) << nl
<< " of which on walls : "
<< returnReduce
(
boundaryPatch().addressing().size(),
sumOp<label>()
) << nl
<< " of which on cell with point on boundary : "
<< returnReduce(nPointNormals, sumOp<label>()) << nl
<< endl;
}
// additional particle info // additional particle info
streamLineParticle::trackingData td streamLineParticle::trackingData td
( (
@ -248,8 +412,16 @@ void Foam::streamLine::track()
vsInterp, vsInterp,
vvInterp, vvInterp,
UIndex, // index of U in vvInterp UIndex, // index of U in vvInterp
trackForward_, // track in +u direction trackForward_, // track in +u direction?
nSubCycle_, // step through cells in steps? nSubCycle_, // automatic track control:step through cells in steps?
trackLength_, // fixed track length
//- For surface-constrained streamlines
followSurface_, // stay on surface?
patchNormals, // per face normal to constrain tracking to
//pointNormals, // per point ,,
trackHeight_, // track height
allTracks_, allTracks_,
allScalars_, allScalars_,
allVectors_ allVectors_
@ -279,7 +451,8 @@ Foam::streamLine::streamLine
name_(name), name_(name),
obr_(obr), obr_(obr),
loadFromFiles_(loadFromFiles), loadFromFiles_(loadFromFiles),
active_(true) active_(true),
nSubCycle_(0)
{ {
// Only active if a fvMesh is available // Only active if a fvMesh is available
if (isA<fvMesh>(obr_)) if (isA<fvMesh>(obr_))
@ -334,6 +507,16 @@ void Foam::streamLine::read(const dictionary& dict)
dict.lookup("U") >> UName_; dict.lookup("U") >> UName_;
} }
} }
if (findIndex(fields_, UName_) == -1)
{
FatalIOErrorIn("streamLine::read(const dictionary&)", dict)
<< "Velocity field for tracking " << UName_
<< " should be present in the list of fields " << fields_
<< exit(FatalIOError);
}
dict.lookup("trackForward") >> trackForward_; dict.lookup("trackForward") >> trackForward_;
dict.lookup("lifeTime") >> lifeTime_; dict.lookup("lifeTime") >> lifeTime_;
if (lifeTime_ < 1) if (lifeTime_ < 1)
@ -343,10 +526,48 @@ void Foam::streamLine::read(const dictionary& dict)
<< exit(FatalError); << exit(FatalError);
} }
dict.lookup("nSubCycle") >> nSubCycle_;
if (nSubCycle_ < 1) bool subCycling = dict.found("nSubCycle");
bool fixedLength = dict.found("trackLength");
if (subCycling && fixedLength)
{ {
nSubCycle_ = 1; FatalIOErrorIn("streamLine::read(const dictionary&)", dict)
<< "Cannot both specify automatic time stepping (through '"
<< "nSubCycle' specification) and fixed track length (through '"
<< "trackLength')"
<< exit(FatalIOError);
}
nSubCycle_ = 1;
if (dict.readIfPresent("nSubCycle", nSubCycle_))
{
trackLength_ = VGREAT;
if (nSubCycle_ < 1)
{
nSubCycle_ = 1;
}
Info<< type() << " : automatic track length specified through"
<< " number of sub cycles : " << nSubCycle_ << nl << endl;
}
else
{
dict.lookup("trackLength") >> trackLength_;
Info<< type() << " : fixed track length specified : "
<< trackLength_ << nl << endl;
}
followSurface_ = false;
trackHeight_ = VGREAT;
if (dict.readIfPresent("followSurface", followSurface_))
{
dict.lookup("trackHeight") >> trackHeight_;
Info<< type() << " : surface-constrained streamline at "
<< trackHeight_ << " distance above the surface" << nl << endl;
} }
interpolationScheme_ = dict.lookupOrDefault interpolationScheme_ = dict.lookupOrDefault

View File

@ -43,6 +43,7 @@ SourceFiles
#include "vectorList.H" #include "vectorList.H"
#include "polyMesh.H" #include "polyMesh.H"
#include "writer.H" #include "writer.H"
#include "indirectPrimitivePatch.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -95,9 +96,17 @@ class streamLine
//- Maximum lifetime (= number of cells) of particle //- Maximum lifetime (= number of cells) of particle
label lifeTime_; label lifeTime_;
//- Surface-constrained?
bool followSurface_;
scalar trackHeight_;
//- Number of subcycling steps //- Number of subcycling steps
label nSubCycle_; label nSubCycle_;
//- Track length
scalar trackLength_;
//- Optional specified name of particles //- Optional specified name of particles
word cloudName_; word cloudName_;
@ -141,6 +150,8 @@ class streamLine
List<DynamicList<vectorList> > allVectors_; List<DynamicList<vectorList> > allVectors_;
//- Construct patch out of all wall patch faces
autoPtr<indirectPrimitivePatch> wallPatch() const;
//- Do all seeding and tracking //- Do all seeding and tracking
void track(); void track();

View File

@ -43,7 +43,7 @@ Foam::scalar Foam::streamLineParticle::calcSubCycleDeltaT
const vector& U const vector& U
) const ) const
{ {
streamLineParticle testParticle(*this); particle testParticle(*this);
bool oldKeepParticle = td.keepParticle; bool oldKeepParticle = td.keepParticle;
bool oldSwitchProcessor = td.switchProcessor; bool oldSwitchProcessor = td.switchProcessor;
@ -59,7 +59,8 @@ Foam::vector Foam::streamLineParticle::interpolateFields
( (
const trackingData& td, const trackingData& td,
const point& position, const point& position,
const label cellI const label cellI,
const label faceI
) )
{ {
if (cellI == -1) if (cellI == -1)
@ -76,7 +77,8 @@ Foam::vector Foam::streamLineParticle::interpolateFields
td.vsInterp_[scalarI].interpolate td.vsInterp_[scalarI].interpolate
( (
position, position,
cellI cellI,
faceI
) )
); );
} }
@ -89,7 +91,8 @@ Foam::vector Foam::streamLineParticle::interpolateFields
td.vvInterp_[vectorI].interpolate td.vvInterp_[vectorI].interpolate
( (
position, position,
cellI cellI,
faceI
) )
); );
} }
@ -201,13 +204,24 @@ bool Foam::streamLineParticle::move
// Store current position and sampled velocity. // Store current position and sampled velocity.
sampledPositions_.append(position()); sampledPositions_.append(position());
vector U = interpolateFields(td, position(), cell()); vector U = interpolateFields(td, position(), cell(), face());
if (!td.trackForward_) if (!td.trackForward_)
{ {
U = -U; U = -U;
} }
if (td.followSurface_)
{
//- Simple: remove wall-normal component. Should keep particle
// at same height. Does not work well on warped faces.
const vector& n = td.patchNormals_[tetFaceI_];
if (n != vector::zero)
{
U -= (U&n)*n;
}
}
scalar magU = mag(U); scalar magU = mag(U);
if (magU < SMALL) if (magU < SMALL)
@ -219,7 +233,13 @@ bool Foam::streamLineParticle::move
U /= magU; U /= magU;
if (subIter == 0 && td.nSubCycle_ > 1) if (td.trackLength_ < GREAT)
{
dt = td.trackLength_;
//Pout<< " subiteration " << subIter
// << " : fixed length: updated dt:" << dt << endl;
}
else if (subIter == 0 && td.nSubCycle_ > 1)
{ {
// Adapt dt to cross cell in a few steps // Adapt dt to cross cell in a few steps
dt = calcSubCycleDeltaT(td, dt, U); dt = calcSubCycleDeltaT(td, dt, U);
@ -264,7 +284,8 @@ bool Foam::streamLineParticle::move
if (debug) if (debug)
{ {
Pout<< "streamLineParticle : Removing stagnant particle:" Pout<< "streamLineParticle : Removing stagnant particle:"
<< p << " sampled positions:" << sampledPositions_.size() << p.position()
<< " sampled positions:" << sampledPositions_.size()
<< endl; << endl;
} }
td.keepParticle = false; td.keepParticle = false;
@ -273,12 +294,13 @@ bool Foam::streamLineParticle::move
{ {
// Normal exit. Store last position and fields // Normal exit. Store last position and fields
sampledPositions_.append(position()); sampledPositions_.append(position());
interpolateFields(td, position(), cell()); interpolateFields(td, position(), cell(), face());
if (debug) if (debug)
{ {
Pout<< "streamLineParticle : Removing particle:" Pout<< "streamLineParticle : Removing particle:"
<< p << " sampled positions:" << sampledPositions_.size() << p.position()
<< " sampled positions:" << sampledPositions_.size()
<< endl; << endl;
} }
} }
@ -374,8 +396,42 @@ void Foam::streamLineParticle::hitWallPatch
const tetIndices& const tetIndices&
) )
{ {
// Remove particle if (td.followSurface_)
td.keepParticle = false; {
// Push slightly in. Since we're pushing to tet centre we should still
// be in the same tet.
tetPointRef tet = currentTet();
const point oldPosition(position());
position() += trackingCorrectionTol*(tet.centre() - position());
if (debug)
{
label patchID = patch(face());
Pout<< "hitWallPatch : on wall "
<< mesh().boundaryMesh()[patchID].name()
<< " moved from " << oldPosition
<< " to " << position()
<< " due to centre " << tet.centre() << endl;
}
// Check that still in tet (should always be the case
if (debug && !tet.inside(position()))
{
FatalErrorIn("streamLineParticle::hitWallPatch()")
<< "Pushing particle " << *this
<< " away from wall " << wpp.name()
<< " moved it outside of tet."
<< exit(FatalError);
}
}
else
{
// Remove particle
td.keepParticle = false;
}
} }

View File

@ -73,6 +73,13 @@ public:
const label UIndex_; const label UIndex_;
const bool trackForward_; const bool trackForward_;
const label nSubCycle_; const label nSubCycle_;
const scalar trackLength_;
//- For surface-constrained tracking
const bool followSurface_;
const pointField& patchNormals_;
const scalar trackHeight_;
DynamicList<vectorList>& allPositions_; DynamicList<vectorList>& allPositions_;
List<DynamicList<scalarList> >& allScalars_; List<DynamicList<scalarList> >& allScalars_;
@ -89,6 +96,12 @@ public:
const label UIndex, const label UIndex,
const bool trackForward, const bool trackForward,
const label nSubCycle, const label nSubCycle,
const scalar trackLength,
const bool followSurface,
const pointField& patchNormals,
const scalar trackHeight,
DynamicList<List<point> >& allPositions, DynamicList<List<point> >& allPositions,
List<DynamicList<scalarList> >& allScalars, List<DynamicList<scalarList> >& allScalars,
List<DynamicList<vectorList> >& allVectors List<DynamicList<vectorList> >& allVectors
@ -100,6 +113,12 @@ public:
UIndex_(UIndex), UIndex_(UIndex),
trackForward_(trackForward), trackForward_(trackForward),
nSubCycle_(nSubCycle), nSubCycle_(nSubCycle),
trackLength_(trackLength),
followSurface_(followSurface),
patchNormals_(patchNormals),
trackHeight_(trackHeight),
allPositions_(allPositions), allPositions_(allPositions),
allScalars_(allScalars), allScalars_(allScalars),
allVectors_(allVectors) allVectors_(allVectors)
@ -135,12 +154,20 @@ private:
const vector& U const vector& U
) const; ) const;
void constrainVelocity
(
trackingData& td,
const scalar dt,
vector& U
);
//- Interpolate all quantities; return interpolated velocity. //- Interpolate all quantities; return interpolated velocity.
vector interpolateFields vector interpolateFields
( (
const trackingData&, const trackingData&,
const point&, const point&,
const label cellI const label cellI,
const label faceI
); );

30
src/renumber/Allwmake Executable file
View File

@ -0,0 +1,30 @@
#!/bin/sh
cd ${0%/*} || exit 1 # run from this directory
makeType=${1:-libso}
## get ZOLTAN_ARCH_PATH
#if settings=`$WM_PROJECT_DIR/bin/foamEtcFile config/zoltan.sh`
#then
# . $settings
# echo "using ZOLTAN_ARCH_PATH=$ZOLTAN_ARCH_PATH"
#else
# echo
# echo "Error: no config/zoltan.sh settings"
# echo
#fi
set -x
wmake $makeType renumberMethods
#if [ -n "$ZOLTAN_ARCH_PATH" ]
#then
# wmake $makeType zoltanRenumber
#else
# echo
# echo "Skipping zoltanRenumber"
# echo
#fi
# ----------------------------------------------------------------- end-of-file

View File

@ -63,7 +63,7 @@ Foam::labelList Foam::CuthillMcKeeRenumber::renumber
( (
const polyMesh& mesh, const polyMesh& mesh,
const pointField& points const pointField& points
) ) const
{ {
CompactListList<label> cellCells; CompactListList<label> cellCells;
decompositionMethod::calcCellCells decompositionMethod::calcCellCells
@ -79,10 +79,7 @@ Foam::labelList Foam::CuthillMcKeeRenumber::renumber
if (reverse_) if (reverse_)
{ {
for (label i = 0; i < orderedToOld.size()/2; i++) reverse(orderedToOld);
{
Swap(orderedToOld[i], orderedToOld[orderedToOld.size()-i-1]);
}
} }
return invert(orderedToOld.size(), orderedToOld); return invert(orderedToOld.size(), orderedToOld);
@ -93,16 +90,13 @@ Foam::labelList Foam::CuthillMcKeeRenumber::renumber
( (
const labelListList& cellCells, const labelListList& cellCells,
const pointField& points const pointField& points
) ) const
{ {
labelList orderedToOld = bandCompression(cellCells); labelList orderedToOld = bandCompression(cellCells);
if (reverse_) if (reverse_)
{ {
for (label i = 0; i < orderedToOld.size()/2; i++) reverse(orderedToOld);
{
Swap(orderedToOld[i], orderedToOld[orderedToOld.size()-i-1]);
}
} }
return invert(orderedToOld.size(), orderedToOld); return invert(orderedToOld.size(), orderedToOld);

View File

@ -82,7 +82,7 @@ public:
//- Return for every coordinate the wanted processor number. //- Return for every coordinate the wanted processor number.
// We need a polyMesh (to be able to load the file) // We need a polyMesh (to be able to load the file)
virtual labelList renumber(const pointField&) virtual labelList renumber(const pointField&) const
{ {
notImplemented("CuthillMcKeeRenumber::renumber(const pointField&)"); notImplemented("CuthillMcKeeRenumber::renumber(const pointField&)");
return labelList(0); return labelList(0);
@ -94,7 +94,7 @@ public:
( (
const polyMesh& mesh, const polyMesh& mesh,
const pointField& cc const pointField& cc
); ) const;
//- Return for every cell the new cell label. //- Return for every cell the new cell label.
// The connectivity is equal to mesh.cellCells() except // The connectivity is equal to mesh.cellCells() except
@ -103,7 +103,7 @@ public:
( (
const labelListList& cellCells, const labelListList& cellCells,
const pointField& cc const pointField& cc
); ) const;
}; };

View File

@ -3,5 +3,6 @@ manualRenumber/manualRenumber.C
CuthillMcKeeRenumber/CuthillMcKeeRenumber.C CuthillMcKeeRenumber/CuthillMcKeeRenumber.C
randomRenumber/randomRenumber.C randomRenumber/randomRenumber.C
springRenumber/springRenumber.C springRenumber/springRenumber.C
boundaryFirstRenumber/boundaryFirstRenumber.C
LIB = $(FOAM_LIBBIN)/librenumberMethods LIB = $(FOAM_LIBBIN)/librenumberMethods

View File

@ -0,0 +1,201 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011 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 "boundaryFirstRenumber.H"
#include "addToRunTimeSelectionTable.H"
#include "bandCompression.H"
#include "decompositionMethod.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
defineTypeNameAndDebug(boundaryFirstRenumber, 0);
addToRunTimeSelectionTable
(
renumberMethod,
boundaryFirstRenumber,
dictionary
);
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::boundaryFirstRenumber::boundaryFirstRenumber
(
const dictionary& renumberDict
)
:
renumberMethod(renumberDict),
reverse_
(
renumberDict.found(typeName + "Coeffs")
? Switch(renumberDict.subDict(typeName + "Coeffs").lookup("reverse"))
: Switch(true)
)
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
Foam::labelList Foam::boundaryFirstRenumber::renumber
(
const polyMesh& mesh,
const pointField& points
) const
{
const labelList& own = mesh.faceOwner();
const labelList& nei = mesh.faceNeighbour();
// Distance to boundary. Minimum of neighbours.
labelList distance(mesh.nCells(), -1);
// New order
labelList newOrder(mesh.nCells());
label cellInOrder = 0;
// Starting faces for walk. These are the zero distance faces.
DynamicList<label> frontFaces(mesh.nFaces()-mesh.nInternalFaces());
const polyBoundaryMesh& patches = mesh.boundaryMesh();
forAll(patches, patchI)
{
const polyPatch& pp = patches[patchI];
//- Note: cannot check for empty since these are introduced by
// fvMeshSubset. Also most loops don't care about patch type.
//if (!isA<emptyPolyPatch>(pp))
{
forAll(pp, i)
{
frontFaces.append(pp.start()+i);
}
}
}
// Loop over all frontFaces
label currentDistance = 0;
while (frontFaces.size() > 0)
{
DynamicList<label> frontCells(frontFaces.size());
// Set all of frontFaces' neighbours to current distance
forAll(frontFaces, i)
{
label faceI = frontFaces[i];
if (mesh.isInternalFace(faceI))
{
label ownCellI = own[faceI];
if (distance[ownCellI] == -1)
{
distance[ownCellI] = currentDistance;
frontCells.append(ownCellI);
}
label neiCellI = nei[faceI];
if (distance[neiCellI] == -1)
{
distance[neiCellI] = currentDistance;
frontCells.append(neiCellI);
}
}
else
{
label ownCellI = own[faceI];
if (distance[ownCellI] == -1)
{
distance[ownCellI] = currentDistance;
frontCells.append(ownCellI);
}
}
}
//Pout<< "For distance:" << currentDistance
// << " from " << frontFaces.size() << " faces to "
// << frontCells.size() << " cells." << endl;
// TBD. Determine order within current shell (frontCells). For now
// just add them.
forAll(frontCells, i)
{
newOrder[cellInOrder] = frontCells[i];
cellInOrder++;
}
// From cells to faces
frontFaces.clear();
forAll(frontCells, i)
{
label cellI = frontCells[i];
const cell& cFaces = mesh.cells()[cellI];
forAll(cFaces, i)
{
label faceI = cFaces[i];
if (mesh.isInternalFace(faceI))
{
label nbrCellI =
(
mesh.faceOwner()[faceI] == cellI
? mesh.faceNeighbour()[faceI]
: mesh.faceOwner()[faceI]
);
if (distance[nbrCellI] == -1)
{
frontFaces.append(faceI);
}
}
}
}
currentDistance++;
}
// Return furthest away cell first
if (reverse_)
{
reverse(newOrder);
}
//forAll(newOrder, i)
//{
// label cellI = newOrder[i];
//
// Pout<< "cell:" << cellI << endl;
// Pout<< " at distance:" << distance[cellI]
// << endl;
//}
return invert(newOrder.size(), newOrder);
}
// ************************************************************************* //

View File

@ -0,0 +1,129 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011 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::boundaryFirstRenumber
Description
Cuthill-McKee renumbering
SourceFiles
boundaryFirstRenumber.C
\*---------------------------------------------------------------------------*/
#ifndef boundaryFirstRenumber_H
#define boundaryFirstRenumber_H
#include "renumberMethod.H"
#include "Switch.H"
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class boundaryFirstRenumber Declaration
\*---------------------------------------------------------------------------*/
class boundaryFirstRenumber
:
public renumberMethod
{
// Private data
const Switch reverse_;
// Private Member Functions
//- Disallow default bitwise copy construct and assignment
void operator=(const boundaryFirstRenumber&);
boundaryFirstRenumber(const boundaryFirstRenumber&);
public:
//- Runtime type information
TypeName("boundaryFirst");
// Constructors
//- Construct given the renumber dictionary
boundaryFirstRenumber(const dictionary& renumberDict);
//- Destructor
virtual ~boundaryFirstRenumber()
{}
// Member Functions
//- Return for every coordinate the wanted processor number.
// We need a polyMesh (to be able to load the file)
virtual labelList renumber(const pointField&) const
{
notImplemented
(
"boundaryFirstRenumber::renumber(const pointField&)"
);
return labelList(0);
}
//- Return for every coordinate the wanted processor number. Use the
// mesh connectivity (if needed)
virtual labelList renumber
(
const polyMesh& mesh,
const pointField& cc
) const;
//- Return for every cell the new cell label.
// The connectivity is equal to mesh.cellCells() except
// - the connections are across coupled patches
virtual labelList renumber
(
const labelListList& cellCells,
const pointField& cc
) const
{
notImplemented
(
"boundaryFirstRenumber::renumber"
"(const labelListList&, const pointField&)"
);
return labelList(0);
}
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -61,7 +61,7 @@ Foam::labelList Foam::manualRenumber::renumber
( (
const polyMesh& mesh, const polyMesh& mesh,
const pointField& points const pointField& points
) ) const
{ {
labelIOList oldToNew labelIOList oldToNew
( (

View File

@ -81,7 +81,7 @@ public:
//- Return for every coordinate the wanted processor number. //- Return for every coordinate the wanted processor number.
// We need a polyMesh (to be able to load the file) // We need a polyMesh (to be able to load the file)
virtual labelList renumber(const pointField&) virtual labelList renumber(const pointField&) const
{ {
notImplemented("manualRenumber::renumber(const pointField&)"); notImplemented("manualRenumber::renumber(const pointField&)");
return labelList(0); return labelList(0);
@ -93,7 +93,7 @@ public:
( (
const polyMesh& mesh, const polyMesh& mesh,
const pointField& cc const pointField& cc
); ) const;
//- Return for every cell the new cell label. //- Return for every cell the new cell label.
// The connectivity is equal to mesh.cellCells() except // The connectivity is equal to mesh.cellCells() except
@ -102,7 +102,7 @@ public:
( (
const labelListList& cellCells, const labelListList& cellCells,
const pointField& cc const pointField& cc
) ) const
{ {
notImplemented notImplemented
( (

View File

@ -55,7 +55,7 @@ Foam::randomRenumber::randomRenumber(const dictionary& renumberDict)
Foam::labelList Foam::randomRenumber::renumber Foam::labelList Foam::randomRenumber::renumber
( (
const pointField& points const pointField& points
) ) const
{ {
Random rndGen(0); Random rndGen(0);
@ -77,7 +77,7 @@ Foam::labelList Foam::randomRenumber::renumber
( (
const polyMesh& mesh, const polyMesh& mesh,
const pointField& points const pointField& points
) ) const
{ {
return renumber(points); return renumber(points);
} }
@ -87,7 +87,7 @@ Foam::labelList Foam::randomRenumber::renumber
( (
const labelListList& cellCells, const labelListList& cellCells,
const pointField& points const pointField& points
) ) const
{ {
return renumber(points); return renumber(points);
} }

View File

@ -76,7 +76,7 @@ public:
//- Return for every coordinate the wanted processor number. //- Return for every coordinate the wanted processor number.
// We need a polyMesh (to be able to load the file) // We need a polyMesh (to be able to load the file)
virtual labelList renumber(const pointField&); virtual labelList renumber(const pointField&) const;
//- Return for every coordinate the wanted processor number. Use the //- Return for every coordinate the wanted processor number. Use the
// mesh connectivity (if needed) // mesh connectivity (if needed)
@ -84,7 +84,7 @@ public:
( (
const polyMesh& mesh, const polyMesh& mesh,
const pointField& cc const pointField& cc
); ) const;
//- Return for every cell the new cell label. //- Return for every cell the new cell label.
// The connectivity is equal to mesh.cellCells() except // The connectivity is equal to mesh.cellCells() except
@ -93,7 +93,7 @@ public:
( (
const labelListList& cellCells, const labelListList& cellCells,
const pointField& cc const pointField& cc
); ) const;
}; };

View File

@ -72,7 +72,7 @@ Foam::labelList Foam::renumberMethod::renumber
( (
const polyMesh& mesh, const polyMesh& mesh,
const pointField& points const pointField& points
) ) const
{ {
CompactListList<label> cellCells; CompactListList<label> cellCells;
decompositionMethod::calcCellCells decompositionMethod::calcCellCells
@ -94,7 +94,7 @@ Foam::labelList Foam::renumberMethod::renumber
const polyMesh& mesh, const polyMesh& mesh,
const labelList& fineToCoarse, const labelList& fineToCoarse,
const pointField& coarsePoints const pointField& coarsePoints
) ) const
{ {
CompactListList<label> coarseCellCells; CompactListList<label> coarseCellCells;
decompositionMethod::calcCellCells decompositionMethod::calcCellCells

View File

@ -111,7 +111,7 @@ public:
//- Return for every cell the new cell label. //- Return for every cell the new cell label.
// This is only defined for geometric renumberMethods. // This is only defined for geometric renumberMethods.
virtual labelList renumber(const pointField&) virtual labelList renumber(const pointField&) const
{ {
notImplemented notImplemented
( (
@ -122,7 +122,7 @@ public:
//- Return for every cell the new cell label. Use the //- Return for every cell the new cell label. Use the
// mesh connectivity (if needed) // mesh connectivity (if needed)
virtual labelList renumber(const polyMesh&, const pointField&); virtual labelList renumber(const polyMesh&, const pointField&) const;
//- Return for every cell the new cell label. Gets //- Return for every cell the new cell label. Gets
// passed agglomeration map (from fine to coarse cells) and coarse // passed agglomeration map (from fine to coarse cells) and coarse
@ -136,7 +136,7 @@ public:
const polyMesh& mesh, const polyMesh& mesh,
const labelList& cellToRegion, const labelList& cellToRegion,
const pointField& regionPoints const pointField& regionPoints
); ) const;
//- Return for every cell the new cell label. //- Return for every cell the new cell label.
// The connectivity is equal to mesh.cellCells() except // The connectivity is equal to mesh.cellCells() except
@ -145,7 +145,7 @@ public:
( (
const labelListList& cellCells, const labelListList& cellCells,
const pointField& cc const pointField& cc
) = 0; ) const = 0;
}; };

View File

@ -60,7 +60,7 @@ Foam::labelList Foam::springRenumber::renumber
( (
const polyMesh& mesh, const polyMesh& mesh,
const pointField& points const pointField& points
) ) const
{ {
CompactListList<label> cellCells; CompactListList<label> cellCells;
decompositionMethod::calcCellCells decompositionMethod::calcCellCells
@ -80,7 +80,7 @@ Foam::labelList Foam::springRenumber::renumber
( (
const labelListList& cellCells, const labelListList& cellCells,
const pointField& points const pointField& points
) ) const
{ {
// Look at cell index as a 1D position parameter. // Look at cell index as a 1D position parameter.
// Move cells to the average 'position' of their neighbour. // Move cells to the average 'position' of their neighbour.

View File

@ -96,7 +96,7 @@ public:
// Member Functions // Member Functions
//- Return for every coordinate the wanted processor number. //- Return for every coordinate the wanted processor number.
virtual labelList renumber(const pointField&) virtual labelList renumber(const pointField&) const
{ {
notImplemented("springRenumber::renumber(const pointField&)"); notImplemented("springRenumber::renumber(const pointField&)");
return labelList(0); return labelList(0);
@ -108,7 +108,7 @@ public:
( (
const polyMesh& mesh, const polyMesh& mesh,
const pointField& cc const pointField& cc
); ) const;
//- Return for every cell the new cell label. //- Return for every cell the new cell label.
// The connectivity is equal to mesh.cellCells() except // The connectivity is equal to mesh.cellCells() except
@ -117,7 +117,7 @@ public:
( (
const labelListList& cellCells, const labelListList& cellCells,
const pointField& cc const pointField& cc
); ) const;
}; };

View File

@ -219,84 +219,93 @@ public:
// Interpolation // Interpolation
//- Map field //- Map field
template<class Type> template<class Type, class CombineOp>
void mapField void mapField
( (
Field<Type>&, Field<Type>&,
const Field<Type>&, const Field<Type>&,
const labelList& adr const labelList& adr,
const CombineOp& cop
) const; ) const;
//- Interpolate field using inverse-distance weights //- Interpolate field using inverse-distance weights
template<class Type> template<class Type, class CombineOp>
void interpolateField void interpolateField
( (
Field<Type>&, Field<Type>&,
const GeometricField<Type, fvPatchField, volMesh>&, const GeometricField<Type, fvPatchField, volMesh>&,
const labelList& adr, const labelList& adr,
const scalarListList& weights const scalarListList& weights,
const CombineOp& cop
) const; ) const;
//- Interpolate field using cell-point interpolation //- Interpolate field using cell-point interpolation
template<class Type> template<class Type, class CombineOp>
void interpolateField void interpolateField
( (
Field<Type>&, Field<Type>&,
const GeometricField<Type, fvPatchField, volMesh>&, const GeometricField<Type, fvPatchField, volMesh>&,
const labelList& adr, const labelList& adr,
const vectorField& centres const vectorField& centres,
const CombineOp& cop
) const; ) const;
//- Interpolate internal volume field //- Interpolate internal volume field
template<class Type> template<class Type, class CombineOp>
void interpolateInternalField void interpolateInternalField
( (
Field<Type>&, Field<Type>&,
const GeometricField<Type, fvPatchField, volMesh>&, const GeometricField<Type, fvPatchField, volMesh>&,
order=INTERPOLATE order=INTERPOLATE,
const CombineOp& cop = eqOp<Type>()
) const; ) const;
template<class Type> template<class Type, class CombineOp>
void interpolateInternalField void interpolateInternalField
( (
Field<Type>&, Field<Type>&,
const tmp<GeometricField<Type, fvPatchField, volMesh> >&, const tmp<GeometricField<Type, fvPatchField, volMesh> >&,
order=INTERPOLATE order=INTERPOLATE,
const CombineOp& cop = eqOp<Type>()
) const; ) const;
//- Interpolate volume field //- Interpolate volume field
template<class Type> template<class Type, class CombineOp>
void interpolate void interpolate
( (
GeometricField<Type, fvPatchField, volMesh>&, GeometricField<Type, fvPatchField, volMesh>&,
const GeometricField<Type, fvPatchField, volMesh>&, const GeometricField<Type, fvPatchField, volMesh>&,
order=INTERPOLATE order=INTERPOLATE,
const CombineOp& cop = eqOp<Type>()
) const; ) const;
template<class Type> template<class Type, class CombineOp>
void interpolate void interpolate
( (
GeometricField<Type, fvPatchField, volMesh>&, GeometricField<Type, fvPatchField, volMesh>&,
const tmp<GeometricField<Type, fvPatchField, volMesh> >&, const tmp<GeometricField<Type, fvPatchField, volMesh> >&,
order=INTERPOLATE order=INTERPOLATE,
const CombineOp& cop = eqOp<Type>()
) const; ) const;
//- Interpolate volume field //- Interpolate volume field
template<class Type> template<class Type, class CombineOp>
tmp<GeometricField<Type, fvPatchField, volMesh> > interpolate tmp<GeometricField<Type, fvPatchField, volMesh> > interpolate
( (
const GeometricField<Type, fvPatchField, volMesh>&, const GeometricField<Type, fvPatchField, volMesh>&,
order=INTERPOLATE order=INTERPOLATE,
const CombineOp& cop = eqOp<Type>()
) const; ) const;
template<class Type> template<class Type, class CombineOp>
tmp<GeometricField<Type, fvPatchField, volMesh> > interpolate tmp<GeometricField<Type, fvPatchField, volMesh> > interpolate
( (
const tmp<GeometricField<Type, fvPatchField, volMesh> >&, const tmp<GeometricField<Type, fvPatchField, volMesh> >&,
order=INTERPOLATE order=INTERPOLATE,
const CombineOp& cop = eqOp<Type>()
) const; ) const;
}; };

View File

@ -31,12 +31,13 @@ License
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class Type> template<class Type, class CombineOp>
void Foam::meshToMesh::mapField void Foam::meshToMesh::mapField
( (
Field<Type>& toF, Field<Type>& toF,
const Field<Type>& fromVf, const Field<Type>& fromVf,
const labelList& adr const labelList& adr,
const CombineOp& cop
) const ) const
{ {
// Direct mapping of nearest-cell values // Direct mapping of nearest-cell values
@ -45,7 +46,7 @@ void Foam::meshToMesh::mapField
{ {
if (adr[celli] != -1) if (adr[celli] != -1)
{ {
toF[celli] = fromVf[adr[celli]]; cop(toF[celli], fromVf[adr[celli]]);
} }
} }
@ -53,13 +54,14 @@ void Foam::meshToMesh::mapField
} }
template<class Type> template<class Type, class CombineOp>
void Foam::meshToMesh::interpolateField void Foam::meshToMesh::interpolateField
( (
Field<Type>& toF, Field<Type>& toF,
const GeometricField<Type, fvPatchField, volMesh>& fromVf, const GeometricField<Type, fvPatchField, volMesh>& fromVf,
const labelList& adr, const labelList& adr,
const scalarListList& weights const scalarListList& weights,
const CombineOp& cop
) const ) const
{ {
// Inverse distance weighted interpolation // Inverse distance weighted interpolation
@ -74,24 +76,27 @@ void Foam::meshToMesh::interpolateField
const labelList& neighbours = cc[adr[celli]]; const labelList& neighbours = cc[adr[celli]];
const scalarList& w = weights[celli]; const scalarList& w = weights[celli];
toF[celli] = fromVf[adr[celli]]*w[0]; Type f = fromVf[adr[celli]]*w[0];
for (label ni = 1; ni < w.size(); ni++) for (label ni = 1; ni < w.size(); ni++)
{ {
toF[celli] += fromVf[neighbours[ni - 1]]*w[ni]; f += fromVf[neighbours[ni - 1]]*w[ni];
} }
cop(toF[celli], f);
} }
} }
} }
template<class Type> template<class Type, class CombineOp>
void Foam::meshToMesh::interpolateField void Foam::meshToMesh::interpolateField
( (
Field<Type>& toF, Field<Type>& toF,
const GeometricField<Type, fvPatchField, volMesh>& fromVf, const GeometricField<Type, fvPatchField, volMesh>& fromVf,
const labelList& adr, const labelList& adr,
const vectorField& centres const vectorField& centres,
const CombineOp& cop
) const ) const
{ {
// Cell-Point interpolation // Cell-Point interpolation
@ -101,31 +106,36 @@ void Foam::meshToMesh::interpolateField
{ {
if (adr[celli] != -1) if (adr[celli] != -1)
{ {
toF[celli] = interpolator.interpolate cop
( (
centres[celli], toF[celli],
adr[celli] interpolator.interpolate
(
centres[celli],
adr[celli]
)
); );
} }
} }
} }
template<class Type> template<class Type, class CombineOp>
void Foam::meshToMesh::interpolateInternalField void Foam::meshToMesh::interpolateInternalField
( (
Field<Type>& toF, Field<Type>& toF,
const GeometricField<Type, fvPatchField, volMesh>& fromVf, const GeometricField<Type, fvPatchField, volMesh>& fromVf,
meshToMesh::order ord meshToMesh::order ord,
const CombineOp& cop
) const ) const
{ {
if (fromVf.mesh() != fromMesh_) if (fromVf.mesh() != fromMesh_)
{ {
FatalErrorIn FatalErrorIn
( (
"meshToMesh::interpolateInternalField(Field<Type>& toF, " "meshToMesh::interpolateInternalField(Field<Type>&, "
"const GeometricField<Type, fvPatchField, volMesh>& fromVf, " "const GeometricField<Type, fvPatchField, volMesh>&, "
"meshToMesh::order ord) const" "meshToMesh::order, const CombineOp&) const"
) << "the argument field does not correspond to the right mesh. " ) << "the argument field does not correspond to the right mesh. "
<< "Field size: " << fromVf.size() << "Field size: " << fromVf.size()
<< " mesh size: " << fromMesh_.nCells() << " mesh size: " << fromMesh_.nCells()
@ -136,9 +146,9 @@ void Foam::meshToMesh::interpolateInternalField
{ {
FatalErrorIn FatalErrorIn
( (
"meshToMesh::interpolateInternalField(Field<Type>& toF, " "meshToMesh::interpolateInternalField(Field<Type>&, "
"const GeometricField<Type, fvPatchField, volMesh>& fromVf, " "const GeometricField<Type, fvPatchField, volMesh>&, "
"meshToMesh::order ord) const" "meshToMesh::order, const CombineOp&) const"
) << "the argument field does not correspond to the right mesh. " ) << "the argument field does not correspond to the right mesh. "
<< "Field size: " << toF.size() << "Field size: " << toF.size()
<< " mesh size: " << toMesh_.nCells() << " mesh size: " << toMesh_.nCells()
@ -148,7 +158,7 @@ void Foam::meshToMesh::interpolateInternalField
switch(ord) switch(ord)
{ {
case MAP: case MAP:
mapField(toF, fromVf, cellAddressing_); mapField(toF, fromVf, cellAddressing_, cop);
break; break;
case INTERPOLATE: case INTERPOLATE:
@ -157,7 +167,8 @@ void Foam::meshToMesh::interpolateInternalField
toF, toF,
fromVf, fromVf,
cellAddressing_, cellAddressing_,
inverseDistanceWeights() inverseDistanceWeights(),
cop
); );
break; break;
@ -167,44 +178,47 @@ void Foam::meshToMesh::interpolateInternalField
toF, toF,
fromVf, fromVf,
cellAddressing_, cellAddressing_,
toMesh_.cellCentres() toMesh_.cellCentres(),
cop
); );
break; break;
default: default:
FatalErrorIn FatalErrorIn
( (
"meshToMesh::interpolateInternalField(Field<Type>& toF, " "meshToMesh::interpolateInternalField(Field<Type>&, "
"const GeometricField<Type, fvPatchField, volMesh>& fromVf, " "const GeometricField<Type, fvPatchField, volMesh>&, "
"meshToMesh::order ord) const" "meshToMesh::order, const CombineOp&) const"
) << "unknown interpolation scheme " << ord ) << "unknown interpolation scheme " << ord
<< exit(FatalError); << exit(FatalError);
} }
} }
template<class Type> template<class Type, class CombineOp>
void Foam::meshToMesh::interpolateInternalField void Foam::meshToMesh::interpolateInternalField
( (
Field<Type>& toF, Field<Type>& toF,
const tmp<GeometricField<Type, fvPatchField, volMesh> >& tfromVf, const tmp<GeometricField<Type, fvPatchField, volMesh> >& tfromVf,
meshToMesh::order ord meshToMesh::order ord,
const CombineOp& cop
) const ) const
{ {
interpolateInternalField(toF, tfromVf(), ord); interpolateInternalField(toF, tfromVf(), ord, cop);
tfromVf.clear(); tfromVf.clear();
} }
template<class Type> template<class Type, class CombineOp>
void Foam::meshToMesh::interpolate void Foam::meshToMesh::interpolate
( (
GeometricField<Type, fvPatchField, volMesh>& toVf, GeometricField<Type, fvPatchField, volMesh>& toVf,
const GeometricField<Type, fvPatchField, volMesh>& fromVf, const GeometricField<Type, fvPatchField, volMesh>& fromVf,
meshToMesh::order ord meshToMesh::order ord,
const CombineOp& cop
) const ) const
{ {
interpolateInternalField(toVf, fromVf, ord); interpolateInternalField(toVf, fromVf, ord, cop);
forAll(toMesh_.boundaryMesh(), patchi) forAll(toMesh_.boundaryMesh(), patchi)
{ {
@ -219,7 +233,8 @@ void Foam::meshToMesh::interpolate
( (
toVf.boundaryField()[patchi], toVf.boundaryField()[patchi],
fromVf, fromVf,
boundaryAddressing_[patchi] boundaryAddressing_[patchi],
cop
); );
break; break;
@ -229,7 +244,8 @@ void Foam::meshToMesh::interpolate
toVf.boundaryField()[patchi], toVf.boundaryField()[patchi],
fromVf, fromVf,
boundaryAddressing_[patchi], boundaryAddressing_[patchi],
toPatch.Cf() toPatch.Cf(),
cop
); );
break; break;
@ -239,7 +255,8 @@ void Foam::meshToMesh::interpolate
toVf.boundaryField()[patchi], toVf.boundaryField()[patchi],
fromVf, fromVf,
boundaryAddressing_[patchi], boundaryAddressing_[patchi],
toPatch.Cf() toPatch.Cf(),
cop
); );
break; break;
@ -247,9 +264,9 @@ void Foam::meshToMesh::interpolate
FatalErrorIn FatalErrorIn
( (
"meshToMesh::interpolate(" "meshToMesh::interpolate("
"GeometricField<Type, fvPatchField, volMesh>& toVf, " "GeometricField<Type, fvPatchField, volMesh>&, "
"const GeometricField<Type, fvPatchField, volMesh>& " "const GeometricField<Type, fvPatchField, volMesh>&, "
"fromVf, meshToMesh::order ord) const" "meshToMesh::order, const CombineOp&) const"
) << "unknown interpolation scheme " << ord ) << "unknown interpolation scheme " << ord
<< exit(FatalError); << exit(FatalError);
} }
@ -286,37 +303,40 @@ void Foam::meshToMesh::interpolate
[ [
fromMeshPatches_.find(patchMap_.find(toPatch.name())())() fromMeshPatches_.find(patchMap_.find(toPatch.name())())()
], ],
boundaryAddressing_[patchi] boundaryAddressing_[patchi],
cop
); );
} }
} }
} }
template<class Type> template<class Type, class CombineOp>
void Foam::meshToMesh::interpolate void Foam::meshToMesh::interpolate
( (
GeometricField<Type, fvPatchField, volMesh>& toVf, GeometricField<Type, fvPatchField, volMesh>& toVf,
const tmp<GeometricField<Type, fvPatchField, volMesh> >& tfromVf, const tmp<GeometricField<Type, fvPatchField, volMesh> >& tfromVf,
meshToMesh::order ord meshToMesh::order ord,
const CombineOp& cop
) const ) const
{ {
interpolate(toVf, tfromVf(), ord); interpolate(toVf, tfromVf(), ord, cop);
tfromVf.clear(); tfromVf.clear();
} }
template<class Type> template<class Type, class CombineOp>
Foam::tmp< Foam::GeometricField<Type, Foam::fvPatchField, Foam::volMesh> > Foam::tmp< Foam::GeometricField<Type, Foam::fvPatchField, Foam::volMesh> >
Foam::meshToMesh::interpolate Foam::meshToMesh::interpolate
( (
const GeometricField<Type, fvPatchField, volMesh>& fromVf, const GeometricField<Type, fvPatchField, volMesh>& fromVf,
meshToMesh::order ord meshToMesh::order ord,
const CombineOp& cop
) const ) const
{ {
// Create and map the internal-field values // Create and map the internal-field values
Field<Type> internalField(toMesh_.nCells()); Field<Type> internalField(toMesh_.nCells());
interpolateInternalField(internalField, fromVf, ord); interpolateInternalField(internalField, fromVf, ord, cop);
// check whether both meshes have got the same number // check whether both meshes have got the same number
// of boundary patches // of boundary patches
@ -325,8 +345,8 @@ Foam::meshToMesh::interpolate
FatalErrorIn FatalErrorIn
( (
"meshToMesh::interpolate" "meshToMesh::interpolate"
"(const GeometricField<Type, fvPatchField, volMesh>& fromVf," "(const GeometricField<Type, fvPatchField, volMesh>&,"
"meshToMesh::order ord) const" "meshToMesh::order, const CombineOp&) const"
) << "Incompatible meshes: different number of boundaries, " ) << "Incompatible meshes: different number of boundaries, "
"only internal field may be interpolated" "only internal field may be interpolated"
<< exit(FatalError); << exit(FatalError);
@ -381,16 +401,17 @@ Foam::meshToMesh::interpolate
} }
template<class Type> template<class Type, class CombineOp>
Foam::tmp< Foam::GeometricField<Type, Foam::fvPatchField, Foam::volMesh> > Foam::tmp< Foam::GeometricField<Type, Foam::fvPatchField, Foam::volMesh> >
Foam::meshToMesh::interpolate Foam::meshToMesh::interpolate
( (
const tmp<GeometricField<Type, fvPatchField, volMesh> >& tfromVf, const tmp<GeometricField<Type, fvPatchField, volMesh> >& tfromVf,
meshToMesh::order ord meshToMesh::order ord,
const CombineOp& cop
) const ) const
{ {
tmp<GeometricField<Type, fvPatchField, volMesh> > tint = tmp<GeometricField<Type, fvPatchField, volMesh> > tint =
interpolate(tfromVf(), ord); interpolate(tfromVf(), ord, cop);
tfromVf.clear(); tfromVf.clear();
return tint; return tint;

View File

@ -28,8 +28,15 @@ streamLines
// Steps particles can travel before being removed // Steps particles can travel before being removed
lifeTime 10000; lifeTime 10000;
// Number of steps per cell (estimate). Set to 1 to disable subcycling. //- Specify either absolute length of steps (trackLength) or a number
nSubCycle 5; // of subcycling steps per cell (nSubCycle)
// Size of single track segment [m]
//trackLength 1e-3;
// Number of steps per cell (estimate). Set to 1 to disable subcycling.
nSubCycle 5;
// Cloud name to use // Cloud name to use
cloudName particleTracks; cloudName particleTracks;

View File

@ -173,7 +173,7 @@ castellatedMeshControls
} }
} }
resolveFeatureAngle 2; resolveFeatureAngle 30;
// Region-wise refinement // Region-wise refinement