Non-Conformal Coupled (NCC): Conservative coupling of non-conforming patches

This major development provides coupling of patches which are
non-conformal, i.e. where the faces of one patch do not match the faces
of the other. The coupling is fully conservative and second order
accurate in space, unlike the Arbitrary Mesh Interface (AMI) and
associated ACMI and Repeat AMI methods which NCC replaces.

Description:

A non-conformal couple is a connection between a pair of boundary
patches formed by projecting one patch onto the other in a way that
fills the space between them. The intersection between the projected
surface and patch forms new faces that are incorporated into the finite
volume mesh. These new faces are created identically on both sides of
the couple, and therefore become equivalent to internal faces within the
mesh. The affected cells remain closed, meaning that the area vectors
sum to zero for all the faces of each cell. Consequently, the main
benefits of the finite volume method, i.e. conservation and accuracy,
are not undermined by the coupling.

A couple connects parts of mesh that are otherwise disconnected and can
be used in the following ways:

+ to simulate rotating geometries, e.g. a propeller or stirrer, in which
  a part of the mesh rotates with the geometry and connects to a
  surrounding mesh which is not moving;
+ to connect meshes that are generated separately, which do not conform
  at their boundaries;
+ to connect patches which only partially overlap, in which the
  non-overlapped section forms another boundary, e.g. a wall;
+ to simulate a case with a geometry which is periodically repeating by
  creating multiple couples with different transformations between
  patches.

The capability for simulating partial overlaps replaces the ACMI
functionality, currently provided by the 'cyclicACMI' patch type, and
which is unreliable unless the couple is perfectly flat. The capability
for simulating periodically repeating geometry replaces the Repeat AMI
functionality currently provided by the 'cyclicRepeatAMI' patch type.

Usage:

The process of meshing for NCC is very similar to existing processes for
meshing for AMI. Typically, a mesh is generated with an identifiable set
of internal faces which coincide with the surface through which the mesh
will be coupled. These faces are then duplicated by running the
'createBaffles' utility to create two boundary patches. The points are
then split using 'splitBaffles' in order to permit independent motion of
the patches.

In AMI, these patches are assigned the 'cyclicAMI' patch type, which
couples them using AMI interpolation methods.

With NCC, the patches remain non-coupled, e.g. a 'wall' type. Coupling
is instead achieved by running the new 'createNonConformalCouples'
utility, which creates additional coupled patches of type
'nonConformalCyclic'. These appear in the 'constant/polyMesh/boundary'
file with zero faces; they are populated with faces in the finite volume
mesh during the connection process in NCC.

For a single couple, such as that which separates the rotating and
stationary sections of a mesh, the utility can be called using the
non-coupled patch names as arguments, e.g.

    createNonConformalCouples -overwrite rotatingZoneInner rotatingZoneOuter

where 'rotatingZoneInner' and 'rotatingZoneOuter' are the names of the
patches.

For multiple couples, and/or couples with transformations,
'createNonConformalCouples' should be run without arguments. Settings
will then be read from a configuration file named
'system/createNonConformalCouplesDict'. See
'$FOAM_ETC/caseDicts/annotated/createNonConformalCouplesDict' for
examples.

Boundary conditions must be specified for the non-coupled patches. For a
couple where the patches fully overlap, boundary conditions
corresponding to a slip wall are typically applied to fields, i.e
'movingWallSlipVelocity' (or 'slip' if the mesh is stationary) for
velocity U, 'zeroGradient' or 'fixedFluxPressure' for pressure p, and
'zeroGradient' for other fields.  For a couple with
partially-overlapping patches, boundary conditions are applied which
physically represent the non-overlapped region, e.g. a no-slip wall.

Boundary conditions also need to be specified for the
'nonConformalCyclic' patches created by 'createNonConformalCouples'. It
is generally recommended that this is done by including the
'$FOAM_ETC/caseDicts/setConstraintTypes' file in the 'boundaryField'
section of each of the field files, e.g.

    boundaryField
    {
        #includeEtc "caseDicts/setConstraintTypes"

        inlet
        {
             ...
        }

        ...
    }

For moving mesh cases, it may be necessary to correct the mesh fluxes
that are changed as a result of the connection procedure. If the
connected patches do not conform perfectly to the mesh motion, then
failure to correct the fluxes can result in noise in the pressure
solution.

Correction for the mesh fluxes is enabled by the 'correctMeshPhi' switch
in the 'PIMPLE' (or equivalent) section of 'system/fvSolution'. When it
is enabled, solver settings are required for 'MeshPhi'. The solution
just needs to distribute the error enough to dissipate the noise. A
smooth solver with a loose tolerance is typically sufficient, e.g. the
settings in 'system/fvSolution' shown below:

    solvers
    {
        MeshPhi
        {
            solver          smoothSolver;
            smoother        symGaussSeidel;
            tolerance       1e-2;
            relTol          0;
        }
        ...
    }

    PIMPLE
    {
         correctMeshPhi      yes;
         ...
    }

The solution of 'MeshPhi' is an inexpensive computation since it is
applied only to a small subset of the mesh adjacent to the
couple. Conservation is maintained whether or not the mesh flux
correction is enabled, and regardless of the solution tolerance for
'MeshPhi'.

Advantages of NCC:

+ NCC maintains conservation which is required for many numerical
  schemes and algorithms to operate effectively, in particular those
  designed to maintain boundedness of a solution.

+ Closed-volume systems no longer suffer from accumulation or loss of
  mass, poor convergence of the pressure equation, and/or concentration
  of error in the reference cell.

+ Partially overlapped simulations are now possible on surfaces that are
  not perfectly flat. The projection fills space so no overlaps or
  spaces are generated inside contiguously overlapping sections, even if
  those sections have sharp angles.

+ The finite volume faces created by NCC have geometrically accurate
  centres. This makes the method second order accurate in space.

+ The polyhedral mesh no longer requires duplicate boundary faces to be
  generated in order to run a partially overlapped simulation.

+ Lagrangian elements can now transfer across non-conformal couplings in
  parallel.

+ Once the intersection has been computed and applied to the finite
  volume mesh, it can use standard cyclic or processor cyclic finite
  volume boundary conditions, with no need for additional patch types or
  matrix interfaces.

+ Parallel communication is done using the standard
  processor-patch-field system. This is more efficient than alternative
  systems since it has been carefully optimised for use within the
  linear solvers.

+ Coupled patches are disconnected prior to mesh motion and topology
  change and reconnected afterwards. This simplifies the boundary
  condition specification for mesh motion fields.

Resolved Bug Reports:

+ https://bugs.openfoam.org/view.php?id=663
+ https://bugs.openfoam.org/view.php?id=883
+ https://bugs.openfoam.org/view.php?id=887
+ https://bugs.openfoam.org/view.php?id=1337
+ https://bugs.openfoam.org/view.php?id=1388
+ https://bugs.openfoam.org/view.php?id=1422
+ https://bugs.openfoam.org/view.php?id=1829
+ https://bugs.openfoam.org/view.php?id=1841
+ https://bugs.openfoam.org/view.php?id=2274
+ https://bugs.openfoam.org/view.php?id=2561
+ https://bugs.openfoam.org/view.php?id=3817

Deprecation:

NCC replaces the functionality provided by AMI, ACMI and Repeat AMI.
ACMI and Repeat AMI are insufficiently reliable to warrant further
maintenance so are removed in an accompanying commit to OpenFOAM-dev.
AMI is more widely used so will be retained alongside NCC for the next
version release of OpenFOAM and then subsequently removed from
OpenFOAM-dev.
This commit is contained in:
Will Bainbridge
2022-05-09 14:35:11 +01:00
parent 94679fa88d
commit 569fa31d09
254 changed files with 18751 additions and 4327 deletions

View File

@ -0,0 +1,3 @@
Test-fvMeshStitcher.C
EXE = $(FOAM_USER_APPBIN)/Test-fvMeshStitcher

View File

@ -0,0 +1,9 @@
EXE_INC = \
-I$(LIB_SRC)/fileFormats/lnInclude \
-I$(LIB_SRC)/finiteVolume/lnInclude \
-I$(LIB_SRC)/meshTools/lnInclude
EXE_LIBS = \
-lfileFormats \
-lfiniteVolume \
-lmeshTools

View File

@ -0,0 +1,78 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2021-2022 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 "argList.H"
#include "fvMesh.H"
#include "Time.H"
#include "timeSelector.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
using namespace Foam;
int main(int argc, char *argv[])
{
Foam::argList::addBoolOption("write", "write mesh/results files");
#include "addOverwriteOption.H"
#include "addRegionOption.H"
#include "setRootCase.H"
#include "createTime.H"
runTime.functionObjects().off();
#include "createNamedMesh.H"
const bool write = args.optionFound("write");
const bool overwrite = args.optionFound("overwrite");
if (write || overwrite)
{
const word oldInstance = mesh.pointsInstance();
mesh.setInstance(runTime.timeName());
// Set the precision of the points data to 10
IOstream::defaultPrecision(max(10u, IOstream::defaultPrecision()));
if (!overwrite)
{
runTime++;
}
else
{
mesh.setInstance(oldInstance);
}
// Write resulting mesh
Info<< "Writing mesh to " << runTime.timeName() << nl << endl;
mesh.write();
}
Info<< "End" << nl << endl;
return 0;
}
// ************************************************************************* //

View File

@ -0,0 +1,3 @@
Test-patchToPatch.C
EXE = $(FOAM_USER_APPBIN)/Test-patchToPatch

View File

@ -0,0 +1,7 @@
EXE_INC = \
-I$(LIB_SRC)/fileFormats/lnInclude \
-I$(LIB_SRC)/meshTools/lnInclude
EXE_LIBS = \
-lfileFormats \
-lmeshTools

View File

@ -0,0 +1,77 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2021-2022 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 "argList.H"
#include "AMIInterpolation.H"
#include "cpuTime.H"
#include "patchToPatch.H"
#include "polyMesh.H"
#include "Time.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
using namespace Foam;
int main(int argc, char *argv[])
{
argList::validArgs.append("source");
argList::validArgs.append("target");
argList::validArgs.append("method");
#include "setRootCase.H"
#include "createTime.H"
#include "createPolyMesh.H"
const polyPatch& srcPatch = mesh.boundaryMesh()[args[1]];
const polyPatch& tgtPatch = mesh.boundaryMesh()[args[2]];
const word& method = args[3];
cpuTime time;
/*
AMIInterpolation(srcPatch, tgtPatch, faceAreaIntersect::tmMesh);
Info<< nl << "AMI" << ": Completed in "
<< time.cpuTimeIncrement() << " s" << nl << endl;
*/
patchToPatch::New(method, false)->update
(
srcPatch,
srcPatch.pointNormals(),
tgtPatch
);
Info<< nl << patchToPatch::typeName << ": Completed in "
<< time.cpuTimeIncrement() << " s" << nl << endl;
Info<< "End" << nl << endl;
return 0;
}
// ************************************************************************* //

View File

@ -2,7 +2,7 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org \\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2011-2018 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2022 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -27,45 +27,45 @@ Application
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#include "fvCFD.H" #include "fvCFD.H"
#include "timeSelector.H"
#include "volPointInterpolation.H" #include "volPointInterpolation.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
template<class Type>
bool interpolate(const fvMesh& mesh, const word& name)
{
typeIOobject<VolField<Type>> io
(
name,
mesh.time().timeName(),
mesh,
IOobject::MUST_READ
);
if (!io.headerOk()) return false;
Info<< "Reading field " << name << nl << endl;
const VolField<Type> vf(io, mesh);
const PointField<Type> pf(volPointInterpolation::New(mesh).interpolate(vf));
Info<< "Writing field " << pf.name() << nl << endl;
return pf.write();
}
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
argList::validArgs.append("field");
Foam::timeSelector::addOptions();
#include "setRootCase.H" #include "setRootCase.H"
#include "createTime.H" #include "createTime.H"
Foam::instantList timeDirs = Foam::timeSelector::select0(runTime, args);
#include "createMesh.H" #include "createMesh.H"
Info<< "Reading field p\n" << endl;
volScalarField p
(
IOobject
(
"p",
runTime.timeName(),
mesh,
IOobject::MUST_READ,
IOobject::AUTO_WRITE
),
mesh
);
Info<< "Reading field U\n" << endl;
volVectorField U
(
IOobject
(
"U",
runTime.timeName(),
mesh,
IOobject::MUST_READ,
IOobject::AUTO_WRITE
),
mesh
);
const pointMesh& pMesh = pointMesh::New(mesh); const pointMesh& pMesh = pointMesh::New(mesh);
const pointBoundaryMesh& pbm = pMesh.boundary(); const pointBoundaryMesh& pbm = pMesh.boundary();
@ -78,21 +78,31 @@ int main(int argc, char *argv[])
<< endl; << endl;
} }
const volPointInterpolation& pInterp = volPointInterpolation::New(mesh); const word name = args.argRead<word>(1);
forAll(timeDirs, timei)
pointScalarField pp(pInterp.interpolate(p));
Info<< pp.name() << " boundary" << endl;
forAll(pp.boundaryField(), patchi)
{ {
Info<< pbm[patchi].name() << " coupled=" runTime.setTime(timeDirs[timei], timei);
<< pp.boundaryField()[patchi].coupled()<< endl;
Info<< "Time = " << runTime.userTimeName() << endl;
mesh.readUpdate();
if
(
!interpolate<scalar>(mesh, name)
&& !interpolate<vector>(mesh, name)
&& !interpolate<sphericalTensor>(mesh, name)
&& !interpolate<symmTensor>(mesh, name)
&& !interpolate<tensor>(mesh, name)
)
{
WarningInFunction
<< "Could not find field " << name << nl << endl;
}
} }
pp.write(); Info<< "End\n" << endl;
pointVectorField pU(pInterp.interpolate(U));
pU.write();
return 0; return 0;
} }

View File

@ -0,0 +1,3 @@
createNonConformalCouples.C
EXE = $(FOAM_APPBIN)/createNonConformalCouples

View File

@ -0,0 +1,9 @@
EXE_INC = \
-I$(LIB_SRC)/finiteVolume/lnInclude \
-I$(LIB_SRC)/dynamicMesh/lnInclude \
-I$(LIB_SRC)/meshTools/lnInclude
EXE_LIBS = \
-lfiniteVolume \
-ldynamicMesh \
-lmeshTools

View File

@ -0,0 +1,377 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2011-2022 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
createNonConformalCouples
Description
Utility to create non-conformal couples between non-coupled patches.
Usage
\b createNonConformalCouples <patch1> <patch2>
Note
If run with two arguments, these arguments specify the patches between
which a single couple is to be created. The resulting couple will not have
a transformation.
Usage
\b createNonConformalCouples
Note
If run without arguments then settings are read from a \b
system/createNonConformalCouplesDict dictionary (or from a different
dictionary specified by the \b -dict option). This dictionary can specify
the creation of multiple couples and/or couples with transformations.
\*---------------------------------------------------------------------------*/
#include "argList.H"
#include "fvMeshStitchersStationary.H"
#include "nonConformalCyclicPolyPatch.H"
#include "nonConformalErrorPolyPatch.H"
#include "nonConformalProcessorCyclicPolyPatch.H"
#include "polyMesh.H"
#include "processorPolyPatch.H"
#include "systemDict.H"
#include "Time.H"
using namespace Foam;
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
void createNonConformalCouples
(
fvMesh& mesh,
const List<Pair<word>>& patchNames,
const wordList& cyclicNames,
const List<cyclicTransform>& transforms
)
{
const polyBoundaryMesh& patches = mesh.boundaryMesh();
List<polyPatch*> newPatches;
// Find the first processor patch and face
label firstProcPatchi = patches.size(), firstProcFacei = mesh.nFaces();
forAll(patches, patchi)
{
const polyPatch& pp = patches[patchi];
if (isA<processorPolyPatch>(pp) && firstProcPatchi == patches.size())
{
firstProcPatchi = patchi;
firstProcFacei = pp.start();
}
if (!isA<processorPolyPatch>(pp) && firstProcPatchi != patches.size())
{
FatalErrorInFunction
<< "Processor patches do not follow boundary patches"
<< exit(FatalError);
}
}
// Clone the non-processor patches
for (label patchi = 0; patchi < firstProcPatchi; ++ patchi)
{
const polyPatch& pp = patches[patchi];
newPatches.append
(
pp.clone(patches, patchi, pp.size(), pp.start()).ptr()
);
}
// Convenience function to generate patch names for the owner or neighbour
auto nccPatchNames = [&](const label i)
{
return
Pair<word>
(
cyclicNames[i] + "_on_" + patchNames[i][0],
cyclicNames[i] + "_on_" + patchNames[i][1]
);
};
// Add the cyclic patches
forAll(patchNames, i)
{
Info<< indent << "Adding "
<< nonConformalCyclicPolyPatch::typeName
<< " interfaces between patches: " << incrIndent << nl
<< indent << patchNames[i] << decrIndent << nl
<< indent << "Named:" << incrIndent << nl
<< indent << Pair<word>(nccPatchNames(i)) << decrIndent << nl
<< indent << "With transform: " << incrIndent << nl;
transforms[i].write(Info);
Info<< decrIndent << nl;
newPatches.append
(
new nonConformalCyclicPolyPatch
(
nccPatchNames(i)[0],
0,
firstProcFacei,
newPatches.size(),
patches,
nonConformalCyclicPolyPatch::typeName,
nccPatchNames(i)[1],
patchNames[i][0],
transforms[i]
)
);
newPatches.append
(
new nonConformalCyclicPolyPatch
(
nccPatchNames(i)[1],
0,
firstProcFacei,
newPatches.size(),
patches,
nonConformalCyclicPolyPatch::typeName,
nccPatchNames(i)[0],
patchNames[i][1],
inv(transforms[i])
)
);
}
// Add the error patches. Note there is only one for each source patch,
// regardless of how many interfaces are attached to that patch.
auto appendErrorPatches = [&](const bool owner)
{
wordHashSet patchANames;
forAll(patchNames, i)
{
patchANames.insert(patchNames[i][!owner]);
}
forAllConstIter(wordHashSet, patchANames, iter)
{
newPatches.append
(
new nonConformalErrorPolyPatch
(
nonConformalErrorPolyPatch::typeName + "_on_" + iter.key(),
0,
firstProcFacei,
newPatches.size(),
patches,
nonConformalErrorPolyPatch::typeName,
iter.key()
)
);
}
};
appendErrorPatches(true);
appendErrorPatches(false);
// Clone the processor patches
for (label patchi = firstProcPatchi; patchi < patches.size(); ++ patchi)
{
const polyPatch& pp = patches[patchi];
newPatches.append
(
pp.clone(patches, newPatches.size(), pp.size(), pp.start()).ptr()
);
}
// Add the processor cyclic patches
if (Pstream::parRun())
{
forAll(patchNames, i)
{
const polyPatch& patch1 = patches[patchNames[i][0]];
const polyPatch& patch2 = patches[patchNames[i][1]];
boolList procHasPatch1(Pstream::nProcs(), false);
procHasPatch1[Pstream::myProcNo()] = !patch1.empty();
Pstream::gatherList(procHasPatch1);
Pstream::scatterList(procHasPatch1);
boolList procHasPatch2(Pstream::nProcs(), false);
procHasPatch2[Pstream::myProcNo()] = !patch2.empty();
Pstream::gatherList(procHasPatch2);
Pstream::scatterList(procHasPatch2);
// Multiple cyclic interfaces must be ordered in a specific way for
// processor communication to function correctly.
//
// A communication that is sent from the cyclic owner is received
// on the cyclic neighbour and vice versa. Therefore, in a coupled
// pair of processors if one sends the owner first the other must
// receive the neighbour first.
//
// We ensure the above by ordering the patches so that for the
// lower indexed processor the owner interface comes first, and for
// the higher indexed processor the neighbour comes first.
auto appendProcPatches = [&](const bool owner, const bool first)
{
const boolList& procHasPatchA =
owner ? procHasPatch1 : procHasPatch2;
const boolList& procHasPatchB =
owner ? procHasPatch2 : procHasPatch1;
if (procHasPatchA[Pstream::myProcNo()])
{
forAll(procHasPatchB, proci)
{
if
(
(
(first && proci < Pstream::myProcNo())
|| (!first && proci > Pstream::myProcNo())
)
&& procHasPatchB[proci]
)
{
newPatches.append
(
new nonConformalProcessorCyclicPolyPatch
(
0,
mesh.nFaces(),
newPatches.size(),
patches,
Pstream::myProcNo(),
proci,
nccPatchNames(i)[!owner],
patchNames[i][!owner]
)
);
}
}
}
};
appendProcPatches(true, true);
appendProcPatches(false, true);
appendProcPatches(false, false);
appendProcPatches(true, false);
}
}
// Re-patch the mesh
mesh.removeFvBoundary();
mesh.addFvPatches(newPatches);
}
int main(int argc, char *argv[])
{
#include "addOverwriteOption.H"
#include "addRegionOption.H"
#include "addDictOption.H"
const bool haveArgs = argList::hasArgs(argc, argv);
if (haveArgs)
{
argList::validArgs.append("patch1");
argList::validArgs.append("patch2");
}
#include "setRootCase.H"
#include "createTime.H"
runTime.functionObjects().off();
// Get the patches between which to create interfaces and the associated
// transformations. If there are arguments then read the patch names from
// the arguments and assume an identity transformation. If not, then load
// the system dictionary and read potentially multiple pairs of patches and
// associated transformations.
List<Pair<word>> patchNames;
wordList cyclicNames;
List<cyclicTransform> transforms;
if (haveArgs)
{
patchNames.append(Pair<word>(args[1], args[2]));
cyclicNames.append(nonConformalCyclicPolyPatch::typeName);
transforms.append(cyclicTransform(true));
}
else
{
static const word dictName("createNonConformalCouplesDict");
IOdictionary dict(systemDict(dictName, args, runTime));
forAllConstIter(dictionary, dict, iter)
{
patchNames.append(iter().dict().lookup<Pair<word>>("patches"));
cyclicNames.append(iter().dict().dictName());
transforms.append(cyclicTransform(iter().dict(), true));
}
}
Foam::word meshRegionName = polyMesh::defaultRegion;
args.optionReadIfPresent("region", meshRegionName);
const bool overwrite = args.optionFound("overwrite");
#include "createNamedMesh.H"
const word oldInstance = mesh.pointsInstance();
// Make sure the mesh is not connected before couples are added
fvMeshStitchers::stationary stitcher(mesh);
stitcher.disconnect(false, false);
createNonConformalCouples
(
mesh,
patchNames,
cyclicNames,
transforms
);
// Connect the mesh so that the new stitching topology gets written out
stitcher.connect(false, false);
mesh.setInstance(runTime.timeName());
// Set the precision of the points data to 10
IOstream::defaultPrecision(max(10u, IOstream::defaultPrecision()));
if (!overwrite)
{
runTime++;
}
else
{
mesh.setInstance(oldInstance);
}
// Write resulting mesh
Info<< "Writing mesh to " << runTime.timeName() << nl << endl;
mesh.write();
Info<< "End\n" << endl;
return 0;
}
// ************************************************************************* //

View File

@ -1,5 +1,4 @@
decomposePar.C decomposePar.C
domainDecomposition.C
dimFieldDecomposer.C dimFieldDecomposer.C
fvFieldDecomposer.C fvFieldDecomposer.C
pointFieldDecomposer.C pointFieldDecomposer.C

View File

@ -1,14 +1,16 @@
EXE_INC = \ EXE_INC = \
-I$(LIB_SRC)/parallel/decompose/decompositionMethods/lnInclude \
-I$(LIB_SRC)/finiteVolume/lnInclude \ -I$(LIB_SRC)/finiteVolume/lnInclude \
-I$(LIB_SRC)/dynamicMesh/lnInclude \
-I$(LIB_SRC)/lagrangian/basic/lnInclude \
-I$(LIB_SRC)/meshTools/lnInclude \ -I$(LIB_SRC)/meshTools/lnInclude \
-I$(LIB_SRC)/parallel/parallel/lnInclude \
-I$(LIB_SRC)/parallel/decompose/decompositionMethods/lnInclude \
-I$(LIB_SRC)/lagrangian/basic/lnInclude \
-I$(LIB_SRC)/regionModels/regionModel/lnInclude -I$(LIB_SRC)/regionModels/regionModel/lnInclude
EXE_LIBS = \ EXE_LIBS = \
-ldynamicMesh \ -lfiniteVolume \
-lgenericPatchFields \ -lmeshTools\
-ldecompositionMethods -L$(FOAM_LIBBIN)/dummy -lmetisDecomp -lscotchDecomp \ -lparallel \
-ldecompositionMethods \
-llagrangian \ -llagrangian \
-lregionModels -lregionModels \
-lgenericPatchFields

View File

