AMIWeights.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) 2018-2021 OpenCFD Ltd.
9-------------------------------------------------------------------------------
10License
11 This file is part of OpenFOAM.
12
13 OpenFOAM is free software: you can redistribute it and/or modify it
14 under the terms of the GNU General Public License as published by
15 the Free Software Foundation, either version 3 of the License, or
16 (at your option) any later version.
17
18 OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
19 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
20 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21 for more details.
22
23 You should have received a copy of the GNU General Public License
24 along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
25
26\*---------------------------------------------------------------------------*/
27
28#include "AMIWeights.H"
29#include "fvMesh.H"
31#include "PatchTools.H"
32#include "cyclicACMIPolyPatch.H"
34
35// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
36
37namespace Foam
38{
39namespace functionObjects
40{
43}
44}
45
46// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
47
49{
50 writeHeader(os, "AMI");
51
52 writeCommented(os, "Time");
53 forAll(patchIDs_, patchi)
54 {
55 writeTabbed(os, "Patch");
56 writeTabbed(os, "nbr_patch");
57
58 if (Pstream::parRun())
59 {
60 writeTabbed(os, "distributed");
61 }
62
63 writeTabbed(os, "src_min_weight");
64 writeTabbed(os, "src_max_weight");
65 writeTabbed(os, "src_average_weight");
66 writeTabbed(os, "src_min_neighbours");
67 writeTabbed(os, "src_max_neighbours");
68 writeTabbed(os, "src_average_neighbours");
69 writeTabbed(os, "tgt_min_weight");
70 writeTabbed(os, "tgt_max_weight");
71 writeTabbed(os, "tgt_average_weight");
72 writeTabbed(os, "tgt_min_neighbours");
73 writeTabbed(os, "tgt_max_neighbours");
74 writeTabbed(os, "tgt_average_neighbours");
75 }
76
77 os << endl;
78}
79
80
82(
83 const cyclicAMIPolyPatch& pp
84)
85{
86 const word& nbrPatchName = pp.neighbPatchName();
87
88 const Switch distributed = pp.AMI().singlePatchProc() == -1;
89
90 const scalarField& srcWeightsSum = pp.AMI().srcWeightsSum();
91 const scalar srcMinWeight = gMin(srcWeightsSum);
92 const scalar srcMaxWeight = gMax(srcWeightsSum);
93 const scalar srcAveWeight = gAverage(srcWeightsSum);
94
95 const labelListList& srcAddress = pp.AMI().srcAddress();
96 label srcMinNbr = labelMax;
97 label srcMaxNbr = labelMin;
98 scalar srcAveNbr = 0;
99 for (const labelList& srcFace : srcAddress)
100 {
101 const label n = srcFace.size();
102 srcAveNbr += n;
103 srcMinNbr = min(srcMinNbr, n);
104 srcMaxNbr = max(srcMaxNbr, n);
105 }
106
107 reduce(srcMinNbr, minOp<label>());
108 reduce(srcMaxNbr, maxOp<label>());
109
110 srcAveNbr =
111 returnReduce(srcAveNbr, sumOp<scalar>())
112 /(returnReduce(srcAddress.size(), sumOp<scalar>()) + ROOTVSMALL);
113
114 const scalarField& tgtWeightsSum = pp.AMI().tgtWeightsSum();
115 const scalar tgtMinWeight = gMin(tgtWeightsSum);
116 const scalar tgtMaxWeight = gMax(tgtWeightsSum);
117 const scalar tgtAveWeight = gAverage(tgtWeightsSum);
118
119 const labelListList& tgtAddress = pp.AMI().tgtAddress();
120 label tgtMinNbr = labelMax;
121 label tgtMaxNbr = labelMin;
122 scalar tgtAveNbr = 0;
123 for (const labelList& tgtFace : tgtAddress)
124 {
125 const label n = tgtFace.size();
126 tgtAveNbr += n;
127 tgtMinNbr = min(tgtMinNbr, n);
128 tgtMaxNbr = max(tgtMaxNbr, n);
129 }
130
131 reduce(tgtMinNbr, minOp<label>());
132 reduce(tgtMaxNbr, maxOp<label>());
133
134 tgtAveNbr =
135 returnReduce(tgtAveNbr, sumOp<scalar>())
136 /(returnReduce(tgtAddress.size(), sumOp<scalar>()) + ROOTVSMALL);
137
138 file()
139 << mesh_.time().timeName() << tab
140 << pp.name() << tab
141 << nbrPatchName << tab;
142
143
144 if (Pstream::parRun())
145 {
146 file() << distributed << tab;
147 }
148
149 file()
150 << srcMinWeight << tab
151 << srcMaxWeight << tab
152 << srcAveWeight << tab
153 << srcMinNbr << tab
154 << srcMaxNbr << tab
155 << srcAveNbr << tab
156 << tgtMinWeight << tab
157 << tgtMaxWeight << tab
158 << tgtAveWeight << tab
159 << tgtMinNbr << tab
160 << tgtMaxNbr << tab
161 << tgtAveNbr << tab
162 << endl;
163
164 Log << " Patches: " << nl
165 << " Source: " << pp.name() << nl
166 << " Target: " << nbrPatchName << nl;
167
168 if (Pstream::parRun())
169 {
170 Log << " Parallel distributed: " << distributed << nl;
171 }
172
173 Log << nl;
174
175 const label w = IOstream::defaultPrecision() + 8;
176
177 Log << " | " << setw(w) << pp.name()
178 << " | " << setw(w) << nbrPatchName << " | " << nl
179 << " min(weight) | " << setw(w) << srcMinWeight
180 << " | " << setw(w) << tgtMinWeight << " | " << nl
181 << " max(weight) | " << setw(w) << srcMaxWeight
182 << " | " << setw(w) << tgtMaxWeight << " | " << nl
183 << " ave(weight) | " << setw(w) << srcAveWeight
184 << " | " << setw(w) << tgtAveWeight << " | " << nl
185 << " min(address) | " << setw(w) << srcMinNbr
186 << " | " << setw(w) << tgtMinNbr << " | " << nl
187 << " max(address) | " << setw(w) << srcMaxNbr
188 << " | " << setw(w) << tgtMaxNbr << " | " << nl
189 << " ave(address) | " << setw(w) << srcAveNbr
190 << " | " << setw(w) << tgtAveNbr << " | " << nl
191 << endl;
192
193 setResult(pp.name() + ":src", pp.name());
194 setResult(pp.name() + ":tgt", nbrPatchName);
195 setResult(pp.name() + ":src:min(weight)", srcMinWeight);
196 setResult(pp.name() + ":src:max(weight)", srcMaxWeight);
197 setResult(pp.name() + ":src:ave(weight)", srcAveWeight);
198 setResult(pp.name() + ":src:min(address)", srcMinNbr);
199 setResult(pp.name() + ":src:max(address)", srcMaxNbr);
200 setResult(pp.name() + ":src:ave(address)", srcAveNbr);
201 setResult(pp.name() + ":tgt:min(weight)", tgtMinWeight);
202 setResult(pp.name() + ":tgt:max(weight)", tgtMaxWeight);
203 setResult(pp.name() + ":tgt:ave(weight)", tgtAveWeight);
204 setResult(pp.name() + ":tgt:min(address)", tgtMinNbr);
205 setResult(pp.name() + ":tgt:max(address)", tgtMaxNbr);
206 setResult(pp.name() + ":tgt:ave(address)", tgtAveNbr);
207}
208
209
211(
212 const cyclicAMIPolyPatch& cpp,
213 const scalarField& weightSum,
214 const word& side
215) const
216{
217 // Collect geometry
218 labelList pointToGlobal;
219 labelList uniqueMeshPointLabels;
221 autoPtr<globalIndex> globalFaces;
222 faceList mergedFaces;
223 pointField mergedPoints;
225 (
226 mesh_,
227 cpp.localFaces(),
228 cpp.meshPoints(),
229 cpp.meshPointMap(),
230
231 pointToGlobal,
232 uniqueMeshPointLabels,
234 globalFaces,
235
236 mergedFaces,
237 mergedPoints
238 );
239
240 // Collect field
241 scalarField mergedWeights;
242 globalFaces().gather(weightSum, mergedWeights);
243
244 const bool isACMI = isA<cyclicACMIPolyPatch>(cpp);
245
246 scalarField mergedMask;
247 if (isACMI)
248 {
249 const cyclicACMIPolyPatch& pp = refCast<const cyclicACMIPolyPatch>(cpp);
250
251 globalFaces().gather(pp.mask(), mergedMask);
252 }
253
254 if (Pstream::master())
255 {
256 instant inst(mesh_.time().value(), mesh_.time().timeName());
257
259 (
260 mergedPoints,
261 mergedFaces,
262 (baseTimeDir()/cpp.name() + "_" + side),
263 false // serial: master-only
264 );
265
266 writer.setTime(inst);
267 writer.writeTimeValue();
268 writer.writeGeometry();
269
270 writer.beginCellData(1 + (isACMI ? 1 : 0));
271 writer.write("weightsSum", mergedWeights);
272
273 if (isACMI)
274 {
275 writer.write("mask", mergedMask);
276 }
277 }
278}
279
280
282(
283 const cyclicAMIPolyPatch& cpp
284) const
285{
286 if (cpp.owner())
287 {
288 writeWeightField(cpp, cpp.AMI().srcWeightsSum(), "src");
289 writeWeightField(cpp.neighbPatch(), cpp.AMI().tgtWeightsSum(), "tgt");
290 }
291}
292
293
294// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
295
297(
298 const word& name,
299 const Time& runTime,
300 const dictionary& dict
301)
302:
304 writeFile(mesh_, name, typeName, dict),
305 writeFields_(false),
306 patchIDs_()
307{
308 read(dict);
309}
310
311
312// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
313
315{
317 {
318 patchIDs_.clear();
319 labelHashSet ids;
320
321 for (const polyPatch& pp : mesh_.boundaryMesh())
322 {
323 const auto* amicpp = isA<cyclicAMIPolyPatch>(pp);
324
325 if (amicpp && amicpp->owner())
326 {
327 ids.insert(pp.index());
328 }
329 }
330
331 patchIDs_ = ids.sortedToc();
332
333 writeFileHeader(file());
334
335 writeFields_ = dict.get<bool>("writeFields");
336
337 return true;
338 }
339
340 return false;
341}
342
343
345{
346 return true;
347}
348
349
351{
352 Log << type() << " " << name() << " write:" << nl;
353
354 const polyBoundaryMesh& pbm = mesh_.boundaryMesh();
355 for (const label patchi : patchIDs_)
356 {
357 const polyPatch& pp = pbm[patchi];
358 const auto& cpp = static_cast<const cyclicAMIPolyPatch&>(pp);
359
360 reportPatch(cpp);
361
362 if (writeFields_)
363 {
364 writeWeightFields(cpp);
365 }
366 }
367
368 return true;
369}
370
371
372// ************************************************************************* //
#define Log
Definition: PDRblock.C:35
label n
Macros for easy insertion into run-time selection tables.
#define addToRunTimeSelectionTable(baseType, thisType, argNames)
Add to construction table with typeName as the key.
vtk::internalMeshWriter writer(topoMesh, topoCells, vtk::formatType::INLINE_ASCII, runTime.path()/"blockTopology")
const scalarField & srcWeightsSum() const
const labelListList & srcAddress() const
Return const access to source patch addressing.
const scalarField & tgtWeightsSum() const
const labelListList & tgtAddress() const
Return const access to target patch addressing.
bool insert(const Key &key)
Insert a new entry, not overwriting existing entries.
Definition: HashSet.H:191
List< Key > sortedToc() const
The table of contents (the keys) in sorted order.
Definition: HashTable.C:137
static unsigned int defaultPrecision() noexcept
Return the default precision.
Definition: IOstream.H:342
An Ostream is an abstract base class for all output systems (streams, files, token lists,...
Definition: Ostream.H:62
static void gatherAndMerge(const scalar mergeDist, const PrimitivePatch< FaceList, PointField > &pp, Field< typename PrimitivePatch< FaceList, PointField >::point_type > &mergedPoints, List< typename PrimitivePatch< FaceList, PointField >::face_type > &mergedFaces, labelList &pointMergeMap, const bool useLocal=false)
Gather points and faces onto master and merge into single patch.
const Map< label > & meshPointMap() const
Mesh point map.
const labelList & meshPoints() const
Return labelList of mesh points in patch.
const List< face_type > & localFaces() const
Return patch faces addressing into local point list.
virtual bool read()
Re-read model coefficients if they have changed.
A simple wrapper around bool so that it can be read as a word: true/false, on/off,...
Definition: Switch.H:78
Class to control time during OpenFOAM simulations that is also the top-level objectRegistry.
Definition: Time.H:80
void size(const label n)
Older name for setAddressableSize.
Definition: UList.H:114
static bool & parRun() noexcept
Test if this a parallel run.
Definition: UPstream.H:433
Pointer management similar to std::unique_ptr, with some additional methods and type checking.
Definition: autoPtr.H:66
Cyclic patch for Arbitrarily Coupled Mesh Interface (ACMI).
const scalarField & mask() const
Mask field where 1 = overlap(coupled), 0 = no-overlap.
Cyclic patch for Arbitrary Mesh Interface (AMI)
const word & neighbPatchName() const
Neighbour patch name.
virtual bool owner() const
Does this side own the patch?
const AMIPatchToPatchInterpolation & AMI() const
Return a reference to the AMI interpolator.
virtual const cyclicAMIPolyPatch & neighbPatch() const
Return a reference to the neighbour patch.
A list of keyword definitions, which are a keyword followed by a number of values (eg,...
Definition: dictionary.H:126
Abstract base-class for Time/database function objects.
Computes the min/max/average weights of arbitrary mesh interface (AMI) patches, and optionally report...
Definition: AMIWeights.H:155
void writeWeightFields(const cyclicAMIPolyPatch &cpp) const
Write weight fields if writeFields=true.
Definition: AMIWeights.C:282
void writeWeightField(const cyclicAMIPolyPatch &cpp, const scalarField &weightSum, const word &side) const
Write weight field.
Definition: AMIWeights.C:211
virtual void reportPatch(const cyclicAMIPolyPatch &pp)
Helper function to report patch information.
Definition: AMIWeights.C:82
virtual void writeFileHeader(Ostream &os)
Output file header information.
Definition: AMIWeights.C:48
virtual bool execute()
Execute, currently does nothing.
Definition: AMIWeights.C:344
virtual bool write()
Write the AMIWeights.
Definition: AMIWeights.C:350
labelList patchIDs_
List of AMI patch IDs.
Definition: AMIWeights.H:164
virtual bool read(const dictionary &)
Read the field min/max data.
Definition: AMIWeights.C:314
Specialization of Foam::functionObject for an Foam::fvMesh, providing a reference to the Foam::fvMesh...
Base class for writing single files from the function objects.
Definition: writeFile.H:120
virtual void writeTabbed(Ostream &os, const string &str) const
Write a tabbed string to stream.
Definition: writeFile.C:285
virtual void writeHeader(Ostream &os, const string &str) const
Write a commented header to stream.
Definition: writeFile.C:295
virtual void writeCommented(Ostream &os, const string &str) const
Write a commented string to stream.
Definition: writeFile.C:269
Calculates points shared by more than two processor patches or cyclic patches.
Definition: globalPoints.H:103
An instant of time. Contains the time value and name. Uses Foam::Time when formatting the name.
Definition: instant.H:56
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
const polyBoundaryMesh & boundaryMesh() const
Return boundaryMesh reference.
Definition: polyPatch.C:315
splitCell * master() const
Definition: splitCell.H:113
Write faces/points (optionally with fields) as a vtp file or a legacy vtk file.
A class for handling words, derived from Foam::string.
Definition: word.H:68
#define defineTypeNameAndDebug(Type, DebugSwitch)
Define the typeName and debug information.
Definition: className.H:121
engineTime & runTime
OBJstream os(runTime.globalPath()/outputName)
Namespace for OpenFOAM.
label max(const labelHashSet &set, label maxValue=labelMin)
Find the max value in labelHashSet, optionally limited by second argument.
Definition: hashSets.C:47
constexpr label labelMin
Definition: label.H:60
fileName::Type type(const fileName &name, const bool followLink=true)
Return the file type: DIRECTORY or FILE, normally following symbolic links.
Definition: MSwindows.C:598
constexpr label labelMax
Definition: label.H:61
Omanip< int > setw(const int i)
Definition: IOmanip.H:199
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:372
void reduce(const List< UPstream::commsStruct > &comms, T &value, const BinaryOp &bop, const int tag, const label comm)
label min(const labelHashSet &set, label minValue=labelMax)
Find the min value in labelHashSet, optionally limited by second argument.
Definition: hashSets.C:33
Type gAverage(const FieldField< Field, Type > &f)
Type gMin(const FieldField< Field, Type > &f)
word name(const expressions::valueTypeCode typeCode)
A word representation of a valueTypeCode. Empty for INVALID.
Definition: exprTraits.C:59
T returnReduce(const T &value, const BinaryOp &bop, const int tag=UPstream::msgType(), const label comm=UPstream::worldComm)
Reduce (copy) and return value.
Type gMax(const FieldField< Field, Type > &f)
constexpr char nl
The newline '\n' character (0x0a)
Definition: Ostream.H:53
constexpr char tab
The tab '\t' character(0x09)
Definition: Ostream.H:52
dictionary dict
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:333