Merge branch 'master' of /home/dm4/OpenFOAM/repositories/OpenFOAM-dev

This commit is contained in:
mattijs
2014-01-14 14:28:16 +00:00
57 changed files with 1224 additions and 4758 deletions

View File

@ -1,4 +1,5 @@
EXE_INC = \ EXE_INC = \
-DFULLDEBUG -g -O0 \
-I$(LIB_SRC)/meshTools/lnInclude \ -I$(LIB_SRC)/meshTools/lnInclude \
-I$(LIB_SRC)/lagrangian/basic/lnInclude \ -I$(LIB_SRC)/lagrangian/basic/lnInclude \
-I$(LIB_SRC)/finiteVolume/lnInclude \ -I$(LIB_SRC)/finiteVolume/lnInclude \

View File

@ -1,130 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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 MapConsistentVolFields_H
#define MapConsistentVolFields_H
#include "GeometricField.H"
#include "meshToMesh.H"
#include "IOobjectList.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
template<class Type, class CombineOp>
void MapConsistentVolFields
(
const IOobjectList& objects,
const meshToMesh& meshToMeshInterp,
const meshToMesh::order& mapOrder,
const CombineOp& cop
)
{
const fvMesh& meshSource = meshToMeshInterp.fromMesh();
const fvMesh& meshTarget = meshToMeshInterp.toMesh();
word fieldClassName
(
GeometricField<Type, fvPatchField, volMesh>::typeName
);
IOobjectList fields = objects.lookupClass(fieldClassName);
forAllIter(IOobjectList, fields, fieldIter)
{
Info<< " interpolating " << fieldIter()->name()
<< endl;
// Read field
GeometricField<Type, fvPatchField, volMesh> fieldSource
(
*fieldIter(),
meshSource
);
IOobject fieldTargetIOobject
(
fieldIter()->name(),
meshTarget.time().timeName(),
meshTarget,
IOobject::MUST_READ,
IOobject::AUTO_WRITE
);
if (fieldTargetIOobject.headerOk())
{
// Read fieldTarget
GeometricField<Type, fvPatchField, volMesh> fieldTarget
(
fieldTargetIOobject,
meshTarget
);
// Interpolate field
meshToMeshInterp.interpolate//<Type, eqOp<Type> >
(
fieldTarget,
fieldSource,
mapOrder,
cop
);
// Write field
fieldTarget.write();
}
else
{
fieldTargetIOobject.readOpt() = IOobject::NO_READ;
// Interpolate field
GeometricField<Type, fvPatchField, volMesh> fieldTarget
(
fieldTargetIOobject,
meshToMeshInterp.interpolate//<Type, eqOp<Type> >
(
fieldSource,
mapOrder,
cop
)
);
// Write field
fieldTarget.write();
}
}
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -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-2014 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -51,19 +51,18 @@ void MapLagrangianFields
( (
const string& cloudName, const string& cloudName,
const IOobjectList& objects, const IOobjectList& objects,
const meshToMesh& meshToMeshInterp, const polyMesh& meshTarget,
const labelList& addParticles const labelList& addParticles
) )
{ {
const fvMesh& meshTarget = meshToMeshInterp.toMesh();
{ {
IOobjectList fields = objects.lookupClass(IOField<Type>::typeName); IOobjectList fields = objects.lookupClass(IOField<Type>::typeName);
forAllIter(IOobjectList, fields, fieldIter) forAllIter(IOobjectList, fields, fieldIter)
{ {
Info<< " mapping lagrangian field " const word& fieldName = fieldIter()->name();
<< fieldIter()->name() << endl;
Info<< " mapping lagrangian field " << fieldName << endl;
// Read field (does not need mesh) // Read field (does not need mesh)
IOField<Type> fieldSource(*fieldIter()); IOField<Type> fieldSource(*fieldIter());
@ -73,7 +72,7 @@ void MapLagrangianFields
( (
IOobject IOobject
( (
fieldIter()->name(), fieldName,
meshTarget.time().timeName(), meshTarget.time().timeName(),
cloud::prefix/cloudName, cloud::prefix/cloudName,
meshTarget, meshTarget,
@ -100,8 +99,9 @@ void MapLagrangianFields
forAllIter(IOobjectList, fieldFields, fieldIter) forAllIter(IOobjectList, fieldFields, fieldIter)
{ {
Info<< " mapping lagrangian fieldField " const word& fieldName = fieldIter()->name();
<< fieldIter()->name() << endl;
Info<< " mapping lagrangian fieldField " << fieldName << endl;
// Read field (does not need mesh) // Read field (does not need mesh)
IOField<Field<Type> > fieldSource(*fieldIter()); IOField<Field<Type> > fieldSource(*fieldIter());
@ -112,7 +112,7 @@ void MapLagrangianFields
( (
IOobject IOobject
( (
fieldIter()->name(), fieldName,
meshTarget.time().timeName(), meshTarget.time().timeName(),
cloud::prefix/cloudName, cloud::prefix/cloudName,
meshTarget, meshTarget,

View File

@ -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-2014 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -27,9 +27,9 @@ License
#define MapMeshes_H #define MapMeshes_H
#include "MapVolFields.H" #include "MapVolFields.H"
#include "MapConsistentVolFields.H"
#include "mapLagrangian.H" #include "mapLagrangian.H"
#include "UnMapped.H" #include "UnMapped.H"
#include "pointMesh.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -37,155 +37,62 @@ namespace Foam
{ {
template<template<class> class CombineOp> template<template<class> class CombineOp>
void MapConsistentMesh void MapMesh
( (
const fvMesh& meshSource, const meshToMesh& interp,
const fvMesh& meshTarget, const HashSet<word>& selectedFields,
const meshToMesh::order& mapOrder const bool noLagrangian
) )
{ {
// Create the interpolation scheme
meshToMesh meshToMeshInterp(meshSource, meshTarget);
Info<< nl
<< "Consistently creating and mapping fields for time "
<< meshSource.time().timeName() << nl << endl;
{ {
const polyMesh& meshSource = interp.srcRegion();
// Search for list of objects for this time // Search for list of objects for this time
IOobjectList objects(meshSource, meshSource.time().timeName()); 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 // Map volFields
// ~~~~~~~~~~~~~ // ~~~~~~~~~~~~~
MapVolFields<scalar> MapVolFields<scalar>
( (
objects, objects,
meshToMeshInterp, selectedFields,
mapOrder, interp,
CombineOp<scalar>() CombineOp<scalar>()
); );
MapVolFields<vector> MapVolFields<vector>
( (
objects, objects,
meshToMeshInterp, selectedFields,
mapOrder, interp,
CombineOp<vector>() CombineOp<vector>()
); );
MapVolFields<sphericalTensor> MapVolFields<sphericalTensor>
( (
objects, objects,
meshToMeshInterp, selectedFields,
mapOrder, interp,
CombineOp<sphericalTensor>() CombineOp<sphericalTensor>()
); );
MapVolFields<symmTensor> MapVolFields<symmTensor>
( (
objects, objects,
meshToMeshInterp, selectedFields,
mapOrder, interp,
CombineOp<symmTensor>() CombineOp<symmTensor>()
); );
MapVolFields<tensor> MapVolFields<tensor>
( (
objects, objects,
meshToMeshInterp, selectedFields,
mapOrder, interp,
CombineOp<tensor>() CombineOp<tensor>()
); );
} }
{ {
const polyMesh& meshTarget = interp.tgtRegion();
// Search for list of target objects for this time // Search for list of target objects for this time
IOobjectList objects(meshTarget, meshTarget.time().timeName()); IOobjectList objects(meshTarget, meshTarget.time().timeName());
@ -206,49 +113,10 @@ void MapSubMesh
UnMapped<pointTensorField>(objects); UnMapped<pointTensorField>(objects);
} }
mapLagrangian(meshToMeshInterp); if (!noLagrangian)
}
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])) mapLagrangian(interp);
{
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
);
} }

View File

@ -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-2014 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -23,8 +23,8 @@ License
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#ifndef MapVolFields_H #ifndef MapConsistentVolFields_H
#define MapVolFields_H #define MapConsistentVolFields_H
#include "GeometricField.H" #include "GeometricField.H"
#include "meshToMesh.H" #include "meshToMesh.H"
@ -39,62 +39,55 @@ template<class Type, class CombineOp>
void MapVolFields void MapVolFields
( (
const IOobjectList& objects, const IOobjectList& objects,
const meshToMesh& meshToMeshInterp, const HashSet<word>& selectedFields,
const meshToMesh::order& mapOrder, const meshToMesh& interp,
const CombineOp& cop const CombineOp& cop
) )
{ {
const fvMesh& meshSource = meshToMeshInterp.fromMesh(); typedef GeometricField<Type, fvPatchField, volMesh> fieldType;
const fvMesh& meshTarget = meshToMeshInterp.toMesh();
word fieldClassName const fvMesh& meshSource = static_cast<const fvMesh&>(interp.srcRegion());
( const fvMesh& meshTarget = static_cast<const fvMesh&>(interp.tgtRegion());
GeometricField<Type, fvPatchField, volMesh>::typeName
);
IOobjectList fields = objects.lookupClass(fieldClassName); IOobjectList fields = objects.lookupClass(fieldType::typeName);
forAllIter(IOobjectList, fields, fieldIter) forAllIter(IOobjectList, fields, fieldIter)
{ {
IOobject fieldTargetIOobject const word& fieldName = fieldIter()->name();
(
fieldIter()->name(),
meshTarget.time().timeName(),
meshTarget,
IOobject::MUST_READ,
IOobject::AUTO_WRITE
);
if (fieldTargetIOobject.headerOk()) if (selectedFields.empty() || selectedFields.found(fieldName))
{ {
Info<< " interpolating " << fieldIter()->name() Info<< " interpolating " << fieldName << endl;
<< endl;
// Read field fieldSource const fieldType fieldSource(*fieldIter(), meshSource);
GeometricField<Type, fvPatchField, volMesh> fieldSource
IOobject targetIO
( (
*fieldIter(), fieldName,
meshSource meshTarget.time().timeName(),
meshTarget,
IOobject::MUST_READ
); );
// Read fieldTarget if (targetIO.headerOk())
GeometricField<Type, fvPatchField, volMesh> fieldTarget {
( fieldType fieldTarget(targetIO, meshTarget);
fieldTargetIOobject,
meshTarget
);
// Interpolate field interp.mapSrcToTgt(fieldSource, cop, fieldTarget);
meshToMeshInterp.interpolate//<Type, eqOp<Type> >
(
fieldTarget,
fieldSource,
mapOrder,
cop
);
// Write field fieldTarget.write();
fieldTarget.write(); }
else
{
targetIO.readOpt() = IOobject::NO_READ;
tmp<fieldType>
tfieldTarget(interp.mapSrcToTgt(fieldSource, cop));
fieldType fieldTarget(targetIO, tfieldTarget);
fieldTarget.write();
}
} }
} }
} }

View File

@ -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-2014 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License

View File

@ -1,15 +1,11 @@
Info<< "\nCreate databases as time" << endl; Info<< "\nCreate databases as time" << endl;
Time runTimeSource HashTable<string> srcOptions(args.options());
( srcOptions.erase("case");
Time::controlDictName, srcOptions.insert("case", fileName(rootDirSource/caseDirSource));
rootDirSource,
caseDirSource
);
Time runTimeTarget argList argsSrc(args, srcOptions, false, false, false);
(
Time::controlDictName, Time runTimeSource(Time::controlDictName, argsSrc);
rootDirTarget,
caseDirTarget Time runTimeTarget(Time::controlDictName, args);
);

View File

@ -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-2013 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2014 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -27,14 +27,12 @@ Application
Description Description
Maps volume fields from one mesh to another, reading and Maps volume fields from one mesh to another, reading and
interpolating all fields present in the time directory of both cases. interpolating all fields present in the time directory of both cases.
Parallel and non-parallel cases are handled without the need to reconstruct
them first.
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#include "fvCFD.H" #include "fvCFD.H"
#include "meshToMesh.H" #include "meshToMesh.H"
#include "processorFvPatch.H" #include "processorPolyPatch.H"
#include "MapMeshes.H" #include "MapMeshes.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -43,26 +41,33 @@ void mapConsistentMesh
( (
const fvMesh& meshSource, const fvMesh& meshSource,
const fvMesh& meshTarget, const fvMesh& meshTarget,
const meshToMesh::order& mapOrder, const meshToMesh::interpolationMethod& mapMethod,
const bool subtract const bool subtract,
const HashSet<word>& selectedFields,
const bool noLagrangian
) )
{ {
Info<< nl << "Consistently creating and mapping fields for time "
<< meshSource.time().timeName() << nl << endl;
meshToMesh interp(meshSource, meshTarget, mapMethod);
if (subtract) if (subtract)
{ {
MapConsistentMesh<minusEqOp> MapMesh<minusEqOp>
( (
meshSource, interp,
meshTarget, selectedFields,
mapOrder noLagrangian
); );
} }
else else
{ {
MapConsistentMesh<eqOp> MapMesh<plusEqOp>
( (
meshSource, interp,
meshTarget, selectedFields,
mapOrder noLagrangian
); );
} }
} }
@ -74,59 +79,40 @@ 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::interpolationMethod& mapMethod,
const bool subtract const bool subtract,
const HashSet<word>& selectedFields,
const bool noLagrangian
) )
{ {
Info<< nl << "Creating and mapping fields for time "
<< meshSource.time().timeName() << nl << endl;
meshToMesh interp
(
meshSource,
meshTarget,
mapMethod,
patchMap,
cuttingPatches
);
if (subtract) if (subtract)
{ {
MapSubMesh<minusEqOp> MapMesh<minusEqOp>
( (
meshSource, interp,
meshTarget, selectedFields,
patchMap, noLagrangian
cuttingPatches,
mapOrder
); );
} }
else else
{ {
MapSubMesh<eqOp> MapMesh<plusEqOp>
( (
meshSource, interp,
meshTarget, selectedFields,
patchMap, noLagrangian
cuttingPatches,
mapOrder
);
}
}
void mapConsistentSubMesh
(
const fvMesh& meshSource,
const fvMesh& meshTarget,
const meshToMesh::order& mapOrder,
const bool subtract
)
{
if (subtract)
{
MapConsistentSubMesh<minusEqOp>
(
meshSource,
meshTarget,
mapOrder
);
}
else
{
MapConsistentSubMesh<eqOp>
(
meshSource,
meshTarget,
mapOrder
); );
} }
} }
@ -139,30 +125,20 @@ wordList addProcessorPatches
) )
{ {
// Add the processor patches to the cutting list // Add the processor patches to the cutting list
HashTable<label> cuttingPatchTable; HashSet<word> cuttingPatchTable;
forAll(cuttingPatches, i) forAll(cuttingPatches, i)
{ {
cuttingPatchTable.insert(cuttingPatches[i], i); cuttingPatchTable.insert(cuttingPatches[i]);
} }
forAll(meshTarget.boundary(), patchi) const polyBoundaryMesh& pbm = meshTarget.boundaryMesh();
forAll(pbm, patchI)
{ {
if (isA<processorFvPatch>(meshTarget.boundary()[patchi])) if (isA<processorPolyPatch>(pbm[patchI]))
{ {
if const word& patchName = pbm[patchI].name();
( cuttingPatchTable.insert(patchName);
!cuttingPatchTable.found
(
meshTarget.boundaryMesh()[patchi].name()
)
)
{
cuttingPatchTable.insert
(
meshTarget.boundaryMesh()[patchi].name(),
-1
);
}
} }
} }
@ -178,7 +154,7 @@ int main(int argc, char *argv[])
( (
"map volume fields from one mesh to another" "map volume fields from one mesh to another"
); );
argList::noParallel();
argList::validArgs.append("sourceCase"); argList::validArgs.append("sourceCase");
argList::addOption argList::addOption
@ -200,16 +176,6 @@ int main(int argc, char *argv[])
"specify the target region" "specify the target region"
); );
argList::addBoolOption argList::addBoolOption
(
"parallelSource",
"the source is decomposed"
);
argList::addBoolOption
(
"parallelTarget",
"the target is decomposed"
);
argList::addBoolOption
( (
"consistent", "consistent",
"source and target geometry and boundary conditions identical" "source and target geometry and boundary conditions identical"
@ -225,14 +191,21 @@ int main(int argc, char *argv[])
"subtract", "subtract",
"subtract mapped source from target" "subtract mapped source from target"
); );
argList::addOption
(
"fields",
"list",
"specify a list of fields to be mapped. Eg, '(U T p)' - "
"regular expressions not currently supported"
);
argList::addBoolOption
(
"noLagrangian",
"skip mapping lagrangian positions and fields"
);
argList args(argc, argv); argList args(argc, argv);
if (!args.check())
{
FatalError.exit();
}
fileName rootDirTarget(args.rootPath()); fileName rootDirTarget(args.rootPath());
fileName caseDirTarget(args.globalCaseName()); fileName caseDirTarget(args.globalCaseName());
@ -256,35 +229,17 @@ int main(int argc, char *argv[])
Info<< "Target region: " << targetRegion << endl; Info<< "Target region: " << targetRegion << endl;
} }
const bool parallelSource = args.optionFound("parallelSource");
const bool parallelTarget = args.optionFound("parallelTarget");
const bool consistent = args.optionFound("consistent"); const bool consistent = args.optionFound("consistent");
meshToMesh::order mapOrder = meshToMesh::INTERPOLATE; meshToMesh::interpolationMethod mapMethod =
meshToMesh::imCellVolumeWeight;
if (args.optionFound("mapMethod")) if (args.optionFound("mapMethod"))
{ {
const word mapMethod(args["mapMethod"]); mapMethod = meshToMesh::interpolationMethodNames_[args["mapMethod"]];
if (mapMethod == "mapNearest")
{
mapOrder = meshToMesh::MAP;
}
else if (mapMethod == "interpolate")
{
mapOrder = meshToMesh::INTERPOLATE;
}
else if (mapMethod == "cellPointInterpolate")
{
mapOrder = meshToMesh::CELL_POINT_INTERPOLATE;
}
else
{
FatalErrorIn(args.executable())
<< "Unknown mapMethod " << mapMethod << ". Valid options are: "
<< "mapNearest, interpolate and cellPointInterpolate"
<< exit(FatalError);
}
Info<< "Mapping method: " << mapMethod << endl; Info<< "Mapping method: "
<< meshToMesh::interpolationMethodNames_[mapMethod] << endl;
} }
const bool subtract = args.optionFound("subtract"); const bool subtract = args.optionFound("subtract");
@ -293,6 +248,13 @@ int main(int argc, char *argv[])
Info<< "Subtracting mapped source field from target" << endl; Info<< "Subtracting mapped source field from target" << endl;
} }
HashSet<word> selectedFields;
if (args.optionFound("fields"))
{
args.optionLookup("fields")() >> selectedFields;
}
const bool noLagrangian = args.optionFound("noLagrangian");
#include "createTimes.H" #include "createTimes.H"
@ -318,341 +280,58 @@ int main(int argc, char *argv[])
mapFieldsDict.lookup("cuttingPatches") >> cuttingPatches; mapFieldsDict.lookup("cuttingPatches") >> cuttingPatches;
} }
if (parallelSource && !parallelTarget) #include "setTimeIndex.H"
Info<< "\nCreate meshes\n" << endl;
fvMesh meshSource
(
IOobject
(
sourceRegion,
runTimeSource.timeName(),
runTimeSource
)
);
fvMesh meshTarget
(
IOobject
(
targetRegion,
runTimeTarget.timeName(),
runTimeTarget
)
);
Info<< "Source mesh size: " << meshSource.nCells() << tab
<< "Target mesh size: " << meshTarget.nCells() << nl << endl;
if (consistent)
{ {
IOdictionary decompositionDict mapConsistentMesh
( (
IOobject meshSource,
( meshTarget,
"decomposeParDict", mapMethod,
runTimeSource.system(), subtract,
runTimeSource, selectedFields,
IOobject::MUST_READ_IF_MODIFIED, noLagrangian
IOobject::NO_WRITE
)
); );
int nProcs(readInt(decompositionDict.lookup("numberOfSubdomains")));
Info<< "Create target mesh\n" << endl;
fvMesh meshTarget
(
IOobject
(
targetRegion,
runTimeTarget.timeName(),
runTimeTarget
)
);
Info<< "Target mesh size: " << meshTarget.nCells() << endl;
for (int procI=0; procI<nProcs; procI++)
{
Info<< nl << "Source processor " << procI << endl;
Time runTimeSource
(
Time::controlDictName,
rootDirSource,
caseDirSource/fileName(word("processor") + name(procI))
);
#include "setTimeIndex.H"
fvMesh meshSource
(
IOobject
(
sourceRegion,
runTimeSource.timeName(),
runTimeSource
)
);
Info<< "mesh size: " << meshSource.nCells() << endl;
if (consistent)
{
mapConsistentSubMesh
(
meshSource,
meshTarget,
mapOrder,
subtract
);
}
else
{
mapSubMesh
(
meshSource,
meshTarget,
patchMap,
cuttingPatches,
mapOrder,
subtract
);
}
}
}
else if (!parallelSource && parallelTarget)
{
IOdictionary decompositionDict
(
IOobject
(
"decomposeParDict",
runTimeTarget.system(),
runTimeTarget,
IOobject::MUST_READ_IF_MODIFIED,
IOobject::NO_WRITE
)
);
int nProcs(readInt(decompositionDict.lookup("numberOfSubdomains")));
Info<< "Create source mesh\n" << endl;
#include "setTimeIndex.H"
fvMesh meshSource
(
IOobject
(
sourceRegion,
runTimeSource.timeName(),
runTimeSource
)
);
Info<< "Source mesh size: " << meshSource.nCells() << endl;
for (int procI=0; procI<nProcs; procI++)
{
Info<< nl << "Target processor " << procI << endl;
Time runTimeTarget
(
Time::controlDictName,
rootDirTarget,
caseDirTarget/fileName(word("processor") + name(procI))
);
fvMesh meshTarget
(
IOobject
(
targetRegion,
runTimeTarget.timeName(),
runTimeTarget
)
);
Info<< "mesh size: " << meshTarget.nCells() << endl;
if (consistent)
{
mapConsistentSubMesh
(
meshSource,
meshTarget,
mapOrder,
subtract
);
}
else
{
mapSubMesh
(
meshSource,
meshTarget,
patchMap,
addProcessorPatches(meshTarget, cuttingPatches),
mapOrder,
subtract
);
}
}
}
else if (parallelSource && parallelTarget)
{
IOdictionary decompositionDictSource
(
IOobject
(
"decomposeParDict",
runTimeSource.system(),
runTimeSource,
IOobject::MUST_READ_IF_MODIFIED,
IOobject::NO_WRITE
)
);
int nProcsSource
(
readInt(decompositionDictSource.lookup("numberOfSubdomains"))
);
IOdictionary decompositionDictTarget
(
IOobject
(
"decomposeParDict",
runTimeTarget.system(),
runTimeTarget,
IOobject::MUST_READ_IF_MODIFIED,
IOobject::NO_WRITE
)
);
int nProcsTarget
(
readInt(decompositionDictTarget.lookup("numberOfSubdomains"))
);
List<boundBox> bbsTarget(nProcsTarget);
List<bool> bbsTargetSet(nProcsTarget, false);
for (int procISource=0; procISource<nProcsSource; procISource++)
{
Info<< nl << "Source processor " << procISource << endl;
Time runTimeSource
(
Time::controlDictName,
rootDirSource,
caseDirSource/fileName(word("processor") + name(procISource))
);
#include "setTimeIndex.H"
fvMesh meshSource
(
IOobject
(
sourceRegion,
runTimeSource.timeName(),
runTimeSource
)
);
Info<< "mesh size: " << meshSource.nCells() << endl;
boundBox bbSource(meshSource.bounds());
for (int procITarget=0; procITarget<nProcsTarget; procITarget++)
{
if
(
!bbsTargetSet[procITarget]
|| (
bbsTargetSet[procITarget]
&& bbsTarget[procITarget].overlaps(bbSource)
)
)
{
Info<< nl << "Target processor " << procITarget << endl;
Time runTimeTarget
(
Time::controlDictName,
rootDirTarget,
caseDirTarget/fileName(word("processor")
+ name(procITarget))
);
fvMesh meshTarget
(
IOobject
(
targetRegion,
runTimeTarget.timeName(),
runTimeTarget
)
);
Info<< "mesh size: " << meshTarget.nCells() << endl;
bbsTarget[procITarget] = meshTarget.bounds();
bbsTargetSet[procITarget] = true;
if (bbsTarget[procITarget].overlaps(bbSource))
{
if (consistent)
{
mapConsistentSubMesh
(
meshSource,
meshTarget,
mapOrder,
subtract
);
}
else
{
mapSubMesh
(
meshSource,
meshTarget,
patchMap,
addProcessorPatches(meshTarget, cuttingPatches),
mapOrder,
subtract
);
}
}
}
}
}
} }
else else
{ {
#include "setTimeIndex.H" mapSubMesh
Info<< "Create meshes\n" << endl;
fvMesh meshSource
( (
IOobject meshSource,
( meshTarget,
sourceRegion, patchMap,
runTimeSource.timeName(), addProcessorPatches(meshTarget, cuttingPatches),
runTimeSource mapMethod,
) subtract,
selectedFields,
noLagrangian
); );
fvMesh meshTarget
(
IOobject
(
targetRegion,
runTimeTarget.timeName(),
runTimeTarget
)
);
Info<< "Source mesh size: " << meshSource.nCells() << tab
<< "Target mesh size: " << meshTarget.nCells() << nl << endl;
if (consistent)
{
mapConsistentMesh(meshSource, meshTarget, mapOrder, subtract);
}
else
{
mapSubMesh
(
meshSource,
meshTarget,
patchMap,
cuttingPatches,
mapOrder,
subtract
);
}
} }
Info<< "\nEnd\n" << endl; Info<< "\nEnd\n" << endl;

View File

@ -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-2013 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2014 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -80,27 +80,17 @@ static label findCell(const Cloud<passiveParticle>& cloud, const point& pt)
} }
void mapLagrangian(const meshToMesh& meshToMeshInterp) void mapLagrangian(const meshToMesh& interp)
{ {
// Determine which particles are in meshTarget // Determine which particles are in meshTarget
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// target to source cell map const polyMesh& meshSource = interp.srcRegion();
const labelList& cellAddressing = meshToMeshInterp.cellAddressing(); const polyMesh& meshTarget = interp.tgtRegion();
const labelListList& sourceToTarget = interp.srcToTgtCellAddr();
// Invert celladdressing to get source to target(s).
// Note: could use sparse addressing but that is too storage inefficient
// (Map<labelList>)
labelListList sourceToTargets
(
invertOneToMany(meshToMeshInterp.fromMesh().nCells(), cellAddressing)
);
const fvMesh& meshSource = meshToMeshInterp.fromMesh();
const fvMesh& meshTarget = meshToMeshInterp.toMesh();
const pointField& targetCc = meshTarget.cellCentres(); const pointField& targetCc = meshTarget.cellCentres();
fileNameList cloudDirs fileNameList cloudDirs
( (
readDir readDir
@ -168,7 +158,7 @@ void mapLagrangian(const meshToMesh& meshToMeshInterp)
if (iter().cell() >= 0) if (iter().cell() >= 0)
{ {
const labelList& targetCells = const labelList& targetCells =
sourceToTargets[iter().cell()]; sourceToTarget[iter().cell()];
// Particle probably in one of the targetcells. Try // Particle probably in one of the targetcells. Try
// all by tracking from their cell centre to the parcel // all by tracking from their cell centre to the parcel
@ -259,17 +249,47 @@ void mapLagrangian(const meshToMesh& meshToMeshInterp)
// ~~~~~~~~~~~~~~~~~~~~~ // ~~~~~~~~~~~~~~~~~~~~~
MapLagrangianFields<label> MapLagrangianFields<label>
(cloudDirs[cloudI], objects, meshToMeshInterp, addParticles); (
cloudDirs[cloudI],
objects,
meshTarget,
addParticles
);
MapLagrangianFields<scalar> MapLagrangianFields<scalar>
(cloudDirs[cloudI], objects, meshToMeshInterp, addParticles); (
cloudDirs[cloudI],
objects,
meshTarget,
addParticles
);
MapLagrangianFields<vector> MapLagrangianFields<vector>
(cloudDirs[cloudI], objects, meshToMeshInterp, addParticles); (
cloudDirs[cloudI],
objects,
meshTarget,
addParticles
);
MapLagrangianFields<sphericalTensor> MapLagrangianFields<sphericalTensor>
(cloudDirs[cloudI], objects, meshToMeshInterp, addParticles); (
cloudDirs[cloudI],
objects,
meshTarget,
addParticles
);
MapLagrangianFields<symmTensor> MapLagrangianFields<symmTensor>
(cloudDirs[cloudI], objects, meshToMeshInterp, addParticles); (
cloudDirs[cloudI],
objects,
meshTarget,
addParticles
);
MapLagrangianFields<tensor> MapLagrangianFields<tensor>
(cloudDirs[cloudI], objects, meshToMeshInterp, addParticles); (
cloudDirs[cloudI],
objects,
meshTarget,
addParticles
);
} }
} }
} }

View File

@ -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-2014 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -43,7 +43,7 @@ namespace Foam
{ {
//- Maps lagrangian positions and fields //- Maps lagrangian positions and fields
void mapLagrangian(const meshToMesh& meshToMeshInterp); void mapLagrangian(const meshToMesh& interp);
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View File

@ -1,3 +1,4 @@
{
instantList sourceTimes = runTimeSource.times(); instantList sourceTimes = runTimeSource.times();
label sourceTimeIndex = runTimeSource.timeIndex(); label sourceTimeIndex = runTimeSource.timeIndex();
if (args.optionFound("sourceTime")) if (args.optionFound("sourceTime"))
@ -29,3 +30,4 @@
Info<< "\nSource time: " << runTimeSource.value() Info<< "\nSource time: " << runTimeSource.value()
<< "\nTarget time: " << runTimeTarget.value() << "\nTarget time: " << runTimeTarget.value()
<< endl; << endl;
}

View File

@ -1,4 +0,0 @@
mapLagrangian.C
mapFields.C
EXE = $(FOAM_APPBIN)/mapFieldsNew

View File

@ -1,13 +0,0 @@
EXE_INC = \
-DFULLDEBUG -g -O0 \
-I$(LIB_SRC)/meshTools/lnInclude \
-I$(LIB_SRC)/lagrangian/basic/lnInclude \
-I$(LIB_SRC)/finiteVolume/lnInclude \
-I$(LIB_SRC)/sampling/lnInclude
EXE_LIBS = \
-lsampling \
-lmeshTools \
-llagrangian \
-lfiniteVolume \
-lgenericPatchFields

View File

@ -1,184 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2013 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/>.
InNamespace
Foam
Description
Gets the indices of (source)particles that have been appended to the
target cloud and maps the lagrangian fields accordingly.
\*---------------------------------------------------------------------------*/
#ifndef MapLagrangianFields_H
#define MapLagrangianFields_H
#include "cloud.H"
#include "GeometricField.H"
#include "meshToMeshNew.H"
#include "IOobjectList.H"
#include "CompactIOField.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
//- Gets the indices of (source)particles that have been appended to the
// target cloud and maps the lagrangian fields accordingly.
template<class Type>
void MapLagrangianFields
(
const string& cloudName,
const IOobjectList& objects,
const polyMesh& meshTarget,
const labelList& addParticles
)
{
{
IOobjectList fields = objects.lookupClass(IOField<Type>::typeName);
forAllIter(IOobjectList, fields, fieldIter)
{
const word& fieldName = fieldIter()->name();
Info<< " mapping lagrangian field " << fieldName << endl;
// Read field (does not need mesh)
IOField<Type> fieldSource(*fieldIter());
// Map
IOField<Type> fieldTarget
(
IOobject
(
fieldName,
meshTarget.time().timeName(),
cloud::prefix/cloudName,
meshTarget,
IOobject::NO_READ,
IOobject::NO_WRITE,
false
),
addParticles.size()
);
forAll(addParticles, i)
{
fieldTarget[i] = fieldSource[addParticles[i]];
}
// Write field
fieldTarget.write();
}
}
{
IOobjectList fieldFields =
objects.lookupClass(IOField<Field<Type> >::typeName);
forAllIter(IOobjectList, fieldFields, fieldIter)
{
const word& fieldName = fieldIter()->name();
Info<< " mapping lagrangian fieldField " << fieldName << endl;
// Read field (does not need mesh)
IOField<Field<Type> > fieldSource(*fieldIter());
// Map - use CompactIOField to automatically write in
// compact form for binary format.
CompactIOField<Field<Type>, Type> fieldTarget
(
IOobject
(
fieldName,
meshTarget.time().timeName(),
cloud::prefix/cloudName,
meshTarget,
IOobject::NO_READ,
IOobject::NO_WRITE,
false
),
addParticles.size()
);
forAll(addParticles, i)
{
fieldTarget[i] = fieldSource[addParticles[i]];
}
// Write field
fieldTarget.write();
}
}
{
IOobjectList fieldFields =
objects.lookupClass(CompactIOField<Field<Type>, Type>::typeName);
forAllIter(IOobjectList, fieldFields, fieldIter)
{
Info<< " mapping lagrangian fieldField "
<< fieldIter()->name() << endl;
// Read field (does not need mesh)
CompactIOField<Field<Type>, Type> fieldSource(*fieldIter());
// Map
CompactIOField<Field<Type>, Type> fieldTarget
(
IOobject
(
fieldIter()->name(),
meshTarget.time().timeName(),
cloud::prefix/cloudName,
meshTarget,
IOobject::NO_READ,
IOobject::NO_WRITE,
false
),
addParticles.size()
);
forAll(addParticles, i)
{
fieldTarget[i] = fieldSource[addParticles[i]];
}
// Write field
fieldTarget.write();
}
}
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -1,131 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2013 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 "mapLagrangian.H"
#include "UnMapped.H"
#include "pointMesh.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
template<template<class> class CombineOp>
void MapMesh
(
const meshToMeshNew& interp,
const HashSet<word>& selectedFields,
const bool noLagrangian
)
{
{
const polyMesh& meshSource = interp.srcRegion();
// Search for list of objects for this time
IOobjectList objects(meshSource, meshSource.time().timeName());
// Map volFields
// ~~~~~~~~~~~~~
MapVolFields<scalar>
(
objects,
selectedFields,
interp,
CombineOp<scalar>()
);
MapVolFields<vector>
(
objects,
selectedFields,
interp,
CombineOp<vector>()
);
MapVolFields<sphericalTensor>
(
objects,
selectedFields,
interp,
CombineOp<sphericalTensor>()
);
MapVolFields<symmTensor>
(
objects,
selectedFields,
interp,
CombineOp<symmTensor>()
);
MapVolFields<tensor>
(
objects,
selectedFields,
interp,
CombineOp<tensor>()
);
}
{
const polyMesh& meshTarget = interp.tgtRegion();
// 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);
}
if (!noLagrangian)
{
mapLagrangian(interp);
}
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -1,104 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2013 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 MapConsistentVolFields_H
#define MapConsistentVolFields_H
#include "GeometricField.H"
#include "meshToMeshNew.H"
#include "IOobjectList.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
template<class Type, class CombineOp>
void MapVolFields
(
const IOobjectList& objects,
const HashSet<word>& selectedFields,
const meshToMeshNew& interp,
const CombineOp& cop
)
{
typedef GeometricField<Type, fvPatchField, volMesh> fieldType;
const fvMesh& meshSource = static_cast<const fvMesh&>(interp.srcRegion());
const fvMesh& meshTarget = static_cast<const fvMesh&>(interp.tgtRegion());
IOobjectList fields = objects.lookupClass(fieldType::typeName);
forAllIter(IOobjectList, fields, fieldIter)
{
const word& fieldName = fieldIter()->name();
if (selectedFields.empty() || selectedFields.found(fieldName))
{
Info<< " interpolating " << fieldName << endl;
const fieldType fieldSource(*fieldIter(), meshSource);
IOobject targetIO
(
fieldName,
meshTarget.time().timeName(),
meshTarget,
IOobject::MUST_READ
);
if (targetIO.headerOk())
{
fieldType fieldTarget(targetIO, meshTarget);
interp.mapSrcToTgt(fieldSource, cop, fieldTarget);
fieldTarget.write();
}
else
{
targetIO.readOpt() = IOobject::NO_READ;
tmp<fieldType>
tfieldTarget(interp.mapSrcToTgt(fieldSource, cop));
fieldType fieldTarget(targetIO, tfieldTarget);
fieldTarget.write();
}
}
}
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -1,57 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2013 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 UnMapped_H
#define UnMapped_H
#include "IOobjectList.H"
#include "OSspecific.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
template<class Type>
void UnMapped(const IOobjectList& objects)
{
IOobjectList fields = objects.lookupClass(Type::typeName);
forAllConstIter(IOobjectList, fields, fieldIter)
{
mvBak(fieldIter()->objectPath(), "unmapped");
}
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -1,11 +0,0 @@
Info<< "\nCreate databases as time" << endl;
HashTable<string> srcOptions(args.options());
srcOptions.erase("case");
srcOptions.insert("case", fileName(rootDirSource/caseDirSource));
argList argsSrc(args, srcOptions, false, false, false);
Time runTimeSource(Time::controlDictName, argsSrc);
Time runTimeTarget(Time::controlDictName, args);

View File

@ -1,343 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2013 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/>.
Application
mapFields
Description
Maps volume fields from one mesh to another, reading and
interpolating all fields present in the time directory of both cases.
\*---------------------------------------------------------------------------*/
#include "fvCFD.H"
#include "meshToMeshNew.H"
#include "processorPolyPatch.H"
#include "MapMeshes.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
void mapConsistentMesh
(
const fvMesh& meshSource,
const fvMesh& meshTarget,
const meshToMeshNew::interpolationMethod& mapMethod,
const bool subtract,
const HashSet<word>& selectedFields,
const bool noLagrangian
)
{
Info<< nl << "Consistently creating and mapping fields for time "
<< meshSource.time().timeName() << nl << endl;
meshToMeshNew interp(meshSource, meshTarget, mapMethod);
if (subtract)
{
MapMesh<minusEqOp>
(
interp,
selectedFields,
noLagrangian
);
}
else
{
MapMesh<plusEqOp>
(
interp,
selectedFields,
noLagrangian
);
}
}
void mapSubMesh
(
const fvMesh& meshSource,
const fvMesh& meshTarget,
const HashTable<word>& patchMap,
const wordList& cuttingPatches,
const meshToMeshNew::interpolationMethod& mapMethod,
const bool subtract,
const HashSet<word>& selectedFields,
const bool noLagrangian
)
{
Info<< nl << "Creating and mapping fields for time "
<< meshSource.time().timeName() << nl << endl;
meshToMeshNew interp
(
meshSource,
meshTarget,
mapMethod,
patchMap,
cuttingPatches
);
if (subtract)
{
MapMesh<minusEqOp>
(
interp,
selectedFields,
noLagrangian
);
}
else
{
MapMesh<plusEqOp>
(
interp,
selectedFields,
noLagrangian
);
}
}
wordList addProcessorPatches
(
const fvMesh& meshTarget,
const wordList& cuttingPatches
)
{
// Add the processor patches to the cutting list
HashSet<word> cuttingPatchTable;
forAll(cuttingPatches, i)
{
cuttingPatchTable.insert(cuttingPatches[i]);
}
const polyBoundaryMesh& pbm = meshTarget.boundaryMesh();
forAll(pbm, patchI)
{
if (isA<processorPolyPatch>(pbm[patchI]))
{
const word& patchName = pbm[patchI].name();
cuttingPatchTable.insert(patchName);
}
}
return cuttingPatchTable.toc();
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
int main(int argc, char *argv[])
{
argList::addNote
(
"map volume fields from one mesh to another"
);
argList::validArgs.append("sourceCase");
argList::addOption
(
"sourceTime",
"scalar|'latestTime'",
"specify the source time"
);
argList::addOption
(
"sourceRegion",
"word",
"specify the source region"
);
argList::addOption
(
"targetRegion",
"word",
"specify the target region"
);
argList::addBoolOption
(
"consistent",
"source and target geometry and boundary conditions identical"
);
argList::addOption
(
"mapMethod",
"word",
"specify the mapping method"
);
argList::addBoolOption
(
"subtract",
"subtract mapped source from target"
);
argList::addOption
(
"fields",
"list",
"specify a list of fields to be mapped. Eg, '(U T p)' - "
"regular expressions not currently supported"
);
argList::addBoolOption
(
"noLagrangian",
"skip mapping lagrangian positions and fields"
);
argList args(argc, argv);
fileName rootDirTarget(args.rootPath());
fileName caseDirTarget(args.globalCaseName());
const fileName casePath = args[1];
const fileName rootDirSource = casePath.path();
const fileName caseDirSource = casePath.name();
Info<< "Source: " << rootDirSource << " " << caseDirSource << endl;
word sourceRegion = fvMesh::defaultRegion;
if (args.optionFound("sourceRegion"))
{
sourceRegion = args["sourceRegion"];
Info<< "Source region: " << sourceRegion << endl;
}
Info<< "Target: " << rootDirTarget << " " << caseDirTarget << endl;
word targetRegion = fvMesh::defaultRegion;
if (args.optionFound("targetRegion"))
{
targetRegion = args["targetRegion"];
Info<< "Target region: " << targetRegion << endl;
}
const bool consistent = args.optionFound("consistent");
meshToMeshNew::interpolationMethod mapMethod =
meshToMeshNew::imCellVolumeWeight;
if (args.optionFound("mapMethod"))
{
mapMethod = meshToMeshNew::interpolationMethodNames_[args["mapMethod"]];
Info<< "Mapping method: "
<< meshToMeshNew::interpolationMethodNames_[mapMethod] << endl;
}
const bool subtract = args.optionFound("subtract");
if (subtract)
{
Info<< "Subtracting mapped source field from target" << endl;
}
HashSet<word> selectedFields;
if (args.optionFound("fields"))
{
args.optionLookup("fields")() >> selectedFields;
}
const bool noLagrangian = args.optionFound("noLagrangian");
#include "createTimes.H"
HashTable<word> patchMap;
wordList cuttingPatches;
if (!consistent)
{
IOdictionary mapFieldsDict
(
IOobject
(
"mapFieldsDict",
runTimeTarget.system(),
runTimeTarget,
IOobject::MUST_READ_IF_MODIFIED,
IOobject::NO_WRITE,
false
)
);
mapFieldsDict.lookup("patchMap") >> patchMap;
mapFieldsDict.lookup("cuttingPatches") >> cuttingPatches;
}
#include "setTimeIndex.H"
Info<< "\nCreate meshes\n" << endl;
fvMesh meshSource
(
IOobject
(
sourceRegion,
runTimeSource.timeName(),
runTimeSource
)
);
fvMesh meshTarget
(
IOobject
(
targetRegion,
runTimeTarget.timeName(),
runTimeTarget
)
);
Info<< "Source mesh size: " << meshSource.nCells() << tab
<< "Target mesh size: " << meshTarget.nCells() << nl << endl;
if (consistent)
{
mapConsistentMesh
(
meshSource,
meshTarget,
mapMethod,
subtract,
selectedFields,
noLagrangian
);
}
else
{
mapSubMesh
(
meshSource,
meshTarget,
patchMap,
addProcessorPatches(meshTarget, cuttingPatches),
mapMethod,
subtract,
selectedFields,
noLagrangian
);
}
Info<< "\nEnd\n" << endl;
return 0;
}
// ************************************************************************* //

View File

@ -1,36 +0,0 @@
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: dev |
| \\ / A nd | Web: www.OpenFOAM.org |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class dictionary;
object mapFieldsDict;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// Specify how to map patches. There are three different options:
// - patch exists in the source case: specify mapping (patchMap)
// - patch should be interpolated from internal values in source case
// (cuttingPatches)
// - patch should not be mapped. Default if not in patchMap or cuttingPatches
// List of pairs of target/source patches for mapping
patchMap
(
lid movingWall
);
// List of target patches cutting the source domain (these need to be
// handled specially e.g. interpolated from internal values)
cuttingPatches
(
fixedWalls
);
// ************************************************************************* //

View File

@ -1,303 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2013 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 "MapLagrangianFields.H"
#include "passiveParticleCloud.H"
#include "meshSearch.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
static const scalar perturbFactor = 1e-6;
// Special version of findCell that generates a cell guaranteed to be
// compatible with tracking.
static label findCell(const Cloud<passiveParticle>& cloud, const point& pt)
{
label cellI = -1;
label tetFaceI = -1;
label tetPtI = -1;
const polyMesh& mesh = cloud.pMesh();
mesh.findCellFacePt(pt, cellI, tetFaceI, tetPtI);
if (cellI >= 0)
{
return cellI;
}
else
{
// See if particle on face by finding nearest face and shifting
// particle.
meshSearch meshSearcher
(
mesh,
polyMesh::FACEPLANES // no decomposition needed
);
label faceI = meshSearcher.findNearestBoundaryFace(pt);
if (faceI >= 0)
{
const point& cc = mesh.cellCentres()[mesh.faceOwner()[faceI]];
const point perturbPt = (1-perturbFactor)*pt+perturbFactor*cc;
mesh.findCellFacePt(perturbPt, cellI, tetFaceI, tetPtI);
return cellI;
}
}
return -1;
}
void mapLagrangian(const meshToMeshNew& interp)
{
// Determine which particles are in meshTarget
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
const polyMesh& meshSource = interp.srcRegion();
const polyMesh& meshTarget = interp.tgtRegion();
const labelListList& sourceToTarget = interp.srcToTgtCellAddr();
const pointField& targetCc = meshTarget.cellCentres();
fileNameList cloudDirs
(
readDir
(
meshSource.time().timePath()/cloud::prefix,
fileName::DIRECTORY
)
);
forAll(cloudDirs, cloudI)
{
// Search for list of lagrangian objects for this time
IOobjectList objects
(
meshSource,
meshSource.time().timeName(),
cloud::prefix/cloudDirs[cloudI]
);
IOobject* positionsPtr = objects.lookup(word("positions"));
if (positionsPtr)
{
Info<< nl << " processing cloud " << cloudDirs[cloudI] << endl;
// Read positions & cell
passiveParticleCloud sourceParcels
(
meshSource,
cloudDirs[cloudI],
false
);
Info<< " read " << sourceParcels.size()
<< " parcels from source mesh." << endl;
// Construct empty target cloud
passiveParticleCloud targetParcels
(
meshTarget,
cloudDirs[cloudI],
IDLList<passiveParticle>()
);
particle::TrackingData<passiveParticleCloud> td(targetParcels);
label sourceParticleI = 0;
// Indices of source particles that get added to targetParcels
DynamicList<label> addParticles(sourceParcels.size());
// Unmapped particles
labelHashSet unmappedSource(sourceParcels.size());
// Initial: track from fine-mesh cell centre to particle position
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// This requires there to be no boundary in the way.
forAllConstIter(Cloud<passiveParticle>, sourceParcels, iter)
{
bool foundCell = false;
// Assume that cell from read parcel is the correct one...
if (iter().cell() >= 0)
{
const labelList& targetCells =
sourceToTarget[iter().cell()];
// Particle probably in one of the targetcells. Try
// all by tracking from their cell centre to the parcel
// position.
forAll(targetCells, i)
{
// Track from its cellcentre to position to make sure.
autoPtr<passiveParticle> newPtr
(
new passiveParticle
(
meshTarget,
targetCc[targetCells[i]],
targetCells[i]
)
);
passiveParticle& newP = newPtr();
label faceI = newP.track(iter().position(), td);
if (faceI < 0 && newP.cell() >= 0)
{
// Hit position.
foundCell = true;
addParticles.append(sourceParticleI);
targetParcels.addParticle(newPtr.ptr());
break;
}
}
}
if (!foundCell)
{
// Store for closer analysis
unmappedSource.insert(sourceParticleI);
}
sourceParticleI++;
}
Info<< " after meshToMesh addressing found "
<< targetParcels.size()
<< " parcels in target mesh." << endl;
// Do closer inspection for unmapped particles
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
if (unmappedSource.size())
{
sourceParticleI = 0;
forAllIter(Cloud<passiveParticle>, sourceParcels, iter)
{
if (unmappedSource.found(sourceParticleI))
{
label targetCell =
findCell(targetParcels, iter().position());
if (targetCell >= 0)
{
unmappedSource.erase(sourceParticleI);
addParticles.append(sourceParticleI);
iter().cell() = targetCell;
targetParcels.addParticle
(
sourceParcels.remove(&iter())
);
}
}
sourceParticleI++;
}
}
addParticles.shrink();
Info<< " after additional mesh searching found "
<< targetParcels.size() << " parcels in target mesh." << endl;
if (addParticles.size())
{
IOPosition<passiveParticleCloud>(targetParcels).write();
// addParticles now contains the indices of the sourceMesh
// particles that were appended to the target mesh.
// Map lagrangian fields
// ~~~~~~~~~~~~~~~~~~~~~
MapLagrangianFields<label>
(
cloudDirs[cloudI],
objects,
meshTarget,
addParticles
);
MapLagrangianFields<scalar>
(
cloudDirs[cloudI],
objects,
meshTarget,
addParticles
);
MapLagrangianFields<vector>
(
cloudDirs[cloudI],
objects,
meshTarget,
addParticles
);
MapLagrangianFields<sphericalTensor>
(
cloudDirs[cloudI],
objects,
meshTarget,
addParticles
);
MapLagrangianFields<symmTensor>
(
cloudDirs[cloudI],
objects,
meshTarget,
addParticles
);
MapLagrangianFields<tensor>
(
cloudDirs[cloudI],
objects,
meshTarget,
addParticles
);
}
}
}
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// ************************************************************************* //

View File

@ -1,56 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2013 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/>.
InNamespace
Foam
Description
Maps lagrangian positions and fields
SourceFiles
mapLagrangian.C
\*---------------------------------------------------------------------------*/
#ifndef mapLagrangian_H
#define mapLagrangian_H
#include "meshToMeshNew.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
//- Maps lagrangian positions and fields
void mapLagrangian(const meshToMeshNew& interp);
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -1,33 +0,0 @@
{
instantList sourceTimes = runTimeSource.times();
label sourceTimeIndex = runTimeSource.timeIndex();
if (args.optionFound("sourceTime"))
{
if (args["sourceTime"] == "latestTime")
{
sourceTimeIndex = sourceTimes.size() - 1;
}
else
{
sourceTimeIndex = Time::findClosestTimeIndex
(
sourceTimes,
args.optionRead<scalar>("sourceTime")
);
}
}
else
{
sourceTimeIndex = Time::findClosestTimeIndex
(
sourceTimes,
runTimeTarget.time().value()
);
}
runTimeSource.setTime(sourceTimes[sourceTimeIndex], sourceTimeIndex);
Info<< "\nSource time: " << runTimeSource.value()
<< "\nTarget time: " << runTimeTarget.value()
<< endl;
}

View File

@ -188,39 +188,14 @@ Foam::OSstream& Foam::messageStream::operator()
Foam::OSstream& Foam::messageStream::operator()(const bool output) Foam::OSstream& Foam::messageStream::operator()(const bool output)
{ {
if (level) if (output)
{ {
bool collect = (severity_ == INFO || severity_ == WARNING); return operator()();
}
// Report the error else
if (!output && collect) {
{ return Snull;
return Snull;
}
else
{
if (title().size())
{
Pout<< title().c_str();
}
if (maxErrors_)
{
errorCount_++;
if (errorCount_ >= maxErrors_)
{
FatalErrorIn("messageStream::operator OSstream&()")
<< "Too many errors"
<< abort(FatalError);
}
}
return Pout;
}
} }
return Snull;
} }

View File

@ -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-2013 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2014 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -55,7 +55,7 @@ namespace Foam
{ {
/*---------------------------------------------------------------------------*\ /*---------------------------------------------------------------------------*\
Class solidBodyMotionFunction Declaration s Class solidBodyMotionFunction Declaration
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
class solidBodyMotionFunction class solidBodyMotionFunction

View File

@ -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-2013 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2014 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -187,11 +187,11 @@ void Foam::fv::option::setCellSet()
{ {
meshInterpPtr_.reset meshInterpPtr_.reset
( (
new meshToMeshNew new meshToMesh
( (
mesh_, mesh_,
nbrMesh, nbrMesh,
meshToMeshNew::interpolationMethodNames_.read meshToMesh::interpolationMethodNames_.read
( (
dict_.lookup("interpolationMethod") dict_.lookup("interpolationMethod")
), ),

View File

@ -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-2013 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2014 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -50,7 +50,7 @@ SourceFiles
#include "volFieldsFwd.H" #include "volFieldsFwd.H"
#include "cellSet.H" #include "cellSet.H"
#include "autoPtr.H" #include "autoPtr.H"
#include "meshToMeshNew.H" #include "meshToMesh.H"
#include "runTimeSelectionTables.H" #include "runTimeSelectionTables.H"
@ -135,7 +135,7 @@ protected:
// Data for smMapRegion only // Data for smMapRegion only
//- Mesh to mesh interpolation object //- Mesh to mesh interpolation object
autoPtr<meshToMeshNew> meshInterpPtr_; autoPtr<meshToMesh> meshInterpPtr_;
//- Name of the neighbour region to map //- Name of the neighbour region to map
word nbrRegionName_; word nbrRegionName_;
@ -293,7 +293,7 @@ public:
inline const word& nbrRegionName() const; inline const word& nbrRegionName() const;
//- Return const access to the mapToMap pointer //- Return const access to the mapToMap pointer
inline const meshToMeshNew& meshInterp() const; inline const meshToMesh& meshInterp() const;
//- Return const access to the cell set //- Return const access to the cell set
inline const labelList& cells() const; inline const labelList& cells() const;

View File

@ -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-2013 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2014 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -132,11 +132,11 @@ inline const Foam::word& Foam::fv::option::nbrRegionName() const
} }
inline const Foam::meshToMeshNew& Foam::fv::option::meshInterp() const inline const Foam::meshToMesh& Foam::fv::option::meshInterp() const
{ {
if (!meshInterpPtr_.valid()) if (!meshInterpPtr_.valid())
{ {
FatalErrorIn("const meshToMeshNew& meshInterp() const") FatalErrorIn("const meshToMesh& meshInterp() const")
<< "Interpolation object not set" << "Interpolation object not set"
<< abort(FatalError); << abort(FatalError);
} }

View File

@ -356,7 +356,7 @@ void Foam::nearWallFields::execute()
Info<< type() << " " << name_ << " output:" << nl; Info<< type() << " " << name_ << " output:" << nl;
Info<< " Sampling fields fields to " << obr_.time().timeName() Info<< " Sampling fields to " << obr_.time().timeName()
<< endl; << endl;
sampleFields(vsf_); sampleFields(vsf_);

View File

@ -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-2013 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2014 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -128,7 +128,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 << " seeded " << nSeeds << " particles" << endl;
// Read or lookup fields // Read or lookup fields
PtrList<volScalarField> vsFlds; PtrList<volScalarField> vsFlds;
@ -625,7 +625,8 @@ void Foam::streamLine::write()
n += allTracks_[trackI].size(); n += allTracks_[trackI].size();
} }
Info<< " Tracks:" << allTracks_.size() << " total samples:" << n Info<< " Tracks:" << allTracks_.size() << nl
<< " Total samples:" << n
<< endl; << endl;

View File

@ -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-2013 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2014 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -750,8 +750,8 @@ void Foam::wallBoundedStreamLine::write()
n += allTracks_[trackI].size(); n += allTracks_[trackI].size();
} }
Info<< "Tracks:" << allTracks_.size() Info<< " Tracks:" << allTracks_.size() << nl
<< " total samples:" << n << endl; << " Total samples:" << n << endl;
// Massage into form suitable for writers // Massage into form suitable for writers

View File

@ -678,16 +678,14 @@ void Foam::forces::read(const dictionary& dict)
localSystem_ = true; localSystem_ = true;
} }
if (dict.readIfPresent("porosity", porosity_) && log_) dict.readIfPresent("porosity", porosity_);
if (porosity_)
{ {
if (porosity_) Info(log_)<< " Including porosity effects" << endl;
{ }
Info<< " Including porosity effects" << endl; else
} {
else Info(log_)<< " Not including porosity effects" << endl;
{
Info<< " Not including porosity effects" << endl;
}
} }
if (dict.found("binData")) if (dict.found("binData"))

View File

@ -57,18 +57,13 @@ graphField/makeGraph.C
meshToMesh = meshToMeshInterpolation/meshToMesh meshToMesh = meshToMeshInterpolation/meshToMesh
$(meshToMesh)/meshToMesh.C $(meshToMesh)/meshToMesh.C
$(meshToMesh)/calculateMeshToMeshAddressing.C $(meshToMesh)/meshToMeshParallelOps.C
$(meshToMesh)/calculateMeshToMeshWeights.C meshToMeshMethods = meshToMeshInterpolation/meshToMesh/calcMethod
$(meshToMeshMethods)/meshToMeshMethod/meshToMeshMethod.C
meshToMeshNew = meshToMeshInterpolation/meshToMeshNew $(meshToMeshMethods)/meshToMeshMethod/meshToMeshMethodNew.C
$(meshToMeshNew)/meshToMeshNew.C $(meshToMeshMethods)/cellVolumeWeight/cellVolumeWeightMethod.C
$(meshToMeshNew)/meshToMeshNewParallelOps.C $(meshToMeshMethods)/direct/directMethod.C
meshToMeshNewMethods = meshToMeshInterpolation/meshToMeshNew/calcMethod $(meshToMeshMethods)/mapNearest/mapNearestMethod.C
$(meshToMeshNewMethods)/meshToMeshMethod/meshToMeshMethod.C
$(meshToMeshNewMethods)/meshToMeshMethod/meshToMeshMethodNew.C
$(meshToMeshNewMethods)/cellVolumeWeight/cellVolumeWeightMethod.C
$(meshToMeshNewMethods)/direct/directMethod.C
$(meshToMeshNewMethods)/mapNearest/mapNearestMethod.C
LIB = $(FOAM_LIBBIN)/libsampling LIB = $(FOAM_LIBBIN)/libsampling

View File

@ -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-2014 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License

View File

@ -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-2014 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License

View File

@ -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-2014 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License

View File

@ -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-2014 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License

View File

@ -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-2014 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License

View File

@ -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-2014 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License

View File

@ -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-2014 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License

View File

@ -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-2014 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License

View File

@ -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-2014 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License

View File

@ -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-2014 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License

View File

@ -1,343 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2012 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
private member of meshToMesh.
Calculates mesh to mesh addressing pattern (for each cell from one mesh
find the closest cell centre in the other mesh).
\*---------------------------------------------------------------------------*/
#include "meshToMesh.H"
#include "SubField.H"
#include "indexedOctree.H"
#include "treeDataCell.H"
#include "treeDataFace.H"
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
void Foam::meshToMesh::calcAddressing()
{
if (debug)
{
Info<< "meshToMesh::calculateAddressing() : "
<< "calculating mesh-to-mesh cell addressing" << endl;
}
// set reference to cells
const cellList& fromCells = fromMesh_.cells();
const pointField& fromPoints = fromMesh_.points();
// In an attempt to preserve the efficiency of linear search and prevent
// failure, a RESCUE mechanism will be set up. Here, we shall mark all
// cells next to the solid boundaries. If such a cell is found as the
// closest, the relationship between the origin and cell will be examined.
// If the origin is outside the cell, a global n-squared search is
// triggered.
// SETTING UP RESCUE
// visit all boundaries and mark the cell next to the boundary.
if (debug)
{
Info<< "meshToMesh::calculateAddressing() : "
<< "Setting up rescue" << endl;
}
List<bool> boundaryCell(fromCells.size(), false);
// set reference to boundary
const polyPatchList& patchesFrom = fromMesh_.boundaryMesh();
forAll(patchesFrom, patchI)
{
// get reference to cells next to the boundary
const labelUList& bCells = patchesFrom[patchI].faceCells();
forAll(bCells, faceI)
{
boundaryCell[bCells[faceI]] = true;
}
}
treeBoundBox meshBb(fromPoints);
scalar typDim = meshBb.avgDim()/(2.0*cbrt(scalar(fromCells.size())));
treeBoundBox shiftedBb
(
meshBb.min(),
meshBb.max() + vector(typDim, typDim, typDim)
);
if (debug)
{
Info<< "\nMesh" << endl;
Info<< " bounding box : " << meshBb << endl;
Info<< " bounding box (shifted) : " << shiftedBb << endl;
Info<< " typical dimension :" << shiftedBb.typDim() << endl;
}
indexedOctree<treeDataCell> oc
(
treeDataCell(false, fromMesh_, polyMesh::FACEDIAGTETS),
shiftedBb, // overall bounding box
8, // maxLevel
10, // leafsize
6.0 // duplicity
);
if (debug)
{
oc.print(Pout, false, 0);
}
cellAddresses
(
cellAddressing_,
toMesh_.cellCentres(),
fromMesh_,
boundaryCell,
oc
);
forAll(toMesh_.boundaryMesh(), patchi)
{
const polyPatch& toPatch = toMesh_.boundaryMesh()[patchi];
if (cuttingPatches_.found(toPatch.name()))
{
boundaryAddressing_[patchi].setSize(toPatch.size());
cellAddresses
(
boundaryAddressing_[patchi],
toPatch.faceCentres(),
fromMesh_,
boundaryCell,
oc
);
}
else if
(
patchMap_.found(toPatch.name())
&& fromMeshPatches_.found(patchMap_.find(toPatch.name())())
)
{
const polyPatch& fromPatch = fromMesh_.boundaryMesh()
[
fromMeshPatches_.find(patchMap_.find(toPatch.name())())()
];
if (fromPatch.empty())
{
WarningIn("meshToMesh::calcAddressing()")
<< "Source patch " << fromPatch.name()
<< " has no faces. Not performing mapping for it."
<< endl;
boundaryAddressing_[patchi] = -1;
}
else
{
treeBoundBox wallBb(fromPatch.localPoints());
scalar typDim =
wallBb.avgDim()/(2.0*sqrt(scalar(fromPatch.size())));
treeBoundBox shiftedBb
(
wallBb.min(),
wallBb.max() + vector(typDim, typDim, typDim)
);
// Note: allow more levels than in meshSearch. Assume patch
// is not as big as all boundary faces
indexedOctree<treeDataFace> oc
(
treeDataFace(false, fromPatch),
shiftedBb, // overall search domain
12, // maxLevel
10, // leafsize
6.0 // duplicity
);
const vectorField::subField centresToBoundary =
toPatch.faceCentres();
boundaryAddressing_[patchi].setSize(toPatch.size());
scalar distSqr = sqr(wallBb.mag());
forAll(toPatch, toi)
{
boundaryAddressing_[patchi][toi] = oc.findNearest
(
centresToBoundary[toi],
distSqr
).index();
}
}
}
}
if (debug)
{
Info<< "meshToMesh::calculateAddressing() : "
<< "finished calculating mesh-to-mesh cell addressing" << endl;
}
}
void Foam::meshToMesh::cellAddresses
(
labelList& cellAddressing_,
const pointField& points,
const fvMesh& fromMesh,
const List<bool>& boundaryCell,
const indexedOctree<treeDataCell>& oc
) const
{
// the implemented search method is a simple neighbour array search.
// It starts from a cell zero, searches its neighbours and finds one
// which is nearer to the target point than the current position.
// The location of the "current position" is reset to that cell and
// search through the neighbours continues. The search is finished
// when all the neighbours of the cell are farther from the target
// point than the current cell
// set curCell label to zero (start)
register label curCell = 0;
// set reference to cell to cell addressing
const vectorField& centresFrom = fromMesh.cellCentres();
const labelListList& cc = fromMesh.cellCells();
forAll(points, toI)
{
// pick up target position
const vector& p = points[toI];
// set the sqr-distance
scalar distSqr = magSqr(p - centresFrom[curCell]);
bool closer;
do
{
closer = false;
// set the current list of neighbouring cells
const labelList& neighbours = cc[curCell];
forAll(neighbours, nI)
{
scalar curDistSqr =
magSqr(p - centresFrom[neighbours[nI]]);
// search through all the neighbours.
// If the cell is closer, reset current cell and distance
if (curDistSqr < (1 - SMALL)*distSqr)
{
curCell = neighbours[nI];
distSqr = curDistSqr;
closer = true; // a closer neighbour has been found
}
}
} while (closer);
cellAddressing_[toI] = -1;
// Check point is actually in the nearest cell
if (fromMesh.pointInCell(p, curCell))
{
cellAddressing_[toI] = curCell;
}
else
{
// If curCell is a boundary cell then the point maybe either outside
// the domain or in an other region of the doamin, either way use
// the octree search to find it.
if (boundaryCell[curCell])
{
cellAddressing_[toI] = oc.findInside(p);
}
else
{
// If not on the boundary search the neighbours
bool found = false;
// set the current list of neighbouring cells
const labelList& neighbours = cc[curCell];
forAll(neighbours, nI)
{
// search through all the neighbours.
// If point is in neighbour reset current cell
if (fromMesh.pointInCell(p, neighbours[nI]))
{
cellAddressing_[toI] = neighbours[nI];
found = true;
break;
}
}
if (!found)
{
// If still not found search the neighbour-neighbours
// set the current list of neighbouring cells
const labelList& neighbours = cc[curCell];
forAll(neighbours, nI)
{
// set the current list of neighbour-neighbouring cells
const labelList& nn = cc[neighbours[nI]];
forAll(nn, nI)
{
// search through all the neighbours.
// If point is in neighbour reset current cell
if (fromMesh.pointInCell(p, nn[nI]))
{
cellAddressing_[toI] = nn[nI];
found = true;
break;
}
}
if (found) break;
}
}
if (!found)
{
// Still not found so us the octree
cellAddressing_[toI] = oc.findInside(p);
}
}
}
}
}
// ************************************************************************* //

View File

@ -1,274 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2013 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 "meshToMesh.H"
#include "tetOverlapVolume.H"
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
void Foam::meshToMesh::calculateInverseDistanceWeights() const
{
if (debug)
{
Info<< "meshToMesh::calculateInverseDistanceWeights() : "
<< "calculating inverse distance weighting factors" << endl;
}
if (inverseDistanceWeightsPtr_)
{
FatalErrorIn("meshToMesh::calculateInverseDistanceWeights()")
<< "weighting factors already calculated"
<< exit(FatalError);
}
//- Initialise overlap volume to zero
V_ = 0.0;
inverseDistanceWeightsPtr_ = new scalarListList(toMesh_.nCells());
scalarListList& invDistCoeffs = *inverseDistanceWeightsPtr_;
// get reference to source mesh data
const labelListList& cc = fromMesh_.cellCells();
const vectorField& centreFrom = fromMesh_.C().internalField();
const vectorField& centreTo = toMesh_.C().internalField();
forAll(cellAddressing_, celli)
{
if (cellAddressing_[celli] != -1)
{
const vector& target = centreTo[celli];
scalar m = mag(target - centreFrom[cellAddressing_[celli]]);
const labelList& neighbours = cc[cellAddressing_[celli]];
// if the nearest cell is a boundary cell or there is a direct hit,
// pick up the value
label directCelli = -1;
if (m < directHitTol || neighbours.empty())
{
directCelli = celli;
}
else
{
forAll(neighbours, ni)
{
scalar nm = mag(target - centreFrom[neighbours[ni]]);
if (nm < directHitTol)
{
directCelli = neighbours[ni];
break;
}
}
}
if (directCelli != -1)
{
// Direct hit
invDistCoeffs[directCelli].setSize(1);
invDistCoeffs[directCelli][0] = 1.0;
V_ += fromMesh_.V()[cellAddressing_[directCelli]];
}
else
{
invDistCoeffs[celli].setSize(neighbours.size() + 1);
// The first coefficient corresponds to the centre cell.
// The rest is ordered in the same way as the cellCells list.
scalar invDist = 1.0/m;
invDistCoeffs[celli][0] = invDist;
scalar sumInvDist = invDist;
// now add the neighbours
forAll(neighbours, ni)
{
invDist = 1.0/mag(target - centreFrom[neighbours[ni]]);
invDistCoeffs[celli][ni + 1] = invDist;
sumInvDist += invDist;
}
// divide by the total inverse-distance
forAll(invDistCoeffs[celli], i)
{
invDistCoeffs[celli][i] /= sumInvDist;
}
V_ +=
invDistCoeffs[celli][0]
*fromMesh_.V()[cellAddressing_[celli]];
for (label i = 1; i < invDistCoeffs[celli].size(); i++)
{
V_ +=
invDistCoeffs[celli][i]*fromMesh_.V()[neighbours[i-1]];
}
}
}
}
}
void Foam::meshToMesh::calculateInverseVolumeWeights() const
{
if (debug)
{
Info<< "meshToMesh::calculateInverseVolumeWeights() : "
<< "calculating inverse volume weighting factors" << endl;
}
if (inverseVolumeWeightsPtr_)
{
FatalErrorIn("meshToMesh::calculateInverseVolumeWeights()")
<< "weighting factors already calculated"
<< exit(FatalError);
}
//- Initialise overlap volume to zero
V_ = 0.0;
inverseVolumeWeightsPtr_ = new scalarListList(toMesh_.nCells());
scalarListList& invVolCoeffs = *inverseVolumeWeightsPtr_;
const labelListList& cellToCell = cellToCellAddressing();
tetOverlapVolume overlapEngine;
forAll(cellToCell, celli)
{
const labelList& overlapCells = cellToCell[celli];
if (overlapCells.size() > 0)
{
invVolCoeffs[celli].setSize(overlapCells.size());
forAll(overlapCells, j)
{
label cellFrom = overlapCells[j];
treeBoundBox bbFromMesh
(
pointField
(
fromMesh_.points(),
fromMesh_.cellPoints()[cellFrom]
)
);
scalar v = overlapEngine.cellCellOverlapVolumeMinDecomp
(
toMesh_,
celli,
fromMesh_,
cellFrom,
bbFromMesh
);
invVolCoeffs[celli][j] = v/toMesh_.V()[celli];
V_ += v;
}
}
}
}
void Foam::meshToMesh::calculateCellToCellAddressing() const
{
if (debug)
{
Info<< "meshToMesh::calculateCellToCellAddressing() : "
<< "calculating cell to cell addressing" << endl;
}
if (cellToCellAddressingPtr_)
{
FatalErrorIn("meshToMesh::calculateCellToCellAddressing()")
<< "addressing already calculated"
<< exit(FatalError);
}
//- Initialise overlap volume to zero
V_ = 0.0;
tetOverlapVolume overlapEngine;
cellToCellAddressingPtr_ = new labelListList(toMesh_.nCells());
labelListList& cellToCell = *cellToCellAddressingPtr_;
forAll(cellToCell, iTo)
{
const labelList overLapCells =
overlapEngine.overlappingCells(fromMesh_, toMesh_, iTo);
if (overLapCells.size() > 0)
{
//Info << "To " << iTo << endl;
//Info << "cellToCell " << overLapCells << endl;
cellToCell[iTo].setSize(overLapCells.size());
forAll(overLapCells, j)
{
cellToCell[iTo][j] = overLapCells[j];
V_ += fromMesh_.V()[overLapCells[j]];
}
}
}
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
const Foam::scalarListList& Foam::meshToMesh::inverseDistanceWeights() const
{
if (!inverseDistanceWeightsPtr_)
{
calculateInverseDistanceWeights();
}
return *inverseDistanceWeightsPtr_;
}
const Foam::scalarListList& Foam::meshToMesh::inverseVolumeWeights() const
{
if (!inverseVolumeWeightsPtr_)
{
calculateInverseVolumeWeights();
}
return *inverseVolumeWeightsPtr_;
}
const Foam::labelListList& Foam::meshToMesh::cellToCellAddressing() const
{
if (!cellToCellAddressingPtr_)
{
calculateCellToCellAddressing();
}
return *cellToCellAddressingPtr_;
}
// ************************************************************************* //

View File

@ -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-2013 OpenFOAM Foundation \\ / A nd | Copyright (C) 2012-2014 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -24,193 +24,553 @@ License
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#include "meshToMesh.H" #include "meshToMesh.H"
#include "processorFvPatch.H" #include "Time.H"
#include "demandDrivenData.H" #include "globalIndex.H"
#include "meshToMeshMethod.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam namespace Foam
{ {
defineTypeNameAndDebug(meshToMesh, 0); defineTypeNameAndDebug(meshToMesh, 0);
template<>
const char* Foam::NamedEnum
<
Foam::meshToMesh::interpolationMethod,
3
>::names[] =
{
"direct",
"mapNearest",
"cellVolumeWeight"
};
const NamedEnum<meshToMesh::interpolationMethod, 3>
meshToMesh::interpolationMethodNames_;
} }
const Foam::scalar Foam::meshToMesh::directHitTol = 1e-5;
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
Foam::labelList Foam::meshToMesh::maskCells
(
const polyMesh& src,
const polyMesh& tgt
) const
{
boundBox intersectBb
(
max(src.bounds().min(), tgt.bounds().min()),
min(src.bounds().max(), tgt.bounds().max())
);
intersectBb.inflate(0.01);
const cellList& srcCells = src.cells();
const faceList& srcFaces = src.faces();
const pointField& srcPts = src.points();
DynamicList<label> cells(src.size());
forAll(srcCells, srcI)
{
boundBox cellBb(srcCells[srcI].points(srcFaces, srcPts), false);
if (intersectBb.overlaps(cellBb))
{
cells.append(srcI);
}
}
if (debug)
{
Pout<< "participating source mesh cells: " << cells.size() << endl;
}
return cells;
}
void Foam::meshToMesh::normaliseWeights
(
const word& descriptor,
const labelListList& addr,
scalarListList& wght
) const
{
const label nCell = returnReduce(wght.size(), sumOp<label>());
if (nCell > 0)
{
forAll(wght, cellI)
{
scalarList& w = wght[cellI];
scalar s = sum(w);
forAll(w, i)
{
// note: normalise by s instead of cell volume since
// 1-to-1 methods duplicate contributions in parallel
w[i] /= s;
}
}
}
}
void Foam::meshToMesh::calcAddressing
(
const polyMesh& src,
const polyMesh& tgt
)
{
autoPtr<meshToMeshMethod> methodPtr
(
meshToMeshMethod::New
(
interpolationMethodNames_[method_],
src,
tgt
)
);
methodPtr->calculate
(
srcToTgtCellAddr_,
srcToTgtCellWght_,
tgtToSrcCellAddr_,
tgtToSrcCellWght_
);
V_ = methodPtr->V();
if (debug)
{
methodPtr->writeConnectivity(src, tgt, srcToTgtCellAddr_);
}
}
void Foam::meshToMesh::calculate()
{
Info<< "Creating mesh-to-mesh addressing for " << srcRegion_.name()
<< " and " << tgtRegion_.name() << " regions using "
<< interpolationMethodNames_[method_] << endl;
singleMeshProc_ = calcDistribution(srcRegion_, tgtRegion_);
if (singleMeshProc_ == -1)
{
// create global indexing for src and tgt meshes
globalIndex globalSrcCells(srcRegion_.nCells());
globalIndex globalTgtCells(tgtRegion_.nCells());
// Create processor map of overlapping cells. This map gets
// (possibly remote) cells from the tgt mesh such that they (together)
// cover all of the src mesh
autoPtr<mapDistribute> mapPtr = calcProcMap(srcRegion_, tgtRegion_);
const mapDistribute& map = mapPtr();
pointField newTgtPoints;
faceList newTgtFaces;
labelList newTgtFaceOwners;
labelList newTgtFaceNeighbours;
labelList newTgtCellIDs;
distributeAndMergeCells
(
map,
tgtRegion_,
globalTgtCells,
newTgtPoints,
newTgtFaces,
newTgtFaceOwners,
newTgtFaceNeighbours,
newTgtCellIDs
);
// create a new target mesh
polyMesh newTgt
(
IOobject
(
"newTgt." + Foam::name(Pstream::myProcNo()),
tgtRegion_.time().timeName(),
tgtRegion_.time(),
IOobject::NO_READ
),
xferMove(newTgtPoints),
xferMove(newTgtFaces),
xferMove(newTgtFaceOwners),
xferMove(newTgtFaceNeighbours),
false // no parallel comms
);
// create some dummy patch info
List<polyPatch*> patches(1);
patches[0] = new polyPatch
(
"defaultFaces",
newTgt.nFaces() - newTgt.nInternalFaces(),
newTgt.nInternalFaces(),
0,
newTgt.boundaryMesh(),
word::null
);
newTgt.addPatches(patches);
// force calculation of tet-base points used for point-in-cell
(void)newTgt.tetBasePtIs();
// force construction of cell tree
// (void)newTgt.cellTree();
if (debug)
{
Pout<< "Created newTgt mesh:" << nl
<< " old cells = " << tgtRegion_.nCells()
<< ", new cells = " << newTgt.nCells() << nl
<< " old faces = " << tgtRegion_.nFaces()
<< ", new faces = " << newTgt.nFaces() << endl;
if (debug > 1)
{
Pout<< "Writing newTgt mesh: " << newTgt.name() << endl;
newTgt.write();
}
}
calcAddressing(srcRegion_, newTgt);
// per source cell the target cell address in newTgt mesh
forAll(srcToTgtCellAddr_, i)
{
labelList& addressing = srcToTgtCellAddr_[i];
forAll(addressing, addrI)
{
addressing[addrI] = newTgtCellIDs[addressing[addrI]];
}
}
// convert target addresses in newTgtMesh into global cell numbering
forAll(tgtToSrcCellAddr_, i)
{
labelList& addressing = tgtToSrcCellAddr_[i];
forAll(addressing, addrI)
{
addressing[addrI] = globalSrcCells.toGlobal(addressing[addrI]);
}
}
// set up as a reverse distribute
mapDistribute::distribute
(
Pstream::nonBlocking,
List<labelPair>(),
tgtRegion_.nCells(),
map.constructMap(),
map.subMap(),
tgtToSrcCellAddr_,
ListPlusEqOp<label>(),
labelList()
);
// set up as a reverse distribute
mapDistribute::distribute
(
Pstream::nonBlocking,
List<labelPair>(),
tgtRegion_.nCells(),
map.constructMap(),
map.subMap(),
tgtToSrcCellWght_,
ListPlusEqOp<scalar>(),
scalarList()
);
// weights normalisation
normaliseWeights
(
"source",
srcToTgtCellAddr_,
srcToTgtCellWght_
);
normaliseWeights
(
"target",
tgtToSrcCellAddr_,
tgtToSrcCellWght_
);
// cache maps and reset addresses
List<Map<label> > cMap;
srcMapPtr_.reset
(
new mapDistribute(globalSrcCells, tgtToSrcCellAddr_, cMap)
);
tgtMapPtr_.reset
(
new mapDistribute(globalTgtCells, srcToTgtCellAddr_, cMap)
);
// collect volume intersection contributions
reduce(V_, sumOp<scalar>());
}
else
{
calcAddressing(srcRegion_, tgtRegion_);
normaliseWeights
(
"source",
srcToTgtCellAddr_,
srcToTgtCellWght_
);
normaliseWeights
(
"target",
tgtToSrcCellAddr_,
tgtToSrcCellWght_
);
}
Info<< " Overlap volume: " << V_ << endl;
}
Foam::AMIPatchToPatchInterpolation::interpolationMethod
Foam::meshToMesh::interpolationMethodAMI
(
const interpolationMethod method
) const
{
switch (method_)
{
case imDirect:
{
return AMIPatchToPatchInterpolation::imDirect;
break;
}
case imMapNearest:
{
return AMIPatchToPatchInterpolation::imMapNearest;
break;
}
case imCellVolumeWeight:
{
return AMIPatchToPatchInterpolation::imFaceAreaWeight;
break;
}
default:
{
FatalErrorIn
(
"Foam::AMIPatchToPatchInterpolation::interpolationMethod"
"Foam::meshToMesh::interpolationMethodAMI"
"("
"const interpolationMethod method"
") const"
)
<< "Unhandled enumeration " << method_
<< abort(FatalError);
}
}
return AMIPatchToPatchInterpolation::imDirect;
}
const Foam::PtrList<Foam::AMIPatchToPatchInterpolation>&
Foam::meshToMesh::patchAMIs() const
{
if (patchAMIs_.empty())
{
const word amiMethod =
AMIPatchToPatchInterpolation::interpolationMethodToWord
(
interpolationMethodAMI(method_)
);
patchAMIs_.setSize(srcPatchID_.size());
forAll(srcPatchID_, i)
{
label srcPatchI = srcPatchID_[i];
label tgtPatchI = tgtPatchID_[i];
const polyPatch& srcPP = srcRegion_.boundaryMesh()[srcPatchI];
const polyPatch& tgtPP = tgtRegion_.boundaryMesh()[tgtPatchI];
Info<< "Creating AMI between source patch " << srcPP.name()
<< " and target patch " << tgtPP.name()
<< " using " << amiMethod
<< endl;
Info<< incrIndent;
patchAMIs_.set
(
i,
new AMIPatchToPatchInterpolation
(
srcPP,
tgtPP,
faceAreaIntersect::tmMesh,
interpolationMethodAMI(method_),
true // flip target patch since patch normals are aligned
)
);
Info<< decrIndent;
}
}
return patchAMIs_;
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::meshToMesh::meshToMesh Foam::meshToMesh::meshToMesh
( (
const fvMesh& meshFrom, const polyMesh& src,
const fvMesh& meshTo, const polyMesh& tgt,
const HashTable<word>& patchMap, const interpolationMethod& method,
const wordList& cuttingPatchNames bool interpAllPatches
) )
: :
fromMesh_(meshFrom), srcRegion_(src),
toMesh_(meshTo), tgtRegion_(tgt),
patchMap_(patchMap), srcPatchID_(),
cellAddressing_(toMesh_.nCells()), tgtPatchID_(),
boundaryAddressing_(toMesh_.boundaryMesh().size()), patchAMIs_(),
inverseDistanceWeightsPtr_(NULL), cuttingPatches_(),
inverseVolumeWeightsPtr_(NULL), srcToTgtCellAddr_(),
cellToCellAddressingPtr_(NULL), tgtToSrcCellAddr_(),
V_(0.0) srcToTgtCellWght_(),
tgtToSrcCellWght_(),
method_(method),
V_(0.0),
singleMeshProc_(-1),
srcMapPtr_(NULL),
tgtMapPtr_(NULL)
{ {
forAll(fromMesh_.boundaryMesh(), patchi) if (interpAllPatches)
{ {
fromMeshPatches_.insert const polyBoundaryMesh& srcBM = src.boundaryMesh();
( const polyBoundaryMesh& tgtBM = tgt.boundaryMesh();
fromMesh_.boundaryMesh()[patchi].name(),
patchi
);
}
forAll(toMesh_.boundaryMesh(), patchi) DynamicList<label> srcPatchID(src.boundaryMesh().size());
{ DynamicList<label> tgtPatchID(tgt.boundaryMesh().size());
toMeshPatches_.insert forAll(srcBM, patchI)
(
toMesh_.boundaryMesh()[patchi].name(),
patchi
);
}
forAll(cuttingPatchNames, i)
{
if (toMeshPatches_.found(cuttingPatchNames[i]))
{ {
cuttingPatches_.insert const polyPatch& pp = srcBM[patchI];
( if (!polyPatch::constraintType(pp.type()))
cuttingPatchNames[i], {
toMeshPatches_.find(cuttingPatchNames[i])() srcPatchID.append(pp.index());
);
} label tgtPatchI = tgt.boundaryMesh().findPatchID(pp.name());
else
{ if (tgtPatchI != -1)
WarningIn {
( tgtPatchID.append(tgtPatchI);
"meshToMesh::meshToMesh" }
"(const fvMesh& meshFrom, const fvMesh& meshTo," else
"const HashTable<word>& patchMap," {
"const wordList& cuttingPatchNames)" FatalErrorIn
) << "Cannot find cutting-patch " << cuttingPatchNames[i] (
<< " in destination mesh" << endl; "Foam::meshToMesh::meshToMesh"
"("
"const polyMesh&, "
"const polyMesh&, "
"const interpolationMethod&, "
"bool"
")"
) << "Source patch " << pp.name()
<< " not found in target mesh. "
<< "Available target patches are " << tgtBM.names()
<< exit(FatalError);
}
}
} }
srcPatchID_.transfer(srcPatchID);
tgtPatchID_.transfer(tgtPatchID);
} }
forAll(toMesh_.boundaryMesh(), patchi) // calculate volume addressing and weights
{ calculate();
// Add the processor patches in the toMesh to the cuttingPatches list
if (isA<processorPolyPatch>(toMesh_.boundaryMesh()[patchi]))
{
cuttingPatches_.insert
(
toMesh_.boundaryMesh()[patchi].name(),
patchi
);
}
}
calcAddressing(); // calculate patch addressing and weights
(void)patchAMIs();
} }
Foam::meshToMesh::meshToMesh Foam::meshToMesh::meshToMesh
( (
const fvMesh& meshFrom, const polyMesh& src,
const fvMesh& meshTo const polyMesh& tgt,
const interpolationMethod& method,
const HashTable<word>& patchMap,
const wordList& cuttingPatches
) )
: :
fromMesh_(meshFrom), srcRegion_(src),
toMesh_(meshTo), tgtRegion_(tgt),
cellAddressing_(toMesh_.nCells()), srcPatchID_(),
boundaryAddressing_(toMesh_.boundaryMesh().size()), tgtPatchID_(),
inverseDistanceWeightsPtr_(NULL), patchAMIs_(),
inverseVolumeWeightsPtr_(NULL), cuttingPatches_(),
cellToCellAddressingPtr_(NULL), srcToTgtCellAddr_(),
V_(0.0) tgtToSrcCellAddr_(),
srcToTgtCellWght_(),
tgtToSrcCellWght_(),
method_(method),
V_(0.0),
singleMeshProc_(-1),
srcMapPtr_(NULL),
tgtMapPtr_(NULL)
{ {
// check whether both meshes have got the same number srcPatchID_.setSize(patchMap.size());
// of boundary patches tgtPatchID_.setSize(patchMap.size());
if (fromMesh_.boundary().size() != toMesh_.boundary().size())
label i = 0;
forAllConstIter(HashTable<word>, patchMap, iter)
{ {
FatalErrorIn const word& tgtPatchName = iter.key();
( const word& srcPatchName = iter();
"meshToMesh::meshToMesh"
"(const fvMesh& meshFrom, const fvMesh& meshTo)" const polyPatch& srcPatch = srcRegion_.boundaryMesh()[srcPatchName];
) << "Incompatible meshes: different number of patches, " const polyPatch& tgtPatch = tgtRegion_.boundaryMesh()[tgtPatchName];
<< "fromMesh = " << fromMesh_.boundary().size()
<< ", toMesh = " << toMesh_.boundary().size() srcPatchID_[i] = srcPatch.index();
<< exit(FatalError); tgtPatchID_[i] = tgtPatch.index();
i++;
} }
forAll(fromMesh_.boundaryMesh(), patchi) // calculate volume addressing and weights
calculate();
// calculate patch addressing and weights
(void)patchAMIs();
// set IDs of cutting patches on target mesh
cuttingPatches_.setSize(cuttingPatches.size());
forAll(cuttingPatches_, i)
{ {
if const word& patchName = cuttingPatches[i];
( cuttingPatches_[i] = tgt.boundaryMesh().findPatchID(patchName);
fromMesh_.boundaryMesh()[patchi].name()
!= toMesh_.boundaryMesh()[patchi].name()
)
{
FatalErrorIn
(
"meshToMesh::meshToMesh"
"(const fvMesh& meshFrom, const fvMesh& meshTo)"
) << "Incompatible meshes: different patch names for patch "
<< patchi
<< ", fromMesh = " << fromMesh_.boundary()[patchi].name()
<< ", toMesh = " << toMesh_.boundary()[patchi].name()
<< exit(FatalError);
}
if
(
fromMesh_.boundaryMesh()[patchi].type()
!= toMesh_.boundaryMesh()[patchi].type()
)
{
FatalErrorIn
(
"meshToMesh::meshToMesh"
"(const fvMesh& meshFrom, const fvMesh& meshTo)"
) << "Incompatible meshes: different patch types for patch "
<< patchi
<< ", fromMesh = " << fromMesh_.boundary()[patchi].type()
<< ", toMesh = " << toMesh_.boundary()[patchi].type()
<< exit(FatalError);
}
fromMeshPatches_.insert
(
fromMesh_.boundaryMesh()[patchi].name(),
patchi
);
toMeshPatches_.insert
(
toMesh_.boundaryMesh()[patchi].name(),
patchi
);
patchMap_.insert
(
toMesh_.boundaryMesh()[patchi].name(),
fromMesh_.boundaryMesh()[patchi].name()
);
} }
calcAddressing();
} }
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::meshToMesh::~meshToMesh() Foam::meshToMesh::~meshToMesh()
{ {}
deleteDemandDrivenData(inverseDistanceWeightsPtr_);
deleteDemandDrivenData(inverseVolumeWeightsPtr_);
deleteDemandDrivenData(cellToCellAddressingPtr_);
}
// ************************************************************************* // // ************************************************************************* //

View File

@ -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-2013 OpenFOAM Foundation \\ / A nd | Copyright (C) 2012-2014 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -25,286 +25,456 @@ Class
Foam::meshToMesh Foam::meshToMesh
Description Description
mesh to mesh interpolation class. Class to calculate the cell-addressing between two overlapping meshes
Note Mapping is performed using a run-time selectable interpolation mothod
This class is due to be deprecated in favour of meshToMeshNew
SeeAlso
meshToMeshMethod
SourceFiles SourceFiles
meshToMesh.C meshToMesh.C
calculateMeshToMeshAddressing.C meshToMeshParallelOps.C
calculateMeshToMeshWeights.C meshToMeshTemplates.C
meshToMeshInterpolate.C
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#ifndef meshtoMesh_H #ifndef meshToMesh_H
#define meshtoMesh_H #define meshToMesh_H
#include "fvMesh.H" #include "polyMesh.H"
#include "HashTable.H" #include "boundBox.H"
#include "fvPatchMapper.H" #include "mapDistribute.H"
#include "scalarList.H" #include "volFieldsFwd.H"
#include "className.H" #include "NamedEnum.H"
#include "AMIPatchToPatchInterpolation.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam namespace Foam
{ {
template<class Type>
class indexedOctree;
class treeDataCell;
/*---------------------------------------------------------------------------*\ /*---------------------------------------------------------------------------*\
Class meshToMesh Declaration Class meshToMesh Declaration
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
class meshToMesh class meshToMesh
{ {
public:
// Public data types
//- Enumeration specifying interpolation method
enum interpolationMethod
{
imDirect,
imMapNearest,
imCellVolumeWeight
};
static const NamedEnum<interpolationMethod, 3>
interpolationMethodNames_;
private:
// Private data // Private data
// mesh references //- Reference to the source mesh
const polyMesh& srcRegion_;
const fvMesh& fromMesh_; //- Reference to the target mesh
const fvMesh& toMesh_; const polyMesh& tgtRegion_;
//- fromMesh patch labels //- List of target patch IDs per source patch (local index)
HashTable<label> fromMeshPatches_; List<label> srcPatchID_;
//- toMesh patch labels //- List of source patch IDs per target patch (local index)
HashTable<label> toMeshPatches_; List<label> tgtPatchID_;
//- Patch map //- List of AMIs between source and target patches
HashTable<word> patchMap_; mutable PtrList<AMIPatchToPatchInterpolation> patchAMIs_;
//- toMesh patch labels which cut the from-mesh //- Cutting patches whose values are set using a zero-gradient condition
HashTable<label> cuttingPatches_; List<label> cuttingPatches_;
//- Cell addressing //- Source to target cell addressing
labelList cellAddressing_; labelListList srcToTgtCellAddr_;
//- Boundary addressing //- Target to source cell addressing
labelListList boundaryAddressing_; labelListList tgtToSrcCellAddr_;
//- Inverse-distance interpolation weights //- Source to target cell interplation weights
mutable scalarListList* inverseDistanceWeightsPtr_; scalarListList srcToTgtCellWght_;
//- Inverse-volume interpolation weights //- Target to source cell interpolation weights
mutable scalarListList* inverseVolumeWeightsPtr_; scalarListList tgtToSrcCellWght_;
//- Cell to cell overlap addressing //- Interpolation method
mutable labelListList* cellToCellAddressingPtr_; interpolationMethod method_;
//- Overlap volume //- Cell total volume in overlap region [m3]
mutable scalar V_; scalar V_;
//- Index of processor that holds all of both sides. -1 in all other
// cases
label singleMeshProc_;
//- Source map pointer - parallel running only
autoPtr<mapDistribute> srcMapPtr_;
//- Target map pointer - parallel running only
autoPtr<mapDistribute> tgtMapPtr_;
// Private Member Functions // Private Member Functions
void calcAddressing(); //- Helper function to add a constant offset to a list
template<class Type>
void add(UList<Type>& fld, const label offset) const;
void cellAddresses //- Return src cell IDs for the overlap region
labelList maskCells(const polyMesh& src, const polyMesh& tgt) const;
//- Normalise the interpolation weights
void normaliseWeights
( (
labelList& cells, const word& descriptor,
const pointField& points, const labelListList& addr,
const fvMesh& fromMesh, scalarListList& wght
const List<bool>& boundaryCell,
const indexedOctree<treeDataCell>& oc
) const; ) const;
void calculateInverseDistanceWeights() const; //- Calculate the addressing between overalping regions of src and tgt
// meshes
void calcAddressing(const polyMesh& src, const polyMesh& tgt);
void calculateInverseVolumeWeights() const; //- Calculate - main driver function
void calculate();
void calculateCellToCellAddressing() const; //- Conversion between mesh and patch interpolation methods
AMIPatchToPatchInterpolation::interpolationMethod
interpolationMethodAMI
(
const interpolationMethod method
) const;
const scalarListList& inverseDistanceWeights() const; //- Return the list of AMIs between source and target patches
const PtrList<AMIPatchToPatchInterpolation>& patchAMIs() const;
const scalarListList& inverseVolumeWeights() const;
const labelListList& cellToCellAddressing() const;
// Private static data members // Parallel operations
//- Direct hit tolerance //- Determine whether the meshes are split across multiple pocessors
static const scalar directHitTol; label calcDistribution
(
const polyMesh& src,
const polyMesh& tgt
) const;
//- Determine which processor bounding-boxes overlap
label calcOverlappingProcs
(
const List<boundBox>& procBb,
const boundBox& bb,
boolList& overlaps
) const;
//- Calculate the mapping between processors
autoPtr<mapDistribute> calcProcMap
(
const polyMesh& src,
const polyMesh& tgt
) const;
//- Distribute mesh info from 'my' processor to others
void distributeCells
(
const mapDistribute& map,
const polyMesh& tgtMesh,
const globalIndex& globalI,
List<pointField>& points,
List<label>& nInternalFaces,
List<faceList>& faces,
List<labelList>& faceOwner,
List<labelList>& faceNeighbour,
List<labelList>& cellIDs,
List<labelList>& nbrProcIDs,
List<labelList>& procLocalFaceIDs
) const;
//- Collect pieces of tgt mesh from other procssors and restructure
void distributeAndMergeCells
(
const mapDistribute& map,
const polyMesh& tgt,
const globalIndex& globalI,
pointField& tgtPoints,
faceList& tgtFaces,
labelList& tgtFaceOwners,
labelList& tgtFaceNeighbours,
labelList& tgtCellIDs
) const;
//- Disallow default bitwise copy construct
meshToMesh(const meshToMesh&);
//- Disallow default bitwise assignment
void operator=(const meshToMesh&);
public: public:
// Declare name of the class and its debug switch //- Run-time type information
ClassName("meshToMesh"); TypeName("meshToMesh");
//- Enumeration specifying required accuracy //- Construct from source and target meshes
enum order meshToMesh
{ (
MAP, const polyMesh& src,
INTERPOLATE, const polyMesh& tgt,
CELL_POINT_INTERPOLATE, const interpolationMethod& method,
CELL_VOLUME_WEIGHT const bool interpAllPatches = true
}; );
// Constructors //- Construct from source and target meshes
meshToMesh
//- Construct from the two meshes, the patch name map for the patches (
// to be interpolated and the names of the toMesh-patches which const polyMesh& src,
// cut the fromMesh const polyMesh& tgt,
meshToMesh const interpolationMethod& method,
( const HashTable<word>& patchMap,
const fvMesh& fromMesh, const wordList& cuttingPatches
const fvMesh& toMesh, );
const HashTable<word>& patchMap,
const wordList& cuttingPatchNames
);
//- Construct from the two meshes assuming there is an exact mapping
// between the patches
meshToMesh
(
const fvMesh& fromMesh,
const fvMesh& toMesh
);
//- Destructor //- Destructor
~meshToMesh(); virtual ~meshToMesh();
// Member Functions // Member Functions
// Access // Access
const fvMesh& fromMesh() const //- Return const access to the source mesh
{ inline const polyMesh& srcRegion() const;
return fromMesh_;
}
const fvMesh& toMesh() const //- Return const access to the target mesh
{ inline const polyMesh& tgtRegion() const;
return toMesh_;
}
//- From toMesh cells to fromMesh cells //- Return const access to the source to target cell addressing
const labelList& cellAddressing() const inline const labelListList& srcToTgtCellAddr() const;
{
return cellAddressing_;
}
//- Overlap volume //- Return const access to the target to source cell addressing
scalar V() const inline const labelListList& tgtToSrcCellAddr() const;
{
return V_; //- Return const access to the source to target cell weights
} inline const scalarListList& srcToTgtCellWght() const;
//- Return const access to the target to source cell weights
inline const scalarListList& tgtToSrcCellWght() const;
//- Return const access to the overlap volume
inline scalar V() const;
// Interpolation // Evaluation
//- Map field // Source-to-target field mapping
template<class Type, class CombineOp>
void mapField
(
Field<Type>&,
const Field<Type>&,
const labelList& adr,
const CombineOp& cop
) const;
//- Interpolate field using inverse-distance weights //- Map field from src to tgt mesh with defined operation
template<class Type, class CombineOp> // Values passed in via 'result' are used to initialise the
void interpolateField // return value
( template<class Type, class CombineOp>
Field<Type>&, void mapSrcToTgt
const GeometricField<Type, fvPatchField, volMesh>&, (
const labelList& adr, const UList<Type>& srcFld,
const scalarListList& weights, const CombineOp& cop,
const CombineOp& cop List<Type>& result
) const; ) const;
//- Interpolate field using inverse-volume weights //- Return the src field mapped to the tgt mesh with a defined
template<class Type, class CombineOp> // operation. Initial values of the result are set to zero
void interpolateField template<class Type, class CombineOp>
( tmp<Field<Type> > mapSrcToTgt
Field<Type>&, (
const GeometricField<Type, fvPatchField, volMesh>&, const Field<Type>& srcFld,
const labelListList& adr, const CombineOp& cop
const scalarListList& weights, ) const;
const CombineOp& cop
) const; //- Convenience function to map a tmp field to the tgt mesh
// with a defined operation
template<class Type, class CombineOp>
tmp<Field<Type> > mapSrcToTgt
(
const tmp<Field<Type> >& tsrcFld,
const CombineOp& cop
) const;
//- Convenience function to map a field to the tgt mesh with a
// default operation (plusEqOp)
template<class Type>
tmp<Field<Type> > mapSrcToTgt
(
const Field<Type>& srcFld
) const;
//- Convenience function to map a tmp field to the tgt mesh
// with a default operation (plusEqOp)
template<class Type>
tmp<Field<Type> > mapSrcToTgt
(
const tmp<Field<Type> >& tsrcFld
) const;
//- Interpolate field using cell-point interpolation // Target-to-source field mapping
template<class Type, class CombineOp>
void interpolateField //- Map field from tgt to src mesh with defined operation
( // Values passed in via 'result' are used to initialise the
Field<Type>&, // return value
const GeometricField<Type, fvPatchField, volMesh>&, template<class Type, class CombineOp>
const labelList& adr, void mapTgtToSrc
const vectorField& centres, (
const CombineOp& cop const UList<Type>& tgtFld,
)const; const CombineOp& cop,
List<Type>& result
) const;
//- Return the tgt field mapped to the src mesh with a defined
// operation. Initial values of the result are set to zero
template<class Type, class CombineOp>
tmp<Field<Type> > mapTgtToSrc
(
const Field<Type>& tgtFld,
const CombineOp& cop
) const;
//- Convenience function to map a tmp field to the src mesh
// with a defined operation
template<class Type, class CombineOp>
tmp<Field<Type> > mapTgtToSrc
(
const tmp<Field<Type> >& ttgtFld,
const CombineOp& cop
) const;
//- Convenience function to map a field to the src mesh with a
// default operation (plusEqOp)
template<class Type>
tmp<Field<Type> > mapTgtToSrc
(
const Field<Type>& tgtFld
) const;
//- Convenience function to map a tmp field to the src mesh
// with a default operation (plusEqOp)
template<class Type>
tmp<Field<Type> > mapTgtToSrc
(
const tmp<Field<Type> >& ttgtFld
) const;
//- Interpolate internal volume field // Source-to-target volume field mapping
template<class Type, class CombineOp>
void interpolateInternalField
(
Field<Type>&,
const GeometricField<Type, fvPatchField, volMesh>&,
order=INTERPOLATE,
const CombineOp& cop = eqOp<Type>()
) const;
template<class Type, class CombineOp> //- Interpolate a field with a defined operation. Values
void interpolateInternalField // passed in via 'result' are used to initialise the return
( // value
Field<Type>&, template<class Type, class CombineOp>
const tmp<GeometricField<Type, fvPatchField, volMesh> >&, void mapSrcToTgt
order=INTERPOLATE, (
const CombineOp& cop = eqOp<Type>() const GeometricField<Type, fvPatchField, volMesh>& field,
) const; const CombineOp& cop,
GeometricField<Type, fvPatchField, volMesh>& result
) const;
//- Interpolate a field with a defined operation. The initial
// values of the result are set to zero
template<class Type, class CombineOp>
tmp<GeometricField<Type, fvPatchField, volMesh> > mapSrcToTgt
(
const GeometricField<Type, fvPatchField, volMesh>& field,
const CombineOp& cop
) const;
//- Interpolate a tmp field with a defined operation. The
// initial values of the result are set to zero
template<class Type, class CombineOp>
tmp<GeometricField<Type, fvPatchField, volMesh> > mapSrcToTgt
(
const tmp<GeometricField<Type, fvPatchField, volMesh> >&
tfield,
const CombineOp& cop
) const;
//- Convenience function to map a field with a default
// operation (plusEqOp)
template<class Type>
tmp<GeometricField<Type, fvPatchField, volMesh> > mapSrcToTgt
(
const GeometricField<Type, fvPatchField, volMesh>& field
) const;
//- Convenience function to map a tmp field with a default
// operation (plusEqOp)
template<class Type>
tmp<GeometricField<Type, fvPatchField, volMesh> > mapSrcToTgt
(
const tmp<GeometricField<Type, fvPatchField, volMesh> >&
tfield
) const;
//- Interpolate volume field // Target-to-source volume field mapping
template<class Type, class CombineOp>
void interpolate
(
GeometricField<Type, fvPatchField, volMesh>&,
const GeometricField<Type, fvPatchField, volMesh>&,
order=INTERPOLATE,
const CombineOp& cop = eqOp<Type>()
) const;
template<class Type, class CombineOp> //- Interpolate a field with a defined operation. Values
void interpolate // passed in via 'result' are used to initialise the return
( // value
GeometricField<Type, fvPatchField, volMesh>&, template<class Type, class CombineOp>
const tmp<GeometricField<Type, fvPatchField, volMesh> >&, void mapTgtToSrc
order=INTERPOLATE, (
const CombineOp& cop = eqOp<Type>() const GeometricField<Type, fvPatchField, volMesh>& field,
) const; const CombineOp& cop,
GeometricField<Type, fvPatchField, volMesh>& result
) const;
//- Interpolate a field with a defined operation. The initial
// values of the result are set to zero
template<class Type, class CombineOp>
tmp<GeometricField<Type, fvPatchField, volMesh> > mapTgtToSrc
(
const GeometricField<Type, fvPatchField, volMesh>& field,
const CombineOp& cop
) const;
//- Interpolate volume field //- Interpolate a tmp field with a defined operation. The
template<class Type, class CombineOp> // initial values of the result are set to zero
tmp<GeometricField<Type, fvPatchField, volMesh> > interpolate template<class Type, class CombineOp>
( tmp<GeometricField<Type, fvPatchField, volMesh> > mapTgtToSrc
const GeometricField<Type, fvPatchField, volMesh>&, (
order=INTERPOLATE, const tmp<GeometricField<Type, fvPatchField, volMesh> >&
const CombineOp& cop = eqOp<Type>() tfield,
) const; const CombineOp& cop
) const;
template<class Type, class CombineOp> //- Convenience function to map a field with a default
tmp<GeometricField<Type, fvPatchField, volMesh> > interpolate // operation (plusEqOp)
( template<class Type>
const tmp<GeometricField<Type, fvPatchField, volMesh> >&, tmp<GeometricField<Type, fvPatchField, volMesh> > mapTgtToSrc
order=INTERPOLATE, (
const CombineOp& cop = eqOp<Type>() const GeometricField<Type, fvPatchField, volMesh>& field
) const; ) const;
//- Convenience function to map a tmp field with a default
// operation (plusEqOp)
template<class Type>
tmp<GeometricField<Type, fvPatchField, volMesh> > mapTgtToSrc
(
const tmp<GeometricField<Type, fvPatchField, volMesh> >&
tfield
) const;
}; };
@ -314,8 +484,12 @@ public:
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#include "meshToMeshI.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository #ifdef NoRepository
# include "meshToMeshInterpolate.C" #include "meshToMeshTemplates.C"
#endif #endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View File

@ -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) 2012-2013 OpenFOAM Foundation \\ / A nd | Copyright (C) 2012-2014 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -23,51 +23,51 @@ License
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#include "meshToMeshNew.H" #include "meshToMesh.H"
// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
inline const Foam::polyMesh& Foam::meshToMeshNew::srcRegion() const inline const Foam::polyMesh& Foam::meshToMesh::srcRegion() const
{ {
return srcRegion_; return srcRegion_;
} }
inline const Foam::polyMesh& Foam::meshToMeshNew::tgtRegion() const inline const Foam::polyMesh& Foam::meshToMesh::tgtRegion() const
{ {
return tgtRegion_; return tgtRegion_;
} }
inline const Foam::labelListList& inline const Foam::labelListList&
Foam::meshToMeshNew::srcToTgtCellAddr() const Foam::meshToMesh::srcToTgtCellAddr() const
{ {
return srcToTgtCellAddr_; return srcToTgtCellAddr_;
} }
inline const Foam::labelListList& inline const Foam::labelListList&
Foam::meshToMeshNew::tgtToSrcCellAddr() const Foam::meshToMesh::tgtToSrcCellAddr() const
{ {
return tgtToSrcCellAddr_; return tgtToSrcCellAddr_;
} }
inline const Foam::scalarListList& inline const Foam::scalarListList&
Foam::meshToMeshNew::srcToTgtCellWght() const Foam::meshToMesh::srcToTgtCellWght() const
{ {
return srcToTgtCellWght_; return srcToTgtCellWght_;
} }
inline const Foam::scalarListList& inline const Foam::scalarListList&
Foam::meshToMeshNew::tgtToSrcCellWght() const Foam::meshToMesh::tgtToSrcCellWght() const
{ {
return tgtToSrcCellWght_; return tgtToSrcCellWght_;
} }
inline Foam::scalar Foam::meshToMeshNew::V() const inline Foam::scalar Foam::meshToMesh::V() const
{ {
return V_; return V_;
} }

View File

@ -1,499 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2013 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 "meshToMesh.H"
#include "volFields.H"
#include "interpolationCellPoint.H"
#include "SubField.H"
#include "mixedFvPatchField.H"
#include "directFvPatchFieldMapper.H"
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class Type, class CombineOp>
void Foam::meshToMesh::mapField
(
Field<Type>& toF,
const Field<Type>& fromVf,
const labelList& adr,
const CombineOp& cop
) const
{
// Direct mapping of nearest-cell values
forAll(toF, celli)
{
if (adr[celli] != -1)
{
cop(toF[celli], fromVf[adr[celli]]);
}
}
//toF.map(fromVf, adr);
}
template<class Type, class CombineOp>
void Foam::meshToMesh::interpolateField
(
Field<Type>& toF,
const GeometricField<Type, fvPatchField, volMesh>& fromVf,
const labelListList& adr,
const scalarListList& weights,
const CombineOp& cop
) const
{
// Inverse volume weighted interpolation
forAll(toF, celli)
{
const labelList& overlapCells = adr[celli];
const scalarList& w = weights[celli];
Type f = pTraits<Type>::zero;
forAll(overlapCells, i)
{
label fromCelli = overlapCells[i];
f += fromVf[fromCelli]*w[i];
cop(toF[celli], f);
}
}
}
template<class Type, class CombineOp>
void Foam::meshToMesh::interpolateField
(
Field<Type>& toF,
const GeometricField<Type, fvPatchField, volMesh>& fromVf,
const labelList& adr,
const scalarListList& weights,
const CombineOp& cop
) const
{
// Inverse distance weighted interpolation
// get reference to cellCells
const labelListList& cc = fromMesh_.cellCells();
forAll(toF, celli)
{
if (adr[celli] != -1)
{
const labelList& neighbours = cc[adr[celli]];
const scalarList& w = weights[celli];
Type f = fromVf[adr[celli]]*w[0];
for (label ni = 1; ni < w.size(); ni++)
{
f += fromVf[neighbours[ni - 1]]*w[ni];
}
cop(toF[celli], f);
}
}
}
template<class Type, class CombineOp>
void Foam::meshToMesh::interpolateField
(
Field<Type>& toF,
const GeometricField<Type, fvPatchField, volMesh>& fromVf,
const labelList& adr,
const vectorField& centres,
const CombineOp& cop
) const
{
// Cell-Point interpolation
interpolationCellPoint<Type> interpolator(fromVf);
forAll(toF, celli)
{
if (adr[celli] != -1)
{
cop
(
toF[celli],
interpolator.interpolate
(
centres[celli],
adr[celli]
)
);
}
}
}
template<class Type, class CombineOp>
void Foam::meshToMesh::interpolateInternalField
(
Field<Type>& toF,
const GeometricField<Type, fvPatchField, volMesh>& fromVf,
meshToMesh::order ord,
const CombineOp& cop
) const
{
if (fromVf.mesh() != fromMesh_)
{
FatalErrorIn
(
"meshToMesh::interpolateInternalField(Field<Type>&, "
"const GeometricField<Type, fvPatchField, volMesh>&, "
"meshToMesh::order, const CombineOp&) const"
) << "the argument field does not correspond to the right mesh. "
<< "Field size: " << fromVf.size()
<< " mesh size: " << fromMesh_.nCells()
<< exit(FatalError);
}
if (toF.size() != toMesh_.nCells())
{
FatalErrorIn
(
"meshToMesh::interpolateInternalField(Field<Type>&, "
"const GeometricField<Type, fvPatchField, volMesh>&, "
"meshToMesh::order, const CombineOp&) const"
) << "the argument field does not correspond to the right mesh. "
<< "Field size: " << toF.size()
<< " mesh size: " << toMesh_.nCells()
<< exit(FatalError);
}
switch(ord)
{
case MAP:
mapField(toF, fromVf, cellAddressing_, cop);
break;
case INTERPOLATE:
{
interpolateField
(
toF,
fromVf,
cellAddressing_,
inverseDistanceWeights(),
cop
);
break;
}
case CELL_POINT_INTERPOLATE:
{
interpolateField
(
toF,
fromVf,
cellAddressing_,
toMesh_.cellCentres(),
cop
);
break;
}
case CELL_VOLUME_WEIGHT:
{
const labelListList& cellToCell = cellToCellAddressing();
const scalarListList& invVolWeights = inverseVolumeWeights();
interpolateField
(
toF,
fromVf,
cellToCell,
invVolWeights,
cop
);
break;
}
default:
FatalErrorIn
(
"meshToMesh::interpolateInternalField(Field<Type>&, "
"const GeometricField<Type, fvPatchField, volMesh>&, "
"meshToMesh::order, const CombineOp&) const"
) << "unknown interpolation scheme " << ord
<< exit(FatalError);
}
}
template<class Type, class CombineOp>
void Foam::meshToMesh::interpolateInternalField
(
Field<Type>& toF,
const tmp<GeometricField<Type, fvPatchField, volMesh> >& tfromVf,
meshToMesh::order ord,
const CombineOp& cop
) const
{
interpolateInternalField(toF, tfromVf(), ord, cop);
tfromVf.clear();
}
template<class Type, class CombineOp>
void Foam::meshToMesh::interpolate
(
GeometricField<Type, fvPatchField, volMesh>& toVf,
const GeometricField<Type, fvPatchField, volMesh>& fromVf,
meshToMesh::order ord,
const CombineOp& cop
) const
{
interpolateInternalField(toVf, fromVf, ord, cop);
forAll(toMesh_.boundaryMesh(), patchi)
{
const fvPatch& toPatch = toMesh_.boundary()[patchi];
if (cuttingPatches_.found(toPatch.name()))
{
switch(ord)
{
case MAP:
{
mapField
(
toVf.boundaryField()[patchi],
fromVf,
boundaryAddressing_[patchi],
cop
);
break;
}
case INTERPOLATE:
{
interpolateField
(
toVf.boundaryField()[patchi],
fromVf,
boundaryAddressing_[patchi],
toPatch.Cf(),
cop
);
break;
}
case CELL_POINT_INTERPOLATE:
{
interpolateField
(
toVf.boundaryField()[patchi],
fromVf,
boundaryAddressing_[patchi],
toPatch.Cf(),
cop
);
break;
}
case CELL_VOLUME_WEIGHT:
{
// Do nothing
break;
}
default:
FatalErrorIn
(
"meshToMesh::interpolate("
"GeometricField<Type, fvPatchField, volMesh>&, "
"const GeometricField<Type, fvPatchField, volMesh>&, "
"meshToMesh::order, const CombineOp&) const"
) << "unknown interpolation scheme " << ord
<< exit(FatalError);
}
if (isA<mixedFvPatchField<Type> >(toVf.boundaryField()[patchi]))
{
refCast<mixedFvPatchField<Type> >
(
toVf.boundaryField()[patchi]
).refValue() = toVf.boundaryField()[patchi];
}
}
else if
(
patchMap_.found(toPatch.name())
&& fromMeshPatches_.found(patchMap_.find(toPatch.name())())
)
{
/*
toVf.boundaryField()[patchi].map
(
fromVf.boundaryField()
[
fromMeshPatches_.find(patchMap_.find(toPatch.name())())()
],
boundaryAddressing_[patchi]
);
*/
mapField
(
toVf.boundaryField()[patchi],
fromVf.boundaryField()
[
fromMeshPatches_.find(patchMap_.find(toPatch.name())())()
],
boundaryAddressing_[patchi],
cop
);
}
}
}
template<class Type, class CombineOp>
void Foam::meshToMesh::interpolate
(
GeometricField<Type, fvPatchField, volMesh>& toVf,
const tmp<GeometricField<Type, fvPatchField, volMesh> >& tfromVf,
meshToMesh::order ord,
const CombineOp& cop
) const
{
interpolate(toVf, tfromVf(), ord, cop);
tfromVf.clear();
}
template<class Type, class CombineOp>
Foam::tmp< Foam::GeometricField<Type, Foam::fvPatchField, Foam::volMesh> >
Foam::meshToMesh::interpolate
(
const GeometricField<Type, fvPatchField, volMesh>& fromVf,
meshToMesh::order ord,
const CombineOp& cop
) const
{
// Create and map the internal-field values
Field<Type> internalField(toMesh_.nCells());
interpolateInternalField(internalField, fromVf, ord, cop);
// check whether both meshes have got the same number
// of boundary patches
if (fromMesh_.boundary().size() != toMesh_.boundary().size())
{
FatalErrorIn
(
"meshToMesh::interpolate"
"(const GeometricField<Type, fvPatchField, volMesh>&,"
"meshToMesh::order, const CombineOp&) const"
) << "Incompatible meshes: different number of boundaries, "
"only internal field may be interpolated"
<< exit(FatalError);
}
// 1. Create the complete field with dummy patch fields
PtrList<fvPatchField<Type> > patchFields
(
boundaryAddressing_.size()
);
forAll(boundaryAddressing_, patchI)
{
patchFields.set
(
patchI,
fvPatchField<Type>::New
(
calculatedFvPatchField<Type>::typeName,
toMesh_.boundary()[patchI],
DimensionedField<Type, volMesh>::null()
)
);
}
// Create the complete field from the pieces
tmp<GeometricField<Type, fvPatchField, volMesh> > ttoF
(
new GeometricField<Type, fvPatchField, volMesh>
(
IOobject
(
"interpolated(" + fromVf.name() + ')',
toMesh_.time().timeName(),
toMesh_,
IOobject::NO_READ,
IOobject::NO_WRITE
),
toMesh_,
fromVf.dimensions(),
internalField,
patchFields
)
);
GeometricField<Type, fvPatchField, volMesh>& toF = ttoF();
// 2. Change the fvPatchFields to the correct type using a mapper
// constructor (with reference to the now correct internal field)
typename GeometricField<Type, fvPatchField, volMesh>::
GeometricBoundaryField& bf = toF.boundaryField();
forAll(boundaryAddressing_, patchI)
{
bf.set
(
patchI,
fvPatchField<Type>::New
(
fromVf.boundaryField()[patchI],
toMesh_.boundary()[patchI],
toF.dimensionedInternalField(),
directFvPatchFieldMapper
(
boundaryAddressing_[patchI]
)
)
);
}
return ttoF;
}
template<class Type, class CombineOp>
Foam::tmp< Foam::GeometricField<Type, Foam::fvPatchField, Foam::volMesh> >
Foam::meshToMesh::interpolate
(
const tmp<GeometricField<Type, fvPatchField, volMesh> >& tfromVf,
meshToMesh::order ord,
const CombineOp& cop
) const
{
tmp<GeometricField<Type, fvPatchField, volMesh> > tint =
interpolate(tfromVf(), ord, cop);
tfromVf.clear();
return tint;
}
// ************************************************************************* //

View File

@ -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) 2012-2013 OpenFOAM Foundation \\ / A nd | Copyright (C) 2012-2014 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -23,7 +23,7 @@ License
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#include "meshToMeshNew.H" #include "meshToMesh.H"
#include "OFstream.H" #include "OFstream.H"
#include "Time.H" #include "Time.H"
#include "globalIndex.H" #include "globalIndex.H"
@ -33,7 +33,7 @@ License
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
Foam::label Foam::meshToMeshNew::calcDistribution Foam::label Foam::meshToMesh::calcDistribution
( (
const polyMesh& src, const polyMesh& src,
const polyMesh& tgt const polyMesh& tgt
@ -63,7 +63,7 @@ Foam::label Foam::meshToMeshNew::calcDistribution
procI = -1; procI = -1;
if (debug) if (debug)
{ {
Info<< "meshToMeshNew::calcDistribution: " Info<< "meshToMesh::calcDistribution: "
<< "Meshes split across multiple processors" << endl; << "Meshes split across multiple processors" << endl;
} }
} }
@ -72,7 +72,7 @@ Foam::label Foam::meshToMeshNew::calcDistribution
procI = findIndex(cellsPresentOnProc, 1); procI = findIndex(cellsPresentOnProc, 1);
if (debug) if (debug)
{ {
Info<< "meshToMeshNew::calcDistribution: " Info<< "meshToMesh::calcDistribution: "
<< "Meshes local to processor" << procI << endl; << "Meshes local to processor" << procI << endl;
} }
} }
@ -82,7 +82,7 @@ Foam::label Foam::meshToMeshNew::calcDistribution
} }
Foam::label Foam::meshToMeshNew::calcOverlappingProcs Foam::label Foam::meshToMesh::calcOverlappingProcs
( (
const List<boundBox>& procBb, const List<boundBox>& procBb,
const boundBox& bb, const boundBox& bb,
@ -108,7 +108,7 @@ Foam::label Foam::meshToMeshNew::calcOverlappingProcs
} }
Foam::autoPtr<Foam::mapDistribute> Foam::meshToMeshNew::calcProcMap Foam::autoPtr<Foam::mapDistribute> Foam::meshToMesh::calcProcMap
( (
const polyMesh& src, const polyMesh& src,
const polyMesh& tgt const polyMesh& tgt
@ -255,7 +255,7 @@ Foam::autoPtr<Foam::mapDistribute> Foam::meshToMeshNew::calcProcMap
} }
void Foam::meshToMeshNew::distributeCells void Foam::meshToMesh::distributeCells
( (
const mapDistribute& map, const mapDistribute& map,
const polyMesh& tgtMesh, const polyMesh& tgtMesh,
@ -495,7 +495,7 @@ void Foam::meshToMeshNew::distributeCells
} }
void Foam::meshToMeshNew::distributeAndMergeCells void Foam::meshToMesh::distributeAndMergeCells
( (
const mapDistribute& map, const mapDistribute& map,
const polyMesh& tgt, const polyMesh& tgt,
@ -791,7 +791,7 @@ void Foam::meshToMeshNew::distributeAndMergeCells
{ {
FatalErrorIn FatalErrorIn
( (
"void Foam::meshToMeshNew::" "void Foam::meshToMesh::"
"distributeAndMergeCells" "distributeAndMergeCells"
"(" "("
"const mapDistribute&, " "const mapDistribute&, "

View File

@ -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) 2012-2013 OpenFOAM Foundation \\ / A nd | Copyright (C) 2012-2014 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -61,7 +61,7 @@ namespace Foam
// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
template<class Type> template<class Type>
void Foam::meshToMeshNew::add void Foam::meshToMesh::add
( (
UList<Type>& fld, UList<Type>& fld,
const label offset const label offset
@ -75,7 +75,7 @@ void Foam::meshToMeshNew::add
template<class Type, class CombineOp> template<class Type, class CombineOp>
void Foam::meshToMeshNew::mapSrcToTgt void Foam::meshToMesh::mapSrcToTgt
( (
const UList<Type>& srcField, const UList<Type>& srcField,
const CombineOp& cop, const CombineOp& cop,
@ -86,7 +86,7 @@ void Foam::meshToMeshNew::mapSrcToTgt
{ {
FatalErrorIn FatalErrorIn
( (
"void Foam::meshToMeshNew::mapSrcToTgt" "void Foam::meshToMesh::mapSrcToTgt"
"(" "("
"const UList<Type>&, " "const UList<Type>&, "
"const CombineOp&, " "const CombineOp&, "
@ -150,7 +150,7 @@ void Foam::meshToMeshNew::mapSrcToTgt
template<class Type, class CombineOp> template<class Type, class CombineOp>
Foam::tmp<Foam::Field<Type> > Foam::meshToMeshNew::mapSrcToTgt Foam::tmp<Foam::Field<Type> > Foam::meshToMesh::mapSrcToTgt
( (
const Field<Type>& srcField, const Field<Type>& srcField,
const CombineOp& cop const CombineOp& cop
@ -172,7 +172,7 @@ Foam::tmp<Foam::Field<Type> > Foam::meshToMeshNew::mapSrcToTgt
template<class Type, class CombineOp> template<class Type, class CombineOp>
Foam::tmp<Foam::Field<Type> > Foam::meshToMeshNew::mapSrcToTgt Foam::tmp<Foam::Field<Type> > Foam::meshToMesh::mapSrcToTgt
( (
const tmp<Field<Type> >& tsrcField, const tmp<Field<Type> >& tsrcField,
const CombineOp& cop const CombineOp& cop
@ -183,7 +183,7 @@ Foam::tmp<Foam::Field<Type> > Foam::meshToMeshNew::mapSrcToTgt
template<class Type> template<class Type>
Foam::tmp<Foam::Field<Type> > Foam::meshToMeshNew::mapSrcToTgt Foam::tmp<Foam::Field<Type> > Foam::meshToMesh::mapSrcToTgt
( (
const Field<Type>& srcField const Field<Type>& srcField
) const ) const
@ -193,7 +193,7 @@ Foam::tmp<Foam::Field<Type> > Foam::meshToMeshNew::mapSrcToTgt
template<class Type> template<class Type>
Foam::tmp<Foam::Field<Type> > Foam::meshToMeshNew::mapSrcToTgt Foam::tmp<Foam::Field<Type> > Foam::meshToMesh::mapSrcToTgt
( (
const tmp<Field<Type> >& tsrcField const tmp<Field<Type> >& tsrcField
) const ) const
@ -203,7 +203,7 @@ Foam::tmp<Foam::Field<Type> > Foam::meshToMeshNew::mapSrcToTgt
template<class Type, class CombineOp> template<class Type, class CombineOp>
void Foam::meshToMeshNew::mapTgtToSrc void Foam::meshToMesh::mapTgtToSrc
( (
const UList<Type>& tgtField, const UList<Type>& tgtField,
const CombineOp& cop, const CombineOp& cop,
@ -214,7 +214,7 @@ void Foam::meshToMeshNew::mapTgtToSrc
{ {
FatalErrorIn FatalErrorIn
( (
"void Foam::meshToMeshNew::mapTgtToSrc" "void Foam::meshToMesh::mapTgtToSrc"
"(" "("
"const UList<Type>&, " "const UList<Type>&, "
"const CombineOp&, " "const CombineOp&, "
@ -276,7 +276,7 @@ void Foam::meshToMeshNew::mapTgtToSrc
template<class Type, class CombineOp> template<class Type, class CombineOp>
Foam::tmp<Foam::Field<Type> > Foam::meshToMeshNew::mapTgtToSrc Foam::tmp<Foam::Field<Type> > Foam::meshToMesh::mapTgtToSrc
( (
const Field<Type>& tgtField, const Field<Type>& tgtField,
const CombineOp& cop const CombineOp& cop
@ -298,7 +298,7 @@ Foam::tmp<Foam::Field<Type> > Foam::meshToMeshNew::mapTgtToSrc
template<class Type, class CombineOp> template<class Type, class CombineOp>
Foam::tmp<Foam::Field<Type> > Foam::meshToMeshNew::mapTgtToSrc Foam::tmp<Foam::Field<Type> > Foam::meshToMesh::mapTgtToSrc
( (
const tmp<Field<Type> >& ttgtField, const tmp<Field<Type> >& ttgtField,
const CombineOp& cop const CombineOp& cop
@ -309,7 +309,7 @@ Foam::tmp<Foam::Field<Type> > Foam::meshToMeshNew::mapTgtToSrc
template<class Type> template<class Type>
Foam::tmp<Foam::Field<Type> > Foam::meshToMeshNew::mapTgtToSrc Foam::tmp<Foam::Field<Type> > Foam::meshToMesh::mapTgtToSrc
( (
const Field<Type>& tgtField const Field<Type>& tgtField
) const ) const
@ -319,7 +319,7 @@ Foam::tmp<Foam::Field<Type> > Foam::meshToMeshNew::mapTgtToSrc
template<class Type> template<class Type>
Foam::tmp<Foam::Field<Type> > Foam::meshToMeshNew::mapTgtToSrc Foam::tmp<Foam::Field<Type> > Foam::meshToMesh::mapTgtToSrc
( (
const tmp<Field<Type> >& ttgtField const tmp<Field<Type> >& ttgtField
) const ) const
@ -329,7 +329,7 @@ Foam::tmp<Foam::Field<Type> > Foam::meshToMeshNew::mapTgtToSrc
template<class Type, class CombineOp> template<class Type, class CombineOp>
void Foam::meshToMeshNew::mapSrcToTgt void Foam::meshToMesh::mapSrcToTgt
( (
const GeometricField<Type, fvPatchField, volMesh>& field, const GeometricField<Type, fvPatchField, volMesh>& field,
const CombineOp& cop, const CombineOp& cop,
@ -369,7 +369,7 @@ void Foam::meshToMeshNew::mapSrcToTgt
template<class Type, class CombineOp> template<class Type, class CombineOp>
Foam::tmp<Foam::GeometricField<Type, Foam::fvPatchField, Foam::volMesh> > Foam::tmp<Foam::GeometricField<Type, Foam::fvPatchField, Foam::volMesh> >
Foam::meshToMeshNew::mapSrcToTgt Foam::meshToMesh::mapSrcToTgt
( (
const GeometricField<Type, fvPatchField, volMesh>& field, const GeometricField<Type, fvPatchField, volMesh>& field,
const CombineOp& cop const CombineOp& cop
@ -409,7 +409,7 @@ Foam::meshToMeshNew::mapSrcToTgt
template<class Type, class CombineOp> template<class Type, class CombineOp>
Foam::tmp<Foam::GeometricField<Type, Foam::fvPatchField, Foam::volMesh> > Foam::tmp<Foam::GeometricField<Type, Foam::fvPatchField, Foam::volMesh> >
Foam::meshToMeshNew::mapSrcToTgt Foam::meshToMesh::mapSrcToTgt
( (
const tmp<GeometricField<Type, fvPatchField, volMesh> >& tfield, const tmp<GeometricField<Type, fvPatchField, volMesh> >& tfield,
const CombineOp& cop const CombineOp& cop
@ -421,7 +421,7 @@ Foam::meshToMeshNew::mapSrcToTgt
template<class Type> template<class Type>
Foam::tmp<Foam::GeometricField<Type, Foam::fvPatchField, Foam::volMesh> > Foam::tmp<Foam::GeometricField<Type, Foam::fvPatchField, Foam::volMesh> >
Foam::meshToMeshNew::mapSrcToTgt Foam::meshToMesh::mapSrcToTgt
( (
const GeometricField<Type, fvPatchField, volMesh>& field const GeometricField<Type, fvPatchField, volMesh>& field
) const ) const
@ -432,7 +432,7 @@ Foam::meshToMeshNew::mapSrcToTgt
template<class Type> template<class Type>
Foam::tmp<Foam::GeometricField<Type, Foam::fvPatchField, Foam::volMesh> > Foam::tmp<Foam::GeometricField<Type, Foam::fvPatchField, Foam::volMesh> >
Foam::meshToMeshNew::mapSrcToTgt Foam::meshToMesh::mapSrcToTgt
( (
const tmp<GeometricField<Type, fvPatchField, volMesh> >& tfield const tmp<GeometricField<Type, fvPatchField, volMesh> >& tfield
) const ) const
@ -442,7 +442,7 @@ Foam::meshToMeshNew::mapSrcToTgt
template<class Type, class CombineOp> template<class Type, class CombineOp>
void Foam::meshToMeshNew::mapTgtToSrc void Foam::meshToMesh::mapTgtToSrc
( (
const GeometricField<Type, fvPatchField, volMesh>& field, const GeometricField<Type, fvPatchField, volMesh>& field,
const CombineOp& cop, const CombineOp& cop,
@ -482,7 +482,7 @@ void Foam::meshToMeshNew::mapTgtToSrc
template<class Type, class CombineOp> template<class Type, class CombineOp>
Foam::tmp<Foam::GeometricField<Type, Foam::fvPatchField, Foam::volMesh> > Foam::tmp<Foam::GeometricField<Type, Foam::fvPatchField, Foam::volMesh> >
Foam::meshToMeshNew::mapTgtToSrc Foam::meshToMesh::mapTgtToSrc
( (
const GeometricField<Type, fvPatchField, volMesh>& field, const GeometricField<Type, fvPatchField, volMesh>& field,
const CombineOp& cop const CombineOp& cop
@ -522,7 +522,7 @@ Foam::meshToMeshNew::mapTgtToSrc
template<class Type, class CombineOp> template<class Type, class CombineOp>
Foam::tmp<Foam::GeometricField<Type, Foam::fvPatchField, Foam::volMesh> > Foam::tmp<Foam::GeometricField<Type, Foam::fvPatchField, Foam::volMesh> >
Foam::meshToMeshNew::mapTgtToSrc Foam::meshToMesh::mapTgtToSrc
( (
const tmp<GeometricField<Type, fvPatchField, volMesh> >& tfield, const tmp<GeometricField<Type, fvPatchField, volMesh> >& tfield,
const CombineOp& cop const CombineOp& cop
@ -534,7 +534,7 @@ Foam::meshToMeshNew::mapTgtToSrc
template<class Type> template<class Type>
Foam::tmp<Foam::GeometricField<Type, Foam::fvPatchField, Foam::volMesh> > Foam::tmp<Foam::GeometricField<Type, Foam::fvPatchField, Foam::volMesh> >
Foam::meshToMeshNew::mapTgtToSrc Foam::meshToMesh::mapTgtToSrc
( (
const GeometricField<Type, fvPatchField, volMesh>& field const GeometricField<Type, fvPatchField, volMesh>& field
) const ) const
@ -545,7 +545,7 @@ Foam::meshToMeshNew::mapTgtToSrc
template<class Type> template<class Type>
Foam::tmp<Foam::GeometricField<Type, Foam::fvPatchField, Foam::volMesh> > Foam::tmp<Foam::GeometricField<Type, Foam::fvPatchField, Foam::volMesh> >
Foam::meshToMeshNew::mapTgtToSrc Foam::meshToMesh::mapTgtToSrc
( (
const tmp<GeometricField<Type, fvPatchField, volMesh> >& tfield const tmp<GeometricField<Type, fvPatchField, volMesh> >& tfield
) const ) const

View File

@ -1,576 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2012-2013 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 "meshToMeshNew.H"
#include "Time.H"
#include "globalIndex.H"
#include "meshToMeshMethod.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
defineTypeNameAndDebug(meshToMeshNew, 0);
template<>
const char* Foam::NamedEnum
<
Foam::meshToMeshNew::interpolationMethod,
3
>::names[] =
{
"direct",
"mapNearest",
"cellVolumeWeight"
};
const NamedEnum<meshToMeshNew::interpolationMethod, 3>
meshToMeshNew::interpolationMethodNames_;
}
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
Foam::labelList Foam::meshToMeshNew::maskCells
(
const polyMesh& src,
const polyMesh& tgt
) const
{
boundBox intersectBb
(
max(src.bounds().min(), tgt.bounds().min()),
min(src.bounds().max(), tgt.bounds().max())
);
intersectBb.inflate(0.01);
const cellList& srcCells = src.cells();
const faceList& srcFaces = src.faces();
const pointField& srcPts = src.points();
DynamicList<label> cells(src.size());
forAll(srcCells, srcI)
{
boundBox cellBb(srcCells[srcI].points(srcFaces, srcPts), false);
if (intersectBb.overlaps(cellBb))
{
cells.append(srcI);
}
}
if (debug)
{
Pout<< "participating source mesh cells: " << cells.size() << endl;
}
return cells;
}
void Foam::meshToMeshNew::normaliseWeights
(
const word& descriptor,
const labelListList& addr,
scalarListList& wght
) const
{
const label nCell = returnReduce(wght.size(), sumOp<label>());
if (nCell > 0)
{
forAll(wght, cellI)
{
scalarList& w = wght[cellI];
scalar s = sum(w);
forAll(w, i)
{
// note: normalise by s instead of cell volume since
// 1-to-1 methods duplicate contributions in parallel
w[i] /= s;
}
}
}
}
void Foam::meshToMeshNew::calcAddressing
(
const polyMesh& src,
const polyMesh& tgt
)
{
autoPtr<meshToMeshMethod> methodPtr
(
meshToMeshMethod::New
(
interpolationMethodNames_[method_],
src,
tgt
)
);
methodPtr->calculate
(
srcToTgtCellAddr_,
srcToTgtCellWght_,
tgtToSrcCellAddr_,
tgtToSrcCellWght_
);
V_ = methodPtr->V();
if (debug)
{
methodPtr->writeConnectivity(src, tgt, srcToTgtCellAddr_);
}
}
void Foam::meshToMeshNew::calculate()
{
Info<< "Creating mesh-to-mesh addressing for " << srcRegion_.name()
<< " and " << tgtRegion_.name() << " regions using "
<< interpolationMethodNames_[method_] << endl;
singleMeshProc_ = calcDistribution(srcRegion_, tgtRegion_);
if (singleMeshProc_ == -1)
{
// create global indexing for src and tgt meshes
globalIndex globalSrcCells(srcRegion_.nCells());
globalIndex globalTgtCells(tgtRegion_.nCells());
// Create processor map of overlapping cells. This map gets
// (possibly remote) cells from the tgt mesh such that they (together)
// cover all of the src mesh
autoPtr<mapDistribute> mapPtr = calcProcMap(srcRegion_, tgtRegion_);
const mapDistribute& map = mapPtr();
pointField newTgtPoints;
faceList newTgtFaces;
labelList newTgtFaceOwners;
labelList newTgtFaceNeighbours;
labelList newTgtCellIDs;
distributeAndMergeCells
(
map,
tgtRegion_,
globalTgtCells,
newTgtPoints,
newTgtFaces,
newTgtFaceOwners,
newTgtFaceNeighbours,
newTgtCellIDs
);
// create a new target mesh
polyMesh newTgt
(
IOobject
(
"newTgt." + Foam::name(Pstream::myProcNo()),
tgtRegion_.time().timeName(),
tgtRegion_.time(),
IOobject::NO_READ
),
xferMove(newTgtPoints),
xferMove(newTgtFaces),
xferMove(newTgtFaceOwners),
xferMove(newTgtFaceNeighbours),
false // no parallel comms
);
// create some dummy patch info
List<polyPatch*> patches(1);
patches[0] = new polyPatch
(
"defaultFaces",
newTgt.nFaces() - newTgt.nInternalFaces(),
newTgt.nInternalFaces(),
0,
newTgt.boundaryMesh(),
word::null
);
newTgt.addPatches(patches);
// force calculation of tet-base points used for point-in-cell
(void)newTgt.tetBasePtIs();
// force construction of cell tree
// (void)newTgt.cellTree();
if (debug)
{
Pout<< "Created newTgt mesh:" << nl
<< " old cells = " << tgtRegion_.nCells()
<< ", new cells = " << newTgt.nCells() << nl
<< " old faces = " << tgtRegion_.nFaces()
<< ", new faces = " << newTgt.nFaces() << endl;
if (debug > 1)
{
Pout<< "Writing newTgt mesh: " << newTgt.name() << endl;
newTgt.write();
}
}
calcAddressing(srcRegion_, newTgt);
// per source cell the target cell address in newTgt mesh
forAll(srcToTgtCellAddr_, i)
{
labelList& addressing = srcToTgtCellAddr_[i];
forAll(addressing, addrI)
{
addressing[addrI] = newTgtCellIDs[addressing[addrI]];
}
}
// convert target addresses in newTgtMesh into global cell numbering
forAll(tgtToSrcCellAddr_, i)
{
labelList& addressing = tgtToSrcCellAddr_[i];
forAll(addressing, addrI)
{
addressing[addrI] = globalSrcCells.toGlobal(addressing[addrI]);
}
}
// set up as a reverse distribute
mapDistribute::distribute
(
Pstream::nonBlocking,
List<labelPair>(),
tgtRegion_.nCells(),
map.constructMap(),
map.subMap(),
tgtToSrcCellAddr_,
ListPlusEqOp<label>(),
labelList()
);
// set up as a reverse distribute
mapDistribute::distribute
(
Pstream::nonBlocking,
List<labelPair>(),
tgtRegion_.nCells(),
map.constructMap(),
map.subMap(),
tgtToSrcCellWght_,
ListPlusEqOp<scalar>(),
scalarList()
);
// weights normalisation
normaliseWeights
(
"source",
srcToTgtCellAddr_,
srcToTgtCellWght_
);
normaliseWeights
(
"target",
tgtToSrcCellAddr_,
tgtToSrcCellWght_
);
// cache maps and reset addresses
List<Map<label> > cMap;
srcMapPtr_.reset
(
new mapDistribute(globalSrcCells, tgtToSrcCellAddr_, cMap)
);
tgtMapPtr_.reset
(
new mapDistribute(globalTgtCells, srcToTgtCellAddr_, cMap)
);
// collect volume intersection contributions
reduce(V_, sumOp<scalar>());
}
else
{
calcAddressing(srcRegion_, tgtRegion_);
normaliseWeights
(
"source",
srcToTgtCellAddr_,
srcToTgtCellWght_
);
normaliseWeights
(
"target",
tgtToSrcCellAddr_,
tgtToSrcCellWght_
);
}
Info<< " Overlap volume: " << V_ << endl;
}
Foam::AMIPatchToPatchInterpolation::interpolationMethod
Foam::meshToMeshNew::interpolationMethodAMI
(
const interpolationMethod method
) const
{
switch (method_)
{
case imDirect:
{
return AMIPatchToPatchInterpolation::imDirect;
break;
}
case imMapNearest:
{
return AMIPatchToPatchInterpolation::imMapNearest;
break;
}
case imCellVolumeWeight:
{
return AMIPatchToPatchInterpolation::imFaceAreaWeight;
break;
}
default:
{
FatalErrorIn
(
"Foam::AMIPatchToPatchInterpolation::interpolationMethod"
"Foam::meshToMeshNew::interpolationMethodAMI"
"("
"const interpolationMethod method"
") const"
)
<< "Unhandled enumeration " << method_
<< abort(FatalError);
}
}
return AMIPatchToPatchInterpolation::imDirect;
}
const Foam::PtrList<Foam::AMIPatchToPatchInterpolation>&
Foam::meshToMeshNew::patchAMIs() const
{
if (patchAMIs_.empty())
{
const word amiMethod =
AMIPatchToPatchInterpolation::interpolationMethodToWord
(
interpolationMethodAMI(method_)
);
patchAMIs_.setSize(srcPatchID_.size());
forAll(srcPatchID_, i)
{
label srcPatchI = srcPatchID_[i];
label tgtPatchI = tgtPatchID_[i];
const polyPatch& srcPP = srcRegion_.boundaryMesh()[srcPatchI];
const polyPatch& tgtPP = tgtRegion_.boundaryMesh()[tgtPatchI];
Info<< "Creating AMI between source patch " << srcPP.name()
<< " and target patch " << tgtPP.name()
<< " using " << amiMethod
<< endl;
Info<< incrIndent;
patchAMIs_.set
(
i,
new AMIPatchToPatchInterpolation
(
srcPP,
tgtPP,
faceAreaIntersect::tmMesh,
interpolationMethodAMI(method_),
true // flip target patch since patch normals are aligned
)
);
Info<< decrIndent;
}
}
return patchAMIs_;
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::meshToMeshNew::meshToMeshNew
(
const polyMesh& src,
const polyMesh& tgt,
const interpolationMethod& method,
bool interpAllPatches
)
:
srcRegion_(src),
tgtRegion_(tgt),
srcPatchID_(),
tgtPatchID_(),
patchAMIs_(),
cuttingPatches_(),
srcToTgtCellAddr_(),
tgtToSrcCellAddr_(),
srcToTgtCellWght_(),
tgtToSrcCellWght_(),
method_(method),
V_(0.0),
singleMeshProc_(-1),
srcMapPtr_(NULL),
tgtMapPtr_(NULL)
{
if (interpAllPatches)
{
const polyBoundaryMesh& srcBM = src.boundaryMesh();
const polyBoundaryMesh& tgtBM = tgt.boundaryMesh();
DynamicList<label> srcPatchID(src.boundaryMesh().size());
DynamicList<label> tgtPatchID(tgt.boundaryMesh().size());
forAll(srcBM, patchI)
{
const polyPatch& pp = srcBM[patchI];
if (!polyPatch::constraintType(pp.type()))
{
srcPatchID.append(pp.index());
label tgtPatchI = tgt.boundaryMesh().findPatchID(pp.name());
if (tgtPatchI != -1)
{
tgtPatchID.append(tgtPatchI);
}
else
{
FatalErrorIn
(
"Foam::meshToMeshNew::meshToMeshNew"
"("
"const polyMesh&, "
"const polyMesh&, "
"const interpolationMethod&, "
"bool"
")"
) << "Source patch " << pp.name()
<< " not found in target mesh. "
<< "Available target patches are " << tgtBM.names()
<< exit(FatalError);
}
}
}
srcPatchID_.transfer(srcPatchID);
tgtPatchID_.transfer(tgtPatchID);
}
// calculate volume addressing and weights
calculate();
// calculate patch addressing and weights
(void)patchAMIs();
}
Foam::meshToMeshNew::meshToMeshNew
(
const polyMesh& src,
const polyMesh& tgt,
const interpolationMethod& method,
const HashTable<word>& patchMap,
const wordList& cuttingPatches
)
:
srcRegion_(src),
tgtRegion_(tgt),
srcPatchID_(),
tgtPatchID_(),
patchAMIs_(),
cuttingPatches_(),
srcToTgtCellAddr_(),
tgtToSrcCellAddr_(),
srcToTgtCellWght_(),
tgtToSrcCellWght_(),
method_(method),
V_(0.0),
singleMeshProc_(-1),
srcMapPtr_(NULL),
tgtMapPtr_(NULL)
{
srcPatchID_.setSize(patchMap.size());
tgtPatchID_.setSize(patchMap.size());
label i = 0;
forAllConstIter(HashTable<word>, patchMap, iter)
{
const word& tgtPatchName = iter.key();
const word& srcPatchName = iter();
const polyPatch& srcPatch = srcRegion_.boundaryMesh()[srcPatchName];
const polyPatch& tgtPatch = tgtRegion_.boundaryMesh()[tgtPatchName];
srcPatchID_[i] = srcPatch.index();
tgtPatchID_[i] = tgtPatch.index();
i++;
}
// calculate volume addressing and weights
calculate();
// calculate patch addressing and weights
(void)patchAMIs();
// set IDs of cutting patches on target mesh
cuttingPatches_.setSize(cuttingPatches.size());
forAll(cuttingPatches_, i)
{
const word& patchName = cuttingPatches[i];
cuttingPatches_[i] = tgt.boundaryMesh().findPatchID(patchName);
}
}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::meshToMeshNew::~meshToMeshNew()
{}
// ************************************************************************* //

View File

@ -1,499 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2012-2013 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::meshToMeshNew
Description
Class to calculate the cell-addressing between two overlapping meshes
Mapping is performed using a run-time selectable interpolation mothod
SeeAlso
meshToMeshMethod
SourceFiles
meshToMeshNew.C
meshToMeshNewParallelOps.C
meshToMeshNewTemplates.C
\*---------------------------------------------------------------------------*/
#ifndef meshToMeshNew_H
#define meshToMeshNew_H
#include "polyMesh.H"
#include "boundBox.H"
#include "mapDistribute.H"
#include "volFieldsFwd.H"
#include "NamedEnum.H"
#include "AMIPatchToPatchInterpolation.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class meshToMeshNew Declaration
\*---------------------------------------------------------------------------*/
class meshToMeshNew
{
public:
// Public data types
//- Enumeration specifying interpolation method
enum interpolationMethod
{
imDirect,
imMapNearest,
imCellVolumeWeight
};
static const NamedEnum<interpolationMethod, 3>
interpolationMethodNames_;
private:
// Private data
//- Reference to the source mesh
const polyMesh& srcRegion_;
//- Reference to the target mesh
const polyMesh& tgtRegion_;
//- List of target patch IDs per source patch (local index)
List<label> srcPatchID_;
//- List of source patch IDs per target patch (local index)
List<label> tgtPatchID_;
//- List of AMIs between source and target patches
mutable PtrList<AMIPatchToPatchInterpolation> patchAMIs_;
//- Cutting patches whose values are set using a zero-gradient condition
List<label> cuttingPatches_;
//- Source to target cell addressing
labelListList srcToTgtCellAddr_;
//- Target to source cell addressing
labelListList tgtToSrcCellAddr_;
//- Source to target cell interplation weights
scalarListList srcToTgtCellWght_;
//- Target to source cell interpolation weights
scalarListList tgtToSrcCellWght_;
//- Interpolation method
interpolationMethod method_;
//- Cell total volume in overlap region [m3]
scalar V_;
//- Index of processor that holds all of both sides. -1 in all other
// cases
label singleMeshProc_;
//- Source map pointer - parallel running only
autoPtr<mapDistribute> srcMapPtr_;
//- Target map pointer - parallel running only
autoPtr<mapDistribute> tgtMapPtr_;
// Private Member Functions
//- Helper function to add a constant offset to a list
template<class Type>
void add(UList<Type>& fld, const label offset) const;
//- Return src cell IDs for the overlap region
labelList maskCells(const polyMesh& src, const polyMesh& tgt) const;
//- Normalise the interpolation weights
void normaliseWeights
(
const word& descriptor,
const labelListList& addr,
scalarListList& wght
) const;
//- Calculate the addressing between overalping regions of src and tgt
// meshes
void calcAddressing(const polyMesh& src, const polyMesh& tgt);
//- Calculate - main driver function
void calculate();
//- Conversion between mesh and patch interpolation methods
AMIPatchToPatchInterpolation::interpolationMethod
interpolationMethodAMI
(
const interpolationMethod method
) const;
//- Return the list of AMIs between source and target patches
const PtrList<AMIPatchToPatchInterpolation>& patchAMIs() const;
// Parallel operations
//- Determine whether the meshes are split across multiple pocessors
label calcDistribution
(
const polyMesh& src,
const polyMesh& tgt
) const;
//- Determine which processor bounding-boxes overlap
label calcOverlappingProcs
(
const List<boundBox>& procBb,
const boundBox& bb,
boolList& overlaps
) const;
//- Calculate the mapping between processors
autoPtr<mapDistribute> calcProcMap
(
const polyMesh& src,
const polyMesh& tgt
) const;
//- Distribute mesh info from 'my' processor to others
void distributeCells
(
const mapDistribute& map,
const polyMesh& tgtMesh,
const globalIndex& globalI,
List<pointField>& points,
List<label>& nInternalFaces,
List<faceList>& faces,
List<labelList>& faceOwner,
List<labelList>& faceNeighbour,
List<labelList>& cellIDs,
List<labelList>& nbrProcIDs,
List<labelList>& procLocalFaceIDs
) const;
//- Collect pieces of tgt mesh from other procssors and restructure
void distributeAndMergeCells
(
const mapDistribute& map,
const polyMesh& tgt,
const globalIndex& globalI,
pointField& tgtPoints,
faceList& tgtFaces,
labelList& tgtFaceOwners,
labelList& tgtFaceNeighbours,
labelList& tgtCellIDs
) const;
//- Disallow default bitwise copy construct
meshToMeshNew(const meshToMeshNew&);
//- Disallow default bitwise assignment
void operator=(const meshToMeshNew&);
public:
//- Run-time type information
TypeName("meshToMeshNew");
//- Construct from source and target meshes
meshToMeshNew
(
const polyMesh& src,
const polyMesh& tgt,
const interpolationMethod& method,
const bool interpAllPatches = true
);
//- Construct from source and target meshes
meshToMeshNew
(
const polyMesh& src,
const polyMesh& tgt,
const interpolationMethod& method,
const HashTable<word>& patchMap,
const wordList& cuttingPatches
);
//- Destructor
virtual ~meshToMeshNew();
// Member Functions
// Access
//- Return const access to the source mesh
inline const polyMesh& srcRegion() const;
//- Return const access to the target mesh
inline const polyMesh& tgtRegion() const;
//- Return const access to the source to target cell addressing
inline const labelListList& srcToTgtCellAddr() const;
//- Return const access to the target to source cell addressing
inline const labelListList& tgtToSrcCellAddr() const;
//- Return const access to the source to target cell weights
inline const scalarListList& srcToTgtCellWght() const;
//- Return const access to the target to source cell weights
inline const scalarListList& tgtToSrcCellWght() const;
//- Return const access to the overlap volume
inline scalar V() const;
// Evaluation
// Source-to-target field mapping
//- Map field from src to tgt mesh with defined operation
// Values passed in via 'result' are used to initialise the
// return value
template<class Type, class CombineOp>
void mapSrcToTgt
(
const UList<Type>& srcFld,
const CombineOp& cop,
List<Type>& result
) const;
//- Return the src field mapped to the tgt mesh with a defined
// operation. Initial values of the result are set to zero
template<class Type, class CombineOp>
tmp<Field<Type> > mapSrcToTgt
(
const Field<Type>& srcFld,
const CombineOp& cop
) const;
//- Convenience function to map a tmp field to the tgt mesh
// with a defined operation
template<class Type, class CombineOp>
tmp<Field<Type> > mapSrcToTgt
(
const tmp<Field<Type> >& tsrcFld,
const CombineOp& cop
) const;
//- Convenience function to map a field to the tgt mesh with a
// default operation (plusEqOp)
template<class Type>
tmp<Field<Type> > mapSrcToTgt
(
const Field<Type>& srcFld
) const;
//- Convenience function to map a tmp field to the tgt mesh
// with a default operation (plusEqOp)
template<class Type>
tmp<Field<Type> > mapSrcToTgt
(
const tmp<Field<Type> >& tsrcFld
) const;
// Target-to-source field mapping
//- Map field from tgt to src mesh with defined operation
// Values passed in via 'result' are used to initialise the
// return value
template<class Type, class CombineOp>
void mapTgtToSrc
(
const UList<Type>& tgtFld,
const CombineOp& cop,
List<Type>& result
) const;
//- Return the tgt field mapped to the src mesh with a defined
// operation. Initial values of the result are set to zero
template<class Type, class CombineOp>
tmp<Field<Type> > mapTgtToSrc
(
const Field<Type>& tgtFld,
const CombineOp& cop
) const;
//- Convenience function to map a tmp field to the src mesh
// with a defined operation
template<class Type, class CombineOp>
tmp<Field<Type> > mapTgtToSrc
(
const tmp<Field<Type> >& ttgtFld,
const CombineOp& cop
) const;
//- Convenience function to map a field to the src mesh with a
// default operation (plusEqOp)
template<class Type>
tmp<Field<Type> > mapTgtToSrc
(
const Field<Type>& tgtFld
) const;
//- Convenience function to map a tmp field to the src mesh
// with a default operation (plusEqOp)
template<class Type>
tmp<Field<Type> > mapTgtToSrc
(
const tmp<Field<Type> >& ttgtFld
) const;
// Source-to-target volume field mapping
//- Interpolate a field with a defined operation. Values
// passed in via 'result' are used to initialise the return
// value
template<class Type, class CombineOp>
void mapSrcToTgt
(
const GeometricField<Type, fvPatchField, volMesh>& field,
const CombineOp& cop,
GeometricField<Type, fvPatchField, volMesh>& result
) const;
//- Interpolate a field with a defined operation. The initial
// values of the result are set to zero
template<class Type, class CombineOp>
tmp<GeometricField<Type, fvPatchField, volMesh> > mapSrcToTgt
(
const GeometricField<Type, fvPatchField, volMesh>& field,
const CombineOp& cop
) const;
//- Interpolate a tmp field with a defined operation. The
// initial values of the result are set to zero
template<class Type, class CombineOp>
tmp<GeometricField<Type, fvPatchField, volMesh> > mapSrcToTgt
(
const tmp<GeometricField<Type, fvPatchField, volMesh> >&
tfield,
const CombineOp& cop
) const;
//- Convenience function to map a field with a default
// operation (plusEqOp)
template<class Type>
tmp<GeometricField<Type, fvPatchField, volMesh> > mapSrcToTgt
(
const GeometricField<Type, fvPatchField, volMesh>& field
) const;
//- Convenience function to map a tmp field with a default
// operation (plusEqOp)
template<class Type>
tmp<GeometricField<Type, fvPatchField, volMesh> > mapSrcToTgt
(
const tmp<GeometricField<Type, fvPatchField, volMesh> >&
tfield
) const;
// Target-to-source volume field mapping
//- Interpolate a field with a defined operation. Values
// passed in via 'result' are used to initialise the return
// value
template<class Type, class CombineOp>
void mapTgtToSrc
(
const GeometricField<Type, fvPatchField, volMesh>& field,
const CombineOp& cop,
GeometricField<Type, fvPatchField, volMesh>& result
) const;
//- Interpolate a field with a defined operation. The initial
// values of the result are set to zero
template<class Type, class CombineOp>
tmp<GeometricField<Type, fvPatchField, volMesh> > mapTgtToSrc
(
const GeometricField<Type, fvPatchField, volMesh>& field,
const CombineOp& cop
) const;
//- Interpolate a tmp field with a defined operation. The
// initial values of the result are set to zero
template<class Type, class CombineOp>
tmp<GeometricField<Type, fvPatchField, volMesh> > mapTgtToSrc
(
const tmp<GeometricField<Type, fvPatchField, volMesh> >&
tfield,
const CombineOp& cop
) const;
//- Convenience function to map a field with a default
// operation (plusEqOp)
template<class Type>
tmp<GeometricField<Type, fvPatchField, volMesh> > mapTgtToSrc
(
const GeometricField<Type, fvPatchField, volMesh>& field
) const;
//- Convenience function to map a tmp field with a default
// operation (plusEqOp)
template<class Type>
tmp<GeometricField<Type, fvPatchField, volMesh> > mapTgtToSrc
(
const tmp<GeometricField<Type, fvPatchField, volMesh> >&
tfield
) const;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#include "meshToMeshNewI.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository
#include "meshToMeshNewTemplates.C"
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -9,13 +9,13 @@ cavityCases="cavity cavityFine cavityGrade cavityHighRe cavityClipped"
runMapFields() runMapFields()
{ {
echo "Running mapFields from $1 to $2" echo "Running mapFields from $1 to $2"
mapFieldsNew $1 -case $2 -sourceTime latestTime > $2/log.mapFields 2>&1 mapFields $1 -case $2 -sourceTime latestTime > $2/log.mapFields 2>&1
} }
runMapFieldsConsistent() runMapFieldsConsistent()
{ {
echo "Running mapFields from $1 to $2" echo "Running mapFields from $1 to $2"
mapFieldsNew $1 -case $2 -sourceTime latestTime -consistent > $2/log.mapFields 2>&1 mapFields $1 -case $2 -sourceTime latestTime -consistent > $2/log.mapFields 2>&1
} }
copySolutionDirs() copySolutionDirs()

View File

@ -1,6 +1,6 @@
.SUFFIXES: .C .cxx .cc .cpp .SUFFIXES: .C .cxx .cc .cpp
c++WARN = -wd327,654,819,1125,1476,1505,1572 c++WARN = -wd327,525,654,819,1125,1476,1505,1572
CC = icpc -std=c++0x CC = icpc -std=c++0x

View File

@ -1,6 +1,6 @@
.SUFFIXES: .C .cxx .cc .cpp .SUFFIXES: .C .cxx .cc .cpp
c++WARN = -wd327,654,819,1125,1476,1505,1572 c++WARN = -wd327,525,654,819,1125,1476,1505,1572
CC = icpc CC = icpc

View File

@ -1,6 +1,6 @@
.SUFFIXES: .C .cxx .cc .cpp .SUFFIXES: .C .cxx .cc .cpp
c++WARN = -wd327,654,819,1125,1476,1505,1572 c++WARN = -wd327,525,654,819,1125,1476,1505,1572
#CC = icpc -gcc-version=400 #CC = icpc -gcc-version=400
CC = icpc -std=c++0x CC = icpc -std=c++0x