Newer
Older
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2010-2011 OpenCFD Ltd.
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "structuredDecomp.H"
#include "addToRunTimeSelectionTable.H"
#include "FaceCellWave.H"
#include "topoDistanceData.H"
#include "fvMeshSubset.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
defineTypeNameAndDebug(structuredDecomp, 0);
addToRunTimeSelectionTable
(
decompositionMethod,
structuredDecomp,
dictionary
);
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::structuredDecomp::structuredDecomp(const dictionary& decompositionDict)
:
mattijs
committed
decompositionMethod(decompositionDict),
methodDict_(decompositionDict_.subDict(typeName + "Coeffs"))
{
mattijs
committed
methodDict_.set("numberOfSubdomains", nDomains());
method_ = decompositionMethod::New(methodDict_);
patches_ = wordList(methodDict_.lookup("patches"));
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
bool Foam::structuredDecomp::parallelAware() const
{
return method_().parallelAware();
}
Foam::labelList Foam::structuredDecomp::decompose
(
const polyMesh& mesh,
const pointField& cc,
const scalarField& cWeights
)
{
labelList patchIDs(patches_.size());
const polyBoundaryMesh& pbm = mesh.boundaryMesh();
label nFaces = 0;
forAll(patches_, i)
{
patchIDs[i] = pbm.findPatchID(patches_[i]);
if (patchIDs[i] == -1)
{
FatalErrorIn("structuredDecomp::decompose(..)")
<< "Cannot find patch " << patches_[i] << endl
<< "Valid patches are " << pbm.names()
<< exit(FatalError);
}
nFaces += pbm[patchIDs[i]].size();
}
// Extract a submesh.
labelHashSet patchCells(2*nFaces);
forAll(patchIDs, i)
{
const labelUList& fc = pbm[patchIDs[i]].faceCells();
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
forAll(fc, i)
{
patchCells.insert(fc[i]);
}
}
// Subset the layer of cells next to the patch
fvMeshSubset subsetter(dynamic_cast<const fvMesh&>(mesh));
subsetter.setLargeCellSubset(patchCells);
const fvMesh& subMesh = subsetter.subMesh();
pointField subCc(cc, subsetter.cellMap());
scalarField subWeights(cWeights, subsetter.cellMap());
// Decompose the layer of cells
labelList subDecomp(method_().decompose(subMesh, subCc, subWeights));
// Transfer to final decomposition
labelList finalDecomp(cc.size(), -1);
forAll(subDecomp, i)
{
finalDecomp[subsetter.cellMap()[i]] = subDecomp[i];
}
// Field on cells and faces.
List<topoDistanceData> cellData(mesh.nCells());
List<topoDistanceData> faceData(mesh.nFaces());
// Start of changes
labelList patchFaces(nFaces);
List<topoDistanceData> patchData(nFaces);
nFaces = 0;
forAll(patchIDs, i)
{
const polyPatch& pp = pbm[patchIDs[i]];
const labelUList& fc = pp.faceCells();
forAll(fc, i)
{
patchFaces[nFaces] = pp.start()+i;
patchData[nFaces] = topoDistanceData(finalDecomp[fc[i]], 0);
nFaces++;
}
}
// Propagate information inwards
FaceCellWave<topoDistanceData> deltaCalc
(
mesh,
patchFaces,
patchData,
faceData,
cellData,
);
// And extract
bool haveWarned = false;
forAll(finalDecomp, cellI)
{
mattijs
committed
if (!cellData[cellI].valid(deltaCalc.data()))
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
{
if (!haveWarned)
{
WarningIn("structuredDecomp::decompose(..)")
<< "Did not visit some cells, e.g. cell " << cellI
<< " at " << mesh.cellCentres()[cellI] << endl
<< "Assigning these cells to domain 0." << endl;
haveWarned = true;
}
finalDecomp[cellI] = 0;
}
else
{
finalDecomp[cellI] = cellData[cellI].data();
}
}
return finalDecomp;
}
Foam::labelList Foam::structuredDecomp::decompose
(
const labelListList& globalPointPoints,
const pointField& points,
const scalarField& pointWeights
)
{
notImplemented
(
"structuredDecomp::decompose\n"
"(\n"
" const labelListList&,\n"
" const pointField&,\n"
" const scalarField&\n"
")\n"
);
return labelList::null();
}
// ************************************************************************* //