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  primitiveEntry* pePtr = new primitiveEntry
260  (
261  fld.name(),
262  token(new token::Compound<List<Type>>(fld))
263  );
264 
265  dict.set(pePtr);
266  return true;
267  }
268  else
269  {
270  return false;
271  }
272 }
273 
274 
275 template<class Type>
277 (
278  const word& name,
279  token& tok,
280  Istream& is,
281  objectRegistry& obr
282 )
283 {
284  const word tag("List<" + word(pTraits<Type>::typeName) + '>');
285 
286  if (tok.isCompound(tag))
287  {
288  auto* fldPtr = obr.getObjectPtr<IOField<Type>>(name);
289  if (!fldPtr)
290  {
291  fldPtr = new IOField<Type>
292  (
293  IOobject
294  (
295  name,
296  obr,
300  ),
301  Foam::zero{}
302  );
303  objectRegistry::store(fldPtr);
304  }
305 
306  fldPtr->transfer
307  (
308  tok.transferCompoundToken<List<Type>>(is)
309  );
310 
311  return true;
312  }
313  else
314  {
315  return false;
316  }
317 }
318 
319 
320 template<class Type>
322 (
323  objectRegistry& obr,
324  const word& fieldName,
325  const Field<Type>& values
326 )
327 {
328  auto* fldPtr = obr.getObjectPtr<IOField<Type>>(fieldName);
329  if (!fldPtr)
330  {
331  fldPtr = new IOField<Type>
332  (
333  IOobject
334  (
335  fieldName,
336  obr,
340  ),
341  Foam::zero{}
342  );
343  objectRegistry::store(fldPtr);
344  }
345 
346  *fldPtr = values;
347 }
348 
349 
350 // ************************************************************************* //
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:1229
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:449
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: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.
static label commWorld() noexcept
Communicator for all ranks (respecting any local worlds)
Definition: UPstream.H:429
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:385
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 storeField(objectRegistry &obr, const word &fieldName, const Field< Type > &values)
Store an IOField on the objectRegistry relative to obr.
static void distribute(const UPstream::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 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)...
const sampleMode mode_
What to sample.
static constexpr const zero Zero
Global zero (0)
Definition: zero.H:127