cyclicAMIPolyPatchTemplates.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) 2021-2024 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 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
30 
31 template<class Type>
33 (
34  const Field<Type>& fld,
35  const UList<Type>& defaultValues
36 ) const
37 {
38  if (owner())
39  {
40  return AMI().interpolateToSource(fld, defaultValues);
41  }
42  else
43  {
44  return neighbPatch().AMI().interpolateToTarget(fld, defaultValues);
45  }
46 }
47 
48 
49 template<class Type>
51 (
52  const Field<Type>& fld,
53  const UList<Type>& defaultValues
54 ) const
55 {
56  autoPtr<coordSystem::cylindrical> cs;
57 
58  // Similar to doTransform.
59  // - could also check if !std::is_same<sphericalTensor, Type>:value
60 
61  if (is_vectorspace<Type>::value)
62  {
63  cs.reset(cylindricalCS());
64  }
65 
66  if (!cs)
67  {
68  return interpolateUntransformed(fld, defaultValues);
69  }
70  else
71  {
72  const cyclicAMIPolyPatch& nbrPp = this->neighbPatch();
73 
74  if (debug)
75  {
76  Pout<< "cyclicAMIPolyPatch::interpolate :"
77  << " patch:" << this->name()
78  << " size:" << this->size()
79  << " nbrPatch:" << nbrPp.name()
80  << " size:" << nbrPp.size()
81  << endl;
82  }
83 
84  if (fld.size() != nbrPp.size())
85  {
87  << "Patch:" << this->name()
88  << " size:" << this->size()
89  << " neighbour patch:" << nbrPp.name()
90  << " size:" << nbrPp.size()
91  << " fld size:" << fld.size()
92  << exit(FatalError);
93  }
94 
95 
96  Field<Type> localFld(fld.size());
97 
98  // Transform to cylindrical coords
99  {
100  const tensorField nbrT(cs().R(nbrPp.faceCentres()));
101  Foam::invTransform(localFld, nbrT, fld);
102  }
103 
104  if (debug&2)
105  {
106  const vectorField::subField nbrFc(nbrPp.faceCentres());
107 
108  Pout<< "On patch:" << this->name()
109  << " size:" << this->size()
110  << " fc:" << gAverage(this->faceCentres())
111  << " getting remote data from:" << nbrPp.name()
112  << " size:" << nbrPp.size()
113  << " fc:" << gAverage(nbrFc)
114  << endl;
115 
116  forAll(fld, i)
117  {
118  Pout<< "At:" << nbrFc[i] << nl
119  << " cart:" << fld[i] << nl
120  << " cyli:" << localFld[i] << nl
121  << endl;
122  }
123  }
124 
125 
126  const tensorField ownT(cs().R(this->faceCentres()));
127 
128  Field<Type> localDeflt(defaultValues.size());
129  if (defaultValues.size() == size())
130  {
131  // Transform default values into cylindrical coords (using
132  // *this faceCentres)
133  // We get in UList (why? Copied from cyclicAMI). Convert to
134  // Field so we can use transformField routines.
135  const SubField<Type> defaultSubFld(defaultValues);
136  const Field<Type>& defaultFld(defaultSubFld);
137  Foam::invTransform(localDeflt, ownT, defaultFld);
138  }
139 
140  // Do the actual interpolation and interpolate back to cartesian
141  return Foam::transform
142  (
143  ownT,
144  interpolateUntransformed(localFld, localDeflt)
145  );
146  }
147 }
148 
149 
150 template<class Type>
152 (
153  const tmp<Field<Type>>& tFld,
154  const UList<Type>& defaultValues
155 ) const
156 {
157  return interpolate(tFld(), defaultValues);
158 }
159 
160 
161 template<class Type>
163 (
164  const Field<Type>& fld,
165  labelRange& sendRequests,
166  PtrList<List<Type>>& sendBuffers,
167  labelRange& recvRequests,
168  PtrList<List<Type>>& recvBuffers
169 ) const
170 {
171  const auto& AMI = (owner() ? this->AMI() : neighbPatch().AMI());
172 
173  if (AMI.distributed())
174  {
175  const auto& map = (owner() ? AMI.tgtMap() : AMI.srcMap());
176 
177  // Insert send/receive requests (non-blocking)
178  map.send
179  (
180  fld,
181  sendRequests,
182  sendBuffers,
183  recvRequests,
184  recvBuffers,
185  3894+this->index() // unique offset + patch index
186  );
187  }
188 }
189 
190 
191 template<class Type>
193 (
194  const Field<Type>& fld,
195  labelRange& sendRequests,
196  PtrList<List<Type>>& sendBuffers,
197  labelRange& recvRequests,
198  PtrList<List<Type>>& recvBuffers
199 ) const
200 {
201  const auto& AMI = (owner() ? this->AMI() : neighbPatch().AMI());
202 
203  if (!AMI.distributed())
204  {
205  return;
206  }
207 
208  autoPtr<coordSystem::cylindrical> cs;
209 
210  if (is_vectorspace<Type>::value)
211  {
212  cs.reset(cylindricalCS());
213  }
214 
215  if (!cs)
216  {
217  initInterpolateUntransformed
218  (
219  fld,
220  sendRequests,
221  sendBuffers,
222  recvRequests,
223  recvBuffers
224  );
225  }
226  else
227  {
228  const cyclicAMIPolyPatch& nbrPp = this->neighbPatch();
229 
230  Field<Type> localFld(fld.size());
231 
232  // Transform to cylindrical coords
233  {
234  const tensorField nbrT(cs().R(nbrPp.faceCentres()));
235  Foam::invTransform(localFld, nbrT, fld);
236  }
237 
238  initInterpolateUntransformed
239  (
240  localFld,
241  sendRequests,
242  sendBuffers,
243  recvRequests,
244  recvBuffers
245  );
246  }
247 }
248 
249 
250 template<class Type>
252 (
253  const Field<Type>& localFld,
254  const labelRange& requests,
255  const PtrList<List<Type>>& recvBuffers,
256  const UList<Type>& defaultValues
257 ) const
258 {
259  const auto& AMI = (owner() ? this->AMI() : neighbPatch().AMI());
260  const auto& map = (owner() ? AMI.tgtMap() : AMI.srcMap());
261 
262  Field<Type> work;
263  if (AMI.distributed())
264  {
265  // Receive (= copy) data from buffers into work. TBD: receive directly
266  // into slices of work.
267  map.receive
268  (
269  requests,
270  recvBuffers,
271  work,
272  3894+this->index() // unique offset + patch index
273  );
274  }
275  const Field<Type>& fld = (AMI.distributed() ? work : localFld);
276 
277  auto tresult = tmp<Field<Type>>::New(this->size(), Zero);
278 
279  // Note: tresult is optionally in transformed coord system
280  autoPtr<coordSystem::cylindrical> cs;
281 
282  if (is_vectorspace<Type>::value)
283  {
284  cs.reset(cylindricalCS());
285  }
286 
287  if (!cs)
288  {
289  AMI.weightedSum
290  (
291  owner(),
292  fld,
293  tresult.ref(),
294  defaultValues
295  );
296  }
297  else
298  {
299  const tensorField ownT(cs().R(this->faceCentres()));
300 
301  Field<Type> localDeflt(defaultValues.size());
302  if (defaultValues.size() == size())
303  {
304  // Transform default values into cylindrical coords (using
305  // *this faceCentres)
306  // We get in UList (why? Copied from cyclicAMI). Convert to
307  // Field so we can use transformField routines.
308  const SubField<Type> defaultSubFld(defaultValues);
309  const Field<Type>& defaultFld(defaultSubFld);
310  Foam::invTransform(localDeflt, ownT, defaultFld);
311  }
312 
313  AMI.weightedSum
314  (
315  owner(),
316  fld,
317  tresult.ref(),
318  localDeflt
319  );
320 
321  // Transform back
322  Foam::transform(tresult.ref(), ownT, tresult());
323  }
325  return tresult;
326 }
327 
328 
329 template<class Type, class CombineOp>
331 (
332  const UList<Type>& fld,
333  const CombineOp& cop,
334  List<Type>& result,
335  const UList<Type>& defaultValues
336 ) const
337 {
338  //- Commented out for now since called with non-primitives (e.g. wallPoint
339  // from FaceCellWave) - missing Foam::transform, Foam::invTransform
340  /*
341  autoPtr<coordSystem::cylindrical> cs;
342 
343  if (is_vectorspace<Type>::value)
344  {
345  cs.reset(cylindricalCS());
346  }
347 
348  if (cs)
349  {
350  const cyclicAMIPolyPatch& nbrPp = this->neighbPatch();
351 
352  // Transform to cylindrical coords
353  {
354  const tensorField nbrT(cs().R(nbrPp.faceCentres()));
355  Foam::invTransform(result, nbrT, result);
356  }
357 
358  const tensorField ownT(cs().R(this->faceCentres()));
359 
360  Field<Type> localDeflt(defaultValues.size());
361  if (defaultValues.size() == size())
362  {
363  // Transform default values into cylindrical coords (using
364  // *this faceCentres)
365  // We get in UList (why? Copied from cyclicAMI). Convert to
366  // Field so we can use transformField routines.
367  const SubField<Type> defaultSubFld(defaultValues);
368  const Field<Type>& defaultFld(defaultSubFld);
369  Foam::invTransform(localDeflt, ownT, defaultFld);
370  }
371 
372  // Do actual AMI interpolation
373  if (owner())
374  {
375  AMI().interpolateToSource
376  (
377  fld,
378  cop,
379  result,
380  localDeflt
381  );
382  }
383  else
384  {
385  neighbPatch().AMI().interpolateToTarget
386  (
387  fld,
388  cop,
389  result,
390  localDeflt
391  );
392  }
393 
394  // Transform back. Result is now at *this
395  Foam::transform(result, ownT, result);
396  }
397  else
398  */
399  {
400  if (owner())
401  {
402  AMI().interpolateToSource
403  (
404  fld,
405  cop,
406  result,
407  defaultValues
408  );
409  }
410  else
411  {
412  neighbPatch().AMI().interpolateToTarget
413  (
414  fld,
415  cop,
416  result,
417  defaultValues
418  );
419  }
420  }
421 }
422 
423 
424 // ************************************************************************* //
const AMIPatchToPatchInterpolation & AMI() const
Return a reference to the AMI interpolator.
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:125
dimensionSet invTransform(const dimensionSet &ds)
Return the argument; transformations do not change the dimensions.
Definition: dimensionSet.C:527
error FatalError
Error stream (stdout output on all processes), with additional &#39;FOAM FATAL ERROR&#39; header text and sta...
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:608
bool interpolate(const vector &p1, const vector &p2, const vector &o, vector &n, scalar l)
Definition: curveTools.C:75
A range or interval of labels defined by a start and a size.
Definition: labelRange.H:52
constexpr char nl
The newline &#39;\n&#39; character (0x0a)
Definition: Ostream.H:50
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:531
tmp< DimensionedField< TypeR, GeoMesh > > New(const tmp< DimensionedField< TypeR, GeoMesh >> &tf1, const word &name, const dimensionSet &dimensions, const bool initCopy=false)
Global function forwards to reuseTmpDimensionedField::New.
tmp< Field< Type > > interpolate(const Field< Type > &fld, const UList< Type > &defaultValues=UList< Type >()) const
Interpolate field.
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:421
void initInterpolate(const Field< Type > &fld, labelRange &sendRequests, PtrList< List< Type >> &sendBuffers, labelRange &recvRequests, PtrList< List< Type >> &recvBuffers) const
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
void interpolateToTarget(const UList< Type > &fld, const CombineOp &cop, List< Type > &result, const UList< Type > &defaultValues=UList< Type >::null()) const
Interpolate from source to target with supplied op to combine existing value with remote value and we...
void initInterpolateUntransformed(const Field< Type > &fld, labelRange &sendRequests, PtrList< List< Type >> &sendBuffers, labelRange &recvRequests, PtrList< List< Type >> &recvBuffers) const
refinementData transform(const tensor &, const refinementData val)
No-op rotational transform for base types.
int debug
Static debugging option.
void interpolateToSource(const UList< Type > &fld, const CombineOp &cop, List< Type > &result, const UList< Type > &defaultValues=UList< Type >::null()) const
Interpolate from target to source with supplied op to combine existing value with remote value and we...
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))
Field< tensor > tensorField
Specialisation of Field<T> for tensor.
tmp< Field< Type > > interpolateUntransformed(const Field< Type > &fld, const UList< Type > &defaultValues) const
Interpolate without periodic.
#define R(A, B, C, D, E, F, K, M)
Type gAverage(const FieldField< Field, Type > &f)
A list of pointers to objects of type <T>, with allocation/deallocation management of the pointers...
Definition: List.H:55
virtual const cyclicAMIPolyPatch & neighbPatch() const
Return a reference to the neighbour patch.
virtual bool owner() const
Does this side own the patch?
SubField< vector > subField
Declare type of subField.
Definition: Field.H:128
A class for managing temporary objects.
Definition: HashPtrTable.H:50
prefixOSstream Pout
OSstream wrapped stdout (std::cout) with parallel prefix.
coordSystem::cylindrical cylindricalCS
Compatibility typedef 1806.
static constexpr const zero Zero
Global zero (0)
Definition: zero.H:127