mappedPatchBaseTemplates.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) 2018-2025 OpenCFD Ltd.
10 -------------------------------------------------------------------------------
11 License
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 
29 template<class Type>
31 {
32  const label myComm = getCommunicator(); // Get or create
33 
34  switch (mode_)
35  {
37  {
38  const auto& interp = AMI();
39 
40  if (sameWorld())
41  {
42  // lst is the other side's values
43  lst = interp.interpolateToSource(Field<Type>(std::move(lst)));
44  }
45  else
46  {
47  const label oldWarnComm = UPstream::commWarn(myComm);
48  const label oldWorldComm = UPstream::commWorld(myComm);
49 
50  // lst is my local data. Now the mapping in the AMI is
51  // from my side to other side. Each processor contains either
52  // faces from one side or from the other side.
53 
54  if (masterWorld())
55  {
56  // I have lst.size() faces on my side, zero of the other
57  // side
58 
59  tmp<Field<Type>> tmasterFld
60  (
61  interp.interpolateToSource(Field<Type>(0))
62  );
63  (void)interp.interpolateToTarget
64  (
65  Field<Type>(std::move(lst))
66  );
67 
68  // We've received in our interpolateToSource the
69  // contribution from the other side
70  lst = tmasterFld;
71  }
72  else
73  {
74  (void)interp.interpolateToSource
75  (
76  Field<Type>(std::move(lst))
77  );
78  tmp<Field<Type>> tmasterFld
79  (
80  interp.interpolateToTarget(Field<Type>(0))
81  );
82 
83  // We've received in our interpolateToTarget the
84  // contribution from the other side
85  lst = tmasterFld;
86  }
87 
88  // Restore communicator settings
89  UPstream::commWarn(oldWarnComm);
90  UPstream::commWorld(oldWorldComm);
91  }
92  break;
93  }
94  default:
95  {
96  const auto& m = map();
97  const label oldWarnComm = UPstream::commWarn(m.comm());
98 
99  m.distribute(lst);
100 
101  UPstream::commWarn(oldWarnComm);
102  }
103  }
104 }
105 
106 
107 template<class Type, class CombineOp>
109 (
110  List<Type>& lst,
111  const CombineOp& cop
112 ) const
113 {
114  const label myComm = getCommunicator(); // Get or create
115 
116  switch (mode_)
117  {
118  case NEARESTPATCHFACEAMI:
119  {
120  const auto& interp = AMI();
121 
122  label oldWarnComm(-1);
123  label oldWorldComm(-1);
124  if (!sameWorld())
125  {
126  oldWarnComm = UPstream::commWarn(myComm);
127  oldWorldComm = UPstream::commWorld(myComm);
128  }
129 
130  lst = interp.interpolateToSource(Field<Type>(std::move(lst)), cop);
131 
132  UPstream::commWarn(oldWarnComm);
133  UPstream::commWorld(oldWorldComm);
134  break;
135  }
136  default:
137  {
138  // Force early construction of parallel data
139  (void)patch_.boundaryMesh().mesh().tetBasePtIs();
140  const auto& m = map();
141 
142  label oldWarnComm(-1);
143  if (!sameWorld())
144  {
145  oldWarnComm = UPstream::commWarn(myComm);
146  }
147 
149  (
151  m.schedule(),
152  m.constructSize(),
153  m.subMap(),
154  false,
155  m.constructMap(),
156  false,
157  lst,
158  Type(Zero),
159  cop,
160  flipOp(),
162  myComm
163  );
164  UPstream::commWarn(oldWarnComm);
165  }
166  }
167 }
168 
169 
170 template<class Type>
171 void Foam::mappedPatchBase::reverseDistribute(List<Type>& lst) const
172 {
173  const label myComm = getCommunicator(); // Get or create
174 
175  switch (mode_)
176  {
177  case NEARESTPATCHFACEAMI:
178  {
179  const auto& interp = AMI();
180 
181  label oldWarnComm(-1);
182  label oldWorldComm(-1);
183  if (!sameWorld())
184  {
185  oldWarnComm = UPstream::commWarn(myComm);
186  oldWorldComm = UPstream::commWorld(myComm);
187  }
188 
189  lst = interp.interpolateToTarget(Field<Type>(std::move(lst)));
190 
191  UPstream::commWarn(oldWarnComm);
192  UPstream::commWorld(oldWorldComm);
193  break;
194  }
195  default:
196  {
197  // Force early construction of parallel data
198  (void)patch_.boundaryMesh().mesh().tetBasePtIs();
199  const auto& m = map();
200 
201  const label oldWarnComm = UPstream::commWarn(m.comm());
202  m.reverseDistribute(sampleSize(), lst);
203  UPstream::commWarn(oldWarnComm);
204  break;
205  }
206  }
207 }
208 
209 
210 template<class Type, class CombineOp>
212 (
213  List<Type>& lst,
214  const CombineOp& cop
215 ) const
216 {
217  const label myComm = getCommunicator(); // Get or create
218 
219  switch (mode_)
220  {
221  case NEARESTPATCHFACEAMI:
222  {
223  const auto& interp = AMI();
224 
225  label oldWarnComm(-1);
226  label oldWorldComm(-1);
227  if (!sameWorld())
228  {
229  oldWarnComm = UPstream::commWarn(myComm);
230  oldWorldComm = UPstream::commWorld(myComm);
231  }
232 
233  lst = interp.interpolateToTarget(Field<Type>(std::move(lst)), cop);
234 
235  UPstream::commWarn(oldWarnComm);
236  UPstream::commWorld(oldWorldComm);
237  break;
238  }
239  default:
240  {
241  (void)patch_.boundaryMesh().mesh().tetBasePtIs();
242  const auto& m = map();
243  const label cSize = sampleSize();
244 
245  label oldWarnComm(-1);
246  if (!sameWorld())
247  {
248  oldWarnComm = UPstream::commWarn(myComm);
249  }
250 
252  (
254  m.schedule(),
255  cSize,
256  m.constructMap(),
257  false,
258  m.subMap(),
259  false,
260  lst,
261  Type(Zero),
262  cop,
263  flipOp(),
265  myComm
266  );
267 
268  UPstream::commWarn(oldWarnComm);
269  break;
270  }
271  }
272 }
273 
274 
275 template<class Type>
277 (
278  const regIOobject& obj,
279  dictionary& dict
280 )
281 {
282  const auto* fldPtr = isA<IOField<Type>>(obj);
283  if (fldPtr)
284  {
285  const auto& fld = *fldPtr;
286 
287  primitiveEntry* pePtr = new primitiveEntry
288  (
289  fld.name(),
290  token(new token::Compound<List<Type>>(fld))
291  );
292 
293  dict.set(pePtr);
294  return true;
295  }
296  else
297  {
298  return false;
299  }
300 }
301 
302 
303 template<class Type>
305 (
306  const word& name,
307  token& tok,
308  Istream& is,
309  objectRegistry& obr
310 )
311 {
312  if (tok.isCompound<List<Type>>())
313  {
314  auto* fldPtr = obr.getObjectPtr<IOField<Type>>(name);
315  if (!fldPtr)
316  {
317  fldPtr = new IOField<Type>
318  (
319  IOobject
320  (
321  name,
322  obr,
326  ),
327  Foam::zero{}
328  );
329  regIOobject::store(fldPtr);
330  }
331 
332  fldPtr->transfer
333  (
334  tok.transferCompoundToken<List<Type>>(is)
335  );
336 
337  return true;
338  }
339  else
340  {
341  return false;
342  }
343 }
344 
345 
346 template<class Type>
348 (
349  objectRegistry& obr,
350  const word& fieldName,
351  const Field<Type>& values
352 )
353 {
354  auto* fldPtr = obr.getObjectPtr<IOField<Type>>(fieldName);
355  if (!fldPtr)
356  {
357  fldPtr = new IOField<Type>
358  (
359  IOobject
360  (
361  fieldName,
362  obr,
366  ),
367  Foam::zero{}
368  );
369  regIOobject::store(fldPtr);
370  }
371 
372  *fldPtr = values;
373 }
374 
375 
376 // ************************************************************************* //
dictionary dict
static bool constructIOField(const word &name, token &tok, Istream &is, objectRegistry &obr)
Attempt to read an IOField<Type> and store on objectRegistry.
bool store()
Register object with its registry and transfer ownership to the registry.
Definition: regIOobjectI.H:36
static int & msgType() noexcept
Message tag of standard messages.
Definition: UPstream.H:1787
Ignore writing from objectRegistry::writeObject()
const mapDistribute & map() const
Return reference to the parallel distribution map.
nearest patch face + AMI interpolation
static label commWarn(const label communicator) noexcept
Alter communicator debugging setting. Warns for use of any communicator differing from specified...
Definition: UPstream.H:1040
List< T > values(const HashTable< T, Key, Hash > &tbl, const bool doSort=false)
List of values from HashTable, optionally sorted.
Definition: HashOps.H:164
bool sameWorld() const
Is sample world the local world?
word name(const expressions::valueTypeCode typeCode)
A word representation of a valueTypeCode. Empty for expressions::valueTypeCode::INVALID.
Definition: exprTraits.C:127
Generic templated field type.
Definition: Field.H:63
bool masterWorld() const
Is my world ordered before the sampleWorld?
const AMIPatchToPatchInterpolation & AMI(const bool forceUpdate=false) const
Return reference to the AMI interpolator.
static label commWorld() noexcept
Communicator for all ranks (respecting any local worlds)
Definition: UPstream.H:1019
gmvFile<< "tracers "<< particles.size()<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().x()<< ' ';}gmvFile<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().y()<< ' ';}gmvFile<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().z()<< ' ';}gmvFile<< nl;for(const word &name :lagrangianScalarNames){ IOField< scalar > fld(IOobject(name, runTime.timeName(), cloud::prefix, mesh, IOobject::MUST_READ, IOobject::NO_WRITE))
void distribute(List< Type > &lst) const
Wrapper around map/interpolate data distribution.
static commsTypes defaultCommsType
Default commsType.
Definition: UPstream.H:963
label getCommunicator() const
Get the communicator (worldComm or world-to-world)
Nothing to be read.
static bool writeIOField(const regIOobject &obj, dictionary &dict)
Attempt to detect an IOField<Type> and write to dictionary.
A class representing the concept of 0 (zero) that can be used to avoid manipulating objects known to ...
Definition: zero.H:57
void reverseDistribute(List< Type > &lst) const
Wrapper around map/interpolate data distribution.
entry * set(entry *entryPtr)
Assign a new entry, overwriting any existing entry.
Definition: dictionary.C:765
A class for managing temporary objects.
Definition: HashPtrTable.H:50
Request registration (bool: true)
static void distribute(const UPstream::commsTypes commsType, const UList< labelPair > &schedule, const label constructSize, const labelListList &subMap, const bool subHasFlip, const labelListList &constructMap, const bool constructHasFlip, List< T > &field, const T &nullValue, const CombineOp &cop, const NegateOp &negOp, const int tag=UPstream::msgType(), const label comm=UPstream::worldComm)
Distribute combine data with specified combine operation and negate operator (for flips)...
static void storeField(objectRegistry &obr, const word &fieldName, const Field< Type > &values)
Store an IOField on the objectRegistry relative to obr.
const sampleMode mode_
What to sample.
static constexpr const zero Zero
Global zero (0)
Definition: zero.H:127