faceAgglomerate.C
Go to the documentation of this file.
1/*---------------------------------------------------------------------------*\
2 ========= |
3 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4 \\ / O peration |
5 \\ / A nd | www.openfoam.com
6 \\/ M anipulation |
7-------------------------------------------------------------------------------
8 Copyright (C) 2011-2016 OpenFOAM Foundation
9 Copyright (C) 2016-2020 OpenCFD Ltd.
10-------------------------------------------------------------------------------
11License
12 This file is part of OpenFOAM.
13
14 OpenFOAM is free software: you can redistribute it and/or modify it
15 under the terms of the GNU General Public License as published by
16 the Free Software Foundation, either version 3 of the License, or
17 (at your option) any later version.
18
19 OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
20 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
21 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22 for more details.
23
24 You should have received a copy of the GNU General Public License
25 along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
26
27Application
28 faceAgglomerate
29
30Group
31 grpPreProcessingUtilities
32
33Description
34 Agglomerate boundary faces using the pairPatchAgglomeration algorithm.
35
36 It writes a map from the fine to coarse grid.
37
38SeeAlso
39 pairPatchAgglomeration.H
40
41\*---------------------------------------------------------------------------*/
42
43#include "argList.H"
44#include "fvMesh.H"
45#include "Time.H"
46#include "volFields.H"
47#include "unitConversion.H"
49#include "labelListIOList.H"
50#include "syncTools.H"
51#include "globalIndex.H"
52
53using namespace Foam;
54
55// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
56
57int main(int argc, char *argv[])
58{
59 argList::addNote
60 (
61 "Agglomerate boundary faces using the pairPatchAgglomeration"
62 " algorithm. Writes a map of fine to coarse grid."
63 );
64
65 argList::addOption("dict", "file", "Alternative viewFactorsDict");
66 #include "addRegionOption.H"
67
68 #include "setRootCase.H"
69 #include "createTime.H"
70 #include "createNamedMesh.H"
71
72 const word dictName("viewFactorsDict");
73
75
76 // Read control dictionary
77 const IOdictionary agglomDict(dictIO);
78
79 const bool writeAgglom(agglomDict.get<bool>("writeFacesAgglomeration"));
80
81 const polyBoundaryMesh& boundary = mesh.boundaryMesh();
82
83 labelListIOList finalAgglom
84 (
86 (
87 "finalAgglom",
88 mesh.facesInstance(),
89 mesh,
90 IOobject::NO_READ,
91 IOobject::NO_WRITE,
92 false
93 ),
94 boundary.size()
95 );
96
97 label nCoarseFaces = 0;
98
99 for (const entry& dEntry : agglomDict)
100 {
101 labelList patchids = boundary.indices(dEntry.keyword());
102
103 for (const label patchi : patchids)
104 {
105 const polyPatch& pp = boundary[patchi];
106
107 if (!pp.coupled())
108 {
109 Info << "\nAgglomerating patch : " << pp.name() << endl;
110
111 pairPatchAgglomeration agglomObject
112 (
113 pp.localFaces(),
114 pp.localPoints(),
115 agglomDict.subDict(pp.name())
116 );
117
118 agglomObject.agglomerate();
119
120 finalAgglom[patchi] =
121 agglomObject.restrictTopBottomAddressing();
122
123 if (finalAgglom[patchi].size())
124 {
125 nCoarseFaces += max(finalAgglom[patchi] + 1);
126 }
127 }
128 }
129 }
130
131
132 // All patches which are not agglomerated are identity for finalAgglom
133 forAll(boundary, patchi)
134 {
135 if (finalAgglom[patchi].size() == 0)
136 {
137 finalAgglom[patchi] = identity(boundary[patchi].size());
138 }
139 }
140
141 // Sync agglomeration across coupled patches
142 labelList nbrAgglom(mesh.nBoundaryFaces(), -1);
143
144 forAll(boundary, patchi)
145 {
146 const polyPatch& pp = boundary[patchi];
147 if (pp.coupled())
148 {
149 finalAgglom[patchi] = identity(pp.size());
150 forAll(pp, i)
151 {
152 const label agglomi = pp.start() - mesh.nInternalFaces() + i;
153 nbrAgglom[agglomi] = finalAgglom[patchi][i];
154 }
155 }
156 }
157
158 syncTools::swapBoundaryFaceList(mesh, nbrAgglom);
159 forAll(boundary, patchi)
160 {
161 const polyPatch& pp = boundary[patchi];
162 if (pp.coupled() && !refCast<const coupledPolyPatch>(pp).owner())
163 {
164 forAll(pp, i)
165 {
166 const label agglomi = pp.start() - mesh.nInternalFaces() + i;
167 finalAgglom[patchi][i] = nbrAgglom[agglomi];
168 }
169 }
170 }
171
172 finalAgglom.write();
173
174 if (writeAgglom)
175 {
176 globalIndex index(nCoarseFaces);
177 volScalarField facesAgglomeration
178 (
180 (
181 "facesAgglomeration",
182 mesh.time().timeName(),
183 mesh,
184 IOobject::NO_READ,
185 IOobject::NO_WRITE
186 ),
187 mesh,
188 dimensionedScalar(dimless, Zero)
189 );
190
191 volScalarField::Boundary& facesAgglomerationBf =
192 facesAgglomeration.boundaryFieldRef();
193
194 label coarsePatchIndex = 0;
195 forAll(boundary, patchi)
196 {
197 const polyPatch& pp = boundary[patchi];
198 if (pp.size() > 0)
199 {
200 fvPatchScalarField& bFacesAgglomeration =
201 facesAgglomerationBf[patchi];
202
203 forAll(bFacesAgglomeration, j)
204 {
205 bFacesAgglomeration[j] =
206 index.toGlobal
207 (
208 Pstream::myProcNo(),
209 finalAgglom[patchi][j] + coarsePatchIndex
210 );
211 }
212
213 coarsePatchIndex += max(finalAgglom[patchi]) + 1;
214 }
215 }
216
217 Info<< "\nWriting facesAgglomeration" << endl;
218 facesAgglomeration.write();
219 }
220
221 Info<< "End\n" << endl;
222 return 0;
223}
224
225
226// ************************************************************************* //
Y[inertIndex] max(0.0)
IOdictionary is derived from dictionary and IOobject to give the dictionary automatic IO functionalit...
Definition: IOdictionary.H:57
Defines the attributes of an object for which implicit objectRegistry management is supported,...
Definition: IOobject.H:170
virtual bool write(const token &tok)=0
Write token to stream or otherwise handle it.
const Field< point_type > & localPoints() const
Return pointField of points in patch.
const List< face_type > & localFaces() const
Return patch faces addressing into local point list.
A keyword and a list of tokens is an 'entry'.
Definition: entry.H:70
Calculates a unique integer (label so might not have enough room - 2G max) for processor + local inde...
Definition: globalIndex.H:68
Primitive patch pair agglomerate method.
const word & name() const noexcept
The patch name.
A polyBoundaryMesh is a polyPatch list with additional search methods and registered IO.
A patch is a list of labels that address the faces in the global face list.
Definition: polyPatch.H:75
virtual bool coupled() const
Return true if this patch is geometrically coupled (i.e. faces and.
Definition: polyPatch.H:380
label start() const
Return start label of this patch in the polyMesh face list.
Definition: polyPatch.H:364
A class for handling words, derived from Foam::string.
Definition: word.H:68
faceListList boundary
dynamicFvMesh & mesh
Required Variables.
const word dictName("faMeshDefinition")
Namespace for OpenFOAM.
labelList identity(const label len, label start=0)
Return an identity map of the given length with (map[i] == i)
Definition: labelList.C:38
messageStream Info
Information stream (stdout output on master, null elsewhere)
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:372
IOobject dictIO
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:333
Unit conversion functions.