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 -------------------------------------------------------------------------------
10 License
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"
30 #include "foamVtkSurfaceWriter.H"
31 #include "PatchTools.H"
32 #include "cyclicACMIPolyPatch.H"
34 
35 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
36 
37 namespace Foam
38 {
39 namespace functionObjects
40 {
41  defineTypeNameAndDebug(AMIWeights, 0);
42  addToRunTimeSelectionTable(functionObject, AMIWeights, dictionary);
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,
233  globalPoints,
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 // ************************************************************************* //
runTime
engineTime & runTime
Definition: createEngineTime.H:13
Foam::functionObjects::AMIWeights::read
virtual bool read(const dictionary &)
Read the field min/max data.
Definition: AMIWeights.C:314
Foam::maxOp
Definition: ops.H:223
Foam::functionObjects::AMIWeights::patchIDs_
labelList patchIDs_
List of AMI patch IDs.
Definition: AMIWeights.H:164
Foam::Switch
A simple wrapper around bool so that it can be read as a word: true/false, on/off,...
Definition: Switch.H:77
Log
#define Log
Definition: PDRblock.C:35
Foam::Time
Class to control time during OpenFOAM simulations that is also the top-level objectRegistry.
Definition: Time.H:73
Foam::globalPoints
Calculates points shared by more than two processor patches or cyclic patches.
Definition: globalPoints.H:102
Foam::cyclicAMIPolyPatch::owner
virtual bool owner() const
Does this side own the patch?
Definition: cyclicAMIPolyPatch.C:964
cyclicACMIPolyPatch.H
Foam::labelMax
constexpr label labelMax
Definition: label.H:61
Foam::word
A class for handling words, derived from Foam::string.
Definition: word.H:65
Foam::returnReduce
T returnReduce(const T &Value, const BinaryOp &bop, const int tag=Pstream::msgType(), const label comm=UPstream::worldComm)
Definition: PstreamReduceOps.H:94
Foam::polyBoundaryMesh
A polyBoundaryMesh is a polyPatch list with additional search methods and registered IO.
Definition: polyBoundaryMesh.H:63
PatchTools.H
Foam::AMIInterpolation::tgtWeightsSum
const scalarField & tgtWeightsSum() const
Definition: AMIInterpolationI.H:219
Foam::gAverage
Type gAverage(const FieldField< Field, Type > &f)
Definition: FieldFieldFunctions.C:604
Foam::minOp
Definition: ops.H:224
Foam::PatchTools::gatherAndMerge
static void gatherAndMerge(const scalar mergeDist, const PrimitivePatch< FaceList, PointField > &p, Field< typename PrimitivePatch< FaceList, PointField >::point_type > &mergedPoints, List< typename PrimitivePatch< FaceList, PointField >::face_type > &mergedFaces, labelList &pointMergeMap)
Gather points and faces onto master and merge into single patch.
Definition: PatchToolsGatherAndMerge.C:38
Foam::read
bool read(const char *buf, int32_t &val)
Same as readInt32.
Definition: int32.H:108
Foam::writer::write
virtual void write(const coordSet &, const wordList &, const List< const Field< Type > * > &, Ostream &) const =0
General entry point for writing.
Foam::AMIInterpolation::srcWeightsSum
const scalarField & srcWeightsSum() const
Definition: AMIInterpolationI.H:153
Foam::UPstream::master
static bool master(const label communicator=worldComm)
Am I the master process.
Definition: UPstream.H:457
Foam::functionObjects::AMIWeights::reportPatch
virtual void reportPatch(const cyclicAMIPolyPatch &pp)
Helper function to report patch information.
Definition: AMIWeights.C:82
Foam::endl
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:369
Foam::functionObjects::AMIWeights::writeWeightFields
void writeWeightFields(const cyclicAMIPolyPatch &cpp) const
Write weight fields if writeFields=true.
Definition: AMIWeights.C:282
Foam::functionObjects::AMIWeights::write
virtual bool write()
Write the AMIWeights.
Definition: AMIWeights.C:350
AMIWeights.H
foamVtkSurfaceWriter.H
Foam::HashSet< label, Hash< label > >
Foam::AMIInterpolation::tgtAddress
const labelListList & tgtAddress() const
Return const access to target patch addressing.
Definition: AMIInterpolationI.H:195
Foam::functionObjects::fvMeshFunctionObject
Specialization of Foam::functionObject for an Foam::fvMesh, providing a reference to the Foam::fvMesh...
Definition: fvMeshFunctionObject.H:64
Foam::min
label min(const labelHashSet &set, label minValue=labelMax)
Find the min value in labelHashSet, optionally limited by second argument.
Definition: hashSets.C:33
Foam::sumOp
Definition: ops.H:213
forAll
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:296
Foam::functionObjects::writeFile::writeHeader
virtual void writeHeader(Ostream &os, const string &str) const
Write a commented header to stream.
Definition: writeFile.C:298
n
label n
Definition: TABSMDCalcMethod2.H:31
Foam::functionObjects::writeFile::read
virtual bool read(const dictionary &dict)
Read.
Definition: writeFile.C:213
Foam::reduce
void reduce(const List< UPstream::commsStruct > &comms, T &Value, const BinaryOp &bop, const int tag, const label comm)
Definition: PstreamReduceOps.H:51
Foam::Field< scalar >
Foam::polyPatch::boundaryMesh
const polyBoundaryMesh & boundaryMesh() const
Return boundaryMesh reference.
Definition: polyPatch.C:315
Foam::polyPatch
A patch is a list of labels that address the faces in the global face list.
Definition: polyPatch.H:68
Foam::functionObjects::AMIWeights::writeWeightField
void writeWeightField(const cyclicAMIPolyPatch &cpp, const scalarField &weightSum, const word &side) const
Write weight field.
Definition: AMIWeights.C:211
Foam::max
label max(const labelHashSet &set, label maxValue=labelMin)
Find the max value in labelHashSet, optionally limited by second argument.
Definition: hashSets.C:47
dict
dictionary dict
Definition: searchingEngine.H:14
Foam::AMIInterpolation::singlePatchProc
label singlePatchProc() const
Definition: AMIInterpolationI.H:111
Foam::dictionary
A list of keyword definitions, which are a keyword followed by a number of values (eg,...
Definition: dictionary.H:123
Foam::cyclicAMIPolyPatch::neighbPatch
virtual const cyclicAMIPolyPatch & neighbPatch() const
Return a reference to the neighbour patch.
Definition: cyclicAMIPolyPatch.C:970
Foam::functionObjects::regionFunctionObject::read
virtual bool read(const dictionary &dict)
Read optional controls.
Definition: regionFunctionObject.C:173
os
OBJstream os(runTime.globalPath()/outputName)
addToRunTimeSelectionTable.H
Macros for easy insertion into run-time selection tables.
Foam::writer
Base class for graphics format writing. Entry points are.
Definition: writer.H:81
Foam::PrimitivePatch::localFaces
const List< face_type > & localFaces() const
Return patch faces addressing into local point list.
Definition: PrimitivePatch.C:317
fvMesh.H
Foam::functionObjects::AMIWeights::execute
virtual bool execute()
Execute, currently does nothing.
Definition: AMIWeights.C:344
Foam
Namespace for OpenFOAM.
Definition: atmBoundaryLayer.C:33
Foam::patchIdentifier::index
label index() const noexcept
The index of this patch in the boundaryMesh.
Definition: patchIdentifier.H:147
Foam::setw
Omanip< int > setw(const int i)
Definition: IOmanip.H:199
Foam::IOstream::defaultPrecision
static unsigned int defaultPrecision() noexcept
Return the default precision.
Definition: IOstream.H:342
Foam::autoPtr
Pointer management similar to std::unique_ptr, with some additional methods and type checking.
Definition: HashPtrTable.H:53
Foam::cyclicAMIPolyPatch::AMI
const AMIPatchToPatchInterpolation & AMI() const
Return a reference to the AMI interpolator.
Definition: cyclicAMIPolyPatch.C:977
Foam::functionObjects::writeFile::writeCommented
virtual void writeCommented(Ostream &os, const string &str) const
Write a commented string to stream.
Definition: writeFile.C:272
Foam::tab
constexpr char tab
Definition: Ostream.H:403
Foam::nl
constexpr char nl
Definition: Ostream.H:404
Foam::vtk::surfaceWriter
Write faces/points (optionally with fields) as a vtp file or a legacy vtk file.
Definition: foamVtkSurfaceWriter.H:65
Foam::functionObjects::addToRunTimeSelectionTable
addToRunTimeSelectionTable(functionObject, ObukhovLength, dictionary)
Foam::functionObjects::AMIWeights::AMIWeights
AMIWeights(const word &name, const Time &runTime, const dictionary &dict)
Construct from Time and dictionary.
Definition: AMIWeights.C:297
Foam::UPstream::parRun
static bool & parRun() noexcept
Test if this a parallel run.
Definition: UPstream.H:433
Foam::List< labelList >
Foam::type
fileName::Type type(const fileName &name, const bool followLink=true)
Return the file type: DIRECTORY or FILE, normally following symbolic links.
Definition: MSwindows.C:590
Foam::functionObjects::AMIWeights::writeFileHeader
virtual void writeFileHeader(Ostream &os)
Output file header information.
Definition: AMIWeights.C:48
Foam::cyclicAMIPolyPatch::neighbPatchName
const word & neighbPatchName() const
Neighbour patch name.
Definition: cyclicAMIPolyPatchI.H:49
Foam::HashSet::insert
bool insert(const Key &key)
Insert a new entry, not overwriting existing entries.
Definition: HashSet.H:191
Foam::functionObjects::defineTypeNameAndDebug
defineTypeNameAndDebug(ObukhovLength, 0)
Foam::labelMin
constexpr label labelMin
Definition: label.H:60
Foam::name
word name(const expressions::valueTypeCode typeCode)
A word representation of a valueTypeCode. Empty for INVALID.
Definition: exprTraits.C:59
Foam::functionObjects::writeFile
Base class for writing single files from the function objects.
Definition: writeFile.H:119
Foam::patchIdentifier::name
const word & name() const noexcept
The patch name.
Definition: patchIdentifier.H:135
Foam::instant
An instant of time. Contains the time value and name.
Definition: instant.H:52
Foam::Ostream
An Ostream is an abstract base class for all output systems (streams, files, token lists,...
Definition: Ostream.H:56
Foam::cyclicACMIPolyPatch
Cyclic patch for Arbitrarily Coupled Mesh Interface (ACMI).
Definition: cyclicACMIPolyPatch.H:78
Foam::gMin
Type gMin(const FieldField< Field, Type > &f)
Definition: FieldFieldFunctions.C:593
Foam::PrimitivePatch::meshPointMap
const Map< label > & meshPointMap() const
Mesh point map.
Definition: PrimitivePatch.C:343
Foam::PrimitivePatch::meshPoints
const labelList & meshPoints() const
Return labelList of mesh points in patch.
Definition: PrimitivePatch.C:330
writer
vtk::internalMeshWriter writer(topoMesh, topoCells, vtk::formatType::INLINE_ASCII, runTime.path()/"blockTopology")
Foam::cyclicACMIPolyPatch::mask
const scalarField & mask() const
Mask field where 1 = overlap(coupled), 0 = no-overlap.
Definition: cyclicACMIPolyPatchI.H:54
Foam::functionObjects::writeFile::writeTabbed
virtual void writeTabbed(Ostream &os, const string &str) const
Write a tabbed string to stream.
Definition: writeFile.C:288
Foam::gMax
Type gMax(const FieldField< Field, Type > &f)
Definition: FieldFieldFunctions.C:592
Foam::AMIInterpolation::srcAddress
const labelListList & srcAddress() const
Return const access to source patch addressing.
Definition: AMIInterpolationI.H:129
Foam::cyclicAMIPolyPatch
Cyclic patch for Arbitrary Mesh Interface (AMI)
Definition: cyclicAMIPolyPatch.H:68