@ -79,6 +79,7 @@ Usage
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#include "processorRunTimes.H"
#include "domainDecomposition.H" #include "domainDecomposition.H"
#include "decompositionMethod.H" #include "decompositionMethod.H"
#include "argList.H" #include "argList.H"
@ -114,14 +115,12 @@ namespace Foam
void decomposeUniform void decomposeUniform
( (
const bool copyUniform, const bool copyUniform,
const domainDecomposition& decomposition, const bool distributeUniform,
const Time& processorDb, const Time& runTime,
const Time& procRunTime,
const word& regionDir = word::null const word& regionDir = word::null
) )
{ {
const Time& runTime = decomposition.mesh().time();
// Any uniform data to copy/link?
const fileName uniformDir(regionDir/"uniform"); const fileName uniformDir(regionDir/"uniform");
if (fileHandler().isDir(runTime.timePath()/uniformDir)) if (fileHandler().isDir(runTime.timePath()/uniformDir))
@ -131,9 +130,9 @@ void decomposeUniform
<< endl; << endl;
const fileName timePath = const fileName timePath =
fileHandler().filePath(processorDb.timePath()); fileHandler().filePath(procRunTime.timePath());
if (copyUniform || decomposition.distributed()) if (copyUniform || distributeUniform)
{ {
if (!fileHandler().exists(timePath/uniformDir)) if (!fileHandler().exists(timePath/uniformDir))
{ {
@ -171,9 +170,9 @@ void decomposeUniform
} }
void writeDecomposition(const domainDecomposition& decomposition) void writeDecomposition(const domainDecomposition& meshes)
{ {
const labelList& procIds = decomposition.cellToProc(); const labelList& procIds = meshes.cellToProc();
// Write the decomposition as labelList for use with 'manual' // Write the decomposition as labelList for use with 'manual'
// decomposition method. // decomposition method.
@ -182,8 +181,8 @@ void writeDecomposition(const domainDecomposition& decomposition)
IOobject IOobject
( (
"cellDecomposition", "cellDecomposition",
decomposition.mesh().facesInstance(), meshes.completeMesh().facesInstance(),
decomposition.mesh(), meshes.completeMesh(),
IOobject::NO_READ, IOobject::NO_READ,
IOobject::NO_WRITE, IOobject::NO_WRITE,
false false
@ -203,12 +202,12 @@ void writeDecomposition(const domainDecomposition& decomposition)
IOobject IOobject
( (
"cellDist", "cellDist",
decomposition.mesh().time().timeName(), meshes.completeMesh().time().timeName(),
decomposition.mesh(), meshes.completeMesh(),
IOobject::NO_READ, IOobject::NO_READ,
IOobject::AUTO_WRITE IOobject::AUTO_WRITE
), ),
decomposition.mesh(), meshes.completeMesh(),
dimless, dimless,
scalarField(scalarList(procIds)) scalarField(scalarList(procIds))
); );
@ -309,18 +308,20 @@ int main(int argc, char *argv[])
} }
// Set time from database // Set time from database
#include "createTime.H" Info<< "Create time\n" << endl;
processorRunTimes runTimes(Foam::Time::controlDictName, args);
// Allow override of time // Allow override of time
instantList times = timeSelector::selectIfPresent(runTime, args); const instantList times = runTimes.selectComplete(args);
// Get region names // Get region names
const wordList regionNames(selectRegionNames(args, runTime)); const wordList regionNames =
selectRegionNames(args, runTimes.completeTime());
// Handle existing decomposition directories // Handle existing decomposition directories
{ {
// Determine the processor count from the directories // Determine the processor count from the directories
label nProcs = fileHandler().nProcs(runTime.path()); label nProcs = fileHandler().nProcs(runTimes.completeTime().path());
if (forceOverwrite) if (forceOverwrite)
{ {
@ -339,7 +340,7 @@ int main(int argc, char *argv[])
( (
fileHandler().readDir fileHandler().readDir
( (
runTime.path(), runTimes.completeTime().path(),
fileType::directory fileType::directory
) )
); );
@ -379,12 +380,17 @@ int main(int argc, char *argv[])
<< " domains, use the -force option or manually" << nl << " domains, use the -force option or manually" << nl
<< "remove processor directories before decomposing. e.g.," << "remove processor directories before decomposing. e.g.,"
<< nl << nl
<< " rm -rf " << runTime.path().c_str() << "/processor*" << " rm -rf " << runTimes.completeTime().path().c_str()
<< "/processor*"
<< nl << nl
<< exit(FatalError); << exit(FatalError);
} }
} }
// Get the decomposition dictionary
const dictionary decomposeParDict =
decompositionMethod::decomposeParDict(runTimes.completeTime());
// Decompose all regions // Decompose all regions
forAll(regionNames, regioni) forAll(regionNames, regioni)
{ {
@ -394,12 +400,12 @@ int main(int argc, char *argv[])
Info<< "\n\nDecomposing mesh " << regionName << nl << endl; Info<< "\n\nDecomposing mesh " << regionName << nl << endl;
// Determine the existing processor count directly // Determine the existing processor count directly
label nProcs = fileHandler().nProcs(runTime.path(), regionDir); const label nProcs =
fileHandler().nProcs(runTimes.completeTime().path(), regionDir);
// Get requested numberOfSubdomains // Get requested numberOfSubdomains
const label nDomains = const label nDomains =
decompositionMethod::decomposeParDict(runTime) decomposeParDict.lookup<label>("numberOfSubdomains");
.lookup<label>("numberOfSubdomains");
// Give file handler a chance to determine the output directory // Give file handler a chance to determine the output directory
const_cast<fileOperation&>(fileHandler()).setNProcs(nDomains); const_cast<fileOperation&>(fileHandler()).setNProcs(nDomains);
@ -421,74 +427,70 @@ int main(int argc, char *argv[])
Info<< "Using existing processor directories" << nl; Info<< "Using existing processor directories" << nl;
} }
Info<< "Create mesh" << endl; // Get flag to determine whether or not to distribute uniform data
fvMesh mesh const label distributeUniform =
( decomposeParDict.lookupOrDefault<bool>("distributed", false);
IOobject
(
regionName,
runTime.timeName(),
runTime,
IOobject::NO_READ,
IOobject::NO_WRITE,
false
),
false
);
// Create decomposition // Create meshes
domainDecomposition decomposition(mesh); Info<< "Create mesh" << endl;
domainDecomposition meshes(runTimes, regionName);
meshes.readComplete();
// Read or generate a decomposition as necessary // Read or generate a decomposition as necessary
if (decomposeFieldsOnly) if (decomposeFieldsOnly)
{ {
decomposition.read(); meshes.readProcs();
if (!copyZero)
{
meshes.readAddressing();
meshes.readUpdate();
}
} }
else else
{ {
decomposition.decompose(); meshes.decompose();
decomposition.write(decomposeSets); meshes.writeProcs(decomposeSets);
if (writeCellDist) if (writeCellDist) writeDecomposition(meshes);
{
writeDecomposition(decomposition);
}
fileHandler().flush(); fileHandler().flush();
} }
// Field maps. These are preserved if decomposing multiple times. // Field maps. These are preserved if decomposing multiple times.
PtrList<fvFieldDecomposer> fieldDecomposerList PtrList<fvFieldDecomposer> fieldDecomposerList
( (
decomposition.nProcs() meshes.nProcs()
); );
PtrList<dimFieldDecomposer> dimFieldDecomposerList PtrList<dimFieldDecomposer> dimFieldDecomposerList
( (
decomposition.nProcs() meshes.nProcs()
); );
PtrList<pointFieldDecomposer> pointFieldDecomposerList PtrList<pointFieldDecomposer> pointFieldDecomposerList
( (
decomposition.nProcs() meshes.nProcs()
); );
// Loop over all times // Loop over all times
forAll(times, timeI) forAll(times, timeI)
{ {
// Set the time // Set the time
runTime.setTime(times[timeI], timeI); runTimes.setTime(times[timeI], timeI);
decomposition.setTime(times[timeI], timeI);
Info<< "Time = " << runTime.userTimeName() << endl; Info<< "Time = " << runTimes.completeTime().userTimeName() << endl;
// Update the mesh // Update the meshes, if necessary
const fvMesh::readUpdateState state = mesh.readUpdate(); fvMesh::readUpdateState state = fvMesh::UNCHANGED;
if (!decomposeFieldsOnly || !copyZero)
{
state = meshes.readUpdate();
}
// Update the decomposition // Write the mesh out, if necessary
if (decomposeFieldsOnly) if (decomposeFieldsOnly)
{ {
decomposition.readUpdate(); // Nothing to do
} }
else if (state == fvMesh::POINTS_MOVED) else if (state == fvMesh::POINTS_MOVED)
{ {
decomposition.writePoints(); meshes.writeProcs(false);
} }
else if else if
( (
@ -496,12 +498,9 @@ int main(int argc, char *argv[])
|| state == fvMesh::TOPO_PATCH_CHANGE || state == fvMesh::TOPO_PATCH_CHANGE
) )
{ {
decomposition.decompose(); meshes.writeProcs(decomposeSets);
decomposition.write(decomposeSets); if (writeCellDist) writeDecomposition(meshes);
if (writeCellDist) fileHandler().flush();
{
writeDecomposition(decomposition);
}
} }
// Clear the field maps if there has been topology change // Clear the field maps if there has been topology change
@ -511,7 +510,7 @@ int main(int argc, char *argv[])
|| state == fvMesh::TOPO_PATCH_CHANGE || state == fvMesh::TOPO_PATCH_CHANGE
) )
{ {
for (label proci = 0; proci < decomposition.nProcs(); proci++) for (label proci = 0; proci < meshes.nProcs(); proci++)
{ {
fieldDecomposerList.set(proci, nullptr); fieldDecomposerList.set(proci, nullptr);
dimFieldDecomposerList.set(proci, nullptr); dimFieldDecomposerList.set(proci, nullptr);
@ -528,43 +527,38 @@ int main(int argc, char *argv[])
{ {
// Copy the field files from the <time> directory to the // Copy the field files from the <time> directory to the
// processor*/<time> directories without altering them // processor*/<time> directories without altering them
const fileName completeTimePath =
runTimes.completeTime().timePath();
fileName prevTimePath; fileName prevProcTimePath;
for (label proci = 0; proci < decomposition.nProcs(); proci++) for (label proci = 0; proci < meshes.nProcs(); proci++)
{ {
Time processorDb const Time& procRunTime =
( meshes.procMeshes()[proci].time();
Time::controlDictName,
args.rootPath(),
args.caseName()
/fileName(word("processor") + name(proci))
);
processorDb.setTime(runTime);
if (fileHandler().isDir(runTime.timePath())) if (fileHandler().isDir(completeTimePath))
{ {
const fileName timePath const fileName procTimePath
( (
fileHandler().objectPath fileHandler().objectPath
( (
IOobject IOobject
( (
"", "",
processorDb.timeName(), procRunTime.timeName(),
processorDb procRunTime
), ),
word::null word::null
) )
); );
if (timePath != prevTimePath) if (procTimePath != prevProcTimePath)
{ {
Info<< "Processor " << proci Info<< "Processor " << proci
<< ": copying " << runTime.timePath() << nl << ": copying " << completeTimePath << nl
<< " to " << timePath << endl; << " to " << procTimePath << endl;
fileHandler().cp(runTime.timePath(), timePath); fileHandler().cp(completeTimePath, procTimePath);
prevProcTimePath = procTimePath;
prevTimePath = timePath;
} }
} }
} }
@ -574,49 +568,73 @@ int main(int argc, char *argv[])
// Decompose the fields // Decompose the fields
// Search for list of objects for this time // Search for list of objects for this time
IOobjectList objects(mesh, runTime.timeName()); IOobjectList objects
(
meshes.completeMesh(),
runTimes.completeTime().timeName()
);
// Construct the vol fields // Construct the vol fields
PtrList<volScalarField> volScalarFields; PtrList<volScalarField> volScalarFields;
readFields(mesh, objects, volScalarFields); readFields(meshes.completeMesh(), objects, volScalarFields);
PtrList<volVectorField> volVectorFields; PtrList<volVectorField> volVectorFields;
readFields(mesh, objects, volVectorFields); readFields(meshes.completeMesh(), objects, volVectorFields);
PtrList<volSphericalTensorField> volSphericalTensorFields; PtrList<volSphericalTensorField> volSphericalTensorFields;
readFields(mesh, objects, volSphericalTensorFields); readFields
(
meshes.completeMesh(),
objects,
volSphericalTensorFields
);
PtrList<volSymmTensorField> volSymmTensorFields; PtrList<volSymmTensorField> volSymmTensorFields;
readFields(mesh, objects, volSymmTensorFields); readFields(meshes.completeMesh(), objects, volSymmTensorFields);
PtrList<volTensorField> volTensorFields; PtrList<volTensorField> volTensorFields;
readFields(mesh, objects, volTensorFields); readFields(meshes.completeMesh(), objects, volTensorFields);
// Construct the dimensioned fields // Construct the dimensioned fields
PtrList<DimensionedField<scalar, volMesh>> dimScalarFields; PtrList<DimensionedField<scalar, volMesh>> dimScalarFields;
readFields(mesh, objects, dimScalarFields); readFields(meshes.completeMesh(), objects, dimScalarFields);
PtrList<DimensionedField<vector, volMesh>> dimVectorFields; PtrList<DimensionedField<vector, volMesh>> dimVectorFields;
readFields(mesh, objects, dimVectorFields); readFields(meshes.completeMesh(), objects, dimVectorFields);
PtrList<DimensionedField<sphericalTensor, volMesh>> PtrList<DimensionedField<sphericalTensor, volMesh>>
dimSphericalTensorFields; dimSphericalTensorFields;
readFields(mesh, objects, dimSphericalTensorFields); readFields
(
meshes.completeMesh(),
objects,
dimSphericalTensorFields
);
PtrList<DimensionedField<symmTensor, volMesh>> PtrList<DimensionedField<symmTensor, volMesh>>
dimSymmTensorFields; dimSymmTensorFields;
readFields(mesh, objects, dimSymmTensorFields); readFields(meshes.completeMesh(), objects, dimSymmTensorFields);
PtrList<DimensionedField<tensor, volMesh>> dimTensorFields; PtrList<DimensionedField<tensor, volMesh>> dimTensorFields;
readFields(mesh, objects, dimTensorFields); readFields(meshes.completeMesh(), objects, dimTensorFields);
// Construct the surface fields // Construct the surface fields
PtrList<surfaceScalarField> surfaceScalarFields; PtrList<surfaceScalarField> surfaceScalarFields;
readFields(mesh, objects, surfaceScalarFields); readFields(meshes.completeMesh(), objects, surfaceScalarFields);
PtrList<surfaceVectorField> surfaceVectorFields; PtrList<surfaceVectorField> surfaceVectorFields;
readFields(mesh, objects, surfaceVectorFields); readFields(meshes.completeMesh(), objects, surfaceVectorFields);
PtrList<surfaceSphericalTensorField> PtrList<surfaceSphericalTensorField>
surfaceSphericalTensorFields; surfaceSphericalTensorFields;
readFields(mesh, objects, surfaceSphericalTensorFields); readFields
(
meshes.completeMesh(),
objects,
surfaceSphericalTensorFields
);
PtrList<surfaceSymmTensorField> surfaceSymmTensorFields; PtrList<surfaceSymmTensorField> surfaceSymmTensorFields;
readFields(mesh, objects, surfaceSymmTensorFields); readFields
(
meshes.completeMesh(),
objects,
surfaceSymmTensorFields
);
PtrList<surfaceTensorField> surfaceTensorFields; PtrList<surfaceTensorField> surfaceTensorFields;
readFields(mesh, objects, surfaceTensorFields); readFields(meshes.completeMesh(), objects, surfaceTensorFields);
// Construct the point fields // Construct the point fields
const pointMesh& pMesh = pointMesh::New(mesh); const pointMesh& pMesh = pointMesh::New(meshes.completeMesh());
PtrList<pointScalarField> pointScalarFields; PtrList<pointScalarField> pointScalarFields;
readFields(pMesh, objects, pointScalarFields); readFields(pMesh, objects, pointScalarFields);
PtrList<pointVectorField> pointVectorFields; PtrList<pointVectorField> pointVectorFields;
@ -633,7 +651,7 @@ int main(int argc, char *argv[])
( (
fileHandler().readDir fileHandler().readDir
( (
runTime.timePath()/cloud::prefix, runTimes.completeTime().timePath()/cloud::prefix,
fileType::directory fileType::directory
) )
); );
@ -672,8 +690,8 @@ int main(int argc, char *argv[])
{ {
IOobjectList sprayObjs IOobjectList sprayObjs
( (
mesh, meshes.completeMesh(),
runTime.timeName(), runTimes.completeTime().timeName(),
cloud::prefix/cloudDirs[i], cloud::prefix/cloudDirs[i],
IOobject::MUST_READ, IOobject::MUST_READ,
IOobject::NO_WRITE, IOobject::NO_WRITE,
@ -695,7 +713,7 @@ int main(int argc, char *argv[])
cloudI, cloudI,
new Cloud<indexedParticle> new Cloud<indexedParticle>
( (
mesh, meshes.completeMesh(),
cloudDirs[i], cloudDirs[i],
false false
) )
@ -707,7 +725,7 @@ int main(int argc, char *argv[])
cloudI, cloudI,
new List<SLList<indexedParticle*>*> new List<SLList<indexedParticle*>*>
( (
mesh.nCells(), meshes.completeMesh().nCells(),
static_cast<SLList<indexedParticle*>*>(nullptr) static_cast<SLList<indexedParticle*>*>(nullptr)
) )
); );
@ -726,7 +744,11 @@ int main(int argc, char *argv[])
label celli = iter().cell(); label celli = iter().cell();
// Check // Check
if (celli < 0 || celli >= mesh.nCells()) if
(
celli < 0
|| celli >= meshes.completeMesh().nCells()
)
{ {
FatalErrorInFunction FatalErrorInFunction
<< "Illegal cell number " << celli << "Illegal cell number " << celli
@ -735,10 +757,11 @@ int main(int argc, char *argv[])
<< " at position " << " at position "
<< iter().position() << nl << iter().position() << nl
<< "Cell number should be between 0 and " << "Cell number should be between 0 and "
<< mesh.nCells()-1 << nl << meshes.completeMesh().nCells()-1 << nl
<< "On this mesh the particle should" << "On this mesh the particle should"
<< " be in cell " << " be in cell "
<< mesh.findCell(iter().position()) << meshes.completeMesh().findCell
(iter().position())
<< exit(FatalError); << exit(FatalError);
} }
@ -754,8 +777,8 @@ int main(int argc, char *argv[])
// Read fields // Read fields
IOobjectList lagrangianObjects IOobjectList lagrangianObjects
( (
mesh, meshes.completeMesh(),
runTime.timeName(), runTimes.completeTime().timeName(),
cloud::prefix/cloudDirs[cloudI], cloud::prefix/cloudDirs[cloudI],
IOobject::MUST_READ, IOobject::MUST_READ,
IOobject::NO_WRITE, IOobject::NO_WRITE,
@ -856,7 +879,7 @@ int main(int argc, char *argv[])
Info<< endl; Info<< endl;
// split the fields over processors // split the fields over processors
for (label proci = 0; proci < decomposition.nProcs(); proci++) for (label proci = 0; proci < meshes.nProcs(); proci++)
{ {
Info<< "Processor " << proci << ": field transfer" << endl; Info<< "Processor " << proci << ": field transfer" << endl;
@ -869,10 +892,11 @@ int main(int argc, char *argv[])
proci, proci,
new fvFieldDecomposer new fvFieldDecomposer
( (
mesh, meshes.completeMesh(),
decomposition.procMeshes()[proci], meshes.procMeshes()[proci],
decomposition.procFaceAddressing()[proci], meshes.procFaceAddressing()[proci],
decomposition.procCellAddressing()[proci] meshes.procCellAddressing()[proci],
meshes.procFaceAddressingBf()[proci]
) )
); );
} }
@ -916,10 +940,10 @@ int main(int argc, char *argv[])
proci, proci,
new dimFieldDecomposer new dimFieldDecomposer
( (
mesh, meshes.completeMesh(),
decomposition.procMeshes()[proci], meshes.procMeshes()[proci],
decomposition.procFaceAddressing()[proci], meshes.procFaceAddressing()[proci],
decomposition.procCellAddressing()[proci] meshes.procCellAddressing()[proci]
) )
); );
} }
@ -949,7 +973,7 @@ int main(int argc, char *argv[])
) )
{ {
const pointMesh& procPMesh = const pointMesh& procPMesh =
pointMesh::New(decomposition.procMeshes()[proci]); pointMesh::New(meshes.procMeshes()[proci]);
if (!pointFieldDecomposerList.set(proci)) if (!pointFieldDecomposerList.set(proci))
{ {
@ -960,7 +984,7 @@ int main(int argc, char *argv[])
( (
pMesh, pMesh,
procPMesh, procPMesh,
decomposition.procPointAddressing()[proci] meshes.procPointAddressing()[proci]
) )
); );
} }
@ -989,10 +1013,10 @@ int main(int argc, char *argv[])
{ {
lagrangianFieldDecomposer fieldDecomposer lagrangianFieldDecomposer fieldDecomposer
( (
mesh, meshes.completeMesh(),
decomposition.procMeshes()[proci], meshes.procMeshes()[proci],
decomposition.procFaceAddressing()[proci], meshes.procFaceAddressing()[proci],
decomposition.procCellAddressing()[proci], meshes.procCellAddressing()[proci],
cloudDirs[cloudI], cloudDirs[cloudI],
lagrangianPositions[cloudI], lagrangianPositions[cloudI],
cellParticles[cloudI] cellParticles[cloudI]
@ -1069,8 +1093,9 @@ int main(int argc, char *argv[])
decomposeUniform decomposeUniform
( (
copyUniform, copyUniform,
decomposition, distributeUniform,
decomposition.procMeshes()[proci].time(), runTimes.completeTime(),
meshes.procMeshes()[proci].time(),
regionDir regionDir
); );
@ -1082,8 +1107,9 @@ int main(int argc, char *argv[])
decomposeUniform decomposeUniform
( (
copyUniform, copyUniform,
decomposition, distributeUniform,
decomposition.procMeshes()[proci].time() runTimes.completeTime(),
meshes.procMeshes()[proci].time()
); );
} }
} }

View File

@ -25,95 +25,38 @@ License
#include "fvFieldDecomposer.H" #include "fvFieldDecomposer.H"
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
Foam::labelList Foam::fvFieldDecomposer::patchFieldDecomposer::alignAddressing Foam::label Foam::fvFieldDecomposer::completePatchID
( (
const labelUList& addressingSlice, const label procPatchi
const label addressingOffset
) const ) const
{ {
labelList addressing(addressingSlice.size()); const fvPatch& procPatch = procMesh_.boundary()[procPatchi];
forAll(addressing, i) if (procPatchi < completeMesh_.boundary().size())
{ {
// Subtract one to align addressing. return procPatchi;
addressing[i] = addressingSlice[i] - (addressingOffset + 1); }
else if (isA<processorCyclicFvPatch>(procPatch))
{
return refCast<const processorCyclicFvPatch>(procPatch).referPatchID();
}
else
{
return -1;
}
} }
return addressing;
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::fvFieldDecomposer::patchFieldDecomposer::patchFieldDecomposer Foam::fvFieldDecomposer::patchFieldDecomposer::patchFieldDecomposer
( (
const labelUList& addressingSlice, const labelUList& addressing
const label addressingOffset
) )
: :
labelList(alignAddressing(addressingSlice, addressingOffset)), labelList(mag(addressing) - 1),
directFvPatchFieldMapper(static_cast<const labelList&>(*this))
{}
Foam::labelList Foam::fvFieldDecomposer::processorVolPatchFieldDecomposer::
alignAddressing
(
const fvMesh& mesh,
const labelUList& addressingSlice
) const
{
labelList addressing(addressingSlice.size());
const labelList& own = mesh.faceOwner();
const labelList& neighb = mesh.faceNeighbour();
forAll(addressing, i)
{
// Subtract one to align addressing.
label ai = mag(addressingSlice[i]) - 1;
if (ai < neighb.size())
{
// This is a regular face. it has been an internal face
// of the original mesh and now it has become a face
// on the parallel boundary.
// Give face the value of the neighbour.
if (addressingSlice[i] >= 0)
{
// I have the owner so use the neighbour value
addressing[i] = neighb[ai];
}
else
{
addressing[i] = own[ai];
}
}
else
{
// This is a face that used to be on a cyclic boundary
// but has now become a parallel patch face. I cannot
// do the interpolation properly (I would need to look
// up the different (face) list of data), so I will
// just grab the value from the owner cell
addressing[i] = own[ai];
}
}
return addressing;
}
Foam::fvFieldDecomposer::processorVolPatchFieldDecomposer::
processorVolPatchFieldDecomposer
(
const fvMesh& mesh,
const labelUList& addressingSlice
)
:
labelList(alignAddressing(mesh, addressingSlice)),
directFvPatchFieldMapper(static_cast<const labelList&>(*this)) directFvPatchFieldMapper(static_cast<const labelList&>(*this))
{} {}
@ -123,34 +66,22 @@ Foam::fvFieldDecomposer::fvFieldDecomposer
const fvMesh& completeMesh, const fvMesh& completeMesh,
const fvMesh& procMesh, const fvMesh& procMesh,
const labelList& faceAddressing, const labelList& faceAddressing,
const labelList& cellAddressing const labelList& cellAddressing,
const surfaceLabelField::Boundary& faceAddressingBf
) )
: :
completeMesh_(completeMesh), completeMesh_(completeMesh),
procMesh_(procMesh), procMesh_(procMesh),
faceAddressing_(faceAddressing), faceAddressing_(faceAddressing),
cellAddressing_(cellAddressing), cellAddressing_(cellAddressing),
patchFieldDecomposers_(procMesh_.boundary().size()), faceAddressingBf_(faceAddressingBf),
processorVolPatchFieldDecomposers_(procMesh_.boundary().size()) patchFieldDecomposers_(procMesh_.boundary().size())
{ {
forAll(procMesh_.boundary(), procPatchi) forAll(procMesh_.boundary(), procPatchi)
{ {
const fvPatch& procPatch = procMesh.boundary()[procPatchi]; const label completePatchi = completePatchID(procPatchi);
// Determine the index of the corresponding complete patch // If there is a corresponding complete patch then create a patch mapper
label completePatchi = -1;
if (procPatchi < completeMesh_.boundary().size())
{
completePatchi = procPatchi;
}
else if (isA<processorCyclicFvPatch>(procPatch))
{
completePatchi =
refCast<const processorCyclicPolyPatch>
(procPatch.patch()).referPatchID();
}
// If there is a corresponding complete patch, then create a mapper
if (completePatchi >= 0) if (completePatchi >= 0)
{ {
patchFieldDecomposers_.set patchFieldDecomposers_.set
@ -158,22 +89,7 @@ Foam::fvFieldDecomposer::fvFieldDecomposer
procPatchi, procPatchi,
new patchFieldDecomposer new patchFieldDecomposer
( (
procPatch.patchSlice(faceAddressing_), faceAddressingBf[completePatchi]
completeMesh_.boundaryMesh()[completePatchi].start()
)
);
}
// If this is a processor patch then create a processor mapper
if (procPatchi >= completeMesh_.boundary().size())
{
processorVolPatchFieldDecomposers_.set
(
procPatchi,
new processorVolPatchFieldDecomposer
(
completeMesh_,
procPatch.patchSlice(faceAddressing_)
) )
); );
} }

View File

@ -63,52 +63,12 @@ public:
public labelList, public labelList,
public directFvPatchFieldMapper public directFvPatchFieldMapper
{ {
// Private Member Functions
labelList alignAddressing
(
const labelUList& addressingSlice,
const label addressingOffset
) const;
public: public:
// Constructors // Constructors
//- Construct given addressing //- Construct given addressing
patchFieldDecomposer patchFieldDecomposer(const labelUList& addressing);
(
const labelUList& addressingSlice,
const label addressingOffset
);
};
//- Processor patch field decomposer class. Maps either owner or
// neighbour data (no interpolate anymore - processorFvPatchField
// holds neighbour data)
class processorVolPatchFieldDecomposer
:
public labelList,
public directFvPatchFieldMapper
{
// Private Member Functions
labelList alignAddressing
(
const fvMesh& mesh,
const labelUList& addressingSlice
) const;
public:
//- Construct given addressing
processorVolPatchFieldDecomposer
(
const fvMesh& mesh,
const labelUList& addressingSlice
);
}; };
@ -128,23 +88,35 @@ private:
//- Reference to cell addressing //- Reference to cell addressing
const labelList& cellAddressing_; const labelList& cellAddressing_;
//- Reference to face addressing boundary field
const surfaceLabelField::Boundary& faceAddressingBf_;
//- List of patch field decomposers //- List of patch field decomposers
PtrList<patchFieldDecomposer> patchFieldDecomposers_; PtrList<patchFieldDecomposer> patchFieldDecomposers_;
//- ...
PtrList<processorVolPatchFieldDecomposer>
processorVolPatchFieldDecomposers_;
// Private Member Functions // Private Member Functions
//- Helper: map & optionally flip a (face) field //- Convert a processor patch to the corresponding complete patch index
label completePatchID(const label procPatchi) const;
//- Map cell values to faces
template<class Type> template<class Type>
static tmp<Field<Type>> mapField static tmp<Field<Type>> mapCellToFace
(
const labelUList& owner,
const labelUList& neighbour,
const Field<Type>& field,
const labelUList& addressing
);
//- Map face values to faces
template<class Type>
static tmp<Field<Type>> mapFaceToFace
( (
const Field<Type>& field, const Field<Type>& field,
const labelUList& mapAndSign, const labelUList& addressing,
const bool applyFlip const bool isFlux
); );
@ -158,7 +130,8 @@ public:
const fvMesh& completeMesh, const fvMesh& completeMesh,
const fvMesh& procMesh, const fvMesh& procMesh,
const labelList& faceAddressing, const labelList& faceAddressing,
const labelList& cellAddressing const labelList& cellAddressing,
const surfaceLabelField::Boundary& faceAddressingBf
); );
//- Disallow default bitwise copy construction //- Disallow default bitwise copy construction

View File

@ -33,35 +33,50 @@ License
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class Type> template<class Type>
Foam::tmp<Foam::Field<Type>> Foam::fvFieldDecomposer::mapField Foam::tmp<Foam::Field<Type>> Foam::fvFieldDecomposer::mapCellToFace
( (
const labelUList& owner,
const labelUList& neighbour,
const Field<Type>& field, const Field<Type>& field,
const labelUList& mapAndSign, const labelUList& addressing
const bool applyFlip
) )
{ {
tmp<Field<Type>> tfld(new Field<Type>(mapAndSign.size())); tmp<Field<Type>> tfld(new Field<Type>(addressing.size()));
Field<Type>& fld = tfld.ref(); Field<Type>& fld = tfld.ref();
if (applyFlip) forAll(addressing, i)
{ {
forAll(mapAndSign, i) fld[i] =
field
[
addressing[i] > 0
? neighbour[addressing[i] - 1]
: owner[- addressing[i] + 1]
];
}
return tfld;
}
template<class Type>
Foam::tmp<Foam::Field<Type>> Foam::fvFieldDecomposer::mapFaceToFace
(
const Field<Type>& field,
const labelUList& addressing,
const bool isFlux
)
{ {
if (mapAndSign[i] < 0) tmp<Field<Type>> tfld(new Field<Type>(addressing.size()));
Field<Type>& fld = tfld.ref();
forAll(addressing, i)
{ {
fld[i] = -field[-mapAndSign[i] - 1]; fld[i] =
} (isFlux && addressing[i] < 0 ? -1 : +1)
else *field[mag(addressing[i]) - 1];
{
fld[i] = field[mapAndSign[i] - 1];
}
}
}
else
{
// Ignore face flipping
fld.map(field, mag(mapAndSign) - 1);
} }
return tfld; return tfld;
} }
@ -74,9 +89,8 @@ Foam::fvFieldDecomposer::decomposeField
const bool allowUnknownPatchFields const bool allowUnknownPatchFields
) const ) const
{ {
// 1. Create the complete field with dummy patch fields // Create dummy patch fields
PtrList<fvPatchField<Type>> patchFields(procMesh_.boundary().size()); PtrList<fvPatchField<Type>> patchFields(procMesh_.boundary().size());
forAll(procMesh_.boundary(), procPatchi) forAll(procMesh_.boundary(), procPatchi)
{ {
patchFields.set patchFields.set
@ -91,7 +105,7 @@ Foam::fvFieldDecomposer::decomposeField
); );
} }
// Create the field for the processor // Create the processor field with the dummy patch fields
tmp<GeometricField<Type, fvPatchField, volMesh>> tresF tmp<GeometricField<Type, fvPatchField, volMesh>> tresF
( (
new GeometricField<Type, fvPatchField, volMesh> new GeometricField<Type, fvPatchField, volMesh>
@ -113,35 +127,17 @@ Foam::fvFieldDecomposer::decomposeField
); );
GeometricField<Type, fvPatchField, volMesh>& resF = tresF.ref(); GeometricField<Type, fvPatchField, volMesh>& resF = tresF.ref();
// Change the patch fields to the correct type using a mapper constructor
// 2. Change the fvPatchFields to the correct type using a mapper // (with reference to the now correct internal field)
// constructor (with reference to the now correct internal field)
typename GeometricField<Type, fvPatchField, volMesh>:: typename GeometricField<Type, fvPatchField, volMesh>::
Boundary& bf = resF.boundaryFieldRef(); Boundary& bf = resF.boundaryFieldRef();
forAll(bf, procPatchi) forAll(bf, procPatchi)
{ {
const fvPatch& procPatch = procMesh_.boundary()[procPatchi]; const fvPatch& procPatch = procMesh_.boundary()[procPatchi];
// Determine the index of the corresponding complete patch const label completePatchi = completePatchID(procPatchi);
label completePatchi = -1;
if (procPatchi < completeMesh_.boundary().size())
{
completePatchi = procPatchi;
}
else if (isA<processorCyclicFvPatch>(procPatch))
{
const label referPatchi =
refCast<const processorCyclicPolyPatch>
(procPatch.patch()).referPatchID();
if (field.boundaryField()[referPatchi].overridesConstraint())
{
completePatchi = referPatchi;
}
}
if (completePatchi != -1) if (completePatchi == procPatchi)
{ {
bf.set bf.set
( (
@ -157,6 +153,10 @@ Foam::fvFieldDecomposer::decomposeField
} }
else if (isA<processorCyclicFvPatch>(procPatch)) else if (isA<processorCyclicFvPatch>(procPatch))
{ {
const label nbrCompletePatchi =
refCast<const processorCyclicFvPatch>(procPatch)
.referPatch().nbrPatchID();
bf.set bf.set
( (
procPatchi, procPatchi,
@ -164,9 +164,12 @@ Foam::fvFieldDecomposer::decomposeField
( (
procPatch, procPatch,
resF(), resF(),
processorVolPatchFieldDecomposers_[procPatchi] mapCellToFace
( (
field.primitiveField() labelUList(),
completeMesh_.lduAddr().patchAddr(nbrCompletePatchi),
field.primitiveField(),
faceAddressingBf_[procPatchi]
) )
) )
); );
@ -180,9 +183,12 @@ Foam::fvFieldDecomposer::decomposeField
( (
procPatch, procPatch,
resF(), resF(),
processorVolPatchFieldDecomposers_[procPatchi] mapCellToFace
( (
field.primitiveField() completeMesh_.owner(),
completeMesh_.neighbour(),
field.primitiveField(),
faceAddressingBf_[procPatchi]
) )
) )
); );
@ -206,7 +212,6 @@ Foam::fvFieldDecomposer::decomposeField
} }
} }
// Create the field for the processor
return tresF; return tresF;
} }
@ -218,34 +223,14 @@ Foam::fvFieldDecomposer::decomposeField
const GeometricField<Type, fvsPatchField, surfaceMesh>& field const GeometricField<Type, fvsPatchField, surfaceMesh>& field
) const ) const
{ {
// Problem with addressing when a processor patch picks up both internal const SubList<label> faceAddressingIf
// faces and faces from cyclic boundaries. This is a bit of a hack, but (
// I cannot find a better solution without making the internal storage faceAddressing_,
// mechanism for surfaceFields correspond to the one of faces in polyMesh procMesh_.nInternalFaces()
// (i.e. using slices) );
Field<Type> allFaceField(field.mesh().nFaces());
forAll(field.primitiveField(), i) // Create dummy patch fields
{
allFaceField[i] = field.primitiveField()[i];
}
forAll(field.boundaryField(), patchi)
{
const Field<Type> & p = field.boundaryField()[patchi];
const label patchStart = field.mesh().boundaryMesh()[patchi].start();
forAll(p, i)
{
allFaceField[patchStart + i] = p[i];
}
}
// 1. Create the complete field with dummy patch fields
PtrList<fvsPatchField<Type>> patchFields(procMesh_.boundary().size()); PtrList<fvsPatchField<Type>> patchFields(procMesh_.boundary().size());
forAll(procMesh_.boundary(), procPatchi) forAll(procMesh_.boundary(), procPatchi)
{ {
patchFields.set patchFields.set
@ -260,6 +245,7 @@ Foam::fvFieldDecomposer::decomposeField
); );
} }
// Create the processor field with the dummy patch fields
tmp<GeometricField<Type, fvsPatchField, surfaceMesh>> tresF tmp<GeometricField<Type, fvsPatchField, surfaceMesh>> tresF
( (
new GeometricField<Type, fvsPatchField, surfaceMesh> new GeometricField<Type, fvsPatchField, surfaceMesh>
@ -275,14 +261,10 @@ Foam::fvFieldDecomposer::decomposeField
), ),
procMesh_, procMesh_,
field.dimensions(), field.dimensions(),
mapField mapFaceToFace
( (
field, field,
labelList::subList faceAddressingIf,
(
faceAddressing_,
procMesh_.nInternalFaces()
),
isFlux(field) isFlux(field)
), ),
patchFields patchFields
@ -290,18 +272,17 @@ Foam::fvFieldDecomposer::decomposeField
); );
GeometricField<Type, fvsPatchField, surfaceMesh>& resF = tresF.ref(); GeometricField<Type, fvsPatchField, surfaceMesh>& resF = tresF.ref();
// Change the patch fields to the correct type using a mapper constructor
// 2. Change the fvsPatchFields to the correct type using a mapper // (with reference to the now correct internal field)
// constructor (with reference to the now correct internal field)
typename GeometricField<Type, fvsPatchField, surfaceMesh>:: typename GeometricField<Type, fvsPatchField, surfaceMesh>::
Boundary& bf = resF.boundaryFieldRef(); Boundary& bf = resF.boundaryFieldRef();
forAll(procMesh_.boundary(), procPatchi) forAll(procMesh_.boundary(), procPatchi)
{ {
const fvPatch& procPatch = procMesh_.boundary()[procPatchi]; const fvPatch& procPatch = procMesh_.boundary()[procPatchi];
if (procPatchi < completeMesh_.boundary().size()) const label completePatchi = completePatchID(procPatchi);
if (completePatchi == procPatchi)
{ {
bf.set bf.set
( (
@ -317,7 +298,6 @@ Foam::fvFieldDecomposer::decomposeField
} }
else if (isA<processorCyclicFvPatch>(procPatch)) else if (isA<processorCyclicFvPatch>(procPatch))
{ {
// Do our own mapping. Avoids a lot of mapping complexity.
bf.set bf.set
( (
procPatchi, procPatchi,
@ -325,10 +305,10 @@ Foam::fvFieldDecomposer::decomposeField
( (
procPatch, procPatch,
resF(), resF(),
mapField mapFaceToFace
( (
allFaceField, field.boundaryField()[completePatchi],
procPatch.patchSlice(faceAddressing_), faceAddressingBf_[procPatchi],
isFlux(field) isFlux(field)
) )
) )
@ -336,7 +316,6 @@ Foam::fvFieldDecomposer::decomposeField
} }
else if (isA<processorFvPatch>(procPatch)) else if (isA<processorFvPatch>(procPatch))
{ {
// Do our own mapping. Avoids a lot of mapping complexity.
bf.set bf.set
( (
procPatchi, procPatchi,
@ -344,10 +323,10 @@ Foam::fvFieldDecomposer::decomposeField
( (
procPatch, procPatch,
resF(), resF(),
mapField mapFaceToFace
( (
allFaceField, field.primitiveField(),
procPatch.patchSlice(faceAddressing_), faceAddressingBf_[procPatchi],
isFlux(field) isFlux(field)
) )
) )
@ -360,7 +339,6 @@ Foam::fvFieldDecomposer::decomposeField
} }
} }
// Create the field for the processor
return tresF; return tresF;
} }

View File

@ -1,3 +1,6 @@
reconstructPar.C reconstructPar.C
fvFieldReconstructor.C
pointFieldReconstructor.C
reconstructLagrangianPositions.C
EXE = $(FOAM_APPBIN)/reconstructPar EXE = $(FOAM_APPBIN)/reconstructPar

View File

@ -1,16 +1,14 @@
EXE_INC = \ EXE_INC = \
-I$(LIB_SRC)/finiteVolume/lnInclude \ -I$(LIB_SRC)/finiteVolume/lnInclude \
-I$(LIB_SRC)/lagrangian/basic/lnInclude \
-I$(LIB_SRC)/dynamicMesh/lnInclude \
-I$(LIB_SRC)/meshTools/lnInclude \ -I$(LIB_SRC)/meshTools/lnInclude \
-I$(LIB_SRC)/parallel/reconstruct/reconstruct/lnInclude \ -I$(LIB_SRC)/parallel/parallel/lnInclude \
-I$(LIB_SRC)/lagrangian/basic/lnInclude \
-I$(LIB_SRC)/regionModels/regionModel/lnInclude -I$(LIB_SRC)/regionModels/regionModel/lnInclude
EXE_LIBS = \ EXE_LIBS = \
-lfiniteVolume \ -lfiniteVolume \
-lgenericPatchFields \
-llagrangian \
-ldynamicMesh \
-lmeshTools \ -lmeshTools \
-lreconstruct \ -lparallel \
-lregionModels -llagrangian \
-lregionModels \
-lgenericPatchFields

View File

@ -1,48 +0,0 @@
{
// Foam version 2.1 changes the addressing of faces in faceProcAddressing
// The following code checks and modifies the addressing for cases where
// the decomposition has been done with the foam2.0 and earlier tools, but
// the reconstruction is attempted with version 2.1 or later
label minFaceIndex = labelMax;
PtrList<labelIOList>& faceProcAddressing = procMeshes.faceProcAddressing();
forAll(faceProcAddressing, proci)
{
const labelList& curFaceAddr = faceProcAddressing[proci];
forAll(curFaceAddr, facei)
{
if (mag(curFaceAddr[facei]) < minFaceIndex)
{
minFaceIndex = mag(curFaceAddr[facei]);
}
}
}
if (minFaceIndex < 1)
{
WarningInFunction
<< "parallel decomposition addressing." << endl
<< "It looks like you are trying to reconstruct the case "
<< "decomposed with an earlier version of FOAM, which could\n"
<< "potentially cause compatibility problems. The code will "
<< "attempt to update the addressing automatically; in case of\n"
<< "failure, please repeat the decomposition of the case using "
<< "the current version fo decomposePar"
<< endl;
forAll(faceProcAddressing, proci)
{
labelList& curFaceAddr = faceProcAddressing[proci];
forAll(curFaceAddr, facei)
{
curFaceAddr[facei] += sign(curFaceAddr[facei]);
}
faceProcAddressing[proci].write();
}
}
}

View File

@ -24,26 +24,55 @@ License
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#include "fvFieldReconstructor.H" #include "fvFieldReconstructor.H"
#include "processorCyclicFvPatch.H"
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
Foam::label Foam::fvFieldReconstructor::completePatchID
(
const label proci,
const label procPatchi
) const
{
const fvPatch& procPatch = procMeshes_[proci].boundary()[procPatchi];
if (procPatchi < completeMesh_.boundary().size())
{
return procPatchi;
}
else if (isA<processorCyclicFvPatch>(procPatch))
{
return refCast<const processorCyclicFvPatch>(procPatch).referPatchID();
}
else
{
return -1;
}
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::fvFieldReconstructor::fvFieldReconstructor Foam::fvFieldReconstructor::fvFieldReconstructor
( (
fvMesh& mesh, const fvMesh& completeMesh,
const PtrList<fvMesh>& procMeshes, const PtrList<fvMesh>& procMeshes,
const PtrList<labelIOList>& faceProcAddressing, const labelListList& faceProcAddressing,
const PtrList<labelIOList>& cellProcAddressing const labelListList& cellProcAddressing,
const PtrList<surfaceLabelField::Boundary>& faceProcAddressingBf
) )
: :
mesh_(mesh), completeMesh_(completeMesh),
procMeshes_(procMeshes), procMeshes_(procMeshes),
faceProcAddressing_(faceProcAddressing), faceProcAddressing_(faceProcAddressing),
cellProcAddressing_(cellProcAddressing), cellProcAddressing_(cellProcAddressing),
faceProcAddressingBf_(faceProcAddressingBf),
nReconstructed_(0) nReconstructed_(0)
{ {
forAll(procMeshes_, proci) forAll(procMeshes_, proci)
{ {
const fvMesh& procMesh = procMeshes_[proci]; const fvMesh& procMesh = procMeshes_[proci];
if if
( (
faceProcAddressing[proci].size() != procMesh.nFaces() faceProcAddressing[proci].size() != procMesh.nFaces()

View File

@ -37,7 +37,7 @@ SourceFiles
#define fvFieldReconstructor_H #define fvFieldReconstructor_H
#include "PtrList.H" #include "PtrList.H"
#include "fvMesh.H" #include "surfaceFields.H"
#include "IOobjectList.H" #include "IOobjectList.H"
#include "fvPatchFieldMapper.H" #include "fvPatchFieldMapper.H"
#include "setSizeFieldMapper.H" #include "setSizeFieldMapper.H"
@ -58,21 +58,40 @@ class fvFieldReconstructor
// Private Data // Private Data
//- Reconstructed mesh reference //- Reconstructed mesh reference
fvMesh& mesh_; const fvMesh& completeMesh_;
//- List of processor meshes //- List of processor meshes
const PtrList<fvMesh>& procMeshes_; const PtrList<fvMesh>& procMeshes_;
//- List of processor face addressing lists //- List of processor face addressing lists
const PtrList<labelIOList>& faceProcAddressing_; const labelListList& faceProcAddressing_;
//- List of processor cell addressing lists //- List of processor cell addressing lists
const PtrList<labelIOList>& cellProcAddressing_; const labelListList& cellProcAddressing_;
//- Boundary field of face addressing
const PtrList<surfaceLabelField::Boundary>& faceProcAddressingBf_;
//- Number of fields reconstructed //- Number of fields reconstructed
label nReconstructed_; label nReconstructed_;
// Private Member Functions
//- Convert a processor patch to the corresponding complete patch index
label completePatchID(const label proci, const label procPatchi) const;
//- ...
template<class Type>
static void rmapFaceToFace
(
Field<Type>& toField,
const Field<Type>& fromField,
const labelUList& addressing,
const bool isFlux
);
public: public:
//- Mapper for sizing only - does not do any actual mapping. //- Mapper for sizing only - does not do any actual mapping.
@ -98,10 +117,11 @@ public:
//- Construct from components //- Construct from components
fvFieldReconstructor fvFieldReconstructor
( (
fvMesh& mesh, const fvMesh& mesh,
const PtrList<fvMesh>& procMeshes, const PtrList<fvMesh>& procMeshes,
const PtrList<labelIOList>& faceProcAddressing, const labelListList& faceProcAddressing,
const PtrList<labelIOList>& cellProcAddressing const labelListList& cellProcAddressing,
const PtrList<surfaceLabelField::Boundary>& faceProcAddressingBf
); );
//- Disallow default bitwise copy construction //- Disallow default bitwise copy construction

View File

@ -30,6 +30,26 @@ License
#include "emptyFvPatch.H" #include "emptyFvPatch.H"
#include "emptyFvPatchField.H" #include "emptyFvPatchField.H"
#include "emptyFvsPatchField.H" #include "emptyFvsPatchField.H"
#include "processorCyclicFvPatch.H"
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class Type>
void Foam::fvFieldReconstructor::rmapFaceToFace
(
Field<Type>& toField,
const Field<Type>& fromField,
const labelUList& addressing,
const bool isFlux
)
{
forAll(addressing, i)
{
toField[mag(addressing[i]) - 1] =
(isFlux && addressing[i] < 0 ? -1 : +1)*fromField[i];
}
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
@ -42,7 +62,7 @@ Foam::fvFieldReconstructor::reconstructFvVolumeInternalField
) const ) const
{ {
// Create the internalField // Create the internalField
Field<Type> internalField(mesh_.nCells()); Field<Type> internalField(completeMesh_.nCells());
forAll(procMeshes_, proci) forAll(procMeshes_, proci)
{ {
@ -61,7 +81,7 @@ Foam::fvFieldReconstructor::reconstructFvVolumeInternalField
new DimensionedField<Type, volMesh> new DimensionedField<Type, volMesh>
( (
fieldIoObject, fieldIoObject,
mesh_, completeMesh_,
procFields[0].dimensions(), procFields[0].dimensions(),
internalField internalField
) )
@ -76,11 +96,8 @@ Foam::fvFieldReconstructor::reconstructFvVolumeInternalField
const IOobject& fieldIoObject const IOobject& fieldIoObject
) const ) const
{ {
// Read the field for all the processors PtrList<DimensionedField<Type, volMesh>>
PtrList<DimensionedField<Type, volMesh>> procFields procFields(procMeshes_.size());
(
procMeshes_.size()
);
forAll(procMeshes_, proci) forAll(procMeshes_, proci)
{ {
@ -103,14 +120,13 @@ Foam::fvFieldReconstructor::reconstructFvVolumeInternalField
); );
} }
return reconstructFvVolumeInternalField return reconstructFvVolumeInternalField
( (
IOobject IOobject
( (
fieldIoObject.name(), fieldIoObject.name(),
mesh_.time().timeName(), completeMesh_.time().timeName(),
mesh_, completeMesh_,
IOobject::NO_READ, IOobject::NO_READ,
IOobject::NO_WRITE, IOobject::NO_WRITE,
false false
@ -129,10 +145,10 @@ Foam::fvFieldReconstructor::reconstructFvVolumeField
) const ) const
{ {
// Create the internalField // Create the internalField
Field<Type> internalField(mesh_.nCells()); Field<Type> internalField(completeMesh_.nCells());
// Create the patch fields // Create the patch fields
PtrList<fvPatchField<Type>> patchFields(mesh_.boundary().size()); PtrList<fvPatchField<Type>> patchFields(completeMesh_.boundary().size());
forAll(procFields, proci) forAll(procFields, proci)
{ {
@ -147,150 +163,71 @@ Foam::fvFieldReconstructor::reconstructFvVolumeField
); );
// Set the boundary patch values in the reconstructed field // Set the boundary patch values in the reconstructed field
forAll(procField.boundaryField(), patchi) forAll(procField.boundaryField(), procPatchi)
{ {
// Get patch index of the original patch const fvPatch& procPatch =
const label curBPatch = procMeshes_[proci].boundary()[procPatchi];
patchi < mesh_.boundary().size() ? patchi : -1;
// Get addressing slice for this patch const label completePatchi = completePatchID(proci, procPatchi);
const labelList::subList cp =
procField.mesh().boundary()[patchi].patchSlice
(
faceProcAddressing_[proci]
);
// check if the boundary patch is not a processor patch if (completePatchi == procPatchi)
if (curBPatch != -1)
{ {
// Regular patch. Fast looping if (!patchFields(completePatchi))
if (!patchFields(curBPatch))
{ {
patchFields.set patchFields.set
( (
curBPatch, completePatchi,
fvPatchField<Type>::New fvPatchField<Type>::New
( (
procField.boundaryField()[patchi], procField.boundaryField()[procPatchi],
mesh_.boundary()[curBPatch], completeMesh_.boundary()[completePatchi],
DimensionedField<Type, volMesh>::null(), DimensionedField<Type, volMesh>::null(),
fvPatchFieldReconstructor fvPatchFieldReconstructor
( (
mesh_.boundary()[curBPatch].size() completeMesh_.boundary()[completePatchi].size()
) )
) )
); );
} }
const label curPatchStart = patchFields[completePatchi].rmap
mesh_.boundaryMesh()[curBPatch].start();
labelList reverseAddressing(cp.size());
forAll(cp, facei)
{
// Check
if (cp[facei] <= 0)
{
FatalErrorInFunction
<< "Processor " << proci
<< " patch "
<< procField.mesh().boundary()[patchi].name()
<< " face " << facei
<< " originates from reversed face since "
<< cp[facei]
<< exit(FatalError);
}
// Subtract one to take into account offsets for
// face direction.
reverseAddressing[facei] = cp[facei] - 1 - curPatchStart;
}
patchFields[curBPatch].rmap
( (
procField.boundaryField()[patchi], procField.boundaryField()[procPatchi],
reverseAddressing faceProcAddressingBf_[proci][procPatchi] - 1
); );
} }
else else if (isA<processorCyclicFvPatch>(procPatch))
{ {
const Field<Type>& curProcPatch = if (!patchFields(completePatchi))
procField.boundaryField()[patchi];
// In processor patches, there's a mix of internal faces (some
// of them turned) and possible cyclics. Slow loop
forAll(cp, facei)
{
// Subtract one to take into account offsets for
// face direction.
label curF = cp[facei] - 1;
// Is the face on the boundary?
if (curF >= mesh_.nInternalFaces())
{
label curBPatch = mesh_.boundaryMesh().whichPatch(curF);
if (!patchFields(curBPatch))
{ {
patchFields.set patchFields.set
( (
curBPatch, completePatchi,
fvPatchField<Type>::New fvPatchField<Type>::New
( (
mesh_.boundary()[curBPatch].type(), completeMesh_.boundary()[completePatchi].type(),
mesh_.boundary()[curBPatch], completeMesh_.boundary()[completePatchi],
DimensionedField<Type, volMesh>::null() DimensionedField<Type, volMesh>::null()
) )
); );
} }
// add the face patchFields[completePatchi].rmap
label curPatchFace =
mesh_.boundaryMesh()
[curBPatch].whichFace(curF);
patchFields[curBPatch][curPatchFace] =
curProcPatch[facei];
}
}
}
}
}
forAll(mesh_.boundary(), patchi)
{
// add empty patches
if
( (
isType<emptyFvPatch>(mesh_.boundary()[patchi]) procField.boundaryField()[procPatchi],
&& !patchFields(patchi) faceProcAddressingBf_[proci][procPatchi] - 1
)
{
patchFields.set
(
patchi,
fvPatchField<Type>::New
(
emptyFvPatchField<Type>::typeName,
mesh_.boundary()[patchi],
DimensionedField<Type, volMesh>::null()
)
); );
} }
} }
}
// Construct and return the field
// Now construct and write the field
// setting the internalField and patchFields
return tmp<GeometricField<Type, fvPatchField, volMesh>> return tmp<GeometricField<Type, fvPatchField, volMesh>>
( (
new GeometricField<Type, fvPatchField, volMesh> new GeometricField<Type, fvPatchField, volMesh>
( (
fieldIoObject, fieldIoObject,
mesh_, completeMesh_,
procFields[0].dimensions(), procFields[0].dimensions(),
internalField, internalField,
patchFields patchFields
@ -306,11 +243,8 @@ Foam::fvFieldReconstructor::reconstructFvVolumeField
const IOobject& fieldIoObject const IOobject& fieldIoObject
) const ) const
{ {
// Read the field for all the processors PtrList<GeometricField<Type, fvPatchField, volMesh>>
PtrList<GeometricField<Type, fvPatchField, volMesh>> procFields procFields(procMeshes_.size());
(
procMeshes_.size()
);
forAll(procMeshes_, proci) forAll(procMeshes_, proci)
{ {
@ -338,8 +272,8 @@ Foam::fvFieldReconstructor::reconstructFvVolumeField
IOobject IOobject
( (
fieldIoObject.name(), fieldIoObject.name(),
mesh_.time().timeName(), completeMesh_.time().timeName(),
mesh_, completeMesh_,
IOobject::NO_READ, IOobject::NO_READ,
IOobject::NO_WRITE, IOobject::NO_WRITE,
false false
@ -358,194 +292,105 @@ Foam::fvFieldReconstructor::reconstructFvSurfaceField
) const ) const
{ {
// Create the internalField // Create the internalField
Field<Type> internalField(mesh_.nInternalFaces()); Field<Type> internalField(completeMesh_.nInternalFaces());
// Create the patch fields // Create the patch fields
PtrList<fvsPatchField<Type>> patchFields(mesh_.boundary().size()); PtrList<fvsPatchField<Type>> patchFields(completeMesh_.boundary().size());
forAll(procMeshes_, proci) forAll(procMeshes_, proci)
{ {
const GeometricField<Type, fvsPatchField, surfaceMesh>& procField = const GeometricField<Type, fvsPatchField, surfaceMesh>& procField =
procFields[proci]; procFields[proci];
// Set the face values in the reconstructed field // Set the internal face values in the reconstructed field
rmapFaceToFace
if (pTraits<Type>::nComponents == 1)
{
// Assume all scalar surfaceFields are oriented flux fields
const labelList& faceMap = faceProcAddressing_[proci];
// Correctly oriented copy of internal field
Field<Type> procInternalField(procField.primitiveField());
// Addressing into original field
// It is necessary to create a copy of the addressing array to
// take care of the face direction offset trick.
labelList curAddr(procInternalField.size());
forAll(procInternalField, i)
{
curAddr[i] = mag(faceMap[i]) - 1;
if (faceMap[i] < 0)
{
procInternalField[i] = -procInternalField[i];
}
}
// Map
internalField.rmap(procInternalField, curAddr);
}
else
{
// Map
internalField.rmap
( (
internalField,
procField.primitiveField(), procField.primitiveField(),
mag(labelField(faceProcAddressing_[proci])) - 1 SubList<label>
(
faceProcAddressing_[proci],
procMeshes_[proci].nInternalFaces()
),
isFlux(procFields[proci])
); );
}
// Set the boundary patch values in the reconstructed field // Set the boundary patch values in the reconstructed field
forAll(procField.boundaryField(), patchi) forAll(procField.boundaryField(), procPatchi)
{ {
// Get patch index of the original patch const fvPatch& procPatch =
const label curBPatch = procMeshes_[proci].boundary()[procPatchi];
patchi < mesh_.boundary().size() ? patchi : -1;
// Get addressing slice for this patch const label completePatchi = completePatchID(proci, procPatchi);
const labelList::subList cp =
procMeshes_[proci].boundary()[patchi].patchSlice
(
faceProcAddressing_[proci]
);
// check if the boundary patch is not a processor patch if (completePatchi == procPatchi)
if (curBPatch != -1)
{ {
// Regular patch. Fast looping if (!patchFields(completePatchi))
if (!patchFields(curBPatch))
{ {
patchFields.set patchFields.set
( (
curBPatch, completePatchi,
fvsPatchField<Type>::New fvsPatchField<Type>::New
( (
procField.boundaryField()[patchi], procField.boundaryField()[procPatchi],
mesh_.boundary()[curBPatch], completeMesh_.boundary()[completePatchi],
DimensionedField<Type, surfaceMesh>::null(), DimensionedField<Type, surfaceMesh>::null(),
fvPatchFieldReconstructor fvPatchFieldReconstructor
( (
mesh_.boundary()[curBPatch].size() completeMesh_.boundary()[completePatchi].size()
) )
) )
); );
} }
const label curPatchStart = patchFields[completePatchi].rmap
mesh_.boundaryMesh()[curBPatch].start();
labelList reverseAddressing(cp.size());
forAll(cp, facei)
{
// Subtract one to take into account offsets for
// face direction.
reverseAddressing[facei] = cp[facei] - 1 - curPatchStart;
}
patchFields[curBPatch].rmap
( (
procField.boundaryField()[patchi], procField.boundaryField()[procPatchi],
reverseAddressing faceProcAddressingBf_[proci][procPatchi] - 1
); );
} }
else else if (isA<processorCyclicFvPatch>(procPatch))
{ {
const Field<Type>& curProcPatch = if (!patchFields(completePatchi))
procField.boundaryField()[patchi];
// In processor patches, there's a mix of internal faces (some
// of them turned) and possible cyclics. Slow loop
forAll(cp, facei)
{
label curF = cp[facei] - 1;
// Is the face turned the right side round
if (curF >= 0)
{
// Is the face on the boundary?
if (curF >= mesh_.nInternalFaces())
{
label curBPatch =
mesh_.boundaryMesh().whichPatch(curF);
if (!patchFields(curBPatch))
{ {
patchFields.set patchFields.set
( (
curBPatch, completePatchi,
fvsPatchField<Type>::New fvsPatchField<Type>::New
( (
mesh_.boundary()[curBPatch].type(), completeMesh_.boundary()[completePatchi].type(),
mesh_.boundary()[curBPatch], completeMesh_.boundary()[completePatchi],
DimensionedField<Type, surfaceMesh>
::null()
)
);
}
// add the face
label curPatchFace =
mesh_.boundaryMesh()
[curBPatch].whichFace(curF);
patchFields[curBPatch][curPatchFace] =
curProcPatch[facei];
}
else
{
// Internal face
internalField[curF] = curProcPatch[facei];
}
}
}
}
}
}
forAll(mesh_.boundary(), patchi)
{
// add empty patches
if
(
isType<emptyFvPatch>(mesh_.boundary()[patchi])
&& !patchFields(patchi)
)
{
patchFields.set
(
patchi,
fvsPatchField<Type>::New
(
emptyFvsPatchField<Type>::typeName,
mesh_.boundary()[patchi],
DimensionedField<Type, surfaceMesh>::null() DimensionedField<Type, surfaceMesh>::null()
) )
); );
} }
patchFields[completePatchi].rmap
(
procField.boundaryField()[procPatchi],
faceProcAddressingBf_[proci][procPatchi] - 1
);
}
else if (isA<processorFvPatch>(procPatch))
{
rmapFaceToFace
(
internalField,
procField.boundaryField()[procPatchi],
faceProcAddressingBf_[proci][procPatchi],
isFlux(procFields[proci])
);
}
}
} }
// Construct and return the field
// Now construct and write the field
// setting the internalField and patchFields
return tmp<GeometricField<Type, fvsPatchField, surfaceMesh>> return tmp<GeometricField<Type, fvsPatchField, surfaceMesh>>
( (
new GeometricField<Type, fvsPatchField, surfaceMesh> new GeometricField<Type, fvsPatchField, surfaceMesh>
( (
fieldIoObject, fieldIoObject,
mesh_, completeMesh_,
procFields[0].dimensions(), procFields[0].dimensions(),
internalField, internalField,
patchFields patchFields
@ -561,11 +406,8 @@ Foam::fvFieldReconstructor::reconstructFvSurfaceField
const IOobject& fieldIoObject const IOobject& fieldIoObject
) const ) const
{ {
// Read the field for all the processors PtrList<GeometricField<Type, fvsPatchField, surfaceMesh>>
PtrList<GeometricField<Type, fvsPatchField, surfaceMesh>> procFields procFields(procMeshes_.size());
(
procMeshes_.size()
);
forAll(procMeshes_, proci) forAll(procMeshes_, proci)
{ {
@ -593,8 +435,8 @@ Foam::fvFieldReconstructor::reconstructFvSurfaceField
IOobject IOobject
( (
fieldIoObject.name(), fieldIoObject.name(),
mesh_.time().timeName(), completeMesh_.time().timeName(),
mesh_, completeMesh_,
IOobject::NO_READ, IOobject::NO_READ,
IOobject::NO_WRITE, IOobject::NO_WRITE,
false false

View File

@ -29,19 +29,19 @@ License
Foam::pointFieldReconstructor::pointFieldReconstructor Foam::pointFieldReconstructor::pointFieldReconstructor
( (
const pointMesh& mesh, const pointMesh& completeMesh,
const PtrList<pointMesh>& procMeshes, const PtrList<pointMesh>& procMeshes,
const PtrList<labelIOList>& pointProcAddressing const labelListList& pointProcAddressing
) )
: :
mesh_(mesh), completeMesh_(completeMesh),
procMeshes_(procMeshes), procMeshes_(procMeshes),
pointProcAddressing_(pointProcAddressing), pointProcAddressing_(pointProcAddressing),
patchPointAddressing_(procMeshes.size()), patchPointAddressing_(procMeshes.size()),
nReconstructed_(0) nReconstructed_(0)
{ {
// Inverse-addressing of the patch point labels. // Inverse-addressing of the patch point labels.
labelList pointMap(mesh_.size(), -1); labelList pointMap(completeMesh_.size(), -1);
// Create the pointPatch addressing // Create the pointPatch addressing
forAll(procMeshes_, proci) forAll(procMeshes_, proci)
@ -52,13 +52,13 @@ Foam::pointFieldReconstructor::pointFieldReconstructor
forAll(procMesh.boundary(), patchi) forAll(procMesh.boundary(), patchi)
{ {
if (patchi < mesh_.boundary().size()) if (patchi < completeMesh_.boundary().size())
{ {
labelList& procPatchAddr = patchPointAddressing_[proci][patchi]; labelList& procPatchAddr = patchPointAddressing_[proci][patchi];
procPatchAddr.setSize(procMesh.boundary()[patchi].size(), -1); procPatchAddr.setSize(procMesh.boundary()[patchi].size(), -1);
const labelList& patchPointLabels = const labelList& patchPointLabels =
mesh_.boundary()[patchi].meshPoints(); completeMesh_.boundary()[patchi].meshPoints();
// Create the inverse-addressing of the patch point labels. // Create the inverse-addressing of the patch point labels.
forAll(patchPointLabels, pointi) forAll(patchPointLabels, pointi)

View File

@ -55,13 +55,13 @@ class pointFieldReconstructor
// Private Data // Private Data
//- Reconstructed mesh reference //- Reconstructed mesh reference
const pointMesh& mesh_; const pointMesh& completeMesh_;
//- List of processor meshes //- List of processor meshes
const PtrList<pointMesh>& procMeshes_; const PtrList<pointMesh>& procMeshes_;
//- List of processor point addressing lists //- List of processor point addressing lists
const PtrList<labelIOList>& pointProcAddressing_; const labelListList& pointProcAddressing_;
//- Point patch addressing //- Point patch addressing
labelListListList patchPointAddressing_; labelListListList patchPointAddressing_;
@ -97,7 +97,7 @@ public:
( (
const pointMesh& mesh, const pointMesh& mesh,
const PtrList<pointMesh>& procMeshes, const PtrList<pointMesh>& procMeshes,
const PtrList<labelIOList>& pointProcAddressing const labelListList& pointProcAddressing
); );
//- Disallow default bitwise copy construction //- Disallow default bitwise copy construction

View File

@ -59,10 +59,10 @@ Foam::pointFieldReconstructor::reconstructField(const IOobject& fieldIoObject)
// Create the internalField // Create the internalField
Field<Type> internalField(mesh_.size()); Field<Type> internalField(completeMesh_.size());
// Create the patch fields // Create the patch fields
PtrList<pointPatchField<Type>> patchFields(mesh_.boundary().size()); PtrList<pointPatchField<Type>> patchFields(completeMesh_.boundary().size());
forAll(procMeshes_, proci) forAll(procMeshes_, proci)
@ -85,7 +85,7 @@ Foam::pointFieldReconstructor::reconstructField(const IOobject& fieldIoObject)
{ {
// Get patch index of the original patch // Get patch index of the original patch
const label curBPatch = const label curBPatch =
patchi < mesh_.boundary().size() ? patchi : -1; patchi < completeMesh_.boundary().size() ? patchi : -1;
// check if the boundary patch is not a processor patch // check if the boundary patch is not a processor patch
if (curBPatch != -1) if (curBPatch != -1)
@ -97,11 +97,11 @@ Foam::pointFieldReconstructor::reconstructField(const IOobject& fieldIoObject)
pointPatchField<Type>::New pointPatchField<Type>::New
( (
procField.boundaryField()[patchi], procField.boundaryField()[patchi],
mesh_.boundary()[curBPatch], completeMesh_.boundary()[curBPatch],
DimensionedField<Type, pointMesh>::null(), DimensionedField<Type, pointMesh>::null(),
pointPatchFieldReconstructor pointPatchFieldReconstructor
( (
mesh_.boundary()[curBPatch].size() completeMesh_.boundary()[curBPatch].size()
) )
) )
); );
@ -125,12 +125,12 @@ Foam::pointFieldReconstructor::reconstructField(const IOobject& fieldIoObject)
IOobject IOobject
( (
fieldIoObject.name(), fieldIoObject.name(),
mesh_().time().timeName(), completeMesh_().time().timeName(),
mesh_(), completeMesh_(),
IOobject::NO_READ, IOobject::NO_READ,
IOobject::NO_WRITE IOobject::NO_WRITE
), ),
mesh_, completeMesh_,
procFields[0].dimensions(), procFields[0].dimensions(),
internalField, internalField,
patchFields patchFields

View File

@ -2,7 +2,7 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org \\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2011-2018 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2022 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -53,8 +53,8 @@ void reconstructLagrangianPositions
const polyMesh& mesh, const polyMesh& mesh,
const word& cloudName, const word& cloudName,
const PtrList<fvMesh>& meshes, const PtrList<fvMesh>& meshes,
const PtrList<labelIOList>& faceProcAddressing, const labelListList& faceProcAddressing,
const PtrList<labelIOList>& cellProcAddressing const labelListList& cellProcAddressing
); );

View File

@ -2,7 +2,7 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org \\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2011-2021 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2022 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 | Website: https://openfoam.org \\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2011-2018 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2022 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -34,8 +34,8 @@ void Foam::reconstructLagrangianPositions
const polyMesh& mesh, const polyMesh& mesh,
const word& cloudName, const word& cloudName,
const PtrList<fvMesh>& meshes, const PtrList<fvMesh>& meshes,
const PtrList<labelIOList>& faceProcAddressing, const labelListList& faceProcAddressing,
const PtrList<labelIOList>& cellProcAddressing const labelListList& cellProcAddressing
) )
{ {
passiveParticleCloud lagrangianPositions passiveParticleCloud lagrangianPositions

View File

@ -32,21 +32,15 @@ Description
#include "argList.H" #include "argList.H"
#include "timeSelector.H" #include "timeSelector.H"
#include "fvCFD.H" #include "fvCFD.H"
#include "IOobjectList.H" #include "IOobjectList.H"
#include "processorMeshes.H" #include "processorRunTimes.H"
#include "domainDecomposition.H"
#include "regionProperties.H" #include "regionProperties.H"
#include "fvFieldReconstructor.H" #include "fvFieldReconstructor.H"
#include "pointFieldReconstructor.H" #include "pointFieldReconstructor.H"
#include "reconstructLagrangian.H" #include "reconstructLagrangian.H"
#include "cellSet.H"
#include "faceSet.H"
#include "pointSet.H"
#include "hexRef8Data.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam namespace Foam
@ -120,7 +114,6 @@ int main(int argc, char *argv[])
); );
#include "setRootCase.H" #include "setRootCase.H"
#include "createTime.H"
HashSet<word> selectedFields; HashSet<word> selectedFields;
if (args.optionFound("fields")) if (args.optionFound("fields"))
@ -144,7 +137,6 @@ int main(int argc, char *argv[])
<< nl << endl; << nl << endl;
} }
const bool noReconstructSets = args.optionFound("noSets"); const bool noReconstructSets = args.optionFound("noSets");
if (noReconstructSets) if (noReconstructSets)
@ -153,7 +145,6 @@ int main(int argc, char *argv[])
<< nl << endl; << nl << endl;
} }
HashSet<word> selectedLagrangianFields; HashSet<word> selectedLagrangianFields;
if (args.optionFound("lagrangianFields")) if (args.optionFound("lagrangianFields"))
{ {
@ -168,12 +159,20 @@ int main(int argc, char *argv[])
args.optionLookup("lagrangianFields")() >> selectedLagrangianFields; args.optionLookup("lagrangianFields")() >> selectedLagrangianFields;
} }
const wordList regionNames(selectRegionNames(args, runTime)); // Set time from database
Info<< "Create time\n" << endl;
processorRunTimes runTimes(Foam::Time::controlDictName, args);
// Allow override of time
const instantList times = runTimes.selectProc(args);
// Get region names
const wordList regionNames =
selectRegionNames(args, runTimes.procTimes()[0]);
// Determine the processor count // Determine the processor count
const label nProcs = const label nProcs =
fileHandler().nProcs(args.path(), regionDir(regionNames[0])); fileHandler().nProcs(args.path(), regionDir(regionNames[0]));
if (!nProcs) if (!nProcs)
{ {
FatalErrorInFunction FatalErrorInFunction
@ -184,38 +183,12 @@ int main(int argc, char *argv[])
// Warn fileHandler of number of processors // Warn fileHandler of number of processors
const_cast<fileOperation&>(fileHandler()).setNProcs(nProcs); const_cast<fileOperation&>(fileHandler()).setNProcs(nProcs);
// Create the processor databases
PtrList<Time> databases(nProcs);
forAll(databases, proci)
{
databases.set
(
proci,
new Time
(
Time::controlDictName,
args.rootPath(),
args.caseName()/fileName(word("processor") + name(proci))
)
);
}
// Use the times list from the master processor
// and select a subset based on the command-line options
instantList timeDirs = timeSelector::select
(
databases[0].times(),
args
);
// Note that we do not set the runTime time so it is still the // Note that we do not set the runTime time so it is still the
// one set through the controlDict. The -time option // one set through the controlDict. The -time option
// only affects the selected set of times from processor0. // only affects the selected set of times from processor0.
// - can be illogical // - can be illogical
// + any point motion handled through mesh.readUpdate // + any point motion handled through mesh.readUpdate
if (times.empty())
if (timeDirs.empty())
{ {
WarningInFunction << "No times selected" << endl; WarningInFunction << "No times selected" << endl;
exit(1); exit(1);
@ -226,130 +199,76 @@ int main(int argc, char *argv[])
instantList masterTimeDirs; instantList masterTimeDirs;
if (newTimes) if (newTimes)
{ {
masterTimeDirs = runTime.times(); masterTimeDirs = runTimes.completeTime().times();
} }
HashSet<word> masterTimeDirSet(2*masterTimeDirs.size()); HashSet<word> masterTimeDirSet(2*masterTimeDirs.size());
forAll(masterTimeDirs, i) forAll(masterTimeDirs, i)
{ {
masterTimeDirSet.insert(masterTimeDirs[i].name()); masterTimeDirSet.insert(masterTimeDirs[i].name());
} }
if if
( (
newTimes newTimes
&& regionNames.size() == 1 && regionNames.size() == 1
&& regionNames[0] == fvMesh::defaultRegion && regionNames[0] == fvMesh::defaultRegion
&& haveAllTimes(masterTimeDirSet, timeDirs) && haveAllTimes(masterTimeDirSet, times)
) )
{ {
Info<< "All times already reconstructed.\n\nEnd\n" << endl; Info<< "All times already reconstructed.\n\nEnd\n" << endl;
return 0; return 0;
} }
// Set all times on processor meshes equal to reconstructed mesh // Reconstruct all regions
forAll(databases, proci)
{
databases[proci].setTime(runTime);
}
forAll(regionNames, regioni) forAll(regionNames, regioni)
{ {
const word& regionName = regionNames[regioni]; const word& regionName = regionNames[regioni];
const word& regionDir = Foam::regionDir(regionName); const word& regionDir = Foam::regionDir(regionName);
Info<< "\n\nReconstructing fields for mesh " << regionName << nl // Create meshes
<< endl; Info<< "\n\nReconstructing fields for mesh " << regionName
<< nl << endl;
fvMesh mesh domainDecomposition meshes(runTimes, regionName);
( meshes.readComplete();
IOobject meshes.readProcs();
( meshes.readAddressing();
regionName, meshes.readUpdate();
runTime.timeName(),
runTime,
IOobject::MUST_READ
),
false
);
// Read all meshes and addressing to reconstructed mesh
processorMeshes procMeshes(databases, regionName);
// Check face addressing for meshes that have been decomposed
// with a very old foam version
#include "checkFaceAddressingComp.H"
// Loop over all times // Loop over all times
forAll(timeDirs, timei) forAll(times, timei)
{ {
if (newTimes && masterTimeDirSet.found(timeDirs[timei].name())) if (newTimes && masterTimeDirSet.found(times[timei].name()))
{ {
Info<< "Skipping time " << timeDirs[timei].name() Info<< "Skipping time " << times[timei].name()
<< endl << endl; << endl << endl;
continue; continue;
} }
// Set the time
runTimes.setTime(times[timei], timei);
// Set time for global database Info<< "Time = " << runTimes.completeTime().userTimeName()
runTime.setTime(timeDirs[timei], timei); << nl << endl;
Info<< "Time = " << runTime.userTimeName() << endl << endl; // Update the meshes
const fvMesh::readUpdateState state = meshes.readUpdate();
// Set time for all databases if (state == fvMesh::POINTS_MOVED)
forAll(databases, proci)
{ {
databases[proci].setTime(timeDirs[timei], timei); meshes.writeComplete(false);
} }
// Check if any new meshes need to be read.
fvMesh::readUpdateState meshStat = mesh.readUpdate();
fvMesh::readUpdateState procStat = procMeshes.readUpdate();
if if
( (
meshStat != procStat state == fvMesh::TOPO_CHANGE
|| state == fvMesh::TOPO_PATCH_CHANGE
// Allowed status difference. Mesh has moved in parallel, but
// the change has not yet been reconstructed.
&& !(
meshStat == fvMesh::UNCHANGED
&& procStat == fvMesh::POINTS_MOVED
)
// Allowed status difference. Mesh has changed topology in both
// cases, and this has lead to new processor interfaces
// (probably). These interfaces are compatible with a
// reconstructed mesh in which patches have not changed.
&& !(
meshStat == fvMesh::TOPO_CHANGE
&& procStat == fvMesh::TOPO_PATCH_CHANGE
)
) )
{ {
WarningInFunction meshes.writeComplete(!noReconstructSets);
<< "readUpdate for the reconstructed mesh:"
<< meshStat << nl
<< "readUpdate for the processor meshes :"
<< procStat << nl
<< "These should be equal or your addressing"
<< " might be incorrect."
<< " Please check your time directories for any "
<< "mesh directories." << endl;
}
// Reconstruct and write the points for moving mesh cases
if (procStat == fvMesh::POINTS_MOVED)
{
procMeshes.reconstructPoints(mesh);
} }
// Get list of objects from processor0 database // Get list of objects from processor0 database
IOobjectList objects IOobjectList objects
( (
procMeshes.meshes()[0], meshes.procMeshes()[0],
databases[0].timeName() runTimes.procTimes()[0].timeName()
); );
if (!noFields) if (!noFields)
@ -359,10 +278,11 @@ int main(int argc, char *argv[])
fvFieldReconstructor fvReconstructor fvFieldReconstructor fvReconstructor
( (
mesh, meshes.completeMesh(),
procMeshes.meshes(), meshes.procMeshes(),
procMeshes.faceProcAddressing(), meshes.procFaceAddressing(),
procMeshes.cellProcAddressing() meshes.procCellAddressing(),
meshes.procFaceAddressingBf()
); );
fvReconstructor.reconstructFvVolumeInternalFields<scalar> fvReconstructor.reconstructFvVolumeInternalFields<scalar>
@ -454,23 +374,23 @@ int main(int argc, char *argv[])
{ {
Info<< "Reconstructing point fields" << nl << endl; Info<< "Reconstructing point fields" << nl << endl;
const pointMesh& pMesh = pointMesh::New(mesh); const pointMesh& completePMesh =
PtrList<pointMesh> pMeshes(procMeshes.meshes().size()); pointMesh::New(meshes.completeMesh());
PtrList<pointMesh> procPMeshes(nProcs);
forAll(pMeshes, proci) forAll(procPMeshes, proci)
{ {
pMeshes.set procPMeshes.set
( (
proci, proci,
new pointMesh(procMeshes.meshes()[proci]) new pointMesh(meshes.procMeshes()[proci])
); );
} }
pointFieldReconstructor pointReconstructor pointFieldReconstructor pointReconstructor
( (
pMesh, completePMesh,
pMeshes, procPMeshes,
procMeshes.pointProcAddressing() meshes.procPointAddressing()
); );
pointReconstructor.reconstructFields<scalar> pointReconstructor.reconstructFields<scalar>
@ -517,13 +437,13 @@ int main(int argc, char *argv[])
{ {
HashTable<IOobjectList> cloudObjects; HashTable<IOobjectList> cloudObjects;
forAll(databases, proci) forAll(runTimes.procTimes(), proci)
{ {
fileName lagrangianDir fileName lagrangianDir
( (
fileHandler().filePath fileHandler().filePath
( (
databases[proci].timePath() runTimes.procTimes()[proci].timePath()
/regionDir /regionDir
/cloud::prefix /cloud::prefix
) )
@ -551,8 +471,8 @@ int main(int argc, char *argv[])
// Do local scan for valid cloud objects // Do local scan for valid cloud objects
IOobjectList sprayObjs IOobjectList sprayObjs
( (
procMeshes.meshes()[proci], meshes.procMeshes()[proci],
databases[proci].timeName(), runTimes.procTimes()[proci].timeName(),
cloud::prefix/cloudDirs[i] cloud::prefix/cloudDirs[i]
); );
@ -567,16 +487,13 @@ int main(int argc, char *argv[])
} }
} }
if (cloudObjects.size()) if (cloudObjects.size())
{ {
// Pass2: reconstruct the cloud // Pass2: reconstruct the cloud
forAllConstIter(HashTable<IOobjectList>, cloudObjects, iter) forAllConstIter(HashTable<IOobjectList>, cloudObjects, iter)
{ {
const word cloudName = string::validate<word> const word cloudName =
( string::validate<word>(iter.key());
iter.key()
);
// Objects (on arbitrary processor) // Objects (on arbitrary processor)
const IOobjectList& sprayObjs = iter(); const IOobjectList& sprayObjs = iter();
@ -586,105 +503,105 @@ int main(int argc, char *argv[])
reconstructLagrangianPositions reconstructLagrangianPositions
( (
mesh, meshes.completeMesh(),
cloudName, cloudName,
procMeshes.meshes(), meshes.procMeshes(),
procMeshes.faceProcAddressing(), meshes.procFaceAddressing(),
procMeshes.cellProcAddressing() meshes.procCellAddressing()
); );
reconstructLagrangianFields<label> reconstructLagrangianFields<label>
( (
cloudName, cloudName,
mesh, meshes.completeMesh(),
procMeshes.meshes(), meshes.procMeshes(),
sprayObjs, sprayObjs,
selectedLagrangianFields selectedLagrangianFields
); );
reconstructLagrangianFieldFields<label> reconstructLagrangianFieldFields<label>
( (
cloudName, cloudName,
mesh, meshes.completeMesh(),
procMeshes.meshes(), meshes.procMeshes(),
sprayObjs, sprayObjs,
selectedLagrangianFields selectedLagrangianFields
); );
reconstructLagrangianFields<scalar> reconstructLagrangianFields<scalar>
( (
cloudName, cloudName,
mesh, meshes.completeMesh(),
procMeshes.meshes(), meshes.procMeshes(),
sprayObjs, sprayObjs,
selectedLagrangianFields selectedLagrangianFields
); );
reconstructLagrangianFieldFields<scalar> reconstructLagrangianFieldFields<scalar>
( (
cloudName, cloudName,
mesh, meshes.completeMesh(),
procMeshes.meshes(), meshes.procMeshes(),
sprayObjs, sprayObjs,
selectedLagrangianFields selectedLagrangianFields
); );
reconstructLagrangianFields<vector> reconstructLagrangianFields<vector>
( (
cloudName, cloudName,
mesh, meshes.completeMesh(),
procMeshes.meshes(), meshes.procMeshes(),
sprayObjs, sprayObjs,
selectedLagrangianFields selectedLagrangianFields
); );
reconstructLagrangianFieldFields<vector> reconstructLagrangianFieldFields<vector>
( (
cloudName, cloudName,
mesh, meshes.completeMesh(),
procMeshes.meshes(), meshes.procMeshes(),
sprayObjs, sprayObjs,
selectedLagrangianFields selectedLagrangianFields
); );
reconstructLagrangianFields<sphericalTensor> reconstructLagrangianFields<sphericalTensor>
( (
cloudName, cloudName,
mesh, meshes.completeMesh(),
procMeshes.meshes(), meshes.procMeshes(),
sprayObjs, sprayObjs,
selectedLagrangianFields selectedLagrangianFields
); );
reconstructLagrangianFieldFields<sphericalTensor> reconstructLagrangianFieldFields<sphericalTensor>
( (
cloudName, cloudName,
mesh, meshes.completeMesh(),
procMeshes.meshes(), meshes.procMeshes(),
sprayObjs, sprayObjs,
selectedLagrangianFields selectedLagrangianFields
); );
reconstructLagrangianFields<symmTensor> reconstructLagrangianFields<symmTensor>
( (
cloudName, cloudName,
mesh, meshes.completeMesh(),
procMeshes.meshes(), meshes.procMeshes(),
sprayObjs, sprayObjs,
selectedLagrangianFields selectedLagrangianFields
); );
reconstructLagrangianFieldFields<symmTensor> reconstructLagrangianFieldFields<symmTensor>
( (
cloudName, cloudName,
mesh, meshes.completeMesh(),
procMeshes.meshes(), meshes.procMeshes(),
sprayObjs, sprayObjs,
selectedLagrangianFields selectedLagrangianFields
); );
reconstructLagrangianFields<tensor> reconstructLagrangianFields<tensor>
( (
cloudName, cloudName,
mesh, meshes.completeMesh(),
procMeshes.meshes(), meshes.procMeshes(),
sprayObjs, sprayObjs,
selectedLagrangianFields selectedLagrangianFields
); );
reconstructLagrangianFieldFields<tensor> reconstructLagrangianFieldFields<tensor>
( (
cloudName, cloudName,
mesh, meshes.completeMesh(),
procMeshes.meshes(), meshes.procMeshes(),
sprayObjs, sprayObjs,
selectedLagrangianFields selectedLagrangianFields
); );
@ -696,278 +613,6 @@ int main(int argc, char *argv[])
} }
} }
if (!noReconstructSets)
{
// Scan to find all sets
HashTable<label> cSetNames;
HashTable<label> fSetNames;
HashTable<label> pSetNames;
forAll(procMeshes.meshes(), proci)
{
const fvMesh& procMesh = procMeshes.meshes()[proci];
// Note: look at sets in current time only or between
// mesh and current time?. For now current time. This will
// miss out on sets in intermediate times that have not
// been reconstructed.
IOobjectList objects
(
procMesh,
databases[0].timeName(), // procMesh.facesInstance()
polyMesh::meshSubDir/"sets"
);
IOobjectList cSets(objects.lookupClass(cellSet::typeName));
forAllConstIter(IOobjectList, cSets, iter)
{
cSetNames.insert(iter.key(), cSetNames.size());
}
IOobjectList fSets(objects.lookupClass(faceSet::typeName));
forAllConstIter(IOobjectList, fSets, iter)
{
fSetNames.insert(iter.key(), fSetNames.size());
}
IOobjectList pSets(objects.lookupClass(pointSet::typeName));
forAllConstIter(IOobjectList, pSets, iter)
{
pSetNames.insert(iter.key(), pSetNames.size());
}
}
if (cSetNames.size() || fSetNames.size() || pSetNames.size())
{
// Construct all sets
PtrList<cellSet> cellSets(cSetNames.size());
PtrList<faceSet> faceSets(fSetNames.size());
PtrList<pointSet> pointSets(pSetNames.size());
Info<< "Reconstructing sets:" << endl;
if (cSetNames.size())
{
Info<< " cellSets "
<< cSetNames.sortedToc() << endl;
}
if (fSetNames.size())
{
Info<< " faceSets "
<< fSetNames.sortedToc() << endl;
}
if (pSetNames.size())
{
Info<< " pointSets "
<< pSetNames.sortedToc() << endl;
}
// Load sets
forAll(procMeshes.meshes(), proci)
{
const fvMesh& procMesh = procMeshes.meshes()[proci];
IOobjectList objects
(
procMesh,
databases[0].timeName(),
polyMesh::meshSubDir/"sets"
);
// cellSets
const labelList& cellMap =
procMeshes.cellProcAddressing()[proci];
IOobjectList cSets
(
objects.lookupClass(cellSet::typeName)
);
forAllConstIter(IOobjectList, cSets, iter)
{
// Load cellSet
const cellSet procSet(*iter());
label setI = cSetNames[iter.key()];
if (!cellSets.set(setI))
{
cellSets.set
(
setI,
new cellSet
(
mesh,
iter.key(),
procSet.size()
)
);
}
cellSet& cSet = cellSets[setI];
cSet.instance() = runTime.timeName();
forAllConstIter(cellSet, procSet, iter)
{
cSet.insert(cellMap[iter.key()]);
}
}
// faceSets
const labelList& faceMap =
procMeshes.faceProcAddressing()[proci];
IOobjectList fSets
(
objects.lookupClass(faceSet::typeName)
);
forAllConstIter(IOobjectList, fSets, iter)
{
// Load faceSet
const faceSet procSet(*iter());
label setI = fSetNames[iter.key()];
if (!faceSets.set(setI))
{
faceSets.set
(
setI,
new faceSet
(
mesh,
iter.key(),
procSet.size()
)
);
}
faceSet& fSet = faceSets[setI];
fSet.instance() = runTime.timeName();
forAllConstIter(faceSet, procSet, iter)
{
fSet.insert(mag(faceMap[iter.key()])-1);
}
}
// pointSets
const labelList& pointMap =
procMeshes.pointProcAddressing()[proci];
IOobjectList pSets
(
objects.lookupClass(pointSet::typeName)
);
forAllConstIter(IOobjectList, pSets, iter)
{
// Load pointSet
const pointSet propSet(*iter());
label setI = pSetNames[iter.key()];
if (!pointSets.set(setI))
{
pointSets.set
(
setI,
new pointSet
(
mesh,
iter.key(),
propSet.size()
)
);
}
pointSet& pSet = pointSets[setI];
pSet.instance() = runTime.timeName();
forAllConstIter(pointSet, propSet, iter)
{
pSet.insert(pointMap[iter.key()]);
}
}
}
// Write sets
forAll(cellSets, i)
{
cellSets[i].write();
}
forAll(faceSets, i)
{
faceSets[i].write();
}
forAll(pointSets, i)
{
pointSets[i].write();
}
}
}
// Reconstruct refinement data
{
PtrList<hexRef8Data> procData(procMeshes.meshes().size());
forAll(procMeshes.meshes(), procI)
{
const fvMesh& procMesh = procMeshes.meshes()[procI];
procData.set
(
procI,
new hexRef8Data
(
IOobject
(
"dummy",
procMesh.time().timeName(),
polyMesh::meshSubDir,
procMesh,
IOobject::READ_IF_PRESENT,
IOobject::NO_WRITE,
false
)
)
);
}
// Combine individual parts
const PtrList<labelIOList>& cellAddr =
procMeshes.cellProcAddressing();
UPtrList<const labelList> cellMaps(cellAddr.size());
forAll(cellAddr, i)
{
cellMaps.set(i, &cellAddr[i]);
}
const PtrList<labelIOList>& pointAddr =
procMeshes.pointProcAddressing();
UPtrList<const labelList> pointMaps(pointAddr.size());
forAll(pointAddr, i)
{
pointMaps.set(i, &pointAddr[i]);
}
UPtrList<const hexRef8Data> procRefs(procData.size());
forAll(procData, i)
{
procRefs.set(i, &procData[i]);
}
hexRef8Data
(
IOobject
(
"dummy",
mesh.time().timeName(),
polyMesh::meshSubDir,
mesh,
IOobject::NO_READ,
IOobject::NO_WRITE,
false
),
cellMaps,
pointMaps,
procRefs
).write();
}
// If there is a "uniform" directory in the time region // If there is a "uniform" directory in the time region
// directory copy from the master processor // directory copy from the master processor
{ {
@ -975,13 +620,17 @@ int main(int argc, char *argv[])
( (
fileHandler().filePath fileHandler().filePath
( (
databases[0].timePath()/regionDir/"uniform" runTimes.procTimes()[0].timePath()/regionDir/"uniform"
) )
); );
if (!uniformDir0.empty() && fileHandler().isDir(uniformDir0)) if (!uniformDir0.empty() && fileHandler().isDir(uniformDir0))
{ {
fileHandler().cp(uniformDir0, runTime.timePath()/regionDir); fileHandler().cp
(
uniformDir0,
runTimes.completeTime().timePath()/regionDir
);
} }
} }
@ -993,13 +642,17 @@ int main(int argc, char *argv[])
( (
fileHandler().filePath fileHandler().filePath
( (
databases[0].timePath()/"uniform" runTimes.procTimes()[0].timePath()/"uniform"
) )
); );
if (!uniformDir0.empty() && fileHandler().isDir(uniformDir0)) if (!uniformDir0.empty() && fileHandler().isDir(uniformDir0))
{ {
fileHandler().cp(uniformDir0, runTime.timePath()); fileHandler().cp
(
uniformDir0,
runTimes.completeTime().timePath()
);
} }
} }
} }

View File

@ -2,7 +2,7 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org \\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2011-2021 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2022 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -34,6 +34,8 @@ Description
#include "faceSet.H" #include "faceSet.H"
#include "volFields.H" #include "volFields.H"
#include "systemDict.H" #include "systemDict.H"
#include "processorFvPatch.H"
#include "CompactListList.H"
using namespace Foam; using namespace Foam;
@ -231,72 +233,96 @@ bool setFaceFieldType
<< fieldHeader.headerClassName() << fieldHeader.headerClassName()
<< " " << fieldName << endl; << " " << fieldName << endl;
// Read the field
fieldType field(fieldHeader, mesh); fieldType field(fieldHeader, mesh);
typename fieldType::Boundary& fieldBf = field.boundaryFieldRef();
// Read the value
const Type& value = pTraits<Type>(fieldValueStream); const Type& value = pTraits<Type>(fieldValueStream);
// Create flat list of selected faces and their value. // Determine the number of non-processor patches
Field<Type> allBoundaryValues(mesh.nFaces()-mesh.nInternalFaces()); label nNonProcPatches = 0;
forAll(field.boundaryField(), patchi) forAll(fieldBf, patchi)
{ {
SubField<Type> nNonProcPatches = patchi;
( if (isA<processorFvPatch>(mesh.boundary()[patchi]))
allBoundaryValues, {
field.boundaryField()[patchi].size(), break;
field.boundaryField()[patchi].patch().start() }
- mesh.nInternalFaces()
) = field.boundaryField()[patchi];
} }
// Override // Create a copy of the boundary field
bool hasWarned = false; typename fieldType::Boundary fieldBfCopy
labelList nChanged
( (
returnReduce(field.boundaryField().size(), maxOp<label>()), fieldType::Internal::null(),
0 fieldBf
); );
// Loop selected faces and set values in the copied boundary field
bool haveWarnedInternal = false, haveWarnedProc = false;
labelList nonProcPatchNChangedFaces(nNonProcPatches, 0);
forAll(selectedFaces, i) forAll(selectedFaces, i)
{ {
label facei = selectedFaces[i]; const label facei = selectedFaces[i];
if (mesh.isInternalFace(facei)) if (mesh.isInternalFace(facei))
{ {
if (!hasWarned) if (!haveWarnedInternal)
{ {
hasWarned = true;
WarningInFunction WarningInFunction
<< "Ignoring internal face " << facei << "Ignoring internal face " << facei
<< ". Suppressing further warnings." << endl; << ". Suppressing further warnings." << endl;
haveWarnedInternal = true;
} }
} }
else else
{ {
label bFacei = facei-mesh.nInternalFaces(); const labelUList patches =
allBoundaryValues[bFacei] = value; mesh.polyBFacePatches()[facei - mesh.nInternalFaces()];
nChanged[mesh.boundaryMesh().patchID()[bFacei]]++; const labelUList patchFaces =
} mesh.polyBFacePatchFaces()[facei - mesh.nInternalFaces()];
}
Pstream::listCombineGather(nChanged, plusEqOp<label>()); forAll(patches, i)
Pstream::listCombineScatter(nChanged);
typename GeometricField<Type, fvPatchField, volMesh>::
Boundary& fieldBf = field.boundaryFieldRef();
// Reassign.
forAll(field.boundaryField(), patchi)
{ {
if (nChanged[patchi] > 0) if (patches[i] >= nNonProcPatches)
{
if (!haveWarnedProc)
{
WarningInFunction
<< "Ignoring face " << patchFaces[i]
<< " of processor patch " << patches[i]
<< ". Suppressing further warnings." << endl;
haveWarnedProc = true;
}
}
else
{
fieldBfCopy[patches[i]][patchFaces[i]] = value;
nonProcPatchNChangedFaces[patches[i]] ++;
}
}
}
}
Pstream::listCombineGather
(
nonProcPatchNChangedFaces,
plusEqOp<label>()
);
Pstream::listCombineScatter
(
nonProcPatchNChangedFaces
);
// Reassign boundary values
forAll(nonProcPatchNChangedFaces, patchi)
{
if (nonProcPatchNChangedFaces[patchi] > 0)
{ {
Info<< " On patch " Info<< " On patch "
<< field.boundaryField()[patchi].patch().name() << field.boundaryField()[patchi].patch().name()
<< " set " << nChanged[patchi] << " values" << endl; << " set " << nonProcPatchNChangedFaces[patchi]
fieldBf[patchi] == SubField<Type> << " values" << endl;
( fieldBf[patchi] == fieldBfCopy[patchi];
allBoundaryValues,
fieldBf[patchi].size(),
fieldBf[patchi].patch().start()
- mesh.nInternalFaces()
);
} }
} }

View File

@ -2,7 +2,7 @@
# ========= | # ========= |
# \\ / F ield | OpenFOAM: The Open Source CFD Toolbox # \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
# \\ / O peration | Website: https://openfoam.org # \\ / O peration | Website: https://openfoam.org
# \\ / A nd | Copyright (C) 2011-2021 OpenFOAM Foundation # \\ / A nd | Copyright (C) 2011-2022 OpenFOAM Foundation
# \\/ M anipulation | # \\/ M anipulation |
#------------------------------------------------------------------------------ #------------------------------------------------------------------------------
# License # License
@ -47,6 +47,7 @@ cleanCase()
for d in constant 0 for d in constant 0
do do
rm -rf $d/polyMesh $d/*/polyMesh \ rm -rf $d/polyMesh $d/*/polyMesh \
$d/fvMesh $d/*/fvMesh \
$d/cellToRegion $d/*/cellToRegion \ $d/cellToRegion $d/*/cellToRegion \
$d/cellLevel* $d/pointLevel* \ $d/cellLevel* $d/pointLevel* \
$d/cellDist $d/cellDecomposition $d/cellDist $d/cellDecomposition

View File

@ -0,0 +1,69 @@
/*--------------------------------*- C++ -*----------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Version: dev
\\/ M anipulation |
\*---------------------------------------------------------------------------*/
FoamFile
{
format ascii;
class dictionary;
location "system";
object createNonConformalCouplesDict;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// Each couple has its own entry in this file. Entries take the following form:
/*
// Unique name used to generate the name of the coupled patches
<name>
{
// Name of the two patches between which to create the coupling
patches (<patch1> <patch2>);
// Type of the transformation; "none", "rotational", or "translational"
transform <transformType>;
// Additional transformation settings (if any)
...
}
*/
// Examples:
// Create a non-conformal couple with no transformation
nonConformalCouple_none
{
patches (nonCouple1 nonCouple2);
transform none;
}
// Create a non-conformal couple with a 30 degree rotational transformation
nonConformalCouple_30deg
{
patches (nonCoupleBehind nonCoupleAhead);
transform rotational;
rotationAxis (-1 0 0);
rotationCentre (0 0 0);
rotationAngle 30;
}
// Create a non-conformal couple with a 2 metre translational transformation
nonConformalCouple_2m
{
patches (nonCoupleBack nonCoupleFront);
transform translational;
separation (0 2 0);
}
// Note that in rare cases it may be appropriate to create multiple couplings
// between the same two patches. That can be achieved with multiple entries
// with the same patches specified. See the
// incompressible/pimpleFoam/RAS/impeller tutorial for an example of this.
// ************************************************************************* //

View File

@ -37,10 +37,9 @@ constraints
preservePatches preservePatches
{ {
//- Keep owner and neighbour on same processor for faces in patches //- Keep owner and neighbour on same processor for faces in patches. Can
// (only makes sense for cyclic patches. Not suitable for e.g. // be used to prevent a cyclic patch from being decomposed into
// cyclicAMI since these are not coupled on the patch level. Use // multiple processor cyclics.
// singleProcessorFaceSets for those)
type preservePatches; type preservePatches;
patches (".*"); patches (".*");
} }
@ -48,12 +47,12 @@ constraints
singleProcessorFaceSets singleProcessorFaceSets
{ {
//- Keep all of faceSet on a single processor. This puts all cells //- Keep all of faceSet on a single processor. This puts all cells
// connected with a point, edge or face on the same processor. // connected with a point, edge or face on the same processor
// (just having face connected cells might not guarantee a balanced // (just having face connected cells might not guarantee a balanced
// decomposition) // decomposition). If processor index is set to -1, the decomposition
// The processor can be -1 (the decompositionMethod chooses the // method chooses the processor to which the face set is decomposed.
// processor for a good load balance) or explicitly provided (upsets // This is likely to create a better balance than if the processor
// balance) // index is explicitly specified.
type singleProcessorFaceSets; type singleProcessorFaceSets;
singleProcessorFaceSets ((f1 -1)); singleProcessorFaceSets ((f1 -1));
} }

View File

@ -1,54 +0,0 @@
/*--------------------------------*- C++ -*----------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Version: dev
\\/ M anipulation |
\*---------------------------------------------------------------------------*/
FoamFile
{
format ascii;
class dictionary;
object createPatchDict;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
pointSync false;
// AMI created from internal boundary with cylinder and cylinder_slave patches
masterAMI
{
name AMI1;
patchInfo
{
type cyclicAMI;
matchTolerance 0.0001;
neighbourPatch AMI2;
}
constructFrom patches;
patches (cylinder);
}
patches
(
// master AMI patch
{
$masterAMI;
}
// slave AMI patch
{
$masterAMI;
name AMI2;
patchInfo
{
neighbourPatch AMI1;
}
patches (cylinder_slave);
}
);
// ************************************************************************* //

View File

@ -13,11 +13,18 @@ FoamFile
} }
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// Whether to convert internal faces only (so leave boundary faces intact).
// This is only relevant if your face selection type can pick up boundary
// faces.
internalFacesOnly true; internalFacesOnly true;
// Example creating two opposing patches named "nonCouple1" and "nonCouple2",
// both of which are included in the "nonCouple" group. These patches can then
// be coupled afterwards by calling "createNonConformalCouples -overwrite
// nonCouple1 nonCouple2".
baffles baffles
{ {
baffleFaces rotating
{ {
type faceZone; type faceZone;
zoneName rotatingZone; zoneName rotatingZone;
@ -26,16 +33,15 @@ baffles
{ {
master master
{ {
name AMI1; name nonCouple1;
type cyclicAMI; type patch;
neighbourPatch AMI2; inGroups (nonCouple);
} }
slave slave
{ {
$master; name nonCouple2;
name AMI2; type patch;
type cyclicAMI; inGroups (nonCouple);
neighbourPatch AMI1;
} }
} }
} }

View File

@ -27,9 +27,21 @@ cyclicSlip
type cyclicSlip; type cyclicSlip;
} }
conformalCoupled nonConformalCyclic
{ {
type conformalCoupled; type nonConformalCyclic;
value $internalField;
}
nonConformalError
{
type nonConformalError;
}
nonConformalProcessorCyclic
{
type nonConformalProcessorCyclic;
value $internalField;
} }
empty empty

View File

@ -49,6 +49,7 @@ parallel/Allwmake $targetType $*
wmake $targetType conversion wmake $targetType conversion
wmake $targetType sampling wmake $targetType sampling
wmake $targetType fvMeshStitchers
wmake $targetType fvMeshMovers wmake $targetType fvMeshMovers
fvMeshTopoChangers/Allwmake $targetType $* fvMeshTopoChangers/Allwmake $targetType $*
wmake $targetType fvMeshDistributors wmake $targetType fvMeshDistributors

View File

@ -91,6 +91,7 @@ void Foam::LESModels::vanDriestDelta::calcDelta()
( (
mesh, mesh,
mesh.boundaryMesh().findPatchIDs<wallPolyPatch>(), mesh.boundaryMesh().findPatchIDs<wallPolyPatch>(),
minWallFaceFraction_,
2, // <-- roughly equivalent to old point-cell corrections 2, // <-- roughly equivalent to old point-cell corrections
y, y,
yStar, yStar,
@ -156,6 +157,14 @@ Foam::LESModels::vanDriestDelta::vanDriestDelta
"yPlusCutOff", "yPlusCutOff",
500 500
) )
),
minWallFaceFraction_
(
dict.optionalSubDict(type() + "Coeffs").lookupOrDefault<scalar>
(
"minWallFaceFraction",
0.1
)
) )
{ {
delta_ = geometricDelta_(); delta_ = geometricDelta_();

View File

@ -61,6 +61,7 @@ class vanDriestDelta
scalar Cdelta_; scalar Cdelta_;
label calcInterval_; label calcInterval_;
scalar yPlusCutOff_; scalar yPlusCutOff_;
scalar minWallFaceFraction_;
// Private Member Functions // Private Member Functions

View File

@ -31,7 +31,7 @@ License
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
Foam::scalar Foam::epsilonWallFunctionFvPatchScalarField::tolerance_ = 1e-5; Foam::scalar Foam::epsilonWallFunctionFvPatchScalarField::tolerance_ = 1e-1;
// * * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * // // * * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * //
@ -368,85 +368,35 @@ void Foam::epsilonWallFunctionFvPatchScalarField::updateCoeffs()
const scalarField& epsilon0 = this->epsilon(); const scalarField& epsilon0 = this->epsilon();
typedef DimensionedField<scalar, volMesh> FieldType; typedef DimensionedField<scalar, volMesh> FieldType;
FieldType& G = FieldType& G =
const_cast<FieldType&> const_cast<FieldType&>
( (
db().lookupObject<FieldType>(turbModel.GName()) db().lookupObject<FieldType>(turbModel.GName())
); );
FieldType& epsilon =
FieldType& epsilon = const_cast<FieldType&>(internalField());
forAll(*this, facei)
{
label celli = patch().faceCells()[facei];
G[celli] = G0[celli];
epsilon[celli] = epsilon0[celli];
}
fvPatchField<scalar>::updateCoeffs();
}
void Foam::epsilonWallFunctionFvPatchScalarField::updateWeightedCoeffs
(
const scalarField& weights
)
{
if (updated())
{
return;
}
const momentumTransportModel& turbModel =
db().lookupObject<momentumTransportModel>
(
IOobject::groupName
(
momentumTransportModel::typeName,
internalField().group()
)
);
setMaster();
if (patch().index() == master_)
{
createAveragingWeights();
calculateTurbulenceFields(turbModel, G(true), epsilon(true));
}
const scalarField& G0 = this->G();
const scalarField& epsilon0 = this->epsilon();
typedef DimensionedField<scalar, volMesh> FieldType;
FieldType& G =
const_cast<FieldType&> const_cast<FieldType&>
( (
db().lookupObject<FieldType>(turbModel.GName()) internalField()
); );
FieldType& epsilon = const_cast<FieldType&>(internalField()); scalarField weights(patch().magSf()/patch().patch().magFaceAreas());
scalarField& epsilonf = *this;
// Only set the values if the weights are > tolerance
forAll(weights, facei) forAll(weights, facei)
{ {
scalar w = weights[facei]; scalar& w = weights[facei];
w = w <= tolerance_ ? 0 : (w - tolerance_)/(1 - tolerance_);
}
if (w > tolerance_) forAll(weights, facei)
{ {
label celli = patch().faceCells()[facei]; const scalar w = weights[facei];
const label celli = patch().faceCells()[facei];
G[celli] = (1.0 - w)*G[celli] + w*G0[celli]; G[celli] = (1 - w)*G[celli] + w*G0[celli];
epsilon[celli] = (1.0 - w)*epsilon[celli] + w*epsilon0[celli]; epsilon[celli] = (1 - w)*epsilon[celli] + w*epsilon0[celli];
epsilonf[facei] = epsilon[celli];
}
} }
this->operator==(scalarField(epsilon, patch().faceCells()));
fvPatchField<scalar>::updateCoeffs(); fvPatchField<scalar>::updateCoeffs();
} }
@ -461,59 +411,20 @@ void Foam::epsilonWallFunctionFvPatchScalarField::manipulateMatrix
return; return;
} }
matrix.setValues(patch().faceCells(), patchInternalField()()); const scalarField& epsilon0 = this->epsilon();
fvPatchField<scalar>::manipulateMatrix(matrix);
}
void Foam::epsilonWallFunctionFvPatchScalarField::manipulateMatrix
(
fvMatrix<scalar>& matrix,
const Field<scalar>& weights
)
{
if (manipulatedMatrix())
{
return;
}
DynamicList<label> constraintCells(weights.size());
DynamicList<scalar> constraintEpsilon(weights.size());
const labelUList& faceCells = patch().faceCells();
const DimensionedField<scalar, volMesh>& epsilon
= internalField();
label nConstrainedCells = 0;
scalarField weights(patch().magSf()/patch().patch().magFaceAreas());
forAll(weights, facei) forAll(weights, facei)
{ {
// Only set the values if the weights are > tolerance scalar& w = weights[facei];
if (weights[facei] > tolerance_) w = w <= tolerance_ ? 0 : (w - tolerance_)/(1 - tolerance_);
{
nConstrainedCells++;
label celli = faceCells[facei];
constraintCells.append(celli);
constraintEpsilon.append(epsilon[celli]);
}
}
if (debug)
{
Pout<< "Patch: " << patch().name()
<< ": number of constrained cells = " << nConstrainedCells
<< " out of " << patch().size()
<< endl;
} }
matrix.setValues matrix.setValues
( (
constraintCells, patch().faceCells(),
scalarField(constraintEpsilon) UIndirectList<scalar>(epsilon0, patch().faceCells()),
weights
); );
fvPatchField<scalar>::manipulateMatrix(matrix); fvPatchField<scalar>::manipulateMatrix(matrix);

View File

@ -226,18 +226,8 @@ public:
//- Update the coefficients associated with the patch field //- Update the coefficients associated with the patch field
virtual void updateCoeffs(); virtual void updateCoeffs();
//- Update the coefficients associated with the patch field
virtual void updateWeightedCoeffs(const scalarField& weights);
//- Manipulate matrix //- Manipulate matrix
virtual void manipulateMatrix(fvMatrix<scalar>& matrix); virtual void manipulateMatrix(fvMatrix<scalar>& matrix);
//- Manipulate matrix with given weights
virtual void manipulateMatrix
(
fvMatrix<scalar>& matrix,
const scalarField& weights
);
}; };

View File

@ -36,7 +36,7 @@ namespace Foam
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
scalar omegaWallFunctionFvPatchScalarField::tolerance_ = 1e-5; scalar omegaWallFunctionFvPatchScalarField::tolerance_ = 1e-1;
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * // // * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
@ -415,77 +415,30 @@ void omegaWallFunctionFvPatchScalarField::updateCoeffs()
( (
db().lookupObject<FieldType>(turbModel.GName()) db().lookupObject<FieldType>(turbModel.GName())
); );
FieldType& omega =
FieldType& omega = const_cast<FieldType&>(internalField());
forAll(*this, facei)
{
label celli = patch().faceCells()[facei];
G[celli] = G0[celli];
omega[celli] = omega0[celli];
}
fvPatchField<scalar>::updateCoeffs();
}
void omegaWallFunctionFvPatchScalarField::updateWeightedCoeffs
(
const scalarField& weights
)
{
if (updated())
{
return;
}
const momentumTransportModel& turbModel =
db().lookupObject<momentumTransportModel>
(
IOobject::groupName
(
momentumTransportModel::typeName,
internalField().group()
)
);
setMaster();
if (patch().index() == master_)
{
createAveragingWeights();
calculateTurbulenceFields(turbModel, G(true), omega(true));
}
const scalarField& G0 = this->G();
const scalarField& omega0 = this->omega();
FieldType& G =
const_cast<FieldType&> const_cast<FieldType&>
( (
db().lookupObject<FieldType>(turbModel.GName()) internalField()
); );
FieldType& omega = const_cast<FieldType&>(internalField()); scalarField weights(patch().magSf()/patch().patch().magFaceAreas());
scalarField& omegaf = *this;
// only set the values if the weights are > tolerance
forAll(weights, facei) forAll(weights, facei)
{ {
scalar w = weights[facei]; scalar& w = weights[facei];
w = w <= tolerance_ ? 0 : (w - tolerance_)/(1 - tolerance_);
}
if (w > tolerance_) forAll(weights, facei)
{ {
label celli = patch().faceCells()[facei]; const scalar w = weights[facei];
const label celli = patch().faceCells()[facei];
G[celli] = (1.0 - w)*G[celli] + w*G0[celli]; G[celli] = (1 - w)*G[celli] + w*G0[celli];
omega[celli] = (1.0 - w)*omega[celli] + w*omega0[celli]; omega[celli] = (1 - w)*omega[celli] + w*omega0[celli];
omegaf[facei] = omega[celli];
}
} }
this->operator==(scalarField(omega, patch().faceCells()));
fvPatchField<scalar>::updateCoeffs(); fvPatchField<scalar>::updateCoeffs();
} }
@ -500,59 +453,20 @@ void omegaWallFunctionFvPatchScalarField::manipulateMatrix
return; return;
} }
matrix.setValues(patch().faceCells(), patchInternalField()()); const scalarField& omega0 = this->omega();
fvPatchField<scalar>::manipulateMatrix(matrix);
}
void omegaWallFunctionFvPatchScalarField::manipulateMatrix
(
fvMatrix<scalar>& matrix,
const Field<scalar>& weights
)
{
if (manipulatedMatrix())
{
return;
}
DynamicList<label> constraintCells(weights.size());
DynamicList<scalar> constraintomega(weights.size());
const labelUList& faceCells = patch().faceCells();
const DimensionedField<scalar, volMesh>& omega
= internalField();
label nConstrainedCells = 0;
scalarField weights(patch().magSf()/patch().patch().magFaceAreas());
forAll(weights, facei) forAll(weights, facei)
{ {
// only set the values if the weights are > tolerance scalar& w = weights[facei];
if (weights[facei] > tolerance_) w = w <= tolerance_ ? 0 : (w - tolerance_)/(1 - tolerance_);
{
nConstrainedCells++;
label celli = faceCells[facei];
constraintCells.append(celli);
constraintomega.append(omega[celli]);
}
}
if (debug)
{
Pout<< "Patch: " << patch().name()
<< ": number of constrained cells = " << nConstrainedCells
<< " out of " << patch().size()
<< endl;
} }
matrix.setValues matrix.setValues
( (
constraintCells, patch().faceCells(),
scalarField(constraintomega) UIndirectList<scalar>(omega0, patch().faceCells()),
weights
); );
fvPatchField<scalar>::manipulateMatrix(matrix); fvPatchField<scalar>::manipulateMatrix(matrix);

View File

@ -2,7 +2,7 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org \\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2011-2020 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2022 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -229,19 +229,9 @@ public:
//- Update the coefficients associated with the patch field //- Update the coefficients associated with the patch field
virtual void updateCoeffs(); virtual void updateCoeffs();
//- Update the coefficients associated with the patch field
virtual void updateWeightedCoeffs(const scalarField& weights);
//- Manipulate matrix //- Manipulate matrix
virtual void manipulateMatrix(fvMatrix<scalar>& matrix); virtual void manipulateMatrix(fvMatrix<scalar>& matrix);
//- Manipulate matrix with given weights
virtual void manipulateMatrix
(
fvMatrix<scalar>& matrix,
const scalarField& weights
);
// I-O // I-O

View File

@ -29,7 +29,7 @@ License
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
Foam::scalar Foam::epsilonmWallFunctionFvPatchScalarField::tolerance_ = 1e-5; Foam::scalar Foam::epsilonmWallFunctionFvPatchScalarField::tolerance_ = 1e-1;
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
@ -96,59 +96,20 @@ void Foam::epsilonmWallFunctionFvPatchScalarField::manipulateMatrix
return; return;
} }
matrix.setValues(patch().faceCells(), patchInternalField()()); const DimensionedField<scalar, volMesh>& epsilon = internalField();
fvPatchField<scalar>::manipulateMatrix(matrix);
}
void Foam::epsilonmWallFunctionFvPatchScalarField::manipulateMatrix
(
fvMatrix<scalar>& matrix,
const Field<scalar>& weights
)
{
if (manipulatedMatrix())
{
return;
}
DynamicList<label> constraintCells(weights.size());
DynamicList<scalar> constraintEpsilon(weights.size());
const labelUList& faceCells = patch().faceCells();
const DimensionedField<scalar, volMesh>& epsilon
= internalField();
label nConstrainedCells = 0;
scalarField weights(patch().magSf()/patch().patch().magFaceAreas());
forAll(weights, facei) forAll(weights, facei)
{ {
// Only set the values if the weights are > tolerance scalar& w = weights[facei];
if (weights[facei] > tolerance_) w = w <= tolerance_ ? 0 : (w - tolerance_)/(1 - tolerance_);
{
nConstrainedCells++;
label celli = faceCells[facei];
constraintCells.append(celli);
constraintEpsilon.append(epsilon[celli]);
}
}
if (debug)
{
Pout<< "Patch: " << patch().name()
<< ": number of constrained cells = " << nConstrainedCells
<< " out of " << patch().size()
<< endl;
} }
matrix.setValues matrix.setValues
( (
constraintCells, patch().faceCells(),
scalarField(constraintEpsilon) UIndirectList<scalar>(epsilon, patch().faceCells()),
weights
); );
fvPatchField<scalar>::manipulateMatrix(matrix); fvPatchField<scalar>::manipulateMatrix(matrix);

View File

@ -128,13 +128,6 @@ public:
//- Manipulate matrix //- Manipulate matrix
virtual void manipulateMatrix(fvMatrix<scalar>& matrix); virtual void manipulateMatrix(fvMatrix<scalar>& matrix);
//- Manipulate matrix with given weights
virtual void manipulateMatrix
(
fvMatrix<scalar>& matrix,
const scalarField& weights
);
}; };

View File

@ -471,9 +471,12 @@ Foam::GeometricBoundaryField<Type, PatchField, GeoMesh>::
boundaryInternalField() const boundaryInternalField() const
{ {
tmp<GeometricBoundaryField<Type, PatchField, GeoMesh>> tresult tmp<GeometricBoundaryField<Type, PatchField, GeoMesh>> tresult
(
new GeometricBoundaryField<Type, PatchField, GeoMesh>
( (
GeometricField<Type, PatchField, GeoMesh>::Internal::null(), GeometricField<Type, PatchField, GeoMesh>::Internal::null(),
*this *this
)
); );
GeometricBoundaryField<Type, PatchField, GeoMesh>& result = tresult.ref(); GeometricBoundaryField<Type, PatchField, GeoMesh>& result = tresult.ref();
@ -686,6 +689,17 @@ void Foam::GeometricBoundaryField<Type, PatchField, GeoMesh>::operator=
} }
template<class Type, template<class> class PatchField, class GeoMesh>
template<template<class> class OtherPatchField>
void Foam::GeometricBoundaryField<Type, PatchField, GeoMesh>::operator=
(
const FieldField<OtherPatchField, Type>& ptff
)
{
FieldField<PatchField, Type>::operator=(ptff);
}
template<class Type, template<class> class PatchField, class GeoMesh> template<class Type, template<class> class PatchField, class GeoMesh>
void Foam::GeometricBoundaryField<Type, PatchField, GeoMesh>:: void Foam::GeometricBoundaryField<Type, PatchField, GeoMesh>::
operator= operator=
@ -724,6 +738,21 @@ operator==
} }
template<class Type, template<class> class PatchField, class GeoMesh>
template<template<class> class OtherPatchField>
void Foam::GeometricBoundaryField<Type, PatchField, GeoMesh>::
operator==
(
const FieldField<OtherPatchField, Type>& ptff
)
{
forAll((*this), patchi)
{
this->operator[](patchi) == ptff[patchi];
}
}
template<class Type, template<class> class PatchField, class GeoMesh> template<class Type, template<class> class PatchField, class GeoMesh>
void Foam::GeometricBoundaryField<Type, PatchField, GeoMesh>::operator== void Foam::GeometricBoundaryField<Type, PatchField, GeoMesh>::operator==
( (

View File

@ -182,6 +182,10 @@ public:
//- Assignment to FieldField<PatchField, Type> //- Assignment to FieldField<PatchField, Type>
void operator=(const FieldField<PatchField, Type>&); void operator=(const FieldField<PatchField, Type>&);
//- Assignment to FieldField<OtherPatchField, Type>
template<template<class> class OtherPatchField>
void operator=(const FieldField<OtherPatchField, Type>&);
//- Assignment to Type //- Assignment to Type
void operator=(const Type&); void operator=(const Type&);
@ -193,6 +197,10 @@ public:
//- Forced assignment to FieldField<PatchField, Type> //- Forced assignment to FieldField<PatchField, Type>
void operator==(const FieldField<PatchField, Type>&); void operator==(const FieldField<PatchField, Type>&);
//- Forced assignment to FieldField<OtherPatchField, Type>
template<template<class> class OtherPatchField>
void operator==(const FieldField<OtherPatchField, Type>&);
//- Forced assignment to Type //- Forced assignment to Type
void operator==(const Type&); void operator==(const Type&);
}; };

View File

@ -736,6 +736,30 @@ Foam::GeometricField<Type, PatchField, GeoMesh>::clone() const
} }
template<class Type, template<class> class PatchField, class GeoMesh>
Foam::tmp<Foam::GeometricField<Type, PatchField, GeoMesh>>
Foam::GeometricField<Type, PatchField, GeoMesh>::cloneUnSliced() const
{
return tmp<GeometricField<Type, PatchField, GeoMesh>>
(
new GeometricField<Type, PatchField, GeoMesh>
(
IOobject
(
this->name(),
this->mesh().thisDb().time().timeName(),
this->mesh().thisDb(),
IOobject::NO_READ,
IOobject::NO_WRITE,
false
),
*this,
GeometricField<Type, PatchField, GeoMesh>::Patch::calculatedType()
)
);
}
template<class Type, template<class> class PatchField, class GeoMesh> template<class Type, template<class> class PatchField, class GeoMesh>
Foam::tmp<Foam::GeometricField<Type, PatchField, GeoMesh>> Foam::tmp<Foam::GeometricField<Type, PatchField, GeoMesh>>
Foam::GeometricField<Type, PatchField, GeoMesh>::New Foam::GeometricField<Type, PatchField, GeoMesh>::New

View File

@ -292,6 +292,9 @@ public:
//- Clone //- Clone
tmp<GeometricField<Type, PatchField, GeoMesh>> clone() const; tmp<GeometricField<Type, PatchField, GeoMesh>> clone() const;
//- Clone un-sliced
tmp<GeometricField<Type, PatchField, GeoMesh>> cloneUnSliced() const;
//- Return a temporary field constructed from name, //- Return a temporary field constructed from name,
// internal field and list of patch fields // internal field and list of patch fields
static tmp<GeometricField<Type, PatchField, GeoMesh>> New static tmp<GeometricField<Type, PatchField, GeoMesh>> New

View File

@ -2,7 +2,7 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org \\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2011-2020 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2022 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -109,28 +109,6 @@ public:
{ {
return true; return true;
} }
//- Evaluate the patch field
virtual void evaluate
(
const Pstream::commsTypes commsType =
Pstream::commsTypes::blocking
) = 0;
//- Initialise swap of patch point values
virtual void initSwapAddSeparated
(
const Pstream::commsTypes,
Field<Type>&
) const
{}
//- Complete swap of patch point values and add to local values
virtual void swapAddSeparated
(
const Pstream::commsTypes,
Field<Type>&
) const = 0;
}; };

View File

@ -2,7 +2,7 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org \\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2011-2020 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2022 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -101,68 +101,4 @@ Foam::cyclicPointPatchField<Type>::cyclicPointPatchField
{} {}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class Type>
void Foam::cyclicPointPatchField<Type>::swapAddSeparated
(
const Pstream::commsTypes,
Field<Type>& pField
) const
{
// Get neighbouring pointPatch
const cyclicPointPatch& nbrPatch = cyclicPatch_.nbrPatch();
if (cyclicPatch_.cyclicPatch().owner())
{
// We inplace modify pField. To prevent the other side (which gets
// evaluated at a later date) using already changed values we do
// all swaps on the side that gets evaluated first.
// Get neighbouring pointPatchField
const GeometricField<Type, pointPatchField, pointMesh>& fld =
refCast<const GeometricField<Type, pointPatchField, pointMesh>>
(
this->internalField()
);
const cyclicPointPatchField<Type>& nbr =
refCast<const cyclicPointPatchField<Type>>
(
fld.boundaryField()[nbrPatch.index()]
);
Field<Type> pf(this->patchInternalField(pField));
Field<Type> nbrPf(nbr.patchInternalField(pField));
const edgeList& pairs = cyclicPatch_.transformPairs();
if (transform().template transforms<Type>())
{
// Transform both sides.
forAll(pairs, pairi)
{
label pointi = pairs[pairi][0];
label nbrPointi = pairs[pairi][1];
Type tmp = pf[pointi];
pf[pointi] = transform().transform(nbrPf[nbrPointi]);
nbrPf[nbrPointi] = transform().invTransform(tmp);
}
}
else
{
forAll(pairs, pairi)
{
Swap(pf[pairs[pairi][0]], nbrPf[pairs[pairi][1]]);
}
}
this->addToInternalField(pField, pf);
nbr.addToInternalField(pField, nbrPf);
}
}
// ************************************************************************* // // ************************************************************************* //

View File

@ -2,7 +2,7 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org \\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2011-2021 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2022 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -133,13 +133,6 @@ public:
Pstream::commsTypes::blocking Pstream::commsTypes::blocking
) )
{} {}
//- Complete swap of patch point values and add to local values
virtual void swapAddSeparated
(
const Pstream::commsTypes commsType,
Field<Type>&
) 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 | Website: https://openfoam.org \\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2011-2021 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2022 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -144,14 +144,6 @@ public:
Pstream::commsTypes::blocking Pstream::commsTypes::blocking
) )
{} {}
//- Assume processor patch always collocated
virtual void swapAddSeparated
(
const Pstream::commsTypes commsType,
Field<Type>&
) 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 | Website: https://openfoam.org \\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2011-2020 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2022 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -91,87 +91,4 @@ Foam::processorCyclicPointPatchField<Type>::~processorCyclicPointPatchField()
{} {}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class Type>
void Foam::processorCyclicPointPatchField<Type>::initSwapAddSeparated
(
const Pstream::commsTypes commsType,
Field<Type>& pField
) const
{
if (Pstream::parRun())
{
// Get internal field into correct order for opposite side
Field<Type> pf
(
this->patchInternalField
(
pField,
procPatch_.reverseMeshPoints()
)
);
if (commsType == Pstream::commsTypes::nonBlocking)
{
receiveBuf_.setSize(pf.size());
IPstream::read
(
commsType,
procPatch_.neighbProcNo(),
reinterpret_cast<char*>(receiveBuf_.begin()),
receiveBuf_.byteSize(),
procPatch_.tag(),
procPatch_.comm()
);
}
OPstream::write
(
commsType,
procPatch_.neighbProcNo(),
reinterpret_cast<const char*>(pf.begin()),
pf.byteSize(),
procPatch_.tag(),
procPatch_.comm()
);
}
}
template<class Type>
void Foam::processorCyclicPointPatchField<Type>::swapAddSeparated
(
const Pstream::commsTypes commsType,
Field<Type>& pField
) const
{
if (Pstream::parRun())
{
// If nonblocking data has already been received into receiveBuf_
if (commsType != Pstream::commsTypes::nonBlocking)
{
receiveBuf_.setSize(this->size());
IPstream::read
(
commsType,
procPatch_.neighbProcNo(),
reinterpret_cast<char*>(receiveBuf_.begin()),
receiveBuf_.byteSize(),
procPatch_.tag(),
procPatch_.comm()
);
}
procPatch_.procCyclicPolyPatch().transform().transform
(
receiveBuf_,
receiveBuf_
);
// All points are separated
this->addToInternalField(pField, receiveBuf_);
}
}
// ************************************************************************* // // ************************************************************************* //

View File

@ -2,7 +2,7 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org \\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2011-2020 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2022 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -148,20 +148,6 @@ public:
Pstream::commsTypes::blocking Pstream::commsTypes::blocking
) )
{} {}
//- Initialise swap of non-collocated patch point values
virtual void initSwapAddSeparated
(
const Pstream::commsTypes commsType,
Field<Type>&
) const;
//- Complete swap of patch point values and add to local values
virtual void swapAddSeparated
(
const Pstream::commsTypes commsType,
Field<Type>&
) 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 | Website: https://openfoam.org \\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2011-2021 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2022 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -295,6 +295,20 @@ bool Foam::argList::postProcess(int argc, char *argv[])
} }
bool Foam::argList::hasArgs(int argc, char *argv[])
{
for (int i=1; i<argc; i++)
{
if (argv[i][0] != '-')
{
return true;
}
}
return false;
}
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
// Convert argv -> args_ // Convert argv -> args_

View File

@ -368,6 +368,9 @@ public:
//- Return true if the post-processing option is specified //- Return true if the post-processing option is specified
static bool postProcess(int argc, char *argv[]); static bool postProcess(int argc, char *argv[]);
//- Return true if there are arguments
static bool hasArgs(int argc, char *argv[]);
//- Set option directly (use with caution) //- Set option directly (use with caution)
// An option with an empty param is a bool option. // An option with an empty param is a bool option.
// Not all valid options can also be set: eg, -case, -roots, ... // Not all valid options can also be set: eg, -case, -roots, ...

View File

@ -2,7 +2,7 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org \\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2011-2018 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2022 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -102,12 +102,12 @@ void Foam::SolverPerformance<Type>::print
{ {
if (pTraits<Type>::nComponents == 1) if (pTraits<Type>::nComponents == 1)
{ {
os << solverName_ << ": Solving for " << fieldName_; os << indent << solverName_ << ": Solving for " << fieldName_;
} }
else else
{ {
os << solverName_ << ": Solving for " os << indent << solverName_ << ": Solving for "
<< word(fieldName_ + pTraits<Type>::componentNames[cmpt]); << word(fieldName_ + pTraits<Type>::componentNames[cmpt]);
} }

View File

@ -2,7 +2,7 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org \\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2011-2020 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2022 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -60,6 +60,22 @@ namespace Foam
lduInterfaceField, lduInterfaceField,
cyclicSlip cyclicSlip
); );
// Add under name nonConformalCyclic
addNamedToRunTimeSelectionTable
(
GAMGInterfaceField,
cyclicGAMGInterfaceField,
lduInterface,
nonConformalCyclic
);
addNamedToRunTimeSelectionTable
(
GAMGInterfaceField,
cyclicGAMGInterfaceField,
lduInterfaceField,
nonConformalCyclic
);
} }

View File

@ -2,7 +2,7 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org \\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2011-2020 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2022 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -44,6 +44,22 @@ namespace Foam
processorCyclicGAMGInterfaceField, processorCyclicGAMGInterfaceField,
lduInterfaceField lduInterfaceField
); );
// Add under name nonConformalProcessorCyclic
addNamedToRunTimeSelectionTable
(
GAMGInterfaceField,
processorCyclicGAMGInterfaceField,
lduInterface,
nonConformalProcessorCyclic
);
addNamedToRunTimeSelectionTable
(
GAMGInterfaceField,
processorCyclicGAMGInterfaceField,
lduInterfaceField,
nonConformalProcessorCyclic
);
} }

View File

@ -2,7 +2,7 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org \\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2011-2020 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2022 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -46,7 +46,6 @@ namespace Foam
Istream Istream
); );
// Add under name cyclicSlip // Add under name cyclicSlip
addNamedToRunTimeSelectionTable addNamedToRunTimeSelectionTable
( (
@ -62,6 +61,22 @@ namespace Foam
Istream, Istream,
cyclicSlip cyclicSlip
); );
// Add under name nonConformalCyclic
addNamedToRunTimeSelectionTable
(
GAMGInterface,
cyclicGAMGInterface,
lduInterface,
nonConformalCyclic
);
addNamedToRunTimeSelectionTable
(
GAMGInterface,
cyclicGAMGInterface,
Istream,
nonConformalCyclic
);
} }

