meshToMeshTemplates.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration | Website: https://openfoam.org
5  \\ / A nd | Copyright (C) 2012-2022 OpenFOAM Foundation
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8 License
9  This file is part of OpenFOAM.
10 
11  OpenFOAM is free software: you can redistribute it and/or modify it
12  under the terms of the GNU General Public License as published by
13  the Free Software Foundation, either version 3 of the License, or
14  (at your option) any later version.
15 
16  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
17  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19  for more details.
20 
21  You should have received a copy of the GNU General Public License
22  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
23 
24 \*---------------------------------------------------------------------------*/
25 
26 #include "fvMesh.H"
27 #include "volFields.H"
29 #include "calculatedFvPatchField.H"
31 
32 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
33 
34 namespace Foam
35 {
36  //- Helper class for list
37  template<class Type>
38  class ListPlusEqOp
39  {
40  public:
41  void operator()(List<Type>& x, const List<Type> y) const
42  {
43  if (y.size())
44  {
45  if (x.size())
46  {
47  label sz = x.size();
48  x.setSize(sz + y.size());
49  forAll(y, i)
50  {
51  x[sz++] = y[i];
52  }
53  }
54  else
55  {
56  x = y;
57  }
58  }
59  }
60  };
61 }
62 
63 
64 // * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
65 
66 template<class Type>
67 void Foam::meshToMesh::add
68 (
69  UList<Type>& fld,
70  const label offset
71 ) const
72 {
73  forAll(fld, i)
74  {
75  fld[i] += offset;
76  }
77 }
78 
79 
80 template<class Type>
82 (
83  const UList<Type>& srcField,
84  List<Type>& result
85 ) const
86 {
87  if (result.size() != tgtToSrcCellAddr_.size())
88  {
90  << "Supplied field size is not equal to target mesh size" << nl
91  << " source mesh = " << srcToTgtCellAddr_.size() << nl
92  << " target mesh = " << tgtToSrcCellAddr_.size() << nl
93  << " supplied field = " << result.size()
94  << abort(FatalError);
95  }
96 
97  if (singleMeshProc_ == -1)
98  {
99  const distributionMap& map = srcMapPtr_();
100 
101  List<Type> work(srcField);
102  map.distribute(work);
103 
104  forAll(result, celli)
105  {
106  const labelList& srcAddress = tgtToSrcCellAddr_[celli];
107  const scalarList& srcWeight = tgtToSrcCellWght_[celli];
108 
109  if (srcAddress.size())
110  {
111  result[celli] *= (1.0 - sum(srcWeight));
112  forAll(srcAddress, i)
113  {
114  result[celli] += srcWeight[i]*work[srcAddress[i]];
115  }
116  }
117  }
118  }
119  else
120  {
121  forAll(result, celli)
122  {
123  const labelList& srcAddress = tgtToSrcCellAddr_[celli];
124  const scalarList& srcWeight = tgtToSrcCellWght_[celli];
125 
126  if (srcAddress.size())
127  {
128  result[celli] *= (1.0 - sum(srcWeight));
129  forAll(srcAddress, i)
130  {
131  result[celli] += srcWeight[i]*srcField[srcAddress[i]];
132  }
133  }
134  }
135  }
136 }
137 
138 
139 template<class Type>
141 (
142  const Field<Type>& srcField
143 ) const
144 {
145  tmp<Field<Type>> tresult
146  (
147  new Field<Type>
148  (
149  tgtToSrcCellAddr_.size(),
150  Zero
151  )
152  );
153 
154  mapSrcToTgt(srcField, tresult.ref());
155 
156  return tresult;
157 }
158 
159 
160 template<class Type>
162 (
163  const tmp<Field<Type>>& tsrcField
164 ) const
165 {
166  return mapSrcToTgt(tsrcField());
167 }
168 
169 
170 template<class Type>
172 (
173  const UList<Type>& tgtField,
174  List<Type>& result
175 ) const
176 {
177  if (result.size() != srcToTgtCellAddr_.size())
178  {
180  << "Supplied field size is not equal to source mesh size" << nl
181  << " source mesh = " << srcToTgtCellAddr_.size() << nl
182  << " target mesh = " << tgtToSrcCellAddr_.size() << nl
183  << " supplied field = " << result.size()
184  << abort(FatalError);
185  }
186 
187  if (singleMeshProc_ == -1)
188  {
189  const distributionMap& map = tgtMapPtr_();
190 
191  List<Type> work(tgtField);
192  map.distribute(work);
193 
194  forAll(result, celli)
195  {
196  const labelList& tgtAddress = srcToTgtCellAddr_[celli];
197  const scalarList& tgtWeight = srcToTgtCellWght_[celli];
198 
199  if (tgtAddress.size())
200  {
201  result[celli] *= (1.0 - sum(tgtWeight));
202  forAll(tgtAddress, i)
203  {
204  result[celli] += tgtWeight[i]*work[tgtAddress[i]];
205  }
206  }
207  }
208  }
209  else
210  {
211  forAll(result, celli)
212  {
213  const labelList& tgtAddress = srcToTgtCellAddr_[celli];
214  const scalarList& tgtWeight = srcToTgtCellWght_[celli];
215 
216  if (tgtAddress.size())
217  {
218  result[celli] *= (1.0 - sum(tgtWeight));
219  forAll(tgtAddress, i)
220  {
221  result[celli] += tgtWeight[i]*tgtField[tgtAddress[i]];
222  }
223  }
224  }
225  }
226 }
227 
228 
229 template<class Type>
231 (
232  const Field<Type>& tgtField
233 ) const
234 {
235  tmp<Field<Type>> tresult
236  (
237  new Field<Type>
238  (
239  srcToTgtCellAddr_.size(),
240  Zero
241  )
242  );
243 
244  mapTgtToSrc(tgtField, tresult.ref());
245 
246  return tresult;
247 }
248 
249 
250 template<class Type>
252 (
253  const tmp<Field<Type>>& ttgtField
254 ) const
255 {
256  return mapTgtToSrc(ttgtField());
257 }
258 
259 
260 template<class Type>
261 void Foam::meshToMesh::mapAndOpSrcToTgt
262 (
263  const AMIInterpolation& AMI,
264  const Field<Type>& srcField,
265  Field<Type>& tgtField
266 ) const
267 {
268  tgtField = pTraits<Type>::zero;
269 
271  (
272  srcField,
273  tgtField,
275  );
276 }
277 
278 
279 template<class Type>
281 (
284 ) const
285 {
286  mapSrcToTgt(field, result.primitiveFieldRef());
287 
288  const PtrList<AMIInterpolation>& AMIList = patchAMIs();
289 
291  Boundary& resultBf = result.boundaryFieldRef();
292 
293  forAll(AMIList, i)
294  {
295  label srcPatchi = srcPatchID_[i];
296  label tgtPatchi = tgtPatchID_[i];
297 
298  const fvPatchField<Type>& srcField = field.boundaryField()[srcPatchi];
299  fvPatchField<Type>& tgtField = resultBf[tgtPatchi];
300 
301  // Clone and map (since rmap does not do general mapping)
302  tmp<fvPatchField<Type>> tnewTgt
303  (
305  (
306  srcField,
307  tgtField.patch(),
308  result(),
310  (
311  AMIList[i].singlePatchProc(),
312  (
313  AMIList[i].singlePatchProc() == -1
314  ? &AMIList[i].srcMap()
315  : nullptr
316  ),
317  AMIList[i].tgtAddress(),
318  AMIList[i].tgtWeights()
319  )
320  )
321  );
322 
323  // Transfer all mapped quantities (value and e.g. gradient) onto
324  // tgtField. Value will get overwritten below.
325  tgtField.rmap(tnewTgt(), identity(tgtField.size()));
326 
327  // Override value to account for CombineOp (note: is dummy template
328  // specialisation for plusEqOp)
329  mapAndOpSrcToTgt(AMIList[i], srcField, tgtField);
330  }
331 
332  forAll(cuttingPatches_, i)
333  {
334  label patchi = cuttingPatches_[i];
335  fvPatchField<Type>& pf = resultBf[patchi];
336  pf == pf.patchInternalField();
337  }
338 }
339 
340 
341 template<class Type>
344 (
346 ) const
347 {
349 
350  const fvMesh& tgtMesh = static_cast<const fvMesh&>(tgtRegion_);
351 
352  const fvBoundaryMesh& tgtBm = tgtMesh.boundary();
353  const typename fieldType::Boundary& srcBfld =
354  field.boundaryField();
355 
356  PtrList<fvPatchField<Type>> tgtPatchFields(tgtBm.size());
357 
358  // construct tgt boundary patch types as copy of 'field' boundary types
359  // note: this will provide place holders for fields with additional
360  // entries, but these values will need to be reset
361  forAll(tgtPatchID_, i)
362  {
363  label srcPatchi = srcPatchID_[i];
364  label tgtPatchi = tgtPatchID_[i];
365 
366  if (!tgtPatchFields.set(tgtPatchi))
367  {
368  tgtPatchFields.set
369  (
370  tgtPatchi,
372  (
373  srcBfld[srcPatchi],
374  tgtMesh.boundary()[tgtPatchi],
377  (
378  labelList(tgtMesh.boundary()[tgtPatchi].size(), -1)
379  )
380  )
381  );
382  }
383  }
384 
385  // Any unset tgtPatchFields become calculated
386  forAll(tgtPatchFields, tgtPatchi)
387  {
388  if (!tgtPatchFields.set(tgtPatchi))
389  {
390  // Note: use factory New method instead of direct generation of
391  // calculated so we keep constraints
392  tgtPatchFields.set
393  (
394  tgtPatchi,
396  (
398  tgtMesh.boundary()[tgtPatchi],
400  )
401  );
402  }
403  }
404 
405  tmp<fieldType> tresult
406  (
407  new fieldType
408  (
409  IOobject
410  (
411  type() + ":interpolate(" + field.name() + ")",
412  tgtMesh.time().timeName(),
413  tgtMesh,
416  ),
417  tgtMesh,
418  field.dimensions(),
419  Field<Type>(tgtMesh.nCells(), Zero),
420  tgtPatchFields
421  )
422  );
423 
424  mapSrcToTgt(field, tresult.ref());
425 
426  return tresult;
427 }
428 
429 
430 template<class Type>
433 (
435 ) const
436 {
437  return mapSrcToTgt(tfield());
438 }
439 
440 
441 template<class Type>
442 void Foam::meshToMesh::mapAndOpTgtToSrc
443 (
444  const AMIInterpolation& AMI,
445  Field<Type>& srcField,
446  const Field<Type>& tgtField
447 ) const
448 {
449  srcField = pTraits<Type>::zero;
450 
452  (
453  tgtField,
454  srcField,
456  );
457 }
458 
459 
460 template<class Type>
462 (
465 ) const
466 {
467  mapTgtToSrc(field, result.primitiveFieldRef());
468 
469  const PtrList<AMIInterpolation>& AMIList = patchAMIs();
470 
471  forAll(AMIList, i)
472  {
473  label srcPatchi = srcPatchID_[i];
474  label tgtPatchi = tgtPatchID_[i];
475 
476  fvPatchField<Type>& srcField = result.boundaryFieldRef()[srcPatchi];
477  const fvPatchField<Type>& tgtField = field.boundaryField()[tgtPatchi];
478 
479 
480  // Clone and map (since rmap does not do general mapping)
481  tmp<fvPatchField<Type>> tnewSrc
482  (
484  (
485  tgtField,
486  srcField.patch(),
487  result(),
489  (
490  AMIList[i].singlePatchProc(),
491  (
492  AMIList[i].singlePatchProc() == -1
493  ? &AMIList[i].tgtMap()
494  : nullptr
495  ),
496  AMIList[i].srcAddress(),
497  AMIList[i].srcWeights()
498  )
499  )
500  );
501 
502  // Transfer all mapped quantities (value and e.g. gradient) onto
503  // srcField. Value will get overwritten below
504  srcField.rmap(tnewSrc(), identity(srcField.size()));
505 
506 
507  // Override value to account for CombineOp (could be dummy for
508  // plusEqOp)
509  mapAndOpTgtToSrc(AMIList[i], srcField, tgtField);
510  }
511 
512  forAll(cuttingPatches_, i)
513  {
514  label patchi = cuttingPatches_[i];
516  pf == pf.patchInternalField();
517  }
518 }
519 
520 
521 template<class Type>
524 (
526 ) const
527 {
529 
530  const fvMesh& srcMesh = static_cast<const fvMesh&>(srcRegion_);
531 
532  const fvBoundaryMesh& srcBm = srcMesh.boundary();
533  const typename fieldType::Boundary& tgtBfld =
534  field.boundaryField();
535 
536  PtrList<fvPatchField<Type>> srcPatchFields(srcBm.size());
537 
538  // construct src boundary patch types as copy of 'field' boundary types
539  // note: this will provide place holders for fields with additional
540  // entries, but these values will need to be reset
541  forAll(srcPatchID_, i)
542  {
543  label srcPatchi = srcPatchID_[i];
544  label tgtPatchi = tgtPatchID_[i];
545 
546  if (!srcPatchFields.set(tgtPatchi))
547  {
548  srcPatchFields.set
549  (
550  srcPatchi,
552  (
553  tgtBfld[srcPatchi],
554  srcMesh.boundary()[tgtPatchi],
557  (
558  labelList(srcMesh.boundary()[srcPatchi].size(), -1)
559  )
560  )
561  );
562  }
563  }
564 
565  // Any unset srcPatchFields become calculated
566  forAll(srcPatchFields, srcPatchi)
567  {
568  if (!srcPatchFields.set(srcPatchi))
569  {
570  // Note: use factory New method instead of direct generation of
571  // calculated so we keep constraints
572  srcPatchFields.set
573  (
574  srcPatchi,
576  (
578  srcMesh.boundary()[srcPatchi],
580  )
581  );
582  }
583  }
584 
585  tmp<fieldType> tresult
586  (
587  new fieldType
588  (
589  IOobject
590  (
591  type() + ":interpolate(" + field.name() + ")",
592  srcMesh.time().timeName(),
593  srcMesh,
596  ),
597  srcMesh,
598  field.dimensions(),
599  Field<Type>(srcMesh.nCells(), Zero),
600  srcPatchFields
601  )
602  );
603 
604  mapTgtToSrc(field, tresult.ref());
605 
606  return tresult;
607 }
608 
609 
610 template<class Type>
613 (
615 ) const
616 {
617  return mapTgtToSrc(tfield());
618 }
619 
620 
621 // ************************************************************************* //
void operator()(List< Type > &x, const List< Type > y) const
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:434
const word & name() const
Return name.
Definition: IOobject.H:315
FieldMapper with weighted mapping from (optionally remote) quantities.
error FatalError
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:306
const Boundary & boundaryField() const
Return const-reference to the boundary field.
T & ref() const
Return non-const reference or generate a fatal error.
Definition: tmpI.H:181
void size(const label)
Override size to be inconsistent with allocated storage.
Definition: ListI.H:164
label nCells() const
Traits class for primitives.
Definition: pTraits.H:50
Abstract base class with a fat-interface to all derived classes covering all possible ways in which t...
Definition: fvPatchField.H:66
labelList identity(const label len)
Create identity map (map[i] == i) of given length.
Definition: ListOps.C:104
Generic GeometricField class.
void mapSrcToTgt(const UList< Type > &srcFld, List< Type > &result) const
Map field from src to tgt mesh with defined operation.
const Time & time() const
Return the top-level database.
Definition: fvMesh.H:372
void distribute(List< T > &fld, const bool dummyTransform=true, const int tag=UPstream::msgType()) const
Distribute data using default commsType.
dimensioned< Type > sum(const DimensionedField< Type, GeoMesh > &df)
scalar y
const dimensionSet & dimensions() const
Return dimensions.
static const DimensionedField< Type, GeoMesh > & null()
Return a null DimensionedField.
Pre-declare SubField and related Field type.
Definition: Field.H:56
static word timeName(const scalar, const int precision=curPrecision_)
Return time name of given scalar time.
Definition: Time.C:666
This boundary condition is not designed to be evaluated; it is assumed that the value is assigned via...
virtual void rmap(const fvPatchField< Type > &, const labelList &)
Reverse map the given fvPatchField onto this fvPatchField.
Definition: fvPatchField.C:199
List< label > labelList
A List of labels.
Definition: labelList.H:56
static const zero Zero
Definition: zero.H:97
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.
errorManip< error > abort(error &err)
Definition: errorManip.H:131
const fvPatch & patch() const
Return patch.
Definition: fvPatchField.H:351
Internal::FieldType & primitiveFieldRef()
Return a reference to the internal field.
static const char nl
Definition: Ostream.H:260
virtual tmp< Field< Type > > patchInternalField() const
Return internal field next to patch as patch field.
Definition: fvPatchField.C:174
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.
Internal & ref()
Return a reference to the dimensioned internal field.
label size() const
Return the number of elements in the UPtrList.
Definition: UPtrListI.H:29
void setSize(const label)
Reset size of List.
Definition: List.C:281
Class containing processor-to-processor mapping information.
label patchi
Boundary & boundaryFieldRef()
Return a reference to the boundary field.
A templated 1D list of pointers to objects of type <T>, where the size of the array is known and used...
Definition: List.H:70
Foam::fvBoundaryMesh.
Mesh data needed to do the Finite Volume discretisation.
Definition: fvMesh.H:95
fileType type(const fileName &, const bool checkVariants=true, const bool followLink=true)
Return the file type: directory or file.
Definition: POSIX.C:488
Interpolation class dealing with transfer of data between two primitive patches with an arbitrary mes...
void mapTgtToSrc(const UList< Type > &tgtFld, List< Type > &result) const
Map field from tgt to src mesh with defined operation.
A class for managing temporary objects.
Definition: PtrList.H:53
IOobject defines the attributes of an object for which implicit objectRegistry management is supporte...
Definition: IOobject.H:98
Namespace for OpenFOAM.
const fvBoundaryMesh & boundary() const
Return reference to boundary mesh.
Definition: fvMesh.C:800