setAndPointToFaceZone.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) 2024-2025 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 "setAndPointToFaceZone.H"
27 #include "FaceCellWave.H"
28 #include "faceZoneSet.H"
29 #include "indexedOctree.H"
30 #include "minData.H"
31 #include "treeDataCell.H"
33 
34 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
35 
36 namespace Foam
37 {
40  (
43  word
44  );
45 }
46 
47 
48 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
49 
51 (
52  const polyMesh& mesh,
53  const word& setName,
54  const vector& point
55 )
56 :
58  setName_(setName),
59  point_(point)
60 {}
61 
62 
64 (
65  const polyMesh& mesh,
66  const dictionary& dict
67 )
68 :
70  setName_(dict.lookup<word>("set")),
71  point_(dict.lookup<vector>("point", dimLength))
72 {}
73 
74 
75 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
76 
78 {}
79 
80 
81 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
82 
84 (
85  const topoSetSource::setAction action,
86  topoSet& set
87 ) const
88 {
89  if (!isA<faceZoneSet>(set))
90  {
92  << "Operation only allowed on a faceZoneSet."
93  << endl;
94  return;
95  }
96 
97  // Cast to get the zone
98  faceZoneSet& fzSet = refCast<faceZoneSet>(set);
99 
100  // Load the set
101  faceSet loadedSet(mesh_, setName_);
102 
103  // Allocate new topology
104  DynamicList<label> newAddressing(fzSet.addressing().size());
105  DynamicList<bool> newFlipMap(fzSet.flipMap().size());
106 
107  if ((action == topoSetSource::NEW) || (action == topoSetSource::ADD))
108  {
109  Info<< " Adding all faces from faceSet " << setName_
110  << " ..." << endl;
111 
112  // Construct a wave to transport a minimum index
113  List<minData> allFaceData(mesh_.nFaces());
114  List<minData> allCellData(mesh_.nCells());
115 
116  // Set the existing faces of the set to a higher index than that of
117  // uninitialised data
118  forAllConstIter(faceSet, loadedSet, iter)
119  {
120  allFaceData[iter.key()] = minData(-1);
121  }
122 
123  // Find the cell containing the given point and give that an even
124  // higher index
125  const label celli = mesh_.cellTree().findInside(point_);
126  if (returnReduce(celli, maxOp<label>()) == -1)
127  {
129  << "Point " << point_ << " was not found in the mesh"
130  << exit(FatalError);
131  }
132  if (celli != -1)
133  {
134  allCellData[celli] = minData(0);
135  }
136 
137  // Create seed faces as all those of the cell containing the given
138  // point. Give these the same index as the cell.
139  const label nSeedFaces = celli != -1 ? mesh_.cells()[celli].size() : 0;
140  labelList seedFaces(nSeedFaces);
141  List<minData> seedFaceData(nSeedFaces);
142  if (celli != -1)
143  {
144  forAll(mesh_.cells()[celli], cellFacei)
145  {
146  const label facei = mesh_.cells()[celli][cellFacei];
147  seedFaces[cellFacei] = facei;
148  seedFaceData = minData(0);
149  }
150  }
151 
152  // Wave from the point to the set faces
154  (
155  mesh_,
156  seedFaces,
157  seedFaceData,
158  allFaceData,
159  allCellData,
160  mesh().globalData().nTotalCells()+1
161  );
162 
163  // Initialise as a copy
164  newAddressing = fzSet.addressing();
165  newFlipMap = fzSet.flipMap();
166 
167  // Unpack. Each set face should be at the boundary between cells that
168  // were and were not visited by the wave. If it is the neighbour that
169  // was visited by the wave, then set the flip map.
170  forAllConstIter(faceSet, loadedSet, iter)
171  {
172  const label facei = iter.key();
173 
174  const label owni = mesh_.faceOwner()[facei];
175  const bool ownValid = allCellData[owni].valid(wave.data());
176 
177  if (mesh_.isInternalFace(facei))
178  {
179  const label nbri = mesh_.faceNeighbour()[facei];
180  const bool nbrValid = allCellData[nbri].valid(wave.data());
181 
182  if (ownValid && nbrValid)
183  {
185  << "Internal face #" << facei << " at "
186  << mesh_.faceCentres()[facei]
187  << " was visited from both sides by a wave from "
188  << point_ << exit(FatalError);
189  }
190 
191  if (!ownValid && !nbrValid)
192  {
194  << "Internal face #" << facei << " at "
195  << mesh_.faceCentres()[facei]
196  << " was not visited by a wave from "
197  << point_ << exit(FatalError);
198  }
199  }
200  else
201  {
202  if (!ownValid)
203  {
205  << "Boundary face #" << facei << " at "
206  << mesh_.faceCentres()[facei]
207  << " was not visited by a wave from "
208  << point_ << exit(FatalError);
209  }
210  }
211 
212  newAddressing.append(facei);
213  newFlipMap.append(!ownValid);
214  }
215  }
216  else if (action == topoSetSource::DELETE)
217  {
218  Info<< " Removing all faces from faceSet " << setName_
219  << " ..." << endl;
220 
221  // Remove everything in the set from the zone. Don't have to worry
222  // about computing the flips here, seeing as we are only removing
223  // faces.
224  DynamicList<label> newAddressing(fzSet.addressing().size());
225  DynamicList<bool> newFlipMap(fzSet.flipMap().size());
226  forAll(fzSet.addressing(), i)
227  {
228  if (!loadedSet.found(fzSet.addressing()[i]))
229  {
230  newAddressing.append(fzSet.addressing()[i]);
231  newFlipMap.append(fzSet.flipMap()[i]);
232  }
233  }
234  }
235 
236  // Transfer into the zone
237  fzSet.addressing().transfer(newAddressing);
238  fzSet.flipMap().transfer(newFlipMap);
239  fzSet.updateSet();
240 }
241 
242 
243 // ************************************************************************* //
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:433
#define forAllConstIter(Container, container, iter)
Iterate across all elements in the container object of type.
Definition: UList.H:476
Macros for easy insertion into run-time selection tables.
DynamicList< T, SizeInc, SizeMult, SizeDiv > & append(const T &)
Append an element at the end of the list.
Definition: DynamicListI.H:296
Wave propagation of information through grid. Every iteration information goes through one layer of c...
Definition: FaceCellWave.H:79
bool found(const Key &) const
Return true if hashedEntry is found in table.
Definition: HashTable.C:138
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
Definition: List.H:91
void transfer(List< T > &)
Transfer the contents of the argument List into this list.
Definition: List.C:342
void size(const label)
Override size to be inconsistent with allocated storage.
Definition: ListI.H:164
A list of keywords followed by any number of values (e.g. words and numbers) or sub-dictionaries.
Definition: dictionary.H:162
A list of face labels.
Definition: faceSet.H:51
Like faceSet but -reads data from faceZone -updates faceZone when writing.
Definition: faceZoneSet.H:52
const boolList & flipMap() const
Definition: faceZoneSet.H:116
const labelList & addressing() const
Definition: faceZoneSet.H:105
void updateSet()
Sort addressing and make faceSet part consistent with addressing.
Definition: faceZoneSet.C:51
For use with FaceCellWave. Transports minimum passive data.
Definition: minData.H:64
Mesh consisting of general polyhedral cells.
Definition: polyMesh.H:80
A topoSetSource to select faces based on usage in a faceSet, where an behind/inside point is used to ...
virtual void applyToSet(const topoSetSource::setAction action, topoSet &) const
virtual ~setAndPointToFaceZone()
Destructor.
setAndPointToFaceZone(const polyMesh &mesh, const word &setName, const vector &normal)
Construct from components.
Base class of a source for a topoSet.
Definition: topoSetSource.H:64
setAction
Enumeration defining the valid actions.
Definition: topoSetSource.H:83
General set of labels of mesh quantity (points, cells, faces).
Definition: topoSet.H:61
A class for handling words, derived from string.
Definition: word.H:62
Foam::fvMesh mesh(Foam::IOobject(regionName, runTime.name(), runTime, Foam::IOobject::MUST_READ), false)
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:334
#define WarningInFunction
Report a warning using Foam::Warning.
label wave(const fvMesh &mesh, const List< labelPair > &changedPatchAndFaces, const label nCorrections, GeometricField< scalar, GeoMesh > &distance, TrackingData &td, GeometricField< DataType, GeoMesh > &... data)
Wave distance (and maybe additional) data from faces. If nCorrections is.
Namespace for OpenFOAM.
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:124
intWM_LABEL_SIZE_t label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
Definition: label.H:59
addToRunTimeSelectionTable(polyPatch, mergedCyclicPolyPatch, word)
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:258
messageStream Info
const dimensionSet dimLength
T returnReduce(const T &Value, const BinaryOp &bop, const int tag=Pstream::msgType(), const label comm=UPstream::worldComm)
defineTypeNameAndDebug(combustionModel, 0)
error FatalError
dictionary dict