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-2023 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  const label oldWarnComm = UPstream::commWarn(myComm);
40  const label oldWorldComm = UPstream::commWorld(myComm);
41 
42  if (sameWorld())
43  {
44  // lst is the other side's values
45  lst = interp.interpolateToSource(Field<Type>(std::move(lst)));
46  }
47  else
48  {
49  // lst is my local data. Now the mapping in the AMI is
50  // from my side to other side. Each processor contains either
51  // faces from one side or from the other side.
52 
53  if (masterWorld())
54  {
55  // I have lst.size() faces on my side, zero of the other
56  // side
57 
58  tmp<Field<Type>> tmasterFld
59  (
60  interp.interpolateToSource(Field<Type>(0))
61  );
62  (void)interp.interpolateToTarget
63  (
64  Field<Type>(std::move(lst))
65  );
66 
67  // We've received in our interpolateToSource the
68  // contribution from the other side
69  lst = tmasterFld;
70  }
71  else
72  {
73  (void)interp.interpolateToSource
74  (
75  Field<Type>(std::move(lst))
76  );
77  tmp<Field<Type>> tmasterFld
78  (
79  interp.interpolateToTarget(Field<Type>(0))
80  );
81 
82  // We've received in our interpolateToTarget the
83  // contribution from the other side
84  lst = tmasterFld;
85  }
86  }
87 
88  // Restore communicator settings
89  UPstream::commWarn(oldWarnComm);
90  UPstream::commWorld(oldWorldComm);
91  break;
92  }
93  default:
94  {
95  const auto& m = map();
96  const label oldWarnComm = UPstream::commWarn(m.comm());
97 
98  m.distribute(lst);
99 
100  UPstream::commWarn(oldWarnComm);
101  }
102  }
103 }
104 
105 
106 template<class Type, class CombineOp>
108 (
109  List<Type>& lst,
110  const CombineOp& cop
111 ) const
112 {
113  const label myComm = getCommunicator(); // Get or create
114 
115  switch (mode_)
116  {
117  case NEARESTPATCHFACEAMI:
118  {
119  const auto& interp = AMI();
120  const label oldWarnComm = UPstream::commWarn(myComm);
121  const label oldWorldComm = UPstream::commWorld(myComm);
122 
123  lst = interp.interpolateToSource(Field<Type>(std::move(lst)), cop);
124 
125  UPstream::commWarn(oldWarnComm);
126  UPstream::commWorld(oldWorldComm);
127  break;
128  }
129  default:
130  {
131  // Force early construction of parallel data
132  (void)patch_.boundaryMesh().mesh().tetBasePtIs();
133  const auto& m = map();
134 
135  const label oldWarnComm = UPstream::commWarn(myComm);
137  (
139  m.schedule(),
140  m.constructSize(),
141  m.subMap(),
142  false,
143  m.constructMap(),
144  false,
145  lst,
146  Type(Zero),
147  cop,
148  flipOp(),
150  myComm
151  );
152  UPstream::commWarn(oldWarnComm);
153  }
154  }
155 }
156 
157 
158 template<class Type>
159 void Foam::mappedPatchBase::reverseDistribute(List<Type>& lst) const
160 {
161  const label myComm = getCommunicator(); // Get or create
162 
163  switch (mode_)
164  {
165  case NEARESTPATCHFACEAMI:
166  {
167  const auto& interp = AMI();
168  const label oldWarnComm = UPstream::commWarn(myComm);
169  const label oldWorldComm = UPstream::commWorld(myComm);
170 
171  lst = interp.interpolateToTarget(Field<Type>(std::move(lst)));
172 
173  UPstream::commWarn(oldWarnComm);
174  UPstream::commWorld(oldWorldComm);
175  break;
176  }
177  default:
178  {
179  // Force early construction of parallel data
180  (void)patch_.boundaryMesh().mesh().tetBasePtIs();
181  const auto& m = map();
182 
183  const label oldWarnComm = UPstream::commWarn(m.comm());
184  m.reverseDistribute(sampleSize(), lst);
185  UPstream::commWarn(oldWarnComm);
186  break;
187  }
188  }
189 }
190 
191 
192 template<class Type, class CombineOp>
194 (
195  List<Type>& lst,
196  const CombineOp& cop
197 ) const
198 {
199  const label myComm = getCommunicator(); // Get or create
200 
201  switch (mode_)
202  {
203  case NEARESTPATCHFACEAMI:
204  {
205  const auto& interp = AMI();
206  const label oldWarnComm = UPstream::commWarn(myComm);
207  const label oldWorldComm = UPstream::commWorld(myComm);
208 
209  lst = interp.interpolateToTarget(Field<Type>(std::move(lst)), cop);
210 
211  UPstream::commWarn(oldWarnComm);
212  UPstream::commWorld(oldWorldComm);
213  break;
214  }
215  default:
216  {
217  (void)patch_.boundaryMesh().mesh().tetBasePtIs();
218  const auto& m = map();
219  const label cSize = sampleSize();
220 
221  const label oldWarnComm = UPstream::commWarn(myComm);
222 
224  (
226  m.schedule(),
227  cSize,
228  m.constructMap(),
229  false,
230  m.subMap(),
231  false,
232  lst,
233  Type(Zero),
234  cop,
235  flipOp(),
237  myComm
238  );
239 
240  UPstream::commWarn(oldWarnComm);
241  break;
242  }
243  }
244 }
245 
246 
247 template<class Type>
249 (
250  const regIOobject& obj,
251  dictionary& dict
252 )
253 {
254  const auto* fldPtr = isA<IOField<Type>>(obj);
255  if (fldPtr)
256  {
257  const auto& fld = *fldPtr;
258 
259  token tok;
260  tok = new token::Compound<List<Type>>(fld);
261 
262  primitiveEntry* pePtr = new primitiveEntry
263  (
264  fld.name(),
265  tokenList
266  (
267  one(),
268  std::move(tok)
269  )
270  );
271 
272  dict.set(pePtr);
273  return true;
274  }
275  else
276  {
277  return false;
278  }
279 }
280 
281 
282 template<class Type>
284 (
285  const word& name,
286  token& tok,
287  Istream& is,
288  objectRegistry& obr
289 )
290 {
291  const word tag = "List<" + word(pTraits<Type>::typeName) + '>';
292 
293  if (tok.isCompound() && tok.compoundToken().type() == tag)
294  {
295  IOField<Type>* fldPtr = obr.getObjectPtr<IOField<Type>>(name);
296  if (fldPtr)
297  {
298  fldPtr->transfer
299  (
300  dynamicCast<token::Compound<List<Type>>>
301  (
302  tok.transferCompoundToken(is)
303  )
304  );
305  }
306  else
307  {
308  fldPtr = new IOField<Type>
309  (
310  IOobject
311  (
312  name,
313  obr,
317  ),
318  label(0)
319  );
320  fldPtr->transfer
321  (
322  dynamicCast<token::Compound<List<Type>>>
323  (
324  tok.transferCompoundToken(is)
325  )
326  );
327  objectRegistry::store(fldPtr);
328  }
329  return true;
330  }
331  else
332  {
333  return false;
334  }
335 }
336 
337 
338 template<class Type>
340 (
341  objectRegistry& obr,
342  const word& fieldName,
343  const Field<Type>& values
344 )
345 {
346  IOField<Type>* fldPtr = obr.getObjectPtr<IOField<Type>>(fieldName);
347  if (fldPtr)
348  {
349  *fldPtr = values;
350  }
351  else
352  {
353  fldPtr = new IOField<Type>
354  (
355  IOobject
356  (
357  fieldName,
358  obr,
362  ),
363  values
364  );
365  objectRegistry::store(fldPtr);
366  }
367 }
368 
369 
370 // ************************************************************************* //
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:1184
Ignore writing from objectRegistry::writeObject()
const mapDistribute & map() const
Return reference to the parallel distribution map.
List< token > tokenList
List of token, used for dictionary primitive entry (for example)
Definition: tokenList.H:32
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:451
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 INVALID.
Definition: exprTraits.C:52
Generic templated field type.
Definition: Field.H:62
bool masterWorld() const
Is my world ordered before the sampleWorld?
const AMIPatchToPatchInterpolation & AMI(const bool forceUpdate=false) const
Return reference to the AMI interpolator.
Type & dynamicCast(U &obj)
A dynamic_cast (for references) that generates FatalError on failed casts.
Definition: typeInfo.H:111
static label commWorld() noexcept
Communicator for all ranks (respecting any local worlds)
Definition: UPstream.H:431
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:387
label getCommunicator() const
Get the communicator (worldComm or world-to-world)
static void distribute(const Pstream::commsTypes commsType, const List< labelPair > &schedule, const label constructSize, const labelListList &subMap, const bool subHasFlip, const labelListList &constructMap, const bool constructHasFlip, List< T > &field, const NegateOp &negOp, const int tag=UPstream::msgType(), const label comm=UPstream::worldComm)
Distribute data with specified negate operator (for flips).
Nothing to be read.
static bool writeIOField(const regIOobject &obj, dictionary &dict)
Attempt to detect an IOField<Type> and write to dictionary.
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:777
A class for managing temporary objects.
Definition: HashPtrTable.H:50
Request registration (bool: true)
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:133