View File

@ -2,7 +2,7 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org \\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2011-2018 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2022 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -44,6 +44,22 @@ namespace Foam
processorCyclicGAMGInterface, processorCyclicGAMGInterface,
Istream Istream
); );
// Add under name nonConformalProcessorCyclic
addNamedToRunTimeSelectionTable
(
GAMGInterface,
processorCyclicGAMGInterface,
lduInterface,
nonConformalProcessorCyclic
);
addNamedToRunTimeSelectionTable
(
GAMGInterface,
processorCyclicGAMGInterface,
Istream,
nonConformalProcessorCyclic
);
} }

View File

@ -131,12 +131,7 @@ Foam::solution::solution
dictName, dictName,
obr.time().system(), obr.time().system(),
obr, obr,
( IOobject::MUST_READ_IF_MODIFIED,
obr.readOpt() == IOobject::MUST_READ
|| obr.readOpt() == IOobject::READ_IF_PRESENT
? IOobject::MUST_READ_IF_MODIFIED
: obr.readOpt()
),
IOobject::NO_WRITE IOobject::NO_WRITE
) )
), ),
@ -147,17 +142,9 @@ Foam::solution::solution
fieldRelaxDefault_(0), fieldRelaxDefault_(0),
eqnRelaxDefault_(0), eqnRelaxDefault_(0),
solvers_(dictionary::null) solvers_(dictionary::null)
{
if
(
readOpt() == IOobject::MUST_READ
|| readOpt() == IOobject::MUST_READ_IF_MODIFIED
|| (readOpt() == IOobject::READ_IF_PRESENT && headerOk())
)
{ {
read(dict()); read(dict());
} }
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //

View File

@ -151,15 +151,8 @@ public:
return !isMaster(); return !isMaster();
} }
//- Return the underlying processorPolyPatch
const processorPolyPatch& procPolyPatch() const
{
return procPolyPatch_;
}
//- Return mesh points in the correct order for the receiving side //- Return mesh points in the correct order for the receiving side
const labelList& reverseMeshPoints() const; const labelList& reverseMeshPoints() const;
}; };

