cellDecomposerTemplates.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) 2024 OpenCFD Ltd.
9 -------------------------------------------------------------------------------
10 License
11  This file is part of OpenFOAM.
12 
13  OpenFOAM is free software: you can redistribute it and/or modify it
14  under the terms of the GNU General Public License as published by
15  the Free Software Foundation, either version 3 of the License, or
16  (at your option) any later version.
17 
18  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
19  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
20  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21  for more details.
22 
23  You should have received a copy of the GNU General Public License
24  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
25 
26 \*---------------------------------------------------------------------------*/
27 
28 #include "fvMesh.H"
29 #include "emptyFvPatchFields.H"
31 #include "mapPolyMesh.H"
32 //#include "polyPatch.H"
33 //#include "lduSchedule.H"
34 //#include "meshToMesh.H"
35 
36 //template<class Type>
37 //void Foam::functionObjects::cellDecomposer::evaluateConstraintTypes
38 //(
39 // GeometricField<Type, fvPatchField, volMesh>& fld
40 //) const
41 //{
42 // fld.boundaryFieldRef().evaluate_if
43 // (
44 // [](const auto& pfld) -> bool
45 // {
46 // return
47 // (
48 // pfld.type() == pfld.patch().patch().type()
49 // && polyPatch::constraintType(pfld.patch().patch().type())
50 // );
51 // }
52 // );
53 //}
54 
55 template<class Type>
57 <
59 >
60 Foam::functionObjects::cellDecomposer::interpolate
61 (
62  const GeometricField<Type, fvPatchField, volMesh>& vf,
63  const fvMesh& sMesh,
64  const labelUList& patchMap,
65  const labelUList& cellMap,
66  const labelUList& faceMap,
67  const bool allowUnmapped
68 ) const
69 {
70  // 1. Create the complete field with dummy patch fields
71  PtrList<fvPatchField<Type>> patchFields(patchMap.size());
72 
73  forAll(patchFields, patchi)
74  {
75  // Set the first one by hand as it corresponds to the
76  // exposed internal faces. Additional interpolation can be put here
77  // as necessary.
78  if (patchMap[patchi] == -1)
79  {
80  patchFields.set
81  (
82  patchi,
83  new emptyFvPatchField<Type>
84  (
85  sMesh.boundary()[patchi],
87  )
88  );
89  }
90  else
91  {
92  patchFields.set
93  (
94  patchi,
96  (
98  sMesh.boundary()[patchi],
100  )
101  );
102  }
103  }
104 
105  auto tresult = tmp<GeometricField<Type, fvPatchField, volMesh>>::New
106  (
107  IOobject
108  (
109  "subset"+vf.name(),
110  sMesh.time().timeName(),
111  sMesh,
114  ),
115  sMesh,
116  vf.dimensions(),
117  Field<Type>(vf.primitiveField(), cellMap),
118  patchFields
119  );
120  auto& result = tresult.ref();
121  result.oriented() = vf.oriented();
122 
123 
124  // 2. Change the fvPatchFields to the correct type using a mapper
125  // constructor (with reference to the now correct internal field)
126 
127  auto& bf = result.boundaryFieldRef();
128 
129  forAll(bf, patchi)
130  {
131  const label basePatchId = patchMap[patchi];
132 
133  if (basePatchId != -1)
134  {
135  // Construct addressing
136  const fvPatch& subPatch = sMesh.boundary()[patchi];
137  const fvPatch& basePatch = vf.mesh().boundary()[basePatchId];
138  const label baseStart = basePatch.start();
139  const label baseSize = basePatch.size();
140 
141  labelList directAddressing(subPatch.size());
142 
143  forAll(directAddressing, i)
144  {
145  const label baseFacei = faceMap[subPatch.start()+i];
146 
147  if (baseFacei >= baseStart && baseFacei < baseStart+baseSize)
148  {
149  directAddressing[i] = baseFacei-baseStart;
150  }
151  else
152  {
153  // Mapped from internal face. Do what? Leave up to
154  // fvPatchField
155  directAddressing[i] = -1;
156  }
157  }
158 
159 
160  directFvPatchFieldMapper mapper(directAddressing);
161 
162  // allowUnmapped : special mode for if we do not want to be
163  // warned for unmapped faces (e.g. from fvMeshDistribute).
164 
165  const bool hasUnmapped = mapper.hasUnmapped();
166  if (allowUnmapped)
167  {
168  mapper.hasUnmapped() = false;
169  }
170 
171  bf.set
172  (
173  patchi,
175  (
176  vf.boundaryField()[basePatchId],
177  subPatch,
178  result.internalField(),
179  mapper
180  )
181  );
182 
183  if (allowUnmapped && hasUnmapped)
184  {
185  // Set unmapped values to zeroGradient. This is the default
186  // action for unmapped fvPatchFields. Note that this bypasses
187  // any special logic for handling unmapped fvPatchFields but
188  // since this is only used inside fvMeshDistribute ...
189 
190  tmp<Field<Type>> tfld(bf[patchi].patchInternalField());
191  const Field<Type>& fld = tfld();
192 
193  Field<Type> value(bf[patchi]);
194  forAll(directAddressing, i)
195  {
196  if (directAddressing[i] == -1)
197  {
198  value[i] = fld[i];
199  }
200  }
201  bf[patchi].fvPatchField<Type>::operator=(value);
202  }
203  }
204  }
205 
206  return tresult;
207 }
208 
209 
210 template<class Type>
211 bool Foam::functionObjects::cellDecomposer::mapFieldType() const
212 {
213  typedef GeometricField<Type, fvPatchField, volMesh> VolFieldType;
214 
215  const fvMesh& mapRegion =
216  this->mesh_.time().lookupObject<fvMesh>(mapRegion_);
217 
218  const labelList patchMap(identity(mapRegion.boundaryMesh().size()));
219 
220  const wordList fieldNames
221  (
222  this->mesh_.sortedNames<VolFieldType>(fieldNames_)
223  );
224 
225  const bool processed = !fieldNames.empty();
226 
227  for (const word& fieldName : fieldNames)
228  {
229  const VolFieldType& field = lookupObject<VolFieldType>(fieldName);
230 
231  auto* mapFieldPtr = mapRegion.getObjectPtr<VolFieldType>(fieldName);
232 
233  if (!mapFieldPtr)
234  {
235  mapFieldPtr = new VolFieldType
236  (
237  IOobject
238  (
239  fieldName,
240  time_.timeName(),
241  mapRegion,
245  ),
246  mapRegion,
247  dimensioned<Type>(field.dimensions(), Zero)
248  );
249 
250  mapFieldPtr->store();
251  }
252 
253  auto& mappedField = *mapFieldPtr;
254 
255  mappedField = interpolate
256  (
257  field,
258  mapRegion,
259  patchMap,
260  mapPtr_().cellMap(),
261  mapPtr_().faceMap(),
262  false //allowUnmapped
263  );
264  Log << " " << fieldName << ": interpolated" << nl;
265 
266  //evaluateConstraintTypes(mappedField);
267  }
268 
269  return processed;
270 }
271 
272 
273 template<class Type>
274 bool Foam::functionObjects::cellDecomposer::writeFieldType() const
275 {
276  typedef GeometricField<Type, fvPatchField, volMesh> VolFieldType;
277 
278  const fvMesh& mapRegion =
279  this->mesh_.time().lookupObject<fvMesh>(mapRegion_);
280 
281  const wordList fieldNames
282  (
283  this->mesh_.sortedNames<VolFieldType>(fieldNames_)
284  );
285 
286  const bool processed = !fieldNames.empty();
287 
288  for (const word& fieldName : fieldNames)
289  {
290  const VolFieldType& mappedField =
291  mapRegion.template lookupObject<VolFieldType>(fieldName);
292 
293  mappedField.write();
294 
295  Log << " " << fieldName << ": written" << nl;
296  }
297 
298  return processed;
299 }
300 
301 
302 // ************************************************************************* //
static const this_type & null() noexcept
Return a null DimensionedField (reference to a nullObject).
rDeltaTY field()
bool interpolate(const vector &p1, const vector &p2, const vector &o, vector &n, scalar l)
Definition: curveTools.C:75
constexpr char nl
The newline &#39;\n&#39; character (0x0a)
Definition: Ostream.H:50
Ignore writing from objectRegistry::writeObject()
DirectFieldMapper< fvPatchFieldMapper > directFvPatchFieldMapper
A fvPatchFieldMapper with direct mapping.
UList< label > labelUList
A UList of labels.
Definition: UList.H:76
Pair< int > faceMap(const label facePi, const face &faceP, const label faceNi, const face &faceN)
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:286
labelList identity(const label len, label start=0)
Return an identity map of the given length with (map[i] == i), works like std::iota() but returning a...
Definition: labelLists.C:44
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))
List< word > wordList
List of word.
Definition: fileName.H:59
Nothing to be read.
static const word & calculatedType() noexcept
The type name for calculated patch fields.
Definition: fvPatchField.H:185
#define Log
Definition: PDRblock.C:28
static autoPtr< functionObject > New(const word &name, const Time &runTime, const dictionary &dict)
Select from dictionary, based on its "type" entry.
List< label > labelList
A List of labels.
Definition: List.H:61
A class for managing temporary objects.
Definition: HashPtrTable.H:50
Request registration (bool: true)
static tmp< fvPatchField< Type > > New(const word &patchFieldType, const fvPatch &, const DimensionedField< Type, volMesh > &)
Return a pointer to a new patchField created on freestore given.
static constexpr const zero Zero
Global zero (0)
Definition: zero.H:127