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-2022 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  const label oldWarnComm(Pstream::warnComm);
34 
35  switch (mode_)
36  {
38  {
39  const label oldWorldComm(Pstream::worldComm);
40  const auto& interp = AMI();
41 
42  Pstream::warnComm = myComm;
43  Pstream::worldComm = myComm;
44 
45  if (sameWorld())
46  {
47  // lst is the other side's values
48  lst = interp.interpolateToSource(Field<Type>(std::move(lst)));
49  }
50  else
51  {
52  // lst is my local data. Now the mapping in the AMI is
53  // from my side to other side. Each processor contains either
54  // faces from one side or from the other side.
55 
56  if (masterWorld())
57  {
58  // I have lst.size() faces on my side, zero of the other
59  // side
60 
61  tmp<Field<Type>> tmasterFld
62  (
63  interp.interpolateToSource(Field<Type>(0))
64  );
65  (void)interp.interpolateToTarget
66  (
67  Field<Type>(std::move(lst))
68  );
69 
70  // We've received in our interpolateToSource the
71  // contribution from the other side
72  lst = tmasterFld;
73  }
74  else
75  {
76  (void)interp.interpolateToSource
77  (
78  Field<Type>(std::move(lst))
79  );
80  tmp<Field<Type>> tmasterFld
81  (
82  interp.interpolateToTarget(Field<Type>(0))
83  );
84 
85  // We've received in our interpolateToTarget the
86  // contribution from the other side
87  lst = tmasterFld;
88  }
89  }
90  Pstream::worldComm = oldWorldComm;
91  Pstream::warnComm = oldWarnComm;
92  break;
93  }
94  default:
95  {
96  const auto& m = map();
97 
98  Pstream::warnComm = m.comm();
99  m.distribute(lst);
100  Pstream::warnComm = 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  const label oldWarnComm(Pstream::warnComm);
115 
116  switch (mode_)
117  {
118  case NEARESTPATCHFACEAMI:
119  {
120  const label oldWorldComm(Pstream::worldComm);
121  const auto& interp = AMI();
122  Pstream::warnComm = myComm;
123  Pstream::worldComm = myComm;
124  lst = interp.interpolateToSource(Field<Type>(std::move(lst)), cop);
125  Pstream::worldComm = oldWorldComm;
126  Pstream::warnComm = oldWarnComm;
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  Pstream::warnComm = 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  Pstream::warnComm = 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  const label oldWarnComm(Pstream::warnComm);
163 
164  switch (mode_)
165  {
166  case NEARESTPATCHFACEAMI:
167  {
168  const label oldWorldComm(Pstream::worldComm);
169  const auto& interp = AMI();
170  Pstream::warnComm = myComm;
171  Pstream::worldComm = myComm;
172  lst = interp.interpolateToTarget(Field<Type>(std::move(lst)));
173  Pstream::worldComm = oldWorldComm;
174  Pstream::warnComm = oldWarnComm;
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  Pstream::warnComm = m.comm();
184  m.reverseDistribute(sampleSize(), lst);
185  Pstream::warnComm = 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  const label oldWarnComm(Pstream::warnComm);
201 
202  switch (mode_)
203  {
204  case NEARESTPATCHFACEAMI:
205  {
206  const label oldWorldComm(Pstream::worldComm);
207  const auto& interp = AMI();
208  Pstream::warnComm = myComm;
209  Pstream::worldComm = myComm;
210  lst = interp.interpolateToTarget(Field<Type>(std::move(lst)), cop);
211  Pstream::worldComm = oldWorldComm;
212  Pstream::warnComm = oldWarnComm;
213  break;
214  }
215  default:
216  {
217  (void)patch_.boundaryMesh().mesh().tetBasePtIs();
218  const auto& m = map();
219  const label cSize = sampleSize();
220  Pstream::warnComm = myComm;
222  (
224  m.schedule(),
225  cSize,
226  m.constructMap(),
227  false,
228  m.subMap(),
229  false,
230  lst,
231  Type(Zero),
232  cop,
233  flipOp(),
235  myComm
236  );
237  Pstream::warnComm = oldWarnComm;
238  break;
239  }
240  }
241 }
242 
243 
244 template<class Type>
246 (
247  const regIOobject& obj,
248  dictionary& dict
249 )
250 {
251  const auto* fldPtr = isA<IOField<Type>>(obj);
252  if (fldPtr)
253  {
254  const auto& fld = *fldPtr;
255 
256  token tok;
257  tok = new token::Compound<List<Type>>(fld);
258 
259  primitiveEntry* pePtr = new primitiveEntry
260  (
261  fld.name(),
262  tokenList
263  (
264  one(),
265  std::move(tok)
266  )
267  );
268 
269  dict.set(pePtr);
270  return true;
271  }
272  else
273  {
274  return false;
275  }
276 }
277 
278 
279 template<class Type>
281 (
282  const word& name,
283  token& tok,
284  Istream& is,
285  objectRegistry& obr
286 )
287 {
288  const word tag = "List<" + word(pTraits<Type>::typeName) + '>';
289 
290  if (tok.isCompound() && tok.compoundToken().type() == tag)
291  {
292  IOField<Type>* fldPtr = obr.findObject<IOField<Type>>(name);
293  if (fldPtr)
294  {
295  fldPtr->transfer
296  (
297  dynamicCast<token::Compound<List<Type>>>
298  (
299  tok.transferCompoundToken(is)
300  )
301  );
302  }
303  else
304  {
305  IOField<Type>* fldPtr = new IOField<Type>
306  (
307  IOobject
308  (
309  name,
310  obr,
313  ),
314  label(0)
315  );
316  fldPtr->transfer
317  (
318  dynamicCast<token::Compound<List<Type>>>
319  (
320  tok.transferCompoundToken(is)
321  )
322  );
323  objectRegistry::store(fldPtr);
324  }
325  return true;
326  }
327  else
328  {
329  return false;
330  }
331 }
332 
333 
334 template<class Type>
336 (
337  objectRegistry& obr,
338  const word& fieldName,
339  const Field<Type>& values
340 )
341 {
342  IOField<Type>* fldPtr = obr.findObject<IOField<Type>>(fieldName);
343  if (fldPtr)
344  {
345  *fldPtr = values;
346  }
347  else
348  {
349  fldPtr = new IOField<Type>
350  (
351  IOobject
352  (
353  fieldName,
354  obr,
357  ),
358  values
359  );
360  objectRegistry::store(fldPtr);
361  }
362 }
363 
364 
365 // ************************************************************************* //
dictionary dict
static bool constructIOField(const word &name, token &tok, Istream &is, objectRegistry &obr)
Attempt to read an IOField<Type> and store on objectRegistry.
List< token > tokenList
List of tokens, used for a IOdictionary entry.
Definition: tokenList.H:38
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:806
Ignore writing from objectRegistry::writeObject()
static label worldComm
Default world communicator (all processors). May differ from globalComm if local worlds are in use...
Definition: UPstream.H:361
const mapDistribute & map() const
Return reference to the parallel distribution map.
nearest patch face + AMI interpolation
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:61
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 warnComm
Debugging: warn for use of any communicator differing from warnComm.
Definition: UPstream.H:366
Type & dynamicCast(U &obj)
A dynamic_cast (for references) that generates FatalError on failed casts.
Definition: typeInfo.H:108
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:337
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
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:157