Loading...
Searching...
No Matches
faceAreaPairGAMGAgglomeration.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) 2023-2024 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
27\*---------------------------------------------------------------------------*/
28
30#include "fvMesh.H"
31#include "surfaceFields.H"
35//#include "processorGAMGInterface.H"
37// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
38
39namespace Foam
40{
42
44 (
48 );
49
51 (
54 geometry
55 );
56}
57
58
59// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
60
62(
63 const lduMesh& mesh,
65)
66:
68{
69 const fvMesh& fvmesh = refCast<const fvMesh>(mesh);
70
72 {
73 // This is the <=2406 logic. Apply perturbation to avoid jagged
74 // agglomerations on axis-aligned meshes
75
76 DebugPoutInFunction<< "Agglomerate with perturbation" << endl;
77
78 //agglomerate(mesh, sqrt(fvmesh.magSf().primitiveField()));
80 (
82 0, //mesh,
83 mag
84 (
86 (
87 fvmesh.Sf().primitiveField()
88 /sqrt(fvmesh.magSf().primitiveField()),
89 vector(1, 1.01, 1.02)
90 //vector::one
91 )
92 ),
93 true
94 );
95 }
96 else
97 {
98 // In partial updating mode. Use Galilean invariant agglomeration
99 // to e.g. have constant agglomeration for solid body rotation. Also
100 // scale with face area to be consistent with (most) discretisation.
101
102 DebugPoutInFunction<< "Agglomerate with faceArea magnitude" << endl;
103
105 (
107 0, //mesh,
109 true
110 );
111 }
112}
113
114
116(
117 const lduMesh& mesh,
118 const scalarField& cellVolumes,
119 const vectorField& faceAreas,
121)
122:
123 pairGAMGAgglomeration(mesh, controlDict)
124{
126 {
127 // This is the <=2406 logic. Apply perturbation to avoid jagged
128 // agglomerations on axis-aligned meshes
129
130 DebugPoutInFunction<< "Agglomerate with perturbation" << endl;
131
132 //agglomerate(mesh, sqrt(mag(faceAreas)));
134 (
136 0, //mesh,
137 mag
138 (
140 (
141 faceAreas
142 /sqrt(mag(faceAreas)),
143 vector(1, 1.01, 1.02)
144 //vector::one
145 )
146 ),
147 true
148 );
149 }
150 else
151 {
152 // In partial updating mode. Use Galilean invariant agglomeration
153 // to e.g. have constant agglomeration for solid body rotation. Also
154 // scale with face area to be consistent with (most) discretisation.
155
156 DebugPoutInFunction<< "Agglomerate with faceArea magnitude" << endl;
157
159 (
161 0, //mesh,
162 mag(faceAreas),
163 true
164 );
165 }
166}
167
168
169// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
170
172{
173 const bool ok = pairGAMGAgglomeration::movePoints();
174
175 if (!requireUpdate_)
176 {
177 // movePoints lower down did not trigger update. Update in case of
178 // cyclicAMI since contains addressing across patches and patches
179 // have moved.
180
181 bool hasCyclicAMI = false;
182 if (!processorAgglomerate())
183 {
184 const auto& fineInterfaces = interfaceLevel(0);
185 forAll(fineInterfaces, inti)
186 {
187 if (fineInterfaces.set(inti))
188 {
189 const auto& intf = fineInterfaces[inti];
190 if
191 (
194 )
195 {
196 hasCyclicAMI = true;
197
199 << "Detected cyclicA(C)MI at interface " << inti
200 << ".Redoing patch agglomeration" << endl;
201
202 break;
203 }
204 }
205 }
206 }
207
208
209 if (hasCyclicAMI)
210 {
211 // Redo the interface agglomeration
212 for
213 (
214 label fineLevelIndex = 0;
215 fineLevelIndex < size();
216 fineLevelIndex++
217 )
218 {
219 // Near complete copy of boundary handling in
220 // GAMGAgglomeration::agglomerateLduAddressing
221
222 const auto& fineMesh = meshLevel(fineLevelIndex);
223 const auto& fineInterfaces = interfaceLevel(fineLevelIndex);
224 const lduAddressing& fineMeshAddr = fineMesh.lduAddr();
225
226 // Get restriction map for current level
227 const labelField& restrictMap =
228 restrictAddressing(fineLevelIndex);
229
230 const label startOfRequests = UPstream::nRequests();
231 forAll(fineInterfaces, inti)
232 {
233 if (fineInterfaces.set(inti))
234 {
235 const auto& intf = fineInterfaces[inti];
236
237 if
238 (
241 )
242 {
243 if (fineLevelIndex == 0)
244 {
245 intf.initInternalFieldTransfer
246 (
248 restrictMap,
249 fineMeshAddr.patchAddr(inti)
250 );
251 }
252 else
253 {
254 intf.initInternalFieldTransfer
255 (
257 restrictMap
258 );
259 }
260 }
261 }
262 }
263
264 // Wait for comms to finised
265 UPstream::waitRequests(startOfRequests);
266
267 // New coarse-level interfaces
268 //lduInterfacePtrsList coarseInterfaces(fineInterfaces.size());
269
270 forAll(fineInterfaces, inti)
271 {
272 if (fineInterfaces.set(inti))
273 {
274 const auto& intf = fineInterfaces[inti];
275
276 if
277 (
280 )
281 {
282 tmp<labelField> restrictMapInternalField;
283
284 // The finest mesh uses patchAddr from the
285 // original lduAdressing.
286 // the coarser levels create thei own adressing for
287 // faceCells
288 if (fineLevelIndex == 0)
289 {
290 restrictMapInternalField =
291 intf.interfaceInternalField
292 (
293 restrictMap,
294 fineMeshAddr.patchAddr(inti)
295 );
296 }
297 else
298 {
299 restrictMapInternalField =
300 intf.interfaceInternalField
301 (
302 restrictMap
303 );
304 }
305
306 tmp<labelField> nbrRestrictMapInternalField =
307 intf.internalFieldTransfer
308 (
310 restrictMap
311 );
312
313 lduPrimitiveMesh& coarseMesh =
314 meshLevels_[fineLevelIndex];
315
316 autoPtr<GAMGInterface> coarseIntf
317 (
319 (
320 inti,
321 coarseMesh.rawInterfaces(),
322 intf,
323 restrictMapInternalField(),
324 nbrRestrictMapInternalField(),
325 fineLevelIndex,
326 fineMesh.comm()
327 )
328 );
329
330 //coarseInterfaces.set(inti, coarseIntf.ptr());
331 coarseMesh.interfaces().set
332 (
333 inti,
334 coarseIntf.ptr()
335 );
336 coarseMesh.primitiveInterfaces().set
337 (
338 inti,
339 &coarseMesh.interfaces()[inti]
340 );
341 }
342 }
343 }
344
345 //meshLevels_[fineLevelIndex].addInterfaces
346 //(
347 // coarseInterfaces,
348 // lduPrimitiveMesh::nonBlockingSchedule
349 // <
350 // processorGAMGInterface
351 // >
352 // (
353 // coarseInterfaces
354 // )
355 //);
356 }
357 }
358
359 if (debug)
360 {
361 printLevels();
362 }
363 }
364
365 return ok;
366}
367
368
369// ************************************************************************* //
Macros for easy insertion into run-time selection tables.
#define addToRunTimeSelectionTable(baseType, thisType, argNames)
Add to construction table with typeName as the key.
Geometric agglomerated algebraic multigrid agglomeration class.
virtual bool movePoints()
Update when the mesh moves.
bool processorAgglomerate() const
Whether to agglomerate across processors.
label nCellsInCoarsestLevel_
Number of cells in coarsest level.
bool requireUpdate_
Does agglomeration require update.
PtrList< lduPrimitiveMesh > meshLevels_
Hierarchy of mesh addressing.
bool requiresUpdate() const
Does the agglomeration need to be fully updated?
void printLevels() const
Print level overview.
const lduInterfacePtrsList & interfaceLevel(const label leveli) const
Return LDU interface addressing of given level.
const labelField & restrictAddressing(const label leveli) const
Return cell restrict addressing of given level.
const lduMesh & meshLevel(const label leveli) const
Return LDU mesh of given level.
static autoPtr< GAMGInterface > New(const label index, const lduInterfacePtrsList &coarseInterfaces, const lduInterface &fineInterface, const labelField &localRestrictAddressing, const labelField &neighbourRestrictAddressing, const label fineLevelIndex, const label coarseComm)
Return a pointer to a new interface created on freestore given.
const Internal::FieldType & primitiveField() const noexcept
Return a const-reference to the internal field values.
static label nRequests() noexcept
Number of outstanding requests (on the internal list of requests).
@ nonBlocking
"nonBlocking" (immediate) : (MPI_Isend, MPI_Irecv)
Definition UPstream.H:84
static void waitRequests()
Wait for all requests to finish.
Definition UPstream.H:2497
const T * set(const label i) const
Return const pointer to element (can be nullptr), or nullptr for out-of-range access (ie,...
Definition UPtrList.H:366
Pointer management similar to std::unique_ptr, with some additional methods and type checking.
Definition autoPtr.H:65
T * ptr() noexcept
Same as release().
Definition autoPtr.H:248
A list of keyword definitions, which are a keyword followed by a number of values (eg,...
Definition dictionary.H:133
Agglomerate using the pair algorithm.
virtual bool movePoints()
Update when the mesh moves.
faceAreaPairGAMGAgglomeration(const lduMesh &mesh, const dictionary &controlDict)
Construct given mesh and controls.
Mesh data needed to do the Finite Volume discretisation.
Definition fvMesh.H:85
const surfaceVectorField & Sf() const
Return cell face area vectors.
const surfaceScalarField & magSf() const
Return cell face area magnitudes.
The class contains the addressing required by the lduMatrix: upper, lower and losort.
virtual const labelUList & patchAddr(const label patchNo) const =0
Return patch to internal addressing given patch number.
Abstract base class for meshes which provide LDU addressing for the construction of lduMatrix and LDU...
Definition lduMesh.H:54
Simplest concrete lduMesh that stores the addressing needed by lduMatrix.
const lduInterfacePtrsList & rawInterfaces() const
Return a list of pointers for each patch.
PtrList< const lduInterface > & primitiveInterfaces()
Return a non-const list of primitive interfaces.
virtual lduInterfacePtrsList interfaces() const
Return a list of pointers for each patch with only those pointing to interfaces being set.
Agglomerate using the pair algorithm.
static tmp< labelField > agglomerate(label &nCoarseCells, const lduAddressing &fineMatrixAddressing, const scalarField &faceWeights)
Calculate and return agglomeration.
pairGAMGAgglomeration(const pairGAMGAgglomeration &)=delete
No copy construct.
A class for managing temporary objects.
Definition tmp.H:75
#define defineTypeNameAndDebug(Type, DebugSwitch)
Define the typeName and debug information.
Definition className.H:142
runTime controlDict().readEntry("adjustTimeStep"
dynamicFvMesh & mesh
#define DebugPoutInFunction
Report an information message using Foam::Pout.
Namespace for handling debugging switches.
Definition debug.C:45
Namespace for OpenFOAM.
Type & refCast(U &obj)
A dynamic_cast (for references) to Type reference.
Definition typeInfo.H:172
Field< scalar > scalarField
Specialisation of Field<T> for scalar.
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition Ostream.H:519
dimensionedScalar sqrt(const dimensionedScalar &ds)
const Type * isA(const U &obj)
Attempt dynamic_cast to Type.
Definition typeInfo.H:87
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
Field< vector > vectorField
Specialisation of Field<T> for vector.
Field< label > labelField
Specialisation of Field<T> for label.
Definition labelField.H:48
dimensioned< Type > cmptMultiply(const dimensioned< Type > &, const dimensioned< Type > &)
Vector< scalar > vector
Definition vector.H:57
#define forAll(list, i)
Loop across all elements in list.
Definition stdFoam.H:299
Foam::surfaceFields.