View File

@ -431,6 +431,35 @@ const Foam::labelList& Foam::polyBoundaryMesh::patchID() const
} }
const Foam::labelList& Foam::polyBoundaryMesh::patchFaceID() const
{
if (!patchFaceIDPtr_.valid())
{
patchFaceIDPtr_.reset
(
new labelList
(
mesh_.nFaces()
- mesh_.nInternalFaces()
)
);
labelList& patchFaceID = patchFaceIDPtr_();
const polyBoundaryMesh& bm = *this;
forAll(bm, patchi)
{
label bFacei = bm[patchi].start() - mesh_.nInternalFaces();
forAll(bm[patchi], i)
{
patchFaceID[bFacei++] = i;
}
}
}
return patchFaceIDPtr_();
}
const Foam::HashTable<Foam::labelList, Foam::word>& const Foam::HashTable<Foam::labelList, Foam::word>&
Foam::polyBoundaryMesh::groupPatchIDs() const Foam::polyBoundaryMesh::groupPatchIDs() const
{ {

View File

@ -70,6 +70,8 @@ class polyBoundaryMesh
mutable autoPtr<labelList> patchIDPtr_; mutable autoPtr<labelList> patchIDPtr_;
mutable autoPtr<labelList> patchFaceIDPtr_;
mutable autoPtr<HashTable<labelList, word>> groupPatchIDsPtr_; mutable autoPtr<HashTable<labelList, word>> groupPatchIDsPtr_;
//- Edges of neighbouring patches //- Edges of neighbouring patches
@ -183,6 +185,9 @@ public:
//- Per boundary face label the patch index //- Per boundary face label the patch index
const labelList& patchID() const; const labelList& patchID() const;
//- Per boundary face label the patch face index
const labelList& patchFaceID() const;
//- Per patch group the patch indices //- Per patch group the patch indices
const HashTable<labelList, word>& groupPatchIDs() const; const HashTable<labelList, word>& groupPatchIDs() const;

View File

@ -403,6 +403,9 @@ public:
//- Set the instance for mesh files //- Set the instance for mesh files
void setInstance(const fileName&); void setInstance(const fileName&);
//- Set the instance for the points files
void setPointsInstance(const fileName&);
// Access // Access

View File

@ -68,6 +68,24 @@ void Foam::polyMesh::setInstance(const fileName& inst)
} }
void Foam::polyMesh::setPointsInstance(const fileName& inst)
{
if (debug)
{
InfoInFunction << "Resetting file instance to " << inst << endl;
}
points_.writeOpt() = IOobject::AUTO_WRITE;
points_.instance() = inst;
if (tetBasePtIsPtr_.valid())
{
tetBasePtIsPtr_->writeOpt() = IOobject::AUTO_WRITE;
tetBasePtIsPtr_->instance() = inst;
}
}
Foam::polyMesh::readUpdateState Foam::polyMesh::readUpdate() Foam::polyMesh::readUpdateState Foam::polyMesh::readUpdate()
{ {
if (debug) if (debug)

View File

@ -39,6 +39,36 @@ namespace Foam
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::processorCyclicPolyPatch::processorCyclicPolyPatch
(
const word& name,
const label size,
const label start,
const label index,
const polyBoundaryMesh& bm,
const int myProcNo,
const int neighbProcNo,
const word& referPatchName,
const word& patchType
)
:
processorPolyPatch
(
name,
size,
start,
index,
bm,
myProcNo,
neighbProcNo,
patchType
),
referPatchName_(referPatchName),
tag_(-1),
referPatchID_(-1)
{}
Foam::processorCyclicPolyPatch::processorCyclicPolyPatch Foam::processorCyclicPolyPatch::processorCyclicPolyPatch
( (
const label size, const label size,

View File

@ -67,6 +67,23 @@ class processorCyclicPolyPatch
protected: protected:
// Protected constructors
//- Construct from components with specified name
processorCyclicPolyPatch
(
const word& name,
const label size,
const label start,
const label index,
const polyBoundaryMesh& bm,
const int myProcNo,
const int neighbProcNo,
const word& referPatchName,
const word& patchType = typeName
);
// Protected Member functions // Protected Member functions
//- Initialise the calculation of the patch geometry //- Initialise the calculation of the patch geometry
@ -245,7 +262,7 @@ public:
const polyBoundaryMesh& bm const polyBoundaryMesh& bm
); );
//- Referring patchID. //- Return the referring patchID
label referPatchID() const label referPatchID() const
{ {
if (referPatchID_ == -1) if (referPatchID_ == -1)
@ -266,6 +283,7 @@ public:
return referPatchID_; return referPatchID_;
} }
//- Return a reference to the referring patch
const cyclicPolyPatch& referPatch() const const cyclicPolyPatch& referPatch() const
{ {
const polyPatch& pp = this->boundaryMesh()[referPatchID()]; const polyPatch& pp = this->boundaryMesh()[referPatchID()];

View File

@ -39,6 +39,14 @@ Description
#include "polyTopoChange.H" #include "polyTopoChange.H"
#include "polyTopoChangeMap.H" #include "polyTopoChangeMap.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
defineTypeNameAndDebug(fvMeshSubset, 0);
}
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
bool Foam::fvMeshSubset::checkCellSubset() const bool Foam::fvMeshSubset::checkCellSubset() const
@ -264,7 +272,7 @@ void Foam::fvMeshSubset::doCoupledPatches
reduce(nUncoupled, sumOp<label>()); reduce(nUncoupled, sumOp<label>());
} }
if (nUncoupled > 0) if (debug && nUncoupled > 0)
{ {
Info<< "Uncoupled " << nUncoupled << " faces on coupled patches. " Info<< "Uncoupled " << nUncoupled << " faces on coupled patches. "
<< "(processorPolyPatch, cyclicPolyPatch)" << endl; << "(processorPolyPatch, cyclicPolyPatch)" << endl;
@ -473,6 +481,12 @@ Foam::fvMeshSubset::fvMeshSubset(const fvMesh& baseMesh)
{} {}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::fvMeshSubset::~fvMeshSubset()
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
void Foam::fvMeshSubset::setCellSubset void Foam::fvMeshSubset::setCellSubset

View File

@ -2,7 +2,7 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org \\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2011-2021 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2022 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -137,6 +137,10 @@ class fvMeshSubset
public: public:
//- Runtime type information
TypeName("fvMeshSubset");
// Constructors // Constructors
//- Construct given a mesh to subset //- Construct given a mesh to subset
@ -146,6 +150,10 @@ public:
fvMeshSubset(const fvMeshSubset&) = delete; fvMeshSubset(const fvMeshSubset&) = delete;
//- Destructor
virtual ~fvMeshSubset();
// Member Functions // Member Functions
// Edit // Edit

View File

@ -31,6 +31,11 @@ $(constraintFvPatches)/symmetryPlane/symmetryPlaneFvPatch.C
$(constraintFvPatches)/symmetry/symmetryFvPatch.C $(constraintFvPatches)/symmetry/symmetryFvPatch.C
$(constraintFvPatches)/wedge/wedgeFvPatch.C $(constraintFvPatches)/wedge/wedgeFvPatch.C
$(constraintFvPatches)/internal/internalFvPatch.C $(constraintFvPatches)/internal/internalFvPatch.C
$(constraintFvPatches)/nonConformal/nonConformalFvPatch.C
$(constraintFvPatches)/nonConformalCoupled/nonConformalCoupledFvPatch.C
$(constraintFvPatches)/nonConformalCyclic/nonConformalCyclicFvPatch.C
$(constraintFvPatches)/nonConformalError/nonConformalErrorFvPatch.C
$(constraintFvPatches)/nonConformalProcessorCyclic/nonConformalProcessorCyclicFvPatch.C
derivedFvPatches = $(fvPatches)/derived derivedFvPatches = $(fvPatches)/derived
$(derivedFvPatches)/wall/wallFvPatch.C $(derivedFvPatches)/wall/wallFvPatch.C
@ -115,6 +120,12 @@ $(fvMeshMovers)/fvMeshMover/fvMeshMover.C
$(fvMeshMovers)/fvMeshMover/fvMeshMoverNew.C $(fvMeshMovers)/fvMeshMover/fvMeshMoverNew.C
$(fvMeshMovers)/none/fvMeshMoversNone.C $(fvMeshMovers)/none/fvMeshMoversNone.C
fvMeshStitchers = fvMesh/fvMeshStitchers
$(fvMeshStitchers)/fvMeshStitcher/fvMeshStitcher.C
$(fvMeshStitchers)/fvMeshStitcher/fvMeshStitcherNew.C
$(fvMeshStitchers)/stationary/fvMeshStitchersStationary.C
functionObjects/fvMeshFunctionObject/fvMeshFunctionObject.C functionObjects/fvMeshFunctionObject/fvMeshFunctionObject.C
functionObjects/volRegion/volRegion.C functionObjects/volRegion/volRegion.C
@ -153,6 +164,9 @@ $(constraintFvPatchFields)/symmetry/symmetryFvPatchFields.C
$(constraintFvPatchFields)/wedge/wedgeFvPatchFields.C $(constraintFvPatchFields)/wedge/wedgeFvPatchFields.C
$(constraintFvPatchFields)/wedge/wedgeFvPatchScalarField.C $(constraintFvPatchFields)/wedge/wedgeFvPatchScalarField.C
$(constraintFvPatchFields)/internal/internalFvPatchFields.C $(constraintFvPatchFields)/internal/internalFvPatchFields.C
$(constraintFvPatchFields)/nonConformalCyclic/nonConformalCyclicFvPatchFields.C
$(constraintFvPatchFields)/nonConformalError/nonConformalErrorFvPatchFields.C
$(constraintFvPatchFields)/nonConformalProcessorCyclic/nonConformalProcessorCyclicFvPatchFields.C
derivedFvPatchFields = $(fvPatchFields)/derived derivedFvPatchFields = $(fvPatchFields)/derived
$(derivedFvPatchFields)/activeBaffleVelocity/activeBaffleVelocityFvPatchVectorField.C $(derivedFvPatchFields)/activeBaffleVelocity/activeBaffleVelocityFvPatchVectorField.C
@ -250,6 +264,7 @@ $(fvsPatchFields)/fvsPatchField/fvsPatchFields.C
basicFvsPatchFields = $(fvsPatchFields)/basic basicFvsPatchFields = $(fvsPatchFields)/basic
$(basicFvsPatchFields)/calculated/calculatedFvsPatchFields.C $(basicFvsPatchFields)/calculated/calculatedFvsPatchFields.C
$(basicFvsPatchFields)/nonConformalCalculated/nonConformalCalculatedFvsPatchFields.C
$(basicFvsPatchFields)/coupled/coupledFvsPatchFields.C $(basicFvsPatchFields)/coupled/coupledFvsPatchFields.C
$(basicFvsPatchFields)/fixedValue/fixedValueFvsPatchFields.C $(basicFvsPatchFields)/fixedValue/fixedValueFvsPatchFields.C
$(basicFvsPatchFields)/sliced/slicedFvsPatchFields.C $(basicFvsPatchFields)/sliced/slicedFvsPatchFields.C
@ -267,6 +282,9 @@ $(constraintFvsPatchFields)/symmetryPlane/symmetryPlaneFvsPatchFields.C
$(constraintFvsPatchFields)/symmetry/symmetryFvsPatchFields.C $(constraintFvsPatchFields)/symmetry/symmetryFvsPatchFields.C
$(constraintFvsPatchFields)/wedge/wedgeFvsPatchFields.C $(constraintFvsPatchFields)/wedge/wedgeFvsPatchFields.C
$(constraintFvsPatchFields)/internal/internalFvsPatchFields.C $(constraintFvsPatchFields)/internal/internalFvsPatchFields.C
$(constraintFvsPatchFields)/nonConformalCyclic/nonConformalCyclicFvsPatchFields.C
$(constraintFvsPatchFields)/nonConformalError/nonConformalErrorFvsPatchFields.C
$(constraintFvsPatchFields)/nonConformalProcessorCyclic/nonConformalProcessorCyclicFvsPatchFields.C
fields/volFields/volFields.C fields/volFields/volFields.C
fields/surfaceFields/surfaceFields.C fields/surfaceFields/surfaceFields.C

View File

@ -27,6 +27,7 @@ License
#include "processorFvPatch.H" #include "processorFvPatch.H"
#include "cyclicFvPatch.H" #include "cyclicFvPatch.H"
#include "cyclicAMIFvPatch.H" #include "cyclicAMIFvPatch.H"
#include "CompactListList.H"
#include "OPstream.H" #include "OPstream.H"
#include "IPstream.H" #include "IPstream.H"
#include "PstreamReduceOps.H" #include "PstreamReduceOps.H"
@ -850,9 +851,9 @@ Foam::label Foam::FvFaceCellWave<Type, TrackingData>::faceToCell()
const labelList& owner = mesh_.owner(); const labelList& owner = mesh_.owner();
const labelList& neighbour = mesh_.neighbour(); const labelList& neighbour = mesh_.neighbour();
forAll(changedPatchAndFaces_, i) forAll(changedPatchAndFaces_, changedFacei)
{ {
const labelPair& patchAndFacei = changedPatchAndFaces_[i]; const labelPair& patchAndFacei = changedPatchAndFaces_[changedFacei];
const label patchi = patchAndFacei.first(); const label patchi = patchAndFacei.first();
const label facei = patchAndFacei.second(); const label facei = patchAndFacei.second();
@ -929,9 +930,9 @@ Foam::label Foam::FvFaceCellWave<Type, TrackingData>::cellToFace()
{ {
const cellList& cells = mesh_.cells(); const cellList& cells = mesh_.cells();
forAll(changedCells_, i) forAll(changedCells_, changedCelli)
{ {
const label celli = changedCells_[i]; const label celli = changedCells_[changedCelli];
if (!cellChanged_[celli]) if (!cellChanged_[celli])
{ {
@ -946,30 +947,33 @@ Foam::label Foam::FvFaceCellWave<Type, TrackingData>::cellToFace()
forAll(cells[celli], cellFacei) forAll(cells[celli], cellFacei)
{ {
// Get the patch (if any) and face index // Get the patch (if any) and face index
label patchi, facei; label polyFacei = cells[celli][cellFacei];
const label polyFacei = cells[celli][cellFacei];
// Get the FV patches and faces associated with this poly face
labelUList patches, faces;
if (polyFacei < mesh_.nInternalFaces()) if (polyFacei < mesh_.nInternalFaces())
{ {
patchi = -1; static label noPatchi = -1;
facei = polyFacei; patches.shallowCopy(labelUList(&noPatchi, 1));
faces.shallowCopy(labelUList(&polyFacei, 1));
} }
else else
{ {
const label polyBFacei = polyFacei - mesh_.nInternalFaces(); const label polyBFacei = polyFacei - mesh_.nInternalFaces();
patchi = mesh_.boundaryMesh().patchID()[polyBFacei]; patches.shallowCopy(mesh_.polyBFacePatches()[polyBFacei]);
facei = polyFacei - mesh_.boundaryMesh()[patchi].start(); faces.shallowCopy(mesh_.polyBFacePatchFaces()[polyBFacei]);
} }
// If connected to an empty patch then skip this face // Propagate into the connected FV faces
if (patchi != -1 && !mesh_.boundary()[patchi].size()) continue; forAll(patches, i)
{
Type& connectedInfo = faceInfo({patchi, facei}); Type& connectedInfo = faceInfo({patches[i], faces[i]});
if (!connectedInfo.equal(info, td_)) if (!connectedInfo.equal(info, td_))
{ {
updateFace updateFace
( (
{patchi, facei}, {patches[i], faces[i]},
celli, celli,
info, info,
propagationTol_, propagationTol_,
@ -977,6 +981,7 @@ Foam::label Foam::FvFaceCellWave<Type, TrackingData>::cellToFace()
); );
} }
} }
}
// Reset status of cell // Reset status of cell
cellChanged_[celli] = false; cellChanged_[celli] = false;

View File

@ -2,7 +2,7 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org \\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2011-2020 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2022 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -126,7 +126,11 @@ public:
} }
//- Return neighbour field of internal field //- Return neighbour field of internal field
virtual tmp<Field<Type>> patchNeighbourField() const = 0; virtual tmp<Field<Type>> patchNeighbourField
(
const Pstream::commsTypes commsType =
Pstream::commsTypes::blocking
) const = 0;
// Evaluation functions // Evaluation functions

View File

@ -2,7 +2,7 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org \\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2011-2020 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2022 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -112,46 +112,6 @@ void Foam::slicedFvPatchField<Type>::updateCoeffs()
} }
template<class Type>
Foam::tmp<Foam::Field<Type>>
Foam::slicedFvPatchField<Type>::patchInternalField() const
{
NotImplemented;
return Field<Type>::null();
}
template<class Type>
void Foam::slicedFvPatchField<Type>::patchInternalField(Field<Type>&) const
{
NotImplemented;
}
template<class Type>
Foam::tmp<Foam::Field<Type>>
Foam::slicedFvPatchField<Type>::patchNeighbourField
(
const Field<Type>& iField
) const
{
NotImplemented;
return Field<Type>::null();
}
template<class Type>
Foam::tmp<Foam::Field<Type>>
Foam::slicedFvPatchField<Type>::patchNeighbourField() const
{
NotImplemented;
return Field<Type>::null();
}
template<class Type> template<class Type>
Foam::tmp<Foam::Field<Type>> Foam::tmp<Foam::Field<Type>>
Foam::slicedFvPatchField<Type>::valueInternalCoeffs Foam::slicedFvPatchField<Type>::valueInternalCoeffs

View File

@ -2,7 +2,7 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org \\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2011-2021 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2022 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -134,22 +134,6 @@ public:
// Sets Updated to true // Sets Updated to true
virtual void updateCoeffs(); virtual void updateCoeffs();
//- Return internal field next to patch as patch field
virtual tmp<Field<Type>> patchInternalField() const;
//- Return internal field next to patch as patch field
virtual void patchInternalField(Field<Type>&) const;
//- Return neighbour coupled given internal cell data
virtual tmp<Field<Type>> patchNeighbourField
(
const Field<Type>& iField
) const;
//- Return patchField of the values on the patch or on the
// opposite patch
virtual tmp<Field<Type>> patchNeighbourField() const;
//- Initialise the evaluation of the patch field //- Initialise the evaluation of the patch field
virtual void initEvaluate virtual void initEvaluate
( (

View File

@ -2,7 +2,7 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org \\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2011-2021 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2022 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -110,7 +110,10 @@ Foam::cyclicFvPatchField<Type>::cyclicFvPatchField
template<class Type> template<class Type>
Foam::tmp<Foam::Field<Type>> Foam::tmp<Foam::Field<Type>>
Foam::cyclicFvPatchField<Type>::patchNeighbourField() const Foam::cyclicFvPatchField<Type>::patchNeighbourField
(
const Pstream::commsTypes
) const
{ {
const Field<Type>& iField = this->primitiveField(); const Field<Type>& iField = this->primitiveField();
const labelUList& nbrFaceCells = const labelUList& nbrFaceCells =
@ -119,7 +122,6 @@ Foam::cyclicFvPatchField<Type>::patchNeighbourField() const
tmp<Field<Type>> tpnf(new Field<Type>(this->size())); tmp<Field<Type>> tpnf(new Field<Type>(this->size()));
Field<Type>& pnf = tpnf.ref(); Field<Type>& pnf = tpnf.ref();
forAll(pnf, facei) forAll(pnf, facei)
{ {
pnf[facei] = transform().transform(iField[nbrFaceCells[facei]]); pnf[facei] = transform().transform(iField[nbrFaceCells[facei]]);

View File

@ -144,7 +144,10 @@ public:
// Evaluation functions // Evaluation functions
//- Return neighbour coupled internal cell data //- Return neighbour coupled internal cell data
tmp<Field<Type>> patchNeighbourField() const; virtual tmp<Field<Type>> patchNeighbourField
(
const Pstream::commsTypes commsType
) const;
//- Return reference to neighbour patchField //- Return reference to neighbour patchField
const cyclicFvPatchField<Type>& nbrPatchField() const; const cyclicFvPatchField<Type>& nbrPatchField() 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 | Website: https://openfoam.org \\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2013-2018 OpenFOAM Foundation \\ / A nd | Copyright (C) 2013-2022 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -45,35 +45,4 @@ Foam::cyclicACMIFvPatchField<Type>::nonOverlapPatchField() const
} }
template<class Type>
void Foam::cyclicACMIFvPatchField<Type>::manipulateMatrix
(
fvMatrix<Type>& matrix
)
{
const scalarField& mask = cyclicACMIPatch().cyclicACMIPatch().mask();
// nothing to be done by the AMI, but re-direct to non-overlap patch
// with non-overlap patch weights
const fvPatchField<Type>& npf = nonOverlapPatchField();
const_cast<fvPatchField<Type>&>(npf).manipulateMatrix(matrix, 1.0 - mask);
}
template<class Type>
void Foam::cyclicACMIFvPatchField<Type>::updateCoeffs()
{
// Update non-overlap patch - some will implement updateCoeffs, and
// others will implement evaluate
// Pass in (1 - mask) to give non-overlap patch the chance to do
// manipulation of non-face based data
const scalarField& mask = cyclicACMIPatch().cyclicACMIPatch().mask();
const fvPatchField<Type>& npf = nonOverlapPatchField();
const_cast<fvPatchField<Type>&>(npf).updateWeightedCoeffs(1.0 - mask);
}
// ************************************************************************* // // ************************************************************************* //

View File

@ -2,7 +2,7 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org \\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2013-2020 OpenFOAM Foundation \\ / A nd | Copyright (C) 2013-2022 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -125,12 +125,6 @@ public:
//- Return reference to non-overlapping patchField //- Return reference to non-overlapping patchField
const fvPatchField<Type>& nonOverlapPatchField() const; const fvPatchField<Type>& nonOverlapPatchField() const;
//- Manipulate matrix
virtual void manipulateMatrix(fvMatrix<Type>& matrix);
//- Update the coefficients associated with the patch field
virtual void updateCoeffs();
}; };

View File

@ -2,7 +2,7 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org \\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2011-2020 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2022 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -126,7 +126,10 @@ bool Foam::cyclicAMIFvPatchField<Type>::coupled() const
template<class Type> template<class Type>
Foam::tmp<Foam::Field<Type>> Foam::tmp<Foam::Field<Type>>
Foam::cyclicAMIFvPatchField<Type>::patchNeighbourField() const Foam::cyclicAMIFvPatchField<Type>::patchNeighbourField
(
const Pstream::commsTypes
) const
{ {
const Field<Type>& iField = this->primitiveField(); const Field<Type>& iField = this->primitiveField();
const labelUList& nbrFaceCells = const labelUList& nbrFaceCells =

View File

@ -152,7 +152,10 @@ public:
virtual bool coupled() const; virtual bool coupled() const;
//- Return neighbour coupled internal cell data //- Return neighbour coupled internal cell data
virtual tmp<Field<Type>> patchNeighbourField() const; virtual tmp<Field<Type>> patchNeighbourField
(
const Pstream::commsTypes
) const;
//- Return reference to neighbour patchField //- Return reference to neighbour patchField
const cyclicAMIFvPatchField<Type>& nbrPatchField() const; const cyclicAMIFvPatchField<Type>& nbrPatchField() 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 | Website: https://openfoam.org \\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2011-2021 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2022 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -81,7 +81,10 @@ Foam::jumpCyclicFvPatchField<Type>::jumpCyclicFvPatchField
template<class Type> template<class Type>
Foam::tmp<Foam::Field<Type>> Foam::tmp<Foam::Field<Type>>
Foam::jumpCyclicFvPatchField<Type>::patchNeighbourField() const Foam::jumpCyclicFvPatchField<Type>::patchNeighbourField
(
const Pstream::commsTypes
) const
{ {
const Field<Type>& iField = this->primitiveField(); const Field<Type>& iField = this->primitiveField();
const labelUList& nbrFaceCells = const labelUList& nbrFaceCells =

View File

@ -2,7 +2,7 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org \\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2011-2020 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2022 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -116,7 +116,10 @@ public:
// Evaluation functions // Evaluation functions
//- Return neighbour coupled given internal cell data //- Return neighbour coupled given internal cell data
tmp<Field<Type>> patchNeighbourField() const; virtual tmp<Field<Type>> patchNeighbourField
(
const Pstream::commsTypes
) const;
//- Update result field based on interface functionality //- Update result field based on interface functionality
virtual void updateInterfaceMatrix virtual void updateInterfaceMatrix

View File

@ -2,7 +2,7 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org \\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2012-2021 OpenFOAM Foundation \\ / A nd | Copyright (C) 2012-2022 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -82,7 +82,10 @@ Foam::jumpCyclicAMIFvPatchField<Type>::jumpCyclicAMIFvPatchField
template<class Type> template<class Type>
Foam::tmp<Foam::Field<Type>> Foam::tmp<Foam::Field<Type>>
Foam::jumpCyclicAMIFvPatchField<Type>::patchNeighbourField() const Foam::jumpCyclicAMIFvPatchField<Type>::patchNeighbourField
(
const Pstream::commsTypes
) const
{ {
const Field<Type>& iField = this->primitiveField(); const Field<Type>& iField = this->primitiveField();
const labelUList& nbrFaceCells = const labelUList& nbrFaceCells =

View File

@ -2,7 +2,7 @@
========= | ========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org \\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2012-2020 OpenFOAM Foundation \\ / A nd | Copyright (C) 2012-2022 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -122,7 +122,10 @@ public:
// Evaluation functions // Evaluation functions
//- Return neighbour coupled given internal cell data //- Return neighbour coupled given internal cell data
tmp<Field<Type>> patchNeighbourField() const; virtual tmp<Field<Type>> patchNeighbourField
(
const Pstream::commsTypes
) const;
//- Update result field based on interface functionality //- Update result field based on interface functionality
virtual void updateInterfaceMatrix virtual void updateInterfaceMatrix

View File

@ -0,0 +1,82 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2021-2022 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 "nonConformalCyclicFvPatchField.H"
#include "transformField.H"
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
template<class Type>
Foam::nonConformalCyclicFvPatchField<Type>::nonConformalCyclicFvPatchField
(
const fvPatch& p,
const DimensionedField<Type, volMesh>& iF
)
:
cyclicFvPatchField<Type>(p, iF),
nonConformalCyclicFvPatch_(refCast<const nonConformalCyclicFvPatch>(p))
{}
template<class Type>
Foam::nonConformalCyclicFvPatchField<Type>::nonConformalCyclicFvPatchField
(
const fvPatch& p,
const DimensionedField<Type, volMesh>& iF,
const dictionary& dict
)
:
cyclicFvPatchField<Type>(p, iF, dict),
nonConformalCyclicFvPatch_(refCast<const nonConformalCyclicFvPatch>(p))
{}
template<class Type>
Foam::nonConformalCyclicFvPatchField<Type>::nonConformalCyclicFvPatchField
(
const nonConformalCyclicFvPatchField<Type>& ptf,
const fvPatch& p,
const DimensionedField<Type, volMesh>& iF,
const fvPatchFieldMapper& mapper
)
:
cyclicFvPatchField<Type>(ptf, p, iF, mapper),
nonConformalCyclicFvPatch_(refCast<const nonConformalCyclicFvPatch>(p))
{}
template<class Type>
Foam::nonConformalCyclicFvPatchField<Type>::nonConformalCyclicFvPatchField
(
const nonConformalCyclicFvPatchField<Type>& ptf,
const DimensionedField<Type, volMesh>& iF
)
:
cyclicFvPatchField<Type>(ptf, iF),
nonConformalCyclicFvPatch_(ptf.nonConformalCyclicFvPatch_)
{}
// ************************************************************************* //

View File

@ -0,0 +1,150 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2021-2022 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::nonConformalCyclicFvPatchField
Description
This boundary condition enforces a non-conformal cyclic condition between a
pair of boundaries.
Usage
Example of the boundary condition specification:
\verbatim
<patchName>
{
type nonConformalCyclic;
}
\endverbatim
Note
The patches must be topologically similar, i.e. if the owner patch is
transformed to the neighbour patch, the patches should be identical (or
very similar).
SourceFiles
nonConformalCyclicFvPatchField.C
\*---------------------------------------------------------------------------*/
#ifndef nonConformalCyclicFvPatchField_H
#define nonConformalCyclicFvPatchField_H
#include "cyclicFvPatchField.H"
#include "nonConformalCyclicFvPatch.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class nonConformalCyclicFvPatch Declaration
\*---------------------------------------------------------------------------*/
template<class Type>
class nonConformalCyclicFvPatchField
:
public cyclicFvPatchField<Type>
{
// Private Data
//- Reference to the fvPatch
const nonConformalCyclicFvPatch& nonConformalCyclicFvPatch_;
public:
//- Runtime type information
TypeName(nonConformalCyclicFvPatch::typeName_());
// Constructors
//- Construct from patch and internal field
nonConformalCyclicFvPatchField
(
const fvPatch&,
const DimensionedField<Type, volMesh>&
);
//- Construct from patch, internal field and dictionary
nonConformalCyclicFvPatchField
(
const fvPatch&,
const DimensionedField<Type, volMesh>&,
const dictionary&
);
//- Construct by mapping given nonConformalCyclicFvPatchField onto a
// new patch
nonConformalCyclicFvPatchField
(
const nonConformalCyclicFvPatchField<Type>&,
const fvPatch&,
const DimensionedField<Type, volMesh>&,
const fvPatchFieldMapper&
);
//- Disallow copy without setting internal field reference
nonConformalCyclicFvPatchField
(
const nonConformalCyclicFvPatchField<Type>&
) = delete;
//- Copy constructor setting internal field reference
nonConformalCyclicFvPatchField
(
const nonConformalCyclicFvPatchField<Type>&,
const DimensionedField<Type, volMesh>&
);
//- Construct and return a clone setting internal field reference
virtual tmp<fvPatchField<Type>> clone
(
const DimensionedField<Type, volMesh>& iF
) const
{
return tmp<fvPatchField<Type>>
(
new nonConformalCyclicFvPatchField<Type>(*this, iF)
);
}
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository
#include "nonConformalCyclicFvPatchField.C"
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,43 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2021-2022 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 "nonConformalCyclicFvPatchFields.H"
#include "addToRunTimeSelectionTable.H"
#include "volFields.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
makePatchFields(nonConformalCyclic);
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// ************************************************************************* //

View File

@ -0,0 +1,49 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2021-2022 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 nonConformalCyclicFvPatchFields_H
#define nonConformalCyclicFvPatchFields_H
#include "nonConformalCyclicFvPatchField.H"
#include "fieldTypes.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
makePatchTypeFieldTypedefs(nonConformalCyclic);
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,50 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2021-2022 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 nonConformalCyclicFvPatchFieldsFwd_H
#define nonConformalCyclicFvPatchFieldsFwd_H
#include "fieldTypes.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
template<class Type> class nonConformalCyclicFvPatchField;
makePatchTypeFieldTypedefs(nonConformalCyclic);
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,82 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2021-2022 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 "nonConformalErrorFvPatchField.H"
#include "transformField.H"
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
template<class Type>
Foam::nonConformalErrorFvPatchField<Type>::nonConformalErrorFvPatchField
(
const fvPatch& p,
const DimensionedField<Type, volMesh>& iF
)
:
zeroGradientFvPatchField<Type>(p, iF),
nonConformalErrorFvPatch_(refCast<const nonConformalErrorFvPatch>(p))
{}
template<class Type>
Foam::nonConformalErrorFvPatchField<Type>::nonConformalErrorFvPatchField
(
const fvPatch& p,
const DimensionedField<Type, volMesh>& iF,
const dictionary& dict
)
:
zeroGradientFvPatchField<Type>(p, iF, dict),
nonConformalErrorFvPatch_(refCast<const nonConformalErrorFvPatch>(p))
{}
template<class Type>
Foam::nonConformalErrorFvPatchField<Type>::nonConformalErrorFvPatchField
(
const nonConformalErrorFvPatchField<Type>& ptf,
const fvPatch& p,
const DimensionedField<Type, volMesh>& iF,
const fvPatchFieldMapper& mapper
)
:
zeroGradientFvPatchField<Type>(ptf, p, iF, mapper),
nonConformalErrorFvPatch_(refCast<const nonConformalErrorFvPatch>(p))
{}
template<class Type>
Foam::nonConformalErrorFvPatchField<Type>::nonConformalErrorFvPatchField
(
const nonConformalErrorFvPatchField<Type>& ptf,
const DimensionedField<Type, volMesh>& iF
)
:
zeroGradientFvPatchField<Type>(ptf, iF),
nonConformalErrorFvPatch_(ptf.nonConformalErrorFvPatch_)
{}
// ************************************************************************* //

View File

@ -0,0 +1,144 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2021-2022 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::nonConformalErrorFvPatchField
Description
This boundary condition enforces a non-conformal error condition.
Usage
Example of the boundary condition specification:
\verbatim
<patchName>
{
type nonConformalError;
}
\endverbatim
SourceFiles
nonConformalErrorFvPatchField.C
\*---------------------------------------------------------------------------*/
#ifndef nonConformalErrorFvPatchField_H
#define nonConformalErrorFvPatchField_H
#include "zeroGradientFvPatchField.H"
#include "nonConformalErrorFvPatch.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class nonConformalErrorFvPatch Declaration
\*---------------------------------------------------------------------------*/
template<class Type>
class nonConformalErrorFvPatchField
:
public zeroGradientFvPatchField<Type>
{
// Private Data
//- Reference to the fvPatch
const nonConformalErrorFvPatch& nonConformalErrorFvPatch_;
public:
//- Runtime type information
TypeName(nonConformalErrorFvPatch::typeName_());
// Constructors
//- Construct from patch and internal field
nonConformalErrorFvPatchField
(
const fvPatch&,
const DimensionedField<Type, volMesh>&
);
//- Construct from patch, internal field and dictionary
nonConformalErrorFvPatchField
(
const fvPatch&,
const DimensionedField<Type, volMesh>&,
const dictionary&
);
//- Construct by mapping given nonConformalErrorFvPatchField onto a
// new patch
nonConformalErrorFvPatchField
(
const nonConformalErrorFvPatchField<Type>&,
const fvPatch&,
const DimensionedField<Type, volMesh>&,
const fvPatchFieldMapper&
);
//- Disallow copy without setting internal field reference
nonConformalErrorFvPatchField
(
const nonConformalErrorFvPatchField<Type>&
) = delete;
//- Copy constructor setting internal field reference
nonConformalErrorFvPatchField
(
const nonConformalErrorFvPatchField<Type>&,
const DimensionedField<Type, volMesh>&
);
//- Construct and return a clone setting internal field reference
virtual tmp<fvPatchField<Type>> clone
(
const DimensionedField<Type, volMesh>& iF
) const
{
return tmp<fvPatchField<Type>>
(
new nonConformalErrorFvPatchField<Type>(*this, iF)
);
}
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository
#include "nonConformalErrorFvPatchField.C"
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,43 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2021-2022 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 "nonConformalErrorFvPatchFields.H"
#include "addToRunTimeSelectionTable.H"
#include "volFields.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
makePatchFields(nonConformalError);
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// ************************************************************************* //

View File

@ -0,0 +1,49 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2021-2022 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 nonConformalErrorFvPatchFields_H
#define nonConformalErrorFvPatchFields_H
#include "nonConformalErrorFvPatchField.H"
#include "fieldTypes.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
makePatchTypeFieldTypedefs(nonConformalError);
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,50 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2021-2022 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 nonConformalErrorFvPatchFieldsFwd_H
#define nonConformalErrorFvPatchFieldsFwd_H
#include "fieldTypes.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
template<class Type> class nonConformalErrorFvPatchField;
makePatchTypeFieldTypedefs(nonConformalError);
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,110 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2011-2022 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 "nonConformalProcessorCyclicFvPatchField.H"
#include "nonConformalProcessorCyclicFvPatch.H"
#include "demandDrivenData.H"
#include "transformField.H"
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
template<class Type>
Foam::nonConformalProcessorCyclicFvPatchField<Type>::
nonConformalProcessorCyclicFvPatchField
(
const fvPatch& p,
const DimensionedField<Type, volMesh>& iF
)
:
processorCyclicFvPatchField<Type>(p, iF),
procPatch_(refCast<const nonConformalProcessorCyclicFvPatch>(p))
{}
template<class Type>
Foam::nonConformalProcessorCyclicFvPatchField<Type>::
nonConformalProcessorCyclicFvPatchField
(
const fvPatch& p,
const DimensionedField<Type, volMesh>& iF,
const dictionary& dict
)
:
processorCyclicFvPatchField<Type>(p, iF, dict),
procPatch_(refCast<const nonConformalProcessorCyclicFvPatch>(p))
{}
template<class Type>
Foam::nonConformalProcessorCyclicFvPatchField<Type>::
nonConformalProcessorCyclicFvPatchField
(
const fvPatch& p,
const DimensionedField<Type, volMesh>& iF,
const Field<Type>& f
)
:
processorCyclicFvPatchField<Type>(p, iF, f),
procPatch_(refCast<const nonConformalProcessorCyclicFvPatch>(p))
{}
template<class Type>
Foam::nonConformalProcessorCyclicFvPatchField<Type>::
nonConformalProcessorCyclicFvPatchField
(
const nonConformalProcessorCyclicFvPatchField<Type>& ptf,
const fvPatch& p,
const DimensionedField<Type, volMesh>& iF,
const fvPatchFieldMapper& mapper
)
:
processorCyclicFvPatchField<Type>(ptf, p, iF, mapper),
procPatch_(refCast<const nonConformalProcessorCyclicFvPatch>(p))
{}
template<class Type>
Foam::nonConformalProcessorCyclicFvPatchField<Type>::
nonConformalProcessorCyclicFvPatchField
(
const nonConformalProcessorCyclicFvPatchField<Type>& ptf,
const DimensionedField<Type, volMesh>& iF
)
:
processorCyclicFvPatchField<Type>(ptf, iF),
procPatch_(refCast<const nonConformalProcessorCyclicFvPatch>(ptf.patch()))
{}
// * * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * //
template<class Type>
Foam::nonConformalProcessorCyclicFvPatchField<Type>::
~nonConformalProcessorCyclicFvPatchField()
{}
// ************************************************************************* //

View File

@ -0,0 +1,180 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2011-2022 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::nonConformalProcessorCyclicFvPatchField
Description
This boundary condition enables processor communication across cyclic
patches.
Usage
Example of the boundary condition specification:
\verbatim
<patchName>
{
type nonConformalProcessorCyclic;
}
\endverbatim
See also
Foam::processorCyclicFvPatchField
SourceFiles
nonConformalProcessorCyclicFvPatchField.C
nonConformalProcessorCyclicFvPatchFields.H
nonConformalProcessorCyclicFvPatchFields.C
nonConformalProcessorCyclicFvPatchFieldsFwd.H
\*---------------------------------------------------------------------------*/
#ifndef nonConformalProcessorCyclicFvPatchField_H
#define nonConformalProcessorCyclicFvPatchField_H
#include "nonConformalProcessorCyclicFvPatch.H"
#include "processorCyclicFvPatchField.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class nonConformalProcessorCyclicFvPatchField Declaration
\*---------------------------------------------------------------------------*/
template<class Type>
class nonConformalProcessorCyclicFvPatchField
:
public processorCyclicFvPatchField<Type>
{
// Private Data
//- Local reference cast into the processor patch
const nonConformalProcessorCyclicFvPatch& procPatch_;
public:
//- Runtime type information
TypeName(nonConformalProcessorCyclicFvPatch::typeName_());
// Constructors
//- Construct from patch and internal field
nonConformalProcessorCyclicFvPatchField
(
const fvPatch&,
const DimensionedField<Type, volMesh>&
);
//- Construct from patch and internal field and patch field
nonConformalProcessorCyclicFvPatchField
(
const fvPatch&,
const DimensionedField<Type, volMesh>&,
const Field<Type>&
);
//- Construct from patch, internal field and dictionary
nonConformalProcessorCyclicFvPatchField
(
const fvPatch&,
const DimensionedField<Type, volMesh>&,
const dictionary&
);
//- Construct by mapping given nonConformalProcessorCyclicFvPatchField
// onto a new patch
nonConformalProcessorCyclicFvPatchField
(
const nonConformalProcessorCyclicFvPatchField<Type>&,
const fvPatch&,
const DimensionedField<Type, volMesh>&,
const fvPatchFieldMapper&
);
//- Disallow copy without setting internal field reference
nonConformalProcessorCyclicFvPatchField
(
const nonConformalProcessorCyclicFvPatchField<Type>&
) = delete;
//- Copy constructor setting internal field reference
nonConformalProcessorCyclicFvPatchField
(
const nonConformalProcessorCyclicFvPatchField<Type>&,
const DimensionedField<Type, volMesh>&
);
//- Construct and return a clone setting internal field reference
virtual tmp<fvPatchField<Type>> clone
(
const DimensionedField<Type, volMesh>& iF
) const
{
return tmp<fvPatchField<Type>>
(
new nonConformalProcessorCyclicFvPatchField<Type>(*this, iF)
);
}
//- Destructor
virtual ~nonConformalProcessorCyclicFvPatchField();
// Member Functions
// Access
//- Return transformation between the coupled patches
virtual const transformer& transform() const
{
return procPatch_.transform();
}
//- Return rank of component for transform
virtual int rank() const
{
return pTraits<Type>::rank;
}
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository
#include "nonConformalProcessorCyclicFvPatchField.C"
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,43 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2011-2022 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 "nonConformalProcessorCyclicFvPatchFields.H"
#include "addToRunTimeSelectionTable.H"
#include "volFields.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
makePatchFields(nonConformalProcessorCyclic);
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// ************************************************************************* //

Some files were not shown because too many files have changed in this diff Show More