Loading...
Searching...
No Matches
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"
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 (UPstream::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(
84)
85{
86 const word& nbrPatchName = pp.neighbPatchName();
87
88 const Switch distributed = pp.AMI().distributed();
89
90 const scalarField& srcWeightsSum = pp.AMI().srcWeightsSum();
91 const auto srcWeightLimits = gMinMax(srcWeightsSum);
92 const auto srcWeightAvg = gAverage(srcWeightsSum);
93
94 const labelListList& srcAddress = pp.AMI().srcAddress();
95
96 labelMinMax srcNbrLimits(labelMax, labelMin);
97 scalar srcNbrAvg(0);
98 for (const labelList& srcFace : srcAddress)
99 {
100 const label n = srcFace.size();
101
102 srcNbrAvg += n;
103 srcNbrLimits.add(n);
104 }
105
106 {
107 reduce(srcNbrLimits, sumOp<labelMinMax>());
108
109 label count = srcAddress.size();
110 sumReduce(srcNbrAvg, count);
111 srcNbrAvg /= (count + ROOTVSMALL);
112 }
113
114 const scalarField& tgtWeightsSum = pp.AMI().tgtWeightsSum();
115 const auto tgtWeightLimits = gMinMax(tgtWeightsSum);
116 const auto tgtWeightAvg = gAverage(tgtWeightsSum);
117
118 const labelListList& tgtAddress = pp.AMI().tgtAddress();
119
120 labelMinMax tgtNbrLimits(labelMax, labelMin);
121 scalar tgtNbrAvg(0);
122 for (const labelList& tgtFace : tgtAddress)
123 {
124 const label n = tgtFace.size();
125
126 tgtNbrAvg += n;
127 tgtNbrLimits.add(n);
128 }
129
130 {
131 reduce(tgtNbrLimits, sumOp<labelMinMax>());
132
133 label count = tgtAddress.size();
134 sumReduce(tgtNbrAvg, count);
135 tgtNbrAvg /= (count + ROOTVSMALL);
136 }
137
138 file()
139 << mesh_.time().timeName() << tab
140 << pp.name() << tab
141 << nbrPatchName << tab;
142
143
144 if (UPstream::parRun())
145 {
146 file() << distributed << tab;
147 }
148
149 file()
150 << srcWeightLimits.min() << tab
151 << srcWeightLimits.max() << tab
152 << srcWeightAvg << tab
153 << srcNbrLimits.min() << tab
154 << srcNbrLimits.max() << tab
155 << srcNbrAvg << tab
156 << tgtWeightLimits.min() << tab
157 << tgtWeightLimits.max() << tab
158 << tgtWeightAvg << tab
159 << tgtNbrLimits.min() << tab
160 << tgtNbrLimits.max() << tab
161 << tgtNbrAvg
162 << endl;
163
164 Log << " Patches: " << nl
165 << " Source: " << pp.name() << nl
166 << " Target: " << nbrPatchName << nl;
167
168 if (UPstream::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) << srcWeightLimits.min()
180 << " | " << setw(w) << tgtWeightLimits.min() << " | " << nl
181 << " max(weight) | " << setw(w) << srcWeightLimits.max()
182 << " | " << setw(w) << tgtWeightLimits.max() << " | " << nl
183 << " ave(weight) | " << setw(w) << srcWeightAvg
184 << " | " << setw(w) << tgtWeightAvg << " | " << nl
185 << " min(address) | " << setw(w) << srcNbrLimits.min()
186 << " | " << setw(w) << tgtNbrLimits.min() << " | " << nl
187 << " max(address) | " << setw(w) << srcNbrLimits.max()
188 << " | " << setw(w) << tgtNbrLimits.max() << " | " << nl
189 << " ave(address) | " << setw(w) << srcNbrAvg
190 << " | " << setw(w) << tgtNbrAvg << " | " << nl
191 << endl;
192
193 setResult(pp.name() + ":src", pp.name());
194 setResult(pp.name() + ":tgt", nbrPatchName);
195 setResult(pp.name() + ":src:min(weight)", srcWeightLimits.min());
196 setResult(pp.name() + ":src:max(weight)", srcWeightLimits.max());
197 setResult(pp.name() + ":src:ave(weight)", srcWeightAvg);
198 setResult(pp.name() + ":src:min(address)", srcNbrLimits.min());
199 setResult(pp.name() + ":src:max(address)", srcNbrLimits.max());
200 setResult(pp.name() + ":src:ave(address)", srcNbrAvg);
201 setResult(pp.name() + ":tgt:min(weight)", tgtWeightLimits.min());
202 setResult(pp.name() + ":tgt:max(weight)", tgtWeightLimits.max());
203 setResult(pp.name() + ":tgt:ave(weight)", tgtWeightAvg);
204 setResult(pp.name() + ":tgt:min(address)", tgtNbrLimits.min());
205 setResult(pp.name() + ":tgt:max(address)", tgtNbrLimits.max());
206 setResult(pp.name() + ":tgt:ave(address)", tgtNbrAvg);
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 = globalFaces().gather(weightSum);
242
243 const bool isACMI = isA<cyclicACMIPolyPatch>(cpp);
244
245 scalarField mergedMask;
246 if (isACMI)
247 {
249
250 mergedMask = globalFaces().gather(pp.mask());
251 }
252
253 if (Pstream::master())
254 {
255 instant inst(mesh_.time().value(), mesh_.time().timeName());
256
258 (
259 mergedPoints,
260 mergedFaces,
261 (baseTimeDir()/cpp.name() + "_" + side),
262 false // serial: master-only
263 );
264
265 writer.setTime(inst);
266 writer.writeTimeValue();
267 writer.writeGeometry();
268
269 writer.beginCellData(1 + (isACMI ? 1 : 0));
270 writer.write("weightsSum", mergedWeights);
271
272 if (isACMI)
274 writer.write("mask", mergedMask);
275 }
276 }
277}
278
279
281(
282 const cyclicAMIPolyPatch& cpp
283) const
284{
285 if (cpp.owner())
286 {
287 writeWeightField(cpp, cpp.AMI().srcWeightsSum(), "src");
288 writeWeightField(cpp.neighbPatch(), cpp.AMI().tgtWeightsSum(), "tgt");
289 }
290}
291
292
293// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
294
296(
297 const word& name,
298 const Time& runTime,
299 const dictionary& dict
300)
301:
302 fvMeshFunctionObject(name, runTime, dict),
303 writeFile(mesh_, name, typeName, dict),
304 writeFields_(false),
305 patchIDs_()
307 read(dict);
308}
309
310
311// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
312
314{
316 {
317 patchIDs_.clear();
318 labelHashSet ids;
319
320 for (const polyPatch& pp : mesh_.boundaryMesh())
321 {
322 const auto* amicpp = isA<cyclicAMIPolyPatch>(pp);
323
324 if (amicpp && amicpp->owner())
325 {
326 ids.insert(pp.index());
327 }
328 }
329
330 patchIDs_ = ids.sortedToc();
331
332 writeFileHeader(file());
333
334 writeFields_ = dict.get<bool>("writeFields");
335
336 return true;
337 }
338
339 return false;
340}
341
344{
345 return true;
346}
347
348
350{
351 Log << type() << " " << name() << " write:" << nl;
352
353 const polyBoundaryMesh& pbm = mesh_.boundaryMesh();
354 for (const label patchi : patchIDs_)
355 {
356 const polyPatch& pp = pbm[patchi];
357 const auto& cpp = static_cast<const cyclicAMIPolyPatch&>(pp);
358
359 reportPatch(cpp);
360
361 if (writeFields_)
362 {
363 writeWeightFields(cpp);
364 }
365 }
366
367 return true;
368}
369
370
371// ************************************************************************* //
#define Log
Definition PDRblock.C:28
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::lineWriter writer(edgeCentres, edgeList::null(), fileName(aMesh.time().globalPath()/(vtkBaseFileName+"-edgesCentres")))
uindirectPrimitivePatch pp(UIndirectList< face >(mesh.faces(), faceLabels), mesh.points())
const polyBoundaryMesh & pbm
const scalarField & srcWeightsSum() const
Return const access to normalisation factor of source patch weights (i.e. the sum before normalisatio...
const scalarField & tgtWeightsSum() const
Return const access to normalisation factor of target patch weights (i.e. the sum before normalisatio...
bool insert(const Key &key)
Insert a new entry, not overwriting existing entries.
Definition HashSet.H:229
List< Key > sortedToc() const
The table of contents (the keys) in sorted order.
Definition HashTable.C:156
static unsigned int defaultPrecision() noexcept
Return the default precision.
Definition IOstream.H:437
const T & max() const noexcept
The max value.
Definition MinMax.H:217
const T & min() const noexcept
The min value.
Definition MinMax.H:207
MinMax< T > & add(const MinMax &other)
Extend the range to include the other min/max range.
Definition MinMaxI.H:240
An Ostream is an abstract base class for all output systems (streams, files, token lists,...
Definition Ostream.H:59
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, globalIndex &pointAddr, globalIndex &faceAddr, labelList &pointMergeMap=const_cast< labelList & >(labelList::null()), 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.
A simple wrapper around bool so that it can be read as a word: true/false, on/off,...
Definition Switch.H:81
Class to control time during OpenFOAM simulations that is also the top-level objectRegistry.
Definition Time.H:75
void size(const label n)
Older name for setAddressableSize.
Definition UList.H:118
static bool parRun(const bool on) noexcept
Set as parallel run on/off.
Definition UPstream.H:1669
static bool master(const label communicator=worldComm)
True if process corresponds to the master rank in the communicator.
Definition UPstream.H:1714
static bool & parRun() noexcept
Test if this a parallel run.
Definition UPstream.H:1681
Pointer management similar to std::unique_ptr, with some additional methods and type checking.
Definition autoPtr.H:65
Cyclic patch for Arbitrarily Coupled Mesh Interface (ACMI).
Cyclic patch for Arbitrary Mesh Interface (AMI).
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:133
Abstract base-class for Time/database function objects.
virtual bool read(const dictionary &dict)
Read and set the function object if its data have changed.
Computes the min/max/average weights of arbitrary mesh interface (AMI) patches, and optionally report...
Definition AMIWeights.H:136
void writeWeightFields(const cyclicAMIPolyPatch &cpp) const
Write weight fields if writeFields=true.
Definition AMIWeights.C:274
void writeWeightField(const cyclicAMIPolyPatch &cpp, const scalarField &weightSum, const word &side) const
Write weight field.
Definition AMIWeights.C:204
virtual void reportPatch(const cyclicAMIPolyPatch &pp)
Helper function to report patch information.
Definition AMIWeights.C:75
virtual bool read(const dictionary &dict)
Read the function-object dictionary.
Definition AMIWeights.C:306
AMIWeights(const word &name, const Time &runTime, const dictionary &dict)
Construct from name, Time and dictionary.
Definition AMIWeights.C:289
bool writeFields_
Flag to write AMI fields (as VTK files).
Definition AMIWeights.H:144
virtual void writeFileHeader(Ostream &os)
Output file header information.
Definition AMIWeights.C:41
virtual bool execute()
Execute the function-object operations (no-op).
Definition AMIWeights.C:336
virtual bool write()
Write the function-object results.
Definition AMIWeights.C:342
labelList patchIDs_
List of AMI patch IDs.
Definition AMIWeights.H:149
const fvMesh & mesh_
Reference to the fvMesh.
fvMeshFunctionObject(const fvMeshFunctionObject &)=delete
No copy construct.
void setResult(const word &entryName, const Type &value)
Add result.
virtual void writeTabbed(Ostream &os, const string &str) const
Write a tabbed string to stream.
Definition writeFile.C:334
writeFile(const objectRegistry &obr, const fileName &prefix, const word &name="undefined", const bool writeToFile=true, const string &ext=".dat")
Construct from objectRegistry, prefix, fileName.
Definition writeFile.C:200
virtual void writeHeader(Ostream &os, const string &str) const
Write a commented header to stream.
Definition writeFile.C:344
virtual bool read(const dictionary &dict)
Read.
Definition writeFile.C:240
virtual OFstream & file()
Return access to the file (if only 1).
Definition writeFile.C:270
virtual void writeCommented(Ostream &os, const string &str) const
Write a commented string to stream.
Definition writeFile.C:318
fileName baseTimeDir() const
Return the base directory for the current time value.
Definition writeFile.C:66
Calculates points shared by more than two processor patches or cyclic patches.
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 registered IO, a reference to the associated polyMesh,...
A patch is a list of labels that address the faces in the global face list.
Definition polyPatch.H:73
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:66
#define defineTypeNameAndDebug(Type, DebugSwitch)
Define the typeName and debug information.
Definition className.H:142
engineTime & runTime
OBJstream os(runTime.globalPath()/outputName)
auto & name
unsigned int count(const UList< bool > &bools, const bool val=true)
Count number of 'true' entries.
Definition BitOps.H:73
Function objects are OpenFOAM utilities to ease workflow configurations and enhance workflows.
Namespace for OpenFOAM.
Type gAverage(const FieldField< Field, Type > &f, const label comm)
The global arithmetic average of a FieldField.
Type & refCast(U &obj)
A dynamic_cast (for references) to Type reference.
Definition typeInfo.H:172
List< labelList > labelListList
List of labelList.
Definition labelList.H:38
bool read(const char *buf, int32_t &val)
Same as readInt32.
Definition int32.H:127
List< label > labelList
A List of labels.
Definition List.H:62
HashSet< label, Hash< label > > labelHashSet
A HashSet of labels, uses label hasher.
Definition HashSet.H:85
constexpr label labelMin
Definition label.H:54
MinMax< label > labelMinMax
A label min/max range.
Definition MinMax.H:96
List< face > faceList
List of faces.
Definition faceListFwd.H:41
fileName::Type type(const fileName &name, const bool followLink=true)
Return the file type: DIRECTORY or FILE, normally following symbolic links.
Definition POSIX.C:801
Field< scalar > scalarField
Specialisation of Field<T> for scalar.
constexpr label labelMax
Definition label.H:55
Omanip< int > setw(const int i)
Definition IOmanip.H:199
const word GlobalIOList< Tuple2< scalar, vector > >::typeName("scalarVectorTable")
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition Ostream.H:519
const Type * isA(const U &obj)
Attempt dynamic_cast to Type.
Definition typeInfo.H:87
void reduce(T &value, BinaryOp bop, const int tag=UPstream::msgType(), const int communicator=UPstream::worldComm)
Reduce inplace (cf. MPI Allreduce).
MinMax< Type > gMinMax(const FieldField< Field, Type > &f)
void sumReduce(T &value, CountType &count, const int tag=UPstream::msgType(), const int communicator=UPstream::worldComm)
Reduce inplace (cf. MPI Allreduce) the sum of value and counter (eg, for averaging).
word name(const expressions::valueTypeCode typeCode)
A word representation of a valueTypeCode. Empty for expressions::valueTypeCode::INVALID.
Definition exprTraits.C:127
vectorField pointField
pointField is a vectorField.
constexpr char nl
The newline '\n' character (0x0a).
Definition Ostream.H:50
constexpr char tab
The tab '\t' character(0x09).
Definition Ostream.H:49
dictionary dict
#define forAll(list, i)
Loop across all elements in list.
Definition stdFoam.H:299