mirror of
https://develop.openfoam.com/Development/openfoam.git
synced 2025-11-28 03:28:01 +00:00
Merge commit 'origin/master' into olesenm
This commit is contained in:
@ -1,11 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
# Build optional components (eg, may depend on third-party libraries)
|
|
||||||
set -x
|
|
||||||
|
|
||||||
# if the library exists, assume there are headers too
|
|
||||||
if [ -e $FOAM_LIBBIN/libccmio.so ]
|
|
||||||
then
|
|
||||||
wmake ccm26ToFoam
|
|
||||||
fi
|
|
||||||
|
|
||||||
# end
|
|
||||||
19
applications/utilities/mesh/conversion/Optional/AllwmakeOptional
Executable file
19
applications/utilities/mesh/conversion/Optional/AllwmakeOptional
Executable file
@ -0,0 +1,19 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
# Build optional components (eg, may depend on third-party libraries)
|
||||||
|
set -x
|
||||||
|
|
||||||
|
# build libccmio if required
|
||||||
|
if [ ! -e $FOAM_LIBBIN/libccmio.so ]
|
||||||
|
then
|
||||||
|
(
|
||||||
|
cd $WM_THIRD_PARTY_DIR && ./AllwmakeLibccmio
|
||||||
|
)
|
||||||
|
fi
|
||||||
|
|
||||||
|
# if the library built okay, the headers must exist too
|
||||||
|
if [ -e $FOAM_LIBBIN/libccmio.so ]
|
||||||
|
then
|
||||||
|
wmake ccm26ToFoam
|
||||||
|
fi
|
||||||
|
|
||||||
|
# end
|
||||||
@ -1,8 +1,8 @@
|
|||||||
EXE_INC = \
|
EXE_INC = \
|
||||||
-I$(LIB_SRC)/finiteVolume/lnInclude \
|
-I$(LIB_SRC)/finiteVolume/lnInclude \
|
||||||
-I$(LIB_SRC)/meshTools/lnInclude \
|
-I$(LIB_SRC)/meshTools/lnInclude \
|
||||||
-I$(THIRD_PARTY)/libccmio \
|
-I${WM_THIRD_PARTY_DIR}/libccmio-2.6.1 \
|
||||||
-I$(THIRD_PARTY)/libccmio/lnInclude
|
-I${WM_THIRD_PARTY_DIR}/libccmio-2.6.1/lnInclude
|
||||||
|
|
||||||
EXE_LIBS = \
|
EXE_LIBS = \
|
||||||
-lfiniteVolume \
|
-lfiniteVolume \
|
||||||
|
|||||||
@ -88,9 +88,9 @@ int main(int argc, char *argv[])
|
|||||||
polyMesh::meshSubDir/"sets"
|
polyMesh::meshSubDir/"sets"
|
||||||
);
|
);
|
||||||
|
|
||||||
Pout<< "Seached : " << mesh.pointsInstance()/polyMesh::meshSubDir/"sets"
|
Pout<< "Searched : " << mesh.pointsInstance()/polyMesh::meshSubDir/"sets"
|
||||||
<< nl
|
<< nl
|
||||||
<< "Found : " << objects.names() << nl
|
<< "Found : " << objects.names() << nl
|
||||||
<< endl;
|
<< endl;
|
||||||
|
|
||||||
|
|
||||||
@ -108,8 +108,10 @@ int main(int argc, char *argv[])
|
|||||||
// Not in memory. Load it.
|
// Not in memory. Load it.
|
||||||
pointSet set(*iter());
|
pointSet set(*iter());
|
||||||
|
|
||||||
if (mesh.pointZones().findZoneID(set.name()) == -1)
|
label zoneID = mesh.pointZones().findZoneID(set.name());
|
||||||
|
if (zoneID == -1)
|
||||||
{
|
{
|
||||||
|
Info<< "Adding set " << set.name() << " as a pointZone." << endl;
|
||||||
label sz = mesh.pointZones().size();
|
label sz = mesh.pointZones().size();
|
||||||
mesh.pointZones().setSize(sz+1);
|
mesh.pointZones().setSize(sz+1);
|
||||||
mesh.pointZones().set
|
mesh.pointZones().set
|
||||||
@ -125,6 +127,13 @@ int main(int argc, char *argv[])
|
|||||||
);
|
);
|
||||||
mesh.pointZones().writeOpt() = IOobject::AUTO_WRITE;
|
mesh.pointZones().writeOpt() = IOobject::AUTO_WRITE;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Info<< "Overwriting contents of existing pointZone " << zoneID
|
||||||
|
<< " with that of set " << set.name() << "." << endl;
|
||||||
|
mesh.pointZones()[zoneID] = set.toc();
|
||||||
|
mesh.pointZones().writeOpt() = IOobject::AUTO_WRITE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -142,8 +151,10 @@ int main(int argc, char *argv[])
|
|||||||
// Not in memory. Load it.
|
// Not in memory. Load it.
|
||||||
cellSet set(*iter());
|
cellSet set(*iter());
|
||||||
|
|
||||||
if (mesh.cellZones().findZoneID(set.name()) == -1)
|
label zoneID = mesh.cellZones().findZoneID(set.name());
|
||||||
|
if (zoneID == -1)
|
||||||
{
|
{
|
||||||
|
Info<< "Adding set " << set.name() << " as a cellZone." << endl;
|
||||||
label sz = mesh.cellZones().size();
|
label sz = mesh.cellZones().size();
|
||||||
mesh.cellZones().setSize(sz+1);
|
mesh.cellZones().setSize(sz+1);
|
||||||
mesh.cellZones().set
|
mesh.cellZones().set
|
||||||
@ -159,6 +170,13 @@ int main(int argc, char *argv[])
|
|||||||
);
|
);
|
||||||
mesh.cellZones().writeOpt() = IOobject::AUTO_WRITE;
|
mesh.cellZones().writeOpt() = IOobject::AUTO_WRITE;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Info<< "Overwriting contents of existing cellZone " << zoneID
|
||||||
|
<< " with that of set " << set.name() << "." << endl;
|
||||||
|
mesh.cellZones()[zoneID] = set.toc();
|
||||||
|
mesh.cellZones().writeOpt() = IOobject::AUTO_WRITE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -262,8 +280,10 @@ int main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mesh.faceZones().findZoneID(set.name()) == -1)
|
label zoneID = mesh.faceZones().findZoneID(set.name());
|
||||||
|
if (zoneID == -1)
|
||||||
{
|
{
|
||||||
|
Info<< "Adding set " << set.name() << " as a faceZone." << endl;
|
||||||
label sz = mesh.faceZones().size();
|
label sz = mesh.faceZones().size();
|
||||||
mesh.faceZones().setSize(sz+1);
|
mesh.faceZones().setSize(sz+1);
|
||||||
mesh.faceZones().set
|
mesh.faceZones().set
|
||||||
@ -280,6 +300,17 @@ int main(int argc, char *argv[])
|
|||||||
);
|
);
|
||||||
mesh.faceZones().writeOpt() = IOobject::AUTO_WRITE;
|
mesh.faceZones().writeOpt() = IOobject::AUTO_WRITE;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Info<< "Overwriting contents of existing faceZone " << zoneID
|
||||||
|
<< " with that of set " << set.name() << "." << endl;
|
||||||
|
mesh.faceZones()[zoneID].resetAddressing
|
||||||
|
(
|
||||||
|
addressing.shrink(),
|
||||||
|
flipMap.shrink()
|
||||||
|
);
|
||||||
|
mesh.faceZones().writeOpt() = IOobject::AUTO_WRITE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Pout<< "Writing mesh." << endl;
|
Pout<< "Writing mesh." << endl;
|
||||||
|
|||||||
@ -1,11 +1,11 @@
|
|||||||
EXE_INC = \
|
EXE_INC = \
|
||||||
-I$(LIB_SRC)/decompositionAgglomeration/decompositionMethods/lnInclude \
|
-I$(LIB_SRC)/decompositionAgglomeration/decompositionMethods/lnInclude \
|
||||||
-I$(LIB_SRC)/finiteVolume/lnInclude \
|
-I$(LIB_SRC)/finiteVolume/lnInclude \
|
||||||
-I$(LIB_SRC)/lagrangian/basic/lnInclude
|
-I$(LIB_SRC)/lagrangian/basic/lnInclude \
|
||||||
|
-I$(LIB_SRC)/meshTools/lnInclude
|
||||||
|
|
||||||
EXE_LIBS = \
|
EXE_LIBS = \
|
||||||
-lfiniteVolume \
|
-lfiniteVolume \
|
||||||
-ldecompositionMethods \
|
-ldecompositionMethods \
|
||||||
-llagrangian \
|
-llagrangian \
|
||||||
-lmeshTools \
|
-lmeshTools
|
||||||
|
|
||||||
|
|||||||
@ -28,6 +28,8 @@ License
|
|||||||
#include "decompositionMethod.H"
|
#include "decompositionMethod.H"
|
||||||
#include "cpuTime.H"
|
#include "cpuTime.H"
|
||||||
#include "cyclicPolyPatch.H"
|
#include "cyclicPolyPatch.H"
|
||||||
|
#include "cellSet.H"
|
||||||
|
#include "regionSplit.H"
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
@ -127,117 +129,34 @@ void domainDecomposition::distributeCells()
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
// Faces where owner and neighbour are not 'connected' (= all except
|
||||||
|
// sameProcFaces)
|
||||||
// Work the faces whose neighbours need to be kept together into an
|
boolList blockedFace(nFaces(), true);
|
||||||
// agglomeration.
|
|
||||||
|
|
||||||
// Per cell the region/agglomeration it is in
|
|
||||||
labelList cellToRegion(nCells(), -1);
|
|
||||||
|
|
||||||
// Current region
|
|
||||||
label regionI = 0;
|
|
||||||
|
|
||||||
labelHashSet freeRegions;
|
|
||||||
|
|
||||||
forAllConstIter(labelHashSet, sameProcFaces, iter)
|
forAllConstIter(labelHashSet, sameProcFaces, iter)
|
||||||
{
|
{
|
||||||
label patchI = boundaryMesh().whichPatch(iter.key());
|
blockedFace[iter.key()] = false;
|
||||||
|
|
||||||
label own = faceOwner()[iter.key()];
|
|
||||||
label nei = -1;
|
|
||||||
|
|
||||||
if (patchI == -1)
|
|
||||||
{
|
|
||||||
nei = faceNeighbour()[iter.key()];
|
|
||||||
}
|
|
||||||
else if (isA<cyclicPolyPatch>(boundaryMesh()[patchI]))
|
|
||||||
{
|
|
||||||
const cyclicPolyPatch& pp =
|
|
||||||
refCast<const cyclicPolyPatch>(boundaryMesh()[patchI]);
|
|
||||||
|
|
||||||
nei = faceOwner()[pp.transformGlobalFace(iter.key())];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (nei != -1)
|
|
||||||
{
|
|
||||||
label ownRegion = cellToRegion[own];
|
|
||||||
label neiRegion = cellToRegion[nei];
|
|
||||||
|
|
||||||
if (ownRegion == -1 && neiRegion == -1)
|
|
||||||
{
|
|
||||||
// Allocate new agglomeration
|
|
||||||
cellToRegion[own] = regionI;
|
|
||||||
cellToRegion[nei] = regionI;
|
|
||||||
regionI++;
|
|
||||||
}
|
|
||||||
else if (ownRegion != -1)
|
|
||||||
{
|
|
||||||
// Owner already part of agglomeration. Add nei to it.
|
|
||||||
cellToRegion[nei] = ownRegion;
|
|
||||||
}
|
|
||||||
else if (neiRegion != -1)
|
|
||||||
{
|
|
||||||
// nei already part of agglomeration. Add own to it.
|
|
||||||
cellToRegion[own] = neiRegion;
|
|
||||||
}
|
|
||||||
else if (ownRegion < neiRegion)
|
|
||||||
{
|
|
||||||
// Renumber neiRegion
|
|
||||||
forAll(cellToRegion, cellI)
|
|
||||||
{
|
|
||||||
if (cellToRegion[cellI] == neiRegion)
|
|
||||||
{
|
|
||||||
cellToRegion[cellI] = ownRegion;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
freeRegions.insert(neiRegion);
|
|
||||||
}
|
|
||||||
else if (ownRegion > neiRegion)
|
|
||||||
{
|
|
||||||
// Renumber ownRegion
|
|
||||||
forAll(cellToRegion, cellI)
|
|
||||||
{
|
|
||||||
if (cellToRegion[cellI] == ownRegion)
|
|
||||||
{
|
|
||||||
cellToRegion[cellI] = neiRegion;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
freeRegions.insert(ownRegion);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Connect coupled boundary faces
|
||||||
|
const polyBoundaryMesh& patches = boundaryMesh();
|
||||||
|
|
||||||
// Do all other cells
|
forAll(patches, patchI)
|
||||||
forAll(cellToRegion, cellI)
|
|
||||||
{
|
{
|
||||||
if (cellToRegion[cellI] == -1)
|
const polyPatch& pp = patches[patchI];
|
||||||
|
|
||||||
|
if (pp.coupled())
|
||||||
{
|
{
|
||||||
cellToRegion[cellI] = regionI++;
|
forAll(pp, i)
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Compact out freeRegions
|
|
||||||
// ~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
{
|
|
||||||
labelList compactRegion(regionI, -1);
|
|
||||||
|
|
||||||
regionI = 0;
|
|
||||||
|
|
||||||
forAll(compactRegion, i)
|
|
||||||
{
|
|
||||||
if (!freeRegions.found(compactRegion[i]))
|
|
||||||
{
|
{
|
||||||
compactRegion[i] = regionI++;
|
blockedFace[pp.start()+i] = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inplaceRenumber(compactRegion, cellToRegion);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Determine global regions, separated by blockedFaces
|
||||||
|
regionSplit globalRegion(*this, blockedFace);
|
||||||
|
|
||||||
|
|
||||||
// Determine region cell centres
|
// Determine region cell centres
|
||||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
@ -249,11 +168,11 @@ void domainDecomposition::distributeCells()
|
|||||||
|
|
||||||
const point greatPoint(GREAT, GREAT, GREAT);
|
const point greatPoint(GREAT, GREAT, GREAT);
|
||||||
|
|
||||||
pointField regionCentres(regionI, greatPoint);
|
pointField regionCentres(globalRegion.nRegions(), greatPoint);
|
||||||
|
|
||||||
forAll(cellToRegion, cellI)
|
forAll(globalRegion, cellI)
|
||||||
{
|
{
|
||||||
label regionI = cellToRegion[cellI];
|
label regionI = globalRegion[cellI];
|
||||||
|
|
||||||
if (regionCentres[regionI] == greatPoint)
|
if (regionCentres[regionI] == greatPoint)
|
||||||
{
|
{
|
||||||
@ -261,10 +180,9 @@ void domainDecomposition::distributeCells()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Do decomposition on agglomeration
|
// Do decomposition on agglomeration
|
||||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
cellToProc_ = decomposePtr().decompose(cellToRegion, regionCentres);
|
cellToProc_ = decomposePtr().decompose(globalRegion, regionCentres);
|
||||||
}
|
}
|
||||||
|
|
||||||
Info<< "\nFinished decomposition in "
|
Info<< "\nFinished decomposition in "
|
||||||
|
|||||||
@ -2,5 +2,7 @@ itoa.C
|
|||||||
ensightMesh.C
|
ensightMesh.C
|
||||||
ensightParticlePositions.C
|
ensightParticlePositions.C
|
||||||
foamToEnsight.C
|
foamToEnsight.C
|
||||||
|
ensightWriteBinary.C
|
||||||
|
|
||||||
EXE = $(FOAM_APPBIN)/foamToEnsight
|
EXE = $(FOAM_APPBIN)/foamToEnsight
|
||||||
|
//EXE = $(FOAM_USER_APPBIN)/foamToEnsight
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
bool meshMoving = true;
|
bool meshMoving = true;
|
||||||
|
|
||||||
if (Times.size() > 2)
|
if (Times.size() > 2)
|
||||||
{
|
{
|
||||||
for(label n2=2; n2<Times.size(); n2++)
|
for(label n2=2; n2<Times.size(); n2++)
|
||||||
@ -16,5 +17,5 @@ if (Times.size() > 2)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
meshMoving = false;
|
meshMoving = false;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -29,8 +29,8 @@ License
|
|||||||
#include "volFields.H"
|
#include "volFields.H"
|
||||||
#include "OFstream.H"
|
#include "OFstream.H"
|
||||||
#include "IOmanip.H"
|
#include "IOmanip.H"
|
||||||
|
|
||||||
#include "itoa.H"
|
#include "itoa.H"
|
||||||
|
#include "ensightWriteBinary.H"
|
||||||
|
|
||||||
using namespace Foam;
|
using namespace Foam;
|
||||||
|
|
||||||
@ -40,7 +40,14 @@ void writeData(const scalarField& sf, OFstream& ensightFile)
|
|||||||
{
|
{
|
||||||
forAll(sf, i)
|
forAll(sf, i)
|
||||||
{
|
{
|
||||||
ensightFile << setw(12) << float(sf[i]) << nl;
|
if (mag( sf[i] ) >= scalar(floatScalarVSMALL))
|
||||||
|
{
|
||||||
|
ensightFile << setw(12) << sf[i] << nl;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ensightFile << setw(12) << scalar(0) << nl;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -54,7 +61,7 @@ scalarField map
|
|||||||
)
|
)
|
||||||
{
|
{
|
||||||
scalarField mf(map.size());
|
scalarField mf(map.size());
|
||||||
|
|
||||||
forAll(map, i)
|
forAll(map, i)
|
||||||
{
|
{
|
||||||
mf[i] = component(vf[map[i]], cmpt);
|
mf[i] = component(vf[map[i]], cmpt);
|
||||||
@ -74,7 +81,7 @@ scalarField map
|
|||||||
)
|
)
|
||||||
{
|
{
|
||||||
scalarField mf(map1.size() + map2.size());
|
scalarField mf(map1.size() + map2.size());
|
||||||
|
|
||||||
forAll(map1, i)
|
forAll(map1, i)
|
||||||
{
|
{
|
||||||
mf[i] = component(vf[map1[i]], cmpt);
|
mf[i] = component(vf[map1[i]], cmpt);
|
||||||
@ -131,6 +138,47 @@ void writeAllData
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class Type>
|
||||||
|
void writeAllDataBinary
|
||||||
|
(
|
||||||
|
const char* key,
|
||||||
|
const Field<Type>& vf,
|
||||||
|
const labelList& prims,
|
||||||
|
const label nPrims,
|
||||||
|
std::ofstream& ensightFile
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (nPrims)
|
||||||
|
{
|
||||||
|
if (Pstream::master())
|
||||||
|
{
|
||||||
|
writeEnsDataBinary(key,ensightFile);
|
||||||
|
|
||||||
|
for (direction cmpt=0; cmpt<pTraits<Type>::nComponents; cmpt++)
|
||||||
|
{
|
||||||
|
writeEnsDataBinary(map(vf, prims, cmpt), ensightFile);
|
||||||
|
|
||||||
|
for (int slave=1; slave<Pstream::nProcs(); slave++)
|
||||||
|
{
|
||||||
|
IPstream fromSlave(Pstream::scheduled, slave);
|
||||||
|
scalarField data(fromSlave);
|
||||||
|
writeEnsDataBinary(data, ensightFile);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (direction cmpt=0; cmpt<pTraits<Type>::nComponents; cmpt++)
|
||||||
|
{
|
||||||
|
OPstream toMaster(Pstream::scheduled, Pstream::masterNo());
|
||||||
|
toMaster<< map(vf, prims, cmpt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
template<class Type>
|
template<class Type>
|
||||||
void writeAllFaceData
|
void writeAllFaceData
|
||||||
(
|
(
|
||||||
@ -177,6 +225,52 @@ void writeAllFaceData
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class Type>
|
||||||
|
void writeAllFaceDataBinary
|
||||||
|
(
|
||||||
|
const char* key,
|
||||||
|
const labelList& prims,
|
||||||
|
const label nPrims,
|
||||||
|
const Field<Type>& pf,
|
||||||
|
const labelList& patchProcessors,
|
||||||
|
std::ofstream& ensightFile
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (nPrims)
|
||||||
|
{
|
||||||
|
if (Pstream::master())
|
||||||
|
{
|
||||||
|
writeEnsDataBinary(key,ensightFile);
|
||||||
|
|
||||||
|
for (direction cmpt=0; cmpt<pTraits<Type>::nComponents; cmpt++)
|
||||||
|
{
|
||||||
|
writeEnsDataBinary(map(pf, prims, cmpt), ensightFile);
|
||||||
|
|
||||||
|
forAll (patchProcessors, i)
|
||||||
|
{
|
||||||
|
if (patchProcessors[i] != 0)
|
||||||
|
{
|
||||||
|
label slave = patchProcessors[i];
|
||||||
|
IPstream fromSlave(Pstream::scheduled, slave);
|
||||||
|
scalarField pf(fromSlave);
|
||||||
|
|
||||||
|
writeEnsDataBinary(pf, ensightFile);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (direction cmpt=0; cmpt<pTraits<Type>::nComponents; cmpt++)
|
||||||
|
{
|
||||||
|
OPstream toMaster(Pstream::scheduled, Pstream::masterNo());
|
||||||
|
toMaster<< map(pf, prims, cmpt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
template<class Type>
|
template<class Type>
|
||||||
bool writePatchField
|
bool writePatchField
|
||||||
(
|
(
|
||||||
@ -193,7 +287,7 @@ bool writePatchField
|
|||||||
{
|
{
|
||||||
if (Pstream::master())
|
if (Pstream::master())
|
||||||
{
|
{
|
||||||
ensightFile
|
ensightFile
|
||||||
<< "part" << nl
|
<< "part" << nl
|
||||||
<< setw(10) << ensightPatchi << nl;
|
<< setw(10) << ensightPatchi << nl;
|
||||||
}
|
}
|
||||||
@ -237,6 +331,65 @@ bool writePatchField
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class Type>
|
||||||
|
bool writePatchFieldBinary
|
||||||
|
(
|
||||||
|
const Foam::Field<Type>& pf,
|
||||||
|
const Foam::label patchi,
|
||||||
|
const Foam::label ensightPatchi,
|
||||||
|
const Foam::faceSets& boundaryFaceSet,
|
||||||
|
const Foam::ensightMesh::nFacePrims& nfp,
|
||||||
|
const Foam::labelList& patchProcessors,
|
||||||
|
std::ofstream& ensightFile
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (nfp.nTris || nfp.nQuads || nfp.nPolys)
|
||||||
|
{
|
||||||
|
if (Pstream::master())
|
||||||
|
{
|
||||||
|
writeEnsDataBinary("part",ensightFile);
|
||||||
|
writeEnsDataBinary(ensightPatchi,ensightFile);
|
||||||
|
}
|
||||||
|
|
||||||
|
writeAllFaceDataBinary
|
||||||
|
(
|
||||||
|
"tria3",
|
||||||
|
boundaryFaceSet.tris,
|
||||||
|
nfp.nTris,
|
||||||
|
pf,
|
||||||
|
patchProcessors,
|
||||||
|
ensightFile
|
||||||
|
);
|
||||||
|
|
||||||
|
writeAllFaceDataBinary
|
||||||
|
(
|
||||||
|
"quad4",
|
||||||
|
boundaryFaceSet.quads,
|
||||||
|
nfp.nQuads,
|
||||||
|
pf,
|
||||||
|
patchProcessors,
|
||||||
|
ensightFile
|
||||||
|
);
|
||||||
|
|
||||||
|
writeAllFaceDataBinary
|
||||||
|
(
|
||||||
|
"nsided",
|
||||||
|
boundaryFaceSet.polys,
|
||||||
|
nfp.nPolys,
|
||||||
|
pf,
|
||||||
|
patchProcessors,
|
||||||
|
ensightFile
|
||||||
|
);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
template<class Type>
|
template<class Type>
|
||||||
void writePatchField
|
void writePatchField
|
||||||
(
|
(
|
||||||
@ -293,7 +446,7 @@ void writePatchField
|
|||||||
ensightCaseFile.setf(ios_base::left);
|
ensightCaseFile.setf(ios_base::left);
|
||||||
|
|
||||||
ensightCaseFile
|
ensightCaseFile
|
||||||
<< pTraits<Type>::typeName
|
<< pTraits<Type>::typeName
|
||||||
<< " per element: 1 "
|
<< " per element: 1 "
|
||||||
<< setw(15) << pfName
|
<< setw(15) << pfName
|
||||||
<< (' ' + prepend + "***." + pfName).c_str()
|
<< (' ' + prepend + "***." + pfName).c_str()
|
||||||
@ -353,9 +506,8 @@ void writePatchField
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template<class Type>
|
template<class Type>
|
||||||
void ensightField
|
void ensightFieldAscii
|
||||||
(
|
(
|
||||||
const Foam::IOobject& fieldObject,
|
const Foam::IOobject& fieldObject,
|
||||||
const Foam::ensightMesh& eMesh,
|
const Foam::ensightMesh& eMesh,
|
||||||
@ -413,14 +565,14 @@ void ensightField
|
|||||||
ensightCaseFile.setf(ios_base::left);
|
ensightCaseFile.setf(ios_base::left);
|
||||||
|
|
||||||
ensightCaseFile
|
ensightCaseFile
|
||||||
<< pTraits<Type>::typeName
|
<< pTraits<Type>::typeName
|
||||||
<< " per element: 1 "
|
<< " per element: 1 "
|
||||||
<< setw(15) << vf.name()
|
<< setw(15) << vf.name()
|
||||||
<< (' ' + prepend + "***." + vf.name()).c_str()
|
<< (' ' + prepend + "***." + vf.name()).c_str()
|
||||||
<< nl;
|
<< nl;
|
||||||
}
|
}
|
||||||
|
|
||||||
ensightFile
|
ensightFile
|
||||||
<< pTraits<Type>::typeName << nl
|
<< pTraits<Type>::typeName << nl
|
||||||
<< "part" << nl
|
<< "part" << nl
|
||||||
<< setw(10) << 1 << nl;
|
<< setw(10) << 1 << nl;
|
||||||
@ -501,7 +653,7 @@ void ensightField
|
|||||||
{
|
{
|
||||||
ensightPatchi++;
|
ensightPatchi++;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
else if (Pstream::master())
|
else if (Pstream::master())
|
||||||
{
|
{
|
||||||
@ -534,4 +686,213 @@ void ensightField
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class Type>
|
||||||
|
void ensightFieldBinary
|
||||||
|
(
|
||||||
|
const Foam::IOobject& fieldObject,
|
||||||
|
const Foam::ensightMesh& eMesh,
|
||||||
|
const Foam::fileName& postProcPath,
|
||||||
|
const Foam::word& prepend,
|
||||||
|
const Foam::label timeIndex,
|
||||||
|
Foam::Ostream& ensightCaseFile
|
||||||
|
)
|
||||||
|
{
|
||||||
|
Info<< "Converting field (binary) " << fieldObject.name() << endl;
|
||||||
|
|
||||||
|
word timeFile = prepend + itoa(timeIndex);
|
||||||
|
|
||||||
|
const fvMesh& mesh = eMesh.mesh;
|
||||||
|
//const Time& runTime = mesh.time();
|
||||||
|
|
||||||
|
const cellSets& meshCellSets = eMesh.meshCellSets;
|
||||||
|
const List<faceSets>& boundaryFaceSets = eMesh.boundaryFaceSets;
|
||||||
|
const HashTable<labelList>& allPatchNames = eMesh.allPatchNames;
|
||||||
|
const HashTable<label>& patchIndices = eMesh.patchIndices;
|
||||||
|
const wordHashSet& patchNames = eMesh.patchNames;
|
||||||
|
const HashTable<ensightMesh::nFacePrims>& nPatchPrims = eMesh.nPatchPrims;
|
||||||
|
|
||||||
|
const labelList& tets = meshCellSets.tets;
|
||||||
|
const labelList& pyrs = meshCellSets.pyrs;
|
||||||
|
const labelList& prisms = meshCellSets.prisms;
|
||||||
|
const labelList& wedges = meshCellSets.wedges;
|
||||||
|
const labelList& hexes = meshCellSets.hexes;
|
||||||
|
const labelList& polys = meshCellSets.polys;
|
||||||
|
|
||||||
|
std::ofstream *ensightFilePtr = NULL;
|
||||||
|
if (Pstream::master())
|
||||||
|
{
|
||||||
|
// set the filename of the ensight file
|
||||||
|
fileName ensightFileName(timeFile + "." + fieldObject.name());
|
||||||
|
ensightFilePtr = new std::ofstream((postProcPath/ensightFileName).c_str(), ios_base::out | ios_base::binary | ios_base::trunc);
|
||||||
|
// Check on file opened?
|
||||||
|
}
|
||||||
|
|
||||||
|
std::ofstream& ensightFile = *ensightFilePtr;
|
||||||
|
|
||||||
|
GeometricField<Type, fvPatchField, volMesh> vf(fieldObject, mesh);
|
||||||
|
|
||||||
|
if (!patchNames.size())
|
||||||
|
{
|
||||||
|
if (Pstream::master())
|
||||||
|
{
|
||||||
|
if (timeIndex == 0)
|
||||||
|
{
|
||||||
|
ensightCaseFile.setf(ios_base::left);
|
||||||
|
|
||||||
|
ensightCaseFile
|
||||||
|
<< pTraits<Type>::typeName
|
||||||
|
<< " per element: 1 "
|
||||||
|
<< setw(15) << vf.name()
|
||||||
|
<< (' ' + prepend + "***." + vf.name()).c_str()
|
||||||
|
<< nl;
|
||||||
|
}
|
||||||
|
|
||||||
|
writeEnsDataBinary(pTraits<Type>::typeName,ensightFile);
|
||||||
|
writeEnsDataBinary("part",ensightFile);
|
||||||
|
writeEnsDataBinary(1,ensightFile);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (meshCellSets.nHexesWedges)
|
||||||
|
{
|
||||||
|
if (Pstream::master())
|
||||||
|
{
|
||||||
|
writeEnsDataBinary("hexa8",ensightFile);
|
||||||
|
|
||||||
|
for (direction cmpt=0; cmpt<pTraits<Type>::nComponents; cmpt++)
|
||||||
|
{
|
||||||
|
writeEnsDataBinary
|
||||||
|
(
|
||||||
|
map(vf, hexes, wedges, cmpt),
|
||||||
|
ensightFile
|
||||||
|
);
|
||||||
|
|
||||||
|
for (int slave=1; slave<Pstream::nProcs(); slave++)
|
||||||
|
{
|
||||||
|
IPstream fromSlave(Pstream::scheduled, slave);
|
||||||
|
scalarField data(fromSlave);
|
||||||
|
writeEnsDataBinary(data, ensightFile);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (direction cmpt=0; cmpt<pTraits<Type>::nComponents; cmpt++)
|
||||||
|
{
|
||||||
|
OPstream toMaster(Pstream::scheduled, Pstream::masterNo());
|
||||||
|
toMaster<< map(vf, hexes, wedges, cmpt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
writeAllDataBinary("penta6", vf, prisms, meshCellSets.nPrisms, ensightFile);
|
||||||
|
writeAllDataBinary("pyramid5", vf, pyrs, meshCellSets.nPyrs, ensightFile);
|
||||||
|
writeAllDataBinary("tetra4", vf, tets, meshCellSets.nTets, ensightFile);
|
||||||
|
writeAllDataBinary("nfaced", vf, polys, meshCellSets.nPolys, ensightFile);
|
||||||
|
}
|
||||||
|
|
||||||
|
label ensightPatchi = 2;
|
||||||
|
|
||||||
|
for
|
||||||
|
(
|
||||||
|
HashTable<labelList>::const_iterator iter = allPatchNames.begin();
|
||||||
|
iter != allPatchNames.end();
|
||||||
|
++iter
|
||||||
|
)
|
||||||
|
{
|
||||||
|
const word& patchName = iter.key();
|
||||||
|
const labelList& patchProcessors = iter();
|
||||||
|
|
||||||
|
if (!patchNames.size() || patchNames.found(patchName))
|
||||||
|
{
|
||||||
|
if (patchIndices.found(patchName))
|
||||||
|
{
|
||||||
|
label patchi = patchIndices.find(patchName)();
|
||||||
|
|
||||||
|
if
|
||||||
|
(
|
||||||
|
writePatchFieldBinary
|
||||||
|
(
|
||||||
|
vf.boundaryField()[patchi],
|
||||||
|
patchi,
|
||||||
|
ensightPatchi,
|
||||||
|
boundaryFaceSets[patchi],
|
||||||
|
nPatchPrims.find(patchName)(),
|
||||||
|
patchProcessors,
|
||||||
|
ensightFile
|
||||||
|
)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
ensightPatchi++;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
else if (Pstream::master())
|
||||||
|
{
|
||||||
|
faceSets nullFaceSet;
|
||||||
|
|
||||||
|
if
|
||||||
|
(
|
||||||
|
writePatchFieldBinary
|
||||||
|
(
|
||||||
|
Field<Type>(),
|
||||||
|
-1,
|
||||||
|
ensightPatchi,
|
||||||
|
nullFaceSet,
|
||||||
|
nPatchPrims.find(patchName)(),
|
||||||
|
patchProcessors,
|
||||||
|
ensightFile
|
||||||
|
)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
ensightPatchi++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Pstream::master())
|
||||||
|
{
|
||||||
|
ensightFile.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class Type>
|
||||||
|
void ensightField
|
||||||
|
(
|
||||||
|
const Foam::IOobject& fieldObject,
|
||||||
|
const Foam::ensightMesh& eMesh,
|
||||||
|
const Foam::fileName& postProcPath,
|
||||||
|
const Foam::word& prepend,
|
||||||
|
const Foam::label timeIndex,
|
||||||
|
const bool binary,
|
||||||
|
Foam::Ostream& ensightCaseFile
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (binary)
|
||||||
|
{
|
||||||
|
ensightFieldBinary<Type>
|
||||||
|
(
|
||||||
|
fieldObject,
|
||||||
|
eMesh,
|
||||||
|
postProcPath,
|
||||||
|
prepend,
|
||||||
|
timeIndex,
|
||||||
|
ensightCaseFile
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ensightFieldAscii<Type>
|
||||||
|
(
|
||||||
|
fieldObject,
|
||||||
|
eMesh,
|
||||||
|
postProcPath,
|
||||||
|
prepend,
|
||||||
|
timeIndex,
|
||||||
|
ensightCaseFile
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
// ************************************************************************* //
|
||||||
|
|||||||
@ -22,8 +22,8 @@ License
|
|||||||
along with OpenFOAM; if not, write to the Free Software Foundation,
|
along with OpenFOAM; if not, write to the Free Software Foundation,
|
||||||
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
|
||||||
InClass
|
InApplication
|
||||||
Foam::ensightField
|
foamToEnsight
|
||||||
|
|
||||||
Description
|
Description
|
||||||
|
|
||||||
@ -48,6 +48,7 @@ void ensightField
|
|||||||
const Foam::fileName& postProcPath,
|
const Foam::fileName& postProcPath,
|
||||||
const Foam::word& prepend,
|
const Foam::word& prepend,
|
||||||
const Foam::label timeIndex,
|
const Foam::label timeIndex,
|
||||||
|
const bool binary,
|
||||||
Foam::Ostream& ensightCaseFile
|
Foam::Ostream& ensightCaseFile
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@ -33,8 +33,10 @@ License
|
|||||||
#include "cellModeller.H"
|
#include "cellModeller.H"
|
||||||
#include "IOmanip.H"
|
#include "IOmanip.H"
|
||||||
#include "itoa.H"
|
#include "itoa.H"
|
||||||
|
#include "ensightWriteBinary.H"
|
||||||
|
#include <fstream>
|
||||||
|
|
||||||
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
// * * * * * * * * * * * * * Private Functions * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
namespace Foam
|
namespace Foam
|
||||||
{
|
{
|
||||||
@ -85,9 +87,14 @@ public:
|
|||||||
|
|
||||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
// Construct from fvMesh
|
Foam::ensightMesh::ensightMesh
|
||||||
Foam::ensightMesh::ensightMesh(const fvMesh& fMesh, const argList& args)
|
(
|
||||||
|
const fvMesh& fMesh,
|
||||||
|
const argList& args,
|
||||||
|
const bool binary
|
||||||
|
)
|
||||||
:
|
:
|
||||||
|
binary_(binary),
|
||||||
mesh(fMesh),
|
mesh(fMesh),
|
||||||
meshCellSets(mesh.nCells()),
|
meshCellSets(mesh.nCells()),
|
||||||
boundaryFaceSets(mesh.boundary().size())
|
boundaryFaceSets(mesh.boundary().size())
|
||||||
@ -130,7 +137,6 @@ Foam::ensightMesh::ensightMesh(const fvMesh& fMesh, const argList& args)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const cellShapeList& cellShapes = mesh.cellShapes();
|
const cellShapeList& cellShapes = mesh.cellShapes();
|
||||||
|
|
||||||
const cellModel& tet = *(cellModeller::lookup("tet"));
|
const cellModel& tet = *(cellModeller::lookup("tet"));
|
||||||
@ -385,6 +391,48 @@ void Foam::ensightMesh::writePrims
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::ensightMesh::writePrimsBinary
|
||||||
|
(
|
||||||
|
const cellShapeList& cellShapes,
|
||||||
|
const label pointOffset,
|
||||||
|
std::ofstream& ensightGeometryFile
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
label po = pointOffset + 1;
|
||||||
|
|
||||||
|
// Create a temp int array
|
||||||
|
int numElem;
|
||||||
|
|
||||||
|
numElem = cellShapes.size();
|
||||||
|
|
||||||
|
if (cellShapes.size() > 0)
|
||||||
|
{
|
||||||
|
// All the cellShapes have the same number of elements!
|
||||||
|
int numIntElem = cellShapes.size() * cellShapes[0].size();
|
||||||
|
List<int> temp(numIntElem);
|
||||||
|
|
||||||
|
int n = 0;
|
||||||
|
|
||||||
|
forAll(cellShapes, i)
|
||||||
|
{
|
||||||
|
const cellShape& cellPoints = cellShapes[i];
|
||||||
|
|
||||||
|
forAll(cellPoints, pointi)
|
||||||
|
{
|
||||||
|
temp[n] = cellPoints[pointi] + po;
|
||||||
|
n++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ensightGeometryFile.write
|
||||||
|
(
|
||||||
|
reinterpret_cast<char*>(temp.begin()),
|
||||||
|
numIntElem*sizeof(int)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void Foam::ensightMesh::writePolys
|
void Foam::ensightMesh::writePolys
|
||||||
(
|
(
|
||||||
const labelList& polys,
|
const labelList& polys,
|
||||||
@ -437,6 +485,64 @@ void Foam::ensightMesh::writePolys
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::ensightMesh::writePolysBinary
|
||||||
|
(
|
||||||
|
const labelList& polys,
|
||||||
|
const cellList& cellFaces,
|
||||||
|
const faceList& faces,
|
||||||
|
const label pointOffset,
|
||||||
|
std::ofstream& ensightGeometryFile
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
if (polys.size())
|
||||||
|
{
|
||||||
|
writeEnsDataBinary("nfaced",ensightGeometryFile);
|
||||||
|
writeEnsDataBinary(polys.size(),ensightGeometryFile);
|
||||||
|
|
||||||
|
label po = pointOffset + 1;
|
||||||
|
|
||||||
|
//TODO No buffer at the moment. To be done for speed purposes!
|
||||||
|
forAll(polys, i)
|
||||||
|
{
|
||||||
|
writeEnsDataBinary
|
||||||
|
(
|
||||||
|
cellFaces[polys[i]].size(),
|
||||||
|
ensightGeometryFile
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
forAll(polys, i)
|
||||||
|
{
|
||||||
|
const labelList& cf = cellFaces[polys[i]];
|
||||||
|
|
||||||
|
forAll(cf, facei)
|
||||||
|
{
|
||||||
|
writeEnsDataBinary
|
||||||
|
(
|
||||||
|
faces[cf[facei]].size(),
|
||||||
|
ensightGeometryFile
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
forAll(polys, i)
|
||||||
|
{
|
||||||
|
const labelList& cf = cellFaces[polys[i]];
|
||||||
|
|
||||||
|
forAll(cf, facei)
|
||||||
|
{
|
||||||
|
const face& f = faces[cf[facei]];
|
||||||
|
|
||||||
|
forAll(f, pointi)
|
||||||
|
{
|
||||||
|
writeEnsDataBinary(f[pointi] + po,ensightGeometryFile);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void Foam::ensightMesh::writeAllPrims
|
void Foam::ensightMesh::writeAllPrims
|
||||||
(
|
(
|
||||||
const char* key,
|
const char* key,
|
||||||
@ -476,6 +582,46 @@ void Foam::ensightMesh::writeAllPrims
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::ensightMesh::writeAllPrimsBinary
|
||||||
|
(
|
||||||
|
const char* key,
|
||||||
|
const label nPrims,
|
||||||
|
const cellShapeList& cellShapes,
|
||||||
|
const labelList& pointOffsets,
|
||||||
|
std::ofstream& ensightGeometryFile
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
if (nPrims)
|
||||||
|
{
|
||||||
|
if (Pstream::master())
|
||||||
|
{
|
||||||
|
writeEnsDataBinary(key,ensightGeometryFile);
|
||||||
|
writeEnsDataBinary(nPrims,ensightGeometryFile);
|
||||||
|
|
||||||
|
writePrimsBinary(cellShapes, 0, ensightGeometryFile);
|
||||||
|
|
||||||
|
for (int slave=1; slave<Pstream::nProcs(); slave++)
|
||||||
|
{
|
||||||
|
IPstream fromSlave(Pstream::scheduled, slave);
|
||||||
|
cellShapeList cellShapes(fromSlave);
|
||||||
|
|
||||||
|
writePrimsBinary
|
||||||
|
(
|
||||||
|
cellShapes,
|
||||||
|
pointOffsets[slave-1],
|
||||||
|
ensightGeometryFile
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
OPstream toMaster(Pstream::scheduled, Pstream::masterNo());
|
||||||
|
toMaster<< cellShapes;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void Foam::ensightMesh::writeFacePrims
|
void Foam::ensightMesh::writeFacePrims
|
||||||
(
|
(
|
||||||
const char* key,
|
const char* key,
|
||||||
@ -514,6 +660,51 @@ void Foam::ensightMesh::writeFacePrims
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::ensightMesh::writeFacePrimsBinary
|
||||||
|
(
|
||||||
|
const char* key,
|
||||||
|
const faceList& patchFaces,
|
||||||
|
const label pointOffset,
|
||||||
|
std::ofstream& ensightGeometryFile
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
if (patchFaces.size())
|
||||||
|
{
|
||||||
|
//TODO No buffer at the moment. To be done for speed purposes!
|
||||||
|
if (word(key) == "nsided")
|
||||||
|
{
|
||||||
|
writeEnsDataBinary(key,ensightGeometryFile);
|
||||||
|
writeEnsDataBinary(patchFaces.size(),ensightGeometryFile);
|
||||||
|
|
||||||
|
forAll(patchFaces, i)
|
||||||
|
{
|
||||||
|
writeEnsDataBinary
|
||||||
|
(
|
||||||
|
patchFaces[i].size(),
|
||||||
|
ensightGeometryFile
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
label po = pointOffset + 1;
|
||||||
|
|
||||||
|
forAll(patchFaces, i)
|
||||||
|
{
|
||||||
|
const face& patchFace = patchFaces[i];
|
||||||
|
|
||||||
|
forAll(patchFace, pointi)
|
||||||
|
{
|
||||||
|
writeEnsDataBinary
|
||||||
|
(
|
||||||
|
patchFace[pointi] + po,
|
||||||
|
ensightGeometryFile
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
Foam::faceList Foam::ensightMesh::map
|
Foam::faceList Foam::ensightMesh::map
|
||||||
(
|
(
|
||||||
const faceList& patchFaces,
|
const faceList& patchFaces,
|
||||||
@ -589,6 +780,65 @@ void Foam::ensightMesh::writeAllFacePrims
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::ensightMesh::writeAllFacePrimsBinary
|
||||||
|
(
|
||||||
|
const char* key,
|
||||||
|
const labelList& prims,
|
||||||
|
const label nPrims,
|
||||||
|
const faceList& patchFaces,
|
||||||
|
const labelList& pointOffsets,
|
||||||
|
const labelList& patchProcessors,
|
||||||
|
std::ofstream& ensightGeometryFile
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
if (nPrims)
|
||||||
|
{
|
||||||
|
if (Pstream::master())
|
||||||
|
{
|
||||||
|
if (word(key) != "nsided")
|
||||||
|
{
|
||||||
|
writeEnsDataBinary(key,ensightGeometryFile);
|
||||||
|
writeEnsDataBinary(nPrims,ensightGeometryFile);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (&prims != NULL)
|
||||||
|
{
|
||||||
|
writeFacePrimsBinary
|
||||||
|
(
|
||||||
|
key,
|
||||||
|
map(patchFaces, prims),
|
||||||
|
0,
|
||||||
|
ensightGeometryFile
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
forAll (patchProcessors, i)
|
||||||
|
{
|
||||||
|
if (patchProcessors[i] != 0)
|
||||||
|
{
|
||||||
|
label slave = patchProcessors[i];
|
||||||
|
IPstream fromSlave(Pstream::scheduled, slave);
|
||||||
|
faceList patchFaces(fromSlave);
|
||||||
|
|
||||||
|
writeFacePrimsBinary
|
||||||
|
(
|
||||||
|
key,
|
||||||
|
patchFaces,
|
||||||
|
pointOffsets[i],
|
||||||
|
ensightGeometryFile
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (&prims != NULL)
|
||||||
|
{
|
||||||
|
OPstream toMaster(Pstream::scheduled, Pstream::masterNo());
|
||||||
|
toMaster<< map(patchFaces, prims);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void Foam::ensightMesh::write
|
void Foam::ensightMesh::write
|
||||||
(
|
(
|
||||||
const fileName& postProcPath,
|
const fileName& postProcPath,
|
||||||
@ -596,6 +846,25 @@ void Foam::ensightMesh::write
|
|||||||
const label timeIndex,
|
const label timeIndex,
|
||||||
Ostream& ensightCaseFile
|
Ostream& ensightCaseFile
|
||||||
) const
|
) const
|
||||||
|
{
|
||||||
|
if (binary_)
|
||||||
|
{
|
||||||
|
writeBinary(postProcPath, prepend, timeIndex, ensightCaseFile);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
writeAscii(postProcPath, prepend, timeIndex, ensightCaseFile);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::ensightMesh::writeAscii
|
||||||
|
(
|
||||||
|
const fileName& postProcPath,
|
||||||
|
const word& prepend,
|
||||||
|
const label timeIndex,
|
||||||
|
Ostream& ensightCaseFile
|
||||||
|
) const
|
||||||
{
|
{
|
||||||
const Time& runTime = mesh.time();
|
const Time& runTime = mesh.time();
|
||||||
const pointField& points = mesh.points();
|
const pointField& points = mesh.points();
|
||||||
@ -643,7 +912,7 @@ void Foam::ensightMesh::write
|
|||||||
|
|
||||||
ensightGeometryFile
|
ensightGeometryFile
|
||||||
<< "OpenFOAM Geometry File " << nl
|
<< "OpenFOAM Geometry File " << nl
|
||||||
<< "EnSight 8.2.6" << nl
|
<< "OpenFOAM version " << Foam::FOAMversion << nl
|
||||||
<< "node id assign" << nl
|
<< "node id assign" << nl
|
||||||
<< "element id assign" << nl;
|
<< "element id assign" << nl;
|
||||||
}
|
}
|
||||||
@ -929,4 +1198,336 @@ void Foam::ensightMesh::write
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::ensightMesh::writeBinary
|
||||||
|
(
|
||||||
|
const fileName& postProcPath,
|
||||||
|
const word& prepend,
|
||||||
|
const label timeIndex,
|
||||||
|
Ostream& ensightCaseFile
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
//const Time& runTime = mesh.time();
|
||||||
|
const pointField& points = mesh.points();
|
||||||
|
const cellList& cellFaces = mesh.cells();
|
||||||
|
const faceList& faces = mesh.faces();
|
||||||
|
const cellShapeList& cellShapes = mesh.cellShapes();
|
||||||
|
|
||||||
|
word timeFile = prepend;
|
||||||
|
|
||||||
|
if (timeIndex == 0)
|
||||||
|
{
|
||||||
|
timeFile += "000.";
|
||||||
|
}
|
||||||
|
else if (mesh.moving())
|
||||||
|
{
|
||||||
|
timeFile += itoa(timeIndex) + '.';
|
||||||
|
}
|
||||||
|
|
||||||
|
// set the filename of the ensight file
|
||||||
|
fileName ensightGeometryFileName = timeFile + "mesh";
|
||||||
|
|
||||||
|
std::ofstream *ensightGeometryFilePtr = NULL;
|
||||||
|
|
||||||
|
if (Pstream::master())
|
||||||
|
{
|
||||||
|
ensightGeometryFilePtr = new std::ofstream((postProcPath/ensightGeometryFileName).c_str(), ios_base::out | ios_base::binary | ios_base::trunc);
|
||||||
|
// Check on file opened?
|
||||||
|
}
|
||||||
|
|
||||||
|
std::ofstream& ensightGeometryFile = *ensightGeometryFilePtr;
|
||||||
|
|
||||||
|
if (Pstream::master())
|
||||||
|
{
|
||||||
|
writeEnsDataBinary("C binary",ensightGeometryFile);
|
||||||
|
writeEnsDataBinary("OpenFOAM Geometry File",ensightGeometryFile);
|
||||||
|
writeEnsDataBinary("Binary format",ensightGeometryFile);
|
||||||
|
writeEnsDataBinary("node id assign",ensightGeometryFile);
|
||||||
|
writeEnsDataBinary("element id assign",ensightGeometryFile);
|
||||||
|
}
|
||||||
|
|
||||||
|
labelList pointOffsets(Pstream::nProcs(), 0);
|
||||||
|
|
||||||
|
if (!patchNames.size())
|
||||||
|
{
|
||||||
|
label nPoints = points.size();
|
||||||
|
Pstream::gather(nPoints, sumOp<label>());
|
||||||
|
|
||||||
|
if (Pstream::master())
|
||||||
|
{
|
||||||
|
writeEnsDataBinary("part",ensightGeometryFile);
|
||||||
|
writeEnsDataBinary(1,ensightGeometryFile);
|
||||||
|
writeEnsDataBinary("FOAM cells",ensightGeometryFile);
|
||||||
|
writeEnsDataBinary("coordinates",ensightGeometryFile);
|
||||||
|
writeEnsDataBinary(nPoints,ensightGeometryFile);
|
||||||
|
|
||||||
|
for (direction d=0; d<vector::nComponents; d++)
|
||||||
|
{
|
||||||
|
//writePointsBinary(points.component(d), ensightGeometryFile);
|
||||||
|
writeEnsDataBinary(points.component(d), ensightGeometryFile);
|
||||||
|
pointOffsets[0] = points.size();
|
||||||
|
|
||||||
|
for (int slave=1; slave<Pstream::nProcs(); slave++)
|
||||||
|
{
|
||||||
|
IPstream fromSlave(Pstream::scheduled, slave);
|
||||||
|
scalarField pointsComponent(fromSlave);
|
||||||
|
//writePointsBinary(pointsComponent, ensightGeometryFile);
|
||||||
|
writeEnsDataBinary(pointsComponent, ensightGeometryFile);
|
||||||
|
pointOffsets[slave] =
|
||||||
|
pointOffsets[slave-1]
|
||||||
|
+ pointsComponent.size();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (direction d=0; d<vector::nComponents; d++)
|
||||||
|
{
|
||||||
|
OPstream toMaster(Pstream::scheduled, Pstream::masterNo());
|
||||||
|
toMaster<< points.component(d);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
writeAllPrimsBinary
|
||||||
|
(
|
||||||
|
"hexa8",
|
||||||
|
meshCellSets.nHexesWedges,
|
||||||
|
map(cellShapes, meshCellSets.hexes, meshCellSets.wedges),
|
||||||
|
pointOffsets,
|
||||||
|
ensightGeometryFile
|
||||||
|
);
|
||||||
|
|
||||||
|
writeAllPrimsBinary
|
||||||
|
(
|
||||||
|
"penta6",
|
||||||
|
meshCellSets.nPrisms,
|
||||||
|
map(cellShapes, meshCellSets.prisms),
|
||||||
|
pointOffsets,
|
||||||
|
ensightGeometryFile
|
||||||
|
);
|
||||||
|
|
||||||
|
writeAllPrimsBinary
|
||||||
|
(
|
||||||
|
"pyramid5",
|
||||||
|
meshCellSets.nPyrs,
|
||||||
|
map(cellShapes, meshCellSets.pyrs),
|
||||||
|
pointOffsets,
|
||||||
|
ensightGeometryFile
|
||||||
|
);
|
||||||
|
|
||||||
|
writeAllPrimsBinary
|
||||||
|
(
|
||||||
|
"tetra4",
|
||||||
|
meshCellSets.nTets,
|
||||||
|
map(cellShapes, meshCellSets.tets),
|
||||||
|
pointOffsets,
|
||||||
|
ensightGeometryFile
|
||||||
|
);
|
||||||
|
|
||||||
|
if (meshCellSets.nPolys)
|
||||||
|
{
|
||||||
|
if (Pstream::master())
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
ensightGeometryFile
|
||||||
|
<< "nfaced" << nl
|
||||||
|
<< setw(10) << meshCellSets.nPolys << nl;
|
||||||
|
*/
|
||||||
|
writePolysBinary
|
||||||
|
(
|
||||||
|
meshCellSets.polys,
|
||||||
|
cellFaces,
|
||||||
|
faces,
|
||||||
|
0,
|
||||||
|
ensightGeometryFile
|
||||||
|
);
|
||||||
|
|
||||||
|
for (int slave=1; slave<Pstream::nProcs(); slave++)
|
||||||
|
{
|
||||||
|
IPstream fromSlave(Pstream::scheduled, slave);
|
||||||
|
labelList polys(fromSlave);
|
||||||
|
cellList cellFaces(fromSlave);
|
||||||
|
faceList faces(fromSlave);
|
||||||
|
|
||||||
|
writePolysBinary
|
||||||
|
(
|
||||||
|
polys,
|
||||||
|
cellFaces,
|
||||||
|
faces,
|
||||||
|
pointOffsets[slave-1],
|
||||||
|
ensightGeometryFile
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
OPstream toMaster(Pstream::scheduled, Pstream::masterNo());
|
||||||
|
toMaster<< meshCellSets.polys << cellFaces << faces;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
label ensightPatchi = 2;
|
||||||
|
|
||||||
|
label iCount = 0;
|
||||||
|
|
||||||
|
for
|
||||||
|
(
|
||||||
|
HashTable<labelList>::const_iterator iter = allPatchNames.begin();
|
||||||
|
iter != allPatchNames.end();
|
||||||
|
++iter
|
||||||
|
)
|
||||||
|
{
|
||||||
|
iCount ++;
|
||||||
|
const labelList& patchProcessors = iter();
|
||||||
|
|
||||||
|
if (!patchNames.size() || patchNames.found(iter.key()))
|
||||||
|
{
|
||||||
|
const word& patchName = iter.key();
|
||||||
|
const nFacePrims& nfp = nPatchPrims.find(patchName)();
|
||||||
|
|
||||||
|
const labelList *trisPtr = NULL;
|
||||||
|
const labelList *quadsPtr = NULL;
|
||||||
|
const labelList *polysPtr = NULL;
|
||||||
|
|
||||||
|
const pointField *patchPointsPtr = NULL;
|
||||||
|
const faceList *patchFacesPtr = NULL;
|
||||||
|
|
||||||
|
if (patchIndices.found(iter.key()))
|
||||||
|
{
|
||||||
|
label patchi = patchIndices.find(iter.key())();
|
||||||
|
const polyPatch& p = mesh.boundaryMesh()[patchi];
|
||||||
|
|
||||||
|
trisPtr = &boundaryFaceSets[patchi].tris;
|
||||||
|
quadsPtr = &boundaryFaceSets[patchi].quads;
|
||||||
|
polysPtr = &boundaryFaceSets[patchi].polys;
|
||||||
|
|
||||||
|
patchPointsPtr = &(p.localPoints());
|
||||||
|
patchFacesPtr = &(p.localFaces());
|
||||||
|
}
|
||||||
|
|
||||||
|
const labelList& tris = *trisPtr;
|
||||||
|
const labelList& quads = *quadsPtr;
|
||||||
|
const labelList& polys = *polysPtr;
|
||||||
|
const pointField& patchPoints = *patchPointsPtr;
|
||||||
|
const faceList& patchFaces = *patchFacesPtr;
|
||||||
|
|
||||||
|
if (nfp.nTris || nfp.nQuads || nfp.nPolys)
|
||||||
|
{
|
||||||
|
labelList patchPointOffsets(Pstream::nProcs(), 0);
|
||||||
|
|
||||||
|
if (Pstream::master())
|
||||||
|
{
|
||||||
|
writeEnsDataBinary("part",ensightGeometryFile);
|
||||||
|
writeEnsDataBinary(ensightPatchi++,ensightGeometryFile);
|
||||||
|
//writeEnsDataBinary(patchName.c_str(),ensightGeometryFile);
|
||||||
|
writeEnsDataBinary(iter.key().c_str(),ensightGeometryFile);
|
||||||
|
writeEnsDataBinary("coordinates",ensightGeometryFile);
|
||||||
|
writeEnsDataBinary(nfp.nPoints,ensightGeometryFile);
|
||||||
|
|
||||||
|
for (direction d=0; d<vector::nComponents; d++)
|
||||||
|
{
|
||||||
|
if (patchPointsPtr)
|
||||||
|
{
|
||||||
|
//writePointsBinary
|
||||||
|
writeEnsDataBinary
|
||||||
|
(
|
||||||
|
patchPoints.component(d),
|
||||||
|
ensightGeometryFile
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
patchPointOffsets = 0;
|
||||||
|
|
||||||
|
|
||||||
|
forAll (patchProcessors, i)
|
||||||
|
{
|
||||||
|
if (patchProcessors[i] != 0)
|
||||||
|
{
|
||||||
|
label slave = patchProcessors[i];
|
||||||
|
IPstream fromSlave(Pstream::scheduled, slave);
|
||||||
|
scalarField patchPointsComponent(fromSlave);
|
||||||
|
|
||||||
|
//writePointsBinary
|
||||||
|
writeEnsDataBinary
|
||||||
|
(
|
||||||
|
patchPointsComponent,
|
||||||
|
ensightGeometryFile
|
||||||
|
);
|
||||||
|
|
||||||
|
if (i < Pstream::nProcs()-1)
|
||||||
|
{
|
||||||
|
patchPointOffsets[i+1] =
|
||||||
|
patchPointOffsets[i]
|
||||||
|
+ patchPointsComponent.size();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (i < Pstream::nProcs()-1)
|
||||||
|
{
|
||||||
|
patchPointOffsets[i+1] =
|
||||||
|
patchPointOffsets[i]
|
||||||
|
+ patchPoints.size();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (patchPointsPtr)
|
||||||
|
{
|
||||||
|
for (direction d=0; d<vector::nComponents; d++)
|
||||||
|
{
|
||||||
|
OPstream toMaster
|
||||||
|
(
|
||||||
|
Pstream::scheduled,
|
||||||
|
Pstream::masterNo()
|
||||||
|
);
|
||||||
|
toMaster<< patchPoints.component(d);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
writeAllFacePrimsBinary
|
||||||
|
(
|
||||||
|
"tria3",
|
||||||
|
tris,
|
||||||
|
nfp.nTris,
|
||||||
|
patchFaces,
|
||||||
|
patchPointOffsets,
|
||||||
|
patchProcessors,
|
||||||
|
ensightGeometryFile
|
||||||
|
);
|
||||||
|
|
||||||
|
writeAllFacePrimsBinary
|
||||||
|
(
|
||||||
|
"quad4",
|
||||||
|
quads,
|
||||||
|
nfp.nQuads,
|
||||||
|
patchFaces,
|
||||||
|
patchPointOffsets,
|
||||||
|
patchProcessors,
|
||||||
|
ensightGeometryFile
|
||||||
|
);
|
||||||
|
|
||||||
|
writeAllFacePrimsBinary
|
||||||
|
(
|
||||||
|
"nsided",
|
||||||
|
polys,
|
||||||
|
nfp.nPolys,
|
||||||
|
patchFaces,
|
||||||
|
patchPointOffsets,
|
||||||
|
patchProcessors,
|
||||||
|
ensightGeometryFile
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (Pstream::master())
|
||||||
|
{
|
||||||
|
delete ensightGeometryFilePtr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// ************************************************************************* //
|
// ************************************************************************* //
|
||||||
|
|||||||
@ -41,6 +41,7 @@ SourceFiles
|
|||||||
#include "HashSet.H"
|
#include "HashSet.H"
|
||||||
#include "fvMesh.H"
|
#include "fvMesh.H"
|
||||||
#include "OFstream.H"
|
#include "OFstream.H"
|
||||||
|
#include <fstream>
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
@ -58,6 +59,9 @@ class ensightMesh
|
|||||||
{
|
{
|
||||||
// Private data
|
// Private data
|
||||||
|
|
||||||
|
//- Set binary file output
|
||||||
|
bool binary_;
|
||||||
|
|
||||||
|
|
||||||
// Private Member Functions
|
// Private Member Functions
|
||||||
|
|
||||||
@ -136,6 +140,66 @@ class ensightMesh
|
|||||||
OFstream& ensightGeometryFile
|
OFstream& ensightGeometryFile
|
||||||
) const;
|
) const;
|
||||||
|
|
||||||
|
void writeAscii
|
||||||
|
(
|
||||||
|
const fileName& postProcPath,
|
||||||
|
const word& prepend,
|
||||||
|
const label timeIndex,
|
||||||
|
Ostream& ensightCaseFile
|
||||||
|
) const;
|
||||||
|
|
||||||
|
void writeBinary
|
||||||
|
(
|
||||||
|
const fileName& postProcPath,
|
||||||
|
const word& prepend,
|
||||||
|
const label timeIndex,
|
||||||
|
Ostream& ensightCaseFile
|
||||||
|
) const;
|
||||||
|
|
||||||
|
void writePrimsBinary
|
||||||
|
(
|
||||||
|
const cellShapeList& cellShapes,
|
||||||
|
const label pointOffset,
|
||||||
|
std::ofstream& ensightGeometryFile
|
||||||
|
) const;
|
||||||
|
|
||||||
|
void writeAllPrimsBinary
|
||||||
|
(
|
||||||
|
const char* key,
|
||||||
|
const label nPrims,
|
||||||
|
const cellShapeList& cellShapes,
|
||||||
|
const labelList& pointOffsets,
|
||||||
|
std::ofstream& ensightGeometryFile
|
||||||
|
) const;
|
||||||
|
|
||||||
|
void writePolysBinary
|
||||||
|
(
|
||||||
|
const labelList& polys,
|
||||||
|
const cellList& cellFaces,
|
||||||
|
const faceList& faces,
|
||||||
|
const label pointOffset,
|
||||||
|
std::ofstream& ensightGeometryFile
|
||||||
|
) const;
|
||||||
|
|
||||||
|
void writeAllFacePrimsBinary
|
||||||
|
(
|
||||||
|
const char* key,
|
||||||
|
const labelList& prims,
|
||||||
|
const label nPrims,
|
||||||
|
const faceList& patchFaces,
|
||||||
|
const labelList& pointOffsets,
|
||||||
|
const labelList& patchProcessors,
|
||||||
|
std::ofstream& ensightGeometryFile
|
||||||
|
) const;
|
||||||
|
|
||||||
|
void writeFacePrimsBinary
|
||||||
|
(
|
||||||
|
const char* key,
|
||||||
|
const faceList& patchFaces,
|
||||||
|
const label pointOffset,
|
||||||
|
std::ofstream& ensightGeometryFile
|
||||||
|
) const;
|
||||||
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
@ -151,7 +215,6 @@ public:
|
|||||||
|
|
||||||
class nFacePrims
|
class nFacePrims
|
||||||
{
|
{
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
label nPoints;
|
label nPoints;
|
||||||
@ -174,7 +237,7 @@ public:
|
|||||||
// Constructors
|
// Constructors
|
||||||
|
|
||||||
//- Construct from fvMesh
|
//- Construct from fvMesh
|
||||||
ensightMesh(const fvMesh&, const argList& args);
|
ensightMesh(const fvMesh&, const argList& args, const bool binary);
|
||||||
|
|
||||||
|
|
||||||
// Destructor
|
// Destructor
|
||||||
@ -184,21 +247,13 @@ public:
|
|||||||
|
|
||||||
// Member Functions
|
// Member Functions
|
||||||
|
|
||||||
// Access
|
void write
|
||||||
|
(
|
||||||
// Check
|
const fileName& postProcPath,
|
||||||
|
const word& prepend,
|
||||||
// Edit
|
const label timeIndex,
|
||||||
|
Ostream& ensightCaseFile
|
||||||
// Write
|
) const;
|
||||||
|
|
||||||
void write
|
|
||||||
(
|
|
||||||
const fileName& postProcPath,
|
|
||||||
const word& prepend,
|
|
||||||
const label timeIndex,
|
|
||||||
Ostream& ensightCaseFile
|
|
||||||
) const;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -22,8 +22,6 @@ License
|
|||||||
along with OpenFOAM; if not, write to the Free Software Foundation,
|
along with OpenFOAM; if not, write to the Free Software Foundation,
|
||||||
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
|
||||||
Description
|
|
||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
#include "ensightParticlePositions.H"
|
#include "ensightParticlePositions.H"
|
||||||
@ -82,7 +80,7 @@ void ensightParticlePositions
|
|||||||
{
|
{
|
||||||
const vector& p = elmnt().position();
|
const vector& p = elmnt().position();
|
||||||
|
|
||||||
ensightFile
|
ensightFile
|
||||||
<< setw(8) << ++nParcels
|
<< setw(8) << ++nParcels
|
||||||
<< setw(12) << p.x() << setw(12) << p.y() << setw(12) << p.z()
|
<< setw(12) << p.x() << setw(12) << p.y() << setw(12) << p.z()
|
||||||
<< nl;
|
<< nl;
|
||||||
|
|||||||
@ -22,8 +22,8 @@ License
|
|||||||
along with OpenFOAM; if not, write to the Free Software Foundation,
|
along with OpenFOAM; if not, write to the Free Software Foundation,
|
||||||
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
|
||||||
InClass
|
InApplication
|
||||||
Foam::ensightParticlePositions
|
foamToEnsight
|
||||||
|
|
||||||
Description
|
Description
|
||||||
|
|
||||||
|
|||||||
@ -22,8 +22,6 @@ License
|
|||||||
along with OpenFOAM; if not, write to the Free Software Foundation,
|
along with OpenFOAM; if not, write to the Free Software Foundation,
|
||||||
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
|
||||||
Description
|
|
||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
#include "ensightSprayField.H"
|
#include "ensightSprayField.H"
|
||||||
@ -83,7 +81,7 @@ void ensightSprayField
|
|||||||
ensightFile << pTraits<Type>::typeName << " values" << nl;
|
ensightFile << pTraits<Type>::typeName << " values" << nl;
|
||||||
|
|
||||||
IOField<Type> vf(fieldObject);
|
IOField<Type> vf(fieldObject);
|
||||||
|
|
||||||
ensightFile.setf(ios_base::scientific, ios_base::floatfield);
|
ensightFile.setf(ios_base::scientific, ios_base::floatfield);
|
||||||
ensightFile.precision(5);
|
ensightFile.precision(5);
|
||||||
|
|
||||||
@ -104,7 +102,7 @@ void ensightSprayField
|
|||||||
{
|
{
|
||||||
ensightFile << nl;
|
ensightFile << nl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( (count % 6 != 0) || (count==0) )
|
if ( (count % 6 != 0) || (count==0) )
|
||||||
|
|||||||
@ -22,8 +22,8 @@ License
|
|||||||
along with OpenFOAM; if not, write to the Free Software Foundation,
|
along with OpenFOAM; if not, write to the Free Software Foundation,
|
||||||
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
|
||||||
InClass
|
InApplication
|
||||||
Foam::ensightSprayField
|
foamToEnsight
|
||||||
|
|
||||||
Description
|
Description
|
||||||
|
|
||||||
|
|||||||
@ -24,44 +24,56 @@ License
|
|||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
#include "processorLduInterfaceField.H"
|
#include "ensightWriteBinary.H"
|
||||||
#include "diagTensorField.H"
|
#include <fstream>
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
namespace Foam
|
void writeEnsDataBinary
|
||||||
|
(
|
||||||
|
const char* val,
|
||||||
|
std::ofstream& ensFile
|
||||||
|
)
|
||||||
{
|
{
|
||||||
//defineTypeNameAndDebug(processorLduInterfaceField, 0);
|
char buffer[80] = {0};
|
||||||
|
strcpy(buffer, val);
|
||||||
|
ensFile.write(buffer, 80*sizeof(char));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
|
void writeEnsDataBinary
|
||||||
|
|
||||||
template<class Type>
|
|
||||||
Foam::processorLduInterfaceField<Type>::~processorLduInterfaceField()
|
|
||||||
{}
|
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
template<class Type>
|
|
||||||
void Foam::processorLduInterfaceField<Type>::transformCoupleField
|
|
||||||
(
|
(
|
||||||
Field<Type>& f
|
const int val,
|
||||||
) const
|
std::ofstream& ensFile
|
||||||
|
)
|
||||||
{
|
{
|
||||||
if (doTransform())
|
ensFile.write(reinterpret_cast<const char*>(&val), sizeof(int));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void writeEnsDataBinary
|
||||||
|
(
|
||||||
|
const scalarField& sf,
|
||||||
|
std::ofstream& ensightFile
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (sf.size() > 0)
|
||||||
{
|
{
|
||||||
if (forwardT().size() == 1)
|
List<float> temp(sf.size());
|
||||||
|
|
||||||
|
forAll(sf, i)
|
||||||
{
|
{
|
||||||
transform(f, forwardT()[0], f);
|
temp[i] = float(sf[i]);
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
transform(f, forwardT(), f);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ensightFile.write
|
||||||
|
(
|
||||||
|
reinterpret_cast<char*>(temp.begin()),
|
||||||
|
sf.size()*sizeof(float)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
// ************************************************************************* //
|
||||||
|
|
||||||
@ -22,27 +22,47 @@ License
|
|||||||
along with OpenFOAM; if not, write to the Free Software Foundation,
|
along with OpenFOAM; if not, write to the Free Software Foundation,
|
||||||
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
|
||||||
|
InApplication
|
||||||
|
foamToEnsight
|
||||||
|
|
||||||
|
Description
|
||||||
|
Collection of functions for binary write in EnSight files
|
||||||
|
|
||||||
|
SourceFiles
|
||||||
|
ensightWriteBinary.C
|
||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
#include "lduInterfaceField.H"
|
#ifndef ensightWriteBinary_H
|
||||||
|
#define ensightWriteBinary_H
|
||||||
|
|
||||||
|
#include "ensightMesh.H"
|
||||||
|
|
||||||
|
using namespace Foam;
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
namespace Foam
|
void writeEnsDataBinary
|
||||||
{
|
(
|
||||||
|
const char* val,
|
||||||
|
std::ofstream& ensFile
|
||||||
|
);
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
void writeEnsDataBinary
|
||||||
|
(
|
||||||
|
const int val,
|
||||||
|
std::ofstream& ensFile
|
||||||
|
);
|
||||||
|
|
||||||
defineTypeNameAndDebug(lduInterfaceField, 0);
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
lduInterfaceField::~lduInterfaceField()
|
|
||||||
{}
|
|
||||||
|
|
||||||
|
void writeEnsDataBinary
|
||||||
|
(
|
||||||
|
const scalarField& sf,
|
||||||
|
std::ofstream& ensightFile
|
||||||
|
);
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
} // End namespace Foam
|
#endif
|
||||||
|
|
||||||
// ************************************************************************* //
|
// ************************************************************************* //
|
||||||
@ -52,26 +52,9 @@ using namespace Foam;
|
|||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
argList::validOptions.insert("patches", "patch list");
|
argList::validOptions.insert("patches", "patch list");
|
||||||
|
argList::validOptions.insert("binary", "" );
|
||||||
# include "addTimeOptions.H"
|
# include "addTimeOptions.H"
|
||||||
|
|
||||||
/*
|
|
||||||
const label nTypes = 3;
|
|
||||||
const word fieldTypes[] =
|
|
||||||
{
|
|
||||||
volScalarField::typeName,
|
|
||||||
volVectorField::typeName,
|
|
||||||
volTensorField::typeName
|
|
||||||
};
|
|
||||||
|
|
||||||
const label nSprayFieldTypes = 3;
|
|
||||||
const word sprayFieldTypes[] =
|
|
||||||
{
|
|
||||||
scalarIOField::typeName,
|
|
||||||
vectorIOField::typeName,
|
|
||||||
tensorIOField::typeName
|
|
||||||
};
|
|
||||||
*/
|
|
||||||
|
|
||||||
const label nTypes = 2;
|
const label nTypes = 2;
|
||||||
const word fieldTypes[] =
|
const word fieldTypes[] =
|
||||||
{
|
{
|
||||||
@ -116,18 +99,38 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
OFstream *ensightCaseFilePtr = NULL;
|
OFstream *ensightCaseFilePtr = NULL;
|
||||||
|
|
||||||
|
// Check options
|
||||||
|
bool binary = false;
|
||||||
|
if (args.options().found("binary"))
|
||||||
|
{
|
||||||
|
binary = true;
|
||||||
|
}
|
||||||
|
|
||||||
if (Pstream::master())
|
if (Pstream::master())
|
||||||
{
|
{
|
||||||
// Open the Case file
|
// Open the Case file
|
||||||
fileName ensightCaseFileName = prepend + "case";
|
fileName ensightCaseFileName = prepend + "case";
|
||||||
|
|
||||||
ensightCaseFilePtr = new OFstream
|
if (!binary)
|
||||||
(
|
{
|
||||||
postProcPath/ensightCaseFileName,
|
ensightCaseFilePtr = new OFstream
|
||||||
runTime.writeFormat(),
|
(
|
||||||
runTime.writeVersion(),
|
postProcPath/ensightCaseFileName,
|
||||||
runTime.writeCompression()
|
runTime.writeFormat(),
|
||||||
);
|
runTime.writeVersion(),
|
||||||
|
runTime.writeCompression()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ensightCaseFilePtr = new OFstream
|
||||||
|
(
|
||||||
|
postProcPath/ensightCaseFileName,
|
||||||
|
runTime.writeFormat(),
|
||||||
|
runTime.writeVersion(),
|
||||||
|
IOstream::UNCOMPRESSED
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
Info<< nl << "Case file is " << ensightCaseFileName << endl;
|
Info<< nl << "Case file is " << ensightCaseFileName << endl;
|
||||||
}
|
}
|
||||||
@ -135,7 +138,7 @@ int main(int argc, char *argv[])
|
|||||||
OFstream& ensightCaseFile = *ensightCaseFilePtr;
|
OFstream& ensightCaseFile = *ensightCaseFilePtr;
|
||||||
|
|
||||||
// Construct the EnSight mesh
|
// Construct the EnSight mesh
|
||||||
ensightMesh eMesh(mesh, args);
|
ensightMesh eMesh(mesh, args, binary);
|
||||||
|
|
||||||
// Set Time to the last time before looking for the spray objects
|
// Set Time to the last time before looking for the spray objects
|
||||||
runTime.setTime(Times[Times.size()-1], Times.size()-1);
|
runTime.setTime(Times[Times.size()-1], Times.size()-1);
|
||||||
@ -250,6 +253,7 @@ int main(int argc, char *argv[])
|
|||||||
postProcPath,
|
postProcPath,
|
||||||
prepend,
|
prepend,
|
||||||
timeIndex,
|
timeIndex,
|
||||||
|
binary,
|
||||||
ensightCaseFile
|
ensightCaseFile
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -262,6 +266,7 @@ int main(int argc, char *argv[])
|
|||||||
postProcPath,
|
postProcPath,
|
||||||
prepend,
|
prepend,
|
||||||
timeIndex,
|
timeIndex,
|
||||||
|
binary,
|
||||||
ensightCaseFile
|
ensightCaseFile
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -274,6 +279,7 @@ int main(int argc, char *argv[])
|
|||||||
postProcPath,
|
postProcPath,
|
||||||
prepend,
|
prepend,
|
||||||
timeIndex,
|
timeIndex,
|
||||||
|
binary,
|
||||||
ensightCaseFile
|
ensightCaseFile
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -286,6 +292,7 @@ int main(int argc, char *argv[])
|
|||||||
postProcPath,
|
postProcPath,
|
||||||
prepend,
|
prepend,
|
||||||
timeIndex,
|
timeIndex,
|
||||||
|
binary,
|
||||||
ensightCaseFile
|
ensightCaseFile
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -298,6 +305,7 @@ int main(int argc, char *argv[])
|
|||||||
postProcPath,
|
postProcPath,
|
||||||
prepend,
|
prepend,
|
||||||
timeIndex,
|
timeIndex,
|
||||||
|
binary,
|
||||||
ensightCaseFile
|
ensightCaseFile
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -22,8 +22,6 @@ License
|
|||||||
along with OpenFOAM; if not, write to the Free Software Foundation,
|
along with OpenFOAM; if not, write to the Free Software Foundation,
|
||||||
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
|
||||||
Description
|
|
||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
#include "itoa.H"
|
#include "itoa.H"
|
||||||
|
|||||||
@ -22,6 +22,9 @@ License
|
|||||||
along with OpenFOAM; if not, write to the Free Software Foundation,
|
along with OpenFOAM; if not, write to the Free Software Foundation,
|
||||||
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
|
||||||
|
InApplication
|
||||||
|
foamToEnsight
|
||||||
|
|
||||||
Description
|
Description
|
||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|||||||
@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
IOobject ioPoints
|
IOobject ioPoints
|
||||||
(
|
(
|
||||||
"points",
|
"points",
|
||||||
runTime.timeName(),
|
runTime.timeName(),
|
||||||
polyMesh::meshSubDir,
|
polyMesh::meshSubDir,
|
||||||
mesh
|
mesh
|
||||||
);
|
);
|
||||||
|
|
||||||
if (ioPoints.headerOk())
|
if (ioPoints.headerOk())
|
||||||
{
|
{
|
||||||
// Reading new points
|
// Reading new points
|
||||||
@ -22,7 +22,7 @@
|
|||||||
IOobject::NO_WRITE
|
IOobject::NO_WRITE
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
mesh.movePoints(newPoints);
|
mesh.movePoints(newPoints);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,17 +0,0 @@
|
|||||||
EXE_INC = \
|
|
||||||
-I$(LIB_SRC)/finiteVolume/lnInclude \
|
|
||||||
-I$(LIB_SRC)/lagrangian/basic/lnInclude \
|
|
||||||
-I$(LIB_SRC)/meshTools/lnInclude \
|
|
||||||
-I$(ParaView_DIR) \
|
|
||||||
-I$(ParaView_DIR)/VTK \
|
|
||||||
-I$(ParaView_INST_DIR)/VTK \
|
|
||||||
-I$(ParaView_INST_DIR)/VTK/Common \
|
|
||||||
-I$(ParaView_INST_DIR)/VTK/Filtering \
|
|
||||||
-I$(ParaView_INST_DIR)/VTK/Rendering \
|
|
||||||
-I../PV3FoamReader
|
|
||||||
|
|
||||||
LIB_LIBS = \
|
|
||||||
-lfiniteVolume \
|
|
||||||
-llagrangian \
|
|
||||||
-lmeshTools \
|
|
||||||
$(GLIBS)
|
|
||||||
@ -63,7 +63,7 @@
|
|||||||
|
|
||||||
<!-- Include sets check box -->
|
<!-- Include sets check box -->
|
||||||
<IntVectorProperty
|
<IntVectorProperty
|
||||||
name="IncludeSets / Zones"
|
name="IncludeSets"
|
||||||
command="SetIncludeSets"
|
command="SetIncludeSets"
|
||||||
number_of_elements="1"
|
number_of_elements="1"
|
||||||
default_values="0">
|
default_values="0">
|
||||||
|
|||||||
3
bin/tools/buildParaViewFunctions
Executable file → Normal file
3
bin/tools/buildParaViewFunctions
Executable file → Normal file
@ -258,4 +258,5 @@ unset VERBOSE INCLUDE_MPI INCLUDE_PYTHON INCLUDE_MESA PYTHON_LIBRARY
|
|||||||
unset CMAKE_VARIABLES OBJ_ADD
|
unset CMAKE_VARIABLES OBJ_ADD
|
||||||
unset CMAKE_SKIP
|
unset CMAKE_SKIP
|
||||||
|
|
||||||
#------------------------------------------------------------------------------
|
|
||||||
|
# ----------------------------------------------------------------- end-of-file
|
||||||
|
|||||||
@ -13,6 +13,11 @@ my %config = (
|
|||||||
);
|
);
|
||||||
|
|
||||||
my %packages = (
|
my %packages = (
|
||||||
|
cmake => {
|
||||||
|
-opt => 1,
|
||||||
|
url => "http://www.cmake.org/files/v2.6/cmake-2.6.0.tar.gz",
|
||||||
|
},
|
||||||
|
|
||||||
lam => {
|
lam => {
|
||||||
-opt => 1,
|
-opt => 1,
|
||||||
url => "http://www.lam-mpi.org/download/files/lam-7.1.4.tar.bz2",
|
url => "http://www.lam-mpi.org/download/files/lam-7.1.4.tar.bz2",
|
||||||
93
wmake/wmakeScheduler.old → bin/tools/thirdPartyGetFunctions
Executable file → Normal file
93
wmake/wmakeScheduler.old → bin/tools/thirdPartyGetFunctions
Executable file → Normal file
@ -1,11 +1,11 @@
|
|||||||
#!/bin/bash
|
#!/bin/sh
|
||||||
#------------------------------------------------------------------------------
|
#------------------------------------------------------------------------------
|
||||||
# ========= |
|
# ========= |
|
||||||
# \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
# \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
# \\ / O peration |
|
# \\ / O peration |
|
||||||
# \\ / A nd | Copyright (C) 1991-2007 OpenCFD Ltd.
|
# \\ / A nd | Copyright (C) 1991-2007 OpenCFD Ltd.
|
||||||
# \\/ M anipulation |
|
# \\/ M anipulation |
|
||||||
#-------------------------------------------------------------------------------
|
#------------------------------------------------------------------------------
|
||||||
# License
|
# License
|
||||||
# This file is part of OpenFOAM.
|
# This file is part of OpenFOAM.
|
||||||
#
|
#
|
||||||
@ -24,47 +24,56 @@
|
|||||||
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
#
|
#
|
||||||
# Script
|
# Script
|
||||||
# wmakeScheduler
|
# thirdPartyGetFunctions
|
||||||
#
|
#
|
||||||
# Description
|
# Description
|
||||||
# Scheduler for network distributed compilations using wmake
|
# Functions for managing the third-party packages
|
||||||
#
|
#
|
||||||
#-------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
lockDir=$HOME/.wmakeScheduler
|
|
||||||
|
|
||||||
eval "cores=$WM_HOSTS"
|
|
||||||
n=${#cores[@]}
|
|
||||||
|
|
||||||
while [ true ]
|
|
||||||
do
|
|
||||||
let "w = 15*$RANDOM"
|
|
||||||
usleep $w
|
|
||||||
for ((i=0; i<n; i++))
|
|
||||||
do
|
|
||||||
core=${cores[$i]}
|
|
||||||
host=${cores[$i]%:*}
|
|
||||||
#echo "** i:$i core:$core host:$host"
|
|
||||||
lock=$lockDir/$core
|
|
||||||
if [ ! -f $lock ]
|
|
||||||
then
|
|
||||||
touch $lock
|
|
||||||
#echo "** Using core $core"
|
|
||||||
if [ "$host" = "$HOST" ]
|
|
||||||
then
|
|
||||||
$*
|
|
||||||
else
|
|
||||||
cmd=`echo $* | sed s/\"/\'\"\'/g`
|
|
||||||
#echo "ssh $host \"cd $PWD; $cmd\""
|
|
||||||
ssh $host "cd $PWD; $cmd"
|
|
||||||
fi
|
|
||||||
retval=$?
|
|
||||||
#echo "** Releasing core $core"
|
|
||||||
rm -f $lock
|
|
||||||
exit $retval
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
done
|
|
||||||
|
|
||||||
|
|
||||||
#------------------------------------------------------------------------------
|
#------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#
|
||||||
|
# get, unpack and change to third party directory
|
||||||
|
# - call from within a sub-shell, since it uses 'cd'
|
||||||
|
#
|
||||||
|
getUnpack() {
|
||||||
|
[ "$#" -eq 1 ] || {
|
||||||
|
echo "getUnpack called with incorrect arguments $@"
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
d=$(foamThirdParty -dir $1 2>/dev/null) || {
|
||||||
|
echo "nothing know about '$1'"
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
foamThirdParty -get -unpack $1 && [ -d "$d" ] || return 1
|
||||||
|
|
||||||
|
[ -d "$d" ] && chmod -R ugo+rX $d 2>/dev/null
|
||||||
|
|
||||||
|
echo $d
|
||||||
|
}
|
||||||
|
|
||||||
|
#
|
||||||
|
# copy Make/{files,options} from wmakeFiles/PACKAGE
|
||||||
|
#
|
||||||
|
cpMakeFiles() {
|
||||||
|
[ "$#" -eq 2 ] || {
|
||||||
|
echo "cpMakeFiles called with incorrect arguments $@"
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
pkg=$1
|
||||||
|
dst=$2
|
||||||
|
|
||||||
|
for i in $(cd wmakeFiles/$pkg && find . -type f)
|
||||||
|
do
|
||||||
|
d=$(dirname $i)
|
||||||
|
b=$(basename $i)
|
||||||
|
|
||||||
|
mkdir -p $dst/$d/Make 2>/dev/null
|
||||||
|
[ -e $dst/$d/Make/$b ] || cp wmakeFiles/$pkg/$i $dst/$d/Make/$b
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# ----------------------------------------------------------------- end-of-file
|
||||||
@ -37,7 +37,7 @@ if [ "$PS1" -a "$foamDotFile" ]; then
|
|||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
export CMAKE_HOME=$WM_PROJECT_INST_DIR/ThirdParty/cmake-2.4.6/platforms/$WM_ARCH
|
export CMAKE_HOME=$WM_THIRD_PARTY_DIR/cmake-2.4.6/platforms/$WM_ARCH
|
||||||
|
|
||||||
if [ -r $CMAKE_HOME ]; then
|
if [ -r $CMAKE_HOME ]; then
|
||||||
export PATH=$CMAKE_HOME/bin:$PATH
|
export PATH=$CMAKE_HOME/bin:$PATH
|
||||||
@ -45,7 +45,7 @@ fi
|
|||||||
|
|
||||||
export ParaView_VERSION=2.4.4
|
export ParaView_VERSION=2.4.4
|
||||||
|
|
||||||
export ParaView_INST_DIR=$WM_PROJECT_INST_DIR/ThirdParty/ParaView$ParaView_VERSION
|
export ParaView_INST_DIR=$WM_THIRD_PARTY_DIR/ParaView$ParaView_VERSION
|
||||||
export ParaView_DIR=$ParaView_INST_DIR/lib/paraview-2.4
|
export ParaView_DIR=$ParaView_INST_DIR/lib/paraview-2.4
|
||||||
|
|
||||||
if [ -r $ParaView_INST_DIR ]; then
|
if [ -r $ParaView_INST_DIR ]; then
|
||||||
|
|||||||
@ -37,7 +37,7 @@ if ($?prompt && $?foamDotFile) then
|
|||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
setenv CMAKE_HOME $WM_PROJECT_INST_DIR/ThirdParty/cmake-2.4.6/platforms/$WM_ARCH
|
setenv CMAKE_HOME $WM_THIRD_PARTY_DIR/cmake-2.4.6/platforms/$WM_ARCH
|
||||||
|
|
||||||
if ( -r $CMAKE_HOME ) then
|
if ( -r $CMAKE_HOME ) then
|
||||||
set path=($CMAKE_HOME/bin $path)
|
set path=($CMAKE_HOME/bin $path)
|
||||||
@ -45,7 +45,7 @@ endif
|
|||||||
|
|
||||||
setenv ParaView_VERSION 2.4.4
|
setenv ParaView_VERSION 2.4.4
|
||||||
|
|
||||||
setenv ParaView_INST_DIR $WM_PROJECT_INST_DIR/ThirdParty/ParaView$ParaView_VERSION
|
setenv ParaView_INST_DIR $WM_THIRD_PARTY_DIR/ParaView$ParaView_VERSION
|
||||||
setenv ParaView_DIR $ParaView_INST_DIR/lib/paraview-2.4
|
setenv ParaView_DIR $ParaView_INST_DIR/lib/paraview-2.4
|
||||||
|
|
||||||
if ( -r $ParaView_INST_DIR ) then
|
if ( -r $ParaView_INST_DIR ) then
|
||||||
|
|||||||
@ -37,7 +37,7 @@ if [ "$PS1" -a "$foamDotFile" ]; then
|
|||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
export CMAKE_HOME=$WM_PROJECT_INST_DIR/ThirdParty/cmake-2.4.6/platforms/$WM_ARCH
|
export CMAKE_HOME=$WM_THIRD_PARTY_DIR/cmake-2.4.6/platforms/$WM_ARCH
|
||||||
|
|
||||||
if [ -r $CMAKE_HOME ]; then
|
if [ -r $CMAKE_HOME ]; then
|
||||||
export PATH=$CMAKE_HOME/bin:$PATH
|
export PATH=$CMAKE_HOME/bin:$PATH
|
||||||
@ -47,7 +47,7 @@ fi
|
|||||||
|
|
||||||
export ParaView_VERSION="3.3-cvs"
|
export ParaView_VERSION="3.3-cvs"
|
||||||
|
|
||||||
export ParaView_INST_DIR=$WM_PROJECT_INST_DIR/ThirdParty/ParaView$ParaView_VERSION
|
export ParaView_INST_DIR=$WM_THIRD_PARTY_DIR/ParaView$ParaView_VERSION
|
||||||
export ParaView_DIR=$ParaView_INST_DIR/platforms/$WM_ARCH$WM_COMPILER
|
export ParaView_DIR=$ParaView_INST_DIR/platforms/$WM_ARCH$WM_COMPILER
|
||||||
|
|
||||||
if [ "$PYTHONPATH" ]; then
|
if [ "$PYTHONPATH" ]; then
|
||||||
|
|||||||
@ -37,7 +37,7 @@ if ($?prompt && $?foamDotFile) then
|
|||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
setenv CMAKE_HOME $WM_PROJECT_INST_DIR/ThirdParty/cmake-2.4.6/platforms/$WM_ARCH
|
setenv CMAKE_HOME $WM_THIRD_PARTY_DIR/cmake-2.4.6/platforms/$WM_ARCH
|
||||||
|
|
||||||
if ( -r $CMAKE_HOME ) then
|
if ( -r $CMAKE_HOME ) then
|
||||||
set path=($CMAKE_HOME/bin $path)
|
set path=($CMAKE_HOME/bin $path)
|
||||||
@ -47,7 +47,7 @@ endif
|
|||||||
|
|
||||||
setenv ParaView_VERSION 3.3-cvs
|
setenv ParaView_VERSION 3.3-cvs
|
||||||
|
|
||||||
setenv ParaView_INST_DIR $WM_PROJECT_INST_DIR/ThirdParty/ParaView$ParaView_VERSION
|
setenv ParaView_INST_DIR $WM_THIRD_PARTY_DIR/ParaView$ParaView_VERSION
|
||||||
setenv ParaView_DIR $ParaView_INST_DIR/platforms/$WM_ARCH$WM_COMPILER
|
setenv ParaView_DIR $ParaView_INST_DIR/platforms/$WM_ARCH$WM_COMPILER
|
||||||
|
|
||||||
if ($?PYTHONPATH) then
|
if ($?PYTHONPATH) then
|
||||||
|
|||||||
@ -57,6 +57,11 @@ export WM_PROJECT_DIR=$FOAM_INST_DIR/$WM_PROJECT-$WM_PROJECT_VERSION
|
|||||||
export WM_PROJECT_USER_DIR=$HOME/$WM_PROJECT/$USER-$WM_PROJECT_VERSION
|
export WM_PROJECT_USER_DIR=$HOME/$WM_PROJECT/$USER-$WM_PROJECT_VERSION
|
||||||
|
|
||||||
|
|
||||||
|
# Location of third-party software
|
||||||
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
export WM_THIRD_PARTY_DIR=$WM_PROJECT_INST_DIR/ThirdParty
|
||||||
|
|
||||||
|
|
||||||
# Operating System/Platform from Unix or MSWindows
|
# Operating System/Platform from Unix or MSWindows
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
# WM_OS = Unix | MSWindows
|
# WM_OS = Unix | MSWindows
|
||||||
|
|||||||
@ -55,6 +55,11 @@ setenv WM_PROJECT_DIR $FOAM_INST_DIR/$WM_PROJECT-$WM_PROJECT_VERSION
|
|||||||
setenv WM_PROJECT_USER_DIR $HOME/$WM_PROJECT/$LOGNAME-$WM_PROJECT_VERSION
|
setenv WM_PROJECT_USER_DIR $HOME/$WM_PROJECT/$LOGNAME-$WM_PROJECT_VERSION
|
||||||
|
|
||||||
|
|
||||||
|
# Location of third-party software
|
||||||
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
setenv WM_THIRD_PARTY_DIR $WM_PROJECT_INST_DIR/ThirdParty
|
||||||
|
|
||||||
|
|
||||||
# Compiler: set to Gcc, Gcc43 or Icc (for Intel's icc)
|
# Compiler: set to Gcc, Gcc43 or Icc (for Intel's icc)
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
if ( ! $?WM_COMPILER ) setenv WM_COMPILER Gcc
|
if ( ! $?WM_COMPILER ) setenv WM_COMPILER Gcc
|
||||||
|
|||||||
@ -74,11 +74,6 @@ AddPath $FOAM_USER_APPBIN
|
|||||||
setenv FOAM_RUN $WM_PROJECT_USER_DIR/run
|
setenv FOAM_RUN $WM_PROJECT_USER_DIR/run
|
||||||
|
|
||||||
|
|
||||||
# Location of third-party software
|
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
set thirdParty=$WM_PROJECT_INST_DIR/ThirdParty
|
|
||||||
|
|
||||||
|
|
||||||
# Compiler settings
|
# Compiler settings
|
||||||
# ~~~~~~~~~~~~~~~~~
|
# ~~~~~~~~~~~~~~~~~
|
||||||
set WM_COMPILER_BIN=
|
set WM_COMPILER_BIN=
|
||||||
@ -94,10 +89,10 @@ switch ("$WM_COMPILER_INST")
|
|||||||
case OpenFOAM:
|
case OpenFOAM:
|
||||||
switch ("$WM_COMPILER")
|
switch ("$WM_COMPILER")
|
||||||
case Gcc43:
|
case Gcc43:
|
||||||
setenv WM_COMPILER_DIR $thirdParty/gcc-4.3.0/platforms/$WM_ARCH$WM_COMPILER_ARCH
|
setenv WM_COMPILER_DIR $WM_THIRD_PARTY_DIR/gcc-4.3.0/platforms/$WM_ARCH$WM_COMPILER_ARCH
|
||||||
breaksw
|
breaksw
|
||||||
case Gcc:
|
case Gcc:
|
||||||
setenv WM_COMPILER_DIR $thirdParty/gcc-4.2.2/platforms/$WM_ARCH$WM_COMPILER_ARCH
|
setenv WM_COMPILER_DIR $WM_THIRD_PARTY_DIR/gcc-4.2.2/platforms/$WM_ARCH$WM_COMPILER_ARCH
|
||||||
breaksw
|
breaksw
|
||||||
endsw
|
endsw
|
||||||
|
|
||||||
@ -135,7 +130,8 @@ unset MPI_ARCH_PATH
|
|||||||
switch ("$WM_MPLIB")
|
switch ("$WM_MPLIB")
|
||||||
case OPENMPI:
|
case OPENMPI:
|
||||||
set mpi_version=openmpi-1.2.6
|
set mpi_version=openmpi-1.2.6
|
||||||
setenv MPI_ARCH_PATH $thirdParty/$mpi_version/platforms/$WM_OPTIONS
|
setenv MPI_HOME $WM_THIRD_PARTY_DIR/$mpi_version
|
||||||
|
setenv MPI_ARCH_PATH $MPI_HOME/platforms/$WM_OPTIONS
|
||||||
|
|
||||||
# Tell OpenMPI where to find its install directory
|
# Tell OpenMPI where to find its install directory
|
||||||
setenv OPAL_PREFIX $MPI_ARCH_PATH
|
setenv OPAL_PREFIX $MPI_ARCH_PATH
|
||||||
@ -149,8 +145,9 @@ case OPENMPI:
|
|||||||
|
|
||||||
case LAM:
|
case LAM:
|
||||||
set mpi_version=lam-7.1.4
|
set mpi_version=lam-7.1.4
|
||||||
setenv MPI_ARCH_PATH $thirdParty/$mpi_version/platforms/$WM_OPTIONS
|
setenv MPI_HOME $WM_THIRD_PARTY_DIR/$mpi_version
|
||||||
setenv LAMHOME $thirdParty/$mpi_version
|
setenv MPI_ARCH_PATH $MPI_HOME/platforms/$WM_OPTIONS
|
||||||
|
setenv LAMHOME $WM_THIRD_PARTY_DIR/$mpi_version
|
||||||
# note: LAMHOME is deprecated, should probably point to MPI_ARCH_PATH too
|
# note: LAMHOME is deprecated, should probably point to MPI_ARCH_PATH too
|
||||||
|
|
||||||
AddLib $MPI_ARCH_PATH/lib
|
AddLib $MPI_ARCH_PATH/lib
|
||||||
@ -162,7 +159,8 @@ case LAM:
|
|||||||
|
|
||||||
case MPICH:
|
case MPICH:
|
||||||
set mpi_version=mpich-1.2.4
|
set mpi_version=mpich-1.2.4
|
||||||
setenv MPI_ARCH_PATH $thirdParty/$mpi_version/platforms/$WM_OPTIONS
|
setenv MPI_HOME $WM_THIRD_PARTY_DIR/$mpi_version
|
||||||
|
setenv MPI_ARCH_PATH $MPI_HOME/platforms/$WM_OPTIONS
|
||||||
setenv MPICH_ROOT $MPI_ARCH_PATH
|
setenv MPICH_ROOT $MPI_ARCH_PATH
|
||||||
|
|
||||||
AddLib $MPI_ARCH_PATH/lib
|
AddLib $MPI_ARCH_PATH/lib
|
||||||
|
|||||||
@ -91,10 +91,6 @@ AddPath $FOAM_USER_APPBIN
|
|||||||
export FOAM_RUN=$WM_PROJECT_USER_DIR/run
|
export FOAM_RUN=$WM_PROJECT_USER_DIR/run
|
||||||
|
|
||||||
|
|
||||||
# Location of third-party software
|
|
||||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
thirdParty=$WM_PROJECT_INST_DIR/ThirdParty
|
|
||||||
|
|
||||||
# Compiler settings
|
# Compiler settings
|
||||||
# ~~~~~~~~~~~~~~~~~
|
# ~~~~~~~~~~~~~~~~~
|
||||||
WM_COMPILER_BIN=
|
WM_COMPILER_BIN=
|
||||||
@ -109,10 +105,10 @@ case "$WM_COMPILER_INST" in
|
|||||||
OpenFOAM)
|
OpenFOAM)
|
||||||
case "$WM_COMPILER" in
|
case "$WM_COMPILER" in
|
||||||
Gcc43)
|
Gcc43)
|
||||||
export WM_COMPILER_DIR=$thirdParty/gcc-4.3.0/platforms/$WM_ARCH$WM_COMPILER_ARCH
|
export WM_COMPILER_DIR=$WM_THIRD_PARTY_DIR/gcc-4.3.0/platforms/$WM_ARCH$WM_COMPILER_ARCH
|
||||||
;;
|
;;
|
||||||
Gcc)
|
Gcc)
|
||||||
export WM_COMPILER_DIR=$thirdParty/gcc-4.2.2/platforms/$WM_ARCH$WM_COMPILER_ARCH
|
export WM_COMPILER_DIR=$WM_THIRD_PARTY_DIR/gcc-4.2.2/platforms/$WM_ARCH$WM_COMPILER_ARCH
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
@ -146,7 +142,8 @@ unset MPI_ARCH_PATH
|
|||||||
case "$WM_MPLIB" in
|
case "$WM_MPLIB" in
|
||||||
OPENMPI)
|
OPENMPI)
|
||||||
mpi_version=openmpi-1.2.6
|
mpi_version=openmpi-1.2.6
|
||||||
export MPI_ARCH_PATH=$thirdParty/$mpi_version/platforms/$WM_OPTIONS
|
export MPI_HOME=$WM_THIRD_PARTY_DIR/$mpi_version
|
||||||
|
export MPI_ARCH_PATH=$MPI_HOME/platforms/$WM_OPTIONS
|
||||||
|
|
||||||
# Tell OpenMPI where to find its install directory
|
# Tell OpenMPI where to find its install directory
|
||||||
export OPAL_PREFIX=$MPI_ARCH_PATH
|
export OPAL_PREFIX=$MPI_ARCH_PATH
|
||||||
@ -160,8 +157,9 @@ OPENMPI)
|
|||||||
|
|
||||||
LAM)
|
LAM)
|
||||||
mpi_version=lam-7.1.4
|
mpi_version=lam-7.1.4
|
||||||
export MPI_ARCH_PATH=$thirdParty/$mpi_version/platforms/$WM_OPTIONS
|
export MPI_HOME=$WM_THIRD_PARTY_DIR/$mpi_version
|
||||||
export LAMHOME=$thirdParty/$mpi_version
|
export MPI_ARCH_PATH=$MPI_HOME/platforms/$WM_OPTIONS
|
||||||
|
export LAMHOME=$WM_THIRD_PARTY_DIR/$mpi_version
|
||||||
# note: LAMHOME is deprecated, should probably point to MPI_ARCH_PATH too
|
# note: LAMHOME is deprecated, should probably point to MPI_ARCH_PATH too
|
||||||
|
|
||||||
AddLib $MPI_ARCH_PATH/lib
|
AddLib $MPI_ARCH_PATH/lib
|
||||||
@ -173,7 +171,8 @@ LAM)
|
|||||||
|
|
||||||
MPICH)
|
MPICH)
|
||||||
mpi_version=mpich-1.2.4
|
mpi_version=mpich-1.2.4
|
||||||
export MPI_ARCH_PATH=$thirdParty/$mpi_version/platforms/$WM_OPTIONS
|
export MPI_HOME=$WM_THIRD_PARTY_DIR/$mpi_version
|
||||||
|
export MPI_ARCH_PATH=$MPI_HOME/platforms/$WM_OPTIONS
|
||||||
export MPICH_ROOT=$MPI_ARCH_PATH
|
export MPICH_ROOT=$MPI_ARCH_PATH
|
||||||
|
|
||||||
AddLib $MPI_ARCH_PATH/lib
|
AddLib $MPI_ARCH_PATH/lib
|
||||||
|
|||||||
@ -256,11 +256,6 @@ $(pairGAMGAgglomeration)/pairGAMGAgglomerationCombineLevels.C
|
|||||||
algebraicPairGAMGAgglomeration = $(GAMGAgglomerations)/algebraicPairGAMGAgglomeration
|
algebraicPairGAMGAgglomeration = $(GAMGAgglomerations)/algebraicPairGAMGAgglomeration
|
||||||
$(algebraicPairGAMGAgglomeration)/algebraicPairGAMGAgglomeration.C
|
$(algebraicPairGAMGAgglomeration)/algebraicPairGAMGAgglomeration.C
|
||||||
|
|
||||||
matrices/LduMatrix/LduMatrix/lduMatrices.C
|
|
||||||
matrices/LduMatrix/Preconditioners/lduPreconditioners.C
|
|
||||||
matrices/LduMatrix/Smoothers/lduSmoothers.C
|
|
||||||
matrices/LduMatrix/Solvers/lduSolvers.C
|
|
||||||
|
|
||||||
meshes/lduMesh/lduMesh.C
|
meshes/lduMesh/lduMesh.C
|
||||||
|
|
||||||
primitiveShapes = meshes/primitiveShapes
|
primitiveShapes = meshes/primitiveShapes
|
||||||
|
|||||||
@ -1,66 +0,0 @@
|
|||||||
/*---------------------------------------------------------------------------*\
|
|
||||||
========= |
|
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
|
||||||
\\ / O peration |
|
|
||||||
\\ / A nd | Copyright (C) 1991-2007 OpenCFD Ltd.
|
|
||||||
\\/ M anipulation |
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
License
|
|
||||||
This file is part of OpenFOAM.
|
|
||||||
|
|
||||||
OpenFOAM is free software; you can redistribute it and/or modify it
|
|
||||||
under the terms of the GNU General Public License as published by the
|
|
||||||
Free Software Foundation; either version 2 of the License, or (at your
|
|
||||||
option) any later version.
|
|
||||||
|
|
||||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
|
||||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
||||||
for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with OpenFOAM; if not, write to the Free Software Foundation,
|
|
||||||
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
#include "CyclicLduInterfaceField.H"
|
|
||||||
#include "diagTensorField.H"
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
namespace Foam
|
|
||||||
{
|
|
||||||
//defineTypeNameAndDebug(CyclicLduInterfaceField, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
template<class Type>
|
|
||||||
Foam::CyclicLduInterfaceField<Type>::~CyclicLduInterfaceField()
|
|
||||||
{}
|
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
template<class Type>
|
|
||||||
void Foam::CyclicLduInterfaceField<Type>::transformCoupleField
|
|
||||||
(
|
|
||||||
Field<Type>& f
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
if (doTransform())
|
|
||||||
{
|
|
||||||
label sizeby2 = f.size()/2;
|
|
||||||
|
|
||||||
for (label facei=0; facei<sizeby2; facei++)
|
|
||||||
{
|
|
||||||
f[facei] = transform(f[facei], forwardT()[0]);
|
|
||||||
f[facei + sizeby2] = transform(f[facei + sizeby2], forwardT()[0]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
|
||||||
@ -1,103 +0,0 @@
|
|||||||
/*---------------------------------------------------------------------------*\
|
|
||||||
========= |
|
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
|
||||||
\\ / O peration |
|
|
||||||
\\ / A nd | Copyright (C) 1991-2007 OpenCFD Ltd.
|
|
||||||
\\/ M anipulation |
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
License
|
|
||||||
This file is part of OpenFOAM.
|
|
||||||
|
|
||||||
OpenFOAM is free software; you can redistribute it and/or modify it
|
|
||||||
under the terms of the GNU General Public License as published by the
|
|
||||||
Free Software Foundation; either version 2 of the License, or (at your
|
|
||||||
option) any later version.
|
|
||||||
|
|
||||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
|
||||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
||||||
for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with OpenFOAM; if not, write to the Free Software Foundation,
|
|
||||||
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
|
|
||||||
Class
|
|
||||||
Foam::CyclicLduInterfaceField
|
|
||||||
|
|
||||||
Description
|
|
||||||
Abstract base class for cyclic coupled interfaces.
|
|
||||||
|
|
||||||
SourceFiles
|
|
||||||
CyclicLduInterfaceField.C
|
|
||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
#ifndef CyclicLduInterfaceField_H
|
|
||||||
#define CyclicLduInterfaceField_H
|
|
||||||
|
|
||||||
#include "primitiveFieldsFwd.H"
|
|
||||||
#include "typeInfo.H"
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
namespace Foam
|
|
||||||
{
|
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*\
|
|
||||||
Class CyclicLduInterfaceField Declaration
|
|
||||||
\*---------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
template<class Type>
|
|
||||||
class CyclicLduInterfaceField
|
|
||||||
{
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
//- Runtime type information
|
|
||||||
TypeName("CyclicLduInterfaceField");
|
|
||||||
|
|
||||||
|
|
||||||
// Constructors
|
|
||||||
|
|
||||||
//- Construct given coupled patch
|
|
||||||
CyclicLduInterfaceField()
|
|
||||||
{}
|
|
||||||
|
|
||||||
|
|
||||||
// Destructor
|
|
||||||
|
|
||||||
virtual ~CyclicLduInterfaceField();
|
|
||||||
|
|
||||||
|
|
||||||
// Member Functions
|
|
||||||
|
|
||||||
// Access
|
|
||||||
|
|
||||||
//- Is the transform required
|
|
||||||
virtual bool doTransform() const = 0;
|
|
||||||
|
|
||||||
//- Return face transformation tensor
|
|
||||||
virtual const tensorField& forwardT() const = 0;
|
|
||||||
|
|
||||||
//- Return neighbour-cell transformation tensor
|
|
||||||
virtual const tensorField& reverseT() const = 0;
|
|
||||||
|
|
||||||
//- Return rank of component for transform
|
|
||||||
virtual int rank() const = 0;
|
|
||||||
|
|
||||||
|
|
||||||
//- Transform given patch internal field
|
|
||||||
void transformCoupleField(Field<Type>& f) const;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
} // End namespace Foam
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
|
||||||
@ -1,147 +0,0 @@
|
|||||||
/*---------------------------------------------------------------------------*\
|
|
||||||
========= |
|
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
|
||||||
\\ / O peration |
|
|
||||||
\\ / A nd | Copyright (C) 1991-2007 OpenCFD Ltd.
|
|
||||||
\\/ M anipulation |
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
License
|
|
||||||
This file is part of OpenFOAM.
|
|
||||||
|
|
||||||
OpenFOAM is free software; you can redistribute it and/or modify it
|
|
||||||
under the terms of the GNU General Public License as published by the
|
|
||||||
Free Software Foundation; either version 2 of the License, or (at your
|
|
||||||
option) any later version.
|
|
||||||
|
|
||||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
|
||||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
||||||
for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with OpenFOAM; if not, write to the Free Software Foundation,
|
|
||||||
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
|
|
||||||
Class
|
|
||||||
Foam::LduInterfaceField
|
|
||||||
|
|
||||||
Description
|
|
||||||
An abstract base class for implicitly-coupled interface fields
|
|
||||||
e.g. processor and cyclic patch fields.
|
|
||||||
|
|
||||||
SourceFiles
|
|
||||||
LduInterfaceField.C
|
|
||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
#ifndef LduInterfaceField_H
|
|
||||||
#define LduInterfaceField_H
|
|
||||||
|
|
||||||
#include "lduInterface.H"
|
|
||||||
#include "Field.H"
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
namespace Foam
|
|
||||||
{
|
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*\
|
|
||||||
Class LduInterfaceField Declaration
|
|
||||||
\*---------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
template<class Type>
|
|
||||||
class LduInterfaceField
|
|
||||||
{
|
|
||||||
// Private data
|
|
||||||
|
|
||||||
//- Reference to the coupled patch this field is defined for
|
|
||||||
const lduInterface& interface_;
|
|
||||||
|
|
||||||
|
|
||||||
// Private Member Functions
|
|
||||||
|
|
||||||
//- Disallow default bitwise copy construct
|
|
||||||
LduInterfaceField(const LduInterfaceField&);
|
|
||||||
|
|
||||||
//- Disallow default bitwise assignment
|
|
||||||
void operator=(const LduInterfaceField&);
|
|
||||||
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
class Amultiplier
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
|
|
||||||
Amultiplier()
|
|
||||||
{}
|
|
||||||
|
|
||||||
virtual void addAmul
|
|
||||||
(
|
|
||||||
Field<Type>& Apsi,
|
|
||||||
const Field<Type>& psi
|
|
||||||
) const = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
//- Runtime type information
|
|
||||||
TypeName("LduInterfaceField");
|
|
||||||
|
|
||||||
|
|
||||||
// Constructors
|
|
||||||
|
|
||||||
//- Construct given interface
|
|
||||||
LduInterfaceField(const lduInterface& interface)
|
|
||||||
:
|
|
||||||
interface_(interface)
|
|
||||||
{}
|
|
||||||
|
|
||||||
|
|
||||||
// Destructor
|
|
||||||
|
|
||||||
virtual ~LduInterfaceField();
|
|
||||||
|
|
||||||
|
|
||||||
// Member Functions
|
|
||||||
|
|
||||||
// Access
|
|
||||||
|
|
||||||
//- Return the interface
|
|
||||||
const lduInterface& interface() const
|
|
||||||
{
|
|
||||||
return interface_;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Coupled interface matrix update
|
|
||||||
|
|
||||||
//- Initialise neighbour matrix update
|
|
||||||
virtual void initInterfaceMatrixUpdate
|
|
||||||
(
|
|
||||||
Field<Type>& Apsi,
|
|
||||||
const Field<Type>& psi,
|
|
||||||
const Amultiplier&,
|
|
||||||
const Pstream::commsTypes commsType
|
|
||||||
) const
|
|
||||||
{}
|
|
||||||
|
|
||||||
//- Update result field based on interface functionality
|
|
||||||
virtual void updateInterfaceMatrix
|
|
||||||
(
|
|
||||||
Field<Type>& Apsi,
|
|
||||||
const Field<Type>& psi,
|
|
||||||
const Amultiplier&,
|
|
||||||
const Pstream::commsTypes commsType
|
|
||||||
) const = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
} // End namespace Foam
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
|
||||||
@ -1,71 +0,0 @@
|
|||||||
/*---------------------------------------------------------------------------*\
|
|
||||||
========= |
|
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
|
||||||
\\ / O peration |
|
|
||||||
\\ / A nd | Copyright (C) 1991-2007 OpenCFD Ltd.
|
|
||||||
\\/ M anipulation |
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
License
|
|
||||||
This file is part of OpenFOAM.
|
|
||||||
|
|
||||||
OpenFOAM is free software; you can redistribute it and/or modify it
|
|
||||||
under the terms of the GNU General Public License as published by the
|
|
||||||
Free Software Foundation; either version 2 of the License, or (at your
|
|
||||||
option) any later version.
|
|
||||||
|
|
||||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
|
||||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
||||||
for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with OpenFOAM; if not, write to the Free Software Foundation,
|
|
||||||
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
|
|
||||||
Type
|
|
||||||
lduInterfaceFieldPtrsList
|
|
||||||
|
|
||||||
Description
|
|
||||||
List of coupled interface fields to be used in coupling.
|
|
||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
#ifndef LduInterfaceFieldPtrsList_H
|
|
||||||
#define LduInterfaceFieldPtrsList_H
|
|
||||||
|
|
||||||
#include "LduInterfaceField.H"
|
|
||||||
#include "UPtrList.H"
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
namespace Foam
|
|
||||||
{
|
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*\
|
|
||||||
Class LduInterfaceFieldPtrsList Declaration
|
|
||||||
\*---------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
template<class Type>
|
|
||||||
class LduInterfaceFieldPtrsList
|
|
||||||
:
|
|
||||||
public UPtrList<const LduInterfaceField<Type> >
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
|
|
||||||
LduInterfaceFieldPtrsList(label size)
|
|
||||||
:
|
|
||||||
UPtrList<const LduInterfaceField<Type> >(size)
|
|
||||||
{}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
} // End namespace Foam
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
|
||||||
|
|
||||||
@ -1,106 +0,0 @@
|
|||||||
/*---------------------------------------------------------------------------*\
|
|
||||||
========= |
|
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
|
||||||
\\ / O peration |
|
|
||||||
\\ / A nd | Copyright (C) 1991-2007 OpenCFD Ltd.
|
|
||||||
\\/ M anipulation |
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
License
|
|
||||||
This file is part of OpenFOAM.
|
|
||||||
|
|
||||||
OpenFOAM is free software; you can redistribute it and/or modify it
|
|
||||||
under the terms of the GNU General Public License as published by the
|
|
||||||
Free Software Foundation; either version 2 of the License, or (at your
|
|
||||||
option) any later version.
|
|
||||||
|
|
||||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
|
||||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
||||||
for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with OpenFOAM; if not, write to the Free Software Foundation,
|
|
||||||
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
|
|
||||||
Class
|
|
||||||
Foam::ProcessorLduInterfaceField
|
|
||||||
|
|
||||||
Description
|
|
||||||
Abstract base class for processor coupled interfaces.
|
|
||||||
|
|
||||||
SourceFiles
|
|
||||||
ProcessorLduInterfaceField.C
|
|
||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
#ifndef ProcessorLduInterfaceField_H
|
|
||||||
#define ProcessorLduInterfaceField_H
|
|
||||||
|
|
||||||
#include "primitiveFieldsFwd.H"
|
|
||||||
#include "typeInfo.H"
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
namespace Foam
|
|
||||||
{
|
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*\
|
|
||||||
Class ProcessorLduInterfaceField Declaration
|
|
||||||
\*---------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
template<class Type>
|
|
||||||
class ProcessorLduInterfaceField
|
|
||||||
{
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
//- Runtime type information
|
|
||||||
TypeName("ProcessorLduInterfaceField");
|
|
||||||
|
|
||||||
|
|
||||||
// Constructors
|
|
||||||
|
|
||||||
//- Construct given coupled patch
|
|
||||||
ProcessorLduInterfaceField()
|
|
||||||
{}
|
|
||||||
|
|
||||||
|
|
||||||
// Destructor
|
|
||||||
|
|
||||||
virtual ~ProcessorLduInterfaceField();
|
|
||||||
|
|
||||||
|
|
||||||
// Member Functions
|
|
||||||
|
|
||||||
// Access
|
|
||||||
|
|
||||||
//- Return processor number
|
|
||||||
virtual int myProcNo() const = 0;
|
|
||||||
|
|
||||||
//- Return neigbour processor number
|
|
||||||
virtual int neighbProcNo() const = 0;
|
|
||||||
|
|
||||||
//- Is the transform required
|
|
||||||
virtual bool doTransform() const = 0;
|
|
||||||
|
|
||||||
//- Return face transformation tensor
|
|
||||||
virtual const tensorField& forwardT() const = 0;
|
|
||||||
|
|
||||||
//- Return rank of component for transform
|
|
||||||
virtual int rank() const = 0;
|
|
||||||
|
|
||||||
|
|
||||||
//- Transform given patch component field
|
|
||||||
void transformCoupleField(Field<Type>& f) const;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
} // End namespace Foam
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
|
||||||
@ -1,391 +0,0 @@
|
|||||||
/*---------------------------------------------------------------------------*\
|
|
||||||
========= |
|
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
|
||||||
\\ / O peration |
|
|
||||||
\\ / A nd | Copyright (C) 1991-2007 OpenCFD Ltd.
|
|
||||||
\\/ M anipulation |
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
License
|
|
||||||
This file is part of OpenFOAM.
|
|
||||||
|
|
||||||
OpenFOAM is free software; you can redistribute it and/or modify it
|
|
||||||
under the terms of the GNU General Public License as published by the
|
|
||||||
Free Software Foundation; either version 2 of the License, or (at your
|
|
||||||
option) any later version.
|
|
||||||
|
|
||||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
|
||||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
||||||
for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with OpenFOAM; if not, write to the Free Software Foundation,
|
|
||||||
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
#include "lduMatrix.H"
|
|
||||||
#include "IOstreams.H"
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
template<class Type, class DType, class LUType>
|
|
||||||
Foam::LduMatrix<Type, DType, LUType>::LduMatrix(const lduMesh& mesh)
|
|
||||||
:
|
|
||||||
lduMesh_(mesh),
|
|
||||||
diagPtr_(NULL),
|
|
||||||
upperPtr_(NULL),
|
|
||||||
lowerPtr_(NULL),
|
|
||||||
sourcePtr_(NULL),
|
|
||||||
interfaces_(0),
|
|
||||||
interfacesUpper_(0),
|
|
||||||
interfacesLower_(0)
|
|
||||||
{}
|
|
||||||
|
|
||||||
|
|
||||||
template<class Type, class DType, class LUType>
|
|
||||||
Foam::LduMatrix<Type, DType, LUType>::LduMatrix(const LduMatrix& A)
|
|
||||||
:
|
|
||||||
lduMesh_(A.lduMesh_),
|
|
||||||
diagPtr_(NULL),
|
|
||||||
upperPtr_(NULL),
|
|
||||||
lowerPtr_(NULL),
|
|
||||||
sourcePtr_(NULL),
|
|
||||||
interfaces_(0),
|
|
||||||
interfacesUpper_(0),
|
|
||||||
interfacesLower_(0)
|
|
||||||
{
|
|
||||||
if (A.diagPtr_)
|
|
||||||
{
|
|
||||||
diagPtr_ = new Field<DType>(*(A.diagPtr_));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (A.upperPtr_)
|
|
||||||
{
|
|
||||||
upperPtr_ = new Field<LUType>(*(A.upperPtr_));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (A.lowerPtr_)
|
|
||||||
{
|
|
||||||
lowerPtr_ = new Field<LUType>(*(A.lowerPtr_));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (A.sourcePtr_)
|
|
||||||
{
|
|
||||||
sourcePtr_ = new Field<Type>(*(A.sourcePtr_));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template<class Type, class DType, class LUType>
|
|
||||||
Foam::LduMatrix<Type, DType, LUType>::LduMatrix(LduMatrix& A, bool reUse)
|
|
||||||
:
|
|
||||||
lduMesh_(A.lduMesh_),
|
|
||||||
diagPtr_(NULL),
|
|
||||||
upperPtr_(NULL),
|
|
||||||
lowerPtr_(NULL),
|
|
||||||
sourcePtr_(NULL),
|
|
||||||
interfaces_(0),
|
|
||||||
interfacesUpper_(0),
|
|
||||||
interfacesLower_(0)
|
|
||||||
{
|
|
||||||
if (reUse)
|
|
||||||
{
|
|
||||||
if (A.diagPtr_)
|
|
||||||
{
|
|
||||||
diagPtr_ = A.diagPtr_;
|
|
||||||
A.diagPtr_ = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (A.upperPtr_)
|
|
||||||
{
|
|
||||||
upperPtr_ = A.upperPtr_;
|
|
||||||
A.upperPtr_ = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (A.lowerPtr_)
|
|
||||||
{
|
|
||||||
lowerPtr_ = A.lowerPtr_;
|
|
||||||
A.lowerPtr_ = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (A.sourcePtr_)
|
|
||||||
{
|
|
||||||
sourcePtr_ = A.sourcePtr_;
|
|
||||||
A.sourcePtr_ = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (A.diagPtr_)
|
|
||||||
{
|
|
||||||
diagPtr_ = new Field<DType>(*(A.diagPtr_));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (A.upperPtr_)
|
|
||||||
{
|
|
||||||
upperPtr_ = new Field<LUType>(*(A.upperPtr_));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (A.lowerPtr_)
|
|
||||||
{
|
|
||||||
lowerPtr_ = new Field<LUType>(*(A.lowerPtr_));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (A.sourcePtr_)
|
|
||||||
{
|
|
||||||
sourcePtr_ = new Field<Type>(*(A.sourcePtr_));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template<class Type, class DType, class LUType>
|
|
||||||
Foam::LduMatrix<Type, DType, LUType>::LduMatrix
|
|
||||||
(
|
|
||||||
const lduMesh& mesh,
|
|
||||||
Istream& is
|
|
||||||
)
|
|
||||||
:
|
|
||||||
lduMesh_(mesh),
|
|
||||||
diagPtr_(new Field<DType>(is)),
|
|
||||||
upperPtr_(new Field<LUType>(is)),
|
|
||||||
lowerPtr_(new Field<LUType>(is)),
|
|
||||||
sourcePtr_(new Field<Type>(is)),
|
|
||||||
interfaces_(0),
|
|
||||||
interfacesUpper_(0),
|
|
||||||
interfacesLower_(0)
|
|
||||||
{}
|
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
template<class Type, class DType, class LUType>
|
|
||||||
Foam::LduMatrix<Type, DType, LUType>::~LduMatrix()
|
|
||||||
{
|
|
||||||
if (diagPtr_)
|
|
||||||
{
|
|
||||||
delete diagPtr_;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (upperPtr_)
|
|
||||||
{
|
|
||||||
delete upperPtr_;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (lowerPtr_)
|
|
||||||
{
|
|
||||||
delete lowerPtr_;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sourcePtr_)
|
|
||||||
{
|
|
||||||
delete sourcePtr_;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
template<class Type, class DType, class LUType>
|
|
||||||
Foam::Field<DType>& Foam::LduMatrix<Type, DType, LUType>::diag()
|
|
||||||
{
|
|
||||||
if (!diagPtr_)
|
|
||||||
{
|
|
||||||
diagPtr_ = new Field<DType>(lduAddr().size(), pTraits<DType>::zero);
|
|
||||||
}
|
|
||||||
|
|
||||||
return *diagPtr_;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template<class Type, class DType, class LUType>
|
|
||||||
Foam::Field<LUType>& Foam::LduMatrix<Type, DType, LUType>::upper()
|
|
||||||
{
|
|
||||||
if (!upperPtr_)
|
|
||||||
{
|
|
||||||
if (lowerPtr_)
|
|
||||||
{
|
|
||||||
upperPtr_ = new Field<LUType>(*lowerPtr_);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
upperPtr_ = new Field<LUType>
|
|
||||||
(
|
|
||||||
lduAddr().lowerAddr().size(),
|
|
||||||
pTraits<LUType>::zero
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return *upperPtr_;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template<class Type, class DType, class LUType>
|
|
||||||
Foam::Field<LUType>& Foam::LduMatrix<Type, DType, LUType>::lower()
|
|
||||||
{
|
|
||||||
if (!lowerPtr_)
|
|
||||||
{
|
|
||||||
if (upperPtr_)
|
|
||||||
{
|
|
||||||
lowerPtr_ = new Field<LUType>(*upperPtr_);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
lowerPtr_ = new Field<LUType>
|
|
||||||
(
|
|
||||||
lduAddr().lowerAddr().size(),
|
|
||||||
pTraits<LUType>::zero
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return *lowerPtr_;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template<class Type, class DType, class LUType>
|
|
||||||
Foam::Field<Type>& Foam::LduMatrix<Type, DType, LUType>::source()
|
|
||||||
{
|
|
||||||
if (!sourcePtr_)
|
|
||||||
{
|
|
||||||
sourcePtr_ = new Field<Type>(lduAddr().size(), pTraits<Type>::zero);
|
|
||||||
}
|
|
||||||
|
|
||||||
return *sourcePtr_;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template<class Type, class DType, class LUType>
|
|
||||||
const Foam::Field<DType>& Foam::LduMatrix<Type, DType, LUType>::diag() const
|
|
||||||
{
|
|
||||||
if (!diagPtr_)
|
|
||||||
{
|
|
||||||
FatalErrorIn
|
|
||||||
(
|
|
||||||
"const Field<DType>& LduMatrix<Type, DType, LUType>::diag() const"
|
|
||||||
) << "diagPtr_ unallocated"
|
|
||||||
<< abort(FatalError);
|
|
||||||
}
|
|
||||||
|
|
||||||
return *diagPtr_;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template<class Type, class DType, class LUType>
|
|
||||||
const Foam::Field<LUType>& Foam::LduMatrix<Type, DType, LUType>::upper() const
|
|
||||||
{
|
|
||||||
if (!lowerPtr_ && !upperPtr_)
|
|
||||||
{
|
|
||||||
FatalErrorIn
|
|
||||||
(
|
|
||||||
"const Field<LUType>& LduMatrix<Type, DType, LUType>::upper() const"
|
|
||||||
) << "lowerPtr_ or upperPtr_ unallocated"
|
|
||||||
<< abort(FatalError);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (upperPtr_)
|
|
||||||
{
|
|
||||||
return *upperPtr_;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return *lowerPtr_;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template<class Type, class DType, class LUType>
|
|
||||||
const Foam::Field<LUType>& Foam::LduMatrix<Type, DType, LUType>::lower() const
|
|
||||||
{
|
|
||||||
if (!lowerPtr_ && !upperPtr_)
|
|
||||||
{
|
|
||||||
FatalErrorIn
|
|
||||||
(
|
|
||||||
"const Field<LUType>& LduMatrix<Type, DType, LUType>::lower() const"
|
|
||||||
) << "lowerPtr_ or upperPtr_ unallocated"
|
|
||||||
<< abort(FatalError);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (lowerPtr_)
|
|
||||||
{
|
|
||||||
return *lowerPtr_;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return *upperPtr_;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template<class Type, class DType, class LUType>
|
|
||||||
const Foam::Field<Type>& Foam::LduMatrix<Type, DType, LUType>::source() const
|
|
||||||
{
|
|
||||||
if (!sourcePtr_)
|
|
||||||
{
|
|
||||||
FatalErrorIn
|
|
||||||
(
|
|
||||||
"const Field<Type>& LduMatrix<Type, DType, LUType>::source() const"
|
|
||||||
) << "sourcePtr_ unallocated"
|
|
||||||
<< abort(FatalError);
|
|
||||||
}
|
|
||||||
|
|
||||||
return *sourcePtr_;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * Friend Operators * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
template<class Type, class DType, class LUType>
|
|
||||||
Foam::Ostream& Foam::operator<<
|
|
||||||
(
|
|
||||||
Ostream& os,
|
|
||||||
const LduMatrix<Type, DType, LUType>& ldum
|
|
||||||
)
|
|
||||||
{
|
|
||||||
if (ldum.diagPtr_)
|
|
||||||
{
|
|
||||||
os << "Diagonal = "
|
|
||||||
<< *ldum.diagPtr_
|
|
||||||
<< endl << endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ldum.upperPtr_)
|
|
||||||
{
|
|
||||||
os << "Upper triangle = "
|
|
||||||
<< *ldum.upperPtr_
|
|
||||||
<< endl << endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ldum.lowerPtr_)
|
|
||||||
{
|
|
||||||
os << "Lower triangle = "
|
|
||||||
<< *ldum.lowerPtr_
|
|
||||||
<< endl << endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ldum.sourcePtr_)
|
|
||||||
{
|
|
||||||
os << "Source = "
|
|
||||||
<< *ldum.sourcePtr_
|
|
||||||
<< endl << endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
os.check("Ostream& operator<<(Ostream&, const LduMatrix&");
|
|
||||||
|
|
||||||
return os;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
#include "LduMatrixOperations.C"
|
|
||||||
#include "LduMatrixATmul.C"
|
|
||||||
#include "LduMatrixUpdateMatrixInterfaces.C"
|
|
||||||
#include "LduMatrixTests.C"
|
|
||||||
#include "LduMatrixPreconditioner.C"
|
|
||||||
#include "LduMatrixSmoother.C"
|
|
||||||
#include "LduMatrixSolver.C"
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
|
||||||
@ -1,935 +0,0 @@
|
|||||||
/*---------------------------------------------------------------------------*\
|
|
||||||
========= |
|
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
|
||||||
\\ / O peration |
|
|
||||||
\\ / A nd | Copyright (C) 1991-2007 OpenCFD Ltd.
|
|
||||||
\\/ M anipulation |
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
License
|
|
||||||
This file is part of OpenFOAM.
|
|
||||||
|
|
||||||
OpenFOAM is free software; you can redistribute it and/or modify it
|
|
||||||
under the terms of the GNU General Public License as published by the
|
|
||||||
Free Software Foundation; either version 2 of the License, or (at your
|
|
||||||
option) any later version.
|
|
||||||
|
|
||||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
|
||||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
||||||
for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with OpenFOAM; if not, write to the Free Software Foundation,
|
|
||||||
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
|
|
||||||
Class
|
|
||||||
Foam::LduMatrix
|
|
||||||
|
|
||||||
Description
|
|
||||||
LduMatrix is a general matrix class in which the coefficients are
|
|
||||||
stored as three arrays, one for the upper triangle, one for the
|
|
||||||
lower triangle and a third for the diagonal.
|
|
||||||
|
|
||||||
Addressing arrays must be supplied for the upper and lower triangles.
|
|
||||||
|
|
||||||
Note
|
|
||||||
It might be better if this class were organised as a hierachy starting
|
|
||||||
from an empty matrix, then deriving diagonal, symmetric and asymmetric
|
|
||||||
matrices.
|
|
||||||
|
|
||||||
SourceFiles
|
|
||||||
LduMatrixATmul.C
|
|
||||||
LduMatrix.C
|
|
||||||
LduMatrixOperations.C
|
|
||||||
LduMatrixSolver.C
|
|
||||||
LduMatrixPreconditioner.C
|
|
||||||
LduMatrixTests.C
|
|
||||||
LduMatrixUpdateMatrixInterfaces.C
|
|
||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
#ifndef LduMatrix_H
|
|
||||||
#define LduMatrix_H
|
|
||||||
|
|
||||||
#include "lduMesh.H"
|
|
||||||
#include "Field.H"
|
|
||||||
#include "FieldField.H"
|
|
||||||
#include "LduInterfaceFieldPtrsList.H"
|
|
||||||
#include "typeInfo.H"
|
|
||||||
#include "autoPtr.H"
|
|
||||||
#include "runTimeSelectionTables.H"
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
namespace Foam
|
|
||||||
{
|
|
||||||
|
|
||||||
// Forward declaration of friend functions and operators
|
|
||||||
|
|
||||||
template<class Type, class DType, class LUType>
|
|
||||||
class LduMatrix;
|
|
||||||
|
|
||||||
template<class Type, class DType, class LUType>
|
|
||||||
Ostream& operator<<
|
|
||||||
(
|
|
||||||
Ostream&,
|
|
||||||
const LduMatrix<Type, DType, LUType>&
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*\
|
|
||||||
Class LduMatrix Declaration
|
|
||||||
\*---------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
template<class Type, class DType, class LUType>
|
|
||||||
class LduMatrix
|
|
||||||
{
|
|
||||||
// private data
|
|
||||||
|
|
||||||
//- LDU mesh reference
|
|
||||||
const lduMesh& lduMesh_;
|
|
||||||
|
|
||||||
//- Diagonal coefficients
|
|
||||||
Field<DType> *diagPtr_;
|
|
||||||
|
|
||||||
//- Off-diagonal coefficients
|
|
||||||
Field<LUType> *upperPtr_, *lowerPtr_;
|
|
||||||
|
|
||||||
//- Source
|
|
||||||
Field<Type> *sourcePtr_;
|
|
||||||
|
|
||||||
//- Field interfaces (processor patches etc.)
|
|
||||||
LduInterfaceFieldPtrsList<Type> interfaces_;
|
|
||||||
|
|
||||||
//- Off-diagonal coefficients for interfaces
|
|
||||||
FieldField<Field, LUType> interfacesUpper_, interfacesLower_;
|
|
||||||
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
//- Class returned by the solver
|
|
||||||
// containing performance statistics
|
|
||||||
class solverPerformance
|
|
||||||
{
|
|
||||||
word solverName_;
|
|
||||||
word fieldName_;
|
|
||||||
Type initialResidual_;
|
|
||||||
Type finalResidual_;
|
|
||||||
label noIterations_;
|
|
||||||
bool converged_;
|
|
||||||
FixedList<bool, pTraits<Type>::nComponents> singular_;
|
|
||||||
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
// Constructors
|
|
||||||
|
|
||||||
solverPerformance()
|
|
||||||
:
|
|
||||||
initialResidual_(pTraits<Type>::zero),
|
|
||||||
finalResidual_(pTraits<Type>::zero),
|
|
||||||
noIterations_(0),
|
|
||||||
converged_(false),
|
|
||||||
singular_(false)
|
|
||||||
{}
|
|
||||||
|
|
||||||
|
|
||||||
solverPerformance
|
|
||||||
(
|
|
||||||
const word& solverName,
|
|
||||||
const word& fieldName,
|
|
||||||
const Type& iRes = pTraits<Type>::zero,
|
|
||||||
const Type& fRes = pTraits<Type>::zero,
|
|
||||||
const label nIter = 0,
|
|
||||||
const bool converged = false,
|
|
||||||
const bool singular = false
|
|
||||||
)
|
|
||||||
:
|
|
||||||
solverName_(solverName),
|
|
||||||
fieldName_(fieldName),
|
|
||||||
initialResidual_(iRes),
|
|
||||||
finalResidual_(fRes),
|
|
||||||
noIterations_(nIter),
|
|
||||||
converged_(converged),
|
|
||||||
singular_(singular)
|
|
||||||
{}
|
|
||||||
|
|
||||||
|
|
||||||
// Member functions
|
|
||||||
|
|
||||||
//- Return solver name
|
|
||||||
const word& solverName() const
|
|
||||||
{
|
|
||||||
return solverName_;
|
|
||||||
}
|
|
||||||
|
|
||||||
//- Return initial residual
|
|
||||||
const Type& initialResidual() const
|
|
||||||
{
|
|
||||||
return initialResidual_;
|
|
||||||
}
|
|
||||||
|
|
||||||
//- Return initial residual
|
|
||||||
Type& initialResidual()
|
|
||||||
{
|
|
||||||
return initialResidual_;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//- Return final residual
|
|
||||||
const Type& finalResidual() const
|
|
||||||
{
|
|
||||||
return finalResidual_;
|
|
||||||
}
|
|
||||||
|
|
||||||
//- Return final residual
|
|
||||||
Type& finalResidual()
|
|
||||||
{
|
|
||||||
return finalResidual_;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//- Return number of iterations
|
|
||||||
label nIterations() const
|
|
||||||
{
|
|
||||||
return noIterations_;
|
|
||||||
}
|
|
||||||
|
|
||||||
//- Return number of iterations
|
|
||||||
label& nIterations()
|
|
||||||
{
|
|
||||||
return noIterations_;
|
|
||||||
}
|
|
||||||
|
|
||||||
//- Check, store and return singularity
|
|
||||||
bool singular(const Type& wApA);
|
|
||||||
|
|
||||||
//- Is the matrix singular?
|
|
||||||
bool singular() const;
|
|
||||||
|
|
||||||
//- Check, store and return convergence
|
|
||||||
bool converged
|
|
||||||
(
|
|
||||||
const Type& tolerance,
|
|
||||||
const Type& relTolerance
|
|
||||||
);
|
|
||||||
|
|
||||||
//- Has the solver converged?
|
|
||||||
bool converged() const
|
|
||||||
{
|
|
||||||
return converged_;
|
|
||||||
}
|
|
||||||
|
|
||||||
//- Print summary of solver performance to the given stream
|
|
||||||
void print(Ostream& os) const;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
//- Abstract base-class for LduMatrix solvers
|
|
||||||
class solver
|
|
||||||
{
|
|
||||||
protected:
|
|
||||||
|
|
||||||
// Protected data
|
|
||||||
|
|
||||||
word fieldName_;
|
|
||||||
const LduMatrix<Type, DType, LUType>& matrix_;
|
|
||||||
|
|
||||||
//- dictionary of controls
|
|
||||||
dictionary controlDict_;
|
|
||||||
|
|
||||||
//- Maximum number of iterations in the solver
|
|
||||||
label maxIter_;
|
|
||||||
|
|
||||||
//- Final convergence tolerance
|
|
||||||
Type tolerance_;
|
|
||||||
|
|
||||||
//- Convergence tolerance relative to the initial
|
|
||||||
Type relTol_;
|
|
||||||
|
|
||||||
|
|
||||||
// Protected Member Functions
|
|
||||||
|
|
||||||
//- Read a control parameter from controlDict
|
|
||||||
template<class T>
|
|
||||||
inline void readControl
|
|
||||||
(
|
|
||||||
const dictionary& controlDict,
|
|
||||||
T& control,
|
|
||||||
const word& controlName
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
//- Read the control parameters from the controlDict_
|
|
||||||
virtual void readControls();
|
|
||||||
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
//- Runtime type information
|
|
||||||
virtual const word& type() const = 0;
|
|
||||||
|
|
||||||
|
|
||||||
// Declare run-time constructor selection tables
|
|
||||||
|
|
||||||
declareRunTimeSelectionTable
|
|
||||||
(
|
|
||||||
autoPtr,
|
|
||||||
solver,
|
|
||||||
symMatrix,
|
|
||||||
(
|
|
||||||
const word& fieldName,
|
|
||||||
const LduMatrix<Type, DType, LUType>& matrix,
|
|
||||||
const dictionary& solverDict
|
|
||||||
),
|
|
||||||
(
|
|
||||||
fieldName,
|
|
||||||
matrix,
|
|
||||||
solverDict
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
declareRunTimeSelectionTable
|
|
||||||
(
|
|
||||||
autoPtr,
|
|
||||||
solver,
|
|
||||||
asymMatrix,
|
|
||||||
(
|
|
||||||
const word& fieldName,
|
|
||||||
const LduMatrix<Type, DType, LUType>& matrix,
|
|
||||||
const dictionary& solverDict
|
|
||||||
),
|
|
||||||
(
|
|
||||||
fieldName,
|
|
||||||
matrix,
|
|
||||||
solverDict
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
// Constructors
|
|
||||||
|
|
||||||
solver
|
|
||||||
(
|
|
||||||
const word& fieldName,
|
|
||||||
const LduMatrix<Type, DType, LUType>& matrix,
|
|
||||||
const dictionary& solverDict
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
// Selectors
|
|
||||||
|
|
||||||
//- Return a new solver
|
|
||||||
static autoPtr<solver> New
|
|
||||||
(
|
|
||||||
const word& fieldName,
|
|
||||||
const LduMatrix<Type, DType, LUType>& matrix,
|
|
||||||
const dictionary& solverDict
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
// Destructor
|
|
||||||
|
|
||||||
virtual ~solver()
|
|
||||||
{}
|
|
||||||
|
|
||||||
|
|
||||||
// Member functions
|
|
||||||
|
|
||||||
// Access
|
|
||||||
|
|
||||||
const word& fieldName() const
|
|
||||||
{
|
|
||||||
return fieldName_;
|
|
||||||
}
|
|
||||||
|
|
||||||
const LduMatrix<Type, DType, LUType>& matrix() const
|
|
||||||
{
|
|
||||||
return matrix_;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//- Read and reset the solver parameters from the given dictionary
|
|
||||||
virtual void read(const dictionary& solverDict);
|
|
||||||
|
|
||||||
virtual solverPerformance solve
|
|
||||||
(
|
|
||||||
Field<Type>& psi
|
|
||||||
) const = 0;
|
|
||||||
|
|
||||||
//- Return the matrix norm used to normalise the residual for the
|
|
||||||
// stopping criterion
|
|
||||||
Type normFactor
|
|
||||||
(
|
|
||||||
const Field<Type>& psi,
|
|
||||||
const Field<Type>& Apsi,
|
|
||||||
Field<Type>& tmpField
|
|
||||||
) const;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
//- Abstract base-class for LduMatrix smoothers
|
|
||||||
class smoother
|
|
||||||
{
|
|
||||||
protected:
|
|
||||||
|
|
||||||
// Protected data
|
|
||||||
|
|
||||||
word fieldName_;
|
|
||||||
const LduMatrix<Type, DType, LUType>& matrix_;
|
|
||||||
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
//- Runtime type information
|
|
||||||
virtual const word& type() const = 0;
|
|
||||||
|
|
||||||
|
|
||||||
// Declare run-time constructor selection tables
|
|
||||||
|
|
||||||
declareRunTimeSelectionTable
|
|
||||||
(
|
|
||||||
autoPtr,
|
|
||||||
smoother,
|
|
||||||
symMatrix,
|
|
||||||
(
|
|
||||||
const word& fieldName,
|
|
||||||
const LduMatrix<Type, DType, LUType>& matrix
|
|
||||||
),
|
|
||||||
(
|
|
||||||
fieldName,
|
|
||||||
matrix
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
declareRunTimeSelectionTable
|
|
||||||
(
|
|
||||||
autoPtr,
|
|
||||||
smoother,
|
|
||||||
asymMatrix,
|
|
||||||
(
|
|
||||||
const word& fieldName,
|
|
||||||
const LduMatrix<Type, DType, LUType>& matrix
|
|
||||||
),
|
|
||||||
(
|
|
||||||
fieldName,
|
|
||||||
matrix
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
// Constructors
|
|
||||||
|
|
||||||
smoother
|
|
||||||
(
|
|
||||||
const word& fieldName,
|
|
||||||
const LduMatrix<Type, DType, LUType>& matrix
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
// Selectors
|
|
||||||
|
|
||||||
//- Return a new smoother
|
|
||||||
static autoPtr<smoother> New
|
|
||||||
(
|
|
||||||
const word& fieldName,
|
|
||||||
const LduMatrix<Type, DType, LUType>& matrix,
|
|
||||||
const dictionary& smootherDict
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
// Destructor
|
|
||||||
|
|
||||||
virtual ~smoother()
|
|
||||||
{}
|
|
||||||
|
|
||||||
|
|
||||||
// Member functions
|
|
||||||
|
|
||||||
// Access
|
|
||||||
|
|
||||||
const word& fieldName() const
|
|
||||||
{
|
|
||||||
return fieldName_;
|
|
||||||
}
|
|
||||||
|
|
||||||
const LduMatrix<Type, DType, LUType>& matrix() const
|
|
||||||
{
|
|
||||||
return matrix_;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//- Smooth the solution for a given number of sweeps
|
|
||||||
virtual void smooth
|
|
||||||
(
|
|
||||||
Field<Type>& psi,
|
|
||||||
const label nSweeps
|
|
||||||
) const = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
//- Abstract base-class for LduMatrix preconditioners
|
|
||||||
class preconditioner
|
|
||||||
{
|
|
||||||
protected:
|
|
||||||
|
|
||||||
// Protected data
|
|
||||||
|
|
||||||
//- Reference to the base-solver this preconditioner is used with
|
|
||||||
const solver& solver_;
|
|
||||||
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
//- Runtime type information
|
|
||||||
virtual const word& type() const = 0;
|
|
||||||
|
|
||||||
|
|
||||||
// Declare run-time constructor selection tables
|
|
||||||
|
|
||||||
declareRunTimeSelectionTable
|
|
||||||
(
|
|
||||||
autoPtr,
|
|
||||||
preconditioner,
|
|
||||||
symMatrix,
|
|
||||||
(
|
|
||||||
const solver& sol,
|
|
||||||
const dictionary& preconditionerDict
|
|
||||||
),
|
|
||||||
(sol, preconditionerDict)
|
|
||||||
);
|
|
||||||
|
|
||||||
declareRunTimeSelectionTable
|
|
||||||
(
|
|
||||||
autoPtr,
|
|
||||||
preconditioner,
|
|
||||||
asymMatrix,
|
|
||||||
(
|
|
||||||
const solver& sol,
|
|
||||||
const dictionary& preconditionerDict
|
|
||||||
),
|
|
||||||
(sol, preconditionerDict)
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
// Constructors
|
|
||||||
|
|
||||||
preconditioner
|
|
||||||
(
|
|
||||||
const solver& sol
|
|
||||||
)
|
|
||||||
:
|
|
||||||
solver_(sol)
|
|
||||||
{}
|
|
||||||
|
|
||||||
|
|
||||||
// Selectors
|
|
||||||
|
|
||||||
//- Return a new preconditioner
|
|
||||||
static autoPtr<preconditioner> New
|
|
||||||
(
|
|
||||||
const solver& sol,
|
|
||||||
const dictionary& preconditionerDict
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
// Destructor
|
|
||||||
|
|
||||||
virtual ~preconditioner()
|
|
||||||
{}
|
|
||||||
|
|
||||||
|
|
||||||
// Member functions
|
|
||||||
|
|
||||||
//- Read and reset the preconditioner parameters
|
|
||||||
// from the given dictionary
|
|
||||||
virtual void read(const dictionary& preconditionerDict)
|
|
||||||
{}
|
|
||||||
|
|
||||||
//- Return wA the preconditioned form of residual rA
|
|
||||||
virtual void precondition
|
|
||||||
(
|
|
||||||
Field<Type>& wA,
|
|
||||||
const Field<Type>& rA
|
|
||||||
) const = 0;
|
|
||||||
|
|
||||||
//- Return wT the transpose-matrix preconditioned form of
|
|
||||||
// residual rT.
|
|
||||||
// This is only required for preconditioning asymmetric matrices.
|
|
||||||
virtual void preconditionT
|
|
||||||
(
|
|
||||||
Field<Type>& wT,
|
|
||||||
const Field<Type>& rT
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
notImplemented
|
|
||||||
(
|
|
||||||
type() +"::preconditionT"
|
|
||||||
"(Field<Type>& wT, const Field<Type>& rT)"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
// Static data
|
|
||||||
|
|
||||||
// Declare name of the class and its debug switch
|
|
||||||
ClassName("LduMatrix");
|
|
||||||
|
|
||||||
//- Large Type for the use in solvers
|
|
||||||
static const scalar great_;
|
|
||||||
|
|
||||||
//- Small Type for the use in solvers
|
|
||||||
static const scalar small_;
|
|
||||||
|
|
||||||
//- Very small Type for the use in solvers
|
|
||||||
static const scalar vsmall_;
|
|
||||||
|
|
||||||
|
|
||||||
// Constructors
|
|
||||||
|
|
||||||
//- Construct given an LDU addressed mesh.
|
|
||||||
// The coefficients are initially empty for subsequent setting.
|
|
||||||
LduMatrix(const lduMesh&);
|
|
||||||
|
|
||||||
//- Construct as copy
|
|
||||||
LduMatrix(const LduMatrix<Type, DType, LUType>&);
|
|
||||||
|
|
||||||
//- Construct as copy or re-use as specified.
|
|
||||||
LduMatrix(LduMatrix<Type, DType, LUType>&, bool reUse);
|
|
||||||
|
|
||||||
//- Construct given an LDU addressed mesh and an Istream
|
|
||||||
// from which the coefficients are read
|
|
||||||
LduMatrix(const lduMesh&, Istream&);
|
|
||||||
|
|
||||||
|
|
||||||
// Destructor
|
|
||||||
|
|
||||||
~LduMatrix();
|
|
||||||
|
|
||||||
|
|
||||||
// Member functions
|
|
||||||
|
|
||||||
// Access to addressing
|
|
||||||
|
|
||||||
//- Return the LDU mesh from which the addressing is obtained
|
|
||||||
const lduMesh& mesh() const
|
|
||||||
{
|
|
||||||
return lduMesh_;
|
|
||||||
}
|
|
||||||
|
|
||||||
//- Return the LDU addressing
|
|
||||||
const lduAddressing& lduAddr() const
|
|
||||||
{
|
|
||||||
return lduMesh_.lduAddr();
|
|
||||||
}
|
|
||||||
|
|
||||||
//- Return the patch evaluation schedule
|
|
||||||
const lduSchedule& patchSchedule() const
|
|
||||||
{
|
|
||||||
return lduAddr().patchSchedule();
|
|
||||||
}
|
|
||||||
|
|
||||||
//- Return interfaces
|
|
||||||
const LduInterfaceFieldPtrsList<Type>& interfaces() const
|
|
||||||
{
|
|
||||||
return interfaces_;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Access to coefficients
|
|
||||||
|
|
||||||
Field<DType>& diag();
|
|
||||||
Field<LUType>& upper();
|
|
||||||
Field<LUType>& lower();
|
|
||||||
Field<Type>& source();
|
|
||||||
|
|
||||||
FieldField<Field, LUType>& interfacesUpper()
|
|
||||||
{
|
|
||||||
return interfacesUpper_;
|
|
||||||
}
|
|
||||||
|
|
||||||
FieldField<Field, LUType>& interfacesLower()
|
|
||||||
{
|
|
||||||
return interfacesLower_;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
const Field<DType>& diag() const;
|
|
||||||
const Field<LUType>& upper() const;
|
|
||||||
const Field<LUType>& lower() const;
|
|
||||||
const Field<Type>& source() const;
|
|
||||||
|
|
||||||
const FieldField<Field, LUType>& interfacesUpper() const
|
|
||||||
{
|
|
||||||
return interfacesUpper_;
|
|
||||||
}
|
|
||||||
|
|
||||||
const FieldField<Field, LUType>& interfacesLower() const
|
|
||||||
{
|
|
||||||
return interfacesLower_;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool hasDiag() const
|
|
||||||
{
|
|
||||||
return (diagPtr_);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool hasUpper() const
|
|
||||||
{
|
|
||||||
return (upperPtr_);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool hasLower() const
|
|
||||||
{
|
|
||||||
return (lowerPtr_);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool hasSource() const
|
|
||||||
{
|
|
||||||
return (sourcePtr_);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool diagonal() const
|
|
||||||
{
|
|
||||||
return (diagPtr_ && !lowerPtr_ && !upperPtr_);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool symmetric() const
|
|
||||||
{
|
|
||||||
return (diagPtr_ && (!lowerPtr_ && upperPtr_));
|
|
||||||
}
|
|
||||||
|
|
||||||
bool asymmetric() const
|
|
||||||
{
|
|
||||||
return (diagPtr_ && lowerPtr_ && upperPtr_);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// operations
|
|
||||||
|
|
||||||
void sumDiag();
|
|
||||||
void negSumDiag();
|
|
||||||
|
|
||||||
void sumMagOffDiag(Field<LUType>& sumOff) const;
|
|
||||||
|
|
||||||
//- Matrix multiplication
|
|
||||||
void Amul(Field<Type>&, const tmp<Field<Type> >&) const;
|
|
||||||
|
|
||||||
//- Matrix transpose multiplication
|
|
||||||
void Tmul(Field<Type>&, const tmp<Field<Type> >&) const;
|
|
||||||
|
|
||||||
|
|
||||||
//- Sum the coefficients on each row of the matrix
|
|
||||||
void sumA(Field<Type>&) const;
|
|
||||||
|
|
||||||
|
|
||||||
void residual(Field<Type>& rA, const Field<Type>& psi) const;
|
|
||||||
|
|
||||||
tmp<Field<Type> > residual(const Field<Type>& psi) const;
|
|
||||||
|
|
||||||
|
|
||||||
//- Initialise the update of interfaced interfaces
|
|
||||||
// for matrix operations
|
|
||||||
void initMatrixInterfaces
|
|
||||||
(
|
|
||||||
const FieldField<Field, LUType>& interfaceCoeffs,
|
|
||||||
const Field<Type>& psiif,
|
|
||||||
Field<Type>& result
|
|
||||||
) const;
|
|
||||||
|
|
||||||
//- Update interfaced interfaces for matrix operations
|
|
||||||
void updateMatrixInterfaces
|
|
||||||
(
|
|
||||||
const FieldField<Field, LUType>& interfaceCoeffs,
|
|
||||||
const Field<Type>& psiif,
|
|
||||||
Field<Type>& result
|
|
||||||
) const;
|
|
||||||
|
|
||||||
|
|
||||||
tmp<Field<Type> > H(const Field<Type>&) const;
|
|
||||||
tmp<Field<Type> > H(const tmp<Field<Type> >&) const;
|
|
||||||
|
|
||||||
tmp<Field<Type> > faceH(const Field<Type>&) const;
|
|
||||||
tmp<Field<Type> > faceH(const tmp<Field<Type> >&) const;
|
|
||||||
|
|
||||||
|
|
||||||
// Member operators
|
|
||||||
|
|
||||||
void operator=(const LduMatrix<Type, DType, LUType>&);
|
|
||||||
|
|
||||||
void negate();
|
|
||||||
|
|
||||||
void operator+=(const LduMatrix<Type, DType, LUType>&);
|
|
||||||
void operator-=(const LduMatrix<Type, DType, LUType>&);
|
|
||||||
|
|
||||||
void operator*=(const scalarField&);
|
|
||||||
void operator*=(scalar);
|
|
||||||
|
|
||||||
|
|
||||||
// Ostream operator
|
|
||||||
|
|
||||||
friend Ostream& operator<< <Type, DType, LUType>
|
|
||||||
(
|
|
||||||
Ostream&,
|
|
||||||
const LduMatrix<Type, DType, LUType>&
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
} // End namespace Foam
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
#define makeLduMatrix(Type, DType, LUType) \
|
|
||||||
\
|
|
||||||
typedef Foam::LduMatrix<Type, DType, LUType> \
|
|
||||||
ldu##Type##DType##LUType##Matrix; \
|
|
||||||
\
|
|
||||||
defineNamedTemplateTypeNameAndDebug(ldu##Type##DType##LUType##Matrix, 0); \
|
|
||||||
\
|
|
||||||
\
|
|
||||||
template<> \
|
|
||||||
const scalar ldu##Type##DType##LUType##Matrix::great_(1e15); \
|
|
||||||
\
|
|
||||||
template<> \
|
|
||||||
const scalar ldu##Type##DType##LUType##Matrix::small_(1e-15); \
|
|
||||||
\
|
|
||||||
template<> \
|
|
||||||
const scalar ldu##Type##DType##LUType##Matrix::vsmall_(VSMALL); \
|
|
||||||
\
|
|
||||||
\
|
|
||||||
typedef LduMatrix<Type, DType, LUType>::smoother \
|
|
||||||
ldu##Type##DType##LUType##Smoother; \
|
|
||||||
\
|
|
||||||
defineTemplateRunTimeSelectionTable \
|
|
||||||
( \
|
|
||||||
ldu##Type##DType##LUType##Smoother, \
|
|
||||||
symMatrix \
|
|
||||||
); \
|
|
||||||
\
|
|
||||||
defineTemplateRunTimeSelectionTable \
|
|
||||||
( \
|
|
||||||
ldu##Type##DType##LUType##Smoother, \
|
|
||||||
asymMatrix \
|
|
||||||
); \
|
|
||||||
\
|
|
||||||
\
|
|
||||||
typedef LduMatrix<Type, DType, LUType>::preconditioner \
|
|
||||||
ldu##Type##DType##LUType##Preconditioner; \
|
|
||||||
\
|
|
||||||
defineTemplateRunTimeSelectionTable \
|
|
||||||
( \
|
|
||||||
ldu##Type##DType##LUType##Preconditioner, \
|
|
||||||
symMatrix \
|
|
||||||
); \
|
|
||||||
\
|
|
||||||
defineTemplateRunTimeSelectionTable \
|
|
||||||
( \
|
|
||||||
ldu##Type##DType##LUType##Preconditioner, \
|
|
||||||
asymMatrix \
|
|
||||||
); \
|
|
||||||
\
|
|
||||||
\
|
|
||||||
typedef LduMatrix<Type, DType, LUType>::solver \
|
|
||||||
ldu##Type##DType##LUType##Solver; \
|
|
||||||
\
|
|
||||||
defineTemplateRunTimeSelectionTable \
|
|
||||||
( \
|
|
||||||
ldu##Type##DType##LUType##Solver, \
|
|
||||||
symMatrix \
|
|
||||||
); \
|
|
||||||
\
|
|
||||||
defineTemplateRunTimeSelectionTable \
|
|
||||||
( \
|
|
||||||
ldu##Type##DType##LUType##Solver, \
|
|
||||||
asymMatrix \
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
#define makeLduPreconditioner(Precon, Type, DType, LUType) \
|
|
||||||
\
|
|
||||||
typedef Precon<Type, DType, LUType> \
|
|
||||||
Precon##Type##DType##LUType##Preconditioner; \
|
|
||||||
defineNamedTemplateTypeNameAndDebug \
|
|
||||||
( \
|
|
||||||
Precon##Type##DType##LUType##Preconditioner, \
|
|
||||||
0 \
|
|
||||||
);
|
|
||||||
|
|
||||||
#define makeLduSymPreconditioner(Precon, Type, DType, LUType) \
|
|
||||||
\
|
|
||||||
LduMatrix<Type, DType, LUType>::preconditioner:: \
|
|
||||||
addsymMatrixConstructorToTable<Precon##Type##DType##LUType##Preconditioner> \
|
|
||||||
add##Precon##Type##DType##LUType##PreconditionerSymMatrixConstructorToTable_;
|
|
||||||
|
|
||||||
#define makeLduAsymPreconditioner(Precon, Type, DType, LUType) \
|
|
||||||
\
|
|
||||||
LduMatrix<Type, DType, LUType>::preconditioner:: \
|
|
||||||
addasymMatrixConstructorToTable<Precon##Type##DType##LUType##Preconditioner> \
|
|
||||||
add##Precon##Type##DType##LUType##PreconditionerAsymMatrixConstructorToTable_;
|
|
||||||
|
|
||||||
|
|
||||||
#define makeLduSmoother(Smoother, Type, DType, LUType) \
|
|
||||||
\
|
|
||||||
typedef Smoother<Type, DType, LUType> \
|
|
||||||
Smoother##Type##DType##LUType##Smoother; \
|
|
||||||
\
|
|
||||||
defineNamedTemplateTypeNameAndDebug \
|
|
||||||
( \
|
|
||||||
Smoother##Type##DType##LUType##Smoother, \
|
|
||||||
0 \
|
|
||||||
);
|
|
||||||
|
|
||||||
#define makeLduSymSmoother(Smoother, Type, DType, LUType) \
|
|
||||||
\
|
|
||||||
LduMatrix<Type, DType, LUType>::smoother:: \
|
|
||||||
addsymMatrixConstructorToTable<Smoother##Type##DType##LUType##Smoother> \
|
|
||||||
add##Smoother##Type##DType##LUType##SymMatrixConstructorToTable_;
|
|
||||||
|
|
||||||
#define makeLduAsymSmoother(Smoother, Type, DType, LUType) \
|
|
||||||
\
|
|
||||||
LduMatrix<Type, DType, LUType>::smoother:: \
|
|
||||||
addasymMatrixConstructorToTable<Smoother##Type##DType##LUType##Smoother> \
|
|
||||||
add##Smoother##Type##DType##LUType##AsymMatrixConstructorToTable_;
|
|
||||||
|
|
||||||
|
|
||||||
#define makeLduSolver(Solver, Type, DType, LUType) \
|
|
||||||
\
|
|
||||||
typedef Solver<Type, DType, LUType> \
|
|
||||||
Solver##Type##DType##LUType##Solver; \
|
|
||||||
\
|
|
||||||
defineNamedTemplateTypeNameAndDebug \
|
|
||||||
( \
|
|
||||||
Solver##Type##DType##LUType##Solver, \
|
|
||||||
0 \
|
|
||||||
);
|
|
||||||
|
|
||||||
#define makeLduSymSolver(Solver, Type, DType, LUType) \
|
|
||||||
\
|
|
||||||
LduMatrix<Type, DType, LUType>::solver:: \
|
|
||||||
addsymMatrixConstructorToTable<Solver##Type##DType##LUType##Solver> \
|
|
||||||
add##Solver##Type##DType##LUType##SymMatrixConstructorToTable_;
|
|
||||||
|
|
||||||
#define makeLduAsymSolver(Solver, Type, DType, LUType) \
|
|
||||||
\
|
|
||||||
LduMatrix<Type, DType, LUType>::solver:: \
|
|
||||||
addasymMatrixConstructorToTable<Solver##Type##DType##LUType##Solver> \
|
|
||||||
add##Solver##Type##DType##LUType##AsymMatrixConstructorToTable_;
|
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
#ifdef NoRepository
|
|
||||||
# include "LduMatrixI.H"
|
|
||||||
# include "LduMatrix.C"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
|
||||||
@ -1,291 +0,0 @@
|
|||||||
/*---------------------------------------------------------------------------*\
|
|
||||||
========= |
|
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
|
||||||
\\ / O peration |
|
|
||||||
\\ / A nd | Copyright (C) 1991-2007 OpenCFD Ltd.
|
|
||||||
\\/ M anipulation |
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
License
|
|
||||||
This file is part of OpenFOAM.
|
|
||||||
|
|
||||||
OpenFOAM is free software; you can redistribute it and/or modify it
|
|
||||||
under the terms of the GNU General Public License as published by the
|
|
||||||
Free Software Foundation; either version 2 of the License, or (at your
|
|
||||||
option) any later version.
|
|
||||||
|
|
||||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
|
||||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
||||||
for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with OpenFOAM; if not, write to the Free Software Foundation,
|
|
||||||
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
#include "LduMatrix.H"
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
namespace Foam
|
|
||||||
{
|
|
||||||
|
|
||||||
template<class Type, class LUType>
|
|
||||||
class Amultiplier
|
|
||||||
:
|
|
||||||
public LduInterfaceField<Type>::Amultiplier
|
|
||||||
{
|
|
||||||
const Field<LUType>& A_;
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
Amultiplier(const Field<LUType>& A)
|
|
||||||
:
|
|
||||||
A_(A)
|
|
||||||
{}
|
|
||||||
|
|
||||||
virtual void addAmul(Field<Type>& Apsi, const Field<Type>& psi) const
|
|
||||||
{
|
|
||||||
Apsi += A_*psi;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
template<class Type, class DType, class LUType>
|
|
||||||
void Foam::LduMatrix<Type, DType, LUType>::Amul
|
|
||||||
(
|
|
||||||
Field<Type>& Apsi,
|
|
||||||
const tmp<Field<Type> >& tpsi
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
Type* __restrict__ ApsiPtr = Apsi.begin();
|
|
||||||
|
|
||||||
const Field<Type>& psi = tpsi();
|
|
||||||
const Type* const __restrict__ psiPtr = psi.begin();
|
|
||||||
|
|
||||||
const DType* const __restrict__ diagPtr = diag().begin();
|
|
||||||
|
|
||||||
const label* const __restrict__ uPtr = lduAddr().upperAddr().begin();
|
|
||||||
const label* const __restrict__ lPtr = lduAddr().lowerAddr().begin();
|
|
||||||
|
|
||||||
const LUType* const __restrict__ upperPtr = upper().begin();
|
|
||||||
const LUType* const __restrict__ lowerPtr = lower().begin();
|
|
||||||
|
|
||||||
// Initialise the update of interfaced interfaces
|
|
||||||
initMatrixInterfaces
|
|
||||||
(
|
|
||||||
interfacesUpper_,
|
|
||||||
psi,
|
|
||||||
Apsi
|
|
||||||
);
|
|
||||||
|
|
||||||
register const label nCells = diag().size();
|
|
||||||
for (register label cell=0; cell<nCells; cell++)
|
|
||||||
{
|
|
||||||
ApsiPtr[cell] = dot(diagPtr[cell], psiPtr[cell]);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
register const label nFaces = upper().size();
|
|
||||||
for (register label face=0; face<nFaces; face++)
|
|
||||||
{
|
|
||||||
ApsiPtr[uPtr[face]] += dot(lowerPtr[face], psiPtr[lPtr[face]]);
|
|
||||||
ApsiPtr[lPtr[face]] += dot(upperPtr[face], psiPtr[uPtr[face]]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update interface interfaces
|
|
||||||
updateMatrixInterfaces
|
|
||||||
(
|
|
||||||
interfacesUpper_,
|
|
||||||
psi,
|
|
||||||
Apsi
|
|
||||||
);
|
|
||||||
|
|
||||||
tpsi.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template<class Type, class DType, class LUType>
|
|
||||||
void Foam::LduMatrix<Type, DType, LUType>::Tmul
|
|
||||||
(
|
|
||||||
Field<Type>& Tpsi,
|
|
||||||
const tmp<Field<Type> >& tpsi
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
Type* __restrict__ TpsiPtr = Tpsi.begin();
|
|
||||||
|
|
||||||
const Field<Type>& psi = tpsi();
|
|
||||||
const Type* const __restrict__ psiPtr = psi.begin();
|
|
||||||
|
|
||||||
const DType* const __restrict__ diagPtr = diag().begin();
|
|
||||||
|
|
||||||
const label* const __restrict__ uPtr = lduAddr().upperAddr().begin();
|
|
||||||
const label* const __restrict__ lPtr = lduAddr().lowerAddr().begin();
|
|
||||||
|
|
||||||
const LUType* const __restrict__ lowerPtr = lower().begin();
|
|
||||||
const LUType* const __restrict__ upperPtr = upper().begin();
|
|
||||||
|
|
||||||
// Initialise the update of interfaced interfaces
|
|
||||||
initMatrixInterfaces
|
|
||||||
(
|
|
||||||
interfacesLower_,
|
|
||||||
psi,
|
|
||||||
Tpsi
|
|
||||||
);
|
|
||||||
|
|
||||||
register const label nCells = diag().size();
|
|
||||||
for (register label cell=0; cell<nCells; cell++)
|
|
||||||
{
|
|
||||||
TpsiPtr[cell] = dot(diagPtr[cell], psiPtr[cell]);
|
|
||||||
}
|
|
||||||
|
|
||||||
register const label nFaces = upper().size();
|
|
||||||
for (register label face=0; face<nFaces; face++)
|
|
||||||
{
|
|
||||||
TpsiPtr[uPtr[face]] += dot(upperPtr[face], psiPtr[lPtr[face]]);
|
|
||||||
TpsiPtr[lPtr[face]] += dot(lowerPtr[face], psiPtr[uPtr[face]]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update interface interfaces
|
|
||||||
updateMatrixInterfaces
|
|
||||||
(
|
|
||||||
interfacesLower_,
|
|
||||||
psi,
|
|
||||||
Tpsi
|
|
||||||
);
|
|
||||||
|
|
||||||
tpsi.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template<class Type, class DType, class LUType>
|
|
||||||
void Foam::LduMatrix<Type, DType, LUType>::sumA
|
|
||||||
(
|
|
||||||
Field<Type>& sumA
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
Type* __restrict__ sumAPtr = sumA.begin();
|
|
||||||
|
|
||||||
const DType* __restrict__ diagPtr = diag().begin();
|
|
||||||
|
|
||||||
const label* __restrict__ uPtr = lduAddr().upperAddr().begin();
|
|
||||||
const label* __restrict__ lPtr = lduAddr().lowerAddr().begin();
|
|
||||||
|
|
||||||
const LUType* __restrict__ lowerPtr = lower().begin();
|
|
||||||
const LUType* __restrict__ upperPtr = upper().begin();
|
|
||||||
|
|
||||||
register const label nCells = diag().size();
|
|
||||||
register const label nFaces = upper().size();
|
|
||||||
|
|
||||||
for (register label cell=0; cell<nCells; cell++)
|
|
||||||
{
|
|
||||||
sumAPtr[cell] = dot(diagPtr[cell], pTraits<Type>::one);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (register label face=0; face<nFaces; face++)
|
|
||||||
{
|
|
||||||
sumAPtr[uPtr[face]] += dot(lowerPtr[face], pTraits<Type>::one);
|
|
||||||
sumAPtr[lPtr[face]] += dot(upperPtr[face], pTraits<Type>::one);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add the interface internal coefficients to diagonal
|
|
||||||
// and the interface boundary coefficients to the sum-off-diagonal
|
|
||||||
forAll(interfaces_, patchI)
|
|
||||||
{
|
|
||||||
if (interfaces_.set(patchI))
|
|
||||||
{
|
|
||||||
const unallocLabelList& pa = lduAddr().patchAddr(patchI);
|
|
||||||
const Field<LUType>& pCoeffs = interfacesUpper_[patchI];
|
|
||||||
|
|
||||||
forAll(pa, face)
|
|
||||||
{
|
|
||||||
sumAPtr[pa[face]] -= dot(pCoeffs[face], pTraits<Type>::one);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template<class Type, class DType, class LUType>
|
|
||||||
void Foam::LduMatrix<Type, DType, LUType>::residual
|
|
||||||
(
|
|
||||||
Field<Type>& rA,
|
|
||||||
const Field<Type>& psi
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
Type* __restrict__ rAPtr = rA.begin();
|
|
||||||
|
|
||||||
const Type* const __restrict__ psiPtr = psi.begin();
|
|
||||||
const DType* const __restrict__ diagPtr = diag().begin();
|
|
||||||
const Type* const __restrict__ sourcePtr = source().begin();
|
|
||||||
|
|
||||||
const label* const __restrict__ uPtr = lduAddr().upperAddr().begin();
|
|
||||||
const label* const __restrict__ lPtr = lduAddr().lowerAddr().begin();
|
|
||||||
|
|
||||||
const LUType* const __restrict__ upperPtr = upper().begin();
|
|
||||||
const LUType* const __restrict__ lowerPtr = lower().begin();
|
|
||||||
|
|
||||||
// Parallel boundary initialisation.
|
|
||||||
// Note: there is a change of sign in the coupled
|
|
||||||
// interface update to add the contibution to the r.h.s.
|
|
||||||
|
|
||||||
FieldField<Field, LUType> mBouCoeffs(interfacesUpper_.size());
|
|
||||||
|
|
||||||
forAll(mBouCoeffs, patchi)
|
|
||||||
{
|
|
||||||
if (interfaces_.set(patchi))
|
|
||||||
{
|
|
||||||
mBouCoeffs.set(patchi, -interfacesUpper_[patchi]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Initialise the update of interfaced interfaces
|
|
||||||
initMatrixInterfaces
|
|
||||||
(
|
|
||||||
mBouCoeffs,
|
|
||||||
psi,
|
|
||||||
rA
|
|
||||||
);
|
|
||||||
|
|
||||||
register const label nCells = diag().size();
|
|
||||||
for (register label cell=0; cell<nCells; cell++)
|
|
||||||
{
|
|
||||||
rAPtr[cell] = sourcePtr[cell] - dot(diagPtr[cell], psiPtr[cell]);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
register const label nFaces = upper().size();
|
|
||||||
for (register label face=0; face<nFaces; face++)
|
|
||||||
{
|
|
||||||
rAPtr[uPtr[face]] -= dot(lowerPtr[face], psiPtr[lPtr[face]]);
|
|
||||||
rAPtr[lPtr[face]] -= dot(upperPtr[face], psiPtr[uPtr[face]]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update interface interfaces
|
|
||||||
updateMatrixInterfaces
|
|
||||||
(
|
|
||||||
mBouCoeffs,
|
|
||||||
psi,
|
|
||||||
rA
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template<class Type, class DType, class LUType>
|
|
||||||
Foam::tmp<Foam::Field<Type> > Foam::LduMatrix<Type, DType, LUType>::residual
|
|
||||||
(
|
|
||||||
const Field<Type>& psi
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
tmp<Field<Type> > trA(new Field<Type>(psi.size()));
|
|
||||||
residual(trA(), psi);
|
|
||||||
return trA;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
|
||||||
@ -1,45 +0,0 @@
|
|||||||
/*---------------------------------------------------------------------------*\
|
|
||||||
========= |
|
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
|
||||||
\\ / O peration |
|
|
||||||
\\ / A nd | Copyright (C) 1991-2007 OpenCFD Ltd.
|
|
||||||
\\/ M anipulation |
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
License
|
|
||||||
This file is part of OpenFOAM.
|
|
||||||
|
|
||||||
OpenFOAM is free software; you can redistribute it and/or modify it
|
|
||||||
under the terms of the GNU General Public License as published by the
|
|
||||||
Free Software Foundation; either version 2 of the License, or (at your
|
|
||||||
option) any later version.
|
|
||||||
|
|
||||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
|
||||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
||||||
for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with OpenFOAM; if not, write to the Free Software Foundation,
|
|
||||||
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
template<class Type, class DType, class LUType>
|
|
||||||
template<class T>
|
|
||||||
inline void Foam::LduMatrix<Type, DType, LUType>::solver::readControl
|
|
||||||
(
|
|
||||||
const dictionary& controlDict,
|
|
||||||
T& control,
|
|
||||||
const word& controlName
|
|
||||||
)
|
|
||||||
{
|
|
||||||
if (controlDict.found(controlName))
|
|
||||||
{
|
|
||||||
controlDict.lookup(controlName) >> control;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
|
||||||
@ -1,481 +0,0 @@
|
|||||||
/*---------------------------------------------------------------------------*\
|
|
||||||
========= |
|
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
|
||||||
\\ / O peration |
|
|
||||||
\\ / A nd | Copyright (C) 1991-2007 OpenCFD Ltd.
|
|
||||||
\\/ M anipulation |
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
License
|
|
||||||
This file is part of OpenFOAM.
|
|
||||||
|
|
||||||
OpenFOAM is free software; you can redistribute it and/or modify it
|
|
||||||
under the terms of the GNU General Public License as published by the
|
|
||||||
Free Software Foundation; either version 2 of the License, or (at your
|
|
||||||
option) any later version.
|
|
||||||
|
|
||||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
|
||||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
||||||
for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with OpenFOAM; if not, write to the Free Software Foundation,
|
|
||||||
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
#include "lduMatrix.H"
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
template<class Type, class DType, class LUType>
|
|
||||||
void Foam::LduMatrix<Type, DType, LUType>::sumDiag()
|
|
||||||
{
|
|
||||||
const Field<LUType>& Lower = const_cast<const LduMatrix&>(*this).lower();
|
|
||||||
const Field<LUType>& Upper = const_cast<const LduMatrix&>(*this).upper();
|
|
||||||
Field<DType>& Diag = diag();
|
|
||||||
|
|
||||||
const unallocLabelList& l = lduAddr().lowerAddr();
|
|
||||||
const unallocLabelList& u = lduAddr().upperAddr();
|
|
||||||
|
|
||||||
for (register label face=0; face<l.size(); face++)
|
|
||||||
{
|
|
||||||
Diag[l[face]] += Lower[face];
|
|
||||||
Diag[u[face]] += Upper[face];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template<class Type, class DType, class LUType>
|
|
||||||
void Foam::LduMatrix<Type, DType, LUType>::negSumDiag()
|
|
||||||
{
|
|
||||||
const Field<LUType>& Lower = const_cast<const LduMatrix&>(*this).lower();
|
|
||||||
const Field<LUType>& Upper = const_cast<const LduMatrix&>(*this).upper();
|
|
||||||
Field<DType>& Diag = diag();
|
|
||||||
|
|
||||||
const unallocLabelList& l = lduAddr().lowerAddr();
|
|
||||||
const unallocLabelList& u = lduAddr().upperAddr();
|
|
||||||
|
|
||||||
for (register label face=0; face<l.size(); face++)
|
|
||||||
{
|
|
||||||
Diag[l[face]] -= Lower[face];
|
|
||||||
Diag[u[face]] -= Upper[face];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template<class Type, class DType, class LUType>
|
|
||||||
void Foam::LduMatrix<Type, DType, LUType>::sumMagOffDiag
|
|
||||||
(
|
|
||||||
Field<LUType>& sumOff
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
const Field<LUType>& Lower = const_cast<const LduMatrix&>(*this).lower();
|
|
||||||
const Field<LUType>& Upper = const_cast<const LduMatrix&>(*this).upper();
|
|
||||||
|
|
||||||
const unallocLabelList& l = lduAddr().lowerAddr();
|
|
||||||
const unallocLabelList& u = lduAddr().upperAddr();
|
|
||||||
|
|
||||||
for (register label face = 0; face < l.size(); face++)
|
|
||||||
{
|
|
||||||
sumOff[u[face]] += cmptMag(Lower[face]);
|
|
||||||
sumOff[l[face]] += cmptMag(Upper[face]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template<class Type, class DType, class LUType>
|
|
||||||
Foam::tmp<Foam::Field<Type> >
|
|
||||||
Foam::LduMatrix<Type, DType, LUType>::H(const Field<Type>& psi) const
|
|
||||||
{
|
|
||||||
tmp<Field<Type> > tHpsi
|
|
||||||
(
|
|
||||||
new Field<Type>(lduAddr().size(), pTraits<Type>::zero)
|
|
||||||
);
|
|
||||||
|
|
||||||
if (lowerPtr_ || upperPtr_)
|
|
||||||
{
|
|
||||||
Field<Type> & Hpsi = tHpsi();
|
|
||||||
|
|
||||||
Type* __restrict__ HpsiPtr = Hpsi.begin();
|
|
||||||
|
|
||||||
const Type* __restrict__ psiPtr = psi.begin();
|
|
||||||
|
|
||||||
const label* __restrict__ uPtr = lduAddr().upperAddr().begin();
|
|
||||||
const label* __restrict__ lPtr = lduAddr().lowerAddr().begin();
|
|
||||||
|
|
||||||
const LUType* __restrict__ lowerPtr = lower().begin();
|
|
||||||
const LUType* __restrict__ upperPtr = upper().begin();
|
|
||||||
|
|
||||||
register const label nFaces = upper().size();
|
|
||||||
|
|
||||||
for (register label face=0; face<nFaces; face++)
|
|
||||||
{
|
|
||||||
HpsiPtr[uPtr[face]] -= lowerPtr[face]*psiPtr[lPtr[face]];
|
|
||||||
HpsiPtr[lPtr[face]] -= upperPtr[face]*psiPtr[uPtr[face]];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return tHpsi;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class Type, class DType, class LUType>
|
|
||||||
Foam::tmp<Foam::Field<Type> >
|
|
||||||
Foam::LduMatrix<Type, DType, LUType>::H(const tmp<Field<Type> >& tpsi) const
|
|
||||||
{
|
|
||||||
tmp<Field<Type> > tHpsi(H(tpsi()));
|
|
||||||
tpsi.clear();
|
|
||||||
return tHpsi;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template<class Type, class DType, class LUType>
|
|
||||||
Foam::tmp<Foam::Field<Type> >
|
|
||||||
Foam::LduMatrix<Type, DType, LUType>::faceH(const Field<Type>& psi) const
|
|
||||||
{
|
|
||||||
const Field<LUType>& Lower = const_cast<const LduMatrix&>(*this).lower();
|
|
||||||
const Field<LUType>& Upper = const_cast<const LduMatrix&>(*this).upper();
|
|
||||||
|
|
||||||
// Take refereces to addressing
|
|
||||||
const unallocLabelList& l = lduAddr().lowerAddr();
|
|
||||||
const unallocLabelList& u = lduAddr().upperAddr();
|
|
||||||
|
|
||||||
tmp<Field<Type> > tfaceHpsi(new Field<Type> (Lower.size()));
|
|
||||||
Field<Type> & faceHpsi = tfaceHpsi();
|
|
||||||
|
|
||||||
for (register label face=0; face<l.size(); face++)
|
|
||||||
{
|
|
||||||
faceHpsi[face] = Upper[face]*psi[u[face]] - Lower[face]*psi[l[face]];
|
|
||||||
}
|
|
||||||
|
|
||||||
return tfaceHpsi;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template<class Type, class DType, class LUType>
|
|
||||||
Foam::tmp<Foam::Field<Type> >
|
|
||||||
Foam::LduMatrix<Type, DType, LUType>::faceH(const tmp<Field<Type> >& tpsi) const
|
|
||||||
{
|
|
||||||
tmp<Field<Type> > tfaceHpsi(faceH(tpsi()));
|
|
||||||
tpsi.clear();
|
|
||||||
return tfaceHpsi;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
template<class Type, class DType, class LUType>
|
|
||||||
void Foam::LduMatrix<Type, DType, LUType>::operator=(const LduMatrix& A)
|
|
||||||
{
|
|
||||||
if (this == &A)
|
|
||||||
{
|
|
||||||
FatalErrorIn
|
|
||||||
(
|
|
||||||
"LduMatrix<Type, DType, LUType>::operator=(const LduMatrix&)"
|
|
||||||
) << "attempted assignment to self"
|
|
||||||
<< abort(FatalError);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (A.diagPtr_)
|
|
||||||
{
|
|
||||||
diag() = A.diag();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (A.upperPtr_)
|
|
||||||
{
|
|
||||||
upper() = A.upper();
|
|
||||||
}
|
|
||||||
else if (upperPtr_)
|
|
||||||
{
|
|
||||||
delete upperPtr_;
|
|
||||||
upperPtr_ = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (A.lowerPtr_)
|
|
||||||
{
|
|
||||||
lower() = A.lower();
|
|
||||||
}
|
|
||||||
else if (lowerPtr_)
|
|
||||||
{
|
|
||||||
delete lowerPtr_;
|
|
||||||
lowerPtr_ = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (A.sourcePtr_)
|
|
||||||
{
|
|
||||||
source() = A.source();
|
|
||||||
}
|
|
||||||
|
|
||||||
interfacesUpper_ = A.interfacesUpper_;
|
|
||||||
interfacesLower_ = A.interfacesLower_;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template<class Type, class DType, class LUType>
|
|
||||||
void Foam::LduMatrix<Type, DType, LUType>::negate()
|
|
||||||
{
|
|
||||||
if (diagPtr_)
|
|
||||||
{
|
|
||||||
diagPtr_->negate();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (upperPtr_)
|
|
||||||
{
|
|
||||||
upperPtr_->negate();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (lowerPtr_)
|
|
||||||
{
|
|
||||||
lowerPtr_->negate();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sourcePtr_)
|
|
||||||
{
|
|
||||||
sourcePtr_->negate();
|
|
||||||
}
|
|
||||||
|
|
||||||
negate(interfacesUpper_);
|
|
||||||
negate(interfacesLower_);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template<class Type, class DType, class LUType>
|
|
||||||
void Foam::LduMatrix<Type, DType, LUType>::operator+=(const LduMatrix& A)
|
|
||||||
{
|
|
||||||
if (A.diagPtr_)
|
|
||||||
{
|
|
||||||
diag() += A.diag();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (A.sourcePtr_)
|
|
||||||
{
|
|
||||||
source() += A.source();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (symmetric() && A.symmetric())
|
|
||||||
{
|
|
||||||
upper() += A.upper();
|
|
||||||
}
|
|
||||||
else if (symmetric() && A.asymmetric())
|
|
||||||
{
|
|
||||||
if (upperPtr_)
|
|
||||||
{
|
|
||||||
lower();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
upper();
|
|
||||||
}
|
|
||||||
|
|
||||||
upper() += A.upper();
|
|
||||||
lower() += A.lower();
|
|
||||||
}
|
|
||||||
else if (asymmetric() && A.symmetric())
|
|
||||||
{
|
|
||||||
if (A.upperPtr_)
|
|
||||||
{
|
|
||||||
lower() += A.upper();
|
|
||||||
upper() += A.upper();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
lower() += A.lower();
|
|
||||||
upper() += A.lower();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
else if (asymmetric() && A.asymmetric())
|
|
||||||
{
|
|
||||||
lower() += A.lower();
|
|
||||||
upper() += A.upper();
|
|
||||||
}
|
|
||||||
else if (diagonal())
|
|
||||||
{
|
|
||||||
if (A.upperPtr_)
|
|
||||||
{
|
|
||||||
upper() = A.upper();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (A.lowerPtr_)
|
|
||||||
{
|
|
||||||
lower() = A.lower();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (A.diagonal())
|
|
||||||
{
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
FatalErrorIn
|
|
||||||
(
|
|
||||||
"LduMatrix<Type, DType, LUType>::operator+=(const LduMatrix& A)"
|
|
||||||
) << "Unknown matrix type combination"
|
|
||||||
<< abort(FatalError);
|
|
||||||
}
|
|
||||||
|
|
||||||
interfacesUpper_ += A.interfacesUpper_;
|
|
||||||
interfacesLower_ += A.interfacesLower_;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template<class Type, class DType, class LUType>
|
|
||||||
void Foam::LduMatrix<Type, DType, LUType>::operator-=(const LduMatrix& A)
|
|
||||||
{
|
|
||||||
if (A.diagPtr_)
|
|
||||||
{
|
|
||||||
diag() -= A.diag();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (A.sourcePtr_)
|
|
||||||
{
|
|
||||||
source() -= A.source();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (symmetric() && A.symmetric())
|
|
||||||
{
|
|
||||||
upper() -= A.upper();
|
|
||||||
}
|
|
||||||
else if (symmetric() && A.asymmetric())
|
|
||||||
{
|
|
||||||
if (upperPtr_)
|
|
||||||
{
|
|
||||||
lower();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
upper();
|
|
||||||
}
|
|
||||||
|
|
||||||
upper() -= A.upper();
|
|
||||||
lower() -= A.lower();
|
|
||||||
}
|
|
||||||
else if (asymmetric() && A.symmetric())
|
|
||||||
{
|
|
||||||
if (A.upperPtr_)
|
|
||||||
{
|
|
||||||
lower() -= A.upper();
|
|
||||||
upper() -= A.upper();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
lower() -= A.lower();
|
|
||||||
upper() -= A.lower();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
else if (asymmetric() && A.asymmetric())
|
|
||||||
{
|
|
||||||
lower() -= A.lower();
|
|
||||||
upper() -= A.upper();
|
|
||||||
}
|
|
||||||
else if (diagonal())
|
|
||||||
{
|
|
||||||
if (A.upperPtr_)
|
|
||||||
{
|
|
||||||
upper() = -A.upper();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (A.lowerPtr_)
|
|
||||||
{
|
|
||||||
lower() = -A.lower();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (A.diagonal())
|
|
||||||
{
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
FatalErrorIn
|
|
||||||
(
|
|
||||||
"LduMatrix<Type, DType, LUType>::operator-=(const LduMatrix& A)"
|
|
||||||
) << "Unknown matrix type combination"
|
|
||||||
<< abort(FatalError);
|
|
||||||
}
|
|
||||||
|
|
||||||
interfacesUpper_ -= A.interfacesUpper_;
|
|
||||||
interfacesLower_ -= A.interfacesLower_;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template<class Type, class DType, class LUType>
|
|
||||||
void Foam::LduMatrix<Type, DType, LUType>::operator*=
|
|
||||||
(
|
|
||||||
const scalarField& sf
|
|
||||||
)
|
|
||||||
{
|
|
||||||
if (diagPtr_)
|
|
||||||
{
|
|
||||||
*diagPtr_ *= sf;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sourcePtr_)
|
|
||||||
{
|
|
||||||
*sourcePtr_ *= sf;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (upperPtr_)
|
|
||||||
{
|
|
||||||
Field<LUType>& upper = *upperPtr_;
|
|
||||||
|
|
||||||
const unallocLabelList& l = lduAddr().lowerAddr();
|
|
||||||
|
|
||||||
for (register label face=0; face<upper.size(); face++)
|
|
||||||
{
|
|
||||||
upper[face] *= sf[l[face]];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (lowerPtr_)
|
|
||||||
{
|
|
||||||
Field<LUType>& lower = *lowerPtr_;
|
|
||||||
|
|
||||||
const unallocLabelList& u = lduAddr().upperAddr();
|
|
||||||
|
|
||||||
for (register label face=0; face<lower.size(); face++)
|
|
||||||
{
|
|
||||||
lower[face] *= sf[u[face]];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
FatalErrorIn
|
|
||||||
(
|
|
||||||
"LduMatrix<Type, DType, LUType>::operator*=(const scalarField& sf)"
|
|
||||||
) << "Scaling a matrix by scalarField is not currently supported\n"
|
|
||||||
"because scaling interfacesUpper_ and interfacesLower_ "
|
|
||||||
"require special transfers"
|
|
||||||
<< abort(FatalError);
|
|
||||||
|
|
||||||
//interfacesUpper_ *= ;
|
|
||||||
//interfacesLower_ *= sf;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template<class Type, class DType, class LUType>
|
|
||||||
void Foam::LduMatrix<Type, DType, LUType>::operator*=(scalar s)
|
|
||||||
{
|
|
||||||
if (diagPtr_)
|
|
||||||
{
|
|
||||||
*diagPtr_ *= s;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sourcePtr_)
|
|
||||||
{
|
|
||||||
*sourcePtr_ *= s;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (upperPtr_)
|
|
||||||
{
|
|
||||||
*upperPtr_ *= s;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (lowerPtr_)
|
|
||||||
{
|
|
||||||
*lowerPtr_ *= s;
|
|
||||||
}
|
|
||||||
|
|
||||||
interfacesUpper_ *= s;
|
|
||||||
interfacesLower_ *= s;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
|
||||||
@ -1,116 +0,0 @@
|
|||||||
/*---------------------------------------------------------------------------*\
|
|
||||||
========= |
|
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
|
||||||
\\ / O peration |
|
|
||||||
\\ / A nd | Copyright (C) 1991-2007 OpenCFD Ltd.
|
|
||||||
\\/ M anipulation |
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
License
|
|
||||||
This file is part of OpenFOAM.
|
|
||||||
|
|
||||||
OpenFOAM is free software; you can redistribute it and/or modify it
|
|
||||||
under the terms of the GNU General Public License as published by the
|
|
||||||
Free Software Foundation; either version 2 of the License, or (at your
|
|
||||||
option) any later version.
|
|
||||||
|
|
||||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
|
||||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
||||||
for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with OpenFOAM; if not, write to the Free Software Foundation,
|
|
||||||
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
#include "LduMatrix.H"
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
template<class Type, class DType, class LUType>
|
|
||||||
Foam::autoPtr<typename Foam::LduMatrix<Type, DType, LUType>::preconditioner>
|
|
||||||
Foam::LduMatrix<Type, DType, LUType>::preconditioner::New
|
|
||||||
(
|
|
||||||
const solver& sol,
|
|
||||||
const dictionary& preconditionerDict
|
|
||||||
)
|
|
||||||
{
|
|
||||||
word preconditionerName = preconditionerDict.lookup("preconditioner");
|
|
||||||
|
|
||||||
if (sol.matrix().symmetric())
|
|
||||||
{
|
|
||||||
typename symMatrixConstructorTable::iterator constructorIter =
|
|
||||||
symMatrixConstructorTablePtr_->find(preconditionerName);
|
|
||||||
|
|
||||||
if (constructorIter == symMatrixConstructorTablePtr_->end())
|
|
||||||
{
|
|
||||||
FatalIOErrorIn
|
|
||||||
(
|
|
||||||
"LduMatrix<Type, DType, LUType>::preconditioner::New"
|
|
||||||
"(const solver&, Istream&)",
|
|
||||||
preconditionerDict
|
|
||||||
) << "Unknown symmetric matrix preconditioner "
|
|
||||||
<< preconditionerName << endl << endl
|
|
||||||
<< "Valid symmetric matrix preconditioners are :" << endl
|
|
||||||
<< symMatrixConstructorTablePtr_->toc()
|
|
||||||
<< exit(FatalIOError);
|
|
||||||
}
|
|
||||||
|
|
||||||
return autoPtr<typename LduMatrix<Type, DType, LUType>::preconditioner>
|
|
||||||
(
|
|
||||||
constructorIter()
|
|
||||||
(
|
|
||||||
sol,
|
|
||||||
preconditionerDict
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
else if (sol.matrix().asymmetric())
|
|
||||||
{
|
|
||||||
typename asymMatrixConstructorTable::iterator constructorIter =
|
|
||||||
asymMatrixConstructorTablePtr_->find(preconditionerName);
|
|
||||||
|
|
||||||
if (constructorIter == asymMatrixConstructorTablePtr_->end())
|
|
||||||
{
|
|
||||||
FatalIOErrorIn
|
|
||||||
(
|
|
||||||
"LduMatrix<Type, DType, LUType>::preconditioner::New"
|
|
||||||
"(const solver&, Istream&)",
|
|
||||||
preconditionerDict
|
|
||||||
) << "Unknown asymmetric matrix preconditioner "
|
|
||||||
<< preconditionerName << endl << endl
|
|
||||||
<< "Valid asymmetric matrix preconditioners are :" << endl
|
|
||||||
<< asymMatrixConstructorTablePtr_->toc()
|
|
||||||
<< exit(FatalIOError);
|
|
||||||
}
|
|
||||||
|
|
||||||
return autoPtr<typename LduMatrix<Type, DType, LUType>::preconditioner>
|
|
||||||
(
|
|
||||||
constructorIter()
|
|
||||||
(
|
|
||||||
sol,
|
|
||||||
preconditionerDict
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
FatalIOErrorIn
|
|
||||||
(
|
|
||||||
"LduMatrix<Type, DType, LUType>::preconditioner::New"
|
|
||||||
"(const solver&, Istream&)",
|
|
||||||
preconditionerDict
|
|
||||||
) << "cannot preconditione incomplete matrix, "
|
|
||||||
"no diagonal or off-diagonal coefficient"
|
|
||||||
<< exit(FatalIOError);
|
|
||||||
|
|
||||||
return autoPtr<typename LduMatrix<Type, DType, LUType>::preconditioner>
|
|
||||||
(
|
|
||||||
NULL
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
|
||||||
@ -1,121 +0,0 @@
|
|||||||
/*---------------------------------------------------------------------------*\
|
|
||||||
========= |
|
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
|
||||||
\\ / O peration |
|
|
||||||
\\ / A nd | Copyright (C) 1991-2007 OpenCFD Ltd.
|
|
||||||
\\/ M anipulation |
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
License
|
|
||||||
This file is part of OpenFOAM.
|
|
||||||
|
|
||||||
OpenFOAM is free software; you can redistribute it and/or modify it
|
|
||||||
under the terms of the GNU General Public License as published by the
|
|
||||||
Free Software Foundation; either version 2 of the License, or (at your
|
|
||||||
option) any later version.
|
|
||||||
|
|
||||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
|
||||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
||||||
for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with OpenFOAM; if not, write to the Free Software Foundation,
|
|
||||||
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
#include "LduMatrix.H"
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
template<class Type, class DType, class LUType>
|
|
||||||
Foam::autoPtr<typename Foam::LduMatrix<Type, DType, LUType>::smoother>
|
|
||||||
Foam::LduMatrix<Type, DType, LUType>::smoother::New
|
|
||||||
(
|
|
||||||
const word& fieldName,
|
|
||||||
const LduMatrix<Type, DType, LUType>& matrix,
|
|
||||||
const dictionary& smootherDict
|
|
||||||
)
|
|
||||||
{
|
|
||||||
word smootherName = smootherDict.lookup("smoother");
|
|
||||||
|
|
||||||
if (matrix.symmetric())
|
|
||||||
{
|
|
||||||
typename symMatrixConstructorTable::iterator constructorIter =
|
|
||||||
symMatrixConstructorTablePtr_->find(smootherName);
|
|
||||||
|
|
||||||
if (constructorIter == symMatrixConstructorTablePtr_->end())
|
|
||||||
{
|
|
||||||
FatalIOErrorIn
|
|
||||||
(
|
|
||||||
"LduMatrix<Type, DType, LUType>::smoother::New", smootherDict
|
|
||||||
) << "Unknown symmetric matrix smoother " << smootherName
|
|
||||||
<< endl << endl
|
|
||||||
<< "Valid symmetric matrix smoothers are :" << endl
|
|
||||||
<< symMatrixConstructorTablePtr_->toc()
|
|
||||||
<< exit(FatalIOError);
|
|
||||||
}
|
|
||||||
|
|
||||||
return autoPtr<typename LduMatrix<Type, DType, LUType>::smoother>
|
|
||||||
(
|
|
||||||
constructorIter()
|
|
||||||
(
|
|
||||||
fieldName,
|
|
||||||
matrix
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
else if (matrix.asymmetric())
|
|
||||||
{
|
|
||||||
typename asymMatrixConstructorTable::iterator constructorIter =
|
|
||||||
asymMatrixConstructorTablePtr_->find(smootherName);
|
|
||||||
|
|
||||||
if (constructorIter == asymMatrixConstructorTablePtr_->end())
|
|
||||||
{
|
|
||||||
FatalIOErrorIn
|
|
||||||
(
|
|
||||||
"LduMatrix<Type, DType, LUType>::smoother::New", smootherDict
|
|
||||||
) << "Unknown asymmetric matrix smoother " << smootherName
|
|
||||||
<< endl << endl
|
|
||||||
<< "Valid asymmetric matrix smoothers are :" << endl
|
|
||||||
<< asymMatrixConstructorTablePtr_->toc()
|
|
||||||
<< exit(FatalIOError);
|
|
||||||
}
|
|
||||||
|
|
||||||
return autoPtr<typename LduMatrix<Type, DType, LUType>::smoother>
|
|
||||||
(
|
|
||||||
constructorIter()
|
|
||||||
(
|
|
||||||
fieldName,
|
|
||||||
matrix
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
FatalIOErrorIn
|
|
||||||
(
|
|
||||||
"LduMatrix<Type, DType, LUType>::smoother::New", smootherDict
|
|
||||||
) << "cannot solve incomplete matrix, no off-diagonal coefficients"
|
|
||||||
<< exit(FatalIOError);
|
|
||||||
|
|
||||||
return autoPtr<typename LduMatrix<Type, DType, LUType>::smoother>(NULL);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
template<class Type, class DType, class LUType>
|
|
||||||
Foam::LduMatrix<Type, DType, LUType>::smoother::smoother
|
|
||||||
(
|
|
||||||
const word& fieldName,
|
|
||||||
const LduMatrix<Type, DType, LUType>& matrix
|
|
||||||
)
|
|
||||||
:
|
|
||||||
fieldName_(fieldName),
|
|
||||||
matrix_(matrix)
|
|
||||||
{}
|
|
||||||
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
|
||||||
@ -1,191 +0,0 @@
|
|||||||
/*---------------------------------------------------------------------------*\
|
|
||||||
========= |
|
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
|
||||||
\\ / O peration |
|
|
||||||
\\ / A nd | Copyright (C) 1991-2007 OpenCFD Ltd.
|
|
||||||
\\/ M anipulation |
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
License
|
|
||||||
This file is part of OpenFOAM.
|
|
||||||
|
|
||||||
OpenFOAM is free software; you can redistribute it and/or modify it
|
|
||||||
under the terms of the GNU General Public License as published by the
|
|
||||||
Free Software Foundation; either version 2 of the License, or (at your
|
|
||||||
option) any later version.
|
|
||||||
|
|
||||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
|
||||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
||||||
for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with OpenFOAM; if not, write to the Free Software Foundation,
|
|
||||||
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
#include "LduMatrix.H"
|
|
||||||
#include "DiagonalSolver.H"
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
template<class Type, class DType, class LUType>
|
|
||||||
Foam::autoPtr<typename Foam::LduMatrix<Type, DType, LUType>::solver>
|
|
||||||
Foam::LduMatrix<Type, DType, LUType>::solver::New
|
|
||||||
(
|
|
||||||
const word& fieldName,
|
|
||||||
const LduMatrix<Type, DType, LUType>& matrix,
|
|
||||||
const dictionary& solverDict
|
|
||||||
)
|
|
||||||
{
|
|
||||||
word solverName = solverDict.lookup("solver");
|
|
||||||
|
|
||||||
if (matrix.diagonal())
|
|
||||||
{
|
|
||||||
return autoPtr<typename LduMatrix<Type, DType, LUType>::solver>
|
|
||||||
(
|
|
||||||
new DiagonalSolver<Type, DType, LUType>
|
|
||||||
(
|
|
||||||
fieldName,
|
|
||||||
matrix,
|
|
||||||
solverDict
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
else if (matrix.symmetric())
|
|
||||||
{
|
|
||||||
typename symMatrixConstructorTable::iterator constructorIter =
|
|
||||||
symMatrixConstructorTablePtr_->find(solverName);
|
|
||||||
|
|
||||||
if (constructorIter == symMatrixConstructorTablePtr_->end())
|
|
||||||
{
|
|
||||||
FatalIOErrorIn
|
|
||||||
(
|
|
||||||
"LduMatrix<Type, DType, LUType>::solver::New", solverDict
|
|
||||||
) << "Unknown symmetric matrix solver " << solverName
|
|
||||||
<< endl << endl
|
|
||||||
<< "Valid symmetric matrix solvers are :" << endl
|
|
||||||
<< symMatrixConstructorTablePtr_->toc()
|
|
||||||
<< exit(FatalIOError);
|
|
||||||
}
|
|
||||||
|
|
||||||
return autoPtr<typename LduMatrix<Type, DType, LUType>::solver>
|
|
||||||
(
|
|
||||||
constructorIter()
|
|
||||||
(
|
|
||||||
fieldName,
|
|
||||||
matrix,
|
|
||||||
solverDict
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
else if (matrix.asymmetric())
|
|
||||||
{
|
|
||||||
typename asymMatrixConstructorTable::iterator constructorIter =
|
|
||||||
asymMatrixConstructorTablePtr_->find(solverName);
|
|
||||||
|
|
||||||
if (constructorIter == asymMatrixConstructorTablePtr_->end())
|
|
||||||
{
|
|
||||||
FatalIOErrorIn
|
|
||||||
(
|
|
||||||
"LduMatrix<Type, DType, LUType>::solver::New", solverDict
|
|
||||||
) << "Unknown asymmetric matrix solver " << solverName
|
|
||||||
<< endl << endl
|
|
||||||
<< "Valid asymmetric matrix solvers are :" << endl
|
|
||||||
<< asymMatrixConstructorTablePtr_->toc()
|
|
||||||
<< exit(FatalIOError);
|
|
||||||
}
|
|
||||||
|
|
||||||
return autoPtr<typename LduMatrix<Type, DType, LUType>::solver>
|
|
||||||
(
|
|
||||||
constructorIter()
|
|
||||||
(
|
|
||||||
fieldName,
|
|
||||||
matrix,
|
|
||||||
solverDict
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
FatalIOErrorIn
|
|
||||||
(
|
|
||||||
"LduMatrix<Type, DType, LUType>::solver::New", solverDict
|
|
||||||
) << "cannot solve incomplete matrix, "
|
|
||||||
"no diagonal or off-diagonal coefficient"
|
|
||||||
<< exit(FatalIOError);
|
|
||||||
|
|
||||||
return autoPtr<typename LduMatrix<Type, DType, LUType>::solver>(NULL);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
template<class Type, class DType, class LUType>
|
|
||||||
Foam::LduMatrix<Type, DType, LUType>::solver::solver
|
|
||||||
(
|
|
||||||
const word& fieldName,
|
|
||||||
const LduMatrix<Type, DType, LUType>& matrix,
|
|
||||||
const dictionary& solverDict
|
|
||||||
)
|
|
||||||
:
|
|
||||||
fieldName_(fieldName),
|
|
||||||
matrix_(matrix),
|
|
||||||
|
|
||||||
controlDict_(solverDict),
|
|
||||||
|
|
||||||
maxIter_(1000),
|
|
||||||
tolerance_(1e-6*pTraits<Type>::one),
|
|
||||||
relTol_(pTraits<Type>::zero)
|
|
||||||
{
|
|
||||||
readControls();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
template<class Type, class DType, class LUType>
|
|
||||||
void Foam::LduMatrix<Type, DType, LUType>::solver::readControls()
|
|
||||||
{
|
|
||||||
readControl(controlDict_, maxIter_, "maxIter");
|
|
||||||
readControl(controlDict_, tolerance_, "tolerance");
|
|
||||||
readControl(controlDict_, relTol_, "relTol");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template<class Type, class DType, class LUType>
|
|
||||||
void Foam::LduMatrix<Type, DType, LUType>::solver::read
|
|
||||||
(
|
|
||||||
const dictionary& solverDict
|
|
||||||
)
|
|
||||||
{
|
|
||||||
controlDict_ = solverDict;
|
|
||||||
readControls();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template<class Type, class DType, class LUType>
|
|
||||||
Type Foam::LduMatrix<Type, DType, LUType>::solver::normFactor
|
|
||||||
(
|
|
||||||
const Field<Type>& psi,
|
|
||||||
const Field<Type>& Apsi,
|
|
||||||
Field<Type>& tmpField
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
// --- Calculate A dot reference value of psi
|
|
||||||
matrix_.sumA(tmpField);
|
|
||||||
cmptMultiply(tmpField, tmpField, gAverage(psi));
|
|
||||||
|
|
||||||
return stabilise
|
|
||||||
(
|
|
||||||
gSum(cmptMag(Apsi - tmpField) + cmptMag(matrix_.source() - tmpField)),
|
|
||||||
matrix_.small_
|
|
||||||
);
|
|
||||||
|
|
||||||
// At convergence this simpler method is equivalent to the above
|
|
||||||
// return stabilise(2*gSumCmptMag(matrix_.source()), matrix_.small_);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
|
||||||
@ -1,119 +0,0 @@
|
|||||||
/*---------------------------------------------------------------------------*\
|
|
||||||
========= |
|
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
|
||||||
\\ / O peration |
|
|
||||||
\\ / A nd | Copyright (C) 1991-2007 OpenCFD Ltd.
|
|
||||||
\\/ M anipulation |
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
License
|
|
||||||
This file is part of OpenFOAM.
|
|
||||||
|
|
||||||
OpenFOAM is free software; you can redistribute it and/or modify it
|
|
||||||
under the terms of the GNU General Public License as published by the
|
|
||||||
Free Software Foundation; either version 2 of the License, or (at your
|
|
||||||
option) any later version.
|
|
||||||
|
|
||||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
|
||||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
||||||
for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with OpenFOAM; if not, write to the Free Software Foundation,
|
|
||||||
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
#include "LduMatrix.H"
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
template<class Type, class DType, class LUType>
|
|
||||||
bool Foam::LduMatrix<Type, DType, LUType>::solverPerformance::singular
|
|
||||||
(
|
|
||||||
const Type& wApA
|
|
||||||
)
|
|
||||||
{
|
|
||||||
for(direction cmpt=0; cmpt<pTraits<Type>::nComponents; cmpt++)
|
|
||||||
{
|
|
||||||
singular_[cmpt] = component(wApA, cmpt) < vsmall_;
|
|
||||||
}
|
|
||||||
|
|
||||||
return singular();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template<class Type, class DType, class LUType>
|
|
||||||
bool Foam::LduMatrix<Type, DType, LUType>::solverPerformance::singular() const
|
|
||||||
{
|
|
||||||
for(direction cmpt=0; cmpt<pTraits<Type>::nComponents; cmpt++)
|
|
||||||
{
|
|
||||||
if (!singular_[cmpt]) return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template<class Type, class DType, class LUType>
|
|
||||||
bool Foam::LduMatrix<Type, DType, LUType>::solverPerformance::converged
|
|
||||||
(
|
|
||||||
const Type& Tolerance,
|
|
||||||
const Type& RelTolerance
|
|
||||||
)
|
|
||||||
{
|
|
||||||
if (debug >= 2)
|
|
||||||
{
|
|
||||||
Info<< solverName_
|
|
||||||
<< ": Iteration " << noIterations_
|
|
||||||
<< " residual = " << finalResidual_
|
|
||||||
<< endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
if
|
|
||||||
(
|
|
||||||
finalResidual_ < Tolerance
|
|
||||||
|| (
|
|
||||||
RelTolerance > small_*pTraits<Type>::one
|
|
||||||
&& finalResidual_ < cmptMultiply(RelTolerance, initialResidual_)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
{
|
|
||||||
converged_ = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
converged_ = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return converged_;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template<class Type, class DType, class LUType>
|
|
||||||
void Foam::LduMatrix<Type, DType, LUType>::solverPerformance::print
|
|
||||||
(
|
|
||||||
Ostream& os
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
for(direction cmpt=0; cmpt<pTraits<Type>::nComponents; cmpt++)
|
|
||||||
{
|
|
||||||
os << solverName_ << ": Solving for "
|
|
||||||
<< word(fieldName_ + pTraits<Type>::componentNames[cmpt]);
|
|
||||||
|
|
||||||
if (singular_[cmpt])
|
|
||||||
{
|
|
||||||
os << ": solution singularity" << endl;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
os << ", Initial residual = " << component(initialResidual_, cmpt)
|
|
||||||
<< ", Final residual = " << component(finalResidual_, cmpt)
|
|
||||||
<< ", No Iterations " << noIterations_
|
|
||||||
<< endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
|
||||||
@ -1,195 +0,0 @@
|
|||||||
/*---------------------------------------------------------------------------*\
|
|
||||||
========= |
|
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
|
||||||
\\ / O peration |
|
|
||||||
\\ / A nd | Copyright (C) 1991-2007 OpenCFD Ltd.
|
|
||||||
\\/ M anipulation |
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
License
|
|
||||||
This file is part of OpenFOAM.
|
|
||||||
|
|
||||||
OpenFOAM is free software; you can redistribute it and/or modify it
|
|
||||||
under the terms of the GNU General Public License as published by the
|
|
||||||
Free Software Foundation; either version 2 of the License, or (at your
|
|
||||||
option) any later version.
|
|
||||||
|
|
||||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
|
||||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
||||||
for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with OpenFOAM; if not, write to the Free Software Foundation,
|
|
||||||
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
#include "LduMatrix.H"
|
|
||||||
#include "LduInterfaceField.H"
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
template<class Type, class DType, class LUType>
|
|
||||||
void Foam::LduMatrix<Type, DType, LUType>::initMatrixInterfaces
|
|
||||||
(
|
|
||||||
const FieldField<Field, LUType>& interfaceCoeffs,
|
|
||||||
const Field<Type>& psiif,
|
|
||||||
Field<Type>& result
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
if
|
|
||||||
(
|
|
||||||
Pstream::defaultCommsType == Pstream::blocking
|
|
||||||
|| Pstream::defaultCommsType == Pstream::nonBlocking
|
|
||||||
)
|
|
||||||
{
|
|
||||||
forAll (interfaces_, interfaceI)
|
|
||||||
{
|
|
||||||
if (interfaces_.set(interfaceI))
|
|
||||||
{
|
|
||||||
interfaces_[interfaceI].initInterfaceMatrixUpdate
|
|
||||||
(
|
|
||||||
result,
|
|
||||||
psiif,
|
|
||||||
Amultiplier<Type, LUType>(interfaceCoeffs[interfaceI]),
|
|
||||||
Pstream::defaultCommsType
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (Pstream::defaultCommsType == Pstream::scheduled)
|
|
||||||
{
|
|
||||||
const lduSchedule& patchSchedule = this->patchSchedule();
|
|
||||||
|
|
||||||
// Loop over the "global" patches are on the list of interfaces but
|
|
||||||
// beyond the end of the schedule which only handles "normal" patches
|
|
||||||
for
|
|
||||||
(
|
|
||||||
label interfaceI=patchSchedule.size()/2;
|
|
||||||
interfaceI<interfaces_.size();
|
|
||||||
interfaceI++
|
|
||||||
)
|
|
||||||
{
|
|
||||||
if (interfaces_.set(interfaceI))
|
|
||||||
{
|
|
||||||
interfaces_[interfaceI].initInterfaceMatrixUpdate
|
|
||||||
(
|
|
||||||
result,
|
|
||||||
psiif,
|
|
||||||
Amultiplier<Type, LUType>(interfaceCoeffs[interfaceI]),
|
|
||||||
Pstream::blocking
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
FatalErrorIn("LduMatrix<Type, DType, LUType>::initMatrixInterfaces")
|
|
||||||
<< "Unsuported communications type "
|
|
||||||
<< Pstream::commsTypeNames[Pstream::defaultCommsType]
|
|
||||||
<< exit(FatalError);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template<class Type, class DType, class LUType>
|
|
||||||
void Foam::LduMatrix<Type, DType, LUType>::updateMatrixInterfaces
|
|
||||||
(
|
|
||||||
const FieldField<Field, LUType>& interfaceCoeffs,
|
|
||||||
const Field<Type>& psiif,
|
|
||||||
Field<Type>& result
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
if
|
|
||||||
(
|
|
||||||
Pstream::defaultCommsType == Pstream::blocking
|
|
||||||
|| Pstream::defaultCommsType == Pstream::nonBlocking
|
|
||||||
)
|
|
||||||
{
|
|
||||||
// Block until all sends/receives have been finished
|
|
||||||
if (Pstream::defaultCommsType == Pstream::nonBlocking)
|
|
||||||
{
|
|
||||||
IPstream::waitRequests();
|
|
||||||
OPstream::waitRequests();
|
|
||||||
}
|
|
||||||
|
|
||||||
forAll (interfaces_, interfaceI)
|
|
||||||
{
|
|
||||||
if (interfaces_.set(interfaceI))
|
|
||||||
{
|
|
||||||
interfaces_[interfaceI].updateInterfaceMatrix
|
|
||||||
(
|
|
||||||
result,
|
|
||||||
psiif,
|
|
||||||
Amultiplier<Type, LUType>(interfaceCoeffs[interfaceI]),
|
|
||||||
Pstream::defaultCommsType
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (Pstream::defaultCommsType == Pstream::scheduled)
|
|
||||||
{
|
|
||||||
const lduSchedule& patchSchedule = this->patchSchedule();
|
|
||||||
|
|
||||||
// Loop over all the "normal" interfaces relating to standard patches
|
|
||||||
forAll (patchSchedule, i)
|
|
||||||
{
|
|
||||||
label interfaceI = patchSchedule[i].patch;
|
|
||||||
|
|
||||||
if (interfaces_.set(interfaceI))
|
|
||||||
{
|
|
||||||
if (patchSchedule[i].init)
|
|
||||||
{
|
|
||||||
interfaces_[interfaceI].initInterfaceMatrixUpdate
|
|
||||||
(
|
|
||||||
result,
|
|
||||||
psiif,
|
|
||||||
Amultiplier<Type, LUType>(interfaceCoeffs[interfaceI]),
|
|
||||||
Pstream::scheduled
|
|
||||||
);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
interfaces_[interfaceI].updateInterfaceMatrix
|
|
||||||
(
|
|
||||||
result,
|
|
||||||
psiif,
|
|
||||||
Amultiplier<Type, LUType>(interfaceCoeffs[interfaceI]),
|
|
||||||
Pstream::scheduled
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Loop over the "global" patches are on the list of interfaces but
|
|
||||||
// beyond the end of the schedule which only handles "normal" patches
|
|
||||||
for
|
|
||||||
(
|
|
||||||
label interfaceI=patchSchedule.size()/2;
|
|
||||||
interfaceI<interfaces_.size();
|
|
||||||
interfaceI++
|
|
||||||
)
|
|
||||||
{
|
|
||||||
if (interfaces_.set(interfaceI))
|
|
||||||
{
|
|
||||||
interfaces_[interfaceI].updateInterfaceMatrix
|
|
||||||
(
|
|
||||||
result,
|
|
||||||
psiif,
|
|
||||||
Amultiplier<Type, LUType>(interfaceCoeffs[interfaceI]),
|
|
||||||
Pstream::blocking
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
FatalErrorIn("LduMatrix<Type, DType, LUType>::updateMatrixInterfaces")
|
|
||||||
<< "Unsuported communications type "
|
|
||||||
<< Pstream::commsTypeNames[Pstream::defaultCommsType]
|
|
||||||
<< exit(FatalError);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
|
||||||
@ -1,11 +0,0 @@
|
|||||||
#include "LduMatrix.H"
|
|
||||||
#include "fieldTypes.H"
|
|
||||||
|
|
||||||
namespace Foam
|
|
||||||
{
|
|
||||||
makeLduMatrix(scalar, scalar, scalar);
|
|
||||||
makeLduMatrix(vector, scalar, scalar);
|
|
||||||
makeLduMatrix(sphericalTensor, scalar, scalar);
|
|
||||||
makeLduMatrix(symmTensor, scalar, scalar);
|
|
||||||
makeLduMatrix(tensor, scalar, scalar);
|
|
||||||
};
|
|
||||||
@ -1,180 +0,0 @@
|
|||||||
/*---------------------------------------------------------------------------*\
|
|
||||||
========= |
|
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
|
||||||
\\ / O peration |
|
|
||||||
\\ / A nd | Copyright (C) 1991-2007 OpenCFD Ltd.
|
|
||||||
\\/ M anipulation |
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
License
|
|
||||||
This file is part of OpenFOAM.
|
|
||||||
|
|
||||||
OpenFOAM is free software; you can redistribute it and/or modify it
|
|
||||||
under the terms of the GNU General Public License as published by the
|
|
||||||
Free Software Foundation; either version 2 of the License, or (at your
|
|
||||||
option) any later version.
|
|
||||||
|
|
||||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
|
||||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
||||||
for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with OpenFOAM; if not, write to the Free Software Foundation,
|
|
||||||
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
#include "TDILUPreconditioner.H"
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
template<class Type, class DType, class LUType>
|
|
||||||
Foam::TDILUPreconditioner<Type, DType, LUType>::TDILUPreconditioner
|
|
||||||
(
|
|
||||||
const typename LduMatrix<Type, DType, LUType>::solver& sol,
|
|
||||||
const dictionary&
|
|
||||||
)
|
|
||||||
:
|
|
||||||
LduMatrix<Type, DType, LUType>::preconditioner(sol),
|
|
||||||
rD_(sol.matrix().diag())
|
|
||||||
{
|
|
||||||
calcInvD(rD_, sol.matrix());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
template<class Type, class DType, class LUType>
|
|
||||||
void Foam::TDILUPreconditioner<Type, DType, LUType>::calcInvD
|
|
||||||
(
|
|
||||||
Field<DType>& rD,
|
|
||||||
const LduMatrix<Type, DType, LUType>& matrix
|
|
||||||
)
|
|
||||||
{
|
|
||||||
DType* __restrict__ rDPtr = rD.begin();
|
|
||||||
|
|
||||||
const label* const __restrict__ uPtr = matrix.lduAddr().upperAddr().begin();
|
|
||||||
const label* const __restrict__ lPtr = matrix.lduAddr().lowerAddr().begin();
|
|
||||||
|
|
||||||
const LUType* const __restrict__ upperPtr = matrix.upper().begin();
|
|
||||||
const LUType* const __restrict__ lowerPtr = matrix.lower().begin();
|
|
||||||
|
|
||||||
register label nFaces = matrix.upper().size();
|
|
||||||
for (register label face=0; face<nFaces; face++)
|
|
||||||
{
|
|
||||||
rDPtr[uPtr[face]] -=
|
|
||||||
dot(dot(upperPtr[face], lowerPtr[face]), inv(rDPtr[lPtr[face]]));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Calculate the reciprocal of the preconditioned diagonal
|
|
||||||
register label nCells = rD.size();
|
|
||||||
|
|
||||||
for (register label cell=0; cell<nCells; cell++)
|
|
||||||
{
|
|
||||||
rDPtr[cell] = inv(rDPtr[cell]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template<class Type, class DType, class LUType>
|
|
||||||
void Foam::TDILUPreconditioner<Type, DType, LUType>::precondition
|
|
||||||
(
|
|
||||||
Field<Type>& wA,
|
|
||||||
const Field<Type>& rA
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
Type* __restrict__ wAPtr = wA.begin();
|
|
||||||
const Type* __restrict__ rAPtr = rA.begin();
|
|
||||||
const DType* __restrict__ rDPtr = rD_.begin();
|
|
||||||
|
|
||||||
const label* const __restrict__ uPtr =
|
|
||||||
this->solver_.matrix().lduAddr().upperAddr().begin();
|
|
||||||
const label* const __restrict__ lPtr =
|
|
||||||
this->solver_.matrix().lduAddr().lowerAddr().begin();
|
|
||||||
const label* const __restrict__ losortPtr =
|
|
||||||
this->solver_.matrix().lduAddr().losortAddr().begin();
|
|
||||||
|
|
||||||
const LUType* const __restrict__ upperPtr =
|
|
||||||
this->solver_.matrix().upper().begin();
|
|
||||||
const LUType* const __restrict__ lowerPtr =
|
|
||||||
this->solver_.matrix().lower().begin();
|
|
||||||
|
|
||||||
register label nCells = wA.size();
|
|
||||||
register label nFaces = this->solver_.matrix().upper().size();
|
|
||||||
register label nFacesM1 = nFaces - 1;
|
|
||||||
|
|
||||||
for (register label cell=0; cell<nCells; cell++)
|
|
||||||
{
|
|
||||||
wAPtr[cell] = dot(rDPtr[cell], rAPtr[cell]);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
register label sface;
|
|
||||||
|
|
||||||
for (register label face=0; face<nFaces; face++)
|
|
||||||
{
|
|
||||||
sface = losortPtr[face];
|
|
||||||
wAPtr[uPtr[sface]] -=
|
|
||||||
dot(rDPtr[uPtr[sface]], dot(lowerPtr[sface], wAPtr[lPtr[sface]]));
|
|
||||||
}
|
|
||||||
|
|
||||||
for (register label face=nFacesM1; face>=0; face--)
|
|
||||||
{
|
|
||||||
wAPtr[lPtr[face]] -=
|
|
||||||
dot(rDPtr[lPtr[face]], dot(upperPtr[face], wAPtr[uPtr[face]]));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template<class Type, class DType, class LUType>
|
|
||||||
void Foam::TDILUPreconditioner<Type, DType, LUType>::preconditionT
|
|
||||||
(
|
|
||||||
Field<Type>& wT,
|
|
||||||
const Field<Type>& rT
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
Type* __restrict__ wTPtr = wT.begin();
|
|
||||||
const Type* __restrict__ rTPtr = rT.begin();
|
|
||||||
const DType* __restrict__ rDPtr = rD_.begin();
|
|
||||||
|
|
||||||
const label* const __restrict__ uPtr =
|
|
||||||
this->solver_.matrix().lduAddr().upperAddr().begin();
|
|
||||||
const label* const __restrict__ lPtr =
|
|
||||||
this->solver_.matrix().lduAddr().lowerAddr().begin();
|
|
||||||
const label* const __restrict__ losortPtr =
|
|
||||||
this->solver_.matrix().lduAddr().losortAddr().begin();
|
|
||||||
|
|
||||||
const LUType* const __restrict__ upperPtr =
|
|
||||||
this->solver_.matrix().upper().begin();
|
|
||||||
const LUType* const __restrict__ lowerPtr =
|
|
||||||
this->solver_.matrix().lower().begin();
|
|
||||||
|
|
||||||
register label nCells = wT.size();
|
|
||||||
register label nFaces = this->solver_.matrix().upper().size();
|
|
||||||
register label nFacesM1 = nFaces - 1;
|
|
||||||
|
|
||||||
for (register label cell=0; cell<nCells; cell++)
|
|
||||||
{
|
|
||||||
wTPtr[cell] = dot(rDPtr[cell], rTPtr[cell]);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (register label face=0; face<nFaces; face++)
|
|
||||||
{
|
|
||||||
wTPtr[uPtr[face]] -=
|
|
||||||
dot(rDPtr[uPtr[face]], dot(upperPtr[face], wTPtr[lPtr[face]]));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
register label sface;
|
|
||||||
|
|
||||||
for (register label face=nFacesM1; face>=0; face--)
|
|
||||||
{
|
|
||||||
sface = losortPtr[face];
|
|
||||||
wTPtr[lPtr[sface]] -=
|
|
||||||
dot(rDPtr[lPtr[sface]], dot(lowerPtr[sface], wTPtr[uPtr[sface]]));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
|
||||||
@ -1,127 +0,0 @@
|
|||||||
/*---------------------------------------------------------------------------*\
|
|
||||||
========= |
|
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
|
||||||
\\ / O peration |
|
|
||||||
\\ / A nd | Copyright (C) 1991-2007 OpenCFD Ltd.
|
|
||||||
\\/ M anipulation |
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
License
|
|
||||||
This file is part of OpenFOAM.
|
|
||||||
|
|
||||||
OpenFOAM is free software; you can redistribute it and/or modify it
|
|
||||||
under the terms of the GNU General Public License as published by the
|
|
||||||
Free Software Foundation; either version 2 of the License, or (at your
|
|
||||||
option) any later version.
|
|
||||||
|
|
||||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
|
||||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
||||||
for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with OpenFOAM; if not, write to the Free Software Foundation,
|
|
||||||
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
|
|
||||||
Class
|
|
||||||
Foam::TDILUPreconditioner
|
|
||||||
|
|
||||||
Description
|
|
||||||
Simplified diagonal-based incomplete LU preconditioner for asymmetric
|
|
||||||
matrices.
|
|
||||||
|
|
||||||
The inverse (reciprocal for scalar) of the preconditioned diagonal is
|
|
||||||
calculated and stored.
|
|
||||||
|
|
||||||
SourceFiles
|
|
||||||
TDILUPreconditioner.C
|
|
||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
#ifndef TDILUPreconditioner_H
|
|
||||||
#define TDILUPreconditioner_H
|
|
||||||
|
|
||||||
#include "LduMatrix.H"
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
namespace Foam
|
|
||||||
{
|
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*\
|
|
||||||
Class TDILUPreconditioner Declaration
|
|
||||||
\*---------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
template<class Type, class DType, class LUType>
|
|
||||||
class TDILUPreconditioner
|
|
||||||
:
|
|
||||||
public LduMatrix<Type, DType, LUType>::preconditioner
|
|
||||||
{
|
|
||||||
// Private data
|
|
||||||
|
|
||||||
//- The inverse (reciprocal for scalar) preconditioned diagonal
|
|
||||||
Field<DType> rD_;
|
|
||||||
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
//- Runtime type information
|
|
||||||
TypeName("DILU");
|
|
||||||
|
|
||||||
|
|
||||||
// Constructors
|
|
||||||
|
|
||||||
//- Construct from matrix components and preconditioner data dictionary
|
|
||||||
TDILUPreconditioner
|
|
||||||
(
|
|
||||||
const typename LduMatrix<Type, DType, LUType>::solver& sol,
|
|
||||||
const dictionary& preconditionerDict
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
// Destructor
|
|
||||||
|
|
||||||
virtual ~TDILUPreconditioner()
|
|
||||||
{}
|
|
||||||
|
|
||||||
|
|
||||||
// Member Functions
|
|
||||||
|
|
||||||
//- Calculate the reciprocal of the preconditioned diagonal
|
|
||||||
static void calcInvD
|
|
||||||
(
|
|
||||||
Field<DType>& rD,
|
|
||||||
const LduMatrix<Type, DType, LUType>& matrix
|
|
||||||
);
|
|
||||||
|
|
||||||
//- Return wA the preconditioned form of residual rA
|
|
||||||
virtual void precondition
|
|
||||||
(
|
|
||||||
Field<Type>& wA,
|
|
||||||
const Field<Type>& rA
|
|
||||||
) const;
|
|
||||||
|
|
||||||
//- Return wT the transpose-matrix preconditioned form of
|
|
||||||
// residual rT.
|
|
||||||
virtual void preconditionT
|
|
||||||
(
|
|
||||||
Field<Type>& wT,
|
|
||||||
const Field<Type>& rT
|
|
||||||
) const;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
} // End namespace Foam
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
#ifdef NoRepository
|
|
||||||
# include "TDILUPreconditioner.C"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
|
||||||
@ -1,81 +0,0 @@
|
|||||||
/*---------------------------------------------------------------------------*\
|
|
||||||
========= |
|
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
|
||||||
\\ / O peration |
|
|
||||||
\\ / A nd | Copyright (C) 1991-2007 OpenCFD Ltd.
|
|
||||||
\\/ M anipulation |
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
License
|
|
||||||
This file is part of OpenFOAM.
|
|
||||||
|
|
||||||
OpenFOAM is free software; you can redistribute it and/or modify it
|
|
||||||
under the terms of the GNU General Public License as published by the
|
|
||||||
Free Software Foundation; either version 2 of the License, or (at your
|
|
||||||
option) any later version.
|
|
||||||
|
|
||||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
|
||||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
||||||
for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with OpenFOAM; if not, write to the Free Software Foundation,
|
|
||||||
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
#include "DiagonalPreconditioner.H"
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
template<class Type, class DType, class LUType>
|
|
||||||
Foam::DiagonalPreconditioner<Type, DType, LUType>::DiagonalPreconditioner
|
|
||||||
(
|
|
||||||
const typename LduMatrix<Type, DType, LUType>::solver& sol,
|
|
||||||
const dictionary&
|
|
||||||
)
|
|
||||||
:
|
|
||||||
LduMatrix<Type, DType, LUType>::preconditioner(sol),
|
|
||||||
rD(sol.matrix().diag().size())
|
|
||||||
{
|
|
||||||
DType* __restrict__ rDPtr = rD.begin();
|
|
||||||
const DType* __restrict__ DPtr = this->solver_.matrix().diag().begin();
|
|
||||||
|
|
||||||
register label nCells = rD.size();
|
|
||||||
|
|
||||||
// Generate inverse (reciprocal for scalar) diagonal
|
|
||||||
for (register label cell=0; cell<nCells; cell++)
|
|
||||||
{
|
|
||||||
rDPtr[cell] = inv(DPtr[cell]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
template<class Type, class DType, class LUType>
|
|
||||||
void Foam::DiagonalPreconditioner<Type, DType, LUType>::read(const dictionary&)
|
|
||||||
{}
|
|
||||||
|
|
||||||
|
|
||||||
template<class Type, class DType, class LUType>
|
|
||||||
void Foam::DiagonalPreconditioner<Type, DType, LUType>::precondition
|
|
||||||
(
|
|
||||||
Field<Type>& wA,
|
|
||||||
const Field<Type>& rA
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
Type* __restrict__ wAPtr = wA.begin();
|
|
||||||
const Type* __restrict__ rAPtr = rA.begin();
|
|
||||||
const DType* __restrict__ rDPtr = rD.begin();
|
|
||||||
|
|
||||||
register label nCells = wA.size();
|
|
||||||
|
|
||||||
for (register label cell=0; cell<nCells; cell++)
|
|
||||||
{
|
|
||||||
wAPtr[cell] = dot(rDPtr[cell], rAPtr[cell]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
|
||||||
@ -1,135 +0,0 @@
|
|||||||
/*---------------------------------------------------------------------------*\
|
|
||||||
========= |
|
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
|
||||||
\\ / O peration |
|
|
||||||
\\ / A nd | Copyright (C) 1991-2007 OpenCFD Ltd.
|
|
||||||
\\/ M anipulation |
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
License
|
|
||||||
This file is part of OpenFOAM.
|
|
||||||
|
|
||||||
OpenFOAM is free software; you can redistribute it and/or modify it
|
|
||||||
under the terms of the GNU General Public License as published by the
|
|
||||||
Free Software Foundation; either version 2 of the License, or (at your
|
|
||||||
option) any later version.
|
|
||||||
|
|
||||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
|
||||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
||||||
for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with OpenFOAM; if not, write to the Free Software Foundation,
|
|
||||||
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
|
|
||||||
Class
|
|
||||||
Foam::DiagonalPreconditioner
|
|
||||||
|
|
||||||
Description
|
|
||||||
Diagonal preconditioner for both symmetric and asymmetric matrices.
|
|
||||||
|
|
||||||
The inverse (reciprocal for scalar) of the diagonal is calculated and
|
|
||||||
stored.
|
|
||||||
|
|
||||||
SourceFiles
|
|
||||||
DiagonalPreconditioner.C
|
|
||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
#ifndef DiagonalPreconditioner_H
|
|
||||||
#define DiagonalPreconditioner_H
|
|
||||||
|
|
||||||
#include "LduMatrix.H"
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
namespace Foam
|
|
||||||
{
|
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*\
|
|
||||||
Class DiagonalPreconditioner Declaration
|
|
||||||
\*---------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
template<class Type, class DType, class LUType>
|
|
||||||
class DiagonalPreconditioner
|
|
||||||
:
|
|
||||||
public LduMatrix<Type, DType, LUType>::preconditioner
|
|
||||||
{
|
|
||||||
// Private data
|
|
||||||
|
|
||||||
//- The inverse (reciprocal for scalar) diagonal
|
|
||||||
Field<DType> rD;
|
|
||||||
|
|
||||||
|
|
||||||
// Private Member Functions
|
|
||||||
|
|
||||||
//- Disallow default bitwise copy construct
|
|
||||||
DiagonalPreconditioner(const DiagonalPreconditioner&);
|
|
||||||
|
|
||||||
//- Disallow default bitwise assignment
|
|
||||||
void operator=(const DiagonalPreconditioner&);
|
|
||||||
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
//- Runtime type information
|
|
||||||
TypeName("diagonal");
|
|
||||||
|
|
||||||
|
|
||||||
// Constructors
|
|
||||||
|
|
||||||
//- Construct from matrix components and preconditioner data dictionary
|
|
||||||
DiagonalPreconditioner
|
|
||||||
(
|
|
||||||
const typename LduMatrix<Type, DType, LUType>::solver& sol,
|
|
||||||
const dictionary& preconditionerDict
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
// Destructor
|
|
||||||
|
|
||||||
virtual ~DiagonalPreconditioner()
|
|
||||||
{}
|
|
||||||
|
|
||||||
|
|
||||||
// Member Functions
|
|
||||||
|
|
||||||
//- Read and reset the preconditioner parameters from the given
|
|
||||||
// dictionary
|
|
||||||
virtual void read(const dictionary& preconditionerDict);
|
|
||||||
|
|
||||||
//- Return wA the preconditioned form of residual rA
|
|
||||||
virtual void precondition
|
|
||||||
(
|
|
||||||
Field<Type>& wA,
|
|
||||||
const Field<Type>& rA
|
|
||||||
) const;
|
|
||||||
|
|
||||||
//- Return wT the transpose-matrix preconditioned form of
|
|
||||||
// residual rT.
|
|
||||||
virtual void preconditionT
|
|
||||||
(
|
|
||||||
Field<Type>& wT,
|
|
||||||
const Field<Type>& rT
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
return(precondition(wT, rT));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
} // End namespace Foam
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
#ifdef NoRepository
|
|
||||||
# include "DiagonalPreconditioner.C"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
|
||||||
@ -1,60 +0,0 @@
|
|||||||
/*---------------------------------------------------------------------------*\
|
|
||||||
========= |
|
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
|
||||||
\\ / O peration |
|
|
||||||
\\ / A nd | Copyright (C) 1991-2007 OpenCFD Ltd.
|
|
||||||
\\/ M anipulation |
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
License
|
|
||||||
This file is part of OpenFOAM.
|
|
||||||
|
|
||||||
OpenFOAM is free software; you can redistribute it and/or modify it
|
|
||||||
under the terms of the GNU General Public License as published by the
|
|
||||||
Free Software Foundation; either version 2 of the License, or (at your
|
|
||||||
option) any later version.
|
|
||||||
|
|
||||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
|
||||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
||||||
for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with OpenFOAM; if not, write to the Free Software Foundation,
|
|
||||||
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
#include "NoPreconditioner.H"
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
template<class Type, class DType, class LUType>
|
|
||||||
Foam::NoPreconditioner<Type, DType, LUType>::NoPreconditioner
|
|
||||||
(
|
|
||||||
const typename LduMatrix<Type, DType, LUType>::solver& sol,
|
|
||||||
const dictionary&
|
|
||||||
)
|
|
||||||
:
|
|
||||||
LduMatrix<Type, DType, LUType>::preconditioner(sol)
|
|
||||||
{}
|
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
template<class Type, class DType, class LUType>
|
|
||||||
void Foam::NoPreconditioner<Type, DType, LUType>::read(const dictionary&)
|
|
||||||
{}
|
|
||||||
|
|
||||||
|
|
||||||
template<class Type, class DType, class LUType>
|
|
||||||
void Foam::NoPreconditioner<Type, DType, LUType>::precondition
|
|
||||||
(
|
|
||||||
Field<Type>& wA,
|
|
||||||
const Field<Type>& rA
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
wA = rA;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
|
||||||
@ -1,126 +0,0 @@
|
|||||||
/*---------------------------------------------------------------------------*\
|
|
||||||
========= |
|
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
|
||||||
\\ / O peration |
|
|
||||||
\\ / A nd | Copyright (C) 1991-2007 OpenCFD Ltd.
|
|
||||||
\\/ M anipulation |
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
License
|
|
||||||
This file is part of OpenFOAM.
|
|
||||||
|
|
||||||
OpenFOAM is free software; you can redistribute it and/or modify it
|
|
||||||
under the terms of the GNU General Public License as published by the
|
|
||||||
Free Software Foundation; either version 2 of the License, or (at your
|
|
||||||
option) any later version.
|
|
||||||
|
|
||||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
|
||||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
||||||
for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with OpenFOAM; if not, write to the Free Software Foundation,
|
|
||||||
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
|
|
||||||
Class
|
|
||||||
Foam::NoPreconditioner
|
|
||||||
|
|
||||||
Description
|
|
||||||
Null preconditioner for both symmetric and asymmetric matrices.
|
|
||||||
|
|
||||||
SourceFiles
|
|
||||||
NoPreconditioner.C
|
|
||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
#ifndef NoPreconditioner_H
|
|
||||||
#define NoPreconditioner_H
|
|
||||||
|
|
||||||
#include "LduMatrix.H"
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
namespace Foam
|
|
||||||
{
|
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*\
|
|
||||||
Class NoPreconditioner Declaration
|
|
||||||
\*---------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
template<class Type, class DType, class LUType>
|
|
||||||
class NoPreconditioner
|
|
||||||
:
|
|
||||||
public LduMatrix<Type, DType, LUType>::preconditioner
|
|
||||||
{
|
|
||||||
// Private Member Functions
|
|
||||||
|
|
||||||
//- Disallow default bitwise copy construct
|
|
||||||
NoPreconditioner(const NoPreconditioner&);
|
|
||||||
|
|
||||||
//- Disallow default bitwise assignment
|
|
||||||
void operator=(const NoPreconditioner&);
|
|
||||||
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
//- Runtime type information
|
|
||||||
TypeName("none");
|
|
||||||
|
|
||||||
|
|
||||||
// Constructors
|
|
||||||
|
|
||||||
//- Construct from matrix components and preconditioner data dictionary
|
|
||||||
NoPreconditioner
|
|
||||||
(
|
|
||||||
const typename LduMatrix<Type, DType, LUType>::solver& sol,
|
|
||||||
const dictionary& preconditionerDict
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
// Destructor
|
|
||||||
|
|
||||||
virtual ~NoPreconditioner()
|
|
||||||
{}
|
|
||||||
|
|
||||||
|
|
||||||
// Member Functions
|
|
||||||
|
|
||||||
//- Read and reset the preconditioner parameters from the given
|
|
||||||
// dictionary
|
|
||||||
virtual void read(const dictionary& preconditionerDict);
|
|
||||||
|
|
||||||
//- Return wA the preconditioned form of residual rA
|
|
||||||
virtual void precondition
|
|
||||||
(
|
|
||||||
Field<Type>& wA,
|
|
||||||
const Field<Type>& rA
|
|
||||||
) const;
|
|
||||||
|
|
||||||
//- Return wT the transpose-matrix preconditioned form of
|
|
||||||
// residual rT.
|
|
||||||
virtual void preconditionT
|
|
||||||
(
|
|
||||||
Field<Type>& wT,
|
|
||||||
const Field<Type>& rT
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
return(precondition(wT, rT));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
} // End namespace Foam
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
#ifdef NoRepository
|
|
||||||
# include "NoPreconditioner.C"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
|
||||||
@ -1,26 +0,0 @@
|
|||||||
#include "NoPreconditioner.H"
|
|
||||||
#include "DiagonalPreconditioner.H"
|
|
||||||
#include "TDILUPreconditioner.H"
|
|
||||||
#include "fieldTypes.H"
|
|
||||||
|
|
||||||
#define makeLduPreconditioners(Type, DType, LUType) \
|
|
||||||
\
|
|
||||||
makeLduPreconditioner(NoPreconditioner, Type, DType, LUType); \
|
|
||||||
makeLduSymPreconditioner(NoPreconditioner, Type, DType, LUType); \
|
|
||||||
makeLduAsymPreconditioner(NoPreconditioner, Type, DType, LUType); \
|
|
||||||
\
|
|
||||||
makeLduPreconditioner(DiagonalPreconditioner, Type, DType, LUType); \
|
|
||||||
makeLduSymPreconditioner(DiagonalPreconditioner, Type, DType, LUType); \
|
|
||||||
makeLduAsymPreconditioner(DiagonalPreconditioner, Type, DType, LUType); \
|
|
||||||
\
|
|
||||||
makeLduPreconditioner(TDILUPreconditioner, Type, DType, LUType); \
|
|
||||||
makeLduAsymPreconditioner(TDILUPreconditioner, Type, DType, LUType);
|
|
||||||
|
|
||||||
namespace Foam
|
|
||||||
{
|
|
||||||
makeLduPreconditioners(scalar, scalar, scalar);
|
|
||||||
makeLduPreconditioners(vector, scalar, scalar);
|
|
||||||
makeLduPreconditioners(sphericalTensor, scalar, scalar);
|
|
||||||
makeLduPreconditioners(symmTensor, scalar, scalar);
|
|
||||||
makeLduPreconditioners(tensor, scalar, scalar);
|
|
||||||
};
|
|
||||||
@ -1,168 +0,0 @@
|
|||||||
/*---------------------------------------------------------------------------*\
|
|
||||||
========= |
|
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
|
||||||
\\ / O peration |
|
|
||||||
\\ / A nd | Copyright (C) 1991-2007 OpenCFD Ltd.
|
|
||||||
\\/ M anipulation |
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
License
|
|
||||||
This file is part of OpenFOAM.
|
|
||||||
|
|
||||||
OpenFOAM is free software; you can redistribute it and/or modify it
|
|
||||||
under the terms of the GNU General Public License as published by the
|
|
||||||
Free Software Foundation; either version 2 of the License, or (at your
|
|
||||||
option) any later version.
|
|
||||||
|
|
||||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
|
||||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
||||||
for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with OpenFOAM; if not, write to the Free Software Foundation,
|
|
||||||
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
#include "TGaussSeidelSmoother.H"
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
template<class Type, class DType, class LUType>
|
|
||||||
Foam::TGaussSeidelSmoother<Type, DType, LUType>::TGaussSeidelSmoother
|
|
||||||
(
|
|
||||||
const word& fieldName,
|
|
||||||
const LduMatrix<Type, DType, LUType>& matrix
|
|
||||||
)
|
|
||||||
:
|
|
||||||
LduMatrix<Type, DType, LUType>::smoother
|
|
||||||
(
|
|
||||||
fieldName,
|
|
||||||
matrix
|
|
||||||
),
|
|
||||||
rD_(matrix.diag().size())
|
|
||||||
{
|
|
||||||
register const label nCells = matrix.diag().size();
|
|
||||||
register const DType* const __restrict__ diagPtr = matrix.diag().begin();
|
|
||||||
register DType* __restrict__ rDPtr = rD_.begin();
|
|
||||||
|
|
||||||
for (register label cellI=0; cellI<nCells; cellI++)
|
|
||||||
{
|
|
||||||
rDPtr[cellI] = inv(diagPtr[cellI]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
template<class Type, class DType, class LUType>
|
|
||||||
void Foam::TGaussSeidelSmoother<Type, DType, LUType>::smooth
|
|
||||||
(
|
|
||||||
const word& fieldName_,
|
|
||||||
Field<Type>& psi,
|
|
||||||
const LduMatrix<Type, DType, LUType>& matrix_,
|
|
||||||
const Field<DType>& rD_,
|
|
||||||
const label nSweeps
|
|
||||||
)
|
|
||||||
{
|
|
||||||
register Type* __restrict__ psiPtr = psi.begin();
|
|
||||||
|
|
||||||
register const label nCells = psi.size();
|
|
||||||
|
|
||||||
Field<Type> bPrime(nCells);
|
|
||||||
register Type* __restrict__ bPrimePtr = bPrime.begin();
|
|
||||||
|
|
||||||
register const DType* const __restrict__ rDPtr = rD_.begin();
|
|
||||||
|
|
||||||
register const LUType* const __restrict__ upperPtr =
|
|
||||||
matrix_.upper().begin();
|
|
||||||
|
|
||||||
register const LUType* const __restrict__ lowerPtr =
|
|
||||||
matrix_.lower().begin();
|
|
||||||
|
|
||||||
register const label* const __restrict__ uPtr =
|
|
||||||
matrix_.lduAddr().upperAddr().begin();
|
|
||||||
|
|
||||||
register const label* const __restrict__ ownStartPtr =
|
|
||||||
matrix_.lduAddr().ownerStartAddr().begin();
|
|
||||||
|
|
||||||
|
|
||||||
// Parallel boundary initialisation. The parallel boundary is treated
|
|
||||||
// as an effective jacobi interface in the boundary.
|
|
||||||
// Note: there is a change of sign in the coupled
|
|
||||||
// interface update to add the contibution to the r.h.s.
|
|
||||||
|
|
||||||
FieldField<Field, LUType> mBouCoeffs(matrix_.interfacesUpper().size());
|
|
||||||
|
|
||||||
forAll(mBouCoeffs, patchi)
|
|
||||||
{
|
|
||||||
if (matrix_.interfaces().set(patchi))
|
|
||||||
{
|
|
||||||
mBouCoeffs.set(patchi, -matrix_.interfacesUpper()[patchi]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (label sweep=0; sweep<nSweeps; sweep++)
|
|
||||||
{
|
|
||||||
bPrime = matrix_.source();
|
|
||||||
|
|
||||||
matrix_.initMatrixInterfaces
|
|
||||||
(
|
|
||||||
mBouCoeffs,
|
|
||||||
psi,
|
|
||||||
bPrime
|
|
||||||
);
|
|
||||||
|
|
||||||
matrix_.updateMatrixInterfaces
|
|
||||||
(
|
|
||||||
mBouCoeffs,
|
|
||||||
psi,
|
|
||||||
bPrime
|
|
||||||
);
|
|
||||||
|
|
||||||
Type curPsi;
|
|
||||||
register label fStart;
|
|
||||||
register label fEnd = ownStartPtr[0];
|
|
||||||
|
|
||||||
for (register label cellI=0; cellI<nCells; cellI++)
|
|
||||||
{
|
|
||||||
// Start and end of this row
|
|
||||||
fStart = fEnd;
|
|
||||||
fEnd = ownStartPtr[cellI + 1];
|
|
||||||
|
|
||||||
// Get the accumulated neighbour side
|
|
||||||
curPsi = bPrimePtr[cellI];
|
|
||||||
|
|
||||||
// Accumulate the owner product side
|
|
||||||
for (register label curFace=fStart; curFace<fEnd; curFace++)
|
|
||||||
{
|
|
||||||
curPsi -= dot(upperPtr[curFace], psiPtr[uPtr[curFace]]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Finish current psi
|
|
||||||
curPsi = dot(rDPtr[cellI], curPsi);
|
|
||||||
|
|
||||||
// Distribute the neighbour side using current psi
|
|
||||||
for (register label curFace=fStart; curFace<fEnd; curFace++)
|
|
||||||
{
|
|
||||||
bPrimePtr[uPtr[curFace]] -= dot(lowerPtr[curFace], curPsi);
|
|
||||||
}
|
|
||||||
|
|
||||||
psiPtr[cellI] = curPsi;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template<class Type, class DType, class LUType>
|
|
||||||
void Foam::TGaussSeidelSmoother<Type, DType, LUType>::smooth
|
|
||||||
(
|
|
||||||
Field<Type>& psi,
|
|
||||||
const label nSweeps
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
smooth(this->fieldName_, psi, this->matrix_, rD_, nSweeps);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
|
||||||
@ -1,113 +0,0 @@
|
|||||||
/*---------------------------------------------------------------------------*\
|
|
||||||
========= |
|
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
|
||||||
\\ / O peration |
|
|
||||||
\\ / A nd | Copyright (C) 1991-2007 OpenCFD Ltd.
|
|
||||||
\\/ M anipulation |
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
License
|
|
||||||
This file is part of OpenFOAM.
|
|
||||||
|
|
||||||
OpenFOAM is free software; you can redistribute it and/or modify it
|
|
||||||
under the terms of the GNU General Public License as published by the
|
|
||||||
Free Software Foundation; either version 2 of the License, or (at your
|
|
||||||
option) any later version.
|
|
||||||
|
|
||||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
|
||||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
||||||
for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with OpenFOAM; if not, write to the Free Software Foundation,
|
|
||||||
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
|
|
||||||
Class
|
|
||||||
Foam::TGaussSeidelSmoother
|
|
||||||
|
|
||||||
Description
|
|
||||||
Foam::TGaussSeidelSmoother
|
|
||||||
|
|
||||||
SourceFiles
|
|
||||||
TGaussSeidelSmoother.C
|
|
||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
#ifndef TGaussSeidelSmoother_H
|
|
||||||
#define TGaussSeidelSmoother_H
|
|
||||||
|
|
||||||
#include "LduMatrix.H"
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
namespace Foam
|
|
||||||
{
|
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*\
|
|
||||||
Class TGaussSeidelSmoother Declaration
|
|
||||||
\*---------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
template<class Type, class DType, class LUType>
|
|
||||||
class TGaussSeidelSmoother
|
|
||||||
:
|
|
||||||
public LduMatrix<Type, DType, LUType>::smoother
|
|
||||||
{
|
|
||||||
// Private data
|
|
||||||
|
|
||||||
//- The inverse (reciprocal for scalars) diagonal
|
|
||||||
Field<DType> rD_;
|
|
||||||
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
//- Runtime type information
|
|
||||||
TypeName("GaussSeidel");
|
|
||||||
|
|
||||||
|
|
||||||
// Constructors
|
|
||||||
|
|
||||||
//- Construct from components
|
|
||||||
TGaussSeidelSmoother
|
|
||||||
(
|
|
||||||
const word& fieldName,
|
|
||||||
const LduMatrix<Type, DType, LUType>& matrix
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
// Member Functions
|
|
||||||
|
|
||||||
//- Smooth for the given number of sweeps
|
|
||||||
static void smooth
|
|
||||||
(
|
|
||||||
const word& fieldName,
|
|
||||||
Field<Type>& psi,
|
|
||||||
const LduMatrix<Type, DType, LUType>& matrix,
|
|
||||||
const Field<DType>& rD,
|
|
||||||
const label nSweeps
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
//- Smooth the solution for a given number of sweeps
|
|
||||||
virtual void smooth
|
|
||||||
(
|
|
||||||
Field<Type>& psi,
|
|
||||||
const label nSweeps
|
|
||||||
) const;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
} // End namespace Foam
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
#ifdef NoRepository
|
|
||||||
# include "TGaussSeidelSmoother.C"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
|
||||||
@ -1,17 +0,0 @@
|
|||||||
#include "TGaussSeidelSmoother.H"
|
|
||||||
#include "fieldTypes.H"
|
|
||||||
|
|
||||||
#define makeLduSmoothers(Type, DType, LUType) \
|
|
||||||
\
|
|
||||||
makeLduSmoother(TGaussSeidelSmoother, Type, DType, LUType); \
|
|
||||||
makeLduSymSmoother(TGaussSeidelSmoother, Type, DType, LUType); \
|
|
||||||
makeLduAsymSmoother(TGaussSeidelSmoother, Type, DType, LUType);
|
|
||||||
|
|
||||||
namespace Foam
|
|
||||||
{
|
|
||||||
makeLduSmoothers(scalar, scalar, scalar);
|
|
||||||
makeLduSmoothers(vector, scalar, scalar);
|
|
||||||
makeLduSmoothers(sphericalTensor, scalar, scalar);
|
|
||||||
makeLduSmoothers(symmTensor, scalar, scalar);
|
|
||||||
makeLduSmoothers(tensor, scalar, scalar);
|
|
||||||
};
|
|
||||||
@ -1,80 +0,0 @@
|
|||||||
/*---------------------------------------------------------------------------*\
|
|
||||||
========= |
|
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
|
||||||
\\ / O peration |
|
|
||||||
\\ / A nd | Copyright (C) 1991-2007 OpenCFD Ltd.
|
|
||||||
\\/ M anipulation |
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
License
|
|
||||||
This file is part of OpenFOAM.
|
|
||||||
|
|
||||||
OpenFOAM is free software; you can redistribute it and/or modify it
|
|
||||||
under the terms of the GNU General Public License as published by the
|
|
||||||
Free Software Foundation; either version 2 of the License, or (at your
|
|
||||||
option) any later version.
|
|
||||||
|
|
||||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
|
||||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
||||||
for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with OpenFOAM; if not, write to the Free Software Foundation,
|
|
||||||
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
#include "DiagonalSolver.H"
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
template<class Type, class DType, class LUType>
|
|
||||||
Foam::DiagonalSolver<Type, DType, LUType>::DiagonalSolver
|
|
||||||
(
|
|
||||||
const word& fieldName,
|
|
||||||
const LduMatrix<Type, DType, LUType>& matrix,
|
|
||||||
const dictionary& solverDict
|
|
||||||
)
|
|
||||||
:
|
|
||||||
LduMatrix<Type, DType, LUType>::solver
|
|
||||||
(
|
|
||||||
fieldName,
|
|
||||||
matrix,
|
|
||||||
solverDict
|
|
||||||
)
|
|
||||||
{}
|
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
template<class Type, class DType, class LUType>
|
|
||||||
void Foam::DiagonalSolver<Type, DType, LUType>::read
|
|
||||||
(
|
|
||||||
const dictionary&
|
|
||||||
)
|
|
||||||
{}
|
|
||||||
|
|
||||||
|
|
||||||
template<class Type, class DType, class LUType>
|
|
||||||
typename Foam::LduMatrix<Type, DType, LUType>::solverPerformance
|
|
||||||
Foam::DiagonalSolver<Type, DType, LUType>::solve
|
|
||||||
(
|
|
||||||
Field<Type>& psi
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
psi = this->matrix_.source()/this->matrix_.diag();
|
|
||||||
|
|
||||||
return typename LduMatrix<Type, DType, LUType>::solverPerformance
|
|
||||||
(
|
|
||||||
typeName,
|
|
||||||
this->fieldName_,
|
|
||||||
pTraits<Type>::zero,
|
|
||||||
pTraits<Type>::zero,
|
|
||||||
0,
|
|
||||||
true,
|
|
||||||
false
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
|
||||||
@ -1,108 +0,0 @@
|
|||||||
/*---------------------------------------------------------------------------*\
|
|
||||||
========= |
|
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
|
||||||
\\ / O peration |
|
|
||||||
\\ / A nd | Copyright (C) 1991-2007 OpenCFD Ltd.
|
|
||||||
\\/ M anipulation |
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
License
|
|
||||||
This file is part of OpenFOAM.
|
|
||||||
|
|
||||||
OpenFOAM is free software; you can redistribute it and/or modify it
|
|
||||||
under the terms of the GNU General Public License as published by the
|
|
||||||
Free Software Foundation; either version 2 of the License, or (at your
|
|
||||||
option) any later version.
|
|
||||||
|
|
||||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
|
||||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
||||||
for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with OpenFOAM; if not, write to the Free Software Foundation,
|
|
||||||
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
|
|
||||||
Class
|
|
||||||
Foam::DiagonalSolver
|
|
||||||
|
|
||||||
Description
|
|
||||||
Foam::DiagonalSolver
|
|
||||||
|
|
||||||
SourceFiles
|
|
||||||
DiagonalSolver.C
|
|
||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
#ifndef DiagonalSolver_H
|
|
||||||
#define DiagonalSolver_H
|
|
||||||
|
|
||||||
#include "LduMatrix.H"
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
namespace Foam
|
|
||||||
{
|
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*\
|
|
||||||
Class DiagonalSolver Declaration
|
|
||||||
\*---------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
template<class Type, class DType, class LUType>
|
|
||||||
class DiagonalSolver
|
|
||||||
:
|
|
||||||
public LduMatrix<Type, DType, LUType>::solver
|
|
||||||
{
|
|
||||||
// Private Member Functions
|
|
||||||
|
|
||||||
//- Disallow default bitwise copy construct
|
|
||||||
DiagonalSolver(const DiagonalSolver&);
|
|
||||||
|
|
||||||
//- Disallow default bitwise assignment
|
|
||||||
void operator=(const DiagonalSolver&);
|
|
||||||
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
//- Runtime type information
|
|
||||||
TypeName("diagonal");
|
|
||||||
|
|
||||||
|
|
||||||
// Constructors
|
|
||||||
|
|
||||||
//- Construct from matrix
|
|
||||||
DiagonalSolver
|
|
||||||
(
|
|
||||||
const word& fieldName,
|
|
||||||
const LduMatrix<Type, DType, LUType>& matrix,
|
|
||||||
const dictionary& solverDict
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
// Member Functions
|
|
||||||
|
|
||||||
//- Read and reset the solver parameters from the given dictionary
|
|
||||||
void read(const dictionary& solverDict);
|
|
||||||
|
|
||||||
//- Solve the matrix with this solver
|
|
||||||
typename LduMatrix<Type, DType, LUType>::solverPerformance solve
|
|
||||||
(
|
|
||||||
Field<Type>& psi
|
|
||||||
) const;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
} // End namespace Foam
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
#ifdef NoRepository
|
|
||||||
# include "DiagonalSolver.C"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
|
||||||
@ -1,195 +0,0 @@
|
|||||||
/*---------------------------------------------------------------------------*\
|
|
||||||
========= |
|
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
|
||||||
\\ / O peration |
|
|
||||||
\\ / A nd | Copyright (C) 1991-2007 OpenCFD Ltd.
|
|
||||||
\\/ M anipulation |
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
License
|
|
||||||
This file is part of OpenFOAM.
|
|
||||||
|
|
||||||
OpenFOAM is free software; you can redistribute it and/or modify it
|
|
||||||
under the terms of the GNU General Public License as published by the
|
|
||||||
Free Software Foundation; either version 2 of the License, or (at your
|
|
||||||
option) any later version.
|
|
||||||
|
|
||||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
|
||||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
||||||
for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with OpenFOAM; if not, write to the Free Software Foundation,
|
|
||||||
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
#include "TPBiCG.H"
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
template<class Type, class DType, class LUType>
|
|
||||||
Foam::TPBiCG<Type, DType, LUType>::TPBiCG
|
|
||||||
(
|
|
||||||
const word& fieldName,
|
|
||||||
const LduMatrix<Type, DType, LUType>& matrix,
|
|
||||||
const dictionary& solverDict
|
|
||||||
)
|
|
||||||
:
|
|
||||||
LduMatrix<Type, DType, LUType>::solver
|
|
||||||
(
|
|
||||||
fieldName,
|
|
||||||
matrix,
|
|
||||||
solverDict
|
|
||||||
)
|
|
||||||
{}
|
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
template<class Type, class DType, class LUType>
|
|
||||||
typename Foam::LduMatrix<Type, DType, LUType>::solverPerformance
|
|
||||||
Foam::TPBiCG<Type, DType, LUType>::solve(Field<Type>& psi) const
|
|
||||||
{
|
|
||||||
word preconditionerName(this->controlDict_.lookup("preconditioner"));
|
|
||||||
|
|
||||||
// --- Setup class containing solver performance data
|
|
||||||
typename LduMatrix<Type, DType, LUType>::solverPerformance solverPerf
|
|
||||||
(
|
|
||||||
preconditionerName + typeName,
|
|
||||||
this->fieldName_
|
|
||||||
);
|
|
||||||
|
|
||||||
register label nCells = psi.size();
|
|
||||||
|
|
||||||
Type* __restrict__ psiPtr = psi.begin();
|
|
||||||
|
|
||||||
Field<Type> pA(nCells);
|
|
||||||
Type* __restrict__ pAPtr = pA.begin();
|
|
||||||
|
|
||||||
Field<Type> pT(nCells, pTraits<Type>::zero);
|
|
||||||
Type* __restrict__ pTPtr = pT.begin();
|
|
||||||
|
|
||||||
Field<Type> wA(nCells);
|
|
||||||
Type* __restrict__ wAPtr = wA.begin();
|
|
||||||
|
|
||||||
Field<Type> wT(nCells);
|
|
||||||
Type* __restrict__ wTPtr = wT.begin();
|
|
||||||
|
|
||||||
Type wArT = this->matrix_.great_*pTraits<Type>::one;
|
|
||||||
Type wArTold = wArT;
|
|
||||||
|
|
||||||
// --- Calculate A.psi and T.psi
|
|
||||||
this->matrix_.Amul(wA, psi);
|
|
||||||
this->matrix_.Tmul(wT, psi);
|
|
||||||
|
|
||||||
// --- Calculate initial residual and transpose residual fields
|
|
||||||
Field<Type> rA(this->matrix_.source() - wA);
|
|
||||||
Field<Type> rT(this->matrix_.source() - wT);
|
|
||||||
Type* __restrict__ rAPtr = rA.begin();
|
|
||||||
Type* __restrict__ rTPtr = rT.begin();
|
|
||||||
|
|
||||||
// --- Calculate normalisation factor
|
|
||||||
Type normFactor = this->normFactor(psi, wA, pA);
|
|
||||||
|
|
||||||
if (LduMatrix<Type, DType, LUType>::debug >= 2)
|
|
||||||
{
|
|
||||||
Info<< " Normalisation factor = " << normFactor << endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
// --- Calculate normalised residual norm
|
|
||||||
solverPerf.initialResidual() = cmptDivide(gSumCmptMag(rA), normFactor);
|
|
||||||
solverPerf.finalResidual() = solverPerf.initialResidual();
|
|
||||||
|
|
||||||
// --- Check convergence, solve if not converged
|
|
||||||
if (!solverPerf.converged(this->tolerance_, this->relTol_))
|
|
||||||
{
|
|
||||||
// --- Select and construct the preconditioner
|
|
||||||
autoPtr<typename LduMatrix<Type, DType, LUType>::preconditioner>
|
|
||||||
preconPtr = LduMatrix<Type, DType, LUType>::preconditioner::New
|
|
||||||
(
|
|
||||||
*this,
|
|
||||||
this->controlDict_
|
|
||||||
);
|
|
||||||
|
|
||||||
// --- Solver iteration
|
|
||||||
do
|
|
||||||
{
|
|
||||||
// --- Store previous wArT
|
|
||||||
wArTold = wArT;
|
|
||||||
|
|
||||||
// --- Precondition residuals
|
|
||||||
preconPtr->precondition(wA, rA);
|
|
||||||
preconPtr->preconditionT(wT, rT);
|
|
||||||
|
|
||||||
// --- Update search directions:
|
|
||||||
wArT = gSumCmptProd(wA, rT);
|
|
||||||
|
|
||||||
if (solverPerf.nIterations() == 0)
|
|
||||||
{
|
|
||||||
for (register label cell=0; cell<nCells; cell++)
|
|
||||||
{
|
|
||||||
pAPtr[cell] = wAPtr[cell];
|
|
||||||
pTPtr[cell] = wTPtr[cell];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Type beta = cmptDivide
|
|
||||||
(
|
|
||||||
wArT,
|
|
||||||
stabilise(wArTold, this->matrix_.vsmall_)
|
|
||||||
);
|
|
||||||
|
|
||||||
for (register label cell=0; cell<nCells; cell++)
|
|
||||||
{
|
|
||||||
pAPtr[cell] = wAPtr[cell] + cmptMultiply(beta, pAPtr[cell]);
|
|
||||||
pTPtr[cell] = wTPtr[cell] + cmptMultiply(beta, pTPtr[cell]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// --- Update preconditioned residuals
|
|
||||||
this->matrix_.Amul(wA, pA);
|
|
||||||
|
|
||||||
this->matrix_.Tmul(wT, pT);
|
|
||||||
|
|
||||||
Type wApT = gSumCmptProd(wA, pT);
|
|
||||||
|
|
||||||
// --- Test for singularity
|
|
||||||
if (solverPerf.singular(cmptDivide(cmptMag(wApT), normFactor)))
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// --- Update solution and residual:
|
|
||||||
|
|
||||||
Type alpha = cmptDivide
|
|
||||||
(
|
|
||||||
wArT,
|
|
||||||
stabilise(wApT, this->matrix_.vsmall_)
|
|
||||||
);
|
|
||||||
|
|
||||||
for (register label cell=0; cell<nCells; cell++)
|
|
||||||
{
|
|
||||||
psiPtr[cell] += cmptMultiply(alpha, pAPtr[cell]);
|
|
||||||
rAPtr[cell] -= cmptMultiply(alpha, wAPtr[cell]);
|
|
||||||
rTPtr[cell] -= cmptMultiply(alpha, wTPtr[cell]);
|
|
||||||
}
|
|
||||||
|
|
||||||
solverPerf.finalResidual() =
|
|
||||||
cmptDivide(gSumCmptMag(rA), normFactor);
|
|
||||||
|
|
||||||
} while
|
|
||||||
(
|
|
||||||
solverPerf.nIterations()++ < this->maxIter_
|
|
||||||
&& !(solverPerf.converged(this->tolerance_, this->relTol_))
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return solverPerf;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
|
||||||
@ -1,112 +0,0 @@
|
|||||||
/*---------------------------------------------------------------------------*\
|
|
||||||
========= |
|
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
|
||||||
\\ / O peration |
|
|
||||||
\\ / A nd | Copyright (C) 1991-2007 OpenCFD Ltd.
|
|
||||||
\\/ M anipulation |
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
License
|
|
||||||
This file is part of OpenFOAM.
|
|
||||||
|
|
||||||
OpenFOAM is free software; you can redistribute it and/or modify it
|
|
||||||
under the terms of the GNU General Public License as published by the
|
|
||||||
Free Software Foundation; either version 2 of the License, or (at your
|
|
||||||
option) any later version.
|
|
||||||
|
|
||||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
|
||||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
||||||
for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with OpenFOAM; if not, write to the Free Software Foundation,
|
|
||||||
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
|
|
||||||
Class
|
|
||||||
Foam::TPBiCG
|
|
||||||
|
|
||||||
Description
|
|
||||||
Preconditioned bi-conjugate gradient solver for asymmetric lduMatrices
|
|
||||||
using a run-time selectable preconditiioner.
|
|
||||||
|
|
||||||
SourceFiles
|
|
||||||
TPBiCG.C
|
|
||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
#ifndef TPBiCG_H
|
|
||||||
#define TPBiCG_H
|
|
||||||
|
|
||||||
#include "LduMatrix.H"
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
namespace Foam
|
|
||||||
{
|
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*\
|
|
||||||
Class TPBiCG Declaration
|
|
||||||
\*---------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
template<class Type, class DType, class LUType>
|
|
||||||
class TPBiCG
|
|
||||||
:
|
|
||||||
public LduMatrix<Type, DType, LUType>::solver
|
|
||||||
{
|
|
||||||
// Private Member Functions
|
|
||||||
|
|
||||||
//- Disallow default bitwise copy construct
|
|
||||||
TPBiCG(const TPBiCG&);
|
|
||||||
|
|
||||||
//- Disallow default bitwise assignment
|
|
||||||
void operator=(const TPBiCG&);
|
|
||||||
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
//- Runtime type information
|
|
||||||
TypeName("PBiCG");
|
|
||||||
|
|
||||||
|
|
||||||
// Constructors
|
|
||||||
|
|
||||||
//- Construct from matrix components and solver data dictionary
|
|
||||||
TPBiCG
|
|
||||||
(
|
|
||||||
const word& fieldName,
|
|
||||||
const LduMatrix<Type, DType, LUType>& matrix,
|
|
||||||
const dictionary& solverDict
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
// Destructor
|
|
||||||
|
|
||||||
virtual ~TPBiCG()
|
|
||||||
{}
|
|
||||||
|
|
||||||
|
|
||||||
// Member Functions
|
|
||||||
|
|
||||||
//- Solve the matrix with this solver
|
|
||||||
virtual typename LduMatrix<Type, DType, LUType>::solverPerformance solve
|
|
||||||
(
|
|
||||||
Field<Type>& psi
|
|
||||||
) const;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
} // End namespace Foam
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
#ifdef NoRepository
|
|
||||||
# include "TPBiCG.C"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
|
||||||
@ -1,191 +0,0 @@
|
|||||||
/*---------------------------------------------------------------------------*\
|
|
||||||
========= |
|
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
|
||||||
\\ / O peration |
|
|
||||||
\\ / A nd | Copyright (C) 1991-2007 OpenCFD Ltd.
|
|
||||||
\\/ M anipulation |
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
License
|
|
||||||
This file is part of OpenFOAM.
|
|
||||||
|
|
||||||
OpenFOAM is free software; you can redistribute it and/or modify it
|
|
||||||
under the terms of the GNU General Public License as published by the
|
|
||||||
Free Software Foundation; either version 2 of the License, or (at your
|
|
||||||
option) any later version.
|
|
||||||
|
|
||||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
|
||||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
||||||
for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with OpenFOAM; if not, write to the Free Software Foundation,
|
|
||||||
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
#include "TPBiCG.H"
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
template<class Type, class DType, class LUType>
|
|
||||||
Foam::TPBiCG<Type, DType, LUType>::TPBiCG
|
|
||||||
(
|
|
||||||
const word& fieldName,
|
|
||||||
const LduMatrix<Type, DType, LUType>& matrix,
|
|
||||||
const dictionary& solverDict
|
|
||||||
)
|
|
||||||
:
|
|
||||||
LduMatrix<Type, DType, LUType>::solver
|
|
||||||
(
|
|
||||||
fieldName,
|
|
||||||
matrix,
|
|
||||||
solverDict
|
|
||||||
)
|
|
||||||
{}
|
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
template<class Type, class DType, class LUType>
|
|
||||||
typename Foam::LduMatrix<Type, DType, LUType>::solverPerformance
|
|
||||||
Foam::TPBiCG<Type, DType, LUType>::solve
|
|
||||||
(
|
|
||||||
Field<Type>& psi
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
word preconditionerName(this->controlDict_.lookup("preconditioner"));
|
|
||||||
|
|
||||||
// --- Setup class containing solver performance data
|
|
||||||
typename LduMatrix<Type, DType, LUType>::solverPerformance solverPerf
|
|
||||||
(
|
|
||||||
preconditionerName + typeName,
|
|
||||||
this->fieldName_
|
|
||||||
);
|
|
||||||
|
|
||||||
register label nCells = psi.size();
|
|
||||||
|
|
||||||
Type* __restrict__ psiPtr = psi.begin();
|
|
||||||
|
|
||||||
Field<Type> pA(nCells);
|
|
||||||
Type* __restrict__ pAPtr = pA.begin();
|
|
||||||
|
|
||||||
Field<Type> pT(nCells, pTraits<Type>::zero);
|
|
||||||
Type* __restrict__ pTPtr = pT.begin();
|
|
||||||
|
|
||||||
Field<Type> wA(nCells);
|
|
||||||
Type* __restrict__ wAPtr = wA.begin();
|
|
||||||
|
|
||||||
Field<Type> wT(nCells);
|
|
||||||
Type* __restrict__ wTPtr = wT.begin();
|
|
||||||
|
|
||||||
scalar wArT = 1e15; //this->matrix_.great_;
|
|
||||||
scalar wArTold = wArT;
|
|
||||||
|
|
||||||
// --- Calculate A.psi and T.psi
|
|
||||||
this->matrix_.Amul(wA, psi);
|
|
||||||
this->matrix_.Tmul(wT, psi);
|
|
||||||
|
|
||||||
// --- Calculate initial residual and transpose residual fields
|
|
||||||
Field<Type> rA(this->matrix_.source() - wA);
|
|
||||||
Field<Type> rT(this->matrix_.source() - wT);
|
|
||||||
Type* __restrict__ rAPtr = rA.begin();
|
|
||||||
Type* __restrict__ rTPtr = rT.begin();
|
|
||||||
|
|
||||||
// --- Calculate normalisation factor
|
|
||||||
Type normFactor = this->normFactor(psi, wA, pA);
|
|
||||||
|
|
||||||
if (LduMatrix<Type, DType, LUType>::debug >= 2)
|
|
||||||
{
|
|
||||||
Info<< " Normalisation factor = " << normFactor << endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
// --- Calculate normalised residual norm
|
|
||||||
solverPerf.initialResidual() = cmptDivide(gSumCmptMag(rA), normFactor);
|
|
||||||
solverPerf.finalResidual() = solverPerf.initialResidual();
|
|
||||||
|
|
||||||
// --- Check convergence, solve if not converged
|
|
||||||
if (!solverPerf.converged(this->tolerance_, this->relTol_))
|
|
||||||
{
|
|
||||||
// --- Select and construct the preconditioner
|
|
||||||
autoPtr<typename LduMatrix<Type, DType, LUType>::preconditioner>
|
|
||||||
preconPtr = LduMatrix<Type, DType, LUType>::preconditioner::New
|
|
||||||
(
|
|
||||||
*this,
|
|
||||||
this->controlDict_
|
|
||||||
);
|
|
||||||
|
|
||||||
// --- Solver iteration
|
|
||||||
do
|
|
||||||
{
|
|
||||||
// --- Store previous wArT
|
|
||||||
wArTold = wArT;
|
|
||||||
|
|
||||||
// --- Precondition residuals
|
|
||||||
preconPtr->precondition(wA, rA);
|
|
||||||
preconPtr->preconditionT(wT, rT);
|
|
||||||
|
|
||||||
// --- Update search directions:
|
|
||||||
//wArT = gSumProd(wA, rT);
|
|
||||||
wArT = sum(wA & rT);
|
|
||||||
|
|
||||||
if (solverPerf.nIterations() == 0)
|
|
||||||
{
|
|
||||||
for (register label cell=0; cell<nCells; cell++)
|
|
||||||
{
|
|
||||||
pAPtr[cell] = wAPtr[cell];
|
|
||||||
pTPtr[cell] = wTPtr[cell];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
scalar beta = cmptDivide(wArT, wArTold);
|
|
||||||
|
|
||||||
for (register label cell=0; cell<nCells; cell++)
|
|
||||||
{
|
|
||||||
pAPtr[cell] = wAPtr[cell] + (beta* pAPtr[cell]);
|
|
||||||
pTPtr[cell] = wTPtr[cell] + (beta* pTPtr[cell]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// --- Update preconditioned residuals
|
|
||||||
this->matrix_.Amul(wA, pA);
|
|
||||||
this->matrix_.Tmul(wT, pT);
|
|
||||||
|
|
||||||
scalar wApT = sum(wA & pT);
|
|
||||||
|
|
||||||
|
|
||||||
// --- Test for singularity
|
|
||||||
//if
|
|
||||||
//(
|
|
||||||
// solverPerf.checkSingularity(ratio(mag(wApT)normFactor))
|
|
||||||
//) break;
|
|
||||||
|
|
||||||
|
|
||||||
// --- Update solution and residual:
|
|
||||||
|
|
||||||
scalar alpha = cmptDivide(wArT, wApT);
|
|
||||||
|
|
||||||
for (register label cell=0; cell<nCells; cell++)
|
|
||||||
{
|
|
||||||
psiPtr[cell] += (alpha* pAPtr[cell]);
|
|
||||||
rAPtr[cell] -= (alpha* wAPtr[cell]);
|
|
||||||
rTPtr[cell] -= (alpha* wTPtr[cell]);
|
|
||||||
}
|
|
||||||
|
|
||||||
solverPerf.finalResidual() =
|
|
||||||
cmptDivide(gSumCmptMag(rA), normFactor);
|
|
||||||
|
|
||||||
} while
|
|
||||||
(
|
|
||||||
solverPerf.nIterations()++ < this->maxIter_
|
|
||||||
&& !(solverPerf.converged(this->tolerance_, this->relTol_))
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return solverPerf;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
|
||||||
@ -1,181 +0,0 @@
|
|||||||
/*---------------------------------------------------------------------------*\
|
|
||||||
========= |
|
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
|
||||||
\\ / O peration |
|
|
||||||
\\ / A nd | Copyright (C) 1991-2007 OpenCFD Ltd.
|
|
||||||
\\/ M anipulation |
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
License
|
|
||||||
This file is part of OpenFOAM.
|
|
||||||
|
|
||||||
OpenFOAM is free software; you can redistribute it and/or modify it
|
|
||||||
under the terms of the GNU General Public License as published by the
|
|
||||||
Free Software Foundation; either version 2 of the License, or (at your
|
|
||||||
option) any later version.
|
|
||||||
|
|
||||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
|
||||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
||||||
for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with OpenFOAM; if not, write to the Free Software Foundation,
|
|
||||||
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
#include "TPCG.H"
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
template<class Type, class DType, class LUType>
|
|
||||||
Foam::TPCG<Type, DType, LUType>::TPCG
|
|
||||||
(
|
|
||||||
const word& fieldName,
|
|
||||||
const LduMatrix<Type, DType, LUType>& matrix,
|
|
||||||
const dictionary& solverDict
|
|
||||||
)
|
|
||||||
:
|
|
||||||
LduMatrix<Type, DType, LUType>::solver
|
|
||||||
(
|
|
||||||
fieldName,
|
|
||||||
matrix,
|
|
||||||
solverDict
|
|
||||||
)
|
|
||||||
{}
|
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
template<class Type, class DType, class LUType>
|
|
||||||
typename Foam::LduMatrix<Type, DType, LUType>::solverPerformance
|
|
||||||
Foam::TPCG<Type, DType, LUType>::solve(Field<Type>& psi) const
|
|
||||||
{
|
|
||||||
word preconditionerName(this->controlDict_.lookup("preconditioner"));
|
|
||||||
|
|
||||||
// --- Setup class containing solver performance data
|
|
||||||
typename LduMatrix<Type, DType, LUType>::solverPerformance solverPerf
|
|
||||||
(
|
|
||||||
preconditionerName + typeName,
|
|
||||||
this->fieldName_
|
|
||||||
);
|
|
||||||
|
|
||||||
register label nCells = psi.size();
|
|
||||||
|
|
||||||
Type* __restrict__ psiPtr = psi.begin();
|
|
||||||
|
|
||||||
Field<Type> pA(nCells);
|
|
||||||
Type* __restrict__ pAPtr = pA.begin();
|
|
||||||
|
|
||||||
Field<Type> wA(nCells);
|
|
||||||
Type* __restrict__ wAPtr = wA.begin();
|
|
||||||
|
|
||||||
Type wArA = this->matrix_.great_*pTraits<Type>::one;
|
|
||||||
Type wArAold = wArA;
|
|
||||||
|
|
||||||
// --- Calculate A.psi
|
|
||||||
this->matrix_.Amul(wA, psi);
|
|
||||||
|
|
||||||
// --- Calculate initial residual field
|
|
||||||
Field<Type> rA(this->matrix_.source() - wA);
|
|
||||||
Type* __restrict__ rAPtr = rA.begin();
|
|
||||||
|
|
||||||
// --- Calculate normalisation factor
|
|
||||||
Type normFactor = this->normFactor(psi, wA, pA);
|
|
||||||
|
|
||||||
if (LduMatrix<Type, DType, LUType>::debug >= 2)
|
|
||||||
{
|
|
||||||
Info<< " Normalisation factor = " << normFactor << endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
// --- Calculate normalised residual norm
|
|
||||||
solverPerf.initialResidual() = cmptDivide(gSumCmptMag(rA), normFactor);
|
|
||||||
solverPerf.finalResidual() = solverPerf.initialResidual();
|
|
||||||
|
|
||||||
// --- Check convergence, solve if not converged
|
|
||||||
if (!solverPerf.converged(this->tolerance_, this->relTol_))
|
|
||||||
{
|
|
||||||
// --- Select and construct the preconditioner
|
|
||||||
autoPtr<typename LduMatrix<Type, DType, LUType>::preconditioner>
|
|
||||||
preconPtr = LduMatrix<Type, DType, LUType>::preconditioner::New
|
|
||||||
(
|
|
||||||
*this,
|
|
||||||
this->controlDict_
|
|
||||||
);
|
|
||||||
|
|
||||||
// --- Solver iteration
|
|
||||||
do
|
|
||||||
{
|
|
||||||
// --- Store previous wArA
|
|
||||||
wArAold = wArA;
|
|
||||||
|
|
||||||
// --- Precondition residual
|
|
||||||
preconPtr->precondition(wA, rA);
|
|
||||||
|
|
||||||
// --- Update search directions:
|
|
||||||
wArA = gSumCmptProd(wA, rA);
|
|
||||||
|
|
||||||
if (solverPerf.nIterations() == 0)
|
|
||||||
{
|
|
||||||
for (register label cell=0; cell<nCells; cell++)
|
|
||||||
{
|
|
||||||
pAPtr[cell] = wAPtr[cell];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Type beta = cmptDivide
|
|
||||||
(
|
|
||||||
wArA,
|
|
||||||
stabilise(wArAold, this->matrix_.vsmall_)
|
|
||||||
);
|
|
||||||
|
|
||||||
for (register label cell=0; cell<nCells; cell++)
|
|
||||||
{
|
|
||||||
pAPtr[cell] = wAPtr[cell] + cmptMultiply(beta, pAPtr[cell]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// --- Update preconditioned residual
|
|
||||||
this->matrix_.Amul(wA, pA);
|
|
||||||
|
|
||||||
Type wApA = gSumCmptProd(wA, pA);
|
|
||||||
|
|
||||||
|
|
||||||
// --- Test for singularity
|
|
||||||
if (solverPerf.singular(cmptDivide(cmptMag(wApA), normFactor)))
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// --- Update solution and residual:
|
|
||||||
|
|
||||||
Type alpha = cmptDivide
|
|
||||||
(
|
|
||||||
wArA,
|
|
||||||
stabilise(wApA, this->matrix_.vsmall_)
|
|
||||||
);
|
|
||||||
|
|
||||||
for (register label cell=0; cell<nCells; cell++)
|
|
||||||
{
|
|
||||||
psiPtr[cell] += cmptMultiply(alpha, pAPtr[cell]);
|
|
||||||
rAPtr[cell] -= cmptMultiply(alpha, wAPtr[cell]);
|
|
||||||
}
|
|
||||||
|
|
||||||
solverPerf.finalResidual() =
|
|
||||||
cmptDivide(gSumCmptMag(rA), normFactor);
|
|
||||||
|
|
||||||
} while
|
|
||||||
(
|
|
||||||
solverPerf.nIterations()++ < this->maxIter_
|
|
||||||
&& !(solverPerf.converged(this->tolerance_, this->relTol_))
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return solverPerf;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
|
||||||
@ -1,154 +0,0 @@
|
|||||||
/*---------------------------------------------------------------------------*\
|
|
||||||
========= |
|
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
|
||||||
\\ / O peration |
|
|
||||||
\\ / A nd | Copyright (C) 1991-2007 OpenCFD Ltd.
|
|
||||||
\\/ M anipulation |
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
License
|
|
||||||
This file is part of OpenFOAM.
|
|
||||||
|
|
||||||
OpenFOAM is free software; you can redistribute it and/or modify it
|
|
||||||
under the terms of the GNU General Public License as published by the
|
|
||||||
Free Software Foundation; either version 2 of the License, or (at your
|
|
||||||
option) any later version.
|
|
||||||
|
|
||||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
|
||||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
||||||
for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with OpenFOAM; if not, write to the Free Software Foundation,
|
|
||||||
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
#include "SmoothSolver.H"
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
template<class Type, class DType, class LUType>
|
|
||||||
Foam::SmoothSolver<Type, DType, LUType>::SmoothSolver
|
|
||||||
(
|
|
||||||
const word& fieldName,
|
|
||||||
const LduMatrix<Type, DType, LUType>& matrix,
|
|
||||||
const dictionary& solverDict
|
|
||||||
)
|
|
||||||
:
|
|
||||||
LduMatrix<Type, DType, LUType>::solver
|
|
||||||
(
|
|
||||||
fieldName,
|
|
||||||
matrix,
|
|
||||||
solverDict
|
|
||||||
),
|
|
||||||
nSweeps_(1)
|
|
||||||
{
|
|
||||||
readControls();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
template<class Type, class DType, class LUType>
|
|
||||||
void Foam::SmoothSolver<Type, DType, LUType>::readControls()
|
|
||||||
{
|
|
||||||
LduMatrix<Type, DType, LUType>::solver::readControls();
|
|
||||||
readControl(this->controlDict_, nSweeps_, "nSweeps");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template<class Type, class DType, class LUType>
|
|
||||||
typename Foam::LduMatrix<Type, DType, LUType>::solverPerformance
|
|
||||||
Foam::SmoothSolver<Type, DType, LUType>::solve(Field<Type>& psi) const
|
|
||||||
{
|
|
||||||
// --- Setup class containing solver performance data
|
|
||||||
typename LduMatrix<Type, DType, LUType>::solverPerformance solverPerf
|
|
||||||
(
|
|
||||||
typeName,
|
|
||||||
this->fieldName_
|
|
||||||
);
|
|
||||||
|
|
||||||
// If the nSweeps_ is negative do a fixed number of sweeps
|
|
||||||
if (nSweeps_ < 0)
|
|
||||||
{
|
|
||||||
autoPtr<typename LduMatrix<Type, DType, LUType>::smoother>
|
|
||||||
smootherPtr = LduMatrix<Type, DType, LUType>::smoother::New
|
|
||||||
(
|
|
||||||
this->fieldName_,
|
|
||||||
this->matrix_,
|
|
||||||
this->controlDict_
|
|
||||||
);
|
|
||||||
|
|
||||||
smootherPtr->smooth(psi, -nSweeps_);
|
|
||||||
|
|
||||||
solverPerf.nIterations() -= nSweeps_;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Type normFactor = pTraits<Type>::zero;
|
|
||||||
|
|
||||||
{
|
|
||||||
Field<Type> Apsi(psi.size());
|
|
||||||
Field<Type> temp(psi.size());
|
|
||||||
|
|
||||||
// Calculate A.psi
|
|
||||||
this->matrix_.Amul(Apsi, psi);
|
|
||||||
|
|
||||||
// Calculate normalisation factor
|
|
||||||
normFactor = this->normFactor(psi, Apsi, temp);
|
|
||||||
|
|
||||||
// Calculate residual magnitude
|
|
||||||
solverPerf.initialResidual() = cmptDivide
|
|
||||||
(
|
|
||||||
gSumCmptMag(this->matrix_.source() - Apsi),
|
|
||||||
normFactor
|
|
||||||
);
|
|
||||||
solverPerf.finalResidual() = solverPerf.initialResidual();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (LduMatrix<Type, DType, LUType>::debug >= 2)
|
|
||||||
{
|
|
||||||
Info<< " Normalisation factor = " << normFactor << endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Check convergence, solve if not converged
|
|
||||||
if (!solverPerf.converged(this->tolerance_, this->relTol_))
|
|
||||||
{
|
|
||||||
autoPtr<typename LduMatrix<Type, DType, LUType>::smoother>
|
|
||||||
smootherPtr = LduMatrix<Type, DType, LUType>::smoother::New
|
|
||||||
(
|
|
||||||
this->fieldName_,
|
|
||||||
this->matrix_,
|
|
||||||
this->controlDict_
|
|
||||||
);
|
|
||||||
|
|
||||||
// Smoothing loop
|
|
||||||
do
|
|
||||||
{
|
|
||||||
smootherPtr->smooth
|
|
||||||
(
|
|
||||||
psi,
|
|
||||||
nSweeps_
|
|
||||||
);
|
|
||||||
|
|
||||||
// Calculate the residual to check convergence
|
|
||||||
solverPerf.finalResidual() = cmptDivide
|
|
||||||
(
|
|
||||||
gSumCmptMag(this->matrix_.residual(psi)),
|
|
||||||
normFactor
|
|
||||||
);
|
|
||||||
} while
|
|
||||||
(
|
|
||||||
(solverPerf.nIterations() += nSweeps_) < this->maxIter_
|
|
||||||
&& !(solverPerf.converged(this->tolerance_, this->relTol_))
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return solverPerf;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
|
||||||
@ -1,111 +0,0 @@
|
|||||||
/*---------------------------------------------------------------------------*\
|
|
||||||
========= |
|
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
|
||||||
\\ / O peration |
|
|
||||||
\\ / A nd | Copyright (C) 1991-2007 OpenCFD Ltd.
|
|
||||||
\\/ M anipulation |
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
License
|
|
||||||
This file is part of OpenFOAM.
|
|
||||||
|
|
||||||
OpenFOAM is free software; you can redistribute it and/or modify it
|
|
||||||
under the terms of the GNU General Public License as published by the
|
|
||||||
Free Software Foundation; either version 2 of the License, or (at your
|
|
||||||
option) any later version.
|
|
||||||
|
|
||||||
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
|
||||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
||||||
for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with OpenFOAM; if not, write to the Free Software Foundation,
|
|
||||||
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
||||||
|
|
||||||
Class
|
|
||||||
Foam::SmoothSolver
|
|
||||||
|
|
||||||
Description
|
|
||||||
Iterative solver for symmetric and assymetric matrices which uses a
|
|
||||||
run-time selected smoother e.g. GaussSeidel to converge the solution to
|
|
||||||
the required tolerance. To improve efficiency, the residual is evaluated
|
|
||||||
after every nSweeps smoothing iterations.
|
|
||||||
|
|
||||||
SourceFiles
|
|
||||||
SmoothSolver.C
|
|
||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
#ifndef SmoothSolver_H
|
|
||||||
#define SmoothSolver_H
|
|
||||||
|
|
||||||
#include "lduMatrix.H"
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
namespace Foam
|
|
||||||
{
|
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*\
|
|
||||||
Class SmoothSolver Declaration
|
|
||||||
\*---------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
template<class Type, class DType, class LUType>
|
|
||||||
class SmoothSolver
|
|
||||||
:
|
|
||||||
public LduMatrix<Type, DType, LUType>::solver
|
|
||||||
{
|
|
||||||
|
|
||||||
protected:
|
|
||||||
|
|
||||||
// Protected data
|
|
||||||
|
|
||||||
//- Number of sweeps before the evaluation of residual
|
|
||||||
label nSweeps_;
|
|
||||||
|
|
||||||
//- Read the control parameters from the controlDict_
|
|
||||||
virtual void readControls();
|
|
||||||
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
//- Runtime type information
|
|
||||||
TypeName("SmoothSolver");
|
|
||||||
|
|
||||||
|
|
||||||
// Constructors
|
|
||||||
|
|
||||||
//- Construct from matrix components and solver data dictionary
|
|
||||||
SmoothSolver
|
|
||||||
(
|
|
||||||
const word& fieldName,
|
|
||||||
const LduMatrix<Type, DType, LUType>& matrix,
|
|
||||||
const dictionary& solverDict
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
// Member Functions
|
|
||||||
|
|
||||||
//- Solve the matrix with this solver
|
|
||||||
virtual typename LduMatrix<Type, DType, LUType>::solverPerformance solve
|
|
||||||
(
|
|
||||||
Field<Type>& psi
|
|
||||||
) const;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
} // End namespace Foam
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
#ifdef NoRepository
|
|
||||||
# include "SmoothSolver.C"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
|
||||||
@ -1,29 +0,0 @@
|
|||||||
#include "TPCG.H"
|
|
||||||
#include "TPBiCG.H"
|
|
||||||
#include "SmoothSolver.H"
|
|
||||||
#include "fieldTypes.H"
|
|
||||||
|
|
||||||
#define makeLduSolvers(Type, DType, LUType) \
|
|
||||||
\
|
|
||||||
makeLduSolver(DiagonalSolver, Type, DType, LUType); \
|
|
||||||
makeLduSymSolver(DiagonalSolver, Type, DType, LUType); \
|
|
||||||
makeLduAsymSolver(DiagonalSolver, Type, DType, LUType); \
|
|
||||||
\
|
|
||||||
makeLduSolver(TPCG, Type, DType, LUType); \
|
|
||||||
makeLduSymSolver(TPCG, Type, DType, LUType); \
|
|
||||||
\
|
|
||||||
makeLduSolver(TPBiCG, Type, DType, LUType); \
|
|
||||||
makeLduAsymSolver(TPBiCG, Type, DType, LUType); \
|
|
||||||
\
|
|
||||||
makeLduSolver(SmoothSolver, Type, DType, LUType); \
|
|
||||||
makeLduSymSolver(SmoothSolver, Type, DType, LUType); \
|
|
||||||
makeLduAsymSolver(SmoothSolver, Type, DType, LUType);
|
|
||||||
|
|
||||||
namespace Foam
|
|
||||||
{
|
|
||||||
makeLduSolvers(scalar, scalar, scalar);
|
|
||||||
makeLduSolvers(vector, scalar, scalar);
|
|
||||||
makeLduSolvers(sphericalTensor, scalar, scalar);
|
|
||||||
makeLduSolvers(symmTensor, scalar, scalar);
|
|
||||||
makeLduSolvers(tensor, scalar, scalar);
|
|
||||||
};
|
|
||||||
@ -1,4 +1,4 @@
|
|||||||
ParMGridGen = $(THIRD_PARTY)/ParMGridGen-1.0
|
ParMGridGen = $(WM_THIRD_PARTY_DIR)/ParMGridGen-1.0
|
||||||
|
|
||||||
TYPE_REAL=
|
TYPE_REAL=
|
||||||
#if defined(SP)
|
#if defined(SP)
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
EXE_INC = \
|
EXE_INC = \
|
||||||
-I$(THIRD_PARTY)/metis-5.0pre2/include
|
-I$(WM_THIRD_PARTY_DIR)/metis-5.0pre2/include
|
||||||
|
|
||||||
LIB_LIBS = \
|
LIB_LIBS = \
|
||||||
-lmetis \
|
-lmetis \
|
||||||
|
|||||||
@ -125,4 +125,50 @@ Foam::labelList Foam::decompositionMethod::decompose
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::decompositionMethod::calcCellCells
|
||||||
|
(
|
||||||
|
const polyMesh& mesh,
|
||||||
|
const labelList& fineToCoarse,
|
||||||
|
const label nCoarse,
|
||||||
|
labelListList& cellCells
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (fineToCoarse.size() != mesh.nCells())
|
||||||
|
{
|
||||||
|
FatalErrorIn
|
||||||
|
(
|
||||||
|
"decompositionMethod::calcCellCells"
|
||||||
|
"(const labelList&, labelListList&) const"
|
||||||
|
) << "Only valid for mesh agglomeration." << exit(FatalError);
|
||||||
|
}
|
||||||
|
|
||||||
|
List<DynamicList<label> > dynCellCells(nCoarse);
|
||||||
|
|
||||||
|
forAll(mesh.faceNeighbour(), faceI)
|
||||||
|
{
|
||||||
|
label own = fineToCoarse[mesh.faceOwner()[faceI]];
|
||||||
|
label nei = fineToCoarse[mesh.faceNeighbour()[faceI]];
|
||||||
|
|
||||||
|
if (own != nei)
|
||||||
|
{
|
||||||
|
if (findIndex(dynCellCells[own], nei) == -1)
|
||||||
|
{
|
||||||
|
dynCellCells[own].append(nei);
|
||||||
|
}
|
||||||
|
if (findIndex(dynCellCells[nei], own) == -1)
|
||||||
|
{
|
||||||
|
dynCellCells[nei].append(own);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cellCells.setSize(dynCellCells.size());
|
||||||
|
forAll(dynCellCells, coarseI)
|
||||||
|
{
|
||||||
|
cellCells[coarseI].transfer(dynCellCells[coarseI].shrink());
|
||||||
|
dynCellCells[coarseI].clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
// ************************************************************************* //
|
||||||
|
|||||||
@ -36,9 +36,6 @@ SourceFiles
|
|||||||
#ifndef decompositionMethod_H
|
#ifndef decompositionMethod_H
|
||||||
#define decompositionMethod_H
|
#define decompositionMethod_H
|
||||||
|
|
||||||
#include "typeInfo.H"
|
|
||||||
#include "runTimeSelectionTables.H"
|
|
||||||
#include "dictionary.H"
|
|
||||||
#include "polyMesh.H"
|
#include "polyMesh.H"
|
||||||
#include "pointField.H"
|
#include "pointField.H"
|
||||||
|
|
||||||
@ -60,6 +57,15 @@ protected:
|
|||||||
label nProcessors_;
|
label nProcessors_;
|
||||||
|
|
||||||
|
|
||||||
|
//- Helper: determine (non-parallel) cellCells from mesh agglomeration.
|
||||||
|
static void calcCellCells
|
||||||
|
(
|
||||||
|
const polyMesh& mesh,
|
||||||
|
const labelList& agglom,
|
||||||
|
const label nCoarse,
|
||||||
|
labelListList& cellCells
|
||||||
|
);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
// Private Member Functions
|
// Private Member Functions
|
||||||
@ -103,13 +109,13 @@ public:
|
|||||||
|
|
||||||
// Selectors
|
// Selectors
|
||||||
|
|
||||||
//- Return a reference to the selected turbulence model
|
//- Return a reference to the selected decomposition method
|
||||||
static autoPtr<decompositionMethod> New
|
static autoPtr<decompositionMethod> New
|
||||||
(
|
(
|
||||||
const dictionary& decompositionDict
|
const dictionary& decompositionDict
|
||||||
);
|
);
|
||||||
|
|
||||||
//- Return a reference to the selected turbulence model
|
//- Return a reference to the selected decomposition method
|
||||||
static autoPtr<decompositionMethod> New
|
static autoPtr<decompositionMethod> New
|
||||||
(
|
(
|
||||||
const dictionary& decompositionDict,
|
const dictionary& decompositionDict,
|
||||||
@ -142,18 +148,35 @@ public:
|
|||||||
// proc boundaries)
|
// proc boundaries)
|
||||||
virtual bool parallelAware() const = 0;
|
virtual bool parallelAware() const = 0;
|
||||||
|
|
||||||
//- Return for every coordinate the wanted processor number
|
//- Return for every coordinate the wanted processor number. Use the
|
||||||
|
// mesh connectivity (if needed)
|
||||||
virtual labelList decompose(const pointField&) = 0;
|
virtual labelList decompose(const pointField&) = 0;
|
||||||
|
|
||||||
//- Return for every coordinate the wanted processor number. Gets
|
//- Return for every coordinate the wanted processor number. Gets
|
||||||
// passed agglomeration map (from fine to coarse cells) and coarse cell
|
// passed agglomeration map (from fine to coarse cells) and coarse cell
|
||||||
// location. Can be overridden by decomposers that provide this
|
// location. Can be overridden by decomposers that provide this
|
||||||
// functionality natively.
|
// functionality natively. Coarse cells are local to the processor
|
||||||
|
// (if in parallel). If you want to have coarse cells spanning
|
||||||
|
// processors use the next function below instead.
|
||||||
virtual labelList decompose
|
virtual labelList decompose
|
||||||
(
|
(
|
||||||
const labelList& agglom,
|
const labelList& cellToRegion,
|
||||||
const pointField&
|
const pointField& regionPoints
|
||||||
);
|
);
|
||||||
|
|
||||||
|
//- Return for every coordinate the wanted processor number. Explicitly
|
||||||
|
// provided connectivity - does not use mesh_.
|
||||||
|
// The connectivity is equal to mesh.cellCells() except for
|
||||||
|
// - in parallel the cell numbers are global cell numbers (starting
|
||||||
|
// from 0 at processor0 and then incrementing all through the
|
||||||
|
// processors)
|
||||||
|
// - the connections are across coupled patches
|
||||||
|
virtual labelList decompose
|
||||||
|
(
|
||||||
|
const labelListList& globalCellCells,
|
||||||
|
const pointField& cc
|
||||||
|
) = 0;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -154,7 +154,25 @@ public:
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//- Return for every coordinate the wanted processor number. Use the
|
||||||
|
// mesh connectivity (if needed)
|
||||||
virtual labelList decompose(const pointField&);
|
virtual labelList decompose(const pointField&);
|
||||||
|
|
||||||
|
//- Return for every coordinate the wanted processor number. Explicitly
|
||||||
|
// provided connectivity - does not use mesh_.
|
||||||
|
// The connectivity is equal to mesh.cellCells() except for
|
||||||
|
// - in parallel the cell numbers are global cell numbers (starting
|
||||||
|
// from 0 at processor0 and then incrementing all through the
|
||||||
|
// processors)
|
||||||
|
// - the connections are across coupled patches
|
||||||
|
virtual labelList decompose
|
||||||
|
(
|
||||||
|
const labelListList& globalCellCells,
|
||||||
|
const pointField& cc
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return decompose(cc);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -97,7 +97,25 @@ public:
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//- Return for every coordinate the wanted processor number. Use the
|
||||||
|
// mesh connectivity (if needed)
|
||||||
virtual labelList decompose(const pointField&);
|
virtual labelList decompose(const pointField&);
|
||||||
|
|
||||||
|
//- Return for every coordinate the wanted processor number. Explicitly
|
||||||
|
// provided connectivity - does not use mesh_.
|
||||||
|
// The connectivity is equal to mesh.cellCells() except for
|
||||||
|
// - in parallel the cell numbers are global cell numbers (starting
|
||||||
|
// from 0 at processor0 and then incrementing all through the
|
||||||
|
// processors)
|
||||||
|
// - the connections are across coupled patches
|
||||||
|
virtual labelList decompose
|
||||||
|
(
|
||||||
|
const labelListList& globalCellCells,
|
||||||
|
const pointField& cc
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return decompose(cc);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -29,7 +29,7 @@ License
|
|||||||
#include "floatScalar.H"
|
#include "floatScalar.H"
|
||||||
#include "IFstream.H"
|
#include "IFstream.H"
|
||||||
#include "Time.H"
|
#include "Time.H"
|
||||||
#include "coupledPolyPatch.H"
|
#include "cyclicPolyPatch.H"
|
||||||
|
|
||||||
extern "C"
|
extern "C"
|
||||||
{
|
{
|
||||||
@ -52,113 +52,18 @@ namespace Foam
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
Foam::metisDecomp::metisDecomp
|
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||||
|
|
||||||
|
// Call Metis with options from dictionary.
|
||||||
|
Foam::label Foam::metisDecomp::decompose
|
||||||
(
|
(
|
||||||
const dictionary& decompositionDict,
|
const List<int>& adjncy,
|
||||||
const polyMesh& mesh
|
const List<int>& xadj,
|
||||||
|
|
||||||
|
List<int>& finalDecomp
|
||||||
)
|
)
|
||||||
:
|
|
||||||
decompositionMethod(decompositionDict),
|
|
||||||
mesh_(mesh)
|
|
||||||
{}
|
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
Foam::labelList Foam::metisDecomp::decompose(const pointField& points)
|
|
||||||
{
|
{
|
||||||
// Make Metis CSR (Compressed Storage Format) storage
|
|
||||||
// adjncy : contains neighbours (= edges in graph)
|
|
||||||
// xadj(celli) : start of information in adjncy for celli
|
|
||||||
|
|
||||||
List<int> xadj(mesh_.nCells()+1);
|
|
||||||
|
|
||||||
// Initialise the number of internal faces of the cells to twice the
|
|
||||||
// number of internal faces
|
|
||||||
label nInternalFaces = 2*mesh_.nInternalFaces();
|
|
||||||
|
|
||||||
// Check the boundary for coupled patches and add to the number of
|
|
||||||
// internal faces
|
|
||||||
const polyBoundaryMesh& pbm = mesh_.boundaryMesh();
|
|
||||||
|
|
||||||
forAll(pbm, patchi)
|
|
||||||
{
|
|
||||||
if (isA<coupledPolyPatch>(pbm[patchi]))
|
|
||||||
{
|
|
||||||
nInternalFaces += pbm[patchi].size();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create the adjncy array the size of the total number of internal and
|
|
||||||
// coupled faces
|
|
||||||
List<int> adjncy(nInternalFaces);
|
|
||||||
|
|
||||||
// Fill in xadj
|
|
||||||
// ~~~~~~~~~~~~
|
|
||||||
label freeAdj = 0;
|
|
||||||
|
|
||||||
for (label cellI = 0; cellI < mesh_.nCells(); cellI++)
|
|
||||||
{
|
|
||||||
xadj[cellI] = freeAdj;
|
|
||||||
|
|
||||||
const labelList& cFaces = mesh_.cells()[cellI];
|
|
||||||
|
|
||||||
forAll(cFaces, i)
|
|
||||||
{
|
|
||||||
label faceI = cFaces[i];
|
|
||||||
|
|
||||||
if
|
|
||||||
(
|
|
||||||
mesh_.isInternalFace(faceI)
|
|
||||||
|| isA<coupledPolyPatch>
|
|
||||||
(pbm[pbm.whichPatch(faceI)])
|
|
||||||
)
|
|
||||||
{
|
|
||||||
freeAdj++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
xadj[mesh_.nCells()] = freeAdj;
|
|
||||||
|
|
||||||
|
|
||||||
// Fill in adjncy
|
|
||||||
// ~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
labelList nFacesPerCell(mesh_.nCells(), 0);
|
|
||||||
|
|
||||||
// Internal faces
|
|
||||||
for (label faceI = 0; faceI < mesh_.nInternalFaces(); faceI++)
|
|
||||||
{
|
|
||||||
label own = mesh_.faceOwner()[faceI];
|
|
||||||
label nei = mesh_.faceNeighbour()[faceI];
|
|
||||||
|
|
||||||
adjncy[xadj[own] + nFacesPerCell[own]++] = nei;
|
|
||||||
adjncy[xadj[nei] + nFacesPerCell[nei]++] = own;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Coupled faces
|
|
||||||
forAll(pbm, patchi)
|
|
||||||
{
|
|
||||||
if (isA<coupledPolyPatch>(pbm[patchi]))
|
|
||||||
{
|
|
||||||
const unallocLabelList& faceCells = pbm[patchi].faceCells();
|
|
||||||
|
|
||||||
label sizeby2 = faceCells.size()/2;
|
|
||||||
|
|
||||||
for (label facei=0; facei<sizeby2; facei++)
|
|
||||||
{
|
|
||||||
label own = faceCells[facei];
|
|
||||||
label nei = faceCells[facei + sizeby2];
|
|
||||||
|
|
||||||
adjncy[xadj[own] + nFacesPerCell[own]++] = nei;
|
|
||||||
adjncy[xadj[nei] + nFacesPerCell[nei]++] = own;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// C style numbering
|
// C style numbering
|
||||||
int numFlag = 0;
|
int numFlag = 0;
|
||||||
|
|
||||||
@ -259,68 +164,69 @@ Foam::labelList Foam::metisDecomp::decompose(const pointField& points)
|
|||||||
);
|
);
|
||||||
cellWeights.transfer(cellIOWeights);
|
cellWeights.transfer(cellIOWeights);
|
||||||
|
|
||||||
if (cellWeights.size() != mesh_.nCells())
|
if (cellWeights.size() != xadj.size()-1)
|
||||||
{
|
{
|
||||||
FatalErrorIn("metisDecomp::decompose(const pointField&)")
|
FatalErrorIn("metisDecomp::decompose(const pointField&)")
|
||||||
<< "Number of cell weights " << cellWeights.size()
|
<< "Number of cell weights " << cellWeights.size()
|
||||||
<< " does not equal number of cells " << mesh_.nCells()
|
<< " does not equal number of cells " << xadj.size()-1
|
||||||
<< exit(FatalError);
|
<< exit(FatalError);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (metisDecompCoeffs.found("faceWeightsFile"))
|
//- faceWeights disabled. Only makes sense for cellCells from mesh.
|
||||||
{
|
//if (metisDecompCoeffs.found("faceWeightsFile"))
|
||||||
Info<< "metisDecomp : Using face-based weights." << endl;
|
//{
|
||||||
|
// Info<< "metisDecomp : Using face-based weights." << endl;
|
||||||
word faceWeightsFile
|
//
|
||||||
(
|
// word faceWeightsFile
|
||||||
metisDecompCoeffs.lookup("faceWeightsFile")
|
// (
|
||||||
);
|
// metisDecompCoeffs.lookup("faceWeightsFile")
|
||||||
|
// );
|
||||||
IOList<int> weights
|
//
|
||||||
(
|
// IOList<int> weights
|
||||||
IOobject
|
// (
|
||||||
(
|
// IOobject
|
||||||
faceWeightsFile,
|
// (
|
||||||
mesh_.time().timeName(),
|
// faceWeightsFile,
|
||||||
mesh_,
|
// mesh_.time().timeName(),
|
||||||
IOobject::MUST_READ,
|
// mesh_,
|
||||||
IOobject::AUTO_WRITE
|
// IOobject::MUST_READ,
|
||||||
)
|
// IOobject::AUTO_WRITE
|
||||||
);
|
// )
|
||||||
|
// );
|
||||||
if (weights.size() != mesh_.nInternalFaces())
|
//
|
||||||
{
|
// if (weights.size() != adjncy.size()/2)
|
||||||
FatalErrorIn("metisDecomp::decompose(const pointField&)")
|
// {
|
||||||
<< "Number of face weights " << weights.size()
|
// FatalErrorIn("metisDecomp::decompose(const pointField&)")
|
||||||
<< " does not equal number of internal faces "
|
// << "Number of face weights " << weights.size()
|
||||||
<< mesh_.nInternalFaces()
|
// << " does not equal number of internal faces "
|
||||||
<< exit(FatalError);
|
// << adjncy.size()/2
|
||||||
}
|
// << exit(FatalError);
|
||||||
|
// }
|
||||||
// Assume symmetric weights. Keep same ordering as adjncy.
|
//
|
||||||
faceWeights.setSize(2*mesh_.nInternalFaces());
|
// // Assume symmetric weights. Keep same ordering as adjncy.
|
||||||
|
// faceWeights.setSize(adjncy.size());
|
||||||
labelList nFacesPerCell(mesh_.nCells(), 0);
|
//
|
||||||
|
// labelList nFacesPerCell(mesh_.nCells(), 0);
|
||||||
for (label faceI = 0; faceI < mesh_.nInternalFaces(); faceI++)
|
//
|
||||||
{
|
// for (label faceI = 0; faceI < mesh_.nInternalFaces(); faceI++)
|
||||||
label w = weights[faceI];
|
// {
|
||||||
|
// label w = weights[faceI];
|
||||||
label own = mesh_.faceOwner()[faceI];
|
//
|
||||||
label nei = mesh_.faceNeighbour()[faceI];
|
// label own = mesh_.faceOwner()[faceI];
|
||||||
|
// label nei = mesh_.faceNeighbour()[faceI];
|
||||||
faceWeights[xadj[own] + nFacesPerCell[own]++] = w;
|
//
|
||||||
faceWeights[xadj[nei] + nFacesPerCell[nei]++] = w;
|
// faceWeights[xadj[own] + nFacesPerCell[own]++] = w;
|
||||||
}
|
// faceWeights[xadj[nei] + nFacesPerCell[nei]++] = w;
|
||||||
}
|
// }
|
||||||
|
//}
|
||||||
}
|
}
|
||||||
|
|
||||||
int numCells = mesh_.nCells();
|
int numCells = xadj.size()-1;
|
||||||
int nProcs = nProcessors_;
|
int nProcs = nProcessors_;
|
||||||
|
|
||||||
// output: cell -> processor addressing
|
// output: cell -> processor addressing
|
||||||
List<int> finalDecomp(mesh_.nCells());
|
finalDecomp.setSize(numCells);
|
||||||
|
|
||||||
// output: number of cut edges
|
// output: number of cut edges
|
||||||
int edgeCut = 0;
|
int edgeCut = 0;
|
||||||
@ -348,8 +254,8 @@ Foam::labelList Foam::metisDecomp::decompose(const pointField& points)
|
|||||||
METIS_WPartGraphRecursive
|
METIS_WPartGraphRecursive
|
||||||
(
|
(
|
||||||
&numCells, // num vertices in graph
|
&numCells, // num vertices in graph
|
||||||
xadj.begin(), // indexing into adjncy
|
const_cast<List<int>&>(xadj).begin(), // indexing into adjncy
|
||||||
adjncy.begin(), // neighbour info
|
const_cast<List<int>&>(adjncy).begin(), // neighbour info
|
||||||
vwgtPtr, // vertexweights
|
vwgtPtr, // vertexweights
|
||||||
adjwgtPtr, // no edgeweights
|
adjwgtPtr, // no edgeweights
|
||||||
&wgtFlag,
|
&wgtFlag,
|
||||||
@ -366,8 +272,8 @@ Foam::labelList Foam::metisDecomp::decompose(const pointField& points)
|
|||||||
METIS_PartGraphRecursive
|
METIS_PartGraphRecursive
|
||||||
(
|
(
|
||||||
&numCells, // num vertices in graph
|
&numCells, // num vertices in graph
|
||||||
xadj.begin(), // indexing into adjncy
|
const_cast<List<int>&>(xadj).begin(), // indexing into adjncy
|
||||||
adjncy.begin(), // neighbour info
|
const_cast<List<int>&>(adjncy).begin(), // neighbour info
|
||||||
vwgtPtr, // vertexweights
|
vwgtPtr, // vertexweights
|
||||||
adjwgtPtr, // no edgeweights
|
adjwgtPtr, // no edgeweights
|
||||||
&wgtFlag,
|
&wgtFlag,
|
||||||
@ -386,8 +292,8 @@ Foam::labelList Foam::metisDecomp::decompose(const pointField& points)
|
|||||||
METIS_WPartGraphKway
|
METIS_WPartGraphKway
|
||||||
(
|
(
|
||||||
&numCells, // num vertices in graph
|
&numCells, // num vertices in graph
|
||||||
xadj.begin(), // indexing into adjncy
|
const_cast<List<int>&>(xadj).begin(), // indexing into adjncy
|
||||||
adjncy.begin(), // neighbour info
|
const_cast<List<int>&>(adjncy).begin(), // neighbour info
|
||||||
vwgtPtr, // vertexweights
|
vwgtPtr, // vertexweights
|
||||||
adjwgtPtr, // no edgeweights
|
adjwgtPtr, // no edgeweights
|
||||||
&wgtFlag,
|
&wgtFlag,
|
||||||
@ -404,8 +310,8 @@ Foam::labelList Foam::metisDecomp::decompose(const pointField& points)
|
|||||||
METIS_PartGraphKway
|
METIS_PartGraphKway
|
||||||
(
|
(
|
||||||
&numCells, // num vertices in graph
|
&numCells, // num vertices in graph
|
||||||
xadj.begin(), // indexing into adjncy
|
const_cast<List<int>&>(xadj).begin(), // indexing into adjncy
|
||||||
adjncy.begin(), // neighbour info
|
const_cast<List<int>&>(adjncy).begin(), // neighbour info
|
||||||
vwgtPtr, // vertexweights
|
vwgtPtr, // vertexweights
|
||||||
adjwgtPtr, // no edgeweights
|
adjwgtPtr, // no edgeweights
|
||||||
&wgtFlag,
|
&wgtFlag,
|
||||||
@ -418,6 +324,131 @@ Foam::labelList Foam::metisDecomp::decompose(const pointField& points)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return edgeCut;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Foam::metisDecomp::metisDecomp
|
||||||
|
(
|
||||||
|
const dictionary& decompositionDict,
|
||||||
|
const polyMesh& mesh
|
||||||
|
)
|
||||||
|
:
|
||||||
|
decompositionMethod(decompositionDict),
|
||||||
|
mesh_(mesh)
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Foam::labelList Foam::metisDecomp::decompose(const pointField& points)
|
||||||
|
{
|
||||||
|
if (points.size() != mesh_.nCells())
|
||||||
|
{
|
||||||
|
FatalErrorIn("metisDecomp::decompose(const pointField&)")
|
||||||
|
<< "Can use this decomposition method only for the whole mesh"
|
||||||
|
<< endl
|
||||||
|
<< "and supply one coordinate (cellCentre) for every cell." << endl
|
||||||
|
<< "The number of coordinates " << points.size() << endl
|
||||||
|
<< "The number of cells in the mesh " << mesh_.nCells()
|
||||||
|
<< exit(FatalError);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make Metis CSR (Compressed Storage Format) storage
|
||||||
|
// adjncy : contains neighbours (= edges in graph)
|
||||||
|
// xadj(celli) : start of information in adjncy for celli
|
||||||
|
|
||||||
|
List<int> xadj(mesh_.nCells()+1);
|
||||||
|
|
||||||
|
// Initialise the number of internal faces of the cells to twice the
|
||||||
|
// number of internal faces
|
||||||
|
label nInternalFaces = 2*mesh_.nInternalFaces();
|
||||||
|
|
||||||
|
// Check the boundary for coupled patches and add to the number of
|
||||||
|
// internal faces
|
||||||
|
const polyBoundaryMesh& pbm = mesh_.boundaryMesh();
|
||||||
|
|
||||||
|
forAll(pbm, patchi)
|
||||||
|
{
|
||||||
|
if (isA<cyclicPolyPatch>(pbm[patchi]))
|
||||||
|
{
|
||||||
|
nInternalFaces += pbm[patchi].size();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create the adjncy array the size of the total number of internal and
|
||||||
|
// coupled faces
|
||||||
|
List<int> adjncy(nInternalFaces);
|
||||||
|
|
||||||
|
// Fill in xadj
|
||||||
|
// ~~~~~~~~~~~~
|
||||||
|
label freeAdj = 0;
|
||||||
|
|
||||||
|
for (label cellI = 0; cellI < mesh_.nCells(); cellI++)
|
||||||
|
{
|
||||||
|
xadj[cellI] = freeAdj;
|
||||||
|
|
||||||
|
const labelList& cFaces = mesh_.cells()[cellI];
|
||||||
|
|
||||||
|
forAll(cFaces, i)
|
||||||
|
{
|
||||||
|
label faceI = cFaces[i];
|
||||||
|
|
||||||
|
if
|
||||||
|
(
|
||||||
|
mesh_.isInternalFace(faceI)
|
||||||
|
|| isA<cyclicPolyPatch>(pbm[pbm.whichPatch(faceI)])
|
||||||
|
)
|
||||||
|
{
|
||||||
|
freeAdj++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
xadj[mesh_.nCells()] = freeAdj;
|
||||||
|
|
||||||
|
|
||||||
|
// Fill in adjncy
|
||||||
|
// ~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
labelList nFacesPerCell(mesh_.nCells(), 0);
|
||||||
|
|
||||||
|
// Internal faces
|
||||||
|
for (label faceI = 0; faceI < mesh_.nInternalFaces(); faceI++)
|
||||||
|
{
|
||||||
|
label own = mesh_.faceOwner()[faceI];
|
||||||
|
label nei = mesh_.faceNeighbour()[faceI];
|
||||||
|
|
||||||
|
adjncy[xadj[own] + nFacesPerCell[own]++] = nei;
|
||||||
|
adjncy[xadj[nei] + nFacesPerCell[nei]++] = own;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Coupled faces. Only cyclics done.
|
||||||
|
forAll(pbm, patchi)
|
||||||
|
{
|
||||||
|
if (isA<cyclicPolyPatch>(pbm[patchi]))
|
||||||
|
{
|
||||||
|
const unallocLabelList& faceCells = pbm[patchi].faceCells();
|
||||||
|
|
||||||
|
label sizeby2 = faceCells.size()/2;
|
||||||
|
|
||||||
|
for (label facei=0; facei<sizeby2; facei++)
|
||||||
|
{
|
||||||
|
label own = faceCells[facei];
|
||||||
|
label nei = faceCells[facei + sizeby2];
|
||||||
|
|
||||||
|
adjncy[xadj[own] + nFacesPerCell[own]++] = nei;
|
||||||
|
adjncy[xadj[nei] + nFacesPerCell[nei]++] = own;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Decompose using default weights
|
||||||
|
List<int> finalDecomp;
|
||||||
|
decompose(adjncy, xadj, finalDecomp);
|
||||||
|
|
||||||
|
// Copy back to labelList
|
||||||
labelList decomp(finalDecomp.size());
|
labelList decomp(finalDecomp.size());
|
||||||
forAll(decomp, i)
|
forAll(decomp, i)
|
||||||
{
|
{
|
||||||
@ -427,68 +458,28 @@ Foam::labelList Foam::metisDecomp::decompose(const pointField& points)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Foam::labelList Foam::metisDecomp::decompose
|
// From cell-cell connections to Metis format (like CompactListList)
|
||||||
|
void Foam::metisDecomp::calcMetisCSR
|
||||||
(
|
(
|
||||||
const labelList& agglom,
|
const labelListList& cellCells,
|
||||||
const pointField& agglomPoints
|
List<int>& adjncy,
|
||||||
|
List<int>& xadj
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
// Make Metis CSR (Compressed Storage Format) storage
|
|
||||||
// adjncy : contains neighbours (= edges in graph)
|
|
||||||
// xadj(celli) : start of information in adjncy for celli
|
|
||||||
|
|
||||||
List<int> xadj(agglomPoints.size()+1);
|
|
||||||
|
|
||||||
// Get cellCells on coarse mesh.
|
|
||||||
labelListList cellCells(agglomPoints.size());
|
|
||||||
{
|
|
||||||
List<DynamicList<label> > dynCellCells(cellCells.size());
|
|
||||||
|
|
||||||
forAll(mesh_.faceNeighbour(), faceI)
|
|
||||||
{
|
|
||||||
label own = agglom[mesh_.faceOwner()[faceI]];
|
|
||||||
label nei = agglom[mesh_.faceNeighbour()[faceI]];
|
|
||||||
|
|
||||||
if (own != nei)
|
|
||||||
{
|
|
||||||
if (findIndex(dynCellCells[own], nei) == -1)
|
|
||||||
{
|
|
||||||
dynCellCells[own].append(nei);
|
|
||||||
}
|
|
||||||
if (findIndex(dynCellCells[nei], own) == -1)
|
|
||||||
{
|
|
||||||
dynCellCells[nei].append(own);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
forAll(dynCellCells, coarseI)
|
|
||||||
{
|
|
||||||
cellCells[coarseI].transfer(dynCellCells[coarseI].shrink());
|
|
||||||
dynCellCells[coarseI].clear();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Count number of internal faces
|
// Count number of internal faces
|
||||||
label nInternalFaces = 0;
|
label nConnections = 0;
|
||||||
|
|
||||||
forAll(cellCells, coarseI)
|
forAll(cellCells, coarseI)
|
||||||
{
|
{
|
||||||
const labelList& cCells = cellCells[coarseI];
|
nConnections += cellCells[coarseI].size();
|
||||||
|
|
||||||
forAll(cCells, i)
|
|
||||||
{
|
|
||||||
if (cCells[i] > coarseI)
|
|
||||||
{
|
|
||||||
nInternalFaces++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create the adjncy array as twice the size of the total number of
|
// Create the adjncy array as twice the size of the total number of
|
||||||
// internal faces
|
// internal faces
|
||||||
List<int> adjncy(2*nInternalFaces);
|
adjncy.setSize(nConnections);
|
||||||
|
|
||||||
|
xadj.setSize(cellCells.size()+1);
|
||||||
|
|
||||||
|
|
||||||
// Fill in xadj
|
// Fill in xadj
|
||||||
// ~~~~~~~~~~~~
|
// ~~~~~~~~~~~~
|
||||||
@ -506,211 +497,47 @@ Foam::labelList Foam::metisDecomp::decompose
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
xadj[cellCells.size()] = freeAdj;
|
xadj[cellCells.size()] = freeAdj;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// C style numbering
|
Foam::labelList Foam::metisDecomp::decompose
|
||||||
int numFlag = 0;
|
(
|
||||||
|
const labelList& agglom,
|
||||||
// Method of decomposition
|
const pointField& agglomPoints
|
||||||
// recursive: multi-level recursive bisection (default)
|
)
|
||||||
// k-way: multi-level k-way
|
{
|
||||||
word method("k-way");
|
if (agglom.size() != mesh_.nCells())
|
||||||
|
|
||||||
// decomposition options. 0 = use defaults
|
|
||||||
List<int> options(5, 0);
|
|
||||||
|
|
||||||
// processor weights initialised with no size, only used if specified in
|
|
||||||
// a file
|
|
||||||
Field<floatScalar> processorWeights;
|
|
||||||
|
|
||||||
// cell weights (so on the vertices of the dual)
|
|
||||||
List<int> cellWeights;
|
|
||||||
|
|
||||||
// Check for user supplied weights and decomp options
|
|
||||||
if (decompositionDict_.found("metisCoeffs"))
|
|
||||||
{
|
{
|
||||||
dictionary metisDecompCoeffs
|
FatalErrorIn
|
||||||
(
|
(
|
||||||
decompositionDict_.subDict("metisCoeffs")
|
"parMetisDecomp::decompose(const labelList&, const pointField&)"
|
||||||
|
) << "Size of cell-to-coarse map " << agglom.size()
|
||||||
|
<< " differs from number of cells in mesh " << mesh_.nCells()
|
||||||
|
<< exit(FatalError);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make Metis CSR (Compressed Storage Format) storage
|
||||||
|
// adjncy : contains neighbours (= edges in graph)
|
||||||
|
// xadj(celli) : start of information in adjncy for celli
|
||||||
|
List<int> adjncy;
|
||||||
|
List<int> xadj;
|
||||||
|
{
|
||||||
|
// Get cellCells on coarse mesh.
|
||||||
|
labelListList cellCells;
|
||||||
|
calcCellCells
|
||||||
|
(
|
||||||
|
mesh_,
|
||||||
|
agglom,
|
||||||
|
agglomPoints.size(),
|
||||||
|
cellCells
|
||||||
);
|
);
|
||||||
|
|
||||||
if (metisDecompCoeffs.found("method"))
|
calcMetisCSR(cellCells, adjncy, xadj);
|
||||||
{
|
|
||||||
metisDecompCoeffs.lookup("method") >> method;
|
|
||||||
|
|
||||||
if (method != "recursive" && method != "k-way")
|
|
||||||
{
|
|
||||||
FatalErrorIn("metisDecomp::decompose()")
|
|
||||||
<< "Method " << method << " in metisCoeffs in dictionary : "
|
|
||||||
<< decompositionDict_.name()
|
|
||||||
<< " should be 'recursive' or 'k-way'"
|
|
||||||
<< exit(FatalError);
|
|
||||||
}
|
|
||||||
|
|
||||||
Info<< "metisDecomp : Using Metis options " << options
|
|
||||||
<< endl << endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (metisDecompCoeffs.found("options"))
|
|
||||||
{
|
|
||||||
metisDecompCoeffs.lookup("options") >> options;
|
|
||||||
|
|
||||||
if (options.size() != 5)
|
|
||||||
{
|
|
||||||
FatalErrorIn("metisDecomp::decompose()")
|
|
||||||
<< "Number of options in metisCoeffs in dictionary : "
|
|
||||||
<< decompositionDict_.name()
|
|
||||||
<< " should be 5"
|
|
||||||
<< exit(FatalError);
|
|
||||||
}
|
|
||||||
|
|
||||||
Info<< "metisDecomp : Using Metis options " << options
|
|
||||||
<< endl << endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (metisDecompCoeffs.found("processorWeights"))
|
|
||||||
{
|
|
||||||
metisDecompCoeffs.lookup("processorWeights") >> processorWeights;
|
|
||||||
processorWeights /= sum(processorWeights);
|
|
||||||
|
|
||||||
if (processorWeights.size() != nProcessors_)
|
|
||||||
{
|
|
||||||
FatalErrorIn("metisDecomp::decompose(const pointField&)")
|
|
||||||
<< "Number of processor weights "
|
|
||||||
<< processorWeights.size()
|
|
||||||
<< " does not equal number of domains " << nProcessors_
|
|
||||||
<< exit(FatalError);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (metisDecompCoeffs.found("cellWeightsFile"))
|
|
||||||
{
|
|
||||||
Info<< "metisDecomp : Using cell-based weights." << endl;
|
|
||||||
|
|
||||||
word cellWeightsFile
|
|
||||||
(
|
|
||||||
metisDecompCoeffs.lookup("cellWeightsFile")
|
|
||||||
);
|
|
||||||
|
|
||||||
IOList<int> cellIOWeights
|
|
||||||
(
|
|
||||||
IOobject
|
|
||||||
(
|
|
||||||
cellWeightsFile,
|
|
||||||
mesh_.time().timeName(),
|
|
||||||
mesh_,
|
|
||||||
IOobject::MUST_READ,
|
|
||||||
IOobject::AUTO_WRITE
|
|
||||||
)
|
|
||||||
);
|
|
||||||
cellWeights.transfer(cellIOWeights);
|
|
||||||
|
|
||||||
if (cellWeights.size() != cellCells.size())
|
|
||||||
{
|
|
||||||
FatalErrorIn("metisDecomp::decompose(const pointField&)")
|
|
||||||
<< "Number of cell weights " << cellWeights.size()
|
|
||||||
<< " does not equal number of agglomerated cells "
|
|
||||||
<< cellCells.size() << exit(FatalError);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int numCells = cellCells.size();
|
// Decompose using default weights
|
||||||
int nProcs = nProcessors_;
|
List<int> finalDecomp;
|
||||||
|
decompose(adjncy, xadj, finalDecomp);
|
||||||
// output: cell -> processor addressing
|
|
||||||
List<int> finalDecomp(cellCells.size());
|
|
||||||
|
|
||||||
// output: number of cut edges
|
|
||||||
int edgeCut = 0;
|
|
||||||
|
|
||||||
// Vertex weight info
|
|
||||||
int wgtFlag = 0;
|
|
||||||
int* vwgtPtr = NULL;
|
|
||||||
int* adjwgtPtr = NULL;
|
|
||||||
|
|
||||||
if (cellWeights.size() > 0)
|
|
||||||
{
|
|
||||||
vwgtPtr = cellWeights.begin();
|
|
||||||
wgtFlag += 2; // Weights on vertices
|
|
||||||
}
|
|
||||||
|
|
||||||
if (method == "recursive")
|
|
||||||
{
|
|
||||||
if (processorWeights.size())
|
|
||||||
{
|
|
||||||
METIS_WPartGraphRecursive
|
|
||||||
(
|
|
||||||
&numCells, // num vertices in graph
|
|
||||||
xadj.begin(), // indexing into adjncy
|
|
||||||
adjncy.begin(), // neighbour info
|
|
||||||
vwgtPtr, // vertexweights
|
|
||||||
adjwgtPtr, // no edgeweights
|
|
||||||
&wgtFlag,
|
|
||||||
&numFlag,
|
|
||||||
&nProcs,
|
|
||||||
processorWeights.begin(),
|
|
||||||
options.begin(),
|
|
||||||
&edgeCut,
|
|
||||||
finalDecomp.begin()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
METIS_PartGraphRecursive
|
|
||||||
(
|
|
||||||
&numCells, // num vertices in graph
|
|
||||||
xadj.begin(), // indexing into adjncy
|
|
||||||
adjncy.begin(), // neighbour info
|
|
||||||
vwgtPtr, // vertexweights
|
|
||||||
adjwgtPtr, // no edgeweights
|
|
||||||
&wgtFlag,
|
|
||||||
&numFlag,
|
|
||||||
&nProcs,
|
|
||||||
options.begin(),
|
|
||||||
&edgeCut,
|
|
||||||
finalDecomp.begin()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (processorWeights.size())
|
|
||||||
{
|
|
||||||
METIS_WPartGraphKway
|
|
||||||
(
|
|
||||||
&numCells, // num vertices in graph
|
|
||||||
xadj.begin(), // indexing into adjncy
|
|
||||||
adjncy.begin(), // neighbour info
|
|
||||||
vwgtPtr, // vertexweights
|
|
||||||
adjwgtPtr, // no edgeweights
|
|
||||||
&wgtFlag,
|
|
||||||
&numFlag,
|
|
||||||
&nProcs,
|
|
||||||
processorWeights.begin(),
|
|
||||||
options.begin(),
|
|
||||||
&edgeCut,
|
|
||||||
finalDecomp.begin()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
METIS_PartGraphKway
|
|
||||||
(
|
|
||||||
&numCells, // num vertices in graph
|
|
||||||
xadj.begin(), // indexing into adjncy
|
|
||||||
adjncy.begin(), // neighbour info
|
|
||||||
vwgtPtr, // vertexweights
|
|
||||||
adjwgtPtr, // no edgeweights
|
|
||||||
&wgtFlag,
|
|
||||||
&numFlag,
|
|
||||||
&nProcs,
|
|
||||||
options.begin(),
|
|
||||||
&edgeCut,
|
|
||||||
finalDecomp.begin()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Rework back into decomposition for original mesh_
|
// Rework back into decomposition for original mesh_
|
||||||
@ -725,4 +552,44 @@ Foam::labelList Foam::metisDecomp::decompose
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::labelList Foam::metisDecomp::decompose
|
||||||
|
(
|
||||||
|
const labelListList& globalCellCells,
|
||||||
|
const pointField& cellCentres
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (cellCentres.size() != globalCellCells.size())
|
||||||
|
{
|
||||||
|
FatalErrorIn
|
||||||
|
(
|
||||||
|
"metisDecomp::decompose(const pointField&, const labelListList&)"
|
||||||
|
) << "Inconsistent number of cells (" << globalCellCells.size()
|
||||||
|
<< ") and number of cell centres (" << cellCentres.size()
|
||||||
|
<< ")." << exit(FatalError);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Make Metis CSR (Compressed Storage Format) storage
|
||||||
|
// adjncy : contains neighbours (= edges in graph)
|
||||||
|
// xadj(celli) : start of information in adjncy for celli
|
||||||
|
|
||||||
|
List<int> adjncy;
|
||||||
|
List<int> xadj;
|
||||||
|
calcMetisCSR(globalCellCells, adjncy, xadj);
|
||||||
|
|
||||||
|
|
||||||
|
// Decompose using default weights
|
||||||
|
List<int> finalDecomp;
|
||||||
|
decompose(adjncy, xadj, finalDecomp);
|
||||||
|
|
||||||
|
// Copy back to labelList
|
||||||
|
labelList decomp(finalDecomp.size());
|
||||||
|
forAll(decomp, i)
|
||||||
|
{
|
||||||
|
decomp[i] = finalDecomp[i];
|
||||||
|
}
|
||||||
|
return decomp;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
// ************************************************************************* //
|
||||||
|
|||||||
@ -55,6 +55,13 @@ class metisDecomp
|
|||||||
|
|
||||||
// Private Member Functions
|
// Private Member Functions
|
||||||
|
|
||||||
|
label decompose
|
||||||
|
(
|
||||||
|
const List<int>& adjncy,
|
||||||
|
const List<int>& xadj,
|
||||||
|
List<int>& finalDecomp
|
||||||
|
);
|
||||||
|
|
||||||
//- Disallow default bitwise copy construct and assignment
|
//- Disallow default bitwise copy construct and assignment
|
||||||
void operator=(const metisDecomp&);
|
void operator=(const metisDecomp&);
|
||||||
metisDecomp(const metisDecomp&);
|
metisDecomp(const metisDecomp&);
|
||||||
@ -90,9 +97,40 @@ public:
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//- Return for every coordinate the wanted processor number. Use the
|
||||||
|
// mesh connectivity (if needed)
|
||||||
virtual labelList decompose(const pointField&);
|
virtual labelList decompose(const pointField&);
|
||||||
|
|
||||||
virtual labelList decompose(const labelList& agglom, const pointField&);
|
//- Return for every coordinate the wanted processor number. Gets
|
||||||
|
// passed agglomeration map (from fine to coarse cells) and coarse cell
|
||||||
|
// location. Can be overridden by decomposers that provide this
|
||||||
|
// functionality natively.
|
||||||
|
virtual labelList decompose
|
||||||
|
(
|
||||||
|
const labelList& agglom,
|
||||||
|
const pointField&
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Return for every coordinate the wanted processor number. Explicitly
|
||||||
|
// provided mesh connectivity.
|
||||||
|
// The connectivity is equal to mesh.cellCells() except for
|
||||||
|
// - in parallel the cell numbers are global cell numbers (starting
|
||||||
|
// from 0 at processor0 and then incrementing all through the
|
||||||
|
// processors)
|
||||||
|
// - the connections are across coupled patches
|
||||||
|
virtual labelList decompose
|
||||||
|
(
|
||||||
|
const labelListList& globalCellCells,
|
||||||
|
const pointField& cc
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Helper to convert cellcells into Metis storage
|
||||||
|
static void calcMetisCSR
|
||||||
|
(
|
||||||
|
const labelListList& globalCellCells,
|
||||||
|
List<int>& adjncy,
|
||||||
|
List<int>& xadj
|
||||||
|
);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -92,6 +92,16 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
virtual labelList decompose(const pointField&);
|
virtual labelList decompose(const pointField&);
|
||||||
|
|
||||||
|
//- Explicitly provided connectivity
|
||||||
|
virtual labelList decompose
|
||||||
|
(
|
||||||
|
const labelListList& globalCellCells,
|
||||||
|
const pointField& cc
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return decompose(cc);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -2,8 +2,8 @@ include $(RULES)/mplib$(WM_MPLIB)
|
|||||||
|
|
||||||
EXE_INC = \
|
EXE_INC = \
|
||||||
$(PFLAGS) $(PINC) \
|
$(PFLAGS) $(PINC) \
|
||||||
-I$(THIRD_PARTY)/ParMetis-3.1/ParMETISLib \
|
-I$(WM_THIRD_PARTY_DIR)/ParMetis-3.1/ParMETISLib \
|
||||||
-I$(THIRD_PARTY)/ParMetis-3.1 \
|
-I$(WM_THIRD_PARTY_DIR)/ParMetis-3.1 \
|
||||||
-I../decompositionMethods/lnInclude
|
-I../decompositionMethods/lnInclude
|
||||||
|
|
||||||
LIB_LIBS = \
|
LIB_LIBS = \
|
||||||
|
|||||||
@ -32,6 +32,7 @@ License
|
|||||||
#include "polyMesh.H"
|
#include "polyMesh.H"
|
||||||
#include "Time.H"
|
#include "Time.H"
|
||||||
#include "labelIOField.H"
|
#include "labelIOField.H"
|
||||||
|
#include "globalIndex.H"
|
||||||
|
|
||||||
#include <mpi.h>
|
#include <mpi.h>
|
||||||
|
|
||||||
@ -56,6 +57,267 @@ namespace Foam
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//- Does prevention of 0 cell domains and calls parmetis.
|
||||||
|
Foam::label Foam::parMetisDecomp::decompose
|
||||||
|
(
|
||||||
|
Field<int>& xadj,
|
||||||
|
Field<int>& adjncy,
|
||||||
|
const pointField& cellCentres,
|
||||||
|
Field<int>& cellWeights,
|
||||||
|
Field<int>& faceWeights,
|
||||||
|
const List<int>& options,
|
||||||
|
|
||||||
|
List<int>& finalDecomp
|
||||||
|
)
|
||||||
|
{
|
||||||
|
// C style numbering
|
||||||
|
int numFlag = 0;
|
||||||
|
|
||||||
|
// Number of dimensions
|
||||||
|
int nDims = 3;
|
||||||
|
|
||||||
|
// Get number of cells on all processors
|
||||||
|
List<int> nLocalCells(Pstream::nProcs());
|
||||||
|
nLocalCells[Pstream::myProcNo()] = xadj.size()-1;
|
||||||
|
Pstream::gatherList(nLocalCells);
|
||||||
|
Pstream::scatterList(nLocalCells);
|
||||||
|
|
||||||
|
// Get cell offsets.
|
||||||
|
List<int> cellOffsets(Pstream::nProcs()+1);
|
||||||
|
int nGlobalCells = 0;
|
||||||
|
forAll(nLocalCells, procI)
|
||||||
|
{
|
||||||
|
cellOffsets[procI] = nGlobalCells;
|
||||||
|
nGlobalCells += nLocalCells[procI];
|
||||||
|
}
|
||||||
|
cellOffsets[Pstream::nProcs()] = nGlobalCells;
|
||||||
|
|
||||||
|
// Convert pointField into float
|
||||||
|
Field<floatScalar> xyz(3*cellCentres.size());
|
||||||
|
int compI = 0;
|
||||||
|
forAll(cellCentres, cellI)
|
||||||
|
{
|
||||||
|
const point& cc = cellCentres[cellI];
|
||||||
|
xyz[compI++] = float(cc.x());
|
||||||
|
xyz[compI++] = float(cc.y());
|
||||||
|
xyz[compI++] = float(cc.z());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make sure every domain has at least one cell
|
||||||
|
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
// (Metis falls over with zero sized domains)
|
||||||
|
// Trickle cells from processors that have them down to those that
|
||||||
|
// don't.
|
||||||
|
|
||||||
|
|
||||||
|
// Number of cells to send down (is same as number of cells next processor
|
||||||
|
// has to receive)
|
||||||
|
List<int> nSendCells(Pstream::nProcs(), 0);
|
||||||
|
|
||||||
|
for (label procI = nLocalCells.size()-1; procI >=1; procI--)
|
||||||
|
{
|
||||||
|
if (nLocalCells[procI]-nSendCells[procI] < 1)
|
||||||
|
{
|
||||||
|
nSendCells[procI-1] = nSendCells[procI]-nLocalCells[procI]+1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// First receive (so increasing the sizes of all arrays)
|
||||||
|
|
||||||
|
if (Pstream::myProcNo() >= 1 && nSendCells[Pstream::myProcNo()-1] > 0)
|
||||||
|
{
|
||||||
|
// Receive cells from previous processor
|
||||||
|
IPstream fromPrevProc(Pstream::blocking, Pstream::myProcNo()-1);
|
||||||
|
|
||||||
|
Field<int> prevXadj(fromPrevProc);
|
||||||
|
Field<int> prevAdjncy(fromPrevProc);
|
||||||
|
Field<floatScalar> prevXyz(fromPrevProc);
|
||||||
|
Field<int> prevCellWeights(fromPrevProc);
|
||||||
|
Field<int> prevFaceWeights(fromPrevProc);
|
||||||
|
|
||||||
|
// Insert adjncy
|
||||||
|
prepend(prevAdjncy, adjncy);
|
||||||
|
// Adapt offsets and prepend xadj
|
||||||
|
xadj += prevAdjncy.size();
|
||||||
|
prepend(prevXadj, xadj);
|
||||||
|
// Coords
|
||||||
|
prepend(prevXyz, xyz);
|
||||||
|
// Weights
|
||||||
|
prepend(prevCellWeights, cellWeights);
|
||||||
|
prepend(prevFaceWeights, faceWeights);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Send to my next processor
|
||||||
|
|
||||||
|
if (nSendCells[Pstream::myProcNo()] > 0)
|
||||||
|
{
|
||||||
|
// Send cells to next processor
|
||||||
|
OPstream toNextProc(Pstream::blocking, Pstream::myProcNo()+1);
|
||||||
|
|
||||||
|
int nCells = nSendCells[Pstream::myProcNo()];
|
||||||
|
int startCell = xadj.size()-1 - nCells;
|
||||||
|
int startFace = xadj[startCell];
|
||||||
|
int nFaces = adjncy.size()-startFace;
|
||||||
|
|
||||||
|
// Send for all cell data: last nCells elements
|
||||||
|
// Send for all face data: last nFaces elements
|
||||||
|
toNextProc
|
||||||
|
<< Field<int>::subField(xadj, nCells, startCell)-startFace
|
||||||
|
<< Field<int>::subField(adjncy, nFaces, startFace)
|
||||||
|
<< SubField<floatScalar>(xyz, nDims*nCells, nDims*startCell)
|
||||||
|
<<
|
||||||
|
(
|
||||||
|
(cellWeights.size() > 0)
|
||||||
|
? static_cast<const Field<int>&>
|
||||||
|
(
|
||||||
|
Field<int>::subField(cellWeights, nCells, startCell)
|
||||||
|
)
|
||||||
|
: Field<int>(0)
|
||||||
|
)
|
||||||
|
<<
|
||||||
|
(
|
||||||
|
(faceWeights.size() > 0)
|
||||||
|
? static_cast<const Field<int>&>
|
||||||
|
(
|
||||||
|
Field<int>::subField(faceWeights, nFaces, startFace)
|
||||||
|
)
|
||||||
|
: Field<int>(0)
|
||||||
|
);
|
||||||
|
|
||||||
|
// Remove data that has been sent
|
||||||
|
if (faceWeights.size() > 0)
|
||||||
|
{
|
||||||
|
faceWeights.setSize(faceWeights.size()-nFaces);
|
||||||
|
}
|
||||||
|
if (cellWeights.size() > 0)
|
||||||
|
{
|
||||||
|
cellWeights.setSize(cellWeights.size()-nCells);
|
||||||
|
}
|
||||||
|
xyz.setSize(xyz.size()-nDims*nCells);
|
||||||
|
adjncy.setSize(adjncy.size()-nFaces);
|
||||||
|
xadj.setSize(xadj.size() - nCells);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Adapt number of cells
|
||||||
|
forAll(nSendCells, procI)
|
||||||
|
{
|
||||||
|
// Sent cells
|
||||||
|
nLocalCells[procI] -= nSendCells[procI];
|
||||||
|
|
||||||
|
if (procI >= 1)
|
||||||
|
{
|
||||||
|
// Received cells
|
||||||
|
nLocalCells[procI] += nSendCells[procI-1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Adapt cellOffsets
|
||||||
|
nGlobalCells = 0;
|
||||||
|
forAll(nLocalCells, procI)
|
||||||
|
{
|
||||||
|
cellOffsets[procI] = nGlobalCells;
|
||||||
|
nGlobalCells += nLocalCells[procI];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Weight info
|
||||||
|
int wgtFlag = 0;
|
||||||
|
int* vwgtPtr = NULL;
|
||||||
|
int* adjwgtPtr = NULL;
|
||||||
|
|
||||||
|
if (cellWeights.size() > 0)
|
||||||
|
{
|
||||||
|
vwgtPtr = cellWeights.begin();
|
||||||
|
wgtFlag += 2; // Weights on vertices
|
||||||
|
}
|
||||||
|
if (faceWeights.size() > 0)
|
||||||
|
{
|
||||||
|
adjwgtPtr = faceWeights.begin();
|
||||||
|
wgtFlag += 1; // Weights on edges
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Number of weights or balance constraints
|
||||||
|
int nCon = 1;
|
||||||
|
// Per processor, per constraint the weight
|
||||||
|
Field<floatScalar> tpwgts(nCon*nProcessors_, 1./nProcessors_);
|
||||||
|
// Imbalance tolerance
|
||||||
|
Field<floatScalar> ubvec(nCon, 1.02);
|
||||||
|
if (nProcessors_ == 1)
|
||||||
|
{
|
||||||
|
// If only one processor there is no imbalance.
|
||||||
|
ubvec[0] = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
MPI_Comm comm = MPI_COMM_WORLD;
|
||||||
|
|
||||||
|
// output: cell -> processor addressing
|
||||||
|
finalDecomp.setSize(nLocalCells[Pstream::myProcNo()]);
|
||||||
|
|
||||||
|
// output: number of cut edges
|
||||||
|
int edgeCut = 0;
|
||||||
|
|
||||||
|
|
||||||
|
ParMETIS_V3_PartGeomKway
|
||||||
|
(
|
||||||
|
cellOffsets.begin(), // vtxDist
|
||||||
|
xadj.begin(),
|
||||||
|
adjncy.begin(),
|
||||||
|
vwgtPtr, // vertexweights
|
||||||
|
adjwgtPtr, // edgeweights
|
||||||
|
&wgtFlag,
|
||||||
|
&numFlag,
|
||||||
|
&nDims,
|
||||||
|
xyz.begin(),
|
||||||
|
&nCon,
|
||||||
|
&nProcessors_, // nParts
|
||||||
|
tpwgts.begin(),
|
||||||
|
ubvec.begin(),
|
||||||
|
const_cast<List<int>&>(options).begin(),
|
||||||
|
&edgeCut,
|
||||||
|
finalDecomp.begin(),
|
||||||
|
&comm
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
// If we sent cells across make sure we undo it
|
||||||
|
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
// Receive back from next processor if I sent something
|
||||||
|
if (nSendCells[Pstream::myProcNo()] > 0)
|
||||||
|
{
|
||||||
|
IPstream fromNextProc(Pstream::blocking, Pstream::myProcNo()+1);
|
||||||
|
|
||||||
|
List<int> nextFinalDecomp(fromNextProc);
|
||||||
|
|
||||||
|
append(nextFinalDecomp, finalDecomp);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Send back to previous processor.
|
||||||
|
if (Pstream::myProcNo() >= 1 && nSendCells[Pstream::myProcNo()-1] > 0)
|
||||||
|
{
|
||||||
|
OPstream toPrevProc(Pstream::blocking, Pstream::myProcNo()-1);
|
||||||
|
|
||||||
|
int nToPrevious = nSendCells[Pstream::myProcNo()-1];
|
||||||
|
|
||||||
|
toPrevProc <<
|
||||||
|
SubList<int>
|
||||||
|
(
|
||||||
|
finalDecomp,
|
||||||
|
nToPrevious,
|
||||||
|
finalDecomp.size()-nToPrevious
|
||||||
|
);
|
||||||
|
|
||||||
|
// Remove locally what has been sent
|
||||||
|
finalDecomp.setSize(finalDecomp.size()-nToPrevious);
|
||||||
|
}
|
||||||
|
|
||||||
|
return edgeCut;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
Foam::parMetisDecomp::parMetisDecomp
|
Foam::parMetisDecomp::parMetisDecomp
|
||||||
@ -73,30 +335,35 @@ Foam::parMetisDecomp::parMetisDecomp
|
|||||||
|
|
||||||
Foam::labelList Foam::parMetisDecomp::decompose(const pointField& points)
|
Foam::labelList Foam::parMetisDecomp::decompose(const pointField& points)
|
||||||
{
|
{
|
||||||
|
if (points.size() != mesh_.nCells())
|
||||||
|
{
|
||||||
|
FatalErrorIn("parMetisDecomp::decompose(const pointField&)")
|
||||||
|
<< "Can use this decomposition method only for the whole mesh"
|
||||||
|
<< endl
|
||||||
|
<< "and supply one coordinate (cellCentre) for every cell." << endl
|
||||||
|
<< "The number of coordinates " << points.size() << endl
|
||||||
|
<< "The number of cells in the mesh " << mesh_.nCells()
|
||||||
|
<< exit(FatalError);
|
||||||
|
}
|
||||||
|
|
||||||
// For running sequential ...
|
// For running sequential ...
|
||||||
if (Pstream::nProcs() <= 1)
|
if (Pstream::nProcs() <= 1)
|
||||||
{
|
{
|
||||||
return metisDecomp(decompositionDict_, mesh_).decompose(points);
|
return metisDecomp(decompositionDict_, mesh_).decompose(points);
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
|
||||||
// Make Metis Distributed CSR (Compressed Storage Format) storage
|
|
||||||
// adjncy : contains cellCells (= edges in graph)
|
|
||||||
// xadj(celli) : start of information in adjncy for celli
|
|
||||||
//
|
|
||||||
|
|
||||||
// Create global cell numbers
|
// Create global cell numbers
|
||||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
// Get number of cells on all processors
|
// Get number of cells on all processors
|
||||||
labelList nLocalCells(Pstream::nProcs());
|
List<int> nLocalCells(Pstream::nProcs());
|
||||||
nLocalCells[Pstream::myProcNo()] = mesh_.nCells();
|
nLocalCells[Pstream::myProcNo()] = mesh_.nCells();
|
||||||
Pstream::gatherList(nLocalCells);
|
Pstream::gatherList(nLocalCells);
|
||||||
Pstream::scatterList(nLocalCells);
|
Pstream::scatterList(nLocalCells);
|
||||||
|
|
||||||
// Get cell offsets.
|
// Get cell offsets.
|
||||||
labelList cellOffsets(Pstream::nProcs()+1);
|
List<int> cellOffsets(Pstream::nProcs()+1);
|
||||||
label nGlobalCells = 0;
|
int nGlobalCells = 0;
|
||||||
forAll(nLocalCells, procI)
|
forAll(nLocalCells, procI)
|
||||||
{
|
{
|
||||||
cellOffsets[procI] = nGlobalCells;
|
cellOffsets[procI] = nGlobalCells;
|
||||||
@ -104,7 +371,14 @@ Foam::labelList Foam::parMetisDecomp::decompose(const pointField& points)
|
|||||||
}
|
}
|
||||||
cellOffsets[Pstream::nProcs()] = nGlobalCells;
|
cellOffsets[Pstream::nProcs()] = nGlobalCells;
|
||||||
|
|
||||||
label myOffset = cellOffsets[Pstream::myProcNo()];
|
int myOffset = cellOffsets[Pstream::myProcNo()];
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// Make Metis Distributed CSR (Compressed Storage Format) storage
|
||||||
|
// adjncy : contains cellCells (= edges in graph)
|
||||||
|
// xadj(celli) : start of information in adjncy for celli
|
||||||
|
//
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -116,7 +390,7 @@ Foam::labelList Foam::parMetisDecomp::decompose(const pointField& points)
|
|||||||
// Get renumbered owner on other side of coupled faces
|
// Get renumbered owner on other side of coupled faces
|
||||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
labelList globalNeighbour(mesh_.nFaces()-mesh_.nInternalFaces());
|
List<int> globalNeighbour(mesh_.nFaces()-mesh_.nInternalFaces());
|
||||||
|
|
||||||
forAll(patches, patchI)
|
forAll(patches, patchI)
|
||||||
{
|
{
|
||||||
@ -142,7 +416,7 @@ Foam::labelList Foam::parMetisDecomp::decompose(const pointField& points)
|
|||||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
// Number of faces per cell
|
// Number of faces per cell
|
||||||
labelList nFacesPerCell(mesh_.nCells(), 0);
|
List<int> nFacesPerCell(mesh_.nCells(), 0);
|
||||||
|
|
||||||
// Number of coupled faces
|
// Number of coupled faces
|
||||||
label nCoupledFaces = 0;
|
label nCoupledFaces = 0;
|
||||||
@ -167,15 +441,15 @@ Foam::labelList Foam::parMetisDecomp::decompose(const pointField& points)
|
|||||||
nFacesPerCell[faceOwner[faceI++]]++;
|
nFacesPerCell[faceOwner[faceI++]]++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Fill in xadj
|
// Fill in xadj
|
||||||
// ~~~~~~~~~~~~
|
// ~~~~~~~~~~~~
|
||||||
|
|
||||||
labelField xadj(mesh_.nCells()+1, -1);
|
Field<int> xadj(mesh_.nCells()+1, -1);
|
||||||
|
|
||||||
label freeAdj = 0;
|
int freeAdj = 0;
|
||||||
|
|
||||||
for (label cellI = 0; cellI < mesh_.nCells(); cellI++)
|
for (label cellI = 0; cellI < mesh_.nCells(); cellI++)
|
||||||
{
|
{
|
||||||
@ -190,7 +464,7 @@ Foam::labelList Foam::parMetisDecomp::decompose(const pointField& points)
|
|||||||
// Fill in adjncy
|
// Fill in adjncy
|
||||||
// ~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~
|
||||||
|
|
||||||
labelField adjncy(2*mesh_.nInternalFaces() + nCoupledFaces, -1);
|
Field<int> adjncy(2*mesh_.nInternalFaces() + nCoupledFaces, -1);
|
||||||
|
|
||||||
nFacesPerCell = 0;
|
nFacesPerCell = 0;
|
||||||
|
|
||||||
@ -223,41 +497,21 @@ Foam::labelList Foam::parMetisDecomp::decompose(const pointField& points)
|
|||||||
bFaceI++;
|
bFaceI++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// C style numbering
|
|
||||||
int numFlag = 0;
|
|
||||||
|
|
||||||
// Number of dimensions
|
|
||||||
int nDims = 3;
|
|
||||||
|
|
||||||
// cell centres
|
|
||||||
Field<floatScalar> xyz(nDims*mesh_.nCells());
|
|
||||||
const pointField& cellCentres = mesh_.cellCentres();
|
|
||||||
label compI = 0;
|
|
||||||
forAll(cellCentres, cellI)
|
|
||||||
{
|
|
||||||
const point& cc = cellCentres[cellI];
|
|
||||||
xyz[compI++] = float(cc.x());
|
|
||||||
xyz[compI++] = float(cc.y());
|
|
||||||
xyz[compI++] = float(cc.z());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// decomposition options. 0 = use defaults
|
// decomposition options. 0 = use defaults
|
||||||
labelList options(3, 0);
|
List<int> options(3, 0);
|
||||||
//options[0] = 1; // don't use defaults but use values below
|
//options[0] = 1; // don't use defaults but use values below
|
||||||
//options[1] = -1; // full debug info
|
//options[1] = -1; // full debug info
|
||||||
//options[2] = 15; // random number seed
|
//options[2] = 15; // random number seed
|
||||||
|
|
||||||
|
|
||||||
// cell weights (so on the vertices of the dual)
|
// cell weights (so on the vertices of the dual)
|
||||||
labelField cellWeights;
|
Field<int> cellWeights;
|
||||||
|
|
||||||
// face weights (so on the edges of the dual)
|
// face weights (so on the edges of the dual)
|
||||||
labelField faceWeights;
|
Field<int> faceWeights;
|
||||||
|
|
||||||
// Check for user supplied weights and decomp options
|
// Check for user supplied weights and decomp options
|
||||||
if (decompositionDict_.found("metisCoeffs"))
|
if (decompositionDict_.found("metisCoeffs"))
|
||||||
@ -364,7 +618,7 @@ Foam::labelList Foam::parMetisDecomp::decompose(const pointField& points)
|
|||||||
faceI++;
|
faceI++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (parMetisDecompCoeffs.found("options"))
|
if (parMetisDecompCoeffs.found("options"))
|
||||||
@ -384,219 +638,353 @@ Foam::labelList Foam::parMetisDecomp::decompose(const pointField& points)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Do actual decomposition
|
||||||
// Make sure every domain has at least one cell
|
List<int> finalDecomp;
|
||||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
decompose
|
||||||
// (Metis falls over with zero sized domains)
|
|
||||||
// Trickle cells from processors that have them down to those that
|
|
||||||
// don't.
|
|
||||||
|
|
||||||
|
|
||||||
// Number of cells to send down (is same as number of cells next processor
|
|
||||||
// has to receive)
|
|
||||||
labelList nSendCells(Pstream::nProcs(), 0);
|
|
||||||
|
|
||||||
for (label procI = nLocalCells.size()-1; procI >=1; procI--)
|
|
||||||
{
|
|
||||||
if (nLocalCells[procI]-nSendCells[procI] < 1)
|
|
||||||
{
|
|
||||||
nSendCells[procI-1] = nSendCells[procI]-nLocalCells[procI]+1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// First receive (so increasing the sizes of all arrays)
|
|
||||||
|
|
||||||
if (Pstream::myProcNo() >= 1 && nSendCells[Pstream::myProcNo()-1] > 0)
|
|
||||||
{
|
|
||||||
// Receive cells from previous processor
|
|
||||||
IPstream fromPrevProc(Pstream::blocking, Pstream::myProcNo()-1);
|
|
||||||
|
|
||||||
labelField prevXadj(fromPrevProc);
|
|
||||||
labelField prevAdjncy(fromPrevProc);
|
|
||||||
Field<floatScalar> prevXyz(fromPrevProc);
|
|
||||||
labelField prevCellWeights(fromPrevProc);
|
|
||||||
labelField prevFaceWeights(fromPrevProc);
|
|
||||||
|
|
||||||
// Insert adjncy
|
|
||||||
prepend(prevAdjncy, adjncy);
|
|
||||||
// Adapt offsets and prepend xadj
|
|
||||||
xadj += prevAdjncy.size();
|
|
||||||
prepend(prevXadj, xadj);
|
|
||||||
// Coords
|
|
||||||
prepend(prevXyz, xyz);
|
|
||||||
// Weights
|
|
||||||
prepend(prevCellWeights, cellWeights);
|
|
||||||
prepend(prevFaceWeights, faceWeights);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Send to my next processor
|
|
||||||
|
|
||||||
if (nSendCells[Pstream::myProcNo()] > 0)
|
|
||||||
{
|
|
||||||
// Send cells to next processor
|
|
||||||
OPstream toNextProc(Pstream::blocking, Pstream::myProcNo()+1);
|
|
||||||
|
|
||||||
label nCells = nSendCells[Pstream::myProcNo()];
|
|
||||||
label startCell = xadj.size()-1 - nCells;
|
|
||||||
label startFace = xadj[startCell];
|
|
||||||
label nFaces = adjncy.size()-startFace;
|
|
||||||
|
|
||||||
// Send for all cell data: last nCells elements
|
|
||||||
// Send for all face data: last nFaces elements
|
|
||||||
toNextProc
|
|
||||||
<< labelField::subField(xadj, nCells, startCell)-startFace
|
|
||||||
<< labelField::subField(adjncy, nFaces, startFace)
|
|
||||||
<< SubField<floatScalar>(xyz, nDims*nCells, nDims*startCell)
|
|
||||||
<<
|
|
||||||
(
|
|
||||||
(cellWeights.size() > 0)
|
|
||||||
? static_cast<const labelField&>
|
|
||||||
(
|
|
||||||
labelField::subField(cellWeights, nCells, startCell)
|
|
||||||
)
|
|
||||||
: labelField(0)
|
|
||||||
)
|
|
||||||
<<
|
|
||||||
(
|
|
||||||
(faceWeights.size() > 0)
|
|
||||||
? static_cast<const labelField&>
|
|
||||||
(
|
|
||||||
labelField::subField(faceWeights, nFaces, startFace)
|
|
||||||
)
|
|
||||||
: labelField(0)
|
|
||||||
);
|
|
||||||
|
|
||||||
// Remove data that has been sent
|
|
||||||
if (faceWeights.size() > 0)
|
|
||||||
{
|
|
||||||
faceWeights.setSize(faceWeights.size()-nFaces);
|
|
||||||
}
|
|
||||||
if (cellWeights.size() > 0)
|
|
||||||
{
|
|
||||||
cellWeights.setSize(cellWeights.size()-nCells);
|
|
||||||
}
|
|
||||||
xyz.setSize(xyz.size()-nDims*nCells);
|
|
||||||
adjncy.setSize(adjncy.size()-nFaces);
|
|
||||||
xadj.setSize(xadj.size() - nCells);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Adapt number of cells
|
|
||||||
forAll(nSendCells, procI)
|
|
||||||
{
|
|
||||||
// Sent cells
|
|
||||||
nLocalCells[procI] -= nSendCells[procI];
|
|
||||||
|
|
||||||
if (procI >= 1)
|
|
||||||
{
|
|
||||||
// Received cells
|
|
||||||
nLocalCells[procI] += nSendCells[procI-1];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Adapt cellOffsets
|
|
||||||
nGlobalCells = 0;
|
|
||||||
forAll(nLocalCells, procI)
|
|
||||||
{
|
|
||||||
cellOffsets[procI] = nGlobalCells;
|
|
||||||
nGlobalCells += nLocalCells[procI];
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Weight info
|
|
||||||
int wgtFlag = 0;
|
|
||||||
label* vwgtPtr = NULL;
|
|
||||||
label* adjwgtPtr = NULL;
|
|
||||||
|
|
||||||
if (cellWeights.size() > 0)
|
|
||||||
{
|
|
||||||
vwgtPtr = cellWeights.begin();
|
|
||||||
wgtFlag += 2; // Weights on vertices
|
|
||||||
}
|
|
||||||
if (faceWeights.size() > 0)
|
|
||||||
{
|
|
||||||
adjwgtPtr = faceWeights.begin();
|
|
||||||
wgtFlag += 1; // Weights on edges
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Number of weights or balance constraints
|
|
||||||
int nCon = 1;
|
|
||||||
// Per processor, per constraint the weight
|
|
||||||
Field<floatScalar> tpwgts(nCon*nProcessors_, 1./nProcessors_);
|
|
||||||
// Imbalance tolerance
|
|
||||||
Field<floatScalar> ubvec(nCon, 1.02);
|
|
||||||
if (nProcessors_ == 1)
|
|
||||||
{
|
|
||||||
// If only one processor there is no imbalance.
|
|
||||||
ubvec[0] = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
MPI_Comm comm = MPI_COMM_WORLD;
|
|
||||||
|
|
||||||
// output: cell -> processor addressing
|
|
||||||
labelList finalDecomp(nLocalCells[Pstream::myProcNo()]);
|
|
||||||
|
|
||||||
// output: number of cut edges
|
|
||||||
int edgeCut = 0;
|
|
||||||
|
|
||||||
|
|
||||||
ParMETIS_V3_PartGeomKway
|
|
||||||
(
|
(
|
||||||
cellOffsets.begin(), // vtxDist
|
xadj,
|
||||||
xadj.begin(),
|
adjncy,
|
||||||
adjncy.begin(),
|
points,
|
||||||
vwgtPtr, // vertexweights
|
cellWeights,
|
||||||
adjwgtPtr, // edgeweights
|
faceWeights,
|
||||||
&wgtFlag,
|
options,
|
||||||
&numFlag,
|
|
||||||
&nDims,
|
finalDecomp
|
||||||
xyz.begin(),
|
|
||||||
&nCon,
|
|
||||||
&nProcessors_, // nParts
|
|
||||||
tpwgts.begin(),
|
|
||||||
ubvec.begin(),
|
|
||||||
options.begin(),
|
|
||||||
&edgeCut,
|
|
||||||
finalDecomp.begin(),
|
|
||||||
&comm
|
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Copy back to labelList
|
||||||
// If we sent cells across make sure we undo it
|
labelList decomp(finalDecomp.size());
|
||||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
forAll(decomp, i)
|
||||||
|
|
||||||
// Receive back from next processor if I sent something
|
|
||||||
if (nSendCells[Pstream::myProcNo()] > 0)
|
|
||||||
{
|
{
|
||||||
IPstream fromNextProc(Pstream::blocking, Pstream::myProcNo()+1);
|
decomp[i] = finalDecomp[i];
|
||||||
|
}
|
||||||
|
return decomp;
|
||||||
|
}
|
||||||
|
|
||||||
labelList nextFinalDecomp(fromNextProc);
|
|
||||||
|
|
||||||
append(nextFinalDecomp, finalDecomp);
|
Foam::labelList Foam::parMetisDecomp::decompose
|
||||||
|
(
|
||||||
|
const labelList& cellToRegion,
|
||||||
|
const pointField& regionPoints
|
||||||
|
)
|
||||||
|
{
|
||||||
|
const labelList& faceOwner = mesh_.faceOwner();
|
||||||
|
const labelList& faceNeighbour = mesh_.faceNeighbour();
|
||||||
|
const polyBoundaryMesh& patches = mesh_.boundaryMesh();
|
||||||
|
|
||||||
|
if (cellToRegion.size() != mesh_.nCells())
|
||||||
|
{
|
||||||
|
FatalErrorIn
|
||||||
|
(
|
||||||
|
"parMetisDecomp::decompose(const labelList&, const pointField&)"
|
||||||
|
) << "Size of cell-to-coarse map " << cellToRegion.size()
|
||||||
|
<< " differs from number of cells in mesh " << mesh_.nCells()
|
||||||
|
<< exit(FatalError);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Send back to previous processor.
|
|
||||||
if (Pstream::myProcNo() >= 1 && nSendCells[Pstream::myProcNo()-1] > 0)
|
// Global region numbering engine
|
||||||
|
globalIndex globalRegions(regionPoints.size());
|
||||||
|
|
||||||
|
|
||||||
|
// Get renumbered owner region on other side of coupled faces
|
||||||
|
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
List<int> globalNeighbour(mesh_.nFaces()-mesh_.nInternalFaces());
|
||||||
|
|
||||||
|
forAll(patches, patchI)
|
||||||
{
|
{
|
||||||
OPstream toPrevProc(Pstream::blocking, Pstream::myProcNo()-1);
|
const polyPatch& pp = patches[patchI];
|
||||||
|
|
||||||
label nToPrevious = nSendCells[Pstream::myProcNo()-1];
|
if (pp.coupled())
|
||||||
|
{
|
||||||
|
label faceI = pp.start();
|
||||||
|
label bFaceI = pp.start() - mesh_.nInternalFaces();
|
||||||
|
|
||||||
toPrevProc <<
|
forAll(pp, i)
|
||||||
SubList<label>
|
{
|
||||||
|
label ownRegion = cellToRegion[faceOwner[faceI]];
|
||||||
|
globalNeighbour[bFaceI++] = globalRegions.toGlobal(ownRegion);
|
||||||
|
faceI++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the cell on the other side of coupled patches
|
||||||
|
syncTools::swapBoundaryFaceList(mesh_, globalNeighbour, false);
|
||||||
|
|
||||||
|
|
||||||
|
// Get globalCellCells on coarse mesh
|
||||||
|
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
labelListList globalRegionRegions;
|
||||||
|
{
|
||||||
|
List<DynamicList<label> > dynRegionRegions(regionPoints.size());
|
||||||
|
|
||||||
|
// Internal faces first
|
||||||
|
forAll(faceNeighbour, faceI)
|
||||||
|
{
|
||||||
|
label ownRegion = cellToRegion[faceOwner[faceI]];
|
||||||
|
label neiRegion = cellToRegion[faceNeighbour[faceI]];
|
||||||
|
|
||||||
|
if (ownRegion != neiRegion)
|
||||||
|
{
|
||||||
|
label globalOwn = globalRegions.toGlobal(ownRegion);
|
||||||
|
label globalNei = globalRegions.toGlobal(neiRegion);
|
||||||
|
|
||||||
|
if (findIndex(dynRegionRegions[ownRegion], globalNei) == -1)
|
||||||
|
{
|
||||||
|
dynRegionRegions[ownRegion].append(globalNei);
|
||||||
|
}
|
||||||
|
if (findIndex(dynRegionRegions[neiRegion], globalOwn) == -1)
|
||||||
|
{
|
||||||
|
dynRegionRegions[neiRegion].append(globalOwn);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Coupled boundary faces
|
||||||
|
forAll(patches, patchI)
|
||||||
|
{
|
||||||
|
const polyPatch& pp = patches[patchI];
|
||||||
|
|
||||||
|
if (pp.coupled())
|
||||||
|
{
|
||||||
|
label faceI = pp.start();
|
||||||
|
label bFaceI = pp.start() - mesh_.nInternalFaces();
|
||||||
|
|
||||||
|
forAll(pp, i)
|
||||||
|
{
|
||||||
|
label ownRegion = cellToRegion[faceOwner[faceI]];
|
||||||
|
label globalNei = globalNeighbour[bFaceI++];
|
||||||
|
faceI++;
|
||||||
|
|
||||||
|
if (findIndex(dynRegionRegions[ownRegion], globalNei) == -1)
|
||||||
|
{
|
||||||
|
dynRegionRegions[ownRegion].append(globalNei);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
globalRegionRegions.setSize(dynRegionRegions.size());
|
||||||
|
forAll(dynRegionRegions, i)
|
||||||
|
{
|
||||||
|
globalRegionRegions[i].transfer(dynRegionRegions[i].shrink());
|
||||||
|
dynRegionRegions[i].clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
labelList regionDecomp(decompose(globalRegionRegions, regionPoints));
|
||||||
|
|
||||||
|
// Rework back into decomposition for original mesh_
|
||||||
|
labelList cellDistribution(cellToRegion.size());
|
||||||
|
|
||||||
|
forAll(cellDistribution, cellI)
|
||||||
|
{
|
||||||
|
cellDistribution[cellI] = regionDecomp[cellToRegion[cellI]];
|
||||||
|
}
|
||||||
|
return cellDistribution;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::labelList Foam::parMetisDecomp::decompose
|
||||||
|
(
|
||||||
|
const labelListList& globalCellCells,
|
||||||
|
const pointField& cellCentres
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (cellCentres.size() != globalCellCells.size())
|
||||||
|
{
|
||||||
|
FatalErrorIn
|
||||||
|
(
|
||||||
|
"parMetisDecomp::decompose(const labelListList&, const pointField&)"
|
||||||
|
) << "Inconsistent number of cells (" << globalCellCells.size()
|
||||||
|
<< ") and number of cell centres (" << cellCentres.size()
|
||||||
|
<< ")." << exit(FatalError);
|
||||||
|
}
|
||||||
|
|
||||||
|
// For running sequential ...
|
||||||
|
if (Pstream::nProcs() <= 1)
|
||||||
|
{
|
||||||
|
return metisDecomp(decompositionDict_, mesh_)
|
||||||
|
.decompose(globalCellCells, cellCentres);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Make Metis Distributed CSR (Compressed Storage Format) storage
|
||||||
|
|
||||||
|
// Connections
|
||||||
|
Field<int> adjncy;
|
||||||
|
// Offsets into adjncy
|
||||||
|
Field<int> xadj;
|
||||||
|
metisDecomp::calcMetisCSR(globalCellCells, adjncy, xadj);
|
||||||
|
|
||||||
|
// decomposition options. 0 = use defaults
|
||||||
|
List<int> options(3, 0);
|
||||||
|
//options[0] = 1; // don't use defaults but use values below
|
||||||
|
//options[1] = -1; // full debug info
|
||||||
|
//options[2] = 15; // random number seed
|
||||||
|
|
||||||
|
// cell weights (so on the vertices of the dual)
|
||||||
|
Field<int> cellWeights;
|
||||||
|
|
||||||
|
// face weights (so on the edges of the dual)
|
||||||
|
Field<int> faceWeights;
|
||||||
|
|
||||||
|
// Check for user supplied weights and decomp options
|
||||||
|
if (decompositionDict_.found("metisCoeffs"))
|
||||||
|
{
|
||||||
|
dictionary parMetisDecompCoeffs
|
||||||
|
(
|
||||||
|
decompositionDict_.subDict("metisCoeffs")
|
||||||
|
);
|
||||||
|
|
||||||
|
if (parMetisDecompCoeffs.found("cellWeightsFile"))
|
||||||
|
{
|
||||||
|
word cellWeightsFile
|
||||||
(
|
(
|
||||||
finalDecomp,
|
parMetisDecompCoeffs.lookup("cellWeightsFile")
|
||||||
nToPrevious,
|
|
||||||
finalDecomp.size()-nToPrevious
|
|
||||||
);
|
);
|
||||||
|
|
||||||
// Remove locally what has been sent
|
Info<< "parMetisDecomp : Using cell-based weights read from "
|
||||||
finalDecomp.setSize(finalDecomp.size()-nToPrevious);
|
<< cellWeightsFile << endl;
|
||||||
|
|
||||||
|
labelIOField cellIOWeights
|
||||||
|
(
|
||||||
|
IOobject
|
||||||
|
(
|
||||||
|
cellWeightsFile,
|
||||||
|
mesh_.time().timeName(),
|
||||||
|
mesh_,
|
||||||
|
IOobject::MUST_READ,
|
||||||
|
IOobject::AUTO_WRITE
|
||||||
|
)
|
||||||
|
);
|
||||||
|
cellWeights.transfer(cellIOWeights);
|
||||||
|
|
||||||
|
if (cellWeights.size() != cellCentres.size())
|
||||||
|
{
|
||||||
|
FatalErrorIn
|
||||||
|
(
|
||||||
|
"parMetisDecomp::decompose"
|
||||||
|
"(const labelListList&, const pointField&)"
|
||||||
|
) << "Number of cell weights " << cellWeights.size()
|
||||||
|
<< " read from " << cellIOWeights.objectPath()
|
||||||
|
<< " does not equal number of cells " << cellCentres.size()
|
||||||
|
<< exit(FatalError);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//- faceWeights disabled. Only makes sense for cellCells from mesh.
|
||||||
|
//if (parMetisDecompCoeffs.found("faceWeightsFile"))
|
||||||
|
//{
|
||||||
|
// word faceWeightsFile
|
||||||
|
// (
|
||||||
|
// parMetisDecompCoeffs.lookup("faceWeightsFile")
|
||||||
|
// );
|
||||||
|
//
|
||||||
|
// Info<< "parMetisDecomp : Using face-based weights read from "
|
||||||
|
// << faceWeightsFile << endl;
|
||||||
|
//
|
||||||
|
// labelIOField weights
|
||||||
|
// (
|
||||||
|
// IOobject
|
||||||
|
// (
|
||||||
|
// faceWeightsFile,
|
||||||
|
// mesh_.time().timeName(),
|
||||||
|
// mesh_,
|
||||||
|
// IOobject::MUST_READ,
|
||||||
|
// IOobject::AUTO_WRITE
|
||||||
|
// )
|
||||||
|
// );
|
||||||
|
//
|
||||||
|
// if (weights.size() != mesh_.nFaces())
|
||||||
|
// {
|
||||||
|
// FatalErrorIn("parMetisDecomp::decompose(const pointField&)")
|
||||||
|
// << "Number of face weights " << weights.size()
|
||||||
|
// << " does not equal number of internal and boundary faces "
|
||||||
|
// << mesh_.nFaces()
|
||||||
|
// << exit(FatalError);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// faceWeights.setSize(2*mesh_.nInternalFaces()+nCoupledFaces);
|
||||||
|
//
|
||||||
|
// // Assume symmetric weights. Keep same ordering as adjncy.
|
||||||
|
// nFacesPerCell = 0;
|
||||||
|
//
|
||||||
|
// // Handle internal faces
|
||||||
|
// for (label faceI = 0; faceI < mesh_.nInternalFaces(); faceI++)
|
||||||
|
// {
|
||||||
|
// label w = weights[faceI];
|
||||||
|
//
|
||||||
|
// label own = faceOwner[faceI];
|
||||||
|
// label nei = faceNeighbour[faceI];
|
||||||
|
//
|
||||||
|
// faceWeights[xadj[own] + nFacesPerCell[own]++] = w;
|
||||||
|
// faceWeights[xadj[nei] + nFacesPerCell[nei]++] = w;
|
||||||
|
// }
|
||||||
|
// // Coupled boundary faces
|
||||||
|
// forAll(patches, patchI)
|
||||||
|
// {
|
||||||
|
// const polyPatch& pp = patches[patchI];
|
||||||
|
//
|
||||||
|
// if (pp.coupled())
|
||||||
|
// {
|
||||||
|
// label faceI = pp.start();
|
||||||
|
//
|
||||||
|
// forAll(pp, i)
|
||||||
|
// {
|
||||||
|
// label w = weights[faceI];
|
||||||
|
// label own = faceOwner[faceI];
|
||||||
|
// adjncy[xadj[own] + nFacesPerCell[own]++] = w;
|
||||||
|
// faceI++;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
|
||||||
|
if (parMetisDecompCoeffs.found("options"))
|
||||||
|
{
|
||||||
|
parMetisDecompCoeffs.lookup("options") >> options;
|
||||||
|
|
||||||
|
Info<< "Using Metis options " << options
|
||||||
|
<< endl << endl;
|
||||||
|
|
||||||
|
if (options.size() != 3)
|
||||||
|
{
|
||||||
|
FatalErrorIn
|
||||||
|
(
|
||||||
|
"parMetisDecomp::decompose"
|
||||||
|
"(const labelListList&, const pointField&)"
|
||||||
|
) << "Number of options " << options.size()
|
||||||
|
<< " should be three." << exit(FatalError);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return finalDecomp;
|
|
||||||
|
// Do actual decomposition
|
||||||
|
List<int> finalDecomp;
|
||||||
|
decompose
|
||||||
|
(
|
||||||
|
xadj,
|
||||||
|
adjncy,
|
||||||
|
cellCentres,
|
||||||
|
cellWeights,
|
||||||
|
faceWeights,
|
||||||
|
options,
|
||||||
|
|
||||||
|
finalDecomp
|
||||||
|
);
|
||||||
|
|
||||||
|
// Copy back to labelList
|
||||||
|
labelList decomp(finalDecomp.size());
|
||||||
|
forAll(decomp, i)
|
||||||
|
{
|
||||||
|
decomp[i] = finalDecomp[i];
|
||||||
|
}
|
||||||
|
return decomp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -62,6 +62,18 @@ class parMetisDecomp
|
|||||||
template<class Type>
|
template<class Type>
|
||||||
static void append(const UList<Type>&, List<Type>&);
|
static void append(const UList<Type>&, List<Type>&);
|
||||||
|
|
||||||
|
label decompose
|
||||||
|
(
|
||||||
|
Field<int>& xadj,
|
||||||
|
Field<int>& adjncy,
|
||||||
|
const pointField& cellCentres,
|
||||||
|
Field<int>& cellWeights,
|
||||||
|
Field<int>& faceWeights,
|
||||||
|
const List<int>& options,
|
||||||
|
|
||||||
|
List<int>& finalDecomp
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
//- Disallow default bitwise copy construct and assignment
|
//- Disallow default bitwise copy construct and assignment
|
||||||
void operator=(const parMetisDecomp&);
|
void operator=(const parMetisDecomp&);
|
||||||
@ -93,12 +105,37 @@ public:
|
|||||||
// Member Functions
|
// Member Functions
|
||||||
|
|
||||||
//- parMetis handles Foam processor boundaries
|
//- parMetis handles Foam processor boundaries
|
||||||
bool parallelAware() const
|
virtual bool parallelAware() const
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
labelList decompose(const pointField&);
|
//- Return for every coordinate the wanted processor number. Use the
|
||||||
|
// mesh connectivity (if needed)
|
||||||
|
virtual labelList decompose(const pointField&);
|
||||||
|
|
||||||
|
//- Return for every coordinate the wanted processor number. Gets
|
||||||
|
// passed agglomeration map (from fine to coarse cells) and coarse cell
|
||||||
|
// location. Can be overridden by decomposers that provide this
|
||||||
|
// functionality natively.
|
||||||
|
virtual labelList decompose
|
||||||
|
(
|
||||||
|
const labelList& agglom,
|
||||||
|
const pointField&
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Return for every coordinate the wanted processor number. Explicitly
|
||||||
|
// provided mesh connectivity.
|
||||||
|
// The connectivity is equal to mesh.cellCells() except for
|
||||||
|
// - in parallel the cell numbers are global cell numbers (starting
|
||||||
|
// from 0 at processor0 and then incrementing all through the
|
||||||
|
// processors)
|
||||||
|
// - the connections are across coupled patches
|
||||||
|
virtual labelList decompose
|
||||||
|
(
|
||||||
|
const labelListList& globalCellCells,
|
||||||
|
const pointField& cc
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -1,8 +1,10 @@
|
|||||||
viscosityModels/viscosityModel/viscosityModel.C
|
viscosityModels/viscosityModel/viscosityModel.C
|
||||||
viscosityModels/viscosityModel/newViscosityModel.C
|
viscosityModels/viscosityModel/newViscosityModel.C
|
||||||
viscosityModels/Newtonian/Newtonian.C
|
viscosityModels/Newtonian/Newtonian.C
|
||||||
|
viscosityModels/powerLaw/powerLaw.C
|
||||||
viscosityModels/CrossPowerLaw/CrossPowerLaw.C
|
viscosityModels/CrossPowerLaw/CrossPowerLaw.C
|
||||||
viscosityModels/BirdCarreau/BirdCarreau.C
|
viscosityModels/BirdCarreau/BirdCarreau.C
|
||||||
|
viscosityModels/HerschelBulkley/HerschelBulkley.C
|
||||||
|
|
||||||
transportModel/transportModel.C
|
transportModel/transportModel.C
|
||||||
singlePhaseTransportModel/singlePhaseTransportModel.C
|
singlePhaseTransportModel/singlePhaseTransportModel.C
|
||||||
|
|||||||
@ -28,31 +28,29 @@ License
|
|||||||
#include "addToRunTimeSelectionTable.H"
|
#include "addToRunTimeSelectionTable.H"
|
||||||
#include "surfaceFields.H"
|
#include "surfaceFields.H"
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||||
|
|
||||||
namespace Foam
|
namespace Foam
|
||||||
{
|
{
|
||||||
namespace viscosityModels
|
namespace viscosityModels
|
||||||
{
|
{
|
||||||
|
defineTypeNameAndDebug(BirdCarreau, 0);
|
||||||
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
addToRunTimeSelectionTable
|
||||||
|
(
|
||||||
defineTypeNameAndDebug(BirdCarreau, 0);
|
viscosityModel,
|
||||||
|
BirdCarreau,
|
||||||
addToRunTimeSelectionTable
|
dictionary
|
||||||
(
|
);
|
||||||
viscosityModel,
|
}
|
||||||
BirdCarreau,
|
}
|
||||||
dictionary
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * * //
|
// * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * * //
|
||||||
|
|
||||||
//- Calculate and return the laminar viscosity
|
Foam::tmp<Foam::volScalarField>
|
||||||
tmp<volScalarField> BirdCarreau::calcNu() const
|
Foam::viscosityModels::BirdCarreau::calcNu() const
|
||||||
{
|
{
|
||||||
return
|
return
|
||||||
nuInf_
|
nuInf_
|
||||||
+ (nu0_ - nuInf_)
|
+ (nu0_ - nuInf_)
|
||||||
*pow(scalar(1) + sqr(k_*strainRate()), (n_ - 1.0)/2.0);
|
*pow(scalar(1) + sqr(k_*strainRate()), (n_ - 1.0)/2.0);
|
||||||
@ -61,8 +59,7 @@ tmp<volScalarField> BirdCarreau::calcNu() const
|
|||||||
|
|
||||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
// from components
|
Foam::viscosityModels::BirdCarreau::BirdCarreau
|
||||||
BirdCarreau::BirdCarreau
|
|
||||||
(
|
(
|
||||||
const word& name,
|
const word& name,
|
||||||
const dictionary& viscosityProperties,
|
const dictionary& viscosityProperties,
|
||||||
@ -93,7 +90,10 @@ BirdCarreau::BirdCarreau
|
|||||||
|
|
||||||
// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
bool BirdCarreau::read(const dictionary& viscosityProperties)
|
bool Foam::viscosityModels::BirdCarreau::read
|
||||||
|
(
|
||||||
|
const dictionary& viscosityProperties
|
||||||
|
)
|
||||||
{
|
{
|
||||||
viscosityModel::read(viscosityProperties);
|
viscosityModel::read(viscosityProperties);
|
||||||
|
|
||||||
@ -108,9 +108,4 @@ bool BirdCarreau::read(const dictionary& viscosityProperties)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
} // End namespace viscosityModels
|
|
||||||
} // End namespace Foam
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
// ************************************************************************* //
|
||||||
|
|||||||
@ -28,29 +28,28 @@ License
|
|||||||
#include "addToRunTimeSelectionTable.H"
|
#include "addToRunTimeSelectionTable.H"
|
||||||
#include "surfaceFields.H"
|
#include "surfaceFields.H"
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||||
|
|
||||||
namespace Foam
|
namespace Foam
|
||||||
{
|
{
|
||||||
namespace viscosityModels
|
namespace viscosityModels
|
||||||
{
|
{
|
||||||
|
defineTypeNameAndDebug(CrossPowerLaw, 0);
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
addToRunTimeSelectionTable
|
||||||
|
(
|
||||||
defineTypeNameAndDebug(CrossPowerLaw, 0);
|
viscosityModel,
|
||||||
|
CrossPowerLaw,
|
||||||
addToRunTimeSelectionTable
|
dictionary
|
||||||
(
|
);
|
||||||
viscosityModel,
|
}
|
||||||
CrossPowerLaw,
|
}
|
||||||
dictionary
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * * //
|
// * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * * //
|
||||||
|
|
||||||
//- Calculate and return the laminar viscosity
|
Foam::tmp<Foam::volScalarField>
|
||||||
tmp<volScalarField> CrossPowerLaw::calcNu() const
|
Foam::viscosityModels::CrossPowerLaw::calcNu() const
|
||||||
{
|
{
|
||||||
return (nu0_ - nuInf_)/(scalar(1) + pow(m_*strainRate(), n_)) + nuInf_;
|
return (nu0_ - nuInf_)/(scalar(1) + pow(m_*strainRate(), n_)) + nuInf_;
|
||||||
}
|
}
|
||||||
@ -58,7 +57,7 @@ tmp<volScalarField> CrossPowerLaw::calcNu() const
|
|||||||
|
|
||||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
CrossPowerLaw::CrossPowerLaw
|
Foam::viscosityModels::CrossPowerLaw::CrossPowerLaw
|
||||||
(
|
(
|
||||||
const word& name,
|
const word& name,
|
||||||
const dictionary& viscosityProperties,
|
const dictionary& viscosityProperties,
|
||||||
@ -89,7 +88,10 @@ CrossPowerLaw::CrossPowerLaw
|
|||||||
|
|
||||||
// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
bool CrossPowerLaw::read(const dictionary& viscosityProperties)
|
bool Foam::viscosityModels::CrossPowerLaw::read
|
||||||
|
(
|
||||||
|
const dictionary& viscosityProperties
|
||||||
|
)
|
||||||
{
|
{
|
||||||
viscosityModel::read(viscosityProperties);
|
viscosityModel::read(viscosityProperties);
|
||||||
|
|
||||||
@ -99,14 +101,9 @@ bool CrossPowerLaw::read(const dictionary& viscosityProperties)
|
|||||||
CrossPowerLawCoeffs_.lookup("nuInf") >> nuInf_;
|
CrossPowerLawCoeffs_.lookup("nuInf") >> nuInf_;
|
||||||
CrossPowerLawCoeffs_.lookup("m") >> m_;
|
CrossPowerLawCoeffs_.lookup("m") >> m_;
|
||||||
CrossPowerLawCoeffs_.lookup("n") >> n_;
|
CrossPowerLawCoeffs_.lookup("n") >> n_;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
} // End namespace viscosityModels
|
|
||||||
} // End namespace Foam
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
// ************************************************************************* //
|
||||||
|
|||||||
@ -0,0 +1,114 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | Copyright (C) 1991-2007 OpenCFD Ltd.
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
License
|
||||||
|
This file is part of OpenFOAM.
|
||||||
|
|
||||||
|
OpenFOAM is free software; you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by the
|
||||||
|
Free Software Foundation; either version 2 of the License, or (at your
|
||||||
|
option) any later version.
|
||||||
|
|
||||||
|
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with OpenFOAM; if not, write to the Free Software Foundation,
|
||||||
|
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#include "HerschelBulkley.H"
|
||||||
|
#include "addToRunTimeSelectionTable.H"
|
||||||
|
#include "surfaceFields.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
namespace viscosityModels
|
||||||
|
{
|
||||||
|
defineTypeNameAndDebug(HerschelBulkley, 0);
|
||||||
|
|
||||||
|
addToRunTimeSelectionTable
|
||||||
|
(
|
||||||
|
viscosityModel,
|
||||||
|
HerschelBulkley,
|
||||||
|
dictionary
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Foam::tmp<Foam::volScalarField>
|
||||||
|
Foam::viscosityModels::HerschelBulkley::calcNu() const
|
||||||
|
{
|
||||||
|
dimensionedScalar tone("tone", dimTime, 1.0);
|
||||||
|
dimensionedScalar rtone("rtone", dimless/dimTime, 1.0);
|
||||||
|
tmp<volScalarField> sr(strainRate());
|
||||||
|
return (min(nu0_,(tau0_ + k_* rtone *( pow(tone * sr(), n_)
|
||||||
|
+ pow(tone*tau0_/nu0_,n_))) / (max(sr(), dimensionedScalar
|
||||||
|
("VSMALL", dimless/dimTime, VSMALL)))));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Foam::viscosityModels::HerschelBulkley::HerschelBulkley
|
||||||
|
(
|
||||||
|
const word& name,
|
||||||
|
const dictionary& viscosityProperties,
|
||||||
|
const volVectorField& U,
|
||||||
|
const surfaceScalarField& phi
|
||||||
|
)
|
||||||
|
:
|
||||||
|
viscosityModel(name, viscosityProperties, U, phi),
|
||||||
|
HerschelBulkleyCoeffs_(viscosityProperties.subDict(typeName + "Coeffs")),
|
||||||
|
k_(HerschelBulkleyCoeffs_.lookup("k")),
|
||||||
|
n_(HerschelBulkleyCoeffs_.lookup("n")),
|
||||||
|
tau0_(HerschelBulkleyCoeffs_.lookup("tau0")),
|
||||||
|
nu0_(HerschelBulkleyCoeffs_.lookup("nu0")),
|
||||||
|
nu_
|
||||||
|
(
|
||||||
|
IOobject
|
||||||
|
(
|
||||||
|
name,
|
||||||
|
U_.time().timeName(),
|
||||||
|
U_.db(),
|
||||||
|
IOobject::NO_READ,
|
||||||
|
IOobject::AUTO_WRITE
|
||||||
|
),
|
||||||
|
calcNu()
|
||||||
|
)
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
bool Foam::viscosityModels::HerschelBulkley::read
|
||||||
|
(
|
||||||
|
const dictionary& viscosityProperties
|
||||||
|
)
|
||||||
|
{
|
||||||
|
viscosityModel::read(viscosityProperties);
|
||||||
|
|
||||||
|
HerschelBulkleyCoeffs_ = viscosityProperties.subDict(typeName + "Coeffs");
|
||||||
|
|
||||||
|
HerschelBulkleyCoeffs_.lookup("k") >> k_;
|
||||||
|
HerschelBulkleyCoeffs_.lookup("n") >> n_;
|
||||||
|
HerschelBulkleyCoeffs_.lookup("tau0") >> tau0_;
|
||||||
|
HerschelBulkleyCoeffs_.lookup("nu0") >> nu0_;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -23,90 +23,106 @@ License
|
|||||||
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
|
||||||
Class
|
Class
|
||||||
Foam::TPCG
|
Foam::viscosityModels::HerschelBulkley
|
||||||
|
|
||||||
Description
|
Description
|
||||||
Preconditioned conjugate gradient solver for symmetric lduMatrices
|
Herschel-Bulkley non-Newtonian viscosity model.
|
||||||
using a run-time selectable preconditiioner.
|
|
||||||
|
|
||||||
SourceFiles
|
SourceFiles
|
||||||
TPCG.C
|
HerschelBulkley.C
|
||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
#ifndef TPCG_H
|
#ifndef HerschelBulkley_H
|
||||||
#define TPCG_H
|
#define HerschelBulkley_H
|
||||||
|
|
||||||
#include "LduMatrix.H"
|
#include "viscosityModel.H"
|
||||||
|
#include "dimensionedScalar.H"
|
||||||
|
#include "volFields.H"
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
namespace Foam
|
namespace Foam
|
||||||
{
|
{
|
||||||
|
namespace viscosityModels
|
||||||
|
{
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*\
|
/*---------------------------------------------------------------------------*\
|
||||||
Class TPCG Declaration
|
Class HerschelBulkley Declaration
|
||||||
\*---------------------------------------------------------------------------*/
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
template<class Type, class DType, class LUType>
|
class HerschelBulkley
|
||||||
class TPCG
|
|
||||||
:
|
:
|
||||||
public LduMatrix<Type, DType, LUType>::solver
|
public viscosityModel
|
||||||
{
|
{
|
||||||
|
// Private data
|
||||||
|
|
||||||
|
dictionary HerschelBulkleyCoeffs_;
|
||||||
|
|
||||||
|
dimensionedScalar k_;
|
||||||
|
dimensionedScalar n_;
|
||||||
|
dimensionedScalar tau0_;
|
||||||
|
dimensionedScalar nu0_;
|
||||||
|
|
||||||
|
volScalarField nu_;
|
||||||
|
|
||||||
|
|
||||||
// Private Member Functions
|
// Private Member Functions
|
||||||
|
|
||||||
//- Disallow default bitwise copy construct
|
//- Calculate and return the laminar viscosity
|
||||||
TPCG(const TPCG&);
|
tmp<volScalarField> calcNu() const;
|
||||||
|
|
||||||
//- Disallow default bitwise assignment
|
|
||||||
void operator=(const TPCG&);
|
|
||||||
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
//- Runtime type information
|
//- Runtime type information
|
||||||
TypeName("PCG");
|
TypeName("HerschelBulkley");
|
||||||
|
|
||||||
|
|
||||||
// Constructors
|
// Constructors
|
||||||
|
|
||||||
//- Construct from matrix components and solver data dictionary
|
//- Construct from components
|
||||||
TPCG
|
HerschelBulkley
|
||||||
(
|
(
|
||||||
const word& fieldName,
|
const word& name,
|
||||||
const LduMatrix<Type, DType, LUType>& matrix,
|
const dictionary& viscosityProperties,
|
||||||
const dictionary& solverDict
|
const volVectorField& U,
|
||||||
|
const surfaceScalarField& phi
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
// Destructor
|
// Destructor
|
||||||
|
|
||||||
virtual ~TPCG()
|
~HerschelBulkley()
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
|
||||||
// Member Functions
|
// Member Functions
|
||||||
|
|
||||||
//- Solve the matrix with this solver
|
//- Return the laminar viscosity
|
||||||
virtual typename LduMatrix<Type, DType, LUType>::solverPerformance solve
|
tmp<volScalarField> nu() const
|
||||||
(
|
{
|
||||||
Field<Type>& psi
|
return nu_;
|
||||||
) const;
|
}
|
||||||
|
|
||||||
|
//- Correct the laminar viscosity
|
||||||
|
void correct()
|
||||||
|
{
|
||||||
|
nu_ = calcNu();
|
||||||
|
}
|
||||||
|
|
||||||
|
//- Read transportProperties dictionary
|
||||||
|
bool read(const dictionary& viscosityProperties);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
} // End namespace viscosityModels
|
||||||
} // End namespace Foam
|
} // End namespace Foam
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
#ifdef NoRepository
|
|
||||||
# include "TPCG.C"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// ************************************************************************* //
|
// ************************************************************************* //
|
||||||
@ -28,22 +28,21 @@ License
|
|||||||
#include "addToRunTimeSelectionTable.H"
|
#include "addToRunTimeSelectionTable.H"
|
||||||
#include "surfaceFields.H"
|
#include "surfaceFields.H"
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||||
|
|
||||||
namespace Foam
|
namespace Foam
|
||||||
{
|
{
|
||||||
namespace viscosityModels
|
namespace viscosityModels
|
||||||
{
|
{
|
||||||
|
defineTypeNameAndDebug(Newtonian, 0);
|
||||||
|
addToRunTimeSelectionTable(viscosityModel, Newtonian, dictionary);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
defineTypeNameAndDebug(Newtonian, 0);
|
|
||||||
|
|
||||||
addToRunTimeSelectionTable(viscosityModel, Newtonian, dictionary);
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
Newtonian::Newtonian
|
Foam::viscosityModels::Newtonian::Newtonian
|
||||||
(
|
(
|
||||||
const word& name,
|
const word& name,
|
||||||
const dictionary& viscosityProperties,
|
const dictionary& viscosityProperties,
|
||||||
@ -71,7 +70,10 @@ Newtonian::Newtonian
|
|||||||
|
|
||||||
// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
bool Newtonian::read(const dictionary& viscosityProperties)
|
bool Foam::viscosityModels::Newtonian::read
|
||||||
|
(
|
||||||
|
const dictionary& viscosityProperties
|
||||||
|
)
|
||||||
{
|
{
|
||||||
viscosityModel::read(viscosityProperties);
|
viscosityModel::read(viscosityProperties);
|
||||||
|
|
||||||
@ -82,9 +84,4 @@ bool Newtonian::read(const dictionary& viscosityProperties)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
} // End namespace viscosityModels
|
|
||||||
} // End namespace Foam
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
// ************************************************************************* //
|
||||||
|
|||||||
111
src/transportModels/incompressible/viscosityModels/powerLaw/powerLaw.C
Executable file
111
src/transportModels/incompressible/viscosityModels/powerLaw/powerLaw.C
Executable file
@ -0,0 +1,111 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration |
|
||||||
|
\\ / A nd | Copyright (C) 1991-2007 OpenCFD Ltd.
|
||||||
|
\\/ M anipulation |
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
License
|
||||||
|
This file is part of OpenFOAM.
|
||||||
|
|
||||||
|
OpenFOAM is free software; you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by the
|
||||||
|
Free Software Foundation; either version 2 of the License, or (at your
|
||||||
|
option) any later version.
|
||||||
|
|
||||||
|
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with OpenFOAM; if not, write to the Free Software Foundation,
|
||||||
|
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#include "powerLaw.H"
|
||||||
|
#include "addToRunTimeSelectionTable.H"
|
||||||
|
#include "surfaceFields.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
namespace viscosityModels
|
||||||
|
{
|
||||||
|
defineTypeNameAndDebug(powerLaw, 0);
|
||||||
|
|
||||||
|
addToRunTimeSelectionTable
|
||||||
|
(
|
||||||
|
viscosityModel,
|
||||||
|
powerLaw,
|
||||||
|
dictionary
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Foam::tmp<Foam::volScalarField>
|
||||||
|
Foam::viscosityModels::powerLaw::calcNu() const
|
||||||
|
{
|
||||||
|
dimensionedScalar tone("tone", dimTime, 1.0);
|
||||||
|
return (max(numin_, min(numax_, k_
|
||||||
|
* pow(tone * strainRate(), n_.value()- scalar(1.0)))));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Foam::viscosityModels::powerLaw::powerLaw
|
||||||
|
(
|
||||||
|
const word& name,
|
||||||
|
const dictionary& viscosityProperties,
|
||||||
|
const volVectorField& U,
|
||||||
|
const surfaceScalarField& phi
|
||||||
|
)
|
||||||
|
:
|
||||||
|
viscosityModel(name, viscosityProperties, U, phi),
|
||||||
|
powerLawCoeffs_(viscosityProperties.subDict(typeName + "Coeffs")),
|
||||||
|
k_(powerLawCoeffs_.lookup("k")),
|
||||||
|
n_(powerLawCoeffs_.lookup("n")),
|
||||||
|
numin_(powerLawCoeffs_.lookup("numin")),
|
||||||
|
numax_(powerLawCoeffs_.lookup("numax")),
|
||||||
|
nu_
|
||||||
|
(
|
||||||
|
IOobject
|
||||||
|
(
|
||||||
|
name,
|
||||||
|
U_.time().timeName(),
|
||||||
|
U_.db(),
|
||||||
|
IOobject::NO_READ,
|
||||||
|
IOobject::AUTO_WRITE
|
||||||
|
),
|
||||||
|
calcNu()
|
||||||
|
)
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
bool Foam::viscosityModels::powerLaw::read
|
||||||
|
(
|
||||||
|
const dictionary& viscosityProperties
|
||||||
|
)
|
||||||
|
{
|
||||||
|
viscosityModel::read(viscosityProperties);
|
||||||
|
|
||||||
|
powerLawCoeffs_ = viscosityProperties.subDict(typeName + "Coeffs");
|
||||||
|
|
||||||
|
powerLawCoeffs_.lookup("k") >> k_;
|
||||||
|
powerLawCoeffs_.lookup("n") >> n_;
|
||||||
|
powerLawCoeffs_.lookup("numin") >> numin_;
|
||||||
|
powerLawCoeffs_.lookup("numax") >> numax_;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -23,90 +23,106 @@ License
|
|||||||
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
|
||||||
Class
|
Class
|
||||||
Foam::TPBiCG
|
Foam::viscosityModels::powerLaw
|
||||||
|
|
||||||
Description
|
Description
|
||||||
Preconditioned bi-conjugate gradient solver for asymmetric lduMatrices
|
Standard power-law non-Newtonian viscosity model.
|
||||||
using a run-time selectable preconditiioner.
|
|
||||||
|
|
||||||
SourceFiles
|
SourceFiles
|
||||||
TPBiCG.C
|
powerLaw.C
|
||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
#ifndef TPBiCG_H
|
#ifndef powerLaw_H
|
||||||
#define TPBiCG_H
|
#define powerLaw_H
|
||||||
|
|
||||||
#include "LduMatrix.H"
|
#include "viscosityModel.H"
|
||||||
|
#include "dimensionedScalar.H"
|
||||||
|
#include "volFields.H"
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
namespace Foam
|
namespace Foam
|
||||||
{
|
{
|
||||||
|
namespace viscosityModels
|
||||||
|
{
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*\
|
/*---------------------------------------------------------------------------*\
|
||||||
Class TPBiCG Declaration
|
Class powerLaw Declaration
|
||||||
\*---------------------------------------------------------------------------*/
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
template<class Type, class DType, class LUType>
|
class powerLaw
|
||||||
class TPBiCG
|
|
||||||
:
|
:
|
||||||
public LduMatrix<Type, DType, LUType>::solver
|
public viscosityModel
|
||||||
{
|
{
|
||||||
|
// Private data
|
||||||
|
|
||||||
|
dictionary powerLawCoeffs_;
|
||||||
|
|
||||||
|
dimensionedScalar k_;
|
||||||
|
dimensionedScalar n_;
|
||||||
|
dimensionedScalar numin_;
|
||||||
|
dimensionedScalar numax_;
|
||||||
|
|
||||||
|
volScalarField nu_;
|
||||||
|
|
||||||
|
|
||||||
// Private Member Functions
|
// Private Member Functions
|
||||||
|
|
||||||
//- Disallow default bitwise copy construct
|
//- Calculate and return the laminar viscosity
|
||||||
TPBiCG(const TPBiCG&);
|
tmp<volScalarField> calcNu() const;
|
||||||
|
|
||||||
//- Disallow default bitwise assignment
|
|
||||||
void operator=(const TPBiCG&);
|
|
||||||
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
//- Runtime type information
|
//- Runtime type information
|
||||||
TypeName("PBiCG");
|
TypeName("powerLaw");
|
||||||
|
|
||||||
|
|
||||||
// Constructors
|
// Constructors
|
||||||
|
|
||||||
//- Construct from matrix components and solver data dictionary
|
//- Construct from components
|
||||||
TPBiCG
|
powerLaw
|
||||||
(
|
(
|
||||||
const word& fieldName,
|
const word& name,
|
||||||
const LduMatrix<Type, DType, LUType>& matrix,
|
const dictionary& viscosityProperties,
|
||||||
const dictionary& solverDict
|
const volVectorField& U,
|
||||||
|
const surfaceScalarField& phi
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
// Destructor
|
// Destructor
|
||||||
|
|
||||||
virtual ~TPBiCG()
|
~powerLaw()
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
|
||||||
// Member Functions
|
// Member Functions
|
||||||
|
|
||||||
//- Solve the matrix with this solver
|
//- Return the laminar viscosity
|
||||||
virtual typename LduMatrix<Type, DType, LUType>::solverPerformance solve
|
tmp<volScalarField> nu() const
|
||||||
(
|
{
|
||||||
Field<Type>& psi
|
return nu_;
|
||||||
) const;
|
}
|
||||||
|
|
||||||
|
//- Correct the laminar viscosity
|
||||||
|
void correct()
|
||||||
|
{
|
||||||
|
nu_ = calcNu();
|
||||||
|
}
|
||||||
|
|
||||||
|
//- Read transportProperties dictionary
|
||||||
|
bool read(const dictionary& viscosityProperties);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
} // End namespace viscosityModels
|
||||||
} // End namespace Foam
|
} // End namespace Foam
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
#ifdef NoRepository
|
|
||||||
# include "PBiCGScalarAlpha.C"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// ************************************************************************* //
|
// ************************************************************************* //
|
||||||
@ -26,22 +26,20 @@ License
|
|||||||
|
|
||||||
#include "viscosityModel.H"
|
#include "viscosityModel.H"
|
||||||
#include "volFields.H"
|
#include "volFields.H"
|
||||||
#include "fvc.H"
|
#include "fvcGrad.H"
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
namespace Foam
|
|
||||||
{
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||||
|
|
||||||
defineTypeNameAndDebug(viscosityModel, 0);
|
namespace Foam
|
||||||
defineRunTimeSelectionTable(viscosityModel, dictionary);
|
{
|
||||||
|
defineTypeNameAndDebug(viscosityModel, 0);
|
||||||
|
defineRunTimeSelectionTable(viscosityModel, dictionary);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
viscosityModel::viscosityModel
|
Foam::viscosityModel::viscosityModel
|
||||||
(
|
(
|
||||||
const word& name,
|
const word& name,
|
||||||
const dictionary& viscosityProperties,
|
const dictionary& viscosityProperties,
|
||||||
@ -58,13 +56,13 @@ viscosityModel::viscosityModel
|
|||||||
|
|
||||||
// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
tmp<volScalarField> viscosityModel::strainRate() const
|
Foam::tmp<Foam::volScalarField> Foam::viscosityModel::strainRate() const
|
||||||
{
|
{
|
||||||
return mag(fvc::grad(U_));
|
return mag(symm(fvc::grad(U_)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool viscosityModel::read(const dictionary& viscosityProperties)
|
bool Foam::viscosityModel::read(const dictionary& viscosityProperties)
|
||||||
{
|
{
|
||||||
viscosityProperties_ = viscosityProperties;
|
viscosityProperties_ = viscosityProperties;
|
||||||
|
|
||||||
@ -72,8 +70,4 @@ bool viscosityModel::read(const dictionary& viscosityProperties)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
} // End namespace Foam
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
// ************************************************************************* //
|
||||||
|
|||||||
@ -28,7 +28,6 @@ Namespace
|
|||||||
Description
|
Description
|
||||||
A namespace for various incompressible viscosityModel implementations.
|
A namespace for various incompressible viscosityModel implementations.
|
||||||
|
|
||||||
|
|
||||||
Class
|
Class
|
||||||
Foam::viscosityModel
|
Foam::viscosityModel
|
||||||
|
|
||||||
|
|||||||
@ -59,7 +59,6 @@ LIB_DIR = $(WM_PROJECT_DIR)/lib
|
|||||||
LIB_WM_OPTIONS_DIR = $(LIB_DIR)/$(WM_OPTIONS)
|
LIB_WM_OPTIONS_DIR = $(LIB_DIR)/$(WM_OPTIONS)
|
||||||
OBJECTS_DIR = $(MAKE_DIR)/$(WM_OPTIONS)
|
OBJECTS_DIR = $(MAKE_DIR)/$(WM_OPTIONS)
|
||||||
CLASSES_DIR = $(MAKE_DIR)/classes
|
CLASSES_DIR = $(MAKE_DIR)/classes
|
||||||
THIRD_PARTY = $(WM_PROJECT_INST_DIR)/ThirdParty
|
|
||||||
|
|
||||||
SYS_INC =
|
SYS_INC =
|
||||||
SYS_LIBS =
|
SYS_LIBS =
|
||||||
|
|||||||
Reference in New Issue
Block a user